<commit_before>#![allow(unstable)]
extern crate num;

use num::{Complex, Zero};
use std::iter::{repeat, range_step_inclusive, range_step};
use std::f32;

pub struct FFT {
    scratch: Vec<Complex<f32>>,
    factors: Vec<(usize, usize)>,
    twiddles: Vec<Complex<f32>>,
}

impl FFT {
    pub fn new(len: usize) -> Self {
        FFT {
            scratch: repeat(Zero::zero()).take(len).collect(),
            factors: factor(len),
            twiddles: range(0, len)
                      .map(|i| -1. * (i as f32) * f32::consts::PI_2 / (len as f32))
                      .map(|phase| Complex::from_polar(&1., &phase))
                      .collect(),
        }
    }

    pub fn process(&mut self, signal: &[Complex<f32>], spectrum: &mut [Complex<f32>]) {
        cooley_tukey(signal, 1,
                     spectrum, 1,
                     self.scratch.as_mut_slice(), 1,
                     self.twiddles.as_slice(),
                     self.factors.as_slice());
    }
}

//TODO can we collapse all these strides into one stride value?
fn cooley_tukey(signal: &[Complex<f32>],
                signal_stride: usize,
                spectrum: &mut [Complex<f32>],
                spectrum_stride: usize,
                scratch: &mut [Complex<f32>],
                scratch_stride: usize,
                twiddles: &[Complex<f32>],
                factors: &[(usize, usize)]) {
    match factors {
        [_] | [] => dft_slice(signal, signal_stride,
                              spectrum, spectrum_stride,
                              twiddles),
        [(n1, n2), other_factors..] => {
            for i in range(0, n1) {
                // perform the smaller FFTs from the signal buffer into
                // the scratch buffer, using the spectrum buffer as scratch space
                cooley_tukey(signal.slice_from(i * signal_stride), signal_stride * n1,
                             scratch.slice_from_mut(i * scratch_stride), scratch_stride * n1,
                             spectrum.slice_from_mut(i * spectrum_stride), spectrum_stride * n1,
                             twiddles, other_factors);
            }

            butterfly(scratch, scratch_stride,
                      spectrum, spectrum_stride,
                      twiddles, n1, n2);
        }
    }
}

fn butterfly(input: &[Complex<f32>],
             input_stride: usize,
             output: &mut [Complex<f32>],
             output_stride: usize,
             twiddles: &[Complex<f32>],
             num_cols: usize,
             num_rows: usize) {
    // for each row in input
    let mut twiddle_idx_increase_1 = 0;
    for (i, in_row) in input.chunks(num_cols * input_stride).enumerate() {
        let out_col = output.slice_from_mut(i * output_stride);
        let out_col_stride = output_stride * num_rows;
        let mut twiddle_idx_increase_2 = 0;
        for spec_bin_idx in range_step(0, out_col.len(), out_col_stride) {
            let spec_bin = unsafe { out_col.get_unchecked_mut(spec_bin_idx) };
            *spec_bin = Zero::zero();
            let mut twiddle_idx = 0;
            let twiddle_idx_increase = twiddle_idx_increase_1 + twiddle_idx_increase_2;
            for sig_bin_idx in range_step(0, in_row.len(), input_stride) {
                let sig_bin = unsafe { in_row.get_unchecked(sig_bin_idx) };
                let twiddle = unsafe { twiddles.get_unchecked(twiddle_idx) };
                *spec_bin = *spec_bin + *twiddle * *sig_bin;
                twiddle_idx += twiddle_idx_increase;
                if twiddle_idx > twiddles.len() { twiddle_idx -= twiddles.len() }
            }
            twiddle_idx_increase_2 += num_rows * input_stride;
        }
        twiddle_idx_increase_1 += input_stride;
    }
}

pub fn dft_slice(signal: &[Complex<f32>],
                 signal_stride: usize,
                 spectrum: &mut [Complex<f32>],
                 spectrum_stride: usize,
                 twiddles: &[Complex<f32>]) {
    let mut twiddle_idx_increase = 0;
    for spec_bin_idx in range_step(0, spectrum.len(), spectrum_stride) {
        let spec_bin = unsafe { spectrum.get_unchecked_mut(spec_bin_idx) };
        *spec_bin = Zero::zero();
        let mut twiddle_idx = 0;
        for signal_bin_idx in range_step(0, signal.len(), signal_stride) {
            let signal_bin = unsafe { signal.get_unchecked(signal_bin_idx) };
            let twiddle = unsafe { twiddles.get_unchecked(twiddle_idx) };
            *spec_bin = *spec_bin + twiddle * *signal_bin;
            twiddle_idx += twiddle_idx_increase;
            if twiddle_idx > twiddles.len() {twiddle_idx -= twiddles.len()}
        }
        twiddle_idx_increase += signal_stride;
    }
}

pub fn dft<'a, 'b, I, O>(signal: I, spectrum: O)
where I: Iterator<Item=&'a Complex<f32>> + ExactSizeIterator + Clone,
      O: Iterator<Item=&'b mut Complex<f32>>
{
    for (k, spec_bin) in spectrum.enumerate()
    {
        let signal_iter = signal.clone();
        let mut sum: Complex<f32> = Zero::zero();
        for (i, &x) in signal_iter.enumerate() {
            let angle = -1. * ((i * k) as f32) * f32::consts::PI_2 / (signal.len() as f32);
            let twiddle: Complex<f32> = Complex::from_polar(&1f32, &angle);
            sum = sum + twiddle * x;
        }
        *spec_bin = sum;
    }
}

fn factor(n: usize) -> Vec<(usize, usize)>
{
    let mut factors = Vec::new();
    let mut next = n;
    while next > 1 {
        for div in Some(2us).into_iter().chain(range_step_inclusive(3us, next, 2)) {
            if next % div == 0 {
                next = next / div;
                factors.push((div, next));
                break;
            }
        }
    }
    return factors;
}
<commit_msg>Changed from 'slice_from' to slicing syntax<commit_after>#![allow(unstable)]
extern crate num;

use num::{Complex, Zero};
use std::iter::{repeat, range_step_inclusive, range_step};
use std::f32;

pub struct FFT {
    scratch: Vec<Complex<f32>>,
    factors: Vec<(usize, usize)>,
    twiddles: Vec<Complex<f32>>,
}

impl FFT {
    pub fn new(len: usize) -> Self {
        FFT {
            scratch: repeat(Zero::zero()).take(len).collect(),
            factors: factor(len),
            twiddles: range(0, len)
                      .map(|i| -1. * (i as f32) * f32::consts::PI_2 / (len as f32))
                      .map(|phase| Complex::from_polar(&1., &phase))
                      .collect(),
        }
    }

    pub fn process(&mut self, signal: &[Complex<f32>], spectrum: &mut [Complex<f32>]) {
        cooley_tukey(signal, 1,
                     spectrum, 1,
                     self.scratch.as_mut_slice(), 1,
                     self.twiddles.as_slice(),
                     self.factors.as_slice());
    }
}

//TODO can we collapse all these strides into one stride value?
fn cooley_tukey(signal: &[Complex<f32>],
                signal_stride: usize,
                spectrum: &mut [Complex<f32>],
                spectrum_stride: usize,
                scratch: &mut [Complex<f32>],
                scratch_stride: usize,
                twiddles: &[Complex<f32>],
                factors: &[(usize, usize)]) {
    match factors {
        [_] | [] => dft_slice(signal, signal_stride,
                              spectrum, spectrum_stride,
                              twiddles),
        [(n1, n2), other_factors..] => {
            for i in range(0, n1) {
                // perform the smaller FFTs from the signal buffer into
                // the scratch buffer, using the spectrum buffer as scratch space
                cooley_tukey(&signal[i * signal_stride..], signal_stride * n1,
                             &mut scratch[i * scratch_stride..], scratch_stride * n1,
                             &mut spectrum[i * spectrum_stride..], spectrum_stride * n1,
                             twiddles, other_factors);
            }

            butterfly(scratch, scratch_stride,
                      spectrum, spectrum_stride,
                      twiddles, n1, n2);
        }
    }
}

fn butterfly(input: &[Complex<f32>],
             input_stride: usize,
             output: &mut [Complex<f32>],
             output_stride: usize,
             twiddles: &[Complex<f32>],
             num_cols: usize,
             num_rows: usize) {
    // for each row in input
    let mut twiddle_idx_increase_1 = 0;
    for (i, in_row) in input.chunks(num_cols * input_stride).enumerate() {
        let out_col = &mut output[i * output_stride..];
        let out_col_stride = output_stride * num_rows;
        let mut twiddle_idx_increase_2 = 0;
        for spec_bin_idx in range_step(0, out_col.len(), out_col_stride) {
            let spec_bin = unsafe { out_col.get_unchecked_mut(spec_bin_idx) };
            *spec_bin = Zero::zero();
            let mut twiddle_idx = 0;
            let twiddle_idx_increase = twiddle_idx_increase_1 + twiddle_idx_increase_2;
            for sig_bin_idx in range_step(0, in_row.len(), input_stride) {
                let sig_bin = unsafe { in_row.get_unchecked(sig_bin_idx) };
                let twiddle = unsafe { twiddles.get_unchecked(twiddle_idx) };
                *spec_bin = *spec_bin + *twiddle * *sig_bin;
                twiddle_idx += twiddle_idx_increase;
                if twiddle_idx > twiddles.len() { twiddle_idx -= twiddles.len() }
            }
            twiddle_idx_increase_2 += num_rows * input_stride;
        }
        twiddle_idx_increase_1 += input_stride;
    }
}

pub fn dft_slice(signal: &[Complex<f32>],
                 signal_stride: usize,
                 spectrum: &mut [Complex<f32>],
                 spectrum_stride: usize,
                 twiddles: &[Complex<f32>]) {
    let mut twiddle_idx_increase = 0;
    for spec_bin_idx in range_step(0, spectrum.len(), spectrum_stride) {
        let spec_bin = unsafe { spectrum.get_unchecked_mut(spec_bin_idx) };
        *spec_bin = Zero::zero();
        let mut twiddle_idx = 0;
        for signal_bin_idx in range_step(0, signal.len(), signal_stride) {
            let signal_bin = unsafe { signal.get_unchecked(signal_bin_idx) };
            let twiddle = unsafe { twiddles.get_unchecked(twiddle_idx) };
            *spec_bin = *spec_bin + twiddle * *signal_bin;
            twiddle_idx += twiddle_idx_increase;
            if twiddle_idx > twiddles.len() {twiddle_idx -= twiddles.len()}
        }
        twiddle_idx_increase += signal_stride;
    }
}

