<commit_before>// Functionality that is shared between the cxx_build::bridge entry point and
// the cxxbridge CLI command.

mod error;
mod file;
pub(super) mod include;
pub(super) mod out;
mod write;

#[cfg(test)]
mod tests;

pub(super) use self::error::Error;
use self::error::{format_err, Result};
use self::file::File;
use crate::syntax::report::Errors;
use crate::syntax::{self, check, Types};
use std::clone::Clone;
use std::fs;
use std::path::Path;

/// Options for C++ code generation.
#[derive(Default, Clone)]
pub struct Opt {
    /// Any additional headers to #include
    pub include: Vec<String>,
    /// Whether to set __attribute__((visibility("default")))
    /// or similar annotations on function implementations.
    pub cxx_impl_annotations: Option<String>,
}

pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
    let header = false;
    generate_from_path(path, opt, header)
}

pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
    let header = true;
    generate_from_path(path, opt, header)
}

fn generate_from_path(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
    let source = match fs::read_to_string(path) {
        Ok(source) => source,
        Err(err) => format_err(path, "", Error::Io(err)),
    };
    match generate_from_string(&source, opt, header) {
        Ok(out) => out,
        Err(err) => format_err(path, &source, err),
    }
}

fn generate_from_string(source: &str, opt: Opt, header: bool) -> Result<Vec<u8>> {
    let mut source = source;
    if source.starts_with("#!") && !source.starts_with("#![") {
        let shebang_end = source.find('\n').unwrap_or(source.len());
        source = &source[shebang_end..];
    }
    let syntax: File = syn::parse_str(source)?;
    let results = generate(syntax, opt, header, !header)?;
    match results {
        (Some(hdr), None) => Ok(hdr),
        (None, Some(cxx)) => Ok(cxx),
        _ => panic!("Unexpected generation"),
    }
}

pub(super) fn generate(
    syntax: File,
    opt: Opt,
    gen_header: bool,
    gen_cxx: bool,
) -> Result<(Option<Vec<u8>>, Option<Vec<u8>>)> {
    proc_macro2::fallback::force();
    let ref mut errors = Errors::new();
    let bridge = syntax
        .modules
        .into_iter()
        .next()
        .ok_or(Error::NoBridgeMod)?;
    let ref namespace = bridge.namespace;
    let trusted = bridge.unsafety.is_some();
    let ref apis = syntax::parse_items(errors, bridge.content, trusted);
    let ref types = Types::collect(errors, apis);
    errors.propagate()?;
    check::typecheck(errors, namespace, apis, types);
    errors.propagate()?;
    // Some callers may wish to generate both header and C++
    // from the same token stream to avoid parsing twice. But others
    // only need to generate one or the other.
    let hdr = if gen_header {
        Some(write::gen(namespace, apis, types, opt.clone(), true).content())
    } else {
        None
    };
    let cxx = if gen_cxx {
        Some(write::gen(namespace, apis, types, opt, false).content())
    } else {
        None
    };
    Ok((hdr, cxx))
}
<commit_msg>Make code generator options non-exhaustive<commit_after>// Functionality that is shared between the cxx_build::bridge entry point and
// the cxxbridge CLI command.

mod error;
mod file;
pub(super) mod include;
pub(super) mod out;
mod write;

#[cfg(test)]
mod tests;

pub(super) use self::error::Error;
use self::error::{format_err, Result};
use self::file::File;
use crate::syntax::report::Errors;
use crate::syntax::{self, check, Types};
use std::clone::Clone;
use std::fs;
use std::path::Path;

/// Options for C++ code generation.
///
/// We expect options to be added over time, so this is a non-exhaustive struct.
/// To instantiate one you need to crate a default value and mutate those fields
/// that you want to modify.
///
/// ```
/// # use cxx_gen::Opt;
/// #
/// let impl_annotations = r#"__attribute__((visibility("default")))"#.to_owned();
///
/// let mut opt = Opt::default();
/// opt.cxx_impl_annotations = Some(impl_annotations);
/// ```
#[derive(Default, Clone)]
#[non_exhaustive]
pub struct Opt {
    /// Any additional headers to #include
    pub include: Vec<String>,
    /// Whether to set __attribute__((visibility("default")))
    /// or similar annotations on function implementations.
    pub cxx_impl_annotations: Option<String>,
}

pub(super) fn do_generate_bridge(path: &Path, opt: Opt) -> Vec<u8> {
    let header = false;
    generate_from_path(path, opt, header)
}

pub(super) fn do_generate_header(path: &Path, opt: Opt) -> Vec<u8> {
    let header = true;
    generate_from_path(path, opt, header)
}

fn generate_from_path(path: &Path, opt: Opt, header: bool) -> Vec<u8> {
    let source = match fs::read_to_string(path) {
        Ok(source) => source,
        Err(err) => format_err(path, "", Error::Io(err)),
    };
    match generate_from_string(&source, opt, header) {
        Ok(out) => out,
        Err(err) => format_err(path, &source, err),
    }
}

fn generate_from_string(source: &str, opt: Opt, header: bool) -> Result<Vec<u8>> {
    let mut source = source;
    if source.starts_with("#!") && !source.starts_with("#![") {
        let shebang_end = source.find('\n').unwrap_or(source.len());
        source = &source[shebang_end..];
    }
    let syntax: File = syn::parse_str(source)?;
    let results = generate(syntax, opt, header, !header)?;
    match results {
        (Some(hdr), None) => Ok(hdr),
        (None, Some(cxx)) => Ok(cxx),
        _ => panic!("Unexpected generation"),
    }
}

pub(super) fn generate(
    syntax: File,
    opt: Opt,
    gen_header: bool,
    gen_cxx: bool,
) -> Result<(Option<Vec<u8>>, Option<Vec<u8>>)> {
    proc_macro2::fallback::force();
    let ref mut errors = Errors::new();
    let bridge = syntax
        .modules
        .into_iter()
        .next()
        .ok_or(Error::NoBridgeMod)?;
    let ref namespace = bridge.namespace;
    let trusted = bridge.unsafety.is_some();
    let ref apis = syntax::parse_items(errors, bridge.content, trusted);
    let ref types = Types::collect(errors, apis);
    errors.propagate()?;
    check::typecheck(errors, namespace, apis, types);
    errors.propagate()?;
    // Some callers may wish to generate both header and C++
    // from the same token stream to avoid parsing twice. But others
    // only need to generate one or the other.
    let hdr = if gen_header {
        Some(write::gen(namespace, apis, types, opt.clone(), true).content())
    } else {
        None
    };
    let cxx = if gen_cxx {
        Some(write::gen(namespace, apis, types, opt, false).content())
    } else {
        None
    };
    Ok((hdr, cxx))
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{convert::TryInto, fs::File, io::Write, path::Path};

use assert_cmd::Command;
use tempdir::TempDir;

static MAIN_RS: &str = include_str!("../../../demo/src/main.rs");
static INPUT_H: &str = include_str!("../../../demo/src/input.h");

#[test]
fn test_help() -> Result<(), Box<dyn std::error::Error>> {
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("-h").assert().success();
    Ok(())
}

#[test]
fn test_gen() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let demo_code_dir = tmp_dir.path().join("demo");
    std::fs::create_dir(&demo_code_dir).unwrap();
    write_to_file(&demo_code_dir, "input.h", INPUT_H.as_bytes());
    write_to_file(&demo_code_dir, "main.rs", MAIN_RS.as_bytes());
    let demo_rs = demo_code_dir.join("main.rs");
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("--inc")
        .arg(demo_code_dir.to_str().unwrap())
        .arg(demo_rs)
        .arg("--outdir")
        .arg(tmp_dir.path().to_str().unwrap())
        .arg("--gen-cpp")
        .arg("--gen-rs-include")
        .assert()
        .success();
    assert_contentful(&tmp_dir, "gen0.cc");
    Ok(())
}

#[test]
fn test_gen_fixed_num() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let demo_code_dir = tmp_dir.path().join("demo");
    std::fs::create_dir(&demo_code_dir).unwrap();
    write_to_file(&demo_code_dir, "input.h", INPUT_H.as_bytes());
    write_to_file(&demo_code_dir, "main.rs", MAIN_RS.as_bytes());
    let demo_rs = demo_code_dir.join("main.rs");
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("-I")
        .arg(demo_code_dir.to_str().unwrap())
        .arg(demo_rs)
        .arg("--outdir")
        .arg(tmp_dir.path().to_str().unwrap())
        .arg("--gen-cpp")
        .arg("--gen-rs-include")
        .arg("--generate-exact")
        .arg("3")
        .arg("--fix-rs-include-name")
        .assert()
        .success();
    assert_contentful(&tmp_dir, "gen0.cc");
    assert_exists(&tmp_dir, "gen1.cc");
    assert_exists(&tmp_dir, "gen2.cc");
    assert_contentful(&tmp_dir, "gen0.include.rs");
    assert_exists(&tmp_dir, "gen1.include.rs");
    assert_exists(&tmp_dir, "gen2.include.rs");
    Ok(())
}

fn write_to_file(dir: &Path, filename: &str, content: &[u8]) {
    let path = dir.join(filename);
    let mut f = File::create(&path).expect("Unable to create file");
    f.write_all(content).expect("Unable to write file");
}

fn assert_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(p.metadata().unwrap().len() > super::BLANK.len().try_into().unwrap());
}

fn assert_exists(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
}
<commit_msg>Remove duplication from test_gen.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{convert::TryInto, fs::File, io::Write, path::Path};

use assert_cmd::Command;
use tempdir::TempDir;

static MAIN_RS: &str = include_str!("../../../demo/src/main.rs");
static INPUT_H: &str = include_str!("../../../demo/src/input.h");

#[test]
fn test_help() -> Result<(), Box<dyn std::error::Error>> {
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("-h").assert().success();
    Ok(())
}

fn base_test<F>(tmp_dir: &TempDir, arg_modifier: F) -> Result<(), Box<dyn std::error::Error>>
where
    F: FnOnce(&mut Command),
{
    let demo_code_dir = tmp_dir.path().join("demo");
    std::fs::create_dir(&demo_code_dir).unwrap();
    write_to_file(&demo_code_dir, "input.h", INPUT_H.as_bytes());
    write_to_file(&demo_code_dir, "main.rs", MAIN_RS.as_bytes());
    let demo_rs = demo_code_dir.join("main.rs");
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    arg_modifier(&mut cmd);
    cmd.arg("--inc")
        .arg(demo_code_dir.to_str().unwrap())
        .arg(demo_rs)
        .arg("--outdir")
        .arg(tmp_dir.path().to_str().unwrap())
        .arg("--gen-cpp")
        .arg("--gen-rs-include")
        .assert()
        .success();
    assert_contentful(&tmp_dir, "gen0.cc");
    Ok(())
}