pub fn dft<'a, 'b, I, O>(signal: I, spectrum: O)
where I: Iterator<Item=&'a Complex<f32>> + ExactSizeIterator + Clone,
      O: Iterator<Item=&'b mut Complex<f32>>
{
    for (k, spec_bin) in spectrum.enumerate()
    {
        let signal_iter = signal.clone();
        let mut sum: Complex<f32> = Zero::zero();
        for (i, &x) in signal_iter.enumerate() {
            let angle = -1. * ((i * k) as f32) * f32::consts::PI_2 / (signal.len() as f32);
            let twiddle: Complex<f32> = Complex::from_polar(&1f32, &angle);
            sum = sum + twiddle * x;
        }
        *spec_bin = sum;
    }
}

fn factor(n: usize) -> Vec<(usize, usize)>
{
    let mut factors = Vec::new();
    let mut next = n;
    while next > 1 {
        for div in Some(2us).into_iter().chain(range_step_inclusive(3us, next, 2)) {
            if next % div == 0 {
                next = next / div;
                factors.push((div, next));
                break;
            }
        }
    }
    return factors;
}
<|endoftext|>


<commit_before>extern crate nix;
extern crate libc;

use nix::unistd::*;
use nix::unistd::Fork::*;
use libc::pid_t;
use nix::Error;
use nix::errno;
use nix::sys::ptrace::*;
use nix::sys::ptrace::ptrace::*;
use nix::sys::wait::*;
use std::ffi::CString;
use std::ptr;
use std::path::Path;
use nix::sys::signal;
use libc::c_void;

pub type TrapInferior = pid_t;
pub type TrapBreakpoint = i32;

static mut original_breakpoint_word : i64 = 0;

mod ffi {
    use libc::{c_int, c_long};

    extern {
        pub fn personality(persona: c_long) -> c_int;
    }
}

fn disable_address_space_layout_randomization() -> () {
    unsafe {
        let old = ffi::personality(0xffffffff);
        ffi::personality((old | 0x0040000) as i64);
    }
}

fn exec_inferior(filename: &Path, args: &[&str]) -> () {
    let c_filename = &CString::new(filename.to_str().unwrap()).unwrap();
    disable_address_space_layout_randomization();
    ptrace(PTRACE_TRACEME, 0, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_TRACEME");
    execve(c_filename, &[], &[])
        .ok()
        .expect("Failed execve");
    unreachable!();
}

fn attach_inferior(pid: pid_t) -> Result<TrapInferior, Error> {
    match waitpid(pid, None) {
        Ok(WaitStatus::Stopped(pid, signal::SIGTRAP)) => return Ok(pid),
        Ok(_) => panic!("Unexpected stop in attach_inferior"),
        Err(e) => return Err(e)
    }
}

pub fn trap_inferior_exec(filename: &Path, args: &[&str]) -> Result<TrapInferior, Error> {
    loop {
        match fork() {
            Ok(Child)                      => exec_inferior(filename, args),
            Ok(Parent(pid))                => return attach_inferior(pid),
            Err(Error::Sys(errno::EAGAIN)) => continue,
            Err(e)                         => return Err(e)
        }
    }
}

pub fn trap_inferior_continue<F>(inferior: TrapInferior, callback: &mut F) -> i8
    where F: FnMut(TrapInferior, TrapBreakpoint) -> () {

    let pid = inferior;

    loop {
        ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut())
            .ok()
            .expect("Failed PTRACE_CONTINUE");

        match waitpid(pid, None) {
            Ok(WaitStatus::Exited(_pid, code)) => return code,
            Ok(WaitStatus::Stopped(_pid, signal::SIGTRAP)) =>
                handle_breakpoint(inferior, callback),
            Ok(_) => panic!("Unexpected stop in trap_inferior_continue"),
            Err(_) => panic!("Unhandled error in trap_inferior_continue")
        }
    }
}

fn handle_breakpoint<F>(inferior: TrapInferior,  mut callback: &mut F) -> ()
    where F: FnMut(TrapInferior, TrapBreakpoint) -> () {

    callback(inferior, 0)
}

pub fn trap_inferior_set_breakpoint(inferior: TrapInferior, location: usize) -> TrapBreakpoint {
    let target_address = location as * mut c_void;
    let aligned_address = location & !0x7usize;

    let original = ptrace(PTRACE_PEEKTEXT, inferior, aligned_address as * mut c_void, ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKTEXT");

    let shift = (location - aligned_address) * 8;
    let mut modified = original as usize;
    modified &= !0xFFusize << shift;
    modified |= 0xCCusize << shift;

    ptrace(PTRACE_POKETEXT, inferior, target_address, modified as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKETEXT");

    0
}
<commit_msg>WIP single step<commit_after>extern crate nix;
extern crate libc;

use nix::unistd::*;
use nix::unistd::Fork::*;
use libc::pid_t;
use nix::Error;
use nix::errno;
use nix::sys::ptrace::*;
use nix::sys::ptrace::ptrace::*;
use nix::sys::wait::*;
use std::ffi::CString;
use std::ptr;
use std::path::Path;
use nix::sys::signal;
use libc::c_void;

pub type TrapInferior = pid_t;
pub type TrapBreakpoint = i32;

static mut original_breakpoint_word : i64 = 0;

mod ffi {
    use libc::{c_int, c_long};

    extern {
        pub fn personality(persona: c_long) -> c_int;
    }
}

fn ptrace_util_get_instruction_pointer(pid: pid_t pid) -> usize
{
  uintptr_t offset = offsetof(struct user, regs.rip);
  return ptrace(PTRACE_PEEKUSER, pid, offset, ptr::null_mut());
}

fn ptrace_util_set_instruction_pointer(pid: pid_t pid, ip: usize) -> ()
{
  uintptr_t offset = offsetof(struct user, regs.rip);
  int result = ptrace(PTRACE_POKEUSER, pid, offset, ip);
  if (result != 0) {
    perror("ptrace_util_set_instruction_pointer: ");
    abort();
  }
}

fn disable_address_space_layout_randomization() -> () {
    unsafe {
        let old = ffi::personality(0xffffffff);
        ffi::personality((old | 0x0040000) as i64);
    }
}

fn exec_inferior(filename: &Path, args: &[&str]) -> () {
    let c_filename = &CString::new(filename.to_str().unwrap()).unwrap();
    disable_address_space_layout_randomization();
    ptrace(PTRACE_TRACEME, 0, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_TRACEME");
    execve(c_filename, &[], &[])
        .ok()
        .expect("Failed execve");
    unreachable!();
}

fn attach_inferior(pid: pid_t) -> Result<TrapInferior, Error> {
    match waitpid(pid, None) {
        Ok(WaitStatus::Stopped(pid, signal::SIGTRAP)) => return Ok(pid),
        Ok(_) => panic!("Unexpected stop in attach_inferior"),
        Err(e) => return Err(e)
    }
}

pub fn trap_inferior_exec(filename: &Path, args: &[&str]) -> Result<TrapInferior, Error> {
    loop {
        match fork() {
            Ok(Child)                      => exec_inferior(filename, args),
            Ok(Parent(pid))                => return attach_inferior(pid),
            Err(Error::Sys(errno::EAGAIN)) => continue,
            Err(e)                         => return Err(e)
        }
    }
}

pub fn trap_inferior_continue<F>(inferior: TrapInferior, callback: &mut F) -> i8
    where F: FnMut(TrapInferior, TrapBreakpoint) -> () {

    let pid = inferior;

    loop {
        ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut())
            .ok()
            .expect("Failed PTRACE_CONTINUE");

        match waitpid(pid, None) {
            Ok(WaitStatus::Exited(_pid, code)) => return code,
            Ok(WaitStatus::Stopped(_pid, signal::SIGTRAP)) =>
                handle_breakpoint(inferior, callback),
            Ok(_) => panic!("Unexpected stop in trap_inferior_continue"),
            Err(_) => panic!("Unhandled error in trap_inferior_continue")
        }
    }
}

fn handle_breakpoint<F>(inferior: TrapInferior,  mut callback: &mut F) -> ()
    where F: FnMut(TrapInferior, TrapBreakpoint) -> () {

    let original = unsafe { original_breakpoint_word };

    ptrace(PTRACE_POKETEXT, inferior, target_address, original as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKETEXT");

    callback(inferior, 0)
}

pub fn trap_inferior_set_breakpoint(inferior: TrapInferior, location: usize) -> TrapBreakpoint {
    let target_address = location as * mut c_void;
    let aligned_address = location & !0x7usize;

    let original = ptrace(PTRACE_PEEKTEXT, inferior, aligned_address as * mut c_void, ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKTEXT");

    let shift = (location - aligned_address) * 8;
    let mut modified = original as usize;
    modified &= !0xFFusize << shift;
    modified |= 0xCCusize << shift;

    ptrace(PTRACE_POKETEXT, inferior, target_address, modified as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKETEXT");

    unsafe { original_breakpoint_word = original as i64; }

    0
}
<|endoftext|>


<commit_before>// Copyright 2015 Drew Short <drew@sothr.com>.
//
// Licensed under the MIT license<LICENSE-MIT or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

mod hash;

pub fn hello(mut result: String) -> String {
    let helloworld = "Hello, World!\n";
    result.push_str(helloworld);
    let n = 1u8;
    let ns = format!("1: {:b}\n", n);
    let n2 = 2u8;
    let n2s = format!("2: {:b}\n", n2);
    result.push_str(&ns);
    result.push_str(&n2s);
    let mut endian = "Big Endian\n";
    if cfg!(target_endian = "big") {
        result.push_str(endian);
    } else {
        endian = "Little Endian\n";
        result.push_str(endian);
    }
    result
}

/*
 * Module for the tests
 */
#[cfg(test)]
mod tests {

    use super::*;
    use std::fs;
    use std::path;
    use hash;

    //#[test]
    fn can_get_test_images() {
        let paths = fs::read_dir(&path::Path::new("./test_images")).unwrap();
        let mut num_paths = 0;
        for path in paths {
            let orig_path = path.unwrap().path();
            let ext = path::Path::new(&orig_path).extension();
            match ext {
                Some(_) => {
                    if ext.unwrap() == "jpg" {
                        num_paths += 1;
                        println!("Is a image {}: {:?}", num_paths, orig_path) ;
                    }
                },
                _ => {
                    println!("Not an image: {:?}", orig_path) ;
                    continue
                }
            }
            //println!("Name: {}", path.unwrap().path().display())
        }
        // Currently 12 images in the test imaages directory
        assert!(num_paths == 12);
    }

    // Simple function for the unit tests to succinctly test a set of images
    // that are organized in the fashion of large->medium->small
    fn test_imageset_hash<F: Fn(hash::PreparedImage) -> u64>(
        hash_func: F,
        large_path: &str,
        medium_path: &str,
        small_path: &str,
        expected_large_hash: u64,
        expected_medium_hash: u64,
        expected_small_hash: u64,
        expected_large_medium_hamming: u64,
        expected_large_small_hamming: u64,
        expected_medium_small_hamming: u64) {

        let large_prepared_image = hash::prepare_image(path::Path::new(large_path), 8u32);
        let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path), 8u32);
        let small_prepared_image = hash::prepare_image(path::Path::new(small_path), 8u32);

        let actual_large_hash = hash_func(large_prepared_image);
        let actual_medium_hash = hash_func(medium_prepared_image);
        let actual_small_hash = hash_func(small_prepared_image);

        // println for the purpose of debugging
        println!("{}: expected: {} actual: {}", large_path, expected_large_hash, actual_large_hash);
        println!("{}: expected: {} actual: {}", medium_path, expected_medium_hash, actual_medium_hash);
        println!("{}: expected: {} actual: {}", small_path, expected_small_hash, actual_small_hash);

        let actual_large_medium_hamming = hash::calculate_hamming_distance(actual_large_hash, actual_medium_hash);
        let actual_large_small_hamming = hash::calculate_hamming_distance(actual_large_hash, actual_small_hash);
        let actual_medium_small_hamming = hash::calculate_hamming_distance(actual_medium_hash, actual_small_hash);

        println!("Large-Medium Hamming Distance: expected: {} actual: {}", expected_large_medium_hamming, actual_large_medium_hamming);
        println!("Large-Small Hamming Distance: expected: {} actual: {}", expected_large_small_hamming, actual_large_small_hamming);
        println!("Medium-Small Hamming Distance: expected: {} actual: {}", expected_medium_small_hamming, actual_medium_small_hamming);

        // Doing that asserts
        assert!(actual_large_hash == expected_large_hash);
        assert!(actual_medium_hash == expected_medium_hash);
        assert!(actual_small_hash == expected_small_hash);

        assert!(actual_large_medium_hamming == expected_large_medium_hamming);
        assert!(actual_large_small_hamming == expected_large_small_hamming);
        assert!(actual_medium_small_hamming == expected_medium_small_hamming);

    }

    //#[test]
    fn confirm_ahash_results() {
        // Sample_01 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_01_large.jpg",
            "./test_images/sample_01_medium.jpg",
            "./test_images/sample_01_small.jpg",
            857051991849750,
            857051991849750,
            857051991849750,
            0u64,
            0u64,
            0u64
        );

        // Sample_02 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_02_large.jpg",
            "./test_images/sample_02_medium.jpg",
            "./test_images/sample_02_small.jpg",
            18446744073441116160,
            18446744073441116160,
            18446744073441116160,
            0u64,
            0u64,
            0u64
        );
        // Sample_03 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_03_large.jpg",
            "./test_images/sample_03_medium.jpg",
            "./test_images/sample_03_small.jpg",
            135670932300497406,
            135670932300497406,
            135670932300497406,
            0u64,
            0u64,
            0u64
        );

        // Sample_04 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_04_large.jpg",
            "./test_images/sample_04_medium.jpg",
            "./test_images/sample_04_small.jpg",
            18446460933225054208,
            18446460933090836480,
            18446460933090836480,
            1u64,
            1u64,
            0u64
        );
    }

    #[test]
    fn confirm_dhash_results() {
        // Sample_01 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_01_large.jpg",
            "./test_images/sample_01_medium.jpg",
            "./test_images/sample_01_small.jpg",
            7937395827556495926,
            7937395827556495926,
            7939647627370181174,
            0u64,
            1u64,
            1u64
        );

        // Sample_02 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_02_large.jpg",
            "./test_images/sample_02_medium.jpg",
            "./test_images/sample_02_small.jpg",
            11009829669713008949,
            11009829670249879861,
            11009829669713008949,
            1u64,
            0u64,
            1u64
        );
        // Sample_03 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_03_large.jpg",
            "./test_images/sample_03_medium.jpg",
            "./test_images/sample_03_small.jpg",
            225528496439353286,
            225528496439353286,
            226654396346195908,
            0u64,
            2u64,
            2u64
        );

        // Sample_04 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_04_large.jpg",
            "./test_images/sample_04_medium.jpg",
            "./test_images/sample_04_small.jpg",
            14620651386429567209,
            14620651386429567209,
            14620651386429567209,
            0u64,
            0u64,
            0u64
        );
    }
}
<commit_msg>Forgot to uncomment the ahash test and the directory select test from local testing.<commit_after>// Copyright 2015 Drew Short <drew@sothr.com>.
//
// Licensed under the MIT license<LICENSE-MIT or http://opensource.org/licenses/MIT>.
// This file may not be copied, modified, or distributed except according to those terms.