#[test]
fn test_gen() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, |_| {})
}

#[test]
fn test_gen_fixed_num() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, |cmd| {
        cmd.arg("--generate-exact")
            .arg("3")
            .arg("--fix-rs-include-name");
    })?;
    assert_contentful(&tmp_dir, "gen0.cc");
    assert_exists(&tmp_dir, "gen1.cc");
    assert_exists(&tmp_dir, "gen2.cc");
    assert_contentful(&tmp_dir, "gen0.include.rs");
    assert_exists(&tmp_dir, "gen1.include.rs");
    assert_exists(&tmp_dir, "gen2.include.rs");
    Ok(())
}

fn write_to_file(dir: &Path, filename: &str, content: &[u8]) {
    let path = dir.join(filename);
    let mut f = File::create(&path).expect("Unable to create file");
    f.write_all(content).expect("Unable to write file");
}

fn assert_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(p.metadata().unwrap().len() > super::BLANK.len().try_into().unwrap());
}

fn assert_exists(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
}
<|endoftext|>


<commit_before>use ::serde_json;
use ::zip;
use std::collections::HashMap;

#[derive(Serialize, Debug)]
struct MultiArchiveJsonWriter<'a> {
    archives: HashMap<&'a str, &'a ZipArchiveJsonWriter<'a>>,
}

#[derive(Serialize, Debug, PartialEq)]
struct ZipArchiveJsonWriter<'a> {
    objects: HashMap<&'a str, &'a ZipObjectJsonWriter>,
}

impl<'a> ZipArchiveJsonWriter<'a> {
    pub fn new() -> ZipArchiveJsonWriter<'a> {
        ZipArchiveJsonWriter { objects: HashMap::new() }
    }
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct ZipObjectJsonWriter {
    compression_type: String,
    original_size: u64,
    compressed_size: u64,
    compression_rate: String,
}

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

    fn get_zip_object() -> ZipObjectJsonWriter {
        ZipObjectJsonWriter {
            compression_type: format!("{}", zip::CompressionMethod::Deflated),
            original_size: 100,
            compressed_size: 50,
            compression_rate: String::from("50%"),
        }
    }

    #[test]
    fn test_serialize_object_json_writer() {
        let zip_object = get_zip_object();

        let zip_object_serialized = serde_json::to_string(&zip_object)
            .unwrap();

        let zip_object_pretty = serde_json::
            to_string_pretty(&zip_object).unwrap();

        let zip_object_deserialized: ZipObjectJsonWriter =
            serde_json::from_str(zip_object_serialized.as_str()).unwrap();

        let zip_object_depretty: ZipObjectJsonWriter =
            serde_json::from_str(zip_object_pretty.as_str()).unwrap();

        assert_eq!(zip_object, zip_object_deserialized);
        assert_eq!(zip_object, zip_object_depretty);
    }

    #[test]
    fn test_new_archive_has_empty_map_of_zip_objects() {
        let zip_archive = ZipArchiveJsonWriter::new();
        let empty_hashmap: HashMap<&str, &ZipObjectJsonWriter> =
            HashMap::new();

        assert_eq!(empty_hashmap, zip_archive.objects);
    }

    #[test]
    fn test_serialize_archive_json_writer() {
        //let mut zip_archive = ZipArchiveJsonWriter::new();
        //let zip_object_name = "foo.txt";
        //let zip_object = get_zip_object();

        //zip_archive.objects.insert(zip_object_name, &zip_object);
    }
}
<commit_msg>Progress on testing serialization for ZipArchiveJsonWriter<commit_after>use ::serde_json;
use ::zip;
use std::collections::HashMap;

#[derive(Serialize, Debug)]
struct MultiArchiveJsonWriter<'a> {
    archives: HashMap<&'a str, &'a ZipArchiveJsonWriter<'a>>,
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct ZipArchiveJsonWriter<'a> {
    objects: HashMap<&'a str, &'a ZipObjectJsonWriter>,
}

impl<'a> ZipArchiveJsonWriter<'a> {
    pub fn new() -> ZipArchiveJsonWriter<'a> {
        ZipArchiveJsonWriter { objects: HashMap::new() }
    }
}

#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct ZipObjectJsonWriter {
    compression_type: String,
    original_size: u64,
    compressed_size: u64,
    compression_rate: String,
}

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

    fn get_zip_object() -> ZipObjectJsonWriter {
        ZipObjectJsonWriter {
            compression_type: format!("{}", zip::CompressionMethod::Deflated),
            original_size: 100,
            compressed_size: 50,
            compression_rate: String::from("50%"),
        }
    }

    #[test]
    fn test_serialize_object_json_writer() {
        let zip_object = get_zip_object();

        let zip_object_serialized = serde_json::to_string(&zip_object)
            .unwrap();

        let zip_object_pretty = serde_json::
            to_string_pretty(&zip_object).unwrap();

        let zip_object_deserialized: ZipObjectJsonWriter =
            serde_json::from_str(zip_object_serialized.as_str()).unwrap();

        let zip_object_depretty: ZipObjectJsonWriter =
            serde_json::from_str(zip_object_pretty.as_str()).unwrap();

        assert_eq!(zip_object, zip_object_deserialized);
        assert_eq!(zip_object, zip_object_depretty);
    }

    #[test]
    fn test_new_archive_has_empty_map_of_zip_objects() {
        let zip_archive = ZipArchiveJsonWriter::new();
        let empty_hashmap: HashMap<&str, &ZipObjectJsonWriter> =
            HashMap::new();

        assert_eq!(empty_hashmap, zip_archive.objects);
    }

    #[test]
    fn test_serialize_archive_json_writer() {
        let zip_object_name = "foo.txt";
        let zip_object = get_zip_object();

        {
            let mut zip_archive = ZipArchiveJsonWriter::new();
            zip_archive.objects.insert(zip_object_name, &zip_object);

            let zip_archive_serialized = serde_json::to_string(&zip_archive)
                .unwrap();
            println!("zip_archive_serialized: {}", zip_archive_serialized);

            let zip_archive_pretty = serde_json::to_string_pretty(&zip_archive)
                .unwrap();
            println!("zip_archive_pretty: {}", zip_archive_pretty);

            let zip_archive_deserialized: ZipArchiveJsonWriter =
                serde_json::from_str(zip_archive_serialized.as_str()).unwrap();

            //let zip_archive_depretty: ZipArchiveJsonWriter =
            //    serde_json::from_str(zip_archive_serialized.as_str()).unwrap();

            //assert_eq!(zip_archive, zip_archive_deserialized);
            //assert_eq!(zip_archive, zip_archive_depretty);
        }
    }
}
<|endoftext|>


<commit_before>// copyright 2017 Kaz Wesley

//! Classic Blake in a Rustic setting

#![no_std]

extern crate block_buffer;
pub extern crate digest;

mod consts;

use block_buffer::BlockBuffer;
use core::mem;
use digest::generic_array::GenericArray;
pub use digest::Digest;

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct State<T> {
    h: [T; 8],
    t: [T; 2],
    nullt: bool,
}

macro_rules! define_compressor {
    ($compressor:ident, $word:ident, $Bufsz:ty, $deserializer:path, $uval:expr,
     $rounds:expr, $shift0:expr, $shift1:expr, $shift2: expr, $shift3: expr) => {
        #[derive(Clone, Copy, Debug)]
        struct $compressor {
            state: State<$word>,
        }

        impl $compressor {
            fn increase_count(&mut self, count: $word) {
                let (new_t0, carry) = self.state.t[0].overflowing_add(count * 8);
                self.state.t[0] = new_t0;
                if carry {
                    self.state.t[1] += 1;
                }
            }

            fn put_block(&mut self, block: &GenericArray<u8, $Bufsz>) {
                const U: [$word; 16] = $uval;

                #[inline(always)]
                fn g(
                    v: &mut [$word; 16],
                    m: &[$word; 16],
                    sigma: &[u8; 16],
                    a: usize,
                    b: usize,
                    c: usize,
                    d: usize,
                    e: usize,
                ) {
                    v[a] = v[a]
                        .wrapping_add(m[sigma[e] as usize] ^ U[sigma[e + 1] as usize])
                        .wrapping_add(v[b]);
                    v[d] = (v[d] ^ v[a]).rotate_right($shift0);
                    v[c] = v[c].wrapping_add(v[d]);
                    v[b] = (v[b] ^ v[c]).rotate_right($shift1);
                    v[a] = v[a]
                        .wrapping_add(m[sigma[e + 1] as usize] ^ U[sigma[e] as usize])
                        .wrapping_add(v[b]);
                    v[d] = (v[d] ^ v[a]).rotate_right($shift2);
                    v[c] = v[c].wrapping_add(v[d]);
                    v[b] = (v[b] ^ v[c]).rotate_right($shift3);
                }

                let mut m = [0; 16];
                for (mx, b) in m
                    .iter_mut()
                    .zip(block.chunks_exact(mem::size_of::<$word>()))
                {
                    *mx = $deserializer(b);
                }

                let mut v = [0; 16];
                &v[..8].copy_from_slice(&self.state.h);
                &v[8..].copy_from_slice(&U[..8]);

                // don't xor t when the block is only padding
                if !self.state.nullt {
                    v[12] ^= self.state.t[0];
                    v[13] ^= self.state.t[0];
                    v[14] ^= self.state.t[1];
                    v[15] ^= self.state.t[1];
                }

                for sigma in &SIGMA[..$rounds] {
                    // column step
                    g(&mut v, &m, sigma, 0, 4, 8, 12, 0);
                    g(&mut v, &m, sigma, 1, 5, 9, 13, 2);
                    g(&mut v, &m, sigma, 2, 6, 10, 14, 4);
                    g(&mut v, &m, sigma, 3, 7, 11, 15, 6);
                    // diagonal step
                    g(&mut v, &m, sigma, 0, 5, 10, 15, 8);
                    g(&mut v, &m, sigma, 1, 6, 11, 12, 10);
                    g(&mut v, &m, sigma, 2, 7, 8, 13, 12);
                    g(&mut v, &m, sigma, 3, 4, 9, 14, 14);
                }

                for (i, vx) in v.iter().enumerate() {
                    self.state.h[i % 8] ^= *vx;
                }
            }
        }
    };
}