mod hash;

pub fn hello(mut result: String) -> String {
    let helloworld = "Hello, World!\n";
    result.push_str(helloworld);
    let n = 1u8;
    let ns = format!("1: {:b}\n", n);
    let n2 = 2u8;
    let n2s = format!("2: {:b}\n", n2);
    result.push_str(&ns);
    result.push_str(&n2s);
    let mut endian = "Big Endian\n";
    if cfg!(target_endian = "big") {
        result.push_str(endian);
    } else {
        endian = "Little Endian\n";
        result.push_str(endian);
    }
    result
}

/*
 * Module for the tests
 */
#[cfg(test)]
mod tests {

    use super::*;
    use std::fs;
    use std::path;
    use hash;

    #[test]
    fn can_get_test_images() {
        let paths = fs::read_dir(&path::Path::new("./test_images")).unwrap();
        let mut num_paths = 0;
        for path in paths {
            let orig_path = path.unwrap().path();
            let ext = path::Path::new(&orig_path).extension();
            match ext {
                Some(_) => {
                    if ext.unwrap() == "jpg" {
                        num_paths += 1;
                        println!("Is a image {}: {:?}", num_paths, orig_path) ;
                    }
                },
                _ => {
                    println!("Not an image: {:?}", orig_path) ;
                    continue
                }
            }
            //println!("Name: {}", path.unwrap().path().display())
        }
        // Currently 12 images in the test imaages directory
        assert!(num_paths == 12);
    }

    // Simple function for the unit tests to succinctly test a set of images
    // that are organized in the fashion of large->medium->small
    fn test_imageset_hash<F: Fn(hash::PreparedImage) -> u64>(
        hash_func: F,
        large_path: &str,
        medium_path: &str,
        small_path: &str,
        expected_large_hash: u64,
        expected_medium_hash: u64,
        expected_small_hash: u64,
        expected_large_medium_hamming: u64,
        expected_large_small_hamming: u64,
        expected_medium_small_hamming: u64) {

        let large_prepared_image = hash::prepare_image(path::Path::new(large_path), 8u32);
        let medium_prepared_image = hash::prepare_image(path::Path::new(medium_path), 8u32);
        let small_prepared_image = hash::prepare_image(path::Path::new(small_path), 8u32);

        let actual_large_hash = hash_func(large_prepared_image);
        let actual_medium_hash = hash_func(medium_prepared_image);
        let actual_small_hash = hash_func(small_prepared_image);

        // println for the purpose of debugging
        println!("{}: expected: {} actual: {}", large_path, expected_large_hash, actual_large_hash);
        println!("{}: expected: {} actual: {}", medium_path, expected_medium_hash, actual_medium_hash);
        println!("{}: expected: {} actual: {}", small_path, expected_small_hash, actual_small_hash);

        let actual_large_medium_hamming = hash::calculate_hamming_distance(actual_large_hash, actual_medium_hash);
        let actual_large_small_hamming = hash::calculate_hamming_distance(actual_large_hash, actual_small_hash);
        let actual_medium_small_hamming = hash::calculate_hamming_distance(actual_medium_hash, actual_small_hash);

        println!("Large-Medium Hamming Distance: expected: {} actual: {}", expected_large_medium_hamming, actual_large_medium_hamming);
        println!("Large-Small Hamming Distance: expected: {} actual: {}", expected_large_small_hamming, actual_large_small_hamming);
        println!("Medium-Small Hamming Distance: expected: {} actual: {}", expected_medium_small_hamming, actual_medium_small_hamming);

        // Doing that asserts
        assert!(actual_large_hash == expected_large_hash);
        assert!(actual_medium_hash == expected_medium_hash);
        assert!(actual_small_hash == expected_small_hash);

        assert!(actual_large_medium_hamming == expected_large_medium_hamming);
        assert!(actual_large_small_hamming == expected_large_small_hamming);
        assert!(actual_medium_small_hamming == expected_medium_small_hamming);

    }

    #[test]
    fn confirm_ahash_results() {
        // Sample_01 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_01_large.jpg",
            "./test_images/sample_01_medium.jpg",
            "./test_images/sample_01_small.jpg",
            857051991849750,
            857051991849750,
            857051991849750,
            0u64,
            0u64,
            0u64
        );

        // Sample_02 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_02_large.jpg",
            "./test_images/sample_02_medium.jpg",
            "./test_images/sample_02_small.jpg",
            18446744073441116160,
            18446744073441116160,
            18446744073441116160,
            0u64,
            0u64,
            0u64
        );
        // Sample_03 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_03_large.jpg",
            "./test_images/sample_03_medium.jpg",
            "./test_images/sample_03_small.jpg",
            135670932300497406,
            135670932300497406,
            135670932300497406,
            0u64,
            0u64,
            0u64
        );

        // Sample_04 tests
        test_imageset_hash(
            hash::get_ahash,
            "./test_images/sample_04_large.jpg",
            "./test_images/sample_04_medium.jpg",
            "./test_images/sample_04_small.jpg",
            18446460933225054208,
            18446460933090836480,
            18446460933090836480,
            1u64,
            1u64,
            0u64
        );
    }

    #[test]
    fn confirm_dhash_results() {
        // Sample_01 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_01_large.jpg",
            "./test_images/sample_01_medium.jpg",
            "./test_images/sample_01_small.jpg",
            7937395827556495926,
            7937395827556495926,
            7939647627370181174,
            0u64,
            1u64,
            1u64
        );

        // Sample_02 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_02_large.jpg",
            "./test_images/sample_02_medium.jpg",
            "./test_images/sample_02_small.jpg",
            11009829669713008949,
            11009829670249879861,
            11009829669713008949,
            1u64,
            0u64,
            1u64
        );
        // Sample_03 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_03_large.jpg",
            "./test_images/sample_03_medium.jpg",
            "./test_images/sample_03_small.jpg",
            225528496439353286,
            225528496439353286,
            226654396346195908,
            0u64,
            2u64,
            2u64
        );

        // Sample_04 tests
        test_imageset_hash(
            hash::get_dhash,
            "./test_images/sample_04_large.jpg",
            "./test_images/sample_04_medium.jpg",
            "./test_images/sample_04_small.jpg",
            14620651386429567209,
            14620651386429567209,
            14620651386429567209,
            0u64,
            0u64,
            0u64
        );
    }
}
<|endoftext|>


<commit_before>//! Manipulations and data types that represent polynomial.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

extern crate num;