macro_rules! define_hasher {
    ($name:ident, $word:ident, $buf:expr, $Bufsz:ty, $bits:expr, $Bytes:ident,
     $serializer:path, $compressor:ident, $iv:expr) => {
        #[derive(Clone)]
        pub struct $name {
            compressor: $compressor,
            buffer: BlockBuffer<$Bufsz>,
        }

        impl core::fmt::Debug for $name {
            fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
                f.debug_struct("Blake")
                    .field("compressor", &self.compressor)
                    .field("buffer.position()", &self.buffer.position())
                    .finish()
            }
        }

        impl Default for $name {
            fn default() -> Self {
                Self {
                    compressor: $compressor {
                        state: State::<$word> {
                            h: $iv,
                            t: [0; 2],
                            nullt: false,
                        },
                    },
                    buffer: BlockBuffer::default(),
                }
            }
        }

        impl digest::BlockInput for $name {
            type BlockSize = $Bytes;
        }

        impl digest::Input for $name {
            fn input<T: AsRef<[u8]>>(&mut self, data: T) {
                let compressor = &mut self.compressor;
                self.buffer.input(data.as_ref(), |block| {
                    compressor.increase_count((mem::size_of::<$word>() * 16) as $word);
                    compressor.put_block(block);
                });
            }
        }

        impl digest::FixedOutput for $name {
            type OutputSize = $Bytes;

            fn fixed_result(self) -> GenericArray<u8, $Bytes> {
                let mut compressor = self.compressor;
                let mut buffer = self.buffer;

                compressor.increase_count(buffer.position() as $word);

                let mut msglen = [0u8; $buf / 8];
                $serializer(&mut msglen[..$buf / 16], compressor.state.t[1]);
                $serializer(&mut msglen[$buf / 16..], compressor.state.t[0]);

                let footerlen = 1 + 2 * mem::size_of::<$word>();

                // low bit indicates full-length variant
                let isfull = ($bits == 8 * mem::size_of::<[$word; 8]>()) as u8;
                // high bit indicates fit with no padding
                let exactfit = if buffer.position() + footerlen != $buf {
                    0x00
                } else {
                    0x80
                };
                let magic = isfull | exactfit;

                // if header won't fit in last data block, pad to the end and start a new one
                let extra_block = buffer.position() + footerlen > $buf;
                if extra_block {
                    let pad = $buf - buffer.position();
                    buffer.input(&PADDING[..pad], |block| compressor.put_block(block));
                    debug_assert_eq!(buffer.position(), 0);
                }

                // pad last block up to footer start point
                compressor.state.nullt = buffer.position() == 0;
                // skip begin-padding byte if continuing padding
                let x = extra_block as usize;
                let (start, end) = (x, x + ($buf - footerlen - buffer.position()));
                buffer.input(&PADDING[start..end], |_| unreachable!());
                buffer.input(&[magic], |_| unreachable!());
                buffer.input(&msglen, |block| compressor.put_block(block));
                debug_assert_eq!(buffer.position(), 0);

                let mut out = GenericArray::default();
                for (h, out) in compressor
                    .state
                    .h
                    .iter()
                    .zip(out.chunks_exact_mut(mem::size_of::<$word>()))
                {
                    $serializer(out, *h);
                }
                out
            }
        }

        impl digest::Reset for $name {
            fn reset(&mut self) {
                *self = Self::default()
            }
        }
    };
}

use block_buffer::byteorder::{ByteOrder, BE};
use consts::{
    BLAKE224_IV, BLAKE256_IV, BLAKE256_U, BLAKE384_IV, BLAKE512_IV, BLAKE512_U, PADDING, SIGMA,
};
use digest::generic_array::typenum::{U128, U28, U32, U48, U64};

#[cfg_attr(rustfmt, rustfmt_skip)]
define_compressor!(Compressor256, u32, U64, BE::read_u32, BLAKE256_U, 14, 16, 12, 8, 7);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake224, u32, 64, U64, 224, U28, BE::write_u32, Compressor256, BLAKE224_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake256, u32, 64, U64, 256, U32, BE::write_u32, Compressor256, BLAKE256_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_compressor!(Compressor512, u64, U128, BE::read_u64, BLAKE512_U, 16, 32, 25, 16, 11);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake384, u64, 128, U128, 384, U48, BE::write_u64, Compressor512, BLAKE384_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake512, u64, 128, U128, 512, U64, BE::write_u64, Compressor512, BLAKE512_IV);
<commit_msg>obviate nullt<commit_after>// copyright 2017 Kaz Wesley

//! Classic Blake in a Rustic setting

#![no_std]

extern crate block_buffer;
pub extern crate digest;

mod consts;

use block_buffer::BlockBuffer;
use core::mem;
use digest::generic_array::GenericArray;
pub use digest::Digest;

#[derive(Debug, Clone, Copy)]
#[repr(C)]
struct State<T> {
    h: [T; 8],
}

macro_rules! define_compressor {
    ($compressor:ident, $word:ident, $Bufsz:ty, $deserializer:path, $uval:expr,
     $rounds:expr, $shift0:expr, $shift1:expr, $shift2: expr, $shift3: expr) => {
        #[derive(Clone, Copy, Debug)]
        struct $compressor {
            state: State<$word>,
        }

        impl $compressor {
            fn put_block(&mut self, block: &GenericArray<u8, $Bufsz>, t: ($word, $word)) {
                const U: [$word; 16] = $uval;

                #[inline(always)]
                fn g(
                    v: &mut [$word; 16],
                    m: &[$word; 16],
                    sigma: &[u8; 16],
                    a: usize,
                    b: usize,
                    c: usize,
                    d: usize,
                    e: usize,
                ) {
                    v[a] = v[a]
                        .wrapping_add(m[sigma[e] as usize] ^ U[sigma[e + 1] as usize])
                        .wrapping_add(v[b]);
                    v[d] = (v[d] ^ v[a]).rotate_right($shift0);
                    v[c] = v[c].wrapping_add(v[d]);
                    v[b] = (v[b] ^ v[c]).rotate_right($shift1);
                    v[a] = v[a]
                        .wrapping_add(m[sigma[e + 1] as usize] ^ U[sigma[e] as usize])
                        .wrapping_add(v[b]);
                    v[d] = (v[d] ^ v[a]).rotate_right($shift2);
                    v[c] = v[c].wrapping_add(v[d]);
                    v[b] = (v[b] ^ v[c]).rotate_right($shift3);
                }

                let mut m = [0; 16];
                for (mx, b) in m
                    .iter_mut()
                    .zip(block.chunks_exact(mem::size_of::<$word>()))
                {
                    *mx = $deserializer(b);
                }

                let mut v = [0; 16];
                &v[..8].copy_from_slice(&self.state.h);
                &v[8..].copy_from_slice(&U[..8]);

                v[12] ^= t.0;
                v[13] ^= t.0;
                v[14] ^= t.1;
                v[15] ^= t.1;

                for sigma in &SIGMA[..$rounds] {
                    // column step
                    g(&mut v, &m, sigma, 0, 4, 8, 12, 0);
                    g(&mut v, &m, sigma, 1, 5, 9, 13, 2);
                    g(&mut v, &m, sigma, 2, 6, 10, 14, 4);
                    g(&mut v, &m, sigma, 3, 7, 11, 15, 6);
                    // diagonal step
                    g(&mut v, &m, sigma, 0, 5, 10, 15, 8);
                    g(&mut v, &m, sigma, 1, 6, 11, 12, 10);
                    g(&mut v, &m, sigma, 2, 7, 8, 13, 12);
                    g(&mut v, &m, sigma, 3, 4, 9, 14, 14);
                }

                for (i, vx) in v.iter().enumerate() {
                    self.state.h[i % 8] ^= *vx;
                }
            }
        }
    };
}

macro_rules! define_hasher {
    ($name:ident, $word:ident, $buf:expr, $Bufsz:ty, $bits:expr, $Bytes:ident,
     $serializer:path, $compressor:ident, $iv:expr) => {
        #[derive(Clone)]
        pub struct $name {
            compressor: $compressor,
            buffer: BlockBuffer<$Bufsz>,
            t: ($word, $word),
        }

        impl $name {
            fn increase_count(t: &mut ($word, $word), count: $word) {
                let (new_t0, carry) = t.0.overflowing_add(count * 8);
                t.0 = new_t0;
                if carry {
                    t.1 += 1;
                }
            }
        }

        impl core::fmt::Debug for $name {
            fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
                f.debug_struct("Blake")
                    .field("compressor", &self.compressor)
                    .field("buffer.position()", &self.buffer.position())
                    .finish()
            }
        }

        impl Default for $name {
            fn default() -> Self {
                Self {
                    compressor: $compressor {
                        state: State::<$word> { h: $iv },
                    },
                    buffer: BlockBuffer::default(),
                    t: (0, 0),
                }
            }
        }

        impl digest::BlockInput for $name {
            type BlockSize = $Bytes;
        }

        impl digest::Input for $name {
            fn input<T: AsRef<[u8]>>(&mut self, data: T) {
                let compressor = &mut self.compressor;
                let t = &mut self.t;
                self.buffer.input(data.as_ref(), |block| {
                    Self::increase_count(t, (mem::size_of::<$word>() * 16) as $word);
                    compressor.put_block(block, *t);
                });
            }
        }

        impl digest::FixedOutput for $name {
            type OutputSize = $Bytes;

            fn fixed_result(self) -> GenericArray<u8, $Bytes> {
                let mut compressor = self.compressor;
                let mut buffer = self.buffer;
                let mut t = self.t;

                Self::increase_count(&mut t, buffer.position() as $word);

                let mut msglen = [0u8; $buf / 8];
                $serializer(&mut msglen[..$buf / 16], t.1);
                $serializer(&mut msglen[$buf / 16..], t.0);

                let footerlen = 1 + 2 * mem::size_of::<$word>();

                // low bit indicates full-length variant
                let isfull = ($bits == 8 * mem::size_of::<[$word; 8]>()) as u8;
                // high bit indicates fit with no padding
                let exactfit = if buffer.position() + footerlen != $buf {
                    0x00
                } else {
                    0x80
                };
                let magic = isfull | exactfit;

                // if header won't fit in last data block, pad to the end and start a new one
                let extra_block = buffer.position() + footerlen > $buf;
                if extra_block {
                    let pad = $buf - buffer.position();
                    buffer.input(&PADDING[..pad], |block| compressor.put_block(block, t));
                    debug_assert_eq!(buffer.position(), 0);
                }

                // pad last block up to footer start point
                if buffer.position() == 0 {
                    // don't xor t when the block is only padding
                    t = (0, 0);
                }
                // skip begin-padding byte if continuing padding
                let x = extra_block as usize;
                let (start, end) = (x, x + ($buf - footerlen - buffer.position()));
                buffer.input(&PADDING[start..end], |_| unreachable!());
                buffer.input(&[magic], |_| unreachable!());
                buffer.input(&msglen, |block| compressor.put_block(block, t));
                debug_assert_eq!(buffer.position(), 0);

                let mut out = GenericArray::default();
                for (h, out) in compressor
                    .state
                    .h
                    .iter()
                    .zip(out.chunks_exact_mut(mem::size_of::<$word>()))
                {
                    $serializer(out, *h);
                }
                out
            }
        }

        impl digest::Reset for $name {
            fn reset(&mut self) {
                *self = Self::default()
            }
        }
    };
}