use std::{cmp, fmt};
use std::ops::{Add, Mul, Neg, Sub};
use num::{Zero, One};

/// Polynomial expression
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Polynomial<T> { data: Vec<T> }

impl<T: Zero> Polynomial<T> {
    /// Creates new `Polynomial`.
    ///
    /// ```rust
    /// use polynomial::Polynomial;
    /// let poly = Polynomial::new(vec![1, 2, 3]);
    /// assert_eq!("1+2*x+3*x^2", poly.pretty("x"));
    /// ```
    #[inline]
    pub fn new(mut data: Vec<T>) -> Polynomial<T> {
        while let Some(true) = data.last().map(|x| x.is_zero()) {
            let _ = data.pop();
        }
        Polynomial { data: data }
    }
}

impl<T: Zero + One + Clone> Polynomial<T> {
    /// Evaluates the polynomial value.
    ///
    /// ```rust
    /// use polynomial::Polynomial;
    /// let poly = Polynomial::new(vec![1, 2, 3]);
    /// assert_eq!(1, poly.eval(0));
    /// assert_eq!(6, poly.eval(1));
    /// assert_eq!(17, poly.eval(2));
    /// ```
    #[inline]
    pub fn eval(&self, x: T) -> T {
        let mut sum: T = Zero::zero();
        let mut x_n: T = One::one();
        for n in self.data.iter() {
            sum = sum + n.clone() * x_n.clone();
            x_n = x_n * x.clone();
        }
        sum
    }
}

impl<T> Polynomial<T> {
    /// Gets the slice of internal data.
    #[inline]
    pub fn data(&self) -> &[T] { &self.data }
}

impl<T> Polynomial<T>
    where T: Zero + One + Eq + Neg<Output = T> + Ord + fmt::Display + Clone
{
    /// Pretty prints the polynomial.
    pub fn pretty(&self, x: &str) -> String {
        if self.is_zero() { return "0".to_string() }

        let one = One::one();
        let mut s = Vec::new();
        for (i, n) in self.data.iter().enumerate() {
            // output n*x^i / -n*x^i
            if n.is_zero() { continue }

            let term = if i.is_zero() {
                n.to_string()
            } else if i == 1 {
                if (*n) == one { x.to_string() }
                else if (*n) == -one.clone() { format!("-{}", x) }
                else { format!("{}*{}", n.to_string(), x) }
            } else {
                if (*n) == one { format!("{}^{}", x, i) }
                else if (*n) == -one.clone() { format!("-{}^{}", x, i) }
                else { format!("{}*{}^{}", n.to_string(), x, i) }
            };

            if s.len() > 0 && (*n) > Zero::zero() { s.push("+".to_string()); }
            s.push(term);
        }

        s.concat()
    }
}

impl<'a, T> Neg for Polynomial<T>
    where T: Neg + Zero + Clone, <T as Neg>::Output: Zero
{
    type Output = Polynomial<<T as Neg>::Output>;

    #[inline]
    fn neg(self) -> Polynomial<<T as Neg>::Output> { -&self }
}

impl<'a, T> Neg for &'a Polynomial<T>
    where T: Neg + Zero + Clone, <T as Neg>::Output: Zero
{
    type Output = Polynomial<<T as Neg>::Output>;

    #[inline]
    fn neg(self) -> Polynomial<<T as Neg>::Output> {
        Polynomial::new(self.data.iter().map(|x| -x.clone()).collect())
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Polynomial<Rhs>> for Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Polynomial<Rhs>> for &'a Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Polynomial<Rhs>> for Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Add<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Add<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Add<Rhs>>::Output>;

    fn add(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Add<Rhs>>::Output> {
        let max_len = cmp::max(self.data.len(), other.data.len());
        let min_len = cmp::min(self.data.len(), other.data.len());

        let mut sum = Vec::with_capacity(max_len);
        for i in (0 .. min_len) {
            sum.push(self.data[i].clone() + other.data[i].clone());
        }

        if self.data.len() <= other.data.len() {
            for i in (min_len .. max_len) {
                sum.push(num::zero::<Lhs>() + other.data[i].clone());
            }
        } else {
            for i in (min_len .. max_len) {
                sum.push(self.data[i].clone() + num::zero::<Rhs>());
            }
        }

        Polynomial::new(sum)
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Sub<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Sub<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Sub<Rhs>>::Output>;

    fn sub(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Sub<Rhs>>::Output> {
        let min_len = cmp::min(self.data.len(), other.data.len());
        let max_len = cmp::max(self.data.len(), other.data.len());

        let mut sub = Vec::with_capacity(max_len);
        for i in (0 .. min_len) {
            sub.push(self.data[i].clone() - other.data[i].clone());
        }
        if self.data.len() <= other.data.len() {
            for i in (min_len .. max_len) {
                sub.push(num::zero::<Lhs>() - other.data[i].clone())
            }
        } else {
            for i in (min_len .. max_len) {
                sub.push(self.data[i].clone() - num::zero::<Rhs>())
            }
        }
        Polynomial::new(sub)
    }
}

forward_all_binop!(impl Mul, mul);

impl<'a, 'b, Lhs, Rhs> Mul<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Mul<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Mul<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Mul<Rhs>>::Output>;

    fn mul(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Mul<Rhs>>::Output> {
        if self.is_zero() || other.is_zero() { return Polynomial::new(vec![]) }

        let slen = self.data.len();
        let olen = other.data.len();
        let prod = (0 .. slen + olen - 1).map(|i| {
            let mut p = num::zero::<<Lhs as Mul<Rhs>>::Output>();
            let kstart = cmp::max(olen, i + 1) - olen;
            let kend = cmp::min(slen, i + 1);
            for k in kstart .. kend {
                p = p + self.data[k].clone() * other.data[i - k].clone();
            }
            p
        }).collect();
        Polynomial::new(prod)
    }
}

impl<T: Zero + Clone> Zero for Polynomial<T> {
    #[inline]
    fn zero() -> Polynomial<T> { Polynomial { data: vec![] } }
    #[inline]
    fn is_zero(&self) -> bool { self.data.is_empty() }
}

impl<T: Zero + One + Clone> One for Polynomial<T> {
    #[inline]
    fn one() -> Polynomial<T> { Polynomial { data: vec![One::one()] } }
}

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

    #[test]
    fn new() {
        fn check(dst: Vec<i32>, src: Vec<i32>) {
            assert_eq!(dst, Polynomial::new(src).data);
        }
        check(vec![1, 2, 3], vec![1, 2, 3]);
        check(vec![1, 2, 3], vec![1, 2, 3, 0, 0]);
        check(vec![], vec![0, 0, 0]);
    }

    #[test]
    fn neg_add_sub() {
        fn check(a: &[i32], b: &[i32], c: &[i32]) {
            fn check_eq(a: &Polynomial<i32>, b: &Polynomial<i32>) {
                assert_eq!(*a, *b);
                assert_eq!(-a, -b);
            }
            fn check_add(sum: &Polynomial<i32>, a: &Polynomial<i32>, b: &Polynomial<i32>) {
                check_eq(sum, &(a + b));
                check_eq(sum, &(b + a));
            }
            fn check_sub(sum: &Polynomial<i32>, a: &Polynomial<i32>, b: &Polynomial<i32>) {
                check_eq(a, &(sum - b));
                check_eq(b, &(sum - a));
            }

            let a = &Polynomial::new(a.to_vec());
            let b = &Polynomial::new(b.to_vec());
            let c = &Polynomial::new(c.to_vec());
            check_add(c, a, b);
            check_add(&(-c), &(-a), &(-b));
            check_sub(c, a, b);
            check_sub(&(-c), &(-a), &(-b));
        }
        check(&[], &[], &[]);
        check(&[], &[1], &[1]);
        check(&[1], &[1], &[2]);
        check(&[1, 0, 1], &[1], &[2, 0, 1]);
        check(&[1, 0, -1], &[-1, 0, 1], &[]);
    }

    #[test]
    fn mul() {
        fn check(a: &[i32], b: &[i32], c: &[i32]) {
            let a = Polynomial::new(a.to_vec());
            let b = Polynomial::new(b.to_vec());
            let c = Polynomial::new(c.to_vec());
            assert_eq!(c, &a * &b);
            assert_eq!(c, &b * &a);
        }
        check(&[], &[], &[]);
        check(&[0, 0], &[], &[]);
        check(&[0, 0], &[1], &[]);
        check(&[1, 0], &[1], &[1]);
        check(&[1, 0, 1], &[1], &[1, 0, 1]);
        check(&[1, 1], &[1, 1], &[1, 2, 1]);
        check(&[1, 1], &[1, 0, 1], &[1, 1, 1, 1]);
        check(&[0, 0, 1], &[0, 0, 1], &[0, 0, 0, 0, 1]);
    }

    #[test]
    fn eval() {
        fn check<F: Fn(i32) -> i32>(pol: &[i32], f: F) {
            for n in (-10 .. 10) {
                assert_eq!(f(n), Polynomial::new(pol.to_vec()).eval(n));
            }
        }
        check(&[], |_x| 0);
        check(&[1], |_x| 1);
        check(&[1, 1], |x| x + 1);
        check(&[0, 1], |x| x);
        check(&[10, -10, 10], |x| 10*x*x - 10 * x + 10);
    }

    #[test]
    fn pretty() {
        fn check(slice: &[i32], s: &str) {
            assert_eq!(s.to_string(), Polynomial::new(slice.to_vec()).pretty("x"));
        }
        check(&[0], "0");
        check(&[1], "1");
        check(&[1, 1], "1+x");
        check(&[1, 1, 1], "1+x+x^2");
        check(&[2, 2, 2], "2+2*x+2*x^2");
        check(&[0, 0, 0, 1], "x^3");
        check(&[0, 0, 0, -1], "-x^3");
        check(&[-1, 0, 0, -1], "-1-x^3");
        check(&[-1, 1, 0, -1], "-1+x-x^3");
        check(&[-1, 1, -1, -1], "-1+x-x^2-x^3");
    }
}
<commit_msg>Run rustfmt<commit_after>//! Manipulations and data types that represent polynomial.

#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results)]

extern crate num;

use std::{cmp, fmt};
use std::ops::{Add, Mul, Neg, Sub};
use num::{Zero, One};

/// Polynomial expression
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct Polynomial<T> {
    data: Vec<T>,
}

impl<T: Zero> Polynomial<T> {
    /// Creates new `Polynomial`.
    ///
    /// ```rust
    /// use polynomial::Polynomial;
    /// let poly = Polynomial::new(vec![1, 2, 3]);
    /// assert_eq!("1+2*x+3*x^2", poly.pretty("x"));
    /// ```
    #[inline]
    pub fn new(mut data: Vec<T>) -> Polynomial<T> {
        while let Some(true) = data.last().map(|x| x.is_zero()) {
            let _ = data.pop();
        }
        Polynomial { data: data }
    }
}

impl<T: Zero + One + Clone> Polynomial<T> {
    /// Evaluates the polynomial value.
    ///
    /// ```rust
    /// use polynomial::Polynomial;
    /// let poly = Polynomial::new(vec![1, 2, 3]);
    /// assert_eq!(1, poly.eval(0));
    /// assert_eq!(6, poly.eval(1));
    /// assert_eq!(17, poly.eval(2));
    /// ```
    #[inline]
    pub fn eval(&self, x: T) -> T {
        let mut sum: T = Zero::zero();
        let mut x_n: T = One::one();
        for n in self.data.iter() {
            sum = sum + n.clone() * x_n.clone();
            x_n = x_n * x.clone();
        }
        sum
    }
}

impl<T> Polynomial<T> {
    /// Gets the slice of internal data.
    #[inline]
    pub fn data(&self) -> &[T] {
        &self.data
    }
}

impl<T> Polynomial<T>
    where T: Zero + One + Eq + Neg<Output = T> + Ord + fmt::Display + Clone
{
    /// Pretty prints the polynomial.
    pub fn pretty(&self, x: &str) -> String {
        if self.is_zero() {
            return "0".to_string();
        }

        let one = One::one();
        let mut s = Vec::new();
        for (i, n) in self.data.iter().enumerate() {
            // output n*x^i / -n*x^i
            if n.is_zero() {
                continue;
            }

            let term = if i.is_zero() {
                n.to_string()
            } else if i == 1 {
                if (*n) == one {
                    x.to_string()
                } else if (*n) == -one.clone() {
                    format!("-{}", x)
                } else {
                    format!("{}*{}", n.to_string(), x)
                }
            } else {
                if (*n) == one {
                    format!("{}^{}", x, i)
                } else if (*n) == -one.clone() {
                    format!("-{}^{}", x, i)
                } else {
                    format!("{}*{}^{}", n.to_string(), x, i)
                }
            };

            if s.len() > 0 && (*n) > Zero::zero() {
                s.push("+".to_string());
            }
            s.push(term);
        }

        s.concat()
    }
}

impl<'a, T> Neg for Polynomial<T>
    where T: Neg + Zero + Clone, <T as Neg>::Output: Zero
{
    type Output = Polynomial<<T as Neg>::Output>;

    #[inline]
    fn neg(self) -> Polynomial<<T as Neg>::Output> {
        -&self
    }
}

impl<'a, T> Neg for &'a Polynomial<T>
    where T: Neg + Zero + Clone, <T as Neg>::Output: Zero
{
    type Output = Polynomial<<T as Neg>::Output>;

    #[inline]
    fn neg(self) -> Polynomial<<T as Neg>::Output> {
        Polynomial::new(self.data.iter().map(|x| -x.clone()).collect())
    }
}

macro_rules! forward_val_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<Lhs, Rhs> $imp<Polynomial<Rhs>> for Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(&other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<Polynomial<Rhs>> for &'a Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                self.$method(&other)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident, $method:ident) => {
        impl<'a, Lhs, Rhs> $imp<&'a Polynomial<Rhs>> for Polynomial<Lhs>
            where Lhs: Zero + $imp<Rhs> + Clone, Rhs: Zero + Clone,
                  <Lhs as $imp<Rhs>>::Output: Zero
        {
            type Output = Polynomial<<Lhs as $imp<Rhs>>::Output>;

            #[inline]
            fn $method(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as $imp<Rhs>>::Output> {
                (&self).$method(other)
            }
        }
    }
}

macro_rules! forward_all_binop {
    (impl $imp:ident, $method:ident) => {
        forward_val_val_binop!(impl $imp, $method);
        forward_ref_val_binop!(impl $imp, $method);
        forward_val_ref_binop!(impl $imp, $method);
    };
}

forward_all_binop!(impl Add, add);

impl<'a, 'b, Lhs, Rhs> Add<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Add<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Add<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Add<Rhs>>::Output>;

    fn add(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Add<Rhs>>::Output> {
        let max_len = cmp::max(self.data.len(), other.data.len());
        let min_len = cmp::min(self.data.len(), other.data.len());

        let mut sum = Vec::with_capacity(max_len);
        for i in (0..min_len) {
            sum.push(self.data[i].clone() + other.data[i].clone());
        }

        if self.data.len() <= other.data.len() {
            for i in (min_len..max_len) {
                sum.push(num::zero::<Lhs>() + other.data[i].clone());
            }
        } else {
            for i in (min_len..max_len) {
                sum.push(self.data[i].clone() + num::zero::<Rhs>());
            }
        }

        Polynomial::new(sum)
    }
}

forward_all_binop!(impl Sub, sub);

impl<'a, 'b, Lhs, Rhs> Sub<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Sub<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Sub<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Sub<Rhs>>::Output>;

    fn sub(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Sub<Rhs>>::Output> {
        let min_len = cmp::min(self.data.len(), other.data.len());
        let max_len = cmp::max(self.data.len(), other.data.len());

        let mut sub = Vec::with_capacity(max_len);
        for i in (0..min_len) {
            sub.push(self.data[i].clone() - other.data[i].clone());
        }
        if self.data.len() <= other.data.len() {
            for i in (min_len..max_len) {
                sub.push(num::zero::<Lhs>() - other.data[i].clone())
            }
        } else {
            for i in (min_len..max_len) {
                sub.push(self.data[i].clone() - num::zero::<Rhs>())
            }
        }
        Polynomial::new(sub)
    }
}

forward_all_binop!(impl Mul, mul);

impl<'a, 'b, Lhs, Rhs> Mul<&'b Polynomial<Rhs>> for &'a Polynomial<Lhs>
    where Lhs: Zero + Mul<Rhs> + Clone, Rhs: Zero + Clone,
          <Lhs as Mul<Rhs>>::Output: Zero
{
    type Output = Polynomial<<Lhs as Mul<Rhs>>::Output>;

    fn mul(self, other: &Polynomial<Rhs>) -> Polynomial<<Lhs as Mul<Rhs>>::Output> {
        if self.is_zero() || other.is_zero() {
            return Polynomial::new(vec![]);
        }

        let slen = self.data.len();
        let olen = other.data.len();
        let prod = (0..slen + olen - 1)
                       .map(|i| {
                           let mut p = num::zero::<<Lhs as Mul<Rhs>>::Output>();
                           let kstart = cmp::max(olen, i + 1) - olen;
                           let kend = cmp::min(slen, i + 1);
                           for k in kstart..kend {
                               p = p + self.data[k].clone() * other.data[i - k].clone();
                           }
                           p
                       })
                       .collect();
        Polynomial::new(prod)
    }
}

impl<T: Zero + Clone> Zero for Polynomial<T> {
    #[inline]
    fn zero() -> Polynomial<T> {
        Polynomial { data: vec![] }
    }
    #[inline]
    fn is_zero(&self) -> bool {
        self.data.is_empty()
    }
}

impl<T: Zero + One + Clone> One for Polynomial<T> {
    #[inline]
    fn one() -> Polynomial<T> {
        Polynomial { data: vec![One::one()] }
    }
}

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

    #[test]
    fn new() {
        fn check(dst: Vec<i32>, src: Vec<i32>) {
            assert_eq!(dst, Polynomial::new(src).data);
        }
        check(vec![1, 2, 3], vec![1, 2, 3]);
        check(vec![1, 2, 3], vec![1, 2, 3, 0, 0]);
        check(vec![], vec![0, 0, 0]);
    }

    #[test]
    fn neg_add_sub() {
        fn check(a: &[i32], b: &[i32], c: &[i32]) {
            fn check_eq(a: &Polynomial<i32>, b: &Polynomial<i32>) {
                assert_eq!(*a, *b);
                assert_eq!(-a, -b);
            }
            fn check_add(sum: &Polynomial<i32>, a: &Polynomial<i32>, b: &Polynomial<i32>) {
                check_eq(sum, &(a + b));
                check_eq(sum, &(b + a));
            }
            fn check_sub(sum: &Polynomial<i32>, a: &Polynomial<i32>, b: &Polynomial<i32>) {
                check_eq(a, &(sum - b));
                check_eq(b, &(sum - a));
            }

            let a = &Polynomial::new(a.to_vec());
            let b = &Polynomial::new(b.to_vec());
            let c = &Polynomial::new(c.to_vec());
            check_add(c, a, b);
            check_add(&(-c), &(-a), &(-b));
            check_sub(c, a, b);
            check_sub(&(-c), &(-a), &(-b));
        }
        check(&[], &[], &[]);
        check(&[], &[1], &[1]);
        check(&[1], &[1], &[2]);
        check(&[1, 0, 1], &[1], &[2, 0, 1]);
        check(&[1, 0, -1], &[-1, 0, 1], &[]);
    }

    #[test]
    fn mul() {
        fn check(a: &[i32], b: &[i32], c: &[i32]) {
            let a = Polynomial::new(a.to_vec());
            let b = Polynomial::new(b.to_vec());
            let c = Polynomial::new(c.to_vec());
            assert_eq!(c, &a * &b);
            assert_eq!(c, &b * &a);
        }
        check(&[], &[], &[]);
        check(&[0, 0], &[], &[]);
        check(&[0, 0], &[1], &[]);
        check(&[1, 0], &[1], &[1]);
        check(&[1, 0, 1], &[1], &[1, 0, 1]);
        check(&[1, 1], &[1, 1], &[1, 2, 1]);
        check(&[1, 1], &[1, 0, 1], &[1, 1, 1, 1]);
        check(&[0, 0, 1], &[0, 0, 1], &[0, 0, 0, 0, 1]);
    }

    #[test]
    fn eval() {
        fn check<F: Fn(i32) -> i32>(pol: &[i32], f: F) {
            for n in (-10..10) {
                assert_eq!(f(n), Polynomial::new(pol.to_vec()).eval(n));
            }
        }
        check(&[], |_x| 0);
        check(&[1], |_x| 1);
        check(&[1, 1], |x| x + 1);
        check(&[0, 1], |x| x);
        check(&[10, -10, 10], |x| 10 * x * x - 10 * x + 10);
    }

    #[test]
    fn pretty() {
        fn check(slice: &[i32], s: &str) {
            assert_eq!(s.to_string(), Polynomial::new(slice.to_vec()).pretty("x"));
        }
        check(&[0], "0");
        check(&[1], "1");
        check(&[1, 1], "1+x");
        check(&[1, 1, 1], "1+x+x^2");
        check(&[2, 2, 2], "2+2*x+2*x^2");
        check(&[0, 0, 0, 1], "x^3");
        check(&[0, 0, 0, -1], "-x^3");
        check(&[-1, 0, 0, -1], "-1-x^3");
        check(&[-1, 1, 0, -1], "-1+x-x^3");
        check(&[-1, 1, -1, -1], "-1+x-x^2-x^3");
    }
}
<|endoftext|>


<commit_before>extern crate flate2;
extern crate tar;

use std::fs::File;
use flate2::read::GzDecoder;
use tar::Archive;

#[test]
fn targz() {
    let file = File::open("tests/simple.tar.gz").unwrap();
    let gz_decoder = GzDecoder::new(file).unwrap();
    let mut tar = Archive::new(gz_decoder);
    let expected = ["a", "b", "c/", "c/d"];
    let actual: Vec<_> = tar.files_mut().unwrap()
        .map(|f| f.unwrap().filename().unwrap().to_owned())
        .collect();
    assert_eq!(actual, expected);
}

#[test]
fn single_vol_names() {
    let file = File::open("tests/backups/single_vol/duplicity-full.20150617T182545Z.vol1.difftar.gz").unwrap();
    let gz_decoder = GzDecoder::new(file).unwrap();
    let mut tar = Archive::new(gz_decoder);
    for file in tar.files_mut().unwrap() {
        if let Ok(f) = file {
            println!("{:?} {:?}", f.mode(), f.filename())
        }
    }
}
<commit_msg>Fixed tests build<commit_after>extern crate flate2;
extern crate tar;

use std::fs::File;
use flate2::read::GzDecoder;
use tar::Archive;

#[test]
fn targz() {
    let file = File::open("tests/simple.tar.gz").unwrap();
    let gz_decoder = GzDecoder::new(file).unwrap();
    let mut tar = Archive::new(gz_decoder);
    let expected = ["a", "b", "c/", "c/d"];
    let actual: Vec<_> = tar.files_mut().unwrap()
        .map(|f| f.unwrap().header().path().unwrap().to_str().unwrap().to_owned())
        .collect();
    assert_eq!(actual, expected);
}

#[test]
fn single_vol_names() {
    let file = File::open("tests/backups/single_vol/duplicity-full.20150617T182545Z.vol1.difftar.gz").unwrap();
    let gz_decoder = GzDecoder::new(file).unwrap();
    let mut tar = Archive::new(gz_decoder);
    for file in tar.files_mut().unwrap() {
        if let Ok(f) = file {
            println!("{:?} {:?}", f.header().mode(), f.header().path().unwrap())
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "piston"]
#![deny(missing_doc)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

extern crate time;
extern crate sync;

// Crates used to reexport.
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "cam" as cam_lib;
extern crate "noise" as noise_lib;
extern crate "genmesh" as genmesh_lib;
extern crate "sprite" as sprite_lib;

// Reexports.
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use cam_lib as cam;
pub use noise_lib as noise;
pub use genmesh_lib as genmesh;
pub use sprite_lib as sprite;

pub use asset_store::AssetStore;
pub use event::{
    Render,
    Update,
    Input,
    Event,
    EventIterator,
    EventSettings,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};

mod asset_store;
<commit_msg>Fix missing_doc warning<commit_after>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]

//! A user friendly game engine written in Rust.

extern crate time;
extern crate sync;

// Crates used to reexport.
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "cam" as cam_lib;
extern crate "noise" as noise_lib;
extern crate "genmesh" as genmesh_lib;
extern crate "sprite" as sprite_lib;

// Reexports.
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use cam_lib as cam;
pub use noise_lib as noise;
pub use genmesh_lib as genmesh;
pub use sprite_lib as sprite;

pub use asset_store::AssetStore;
pub use event::{
    Render,
    Update,
    Input,
    Event,
    EventIterator,
    EventSettings,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};

mod asset_store;
<|endoftext|>


<commit_before>// Copyright 2019 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interface to the operating system's random number generator.
//!
//! # Supported targets
//!
//! | Target            | Target Triple      | Implementation
//! | ----------------- | ------------------ | --------------
//! | Linux, Android    | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random` |
//! | Windows           | `*‑pc‑windows‑*`   | [`BCryptGenRandom`][3] |
//! | macOS             | `*‑apple‑darwin`   | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
//! | iOS               | `*‑apple‑ios`      | [`SecRandomCopyBytes`][4]
//! | FreeBSD           | `*‑freebsd`        | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
//! | OpenBSD           | `*‑openbsd`        | [`getentropy`][6]
//! | NetBSD            | `*‑netbsd`         | [`kern.arandom`][7]
//! | Dragonfly BSD     | `*‑dragonfly`      | [`/dev/random`][8]
//! | Solaris, illumos  | `*‑solaris`, `*‑illumos` | [`getrandom()`][9] if available, otherwise [`/dev/random`][10]
//! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`][11]
//! | Redox             | `*‑redox`          | [`rand:`][12]
//! | Haiku             | `*‑haiku`          | `/dev/random` (identical to `/dev/urandom`)
//! | SGX               | `x86_64‑*‑sgx`     | [RDRAND][18]
//! | VxWorks           | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`
//! | Emscripten        | `*‑emscripten`     | `/dev/random` (identical to `/dev/urandom`)
//! | WASI              | `wasm32‑wasi`      | [`__wasi_random_get`][17]
//! | Web Browser       | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16]
//! | Node.js           | `wasm32‑*‑unknown` | [`crypto.randomBytes`][15], see [WebAssembly support][16]
//!
//! There is no blanket implementation on `unix` targets that reads from
//! `/dev/urandom`. This ensures all supported targets are using the recommended
//! interface and respect maximum buffer sizes.
//!
//! Pull Requests that add support for new targets to `getrandom` are always welcome.
//!
//! ## Unsupported targets
//!
//! By default, `getrandom` will not compile on unsupported targets, but certain
//! features allow a user to select a "fallback" implementation if no supported
//! implementation exists.
//!
//! All of the below mechanisms only affect unsupported
//! targets. Supported targets will _always_ use their supported implementations.
//! This prevents a crate from overriding a secure source of randomness
//! (either accidentally or intentionally).
//!
//! ### RDRAND on x86
//!
//! *If the `"rdrand"` Cargo feature is enabled*, `getrandom` will fallback to using
//! the [`RDRAND`][18] instruction to get randomness on `no_std` `x86`/`x86_64`
//! targets. This feature has no effect on other CPU architectures.
//!
//! ### WebAssembly support
//!
//! This crate fully supports the
//! [`wasm32-wasi`](https://github.com/CraneStation/wasi) and
//! [`wasm32-unknown-emscripten`](https://www.hellorust.com/setup/emscripten/)
//! targets. However, the `wasm32-unknown-unknown` target is not automatically
//! supported since, from the target name alone, we cannot deduce which
//! JavaScript interface is in use (or if JavaScript is available at all).
//!
//! Instead, *if the `"js"` Cargo feature is enabled*, this crate will assume
//! that you are building for an environment containing JavaScript, and will
//! call the appropriate methods. Both web browser (main window and Web Workers)
//! and Node.js environments are supported, invoking the methods
//! [described above](#supported-targets) using the
//! [wasm-bindgen](https://github.com/rust-lang/rust-bindgen) toolchain.
//!
//! This feature has no effect on targets other than `wasm32-unknown-unknown`.
//!
//! ### Custom implementations
//!
//! The [`register_custom_getrandom!`] macro allows a user to mark their own
//! function as the backing implementation for [`getrandom`]. See the macro's
//! documentation for more information about writing and registering your own
//! custom implementations.
//!
//! Note that registering a custom implementation only has an effect on targets
//! that would otherwise not compile. Any supported targets (including those
//! using `"rdrand"` and `"js"` Cargo features) continue using their normal
//! implementations even if a function is registered.
//!
//! ### Indirect Dependencies
//!
//! If `getrandom` is not a direct dependency of your crate, you can still
//! enable any of the above fallback behaviors by enabling the relevant
//! feature in your root crate's `Cargo.toml`:
//! ```toml
//! [dependencies]
//! getrandom = { version = "0.2", features = ["js"] }
//! ```
//!
//! ## Early boot
//!
//! Sometimes, early in the boot process, the OS has not collected enough
//! entropy to securely seed its RNG. This is especially common on virtual
//! machines, where standard "random" events are hard to come by.
//!
//! Some operating system interfaces always block until the RNG is securely
//! seeded. This can take anywhere from a few seconds to more than a minute.
//! A few (Linux, NetBSD and Solaris) offer a choice between blocking and
//! getting an error; in these cases, we always choose to block.
//!
//! On Linux (when the `getrandom` system call is not available), reading from
//! `/dev/urandom` never blocks, even when the OS hasn't collected enough
//! entropy yet. To avoid returning low-entropy bytes, we first poll
//! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
//!
//! ## Error handling
//!
//! We always choose failure over returning insecure "random" bytes. In general,
//! on supported platforms, failure is highly unlikely, though not impossible.
//! If an error does occur, then it is likely that it will occur on every call to
//! `getrandom`, hence after the first successful call one can be reasonably
//! confident that no errors will occur.
//!
//! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
//! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
//! [3]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
//! [6]: https://man.openbsd.org/getentropy.2
//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
//! [11]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
//! [12]: https://github.com/redox-os/randd/blob/master/src/main.rs
//! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
//! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
//! [16]: #webassembly-support
//! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
//! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
//! [20]: https://www.unix.com/man-page/mojave/4/random/
//! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable

#![doc(
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
    html_root_url = "https://rust-random.github.io/rand/"
)]
#![no_std]
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
// `matches!` macro was added only in Rust 1.42, which is bigger than our MSRV
#![allow(clippy::match_like_matches_macro)]

#[macro_use]
extern crate cfg_if;

mod error;
mod util;
// To prevent a breaking change when targets are added, we always export the
// register_custom_getrandom macro, so old Custom RNG crates continue to build.
#[cfg(feature = "custom")]
mod custom;
#[cfg(feature = "std")]
mod error_impls;

pub use crate::error::Error;

// System-specific implementations.
//
// These should all provide getrandom_inner with the same signature as getrandom.
cfg_if! {
    if #[cfg(any(target_os = "dragonfly", target_os = "emscripten",
                 target_os = "haiku",     target_os = "redox"))] {
        mod util_libc;
        #[path = "use_file.rs"] mod imp;
    } else if #[cfg(any(target_os = "android", target_os = "linux"))] {
        mod util_libc;
        mod use_file;
        #[path = "linux_android.rs"] mod imp;
    } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
        mod util_libc;
        mod use_file;
        #[path = "solaris_illumos.rs"] mod imp;
    } else if #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] {
        mod util_libc;
        #[path = "bsd_arandom.rs"] mod imp;
    } else if #[cfg(target_os = "fuchsia")] {
        #[path = "fuchsia.rs"] mod imp;
    } else if #[cfg(target_os = "ios")] {
        #[path = "ios.rs"] mod imp;
    } else if #[cfg(target_os = "macos")] {
        mod util_libc;
        mod use_file;
        #[path = "macos.rs"] mod imp;
    } else if #[cfg(target_os = "openbsd")] {
        mod util_libc;
        #[path = "openbsd.rs"] mod imp;
    } else if #[cfg(target_os = "wasi")] {
        #[path = "wasi.rs"] mod imp;
    } else if #[cfg(target_os = "vxworks")] {
        mod util_libc;
        #[path = "vxworks.rs"] mod imp;
    } else if #[cfg(windows)] {
        #[path = "windows.rs"] mod imp;
    } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
        #[path = "rdrand.rs"] mod imp;
    } else if #[cfg(all(feature = "rdrand",
                        any(target_arch = "x86_64", target_arch = "x86")))] {
        #[path = "rdrand.rs"] mod imp;
    } else if #[cfg(all(feature = "js",
                        target_arch = "wasm32", target_os = "unknown"))] {
        #[path = "js.rs"] mod imp;
    } else if #[cfg(feature = "custom")] {
        use custom as imp;
    } else {
        compile_error!("target is not supported, for more information see: \
                        https://docs.rs/getrandom/#unsupported-targets");
    }
}