use block_buffer::byteorder::{ByteOrder, BE};
use consts::{
    BLAKE224_IV, BLAKE256_IV, BLAKE256_U, BLAKE384_IV, BLAKE512_IV, BLAKE512_U, PADDING, SIGMA,
};
use digest::generic_array::typenum::{U128, U28, U32, U48, U64};

#[cfg_attr(rustfmt, rustfmt_skip)]
define_compressor!(Compressor256, u32, U64, BE::read_u32, BLAKE256_U, 14, 16, 12, 8, 7);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake224, u32, 64, U64, 224, U28, BE::write_u32, Compressor256, BLAKE224_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake256, u32, 64, U64, 256, U32, BE::write_u32, Compressor256, BLAKE256_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_compressor!(Compressor512, u64, U128, BE::read_u64, BLAKE512_U, 16, 32, 25, 16, 11);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake384, u64, 128, U128, 384, U48, BE::write_u64, Compressor512, BLAKE384_IV);

#[cfg_attr(rustfmt, rustfmt_skip)]
define_hasher!(Blake512, u64, 128, U128, 512, U64, BE::write_u64, Compressor512, BLAKE512_IV);
<|endoftext|>


<commit_before>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::handle::{WlcView, WlcOutput};

pub type TreeResult = Result<(), TryLockError<MutexGuard<'static, Tree>>>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

pub struct Tree {
    root: Node,
    active_container: *const Node,
}

unsafe impl Send for Tree {}

impl Tree {
    /// Returns the currently viewed container.
    /// If multiple views are selected, the parent container they share is returned
    fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    /// Get the monitor (output) that the active container is located on
    fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            node.get_ancestor_of_type(ContainerType::Output)
        } else {
            None
        }
    }

    /// Get the workspace that the active container is located on
    fn get_current_workspace(&self) -> Option<&mut Node> {
        if let Some(container) = self.get_active_container() {
            //if let Some(child) = container.get_ancestor_of_type(ContainerType::Workspace) {
            //return child.get_children()[0].get_parent()

            //}
            // NOTE hack here, remove commented code above to make this work properly
            let parent = container.get_parent().expect(ERR_BAD_TREE);
            for child in parent.get_children_mut() {
                if child == container {
                    return Some(child);
                }
            }
        }
        return None
    }

    /// Find the workspace node that has the given name
    fn get_workspace_by_name(&self, name: &str) -> Option<&Node> {
        for child in self.root.get_children()[0].get_children() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Find the workspace node that has the given name, with a mutable reference
    fn get_workspace_by_name_mut(&mut self, name: &str) -> Option<&mut Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Make a new output container with the given WlcOutput.
    /// This is done when a new monitor is added
    fn add_output(&mut self, wlc_output: WlcOutput) {
        self.root.new_child(Container::new_output(wlc_output));
    }

    /// Make a new workspace container with the given name.
    fn add_workspace(&mut self, name: String) {
        let workspace = Container::new_workspace(name.to_string());
        let mut index = 0;
        if let Some(output) = self.get_active_output() {
            for (cur_index, child) in self.root.get_children().iter().enumerate() {
                if child == output {
                    index = cur_index;
                    break;
                }
            }
        }
        self.root.get_children_mut()[index].new_child(workspace);
    }

    /// Make a new view container with the given WlcView, and adds it to
    /// the active workspace.
    fn add_view(&self, wlc_view: WlcView) {
        if let Some(current_workspace) = self.get_current_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            current_workspace.new_child(Container::new_view(wlc_view));
        }
    }

    /// Remove the view container with the given view
    fn remove_view(&self, wlc_view: &WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

pub fn add_output(wlc_output: WlcOutput) -> TreeResult {
    {
        let mut tree = try!(TREE.try_lock());
        tree.add_output(wlc_output);
    }
    try!(add_workspace("1".to_string()));
    try!(switch_workspace(&"1"));
    Ok(())
}

pub fn add_workspace(name: String) -> TreeResult {
    trace!("Adding new workspace to root");
    let mut tree = try!(TREE.lock());
    tree.add_workspace(name);
    Ok(())
}

pub fn add_view(wlc_view: WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.add_view(wlc_view);
    Ok(())
}

pub fn remove_view(wlc_view: &WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.remove_view(wlc_view);
    Ok(())
}

pub fn switch_workspace(name: &str) -> TreeResult {
    trace!("Switching to workspace {}", name);
    let mut tree = try!(TREE.lock());
    if let Some(old_workspace) = tree.get_current_workspace() {
        old_workspace.set_visibility(false);
    }
    let current_workspace: *const Node;
    {
        if let Some(_) = tree.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            tree.add_workspace(name.to_string());
        }
        let new_current_workspace = tree.get_workspace_by_name_mut(name).expect(ERR_BAD_TREE);
        new_current_workspace.set_visibility(true);
        // Set the first view to be focused, so that the view is updated to this new workspace
        if new_current_workspace.get_children().len() > 0 {
            trace!("Focusing view");
            match new_current_workspace.get_children_mut()[0]
                .get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.focus(),
                _ => {},
            }
        } else {
            WlcView::root().focus();
        }
        current_workspace = new_current_workspace as *const Node;
    }
    tree.active_container = current_workspace;
    Ok(())
}
<commit_msg>get_current_workspace -> get_active_workspace, for name consistency<commit_after>//! Main module to handle the layout.
//! This is where the i3-specific code is.

use std::sync::{Mutex, MutexGuard, TryLockError};
use std::ptr;

use super::container::{Container, Handle, ContainerType};
use super::node::{Node};
use super::super::rustwlc::handle::{WlcView, WlcOutput};

pub type TreeResult = Result<(), TryLockError<MutexGuard<'static, Tree>>>;

const ERR_BAD_TREE: &'static str = "Layout tree was in an invalid configuration";

lazy_static! {
    static ref TREE: Mutex<Tree> = {
        Mutex::new(Tree{
            root: Node::new(Container::new_root()),
            active_container: ptr::null(),
        })
    };
}

pub struct Tree {
    root: Node,
    active_container: *const Node,
}

unsafe impl Send for Tree {}

impl Tree {
    /// Returns the currently viewed container.
    /// If multiple views are selected, the parent container they share is returned
    fn get_active_container(&self) -> Option<&Node> {
        if self.active_container.is_null() {
            None
        } else {
            unsafe {
                Some(&*self.active_container)
            }
        }
    }

    /// Get the monitor (output) that the active container is located on
    fn get_active_output(&self) -> Option<&Node> {
        if let Some(node) = self.get_active_container() {
            node.get_ancestor_of_type(ContainerType::Output)
        } else {
            None
        }
    }

    /// Get the workspace that the active container is located on
    fn get_active_workspace(&self) -> Option<&mut Node> {
        if let Some(container) = self.get_active_container() {
            //if let Some(child) = container.get_ancestor_of_type(ContainerType::Workspace) {
            //return child.get_children()[0].get_parent()

            //}
            // NOTE hack here, remove commented code above to make this work properly
            let parent = container.get_parent().expect(ERR_BAD_TREE);
            for child in parent.get_children_mut() {
                if child == container {
                    return Some(child);
                }
            }
        }
        return None
    }