/// Fill `dest` with random bytes from the system's preferred random number
/// source.
///
/// This function returns an error on any failure, including partial reads. We
/// make no guarantees regarding the contents of `dest` on error. If `dest` is
/// empty, `getrandom` immediately returns success, making no calls to the
/// underlying operating system.
///
/// Blocking is possible, at least during early boot; see module documentation.
///
/// In general, `getrandom` will be fast enough for interactive usage, though
/// significantly slower than a user-space CSPRNG; for the latter consider
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
    if dest.is_empty() {
        return Ok(());
    }
    imp::getrandom_inner(dest)
}

#[cfg(test)]
mod test_common;
#[cfg(test)]
mod test_rdrand;
<commit_msg>Fix Target Triple<commit_after>// Copyright 2019 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Interface to the operating system's random number generator.
//!
//! # Supported targets
//!
//! | Target            | Target Triple      | Implementation
//! | ----------------- | ------------------ | --------------
//! | Linux, Android    | `*‑linux‑*`        | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random` |
//! | Windows           | `*‑windows‑*`      | [`BCryptGenRandom`][3] |
//! | macOS             | `*‑apple‑darwin`   | [`getentropy()`][19] if available, otherwise [`/dev/random`][20] (identical to `/dev/urandom`)
//! | iOS               | `*‑apple‑ios`      | [`SecRandomCopyBytes`][4]
//! | FreeBSD           | `*‑freebsd`        | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
//! | OpenBSD           | `*‑openbsd`        | [`getentropy`][6]
//! | NetBSD            | `*‑netbsd`         | [`kern.arandom`][7]
//! | Dragonfly BSD     | `*‑dragonfly`      | [`/dev/random`][8]
//! | Solaris, illumos  | `*‑solaris`, `*‑illumos` | [`getrandom()`][9] if available, otherwise [`/dev/random`][10]
//! | Fuchsia OS        | `*‑fuchsia`        | [`cprng_draw`][11]
//! | Redox             | `*‑redox`          | [`rand:`][12]
//! | Haiku             | `*‑haiku`          | `/dev/random` (identical to `/dev/urandom`)
//! | SGX               | `x86_64‑*‑sgx`     | [RDRAND][18]
//! | VxWorks           | `*‑wrs‑vxworks‑*`  | `randABytes` after checking entropy pool initialization with `randSecure`
//! | Emscripten        | `*‑emscripten`     | `/dev/random` (identical to `/dev/urandom`)
//! | WASI              | `wasm32‑wasi`      | [`__wasi_random_get`][17]
//! | Web Browser       | `wasm32‑*‑unknown` | [`Crypto.getRandomValues()`][14], see [WebAssembly support][16]
//! | Node.js           | `wasm32‑*‑unknown` | [`crypto.randomBytes`][15], see [WebAssembly support][16]
//!
//! There is no blanket implementation on `unix` targets that reads from
//! `/dev/urandom`. This ensures all supported targets are using the recommended
//! interface and respect maximum buffer sizes.
//!
//! Pull Requests that add support for new targets to `getrandom` are always welcome.
//!
//! ## Unsupported targets
//!
//! By default, `getrandom` will not compile on unsupported targets, but certain
//! features allow a user to select a "fallback" implementation if no supported
//! implementation exists.
//!
//! All of the below mechanisms only affect unsupported
//! targets. Supported targets will _always_ use their supported implementations.
//! This prevents a crate from overriding a secure source of randomness
//! (either accidentally or intentionally).
//!
//! ### RDRAND on x86
//!
//! *If the `"rdrand"` Cargo feature is enabled*, `getrandom` will fallback to using
//! the [`RDRAND`][18] instruction to get randomness on `no_std` `x86`/`x86_64`
//! targets. This feature has no effect on other CPU architectures.
//!
//! ### WebAssembly support
//!
//! This crate fully supports the
//! [`wasm32-wasi`](https://github.com/CraneStation/wasi) and
//! [`wasm32-unknown-emscripten`](https://www.hellorust.com/setup/emscripten/)
//! targets. However, the `wasm32-unknown-unknown` target is not automatically
//! supported since, from the target name alone, we cannot deduce which
//! JavaScript interface is in use (or if JavaScript is available at all).
//!
//! Instead, *if the `"js"` Cargo feature is enabled*, this crate will assume
//! that you are building for an environment containing JavaScript, and will
//! call the appropriate methods. Both web browser (main window and Web Workers)
//! and Node.js environments are supported, invoking the methods
//! [described above](#supported-targets) using the
//! [wasm-bindgen](https://github.com/rust-lang/rust-bindgen) toolchain.
//!
//! This feature has no effect on targets other than `wasm32-unknown-unknown`.
//!
//! ### Custom implementations
//!
//! The [`register_custom_getrandom!`] macro allows a user to mark their own
//! function as the backing implementation for [`getrandom`]. See the macro's
//! documentation for more information about writing and registering your own
//! custom implementations.
//!
//! Note that registering a custom implementation only has an effect on targets
//! that would otherwise not compile. Any supported targets (including those
//! using `"rdrand"` and `"js"` Cargo features) continue using their normal
//! implementations even if a function is registered.
//!
//! ### Indirect Dependencies
//!
//! If `getrandom` is not a direct dependency of your crate, you can still
//! enable any of the above fallback behaviors by enabling the relevant
//! feature in your root crate's `Cargo.toml`:
//! ```toml
//! [dependencies]
//! getrandom = { version = "0.2", features = ["js"] }
//! ```
//!
//! ## Early boot
//!
//! Sometimes, early in the boot process, the OS has not collected enough
//! entropy to securely seed its RNG. This is especially common on virtual
//! machines, where standard "random" events are hard to come by.
//!
//! Some operating system interfaces always block until the RNG is securely
//! seeded. This can take anywhere from a few seconds to more than a minute.
//! A few (Linux, NetBSD and Solaris) offer a choice between blocking and
//! getting an error; in these cases, we always choose to block.
//!
//! On Linux (when the `getrandom` system call is not available), reading from
//! `/dev/urandom` never blocks, even when the OS hasn't collected enough
//! entropy yet. To avoid returning low-entropy bytes, we first poll
//! `/dev/random` and only switch to `/dev/urandom` once this has succeeded.
//!
//! ## Error handling
//!
//! We always choose failure over returning insecure "random" bytes. In general,
//! on supported platforms, failure is highly unlikely, though not impossible.
//! If an error does occur, then it is likely that it will occur on every call to
//! `getrandom`, hence after the first successful call one can be reasonably
//! confident that no errors will occur.
//!
//! [1]: http://man7.org/linux/man-pages/man2/getrandom.2.html
//! [2]: http://man7.org/linux/man-pages/man4/urandom.4.html
//! [3]: https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
//! [6]: https://man.openbsd.org/getentropy.2
//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
//! [11]: https://fuchsia.dev/fuchsia-src/zircon/syscalls/cprng_draw
//! [12]: https://github.com/redox-os/randd/blob/master/src/main.rs
//! [14]: https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues
//! [15]: https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback
//! [16]: #webassembly-support
//! [17]: https://github.com/WebAssembly/WASI/blob/master/design/WASI-core.md#__wasi_random_get
//! [18]: https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide
//! [19]: https://www.unix.com/man-page/mojave/2/getentropy/
//! [20]: https://www.unix.com/man-page/mojave/4/random/
//! [21]: https://www.freebsd.org/cgi/man.cgi?query=getrandom&manpath=FreeBSD+12.0-stable