    /// Find the workspace node that has the given name
    fn get_workspace_by_name(&self, name: &str) -> Option<&Node> {
        for child in self.root.get_children()[0].get_children() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Find the workspace node that has the given name, with a mutable reference
    fn get_workspace_by_name_mut(&mut self, name: &str) -> Option<&mut Node> {
        for child in self.root.get_children_mut()[0].get_children_mut() {
            if child.get_val().get_name().expect(ERR_BAD_TREE) != name {
                continue
            }
            return Some(child);
        }
        return None
    }

    /// Make a new output container with the given WlcOutput.
    /// This is done when a new monitor is added
    fn add_output(&mut self, wlc_output: WlcOutput) {
        self.root.new_child(Container::new_output(wlc_output));
    }

    /// Make a new workspace container with the given name.
    fn add_workspace(&mut self, name: String) {
        let workspace = Container::new_workspace(name.to_string());
        let mut index = 0;
        if let Some(output) = self.get_active_output() {
            for (cur_index, child) in self.root.get_children().iter().enumerate() {
                if child == output {
                    index = cur_index;
                    break;
                }
            }
        }
        self.root.get_children_mut()[index].new_child(workspace);
    }

    /// Make a new view container with the given WlcView, and adds it to
    /// the active workspace.
    fn add_view(&self, wlc_view: WlcView) {
        if let Some(current_workspace) = self.get_active_workspace() {
            trace!("Adding view {:?} to {:?}", wlc_view, current_workspace);
            current_workspace.new_child(Container::new_view(wlc_view));
        }
    }

    /// Remove the view container with the given view
    fn remove_view(&self, wlc_view: &WlcView) {
        if let Some(view) = self.root.find_view_by_handle(&wlc_view) {
            let parent = view.get_parent().expect(ERR_BAD_TREE);
            parent.remove_child(view);
        }
    }
}

pub fn add_output(wlc_output: WlcOutput) -> TreeResult {
    {
        let mut tree = try!(TREE.try_lock());
        tree.add_output(wlc_output);
    }
    try!(add_workspace("1".to_string()));
    try!(switch_workspace(&"1"));
    Ok(())
}

pub fn add_workspace(name: String) -> TreeResult {
    trace!("Adding new workspace to root");
    let mut tree = try!(TREE.lock());
    tree.add_workspace(name);
    Ok(())
}

pub fn add_view(wlc_view: WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.add_view(wlc_view);
    Ok(())
}

pub fn remove_view(wlc_view: &WlcView) -> TreeResult {
    let tree = try!(TREE.lock());
    tree.remove_view(wlc_view);
    Ok(())
}

pub fn switch_workspace(name: &str) -> TreeResult {
    trace!("Switching to workspace {}", name);
    let mut tree = try!(TREE.lock());
    if let Some(old_workspace) = tree.get_active_workspace() {
        old_workspace.set_visibility(false);
    }
    let current_workspace: *const Node;
    {
        if let Some(_) = tree.get_workspace_by_name(name) {
            trace!("Found workspace {}", name);
        } else {
            trace!("Adding workspace {}", name);
            tree.add_workspace(name.to_string());
        }
        let new_current_workspace = tree.get_workspace_by_name_mut(name).expect(ERR_BAD_TREE);
        new_current_workspace.set_visibility(true);
        // Set the first view to be focused, so that the view is updated to this new workspace
        if new_current_workspace.get_children().len() > 0 {
            trace!("Focusing view");
            match new_current_workspace.get_children_mut()[0]
                .get_val().get_handle().expect(ERR_BAD_TREE) {
                Handle::View(view) => view.focus(),
                _ => {},
            }
        } else {
            WlcView::root().focus();
        }
        current_workspace = new_current_workspace as *const Node;
    }
    tree.active_container = current_workspace;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate regex;

use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

use regex::Regex;
use clap::{App,Arg};

fn main() {
    let args = App::new("grep-lite")
        .version("0.1")
        .about("searches for patterns")
        .arg(Arg::with_name("pattern")
             .help("the pattern to search for")
             .takes_value(true)
             .required(true))
        .arg(Arg::with_name("input")
             .help("File to search")
             .takes_value(true)
             .required(true))
        .get_matches();

    let pattern = args.value_of("pattern").unwrap();
    let re = Regex::new(pattern).unwrap();

    let input = args.value_of("input").unwrap();
    let f = File::open(input).unwrap();
    let mut reader = BufReader::new(f);

    // PARAMETERS
    let context_lines = 2;
    let needle = "oo";
    let haystack = "Every face, every shop,
    bedroom window, public-house, and
    dark square is a picture
    feverishly turned--in search of what?
    It is the same with books.
    what do we seek
    through millions of pages?";

    // INITIALIZATINO
    let mut tags: Vec<usize> = Vec::new();
    let mut ctx: Vec<Vec<(usize, String)>> = Vec::new();

    // PASS 1
    for (i, line) in haystack.lines().enumerate() {
        if line.contains(needle) {
            tags.push(i);

            let v = Vec::with_capacity(2*context_lines + 1);
            ctx.push(v)
        }
    }

    if tags.len() == 0 {
        return;
    }

    // PASS 2
    for (i, line) in haystack.lines().enumerate() {
        for (j, tag) in tags.iter().enumerate() {
            let lower_bound = tag.saturating_sub(context_lines);
            let upper_bound = tag + context_lines;

            if (i >= lower_bound) && (i <= upper_bound) {
                let line_as_string = String::from(line);
                let local_ctx = (i, line_as_string);
                ctx[j].push(local_ctx);
            }
        }
    }

    // OUTPUT
    for local_ctx in ctx.iter() {
        for &(i, ref line) in local_ctx.iter() {
            let line_num = i + 1;
            println!("{}: {}", line_num, line);
        }
    }
    println!();

    let mut line = String::new();
    let mut idx = 0;
    loop {
        let len = reader.read_line(&mut line).unwrap();
        if len == 0 {
            break
        }

        match re.find(&line) {
            Some(_) => {
                let line_num = idx + 1;
                println!("{}: {}", line_num, line);
                println!("{} ({} bytes long)", line, len);
            },
            None => (),
        }

        line.truncate(0);
        idx = idx + 1;
    }
}
<commit_msg>use BufReader::lines() to iterate over whole document<commit_after>extern crate clap;
extern crate regex;

use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;

use regex::Regex;
use clap::{App,Arg};

fn main() {
    let args = App::new("grep-lite")
        .version("0.1")
        .about("searches for patterns")
        .arg(Arg::with_name("pattern")
             .help("the pattern to search for")
             .takes_value(true)
             .required(true))
        .arg(Arg::with_name("input")
             .help("File to search")
             .takes_value(true)
             .required(true))
        .get_matches();

    let pattern = args.value_of("pattern").unwrap();
    let re = Regex::new(pattern).unwrap();

    let input = args.value_of("input").unwrap();
    let f = File::open(input).unwrap();
    let reader = BufReader::new(f);

    // PARAMETERS
    let context_lines = 2;
    let needle = "oo";
    let haystack = "Every face, every shop,
    bedroom window, public-house, and
    dark square is a picture
    feverishly turned--in search of what?
    It is the same with books.
    what do we seek
    through millions of pages?";

    // INITIALIZATINO
    let mut tags: Vec<usize> = Vec::new();
    let mut ctx: Vec<Vec<(usize, String)>> = Vec::new();

    // PASS 1
    for (i, line) in haystack.lines().enumerate() {
        if line.contains(needle) {
            tags.push(i);

            let v = Vec::with_capacity(2*context_lines + 1);
            ctx.push(v)
        }
    }

    if tags.len() == 0 {
        return;
    }

    // PASS 2
    for (i, line) in haystack.lines().enumerate() {
        for (j, tag) in tags.iter().enumerate() {
            let lower_bound = tag.saturating_sub(context_lines);
            let upper_bound = tag + context_lines;

            if (i >= lower_bound) && (i <= upper_bound) {
                let line_as_string = String::from(line);
                let local_ctx = (i, line_as_string);
                ctx[j].push(local_ctx);
            }
        }
    }

    // OUTPUT
    for local_ctx in ctx.iter() {
        for &(i, ref line) in local_ctx.iter() {
            let line_num = i + 1;
            println!("{}: {}", line_num, line);
        }
    }
    println!();

    let mut idx = 0;
    for line_ in reader.lines() {
        let line = line_.unwrap();
        match re.find(&line) {
            Some(_) => {
                let line_num = idx + 1;
                println!("{}: {}", line_num, line);
            },
            None => (),
        }
        idx = idx + 1;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 by SiegeLord
//
// All rights reserved. Distributed under ZLib. For full terms see the file LICENSE.

#![allow(raw_pointer_derive)]

use libc::*;
use std::mem;

use internal::keycodes::{KeyCode, KeyModifier};
use internal::core::Core;
use ffi::*;

pub use self::Event::*;

pub mod external
{
	pub use super::{Event, EventQueue, EventSource};
	pub use super::Event::*;
}

pub struct EventQueue
{
	allegro_queue: *mut ALLEGRO_EVENT_QUEUE,
}

impl EventQueue
{
	pub fn new(_: &Core) -> Result<EventQueue, ()>
	{
		unsafe
		{
			let q = al_create_event_queue();
			if q.is_null()
			{
				Err(())
			}
			else
			{
				Ok(EventQueue{ allegro_queue: q })
			}
		}
	}

	pub fn register_event_source(&self, src: &EventSource)
	{
		unsafe
		{
			al_register_event_source(self.allegro_queue, src.allegro_source);
		}
	}

	pub fn is_empty(&self) -> bool
	{
		unsafe
		{
			al_is_event_queue_empty(self.allegro_queue) != 0
		}
	}

	pub fn get_next_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			if al_get_next_event(self.allegro_queue, &mut e) != 0
			{
				Event::from_allegro_event(&mut e)
			}
			else
			{
				NoEvent
			}
		}
	}

	pub fn peek_next_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			if al_peek_next_event(self.allegro_queue, &mut e) != 0
			{
				Event::from_allegro_event(&mut e)
			}
			else
			{
				NoEvent
			}
		}
	}

	pub fn drop_next_event(&self) -> bool
	{
		unsafe
		{
			al_drop_next_event(self.allegro_queue) != 0
		}
	}

	pub fn flush(&self)
	{
		unsafe
		{
			al_flush_event_queue(self.allegro_queue);
		}
	}

	pub fn wait_for_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			al_wait_for_event(self.allegro_queue, &mut e);
		}
		Event::from_allegro_event(&mut e)
	}

	pub fn wait_for_event_timed(&self, secs: f64) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			al_wait_for_event_timed(self.allegro_queue, &mut e, secs as c_float);
		}
		Event::from_allegro_event(&mut e)
	}
}

impl Iterator for EventQueue
{
	type Item = Event;
	fn next(&mut self) -> Option<Event>
	{
		match self.get_next_event()
		{
			NoEvent => None,
			e => Some(e)
		}
	}
}

// Not Send just because of the marker
impl Drop for EventQueue
{
	fn drop(&mut self)
	{
		unsafe
		{
			al_destroy_event_queue(self.allegro_queue);
		}
	}
}

#[allow(missing_copy_implementations)]
pub struct EventSource
{
	allegro_source: *mut ALLEGRO_EVENT_SOURCE,
}

impl EventSource
{
	pub fn get_event_source(&self) -> *mut ALLEGRO_EVENT_SOURCE
	{
		self.allegro_source
	}
}

#[derive(Copy, Clone)]
pub enum Event
{
	NoEvent,
	DisplayClose
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64
	},
	JoystickAxes
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		stick: i32,
		axis: i32,
		pos: f32
	},
	JoystickButtonDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		button: i32
	},
	JoystickButtonUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		button: i32
	},
	JoystickConfiguration
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64
	},
	KeyDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY
	},
	KeyUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY
	},
	KeyChar
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY,
		unichar: char,
		repeat: bool,
		modifiers: KeyModifier
	},
	MouseAxes
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		dx: i32,
		dy: i32,
		dz: i32,
		dw: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseButtonDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		button: u32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseButtonUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		button: u32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseWarped
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		dx: i32,
		dy: i32,
		dz: i32,
		dw: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseEnterDisplay
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseLeaveDisplay
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	TimerTick
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		count: i64
	},
}