#![doc(
    html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
    html_favicon_url = "https://www.rust-lang.org/favicon.ico",
    html_root_url = "https://rust-random.github.io/rand/"
)]
#![no_std]
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
// `matches!` macro was added only in Rust 1.42, which is bigger than our MSRV
#![allow(clippy::match_like_matches_macro)]

#[macro_use]
extern crate cfg_if;

mod error;
mod util;
// To prevent a breaking change when targets are added, we always export the
// register_custom_getrandom macro, so old Custom RNG crates continue to build.
#[cfg(feature = "custom")]
mod custom;
#[cfg(feature = "std")]
mod error_impls;

pub use crate::error::Error;

// System-specific implementations.
//
// These should all provide getrandom_inner with the same signature as getrandom.
cfg_if! {
    if #[cfg(any(target_os = "dragonfly", target_os = "emscripten",
                 target_os = "haiku",     target_os = "redox"))] {
        mod util_libc;
        #[path = "use_file.rs"] mod imp;
    } else if #[cfg(any(target_os = "android", target_os = "linux"))] {
        mod util_libc;
        mod use_file;
        #[path = "linux_android.rs"] mod imp;
    } else if #[cfg(any(target_os = "illumos", target_os = "solaris"))] {
        mod util_libc;
        mod use_file;
        #[path = "solaris_illumos.rs"] mod imp;
    } else if #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] {
        mod util_libc;
        #[path = "bsd_arandom.rs"] mod imp;
    } else if #[cfg(target_os = "fuchsia")] {
        #[path = "fuchsia.rs"] mod imp;
    } else if #[cfg(target_os = "ios")] {
        #[path = "ios.rs"] mod imp;
    } else if #[cfg(target_os = "macos")] {
        mod util_libc;
        mod use_file;
        #[path = "macos.rs"] mod imp;
    } else if #[cfg(target_os = "openbsd")] {
        mod util_libc;
        #[path = "openbsd.rs"] mod imp;
    } else if #[cfg(target_os = "wasi")] {
        #[path = "wasi.rs"] mod imp;
    } else if #[cfg(target_os = "vxworks")] {
        mod util_libc;
        #[path = "vxworks.rs"] mod imp;
    } else if #[cfg(windows)] {
        #[path = "windows.rs"] mod imp;
    } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] {
        #[path = "rdrand.rs"] mod imp;
    } else if #[cfg(all(feature = "rdrand",
                        any(target_arch = "x86_64", target_arch = "x86")))] {
        #[path = "rdrand.rs"] mod imp;
    } else if #[cfg(all(feature = "js",
                        target_arch = "wasm32", target_os = "unknown"))] {
        #[path = "js.rs"] mod imp;
    } else if #[cfg(feature = "custom")] {
        use custom as imp;
    } else {
        compile_error!("target is not supported, for more information see: \
                        https://docs.rs/getrandom/#unsupported-targets");
    }
}

/// Fill `dest` with random bytes from the system's preferred random number
/// source.
///
/// This function returns an error on any failure, including partial reads. We
/// make no guarantees regarding the contents of `dest` on error. If `dest` is
/// empty, `getrandom` immediately returns success, making no calls to the
/// underlying operating system.
///
/// Blocking is possible, at least during early boot; see module documentation.
///
/// In general, `getrandom` will be fast enough for interactive usage, though
/// significantly slower than a user-space CSPRNG; for the latter consider
/// [`rand::thread_rng`](https://docs.rs/rand/*/rand/fn.thread_rng.html).
pub fn getrandom(dest: &mut [u8]) -> Result<(), Error> {
    if dest.is_empty() {
        return Ok(());
    }
    imp::getrandom_inner(dest)
}

#[cfg(test)]
mod test_common;
#[cfg(test)]
mod test_rdrand;
<|endoftext|>


<commit_before>#![feature(rustc_private)]
#![feature(map_first_last)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(io_error_more)]
#![feature(int_log)]
#![feature(variant_count)]
#![feature(yeet_expr)]
#![feature(is_some_and)]
#![feature(nonzero_ops)]
#![feature(local_key_cell_methods)]
// Configure clippy and other lints
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq,
    clippy::derive_hash_xor_eq,
    clippy::too_many_arguments,
    clippy::type_complexity,
    clippy::single_element_loop,
    clippy::needless_return,
    // We are not implementing queries here so it's fine
    rustc::potential_query_instability
)]
#![warn(
    rust_2018_idioms,
    clippy::cast_possible_wrap, // unsigned -> signed
    clippy::cast_sign_loss, // signed -> unsigned
    clippy::cast_lossless,
    clippy::cast_possible_truncation,
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod clock;
mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod tag_gc;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::clock::{Clock, Instant};
pub use crate::concurrency::{
    data_race::{
        AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd,
        EvalContextExt as DataRaceEvalContextExt,
    },
    sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId},
    thread::{
        EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager,
        ThreadState, Time,
    },
};
pub use crate::diagnostics::{
    report_error, EvalContextExt as DiagnosticsEvalContextExt, NonHaltingDiagnostic,
    TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, Provenance,
    ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, Stack, Stacks,
};
pub use crate::tag_gc::{EvalContextExt as _, VisitTags};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
    "-Zextra-const-ub-checks",
];
<commit_msg>Auto merge of #102926 - matthiaskrgr:rollup-oe2cdzj, r=matthiaskrgr<commit_after>#![feature(rustc_private)]
#![feature(map_try_insert)]
#![feature(never_type)]
#![feature(try_blocks)]
#![feature(io_error_more)]
#![feature(int_log)]
#![feature(variant_count)]
#![feature(yeet_expr)]
#![feature(is_some_and)]
#![feature(nonzero_ops)]
#![feature(local_key_cell_methods)]
// Configure clippy and other lints
#![allow(
    clippy::collapsible_else_if,
    clippy::collapsible_if,
    clippy::comparison_chain,
    clippy::enum_variant_names,
    clippy::field_reassign_with_default,
    clippy::manual_map,
    clippy::new_without_default,
    clippy::single_match,
    clippy::useless_format,
    clippy::derive_partial_eq_without_eq,
    clippy::derive_hash_xor_eq,
    clippy::too_many_arguments,
    clippy::type_complexity,
    clippy::single_element_loop,
    clippy::needless_return,
    // We are not implementing queries here so it's fine
    rustc::potential_query_instability
)]
#![warn(
    rust_2018_idioms,
    clippy::cast_possible_wrap, // unsigned -> signed
    clippy::cast_sign_loss, // signed -> unsigned
    clippy::cast_lossless,
    clippy::cast_possible_truncation,
)]

extern crate rustc_apfloat;
extern crate rustc_ast;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_hir;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

mod clock;
mod concurrency;
mod diagnostics;
mod eval;
mod helpers;
mod intptrcast;
mod machine;
mod mono_hash_map;
mod operator;
mod range_map;
mod shims;
mod stacked_borrows;
mod tag_gc;

// Establish a "crate-wide prelude": we often import `crate::*`.

// Make all those symbols available in the same place as our own.
pub use rustc_const_eval::interpret::*;
// Resolve ambiguity.
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};

pub use crate::shims::dlsym::{Dlsym, EvalContextExt as _};
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
pub use crate::shims::foreign_items::EvalContextExt as _;
pub use crate::shims::intrinsics::EvalContextExt as _;
pub use crate::shims::os_str::EvalContextExt as _;
pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
pub use crate::shims::time::EvalContextExt as _;
pub use crate::shims::tls::{EvalContextExt as _, TlsData};
pub use crate::shims::EvalContextExt as _;

pub use crate::clock::{Clock, Instant};
pub use crate::concurrency::{
    data_race::{
        AtomicFenceOrd, AtomicReadOrd, AtomicRwOrd, AtomicWriteOrd,
        EvalContextExt as DataRaceEvalContextExt,
    },
    sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId},
    thread::{
        EvalContextExt as ThreadsEvalContextExt, SchedulingAction, ThreadId, ThreadManager,
        ThreadState, Time,
    },
};
pub use crate::diagnostics::{
    report_error, EvalContextExt as DiagnosticsEvalContextExt, NonHaltingDiagnostic,
    TerminationInfo,
};
pub use crate::eval::{
    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
};
pub use crate::helpers::{CurrentSpan, EvalContextExt as HelpersEvalContextExt};
pub use crate::intptrcast::ProvenanceMode;
pub use crate::machine::{
    AllocExtra, FrameData, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, Provenance,
    ProvenanceExtra, PAGE_SIZE, STACK_ADDR, STACK_SIZE,
};
pub use crate::mono_hash_map::MonoHashMap;
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
pub use crate::range_map::RangeMap;
pub use crate::stacked_borrows::{
    CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, Stack, Stacks,
};
pub use crate::tag_gc::{EvalContextExt as _, VisitTags};

/// Insert rustc arguments at the beginning of the argument list that Miri wants to be
/// set per default, for maximal validation power.
pub const MIRI_DEFAULT_ARGS: &[&str] = &[
    "-Zalways-encode-mir",
    "-Zmir-emit-retag",
    "-Zmir-opt-level=0",
    "--cfg=miri",
    "-Cdebug-assertions=on",
    "-Zextra-const-ub-checks",
];
<|endoftext|>


<commit_before>
#![feature(const_ptr_offset, lang_items)]
#![feature(asm_const)]
#![feature(asm_sym)]
#![feature(allocator_api)]
#![feature(panic_info_message)]
#![feature(naked_functions)]
#![feature(abi_x86_interrupt)]
#![feature(specialization)]
#![feature(linked_list_cursors)]
#![feature(const_fn_fn_ptr_basics)]
#![no_std]

extern crate alloc;
extern crate spin;
#[cfg(target_arch = "x86_64")]
extern crate x86;
#[macro_use]
extern crate bitflags;
extern crate goblin;
extern crate num_traits;

// These need to be visible to the linker, so we need to export them.
#[cfg(target_arch = "x86_64")]
pub use arch::processor::*;
use core::panic::PanicInfo;
pub use logging::*;

#[macro_use]
pub mod macros;
#[macro_use]
pub mod logging;
pub mod arch;
pub mod collections;
pub mod console;
pub mod consts;
pub mod errno;
pub mod fs;
pub mod mm;
pub mod scheduler;
pub mod synch;
pub mod syscall;

#[global_allocator]
static ALLOCATOR: &'static mm::allocator::Allocator = &mm::allocator::Allocator;

/// This function is called on panic.
#[cfg(not(test))]
#[panic_handler]
pub fn panic(info: &PanicInfo) -> ! {
	let tid = scheduler::get_current_taskid();

	print!("[!!!PANIC from task {}!!!] ", tid);

	if let Some(location) = info.location() {
		print!("{}:{}: ", location.file(), location.line());
	}

	if let Some(message) = info.message() {
		print!("{}", message);
	}

	print!("\n");

	loop {
		halt();
	}
}
<commit_msg>minior changes to pass the format check<commit_after>#![feature(const_ptr_offset, lang_items)]
#![feature(asm_const)]
#![feature(asm_sym)]
#![feature(allocator_api)]
#![feature(panic_info_message)]
#![feature(naked_functions)]
#![feature(abi_x86_interrupt)]
#![feature(specialization)]
#![feature(linked_list_cursors)]
#![feature(const_fn_fn_ptr_basics)]
#![no_std]

extern crate alloc;
extern crate spin;
#[cfg(target_arch = "x86_64")]
extern crate x86;
#[macro_use]
extern crate bitflags;
extern crate goblin;
extern crate num_traits;

// These need to be visible to the linker, so we need to export them.
#[cfg(target_arch = "x86_64")]
pub use arch::processor::*;
use core::panic::PanicInfo;
pub use logging::*;

#[macro_use]
pub mod macros;
#[macro_use]
pub mod logging;
pub mod arch;
pub mod collections;
pub mod console;
pub mod consts;
pub mod errno;
pub mod fs;
pub mod mm;
pub mod scheduler;
pub mod synch;
pub mod syscall;

#[global_allocator]
static ALLOCATOR: &'static mm::allocator::Allocator = &mm::allocator::Allocator;

/// This function is called on panic.
#[cfg(not(test))]
#[panic_handler]
pub fn panic(info: &PanicInfo) -> ! {
	let tid = scheduler::get_current_taskid();

	print!("[!!!PANIC from task {}!!!] ", tid);

	if let Some(location) = info.location() {
		print!("{}:{}: ", location.file(), location.line());
	}

	if let Some(message) = info.message() {
		print!("{}", message);
	}

	print!("\n");

	loop {
		halt();
	}
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>feat(lib): add pginterval for a 1 to 1 mapping between rust and postgres<commit_after>#[derive(Debug)]
/// The wire format that postgres sends intervals in. Shouldn't be used directly.
pub struct PgInterval {
  months: i32
  days: i32,
  microseconds: i64,
}

impl PgInterval {
    /// Construct a new instance of a PgInterval.
    pub fn new(months: i32, days: i32, microseconds: i64) -> PgInterval {
        PgInterval {
            months: months,
            days: days,
            microseconds: days
        }
    }
}
<|endoftext|>