impl Event
{
	fn from_allegro_event(e: &mut ALLEGRO_EVENT) -> Event
	{
		unsafe
		{
			let src = (*e.any()).source;
			let ts = (*e.any()).timestamp as f64;
			match *e._type() as u32
			{
				ALLEGRO_EVENT_DISPLAY_CLOSE =>
				{
					DisplayClose{source: src, timestamp: ts}
				},
				ALLEGRO_EVENT_JOYSTICK_AXIS =>
				{
					let a = *e.joystick();
					JoystickAxes{source: src, timestamp: ts, id: a.id, stick: a.stick as i32, axis: a.axis as i32, pos: a.pos as f32}
				},
				ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN =>
				{
					let a = *e.joystick();
					JoystickButtonDown{source: src, timestamp: ts, id: a.id, button: a.button as i32}
				},
				ALLEGRO_EVENT_JOYSTICK_BUTTON_UP =>
				{
					let a = *e.joystick();
					JoystickButtonUp{source: src, timestamp: ts, id: a.id, button: a.button as i32}
				},
				ALLEGRO_EVENT_JOYSTICK_CONFIGURATION =>
				{
					JoystickConfiguration{source: src, timestamp: ts}
				},
				ALLEGRO_EVENT_KEY_DOWN =>
				{
					let k = *e.keyboard();
					KeyDown{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display}
				},
				ALLEGRO_EVENT_KEY_UP =>
				{
					let k = *e.keyboard();
					KeyUp{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display}
				},
				ALLEGRO_EVENT_KEY_CHAR =>
				{
					let k = *e.keyboard();
					KeyChar{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display,
					        unichar: mem::transmute(k.unichar), repeat: k.repeat != 0, modifiers: mem::transmute(k.modifiers)}
				},
				ALLEGRO_EVENT_MOUSE_AXES =>
				{
					let m = *e.mouse();
					MouseAxes{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, dx: m.dx, dy: m.dy, dz: m.dz, dw: m.dw, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_BUTTON_DOWN =>
				{
					let m = *e.mouse();
					MouseButtonDown{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, button: m.button, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_BUTTON_UP =>
				{
					let m = *e.mouse();
					MouseButtonUp{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, button: m.button, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_WARPED =>
				{
					let m = *e.mouse();
					MouseWarped{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, dx: m.dx, dy: m.dy, dz: m.dz, dw: m.dw, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY =>
				{
					let m = *e.mouse();
					MouseEnterDisplay{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY =>
				{
					let m = *e.mouse();
					MouseLeaveDisplay{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, display: m.display}
				},
				ALLEGRO_EVENT_TIMER =>
				{
					let t = *e.timer();
					TimerTick{source: src, timestamp: ts, count: t.count as i64}
				},
				_ => NoEvent
			}
		}
	}
}

pub fn new_event_source_ref(source: *mut ALLEGRO_EVENT_SOURCE) -> EventSource
{
	EventSource{ allegro_source: source }
}
<commit_msg>Add DisplayResize event.<commit_after>// Copyright (c) 2014 by SiegeLord
//
// All rights reserved. Distributed under ZLib. For full terms see the file LICENSE.

#![allow(raw_pointer_derive)]

use libc::*;
use std::mem;

use internal::keycodes::{KeyCode, KeyModifier};
use internal::core::Core;
use ffi::*;

pub use self::Event::*;

pub mod external
{
	pub use super::{Event, EventQueue, EventSource};
	pub use super::Event::*;
}

pub struct EventQueue
{
	allegro_queue: *mut ALLEGRO_EVENT_QUEUE,
}

impl EventQueue
{
	pub fn new(_: &Core) -> Result<EventQueue, ()>
	{
		unsafe
		{
			let q = al_create_event_queue();
			if q.is_null()
			{
				Err(())
			}
			else
			{
				Ok(EventQueue{ allegro_queue: q })
			}
		}
	}

	pub fn register_event_source(&self, src: &EventSource)
	{
		unsafe
		{
			al_register_event_source(self.allegro_queue, src.allegro_source);
		}
	}

	pub fn is_empty(&self) -> bool
	{
		unsafe
		{
			al_is_event_queue_empty(self.allegro_queue) != 0
		}
	}

	pub fn get_next_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			if al_get_next_event(self.allegro_queue, &mut e) != 0
			{
				Event::from_allegro_event(&mut e)
			}
			else
			{
				NoEvent
			}
		}
	}

	pub fn peek_next_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			if al_peek_next_event(self.allegro_queue, &mut e) != 0
			{
				Event::from_allegro_event(&mut e)
			}
			else
			{
				NoEvent
			}
		}
	}

	pub fn drop_next_event(&self) -> bool
	{
		unsafe
		{
			al_drop_next_event(self.allegro_queue) != 0
		}
	}

	pub fn flush(&self)
	{
		unsafe
		{
			al_flush_event_queue(self.allegro_queue);
		}
	}

	pub fn wait_for_event(&self) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			al_wait_for_event(self.allegro_queue, &mut e);
		}
		Event::from_allegro_event(&mut e)
	}

	pub fn wait_for_event_timed(&self, secs: f64) -> Event
	{
		let mut e = ALLEGRO_EVENT::new();
		unsafe
		{
			al_wait_for_event_timed(self.allegro_queue, &mut e, secs as c_float);
		}
		Event::from_allegro_event(&mut e)
	}
}

impl Iterator for EventQueue
{
	type Item = Event;
	fn next(&mut self) -> Option<Event>
	{
		match self.get_next_event()
		{
			NoEvent => None,
			e => Some(e)
		}
	}
}

// Not Send just because of the marker
impl Drop for EventQueue
{
	fn drop(&mut self)
	{
		unsafe
		{
			al_destroy_event_queue(self.allegro_queue);
		}
	}
}

#[allow(missing_copy_implementations)]
pub struct EventSource
{
	allegro_source: *mut ALLEGRO_EVENT_SOURCE,
}

impl EventSource
{
	pub fn get_event_source(&self) -> *mut ALLEGRO_EVENT_SOURCE
	{
		self.allegro_source
	}
}

#[derive(Copy, Clone)]
pub enum Event
{
	NoEvent,
	DisplayClose
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64
	},
	DisplayResize
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		x: i32,
		y: i32,
		width: i32,
		height: i32,
		timestamp: f64
	},
	JoystickAxes
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		stick: i32,
		axis: i32,
		pos: f32
	},
	JoystickButtonDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		button: i32
	},
	JoystickButtonUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		id: *mut ALLEGRO_JOYSTICK,
		button: i32
	},
	JoystickConfiguration
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64
	},
	KeyDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY
	},
	KeyUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY
	},
	KeyChar
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		keycode: KeyCode,
		display: *mut ALLEGRO_DISPLAY,
		unichar: char,
		repeat: bool,
		modifiers: KeyModifier
	},
	MouseAxes
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		dx: i32,
		dy: i32,
		dz: i32,
		dw: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseButtonDown
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		button: u32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseButtonUp
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		button: u32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseWarped
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		dx: i32,
		dy: i32,
		dz: i32,
		dw: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseEnterDisplay
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	MouseLeaveDisplay
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		x: i32,
		y: i32,
		z: i32,
		w: i32,
		display: *mut ALLEGRO_DISPLAY
	},
	TimerTick
	{
		source: *mut ALLEGRO_EVENT_SOURCE,
		timestamp: f64,
		count: i64
	},
}

impl Event
{
	fn from_allegro_event(e: &mut ALLEGRO_EVENT) -> Event
	{
		unsafe
		{
			let src = (*e.any()).source;
			let ts = (*e.any()).timestamp as f64;
			match *e._type() as u32
			{
				ALLEGRO_EVENT_DISPLAY_CLOSE =>
				{
					DisplayClose{source: src, timestamp: ts}
				},
				ALLEGRO_EVENT_DISPLAY_RESIZE =>
				{
					let a = *e.display();
					DisplayResize{source: src, x: a.x as i32, y: a.y as i32, width: a.width as i32, height: a.height as i32, timestamp: ts}
				},
				ALLEGRO_EVENT_JOYSTICK_AXIS =>
				{
					let a = *e.joystick();
					JoystickAxes{source: src, timestamp: ts, id: a.id, stick: a.stick as i32, axis: a.axis as i32, pos: a.pos as f32}
				},
				ALLEGRO_EVENT_JOYSTICK_BUTTON_DOWN =>
				{
					let a = *e.joystick();
					JoystickButtonDown{source: src, timestamp: ts, id: a.id, button: a.button as i32}
				},
				ALLEGRO_EVENT_JOYSTICK_BUTTON_UP =>
				{
					let a = *e.joystick();
					JoystickButtonUp{source: src, timestamp: ts, id: a.id, button: a.button as i32}
				},
				ALLEGRO_EVENT_JOYSTICK_CONFIGURATION =>
				{
					JoystickConfiguration{source: src, timestamp: ts}
				},
				ALLEGRO_EVENT_KEY_DOWN =>
				{
					let k = *e.keyboard();
					KeyDown{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display}
				},
				ALLEGRO_EVENT_KEY_UP =>
				{
					let k = *e.keyboard();
					KeyUp{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display}
				},
				ALLEGRO_EVENT_KEY_CHAR =>
				{
					let k = *e.keyboard();
					KeyChar{source: src, timestamp: ts, keycode: KeyCode::from_allegro_key(k.keycode), display: k.display,
					        unichar: mem::transmute(k.unichar), repeat: k.repeat != 0, modifiers: mem::transmute(k.modifiers)}
				},
				ALLEGRO_EVENT_MOUSE_AXES =>
				{
					let m = *e.mouse();
					MouseAxes{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, dx: m.dx, dy: m.dy, dz: m.dz, dw: m.dw, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_BUTTON_DOWN =>
				{
					let m = *e.mouse();
					MouseButtonDown{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, button: m.button, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_BUTTON_UP =>
				{
					let m = *e.mouse();
					MouseButtonUp{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, button: m.button, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_WARPED =>
				{
					let m = *e.mouse();
					MouseWarped{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, dx: m.dx, dy: m.dy, dz: m.dz, dw: m.dw, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_ENTER_DISPLAY =>
				{
					let m = *e.mouse();
					MouseEnterDisplay{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, display: m.display}
				},
				ALLEGRO_EVENT_MOUSE_LEAVE_DISPLAY =>
				{
					let m = *e.mouse();
					MouseLeaveDisplay{source: src, timestamp: ts, x: m.x, y: m.y, z: m.z, w: m.w, display: m.display}
				},
				ALLEGRO_EVENT_TIMER =>
				{
					let t = *e.timer();
					TimerTick{source: src, timestamp: ts, count: t.count as i64}
				},
				_ => NoEvent
			}
		}
	}
}

pub fn new_event_source_ref(source: *mut ALLEGRO_EVENT_SOURCE) -> EventSource
{
	EventSource{ allegro_source: source }
}
<|endoftext|>


<commit_before>use crate::common::util::*;

#[cfg(target_os = "linux")]
#[test]
fn test_count() {
    for opt in vec!["-q", "--count"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_boot() {
    for opt in vec!["-b", "--boot"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_heading() {
    for opt in vec!["-H", "--heading"] {
        // allow whitespace variation
        // * minor whitespace differences occur between platform built-in outputs;
        //   specifically number of TABs between "TIME" and "COMMENT" may be variant
        let actual = new_ucmd!().arg(opt).succeeds().stdout_move_str();
        let expect = expected_result(opt);
        println!("actual: {:?}", actual);
        println!("expect: {:?}", expect);
        let v_actual: Vec<&str> = actual.split_whitespace().collect();
        let v_expect: Vec<&str> = expect.split_whitespace().collect();
        assert_eq!(v_actual, v_expect);
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_short() {
    for opt in vec!["-s", "--short"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_login() {
    for opt in vec!["-l", "--login"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_m() {
    for opt in vec!["-m"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_process() {
    for opt in vec!["-p", "--process"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_runlevel() {
    for opt in vec!["-r", "--runlevel"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_time() {
    for opt in vec!["-t", "--time"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_mesg() {
    for opt in vec!["-w", "-T", "--users", "--message", "--writable"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_arg1_arg2() {
    let scene = TestScenario::new(util_name!());

    let expected = scene
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .arg("am")
        .arg("i")
        .succeeds();

    scene
        .ucmd()
        .arg("am")
        .arg("i")
        .succeeds()
        .stdout_is(expected.stdout_str());
}

#[test]
fn test_too_many_args() {
    let expected =
        "error: The value 'u' was provided to '<FILE>...', but it wasn't expecting any more values";

    new_ucmd!()
        .arg("am")
        .arg("i")
        .arg("u")
        .fails()
        .stderr_contains(expected);
}

#[cfg(target_os = "linux")]
#[test]
fn test_users() {
    for opt in vec!["-u", "--users"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_lookup() {
    for opt in vec!["--lookup"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_dead() {
    for opt in vec!["-d", "--dead"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_all_separately() {
    // -a, --all         same as -b -d --login -p -r -t -T -u
    let scene = TestScenario::new(util_name!());

    let expected = scene
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .arg("-b")
        .arg("-d")
        .arg("--login")
        .arg("-p")
        .arg("-r")
        .arg("-t")
        .arg("-T")
        .arg("-u")
        .succeeds();

    scene
        .ucmd()
        .arg("-b")
        .arg("-d")
        .arg("--login")
        .arg("-p")
        .arg("-r")
        .arg("-t")
        .arg("-T")
        .arg("-u")
        .succeeds()
        .stdout_is(expected.stdout_str());

    scene
        .ucmd()
        .arg("--all")
        .succeeds()
        .stdout_is(expected.stdout_str());
}

#[cfg(target_os = "linux")]
#[test]
fn test_all() {
    for opt in vec!["-a", "--all"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
fn expected_result(arg: &str) -> String {
    TestScenario::new(util_name!())
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .args(&[arg])
        .succeeds()
        .stdout_move_str()
}
<commit_msg>Ignore test_lookup until issue #2181 is fixed<commit_after>use crate::common::util::*;

#[cfg(target_os = "linux")]
#[test]
fn test_count() {
    for opt in vec!["-q", "--count"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_boot() {
    for opt in vec!["-b", "--boot"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_heading() {
    for opt in vec!["-H", "--heading"] {
        // allow whitespace variation
        // * minor whitespace differences occur between platform built-in outputs;
        //   specifically number of TABs between "TIME" and "COMMENT" may be variant
        let actual = new_ucmd!().arg(opt).succeeds().stdout_move_str();
        let expect = expected_result(opt);
        println!("actual: {:?}", actual);
        println!("expect: {:?}", expect);
        let v_actual: Vec<&str> = actual.split_whitespace().collect();
        let v_expect: Vec<&str> = expect.split_whitespace().collect();
        assert_eq!(v_actual, v_expect);
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_short() {
    for opt in vec!["-s", "--short"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_login() {
    for opt in vec!["-l", "--login"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_m() {
    for opt in vec!["-m"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_process() {
    for opt in vec!["-p", "--process"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_runlevel() {
    for opt in vec!["-r", "--runlevel"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_time() {
    for opt in vec!["-t", "--time"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_mesg() {
    for opt in vec!["-w", "-T", "--users", "--message", "--writable"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_arg1_arg2() {
    let scene = TestScenario::new(util_name!());

    let expected = scene
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .arg("am")
        .arg("i")
        .succeeds();

    scene
        .ucmd()
        .arg("am")
        .arg("i")
        .succeeds()
        .stdout_is(expected.stdout_str());
}

#[test]
fn test_too_many_args() {
    let expected =
        "error: The value 'u' was provided to '<FILE>...', but it wasn't expecting any more values";

    new_ucmd!()
        .arg("am")
        .arg("i")
        .arg("u")
        .fails()
        .stderr_contains(expected);
}

#[cfg(target_os = "linux")]
#[test]
fn test_users() {
    for opt in vec!["-u", "--users"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
#[ignore]
fn test_lookup() {
    for opt in vec!["--lookup"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_dead() {
    for opt in vec!["-d", "--dead"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
#[test]
fn test_all_separately() {
    // -a, --all         same as -b -d --login -p -r -t -T -u
    let scene = TestScenario::new(util_name!());

    let expected = scene
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .arg("-b")
        .arg("-d")
        .arg("--login")
        .arg("-p")
        .arg("-r")
        .arg("-t")
        .arg("-T")
        .arg("-u")
        .succeeds();

    scene
        .ucmd()
        .arg("-b")
        .arg("-d")
        .arg("--login")
        .arg("-p")
        .arg("-r")
        .arg("-t")
        .arg("-T")
        .arg("-u")
        .succeeds()
        .stdout_is(expected.stdout_str());

    scene
        .ucmd()
        .arg("--all")
        .succeeds()
        .stdout_is(expected.stdout_str());
}

#[cfg(target_os = "linux")]
#[test]
fn test_all() {
    for opt in vec!["-a", "--all"] {
        new_ucmd!()
            .arg(opt)
            .succeeds()
            .stdout_is(expected_result(opt));
    }
}

#[cfg(target_os = "linux")]
fn expected_result(arg: &str) -> String {
    TestScenario::new(util_name!())
        .cmd_keepenv(util_name!())
        .env("LANGUAGE", "C")
        .args(&[arg])
        .succeeds()
        .stdout_move_str()
}
<|endoftext|>


<commit_before>#![feature(slice_concat_ext)]

extern crate compiletest_rs as compiletest;
extern crate colored;

use colored::*;

use std::slice::SliceConcatExt;
use std::path::{PathBuf, Path};
use std::io::Write;
use std::env;

macro_rules! eprintln {
    ($($arg:tt)*) => {
        let stderr = std::io::stderr();
        writeln!(stderr.lock(), $($arg)*).unwrap();
    }
}

fn miri_path() -> PathBuf {
    if rustc_test_suite().is_some() {
        PathBuf::from(option_env!("MIRI_PATH").unwrap())
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/miri"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn have_fullmir() -> bool {
    // We assume we have full MIR when MIRI_SYSROOT is set or when we are in rustc
    std::env::var("MIRI_SYSROOT").is_ok() || rustc_test_suite().is_some()
}

fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool) {
    if need_fullmir && !have_fullmir() {
        eprintln!("{}", format!(
            "## Skipping compile-fail tests in {} against miri for target {} due to missing mir",
            path,
            target
        ).yellow().bold());
        return;
    }

    eprintln!("{}", format!(
        "## Running compile-fail tests in {} against miri for target {}",
        path,
        target
    ).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "compile-fail".parse().expect("Invalid mode");
    config.rustc_path = miri_path();
    let mut flags = Vec::new();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    flags.push(format!("--sysroot {}", sysroot.display()));
    config.src_base = PathBuf::from(path.to_string());
    flags.push("-Zmir-emit-validate=1".to_owned());
    config.target_rustcflags = Some(flags.join(" "));
    config.target = target.to_owned();
    config.host = host.to_owned();
    compiletest::run_tests(&config);
}

fn rustc_pass(sysroot: &Path, path: &str) {
    eprintln!("{}", format!("## Running run-pass tests in {} against rustc", path).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    if let Some(rustc_path) = rustc_test_suite() {
        config.rustc_path = rustc_path;
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
        config.target_rustcflags = Some(format!("-Dwarnings --sysroot {}", sysroot.display()));
    } else {
        config.target_rustcflags = Some("-Dwarnings".to_owned());
    }
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool, opt: bool) {
    if need_fullmir && !have_fullmir() {
        eprintln!("{}", format!(
            "## Skipping run-pass tests in {} against miri for target {} due to missing mir",
            path,
            target
        ).yellow().bold());
        return;
    }

    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running run-pass tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "ui".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = miri_path();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    let mut flags = Vec::new();
    flags.push(format!("--sysroot {}", sysroot.display()));
    if have_fullmir() {
        flags.push("-Zmiri-start-fn".to_owned());
    }
    if opt {
        flags.push("-Zmir-opt-level=3".to_owned());
    } else {
        flags.push("-Zmir-opt-level=0".to_owned());
        // For now, only validate without optimizations.  Inlining breaks validation.
        flags.push("-Zmir-emit-validate=1".to_owned());
    }
    // Control miri logging. This is okay despite concurrent test execution as all tests
    // will set this env var to the same value.
    env::set_var("MIRI_LOG", "warn");
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

fn is_target_dir<P: Into<PathBuf>>(path: P) -> bool {
    let mut path = path.into();
    path.push("lib");
    path.metadata().map(|m| m.is_dir()).unwrap_or(false)
}

fn for_all_targets<F: FnMut(String)>(sysroot: &Path, mut f: F) {
    let target_dir = sysroot.join("lib").join("rustlib");
    for entry in std::fs::read_dir(target_dir).expect("invalid sysroot") {
        let entry = entry.unwrap();
        if !is_target_dir(entry.path()) {
            continue;
        }
        let target = entry.file_name().into_string().unwrap();
        f(target);
    }
}

fn get_sysroot() -> PathBuf {
    let sysroot = std::env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
        let sysroot = std::process::Command::new("rustc")
            .arg("--print")
            .arg("sysroot")
            .output()
            .expect("rustc not found")
            .stdout;
        String::from_utf8(sysroot).expect("sysroot is not utf8")
    });
    PathBuf::from(sysroot.trim())
}

fn get_host() -> String {
    let rustc = rustc_test_suite().unwrap_or(PathBuf::from("rustc"));
    println!("using rustc at {}", rustc.display());
    let host = std::process::Command::new(rustc)
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let host = std::str::from_utf8(&host).expect("sysroot is not utf8");
    let host = host.split("\nhost: ").nth(1).expect(
        "no host: part in rustc -vV",
    );
    let host = host.split('\n').next().expect("no \n after host");
    String::from(host)
}

fn run_pass_miri(opt: bool) {
    let sysroot = get_sysroot();
    let host = get_host();

    for_all_targets(&sysroot, |target| {
        miri_pass(&sysroot, "tests/run-pass", &target, &host, false, opt);
    });
    miri_pass(&sysroot, "tests/run-pass-fullmir", &host, &host, true, opt);
}

#[test]
fn run_pass_miri_noopt() {
    run_pass_miri(false);
}

#[test]
#[ignore]
// FIXME: Disabled for now, as the optimizer is pretty broken and crashes...
// See https://github.com/rust-lang/rust/issues/50411
fn run_pass_miri_opt() {
    run_pass_miri(true);
}

#[test]
fn run_pass_rustc() {
    let sysroot = get_sysroot();
    rustc_pass(&sysroot, "tests/run-pass");
    rustc_pass(&sysroot, "tests/run-pass-fullmir");
}

#[test]
fn compile_fail_miri() {
    let sysroot = get_sysroot();
    let host = get_host();

    // FIXME: run tests for other targets, too
    compile_fail(&sysroot, "tests/compile-fail", &host, &host, false);
    compile_fail(&sysroot, "tests/compile-fail-fullmir", &host, &host, true);
}
<commit_msg>testsuite: put everything into a single test to fix interleaved output mess<commit_after>#![feature(slice_concat_ext)]

extern crate compiletest_rs as compiletest;
extern crate colored;

use colored::*;

use std::slice::SliceConcatExt;
use std::path::{PathBuf, Path};
use std::io::Write;
use std::env;

macro_rules! eprintln {
    ($($arg:tt)*) => {
        let stderr = std::io::stderr();
        writeln!(stderr.lock(), $($arg)*).unwrap();
    }
}

fn miri_path() -> PathBuf {
    if rustc_test_suite().is_some() {
        PathBuf::from(option_env!("MIRI_PATH").unwrap())
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/miri"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn have_fullmir() -> bool {
    // We assume we have full MIR when MIRI_SYSROOT is set or when we are in rustc
    std::env::var("MIRI_SYSROOT").is_ok() || rustc_test_suite().is_some()
}

fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool) {
    if need_fullmir && !have_fullmir() {
        eprintln!("{}", format!(
            "## Skipping compile-fail tests in {} against miri for target {} due to missing mir",
            path,
            target
        ).yellow().bold());
        return;
    }

    eprintln!("{}", format!(
        "## Running compile-fail tests in {} against miri for target {}",
        path,
        target
    ).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "compile-fail".parse().expect("Invalid mode");
    config.rustc_path = miri_path();
    let mut flags = Vec::new();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    flags.push(format!("--sysroot {}", sysroot.display()));
    config.src_base = PathBuf::from(path.to_string());
    flags.push("-Zmir-emit-validate=1".to_owned());
    config.target_rustcflags = Some(flags.join(" "));
    config.target = target.to_owned();
    config.host = host.to_owned();
    compiletest::run_tests(&config);
}

fn rustc_pass(sysroot: &Path, path: &str) {
    eprintln!("{}", format!("## Running run-pass tests in {} against rustc", path).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    if let Some(rustc_path) = rustc_test_suite() {
        config.rustc_path = rustc_path;
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
        config.target_rustcflags = Some(format!("-Dwarnings --sysroot {}", sysroot.display()));
    } else {
        config.target_rustcflags = Some("-Dwarnings".to_owned());
    }
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool, opt: bool) {
    if need_fullmir && !have_fullmir() {
        eprintln!("{}", format!(
            "## Skipping run-pass tests in {} against miri for target {} due to missing mir",
            path,
            target
        ).yellow().bold());
        return;
    }

    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running run-pass tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());
    let mut config = compiletest::Config::default().tempdir();
    config.mode = "ui".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = miri_path();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    let mut flags = Vec::new();
    flags.push(format!("--sysroot {}", sysroot.display()));
    if have_fullmir() {
        flags.push("-Zmiri-start-fn".to_owned());
    }
    if opt {
        flags.push("-Zmir-opt-level=3".to_owned());
    } else {
        flags.push("-Zmir-opt-level=0".to_owned());
        // For now, only validate without optimizations.  Inlining breaks validation.
        flags.push("-Zmir-emit-validate=1".to_owned());
    }
    // Control miri logging. This is okay despite concurrent test execution as all tests
    // will set this env var to the same value.
    env::set_var("MIRI_LOG", "warn");
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

fn is_target_dir<P: Into<PathBuf>>(path: P) -> bool {
    let mut path = path.into();
    path.push("lib");
    path.metadata().map(|m| m.is_dir()).unwrap_or(false)
}

fn for_all_targets<F: FnMut(String)>(sysroot: &Path, mut f: F) {
    let target_dir = sysroot.join("lib").join("rustlib");
    for entry in std::fs::read_dir(target_dir).expect("invalid sysroot") {
        let entry = entry.unwrap();
        if !is_target_dir(entry.path()) {
            continue;
        }
        let target = entry.file_name().into_string().unwrap();
        f(target);
    }
}

fn get_sysroot() -> PathBuf {
    let sysroot = std::env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
        let sysroot = std::process::Command::new("rustc")
            .arg("--print")
            .arg("sysroot")
            .output()
            .expect("rustc not found")
            .stdout;
        String::from_utf8(sysroot).expect("sysroot is not utf8")
    });
    PathBuf::from(sysroot.trim())
}

fn get_host() -> String {
    let rustc = rustc_test_suite().unwrap_or(PathBuf::from("rustc"));
    println!("using rustc at {}", rustc.display());
    let host = std::process::Command::new(rustc)
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let host = std::str::from_utf8(&host).expect("sysroot is not utf8");
    let host = host.split("\nhost: ").nth(1).expect(
        "no host: part in rustc -vV",
    );
    let host = host.split('\n').next().expect("no \n after host");
    String::from(host)
}

fn run_pass_miri(opt: bool) {
    let sysroot = get_sysroot();
    let host = get_host();

    for_all_targets(&sysroot, |target| {
        miri_pass(&sysroot, "tests/run-pass", &target, &host, false, opt);
    });
    miri_pass(&sysroot, "tests/run-pass-fullmir", &host, &host, true, opt);
}

fn run_pass_rustc() {
    let sysroot = get_sysroot();
    rustc_pass(&sysroot, "tests/run-pass");
    rustc_pass(&sysroot, "tests/run-pass-fullmir");
}

fn compile_fail_miri() {
    let sysroot = get_sysroot();
    let host = get_host();

    // FIXME: run tests for other targets, too
    compile_fail(&sysroot, "tests/compile-fail", &host, &host, false);
    compile_fail(&sysroot, "tests/compile-fail-fullmir", &host, &host, true);
}

#[test]
fn test() {
    // We put everything into a single test to avoid the parallelism `cargo test`
    // introduces.  We still get parallelism within our tests because `compiletest`
    // uses `libtest` which runs jobs in parallel.

    run_pass_rustc();

    run_pass_miri(false);

    // FIXME: Disabled for now, as the optimizer is pretty broken and crashes...
    // See https://github.com/rust-lang/rust/issues/50411
    //run_pass_miri(true);

    compile_fail_miri();
}
<|endoftext|>


<commit_before>#[rustversion::attr(not(nightly), ignore)]
#[test]
fn ui() {
    let t = trybuild::TestCases::new();
    t.compile_fail("tests/ui/*.rs");
}
<commit_msg>Exclude ui tests from cargo miri test<commit_after>#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[test]
fn ui() {
    let t = trybuild::TestCases::new();
    t.compile_fail("tests/ui/*.rs");
}
<|endoftext|>


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

use    app_units::Au;
use azure::azure_hl::{AntialiasMode, Color,
ColorPattern, CompositionOp};
use euclid::size::Size2D;
use azure::azure::AzIntSize;
use azure::azure::{AzIntSize};

use std;

mod paint_context;
pub mod display_list;
mod test::{
};

extern crate webrender_traits;
extern crate style_traits;

impl test {

    fn test_fun(y:f32)->f32{
        let x=5;
        x = x-1;
        x = x*x;
        let z = match y {
            1 =>2,
            2 => 1,
        };
        let z = &Vec<T>;
        struct Member {
            member_name:"Foo"
            member_id:5
        }
    }

    fn test_fun2(y : &String, z : &Vec<f32>, r: &Root<isize>) -> f32 {
        let x = true;
        x
            && x;
    }

}
<commit_msg>Auto merge of #11761 - Wafflespeanut:tidy_test, r=emilio<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use    app_units::Au;
use azure::azure_hl::{AntialiasMode, Color,
ColorPattern, CompositionOp};
use euclid::size::Size2D;
use azure::azure::AzIntSize;
use azure::azure::{AzIntSize};

use std;

mod paint_context;
pub mod display_list;
mod test::{
};

extern crate webrender_traits;
extern crate style_traits;

#[foo = "bar,baz"]
impl test {

    fn test_fun(y:f32)->f32{
        let x=5;
        x = x-1;
        x = x*x;
        let z = match y {
            1 =>2,
            2 => 1,
        };
        let z = &Vec<T>;
        struct Member {
            member_name:"Foo"
            member_id:5
        }
    }

    fn test_fun2(y : &String, z : &Vec<f32>, r: &Root<isize>) -> f32 {
        let x = true;
        x
            && x;
    }

}
<|endoftext|>