<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// 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
//
//     http://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.

//! Various helper macros.

mod pso;
mod structure;

#[macro_export]
macro_rules! gfx_format {
    ($name:ident : $surface:ident = $container:ident<$channel:ident>) => {
        impl $crate::format::Formatted for $name {
            type Surface = $crate::format::$surface;
            type Channel = $crate::format::$channel;
            type View = $crate::format::$container<
                <$crate::format::$channel as $crate::format::ChannelTyped>::ShaderType
                >;
        }
    }
}

/// Defines vertex, constant and pipeline formats in one block.
///
/// # Example
///
/// ```{.rust}
/// #[macro_use]
/// extern crate gfx;
///
/// gfx_defines! {
///     vertex Vertex {
///         pos: [f32; 4] = "a_Pos",
///         tex_coord: [f32; 2] = "a_TexCoord",
///     }
///
///     constant Locals {
///         transform: [[f32; 4]; 4] = "u_Transform",
///     }
///
///     pipeline pipe {
///         vbuf: gfx::VertexBuffer<Vertex> = (),
///         transform: gfx::Global<[[f32; 4]; 4]> = "u_Transform",
///         locals: gfx::ConstantBuffer<Locals> = "Locals",
///         color: gfx::TextureSampler<[f32; 4]> = "t_Color",
///         out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
///         out_depth: gfx::DepthTarget<gfx::format::DepthStencil> =
///             gfx::preset::depth::LESS_EQUAL_WRITE,
///     }
/// }
///
/// impl Vertex {
///     fn new(p: [i8; 3], tex: [i8; 2]) -> Vertex {
///         Vertex {
///             pos: [p[0] as f32, p[1] as f32, p[2] as f32, 1.0f32],
///             tex_coord: [tex[0] as f32, tex[1] as f32],
///         }
///     }
/// }
///
/// fn main() {
///     let vertex_data = [
///         Vertex::new([-1, -1, 1], [0, 0]),
///         Vertex::new([ 1, -1, 1], [1, 0]),
///         // Add more vertices..
///     ];
/// }
/// ```
/// `vertex` and `constant` structures defined with `gfx_defines!`
/// can be extended with attributes:
///
/// ```{.rust}
/// #[macro_use]
/// extern crate gfx;
///
/// gfx_defines! {
///     #[derive(Default)]
///     vertex Vertex {
///         pos: [f32; 4] = "a_Pos",
///         tex_coord: [f32; 2] = "a_TexCoord",
///     }
/// }
///
/// fn main() {
///     let vertex = Vertex::default();
///     assert_eq!(vertex.pos[0], 0f32);
///     assert_eq!(vertex.tex_coord[0], 0f32);
/// }
/// ```
///
/// # `pipe`
///
/// The `pipeline state object` can consist of:
///
/// - A single vertex buffer object to hold the vertices.
/// - Single or multiple constant buffer objects.
/// - Single or multiple global buffer objects.
/// - Single or multiple samplers such as texture samplers.
/// - [Render](pso/target/struct.RenderTarget.html), [blend](pso/target/struct.BlendTarget.html),
///   [depth](pso/target/struct.DepthTarget.html) and [stencil](pso/target/struct.StencilTarget.html) targets
/// - A shader resource view (SRV, DX11)
/// - A unordered access view (UAV, DX11, not yet implemented in OpenGL backend)
/// - Scissors rectangle value (DX11)
///
/// Structure of a `pipeline state object` can be defined
/// freely but should at the very least consist of one vertex buffer object.
///
/// # `vertex`
///
/// Defines the vertex format
///
/// # `constant`
///
/// Defines constants values
///
#[macro_export]
macro_rules! gfx_defines {
    ($(#[$attr:meta])* vertex $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_vertex_struct_meta!($(#[$attr])* vertex_struct_meta $name {$($field:$ty = $e,)+});
    };

    ($(#[$attr:meta])* constant $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_constant_struct_meta!($(#[$attr])* constant_struct_meta $name {$($field:$ty = $e,)+});
    };

    (pipeline $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_pipeline!($name {$($field:$ty = $e,)+});
    };

    // The recursive case for vertex structs
    ($(#[$attr:meta])* vertex $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $(#[$attr])*
            vertex $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };

    // The recursive case for constant structs
    ($(#[$attr:meta])* constant $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $(#[$attr])*
            constant $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };

    // The recursive case for the other keywords
    ($keyword:ident $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $keyword $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };
}
<commit_msg>Polished gfx_defines documentation<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// 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
//
//     http://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.

//! Various helper macros.

mod pso;
mod structure;

#[macro_export]
macro_rules! gfx_format {
    ($name:ident : $surface:ident = $container:ident<$channel:ident>) => {
        impl $crate::format::Formatted for $name {
            type Surface = $crate::format::$surface;
            type Channel = $crate::format::$channel;
            type View = $crate::format::$container<
                <$crate::format::$channel as $crate::format::ChannelTyped>::ShaderType
                >;
        }
    }
}

/// Defines vertex, constant and pipeline formats in one block.
///
/// # Example
///
/// ```{.rust}
/// #[macro_use]
/// extern crate gfx;
///
/// gfx_defines! {
///     vertex Vertex {
///         pos: [f32; 4] = "a_Pos",
///         tex_coord: [f32; 2] = "a_TexCoord",
///     }
///
///     constant Locals {
///         transform: [[f32; 4]; 4] = "u_Transform",
///     }
///
///     pipeline pipe {
///         vbuf: gfx::VertexBuffer<Vertex> = (),
///         // Global buffers are added for compatibility when
///         // constant buffers are not supported.
///         transform: gfx::Global<[[f32; 4]; 4]> = "u_Transform",
///         locals: gfx::ConstantBuffer<Locals> = "Locals",
///         color: gfx::TextureSampler<[f32; 4]> = "t_Color",
///         out_color: gfx::RenderTarget<gfx::format::Rgba8> = "Target0",
///         out_depth: gfx::DepthTarget<gfx::format::DepthStencil> =
///             gfx::preset::depth::LESS_EQUAL_WRITE,
///     }
/// }
///
/// impl Vertex {
///     fn new(p: [i8; 3], tex: [i8; 2]) -> Vertex {
///         Vertex {
///             pos: [p[0] as f32, p[1] as f32, p[2] as f32, 1.0f32],
///             tex_coord: [tex[0] as f32, tex[1] as f32],
///         }
///     }
/// }
///
/// fn main() {
///     let vertex_data = [
///         Vertex::new([-1, -1, 1], [0, 0]),
///         Vertex::new([ 1, -1, 1], [1, 0]),
///         // Add more vertices..
///     ];
/// }
/// ```
/// `vertex` and `constant` structures defined with `gfx_defines!`
/// can be extended with attributes:
///
/// ```{.rust}
/// #[macro_use]
/// extern crate gfx;
///
/// gfx_defines! {
///     #[derive(Default)]
///     vertex Vertex {
///         pos: [f32; 4] = "a_Pos",
///         tex_coord: [f32; 2] = "a_TexCoord",
///     }
/// }
///
/// fn main() {
///     let vertex = Vertex::default();
///     assert_eq!(vertex.pos[0], 0f32);
///     assert_eq!(vertex.tex_coord[0], 0f32);
/// }
/// ```
///
/// # `pipe`
///
/// The `pipeline state object` or `pso` can consist of the following
/// `pso` components:
///
/// - A single [vertex buffer](pso/buffer/type.VertexBuffer.html) component to hold the vertices.
/// - A single [instance buffer](pso/buffer/type.InstanceBuffer.html) component.
/// - Single or multiple [constant buffer](pso/buffer/struct.ConstantBuffer.html) components. (DX11 and OpenGL3)
/// - Single or multiple [global buffer](pos/buffer/struct.Global.html) components.
/// - Single or multiple [samplers](pos/resource/struct.Sampler.html)
///   such as [texture samplers](pso/resource/struct.TextureSampler.html].
/// - [Render](pso/target/struct.RenderTarget.html), [blend](pso/target/struct.BlendTarget.html),
///   [depth](pso/target/struct.DepthTarget.html) and [stencil](pso/target/struct.StencilTarget.html) targets
/// - A [shader resource view](pso/resource/struct.ShaderResource.html) (SRV, DX11)
/// - A [unordered access view](pso/resource/struct.UnorderedAccess.html) (UAV, DX11, not yet implemented in the OpenGL backend)
/// - A [scissor](pso/target/struct.Scissor.html) rectangle value (DX11)
///
/// Structure of a `pipeline state object` can be defined
/// freely but should at the very least consist of one vertex buffer object.
///
/// # `vertex`
///
/// Defines a vertex format to be passed onto a vertex buffer. Similar
/// to `pipeline state objects` multiple vertex formats can be set.
///
/// # `constant`
///
/// Defines a structure for shader constant data. This constant data
/// is then appended into a constant buffer in the `pso`. Constant buffers
/// are only supported by DirectX 11 and OpenGL backend uses it's own
/// Uniform Buffer Object which requires OpenGL 3.1.
#[macro_export]
macro_rules! gfx_defines {
    ($(#[$attr:meta])* vertex $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_vertex_struct_meta!($(#[$attr])* vertex_struct_meta $name {$($field:$ty = $e,)+});
    };

    ($(#[$attr:meta])* constant $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_constant_struct_meta!($(#[$attr])* constant_struct_meta $name {$($field:$ty = $e,)+});
    };

    (pipeline $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    }) => {
        gfx_pipeline!($name {$($field:$ty = $e,)+});
    };

    // The recursive case for vertex structs
    ($(#[$attr:meta])* vertex $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $(#[$attr])*
            vertex $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };

    // The recursive case for constant structs
    ($(#[$attr:meta])* constant $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $(#[$attr])*
            constant $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };

    // The recursive case for the other keywords
    ($keyword:ident $name:ident {
            $( $field:ident : $ty:ty = $e:expr, )+
    } $($tail:tt)+) => {
        gfx_defines! {
            $keyword $name { $($field : $ty = $e,)+ }
        }
        gfx_defines!($($tail)+);
    };
}
<|endoftext|>


<commit_before><commit_msg>Another check for cycles.<commit_after><|endoftext|>


<commit_before><commit_msg>(doc) IronResponse::from_http.<commit_after><|endoftext|>


<commit_before><commit_msg>Add first Command enums.<commit_after>pub enum Command {
    Quit,
    OpenFile { filename: String }
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #477 - zethra:master, r=alexcrichton<commit_after><|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2304<commit_after>// https://leetcode.com/problems/minimum-path-cost-in-a-grid/
pub fn min_path_cost(grid: Vec<Vec<i32>>, move_cost: Vec<Vec<i32>>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        min_path_cost(
            vec![vec![5, 3], vec![4, 0], vec![2, 1]],
            vec![
                vec![9, 8],
                vec![1, 5],
                vec![10, 12],
                vec![18, 6],
                vec![2, 4],
                vec![14, 3]
            ]
        )
    ); // 17
    println!(
        "{}",
        min_path_cost(
            vec![vec![5, 1, 2], vec![4, 0, 3]],
            vec![
                vec![12, 10, 15],
                vec![20, 23, 8],
                vec![21, 7, 1],
                vec![8, 1, 13],
                vec![9, 10, 25],
                vec![5, 3, 2]
            ]
        )
    ); // 6
}
<|endoftext|>


<commit_before>extern crate compiletest_rs as compiletest;

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

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

fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, fullmir: bool) {
    eprintln!("## Running compile-fail tests in {} against miri for target {}", path, target);
    let mut config = compiletest::default_config();
    config.mode = "compile-fail".parse().expect("Invalid mode");
    config.rustc_path = "target/debug/miri".into();
    if fullmir {
        if host != target {
            // skip fullmir on nonhost
            return;
        }
        let sysroot = Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST");
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
        config.src_base = PathBuf::from(path.to_string());
    } else {
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
        config.src_base = PathBuf::from(path.to_string());
    }
    config.target = target.to_owned();
    compiletest::run_tests(&config);
}

fn run_pass(path: &str) {
    eprintln!("## Running run-pass tests in {} against rustc", path);
    let mut config = compiletest::default_config();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target_rustcflags = Some("-Dwarnings".to_string());
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool) {
    eprintln!("## Running run-pass tests in {} against miri for target {}", path, target);
    let mut config = compiletest::default_config();
    config.mode = "mir-opt".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = PathBuf::from("target/debug/miri");
    if fullmir {
        if host != target {
            // skip fullmir on nonhost
            return;
        }
        let sysroot = Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST");
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
    }
    // don't actually execute the final binary, it might be for other targets and we only care
    // about running miri, not the binary.
    config.runtool = Some("echo \"\" || ".to_owned());
    if target == host {
        std::env::set_var("MIRI_HOST_TARGET", "yes");
    }
    compiletest::run_tests(&config);
    std::env::set_var("MIRI_HOST_TARGET", "");
}

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);
    }
}

#[test]
fn compile_test() {
    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")
    });
    let sysroot = &Path::new(sysroot.trim());
    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");

    if let Ok(path) = std::env::var("MIRI_RUSTC_TEST") {
        let mut mir_not_found = Vec::new();
        let mut crate_not_found = Vec::new();
        let mut success = 0;
        let mut failed = Vec::new();
        let mut c_abi_fns = Vec::new();
        let mut abi = Vec::new();
        let mut unsupported = Vec::new();
        let mut unimplemented_intrinsic = Vec::new();
        let mut limits = Vec::new();
        let mut files: Vec<_> = std::fs::read_dir(path).unwrap().collect();
        while let Some(file) = files.pop() {
            let file = file.unwrap();
            let path = file.path();
            if file.metadata().unwrap().is_dir() {
                if !path.to_str().unwrap().ends_with("auxiliary") {
                    // add subdirs recursively
                    files.extend(std::fs::read_dir(path).unwrap());
                }
                continue;
            }
            if !file.metadata().unwrap().is_file() || !path.to_str().unwrap().ends_with(".rs") {
                continue;
            }
            let stderr = std::io::stderr();
            write!(stderr.lock(), "test [miri-pass] {} ... ", path.display()).unwrap();
            let mut cmd = std::process::Command::new("target/debug/miri");
            cmd.arg(path);
            let libs = Path::new(&sysroot).join("lib");
            let sysroot = libs.join("rustlib").join(&host).join("lib");
            let paths = std::env::join_paths(&[libs, sysroot]).unwrap();
            cmd.env(compiletest::procsrv::dylib_env_var(), paths);
            cmd.env("MIRI_SYSROOT", Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST"));

            match cmd.output() {
                Ok(ref output) if output.status.success() => {
                    success += 1;
                    writeln!(stderr.lock(), "ok").unwrap()
                },
                Ok(output) => {
                    let output_err = std::str::from_utf8(&output.stderr).unwrap();
                    if let Some(text) = output_err.splitn(2, "no mir for `").nth(1) {
                        let end = text.find('`').unwrap();
                        mir_not_found.push(text[..end].to_string());
                        writeln!(stderr.lock(), "NO MIR FOR `{}`", &text[..end]).unwrap();
                    } else if let Some(text) = output_err.splitn(2, "can't find crate for `").nth(1) {
                        let end = text.find('`').unwrap();
                        crate_not_found.push(text[..end].to_string());
                        writeln!(stderr.lock(), "CAN'T FIND CRATE FOR `{}`", &text[..end]).unwrap();
                    } else {
                        for text in output_err.split("error: ").skip(1) {
                            let end = text.find('\n').unwrap_or(text.len());
                            let c_abi = "can't call C ABI function: ";
                            let unimplemented_intrinsic_s = "unimplemented intrinsic: ";
                            let unsupported_s = "miri does not support ";
                            let abi_s = "can't handle function with ";
                            let limit_s = "reached the configured maximum ";
                            if text.starts_with(c_abi) {
                                c_abi_fns.push(text[c_abi.len()..end].to_string());
                            } else if text.starts_with(unimplemented_intrinsic_s) {
                                unimplemented_intrinsic.push(text[unimplemented_intrinsic_s.len()..end].to_string());
                            } else if text.starts_with(unsupported_s) {
                                unsupported.push(text[unsupported_s.len()..end].to_string());
                            } else if text.starts_with(abi_s) {
                                abi.push(text[abi_s.len()..end].to_string());
                            } else if text.starts_with(limit_s) {
                                limits.push(text[limit_s.len()..end].to_string());
                            } else if text.find("aborting").is_none() {
                                failed.push(text[..end].to_string());
                            }
                        }
                        writeln!(stderr.lock(), "FAILED with exit code {:?}", output.status.code()).unwrap();
                        writeln!(stderr.lock(), "stdout: \n {}", std::str::from_utf8(&output.stdout).unwrap()).unwrap();
                        writeln!(stderr.lock(), "stderr: \n {}", output_err).unwrap();
                    }
                }
                Err(e) => {
                    writeln!(stderr.lock(), "FAILED: {}", e).unwrap();
                    panic!("failed to execute miri");
                },
            }
        }
        let stderr = std::io::stderr();
        let mut stderr = stderr.lock();
        writeln!(stderr, "{} success, {} no mir, {} crate not found, {} failed, \
                          {} C fn, {} ABI, {} unsupported, {} intrinsic",
                          success, mir_not_found.len(), crate_not_found.len(), failed.len(),
                          c_abi_fns.len(), abi.len(), unsupported.len(), unimplemented_intrinsic.len()).unwrap();
        writeln!(stderr, "# The \"other reasons\" errors").unwrap();
        writeln!(stderr, "(sorted, deduplicated)").unwrap();
        print_vec(&mut stderr, failed);

        writeln!(stderr, "# can't call C ABI function").unwrap();
        print_vec(&mut stderr, c_abi_fns);

        writeln!(stderr, "# unsupported ABI").unwrap();
        print_vec(&mut stderr, abi);

        writeln!(stderr, "# unsupported").unwrap();
        print_vec(&mut stderr, unsupported);

        writeln!(stderr, "# unimplemented intrinsics").unwrap();
        print_vec(&mut stderr, unimplemented_intrinsic);

        writeln!(stderr, "# mir not found").unwrap();
        print_vec(&mut stderr, mir_not_found);

        writeln!(stderr, "# crate not found").unwrap();
        print_vec(&mut stderr, crate_not_found);

        panic!("ran miri on rustc test suite. Test failing for convenience");
    } else {
        run_pass("tests/run-pass");
        run_pass("tests/run-pass-fullmir");
        for_all_targets(sysroot, |target| {
            miri_pass("tests/run-pass", &target, host, false);
            compile_fail(sysroot, "tests/compile-fail", &target, host, false);
        });
        miri_pass("tests/run-pass-fullmir", host, host, true);
        compile_fail(sysroot, "tests/compile-fail-fullmir", host, host, true);
    }
}

fn print_vec<W: std::io::Write>(stderr: &mut W, v: Vec<String>) {
    writeln!(stderr, "```").unwrap();
    for (n, s) in vec_to_hist(v).into_iter().rev() {
        writeln!(stderr, "{:4} {}", n, s).unwrap();
    }
    writeln!(stderr, "```").unwrap();
}

fn vec_to_hist<T: PartialEq + Ord>(mut v: Vec<T>) -> Vec<(usize, T)> {
    v.sort();
    let mut v = v.into_iter();
    let mut result = Vec::new();
    let mut current = v.next();
    'outer: while let Some(current_val) = current {
        let mut n = 1;
        for next in &mut v {
            if next == current_val {
                n += 1;
            } else {
                result.push((n, current_val));
                current = Some(next);
                continue 'outer;
            }
        }
        result.push((n, current_val));
        break;
    }
    result.sort();
    result
}
<commit_msg>split up the test suite<commit_after>extern crate compiletest_rs as compiletest;

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

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

fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, fullmir: bool) {
    eprintln!("## Running compile-fail tests in {} against miri for target {}", path, target);
    let mut config = compiletest::default_config();
    config.mode = "compile-fail".parse().expect("Invalid mode");
    config.rustc_path = "target/debug/miri".into();
    if fullmir {
        if host != target {
            // skip fullmir on nonhost
            return;
        }
        let sysroot = Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST");
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
        config.src_base = PathBuf::from(path.to_string());
    } else {
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
        config.src_base = PathBuf::from(path.to_string());
    }
    config.target = target.to_owned();
    compiletest::run_tests(&config);
}

fn run_pass(path: &str) {
    eprintln!("## Running run-pass tests in {} against rustc", path);
    let mut config = compiletest::default_config();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target_rustcflags = Some("-Dwarnings".to_string());
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool) {
    eprintln!("## Running run-pass tests in {} against miri for target {}", path, target);
    let mut config = compiletest::default_config();
    config.mode = "mir-opt".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = PathBuf::from("target/debug/miri");
    if fullmir {
        if host != target {
            // skip fullmir on nonhost
            return;
        }
        let sysroot = Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST");
        config.target_rustcflags = Some(format!("--sysroot {}", sysroot.to_str().unwrap()));
    }
    // don't actually execute the final binary, it might be for other targets and we only care
    // about running miri, not the binary.
    config.runtool = Some("echo \"\" || ".to_owned());
    if target == host {
        std::env::set_var("MIRI_HOST_TARGET", "yes");
    }
    compiletest::run_tests(&config);
    std::env::set_var("MIRI_HOST_TARGET", "");
}

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 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)
}

#[test]
fn rustc_test() {
    if let Ok(path) = std::env::var("MIRI_RUSTC_TEST") {
        let sysroot = get_sysroot();
        let host = get_host();

        let mut mir_not_found = Vec::new();
        let mut crate_not_found = Vec::new();
        let mut success = 0;
        let mut failed = Vec::new();
        let mut c_abi_fns = Vec::new();
        let mut abi = Vec::new();
        let mut unsupported = Vec::new();
        let mut unimplemented_intrinsic = Vec::new();
        let mut limits = Vec::new();
        let mut files: Vec<_> = std::fs::read_dir(path).unwrap().collect();
        while let Some(file) = files.pop() {
            let file = file.unwrap();
            let path = file.path();
            if file.metadata().unwrap().is_dir() {
                if !path.to_str().unwrap().ends_with("auxiliary") {
                    // add subdirs recursively
                    files.extend(std::fs::read_dir(path).unwrap());
                }
                continue;
            }
            if !file.metadata().unwrap().is_file() || !path.to_str().unwrap().ends_with(".rs") {
                continue;
            }
            let stderr = std::io::stderr();
            write!(stderr.lock(), "test [miri-pass] {} ... ", path.display()).unwrap();
            let mut cmd = std::process::Command::new("target/debug/miri");
            cmd.arg(path);
            let libs = Path::new(&sysroot).join("lib");
            let sysroot = libs.join("rustlib").join(&host).join("lib");
            let paths = std::env::join_paths(&[libs, sysroot]).unwrap();
            cmd.env(compiletest::procsrv::dylib_env_var(), paths);
            cmd.env("MIRI_SYSROOT", Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST"));

            match cmd.output() {
                Ok(ref output) if output.status.success() => {
                    success += 1;
                    writeln!(stderr.lock(), "ok").unwrap()
                },
                Ok(output) => {
                    let output_err = std::str::from_utf8(&output.stderr).unwrap();
                    if let Some(text) = output_err.splitn(2, "no mir for `").nth(1) {
                        let end = text.find('`').unwrap();
                        mir_not_found.push(text[..end].to_string());
                        writeln!(stderr.lock(), "NO MIR FOR `{}`", &text[..end]).unwrap();
                    } else if let Some(text) = output_err.splitn(2, "can't find crate for `").nth(1) {
                        let end = text.find('`').unwrap();
                        crate_not_found.push(text[..end].to_string());
                        writeln!(stderr.lock(), "CAN'T FIND CRATE FOR `{}`", &text[..end]).unwrap();
                    } else {
                        for text in output_err.split("error: ").skip(1) {
                            let end = text.find('\n').unwrap_or(text.len());
                            let c_abi = "can't call C ABI function: ";
                            let unimplemented_intrinsic_s = "unimplemented intrinsic: ";
                            let unsupported_s = "miri does not support ";
                            let abi_s = "can't handle function with ";
                            let limit_s = "reached the configured maximum ";
                            if text.starts_with(c_abi) {
                                c_abi_fns.push(text[c_abi.len()..end].to_string());
                            } else if text.starts_with(unimplemented_intrinsic_s) {
                                unimplemented_intrinsic.push(text[unimplemented_intrinsic_s.len()..end].to_string());
                            } else if text.starts_with(unsupported_s) {
                                unsupported.push(text[unsupported_s.len()..end].to_string());
                            } else if text.starts_with(abi_s) {
                                abi.push(text[abi_s.len()..end].to_string());
                            } else if text.starts_with(limit_s) {
                                limits.push(text[limit_s.len()..end].to_string());
                            } else if text.find("aborting").is_none() {
                                failed.push(text[..end].to_string());
                            }
                        }
                        writeln!(stderr.lock(), "FAILED with exit code {:?}", output.status.code()).unwrap();
                        writeln!(stderr.lock(), "stdout: \n {}", std::str::from_utf8(&output.stdout).unwrap()).unwrap();
                        writeln!(stderr.lock(), "stderr: \n {}", output_err).unwrap();
                    }
                }
                Err(e) => {
                    writeln!(stderr.lock(), "FAILED: {}", e).unwrap();
                    panic!("failed to execute miri");
                },
            }
        }
        let stderr = std::io::stderr();
        let mut stderr = stderr.lock();
        writeln!(stderr, "{} success, {} no mir, {} crate not found, {} failed, \
                          {} C fn, {} ABI, {} unsupported, {} intrinsic",
                          success, mir_not_found.len(), crate_not_found.len(), failed.len(),
                          c_abi_fns.len(), abi.len(), unsupported.len(), unimplemented_intrinsic.len()).unwrap();
        writeln!(stderr, "# The \"other reasons\" errors").unwrap();
        writeln!(stderr, "(sorted, deduplicated)").unwrap();
        print_vec(&mut stderr, failed);

        writeln!(stderr, "# can't call C ABI function").unwrap();
        print_vec(&mut stderr, c_abi_fns);

        writeln!(stderr, "# unsupported ABI").unwrap();
        print_vec(&mut stderr, abi);

        writeln!(stderr, "# unsupported").unwrap();
        print_vec(&mut stderr, unsupported);

        writeln!(stderr, "# unimplemented intrinsics").unwrap();
        print_vec(&mut stderr, unimplemented_intrinsic);

        writeln!(stderr, "# mir not found").unwrap();
        print_vec(&mut stderr, mir_not_found);

        writeln!(stderr, "# crate not found").unwrap();
        print_vec(&mut stderr, crate_not_found);

        panic!("ran miri on rustc test suite. Test failing for convenience");
    }
}

#[test]
fn run_pass_miri() {
    if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
        return;
    }

    let sysroot = get_sysroot();
    let host = get_host();

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

#[test]
fn run_pass_rustc() {
    if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
        return;
    }

    run_pass("tests/run-pass");
    run_pass("tests/run-pass-fullmir");
}

#[test]
fn compile_fail_miri() {
    if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
        return;
    }

    let sysroot = get_sysroot();
    let host = get_host();

    for_all_targets(&sysroot, |target| {
        compile_fail(&sysroot, "tests/compile-fail", &target, &host, false);
    });
    compile_fail(&sysroot, "tests/compile-fail-fullmir", &host, &host, true);
}

fn print_vec<W: std::io::Write>(stderr: &mut W, v: Vec<String>) {
    writeln!(stderr, "```").unwrap();
    for (n, s) in vec_to_hist(v).into_iter().rev() {
        writeln!(stderr, "{:4} {}", n, s).unwrap();
    }
    writeln!(stderr, "```").unwrap();
}

fn vec_to_hist<T: PartialEq + Ord>(mut v: Vec<T>) -> Vec<(usize, T)> {
    v.sort();
    let mut v = v.into_iter();
    let mut result = Vec::new();
    let mut current = v.next();
    'outer: while let Some(current_val) = current {
        let mut n = 1;
        for next in &mut v {
            if next == current_val {
                n += 1;
            } else {
                result.push((n, current_val));
                current = Some(next);
                continue 'outer;
            }
        }
        result.push((n, current_val));
        break;
    }
    result.sort();
    result
}
<|endoftext|>


<commit_before>use types::*;

use nom::{be_i8, be_u8, be_i16, be_u16, be_i32, be_u32, be_i64, be_u64, be_f32, be_f64};

/* FIXME: we convert to a Some so that nom can happily handle some _ case which would otherwise fail as we're exhaustive */
named!(pub parse_value<AMQPValue>,                 switch!(map!(parse_type, |t| Some(t)),
    Some(AMQPType::Boolean)        => map!(call!(parse_boolean),          |b| AMQPValue::Boolean(b))        |
    Some(AMQPType::ShortShortInt)  => map!(call!(parse_short_short_int),  |i| AMQPValue::ShortShortInt(i))  |
    Some(AMQPType::ShortShortUInt) => map!(call!(parse_short_short_uint), |u| AMQPValue::ShortShortUInt(u)) |
    Some(AMQPType::ShortInt)       => map!(call!(parse_short_int),        |i| AMQPValue::ShortInt(i))       |
    Some(AMQPType::ShortUInt)      => map!(call!(parse_short_uint),       |u| AMQPValue::ShortUInt(u))      |
    Some(AMQPType::LongInt)        => map!(call!(parse_long_int),         |i| AMQPValue::LongInt(i))        |
    Some(AMQPType::LongUInt)       => map!(call!(parse_long_uint),        |u| AMQPValue::LongUInt(u))       |
    Some(AMQPType::LongLongInt)    => map!(call!(parse_long_long_int),    |i| AMQPValue::LongLongInt(i))    |
    Some(AMQPType::LongLongUInt)   => map!(call!(parse_long_long_uint),   |u| AMQPValue::LongLongUInt(u))   |
    Some(AMQPType::Float)          => map!(call!(parse_float),            |f| AMQPValue::Float(f))          |
    Some(AMQPType::Double)         => map!(call!(parse_double),           |d| AMQPValue::Double(d))         |
    Some(AMQPType::DecimalValue)   => map!(call!(parse_decimal_value),    |d| AMQPValue::DecimalValue(d))   |
    Some(AMQPType::ShortString)    => map!(call!(parse_short_string),     |s| AMQPValue::ShortString(s))    |
    Some(AMQPType::LongString)     => map!(call!(parse_long_string),      |s| AMQPValue::LongString(s))     |
    Some(AMQPType::FieldArray)     => map!(call!(parse_field_array),      |a| AMQPValue::FieldArray(a))     |
    Some(AMQPType::Timestamp)      => map!(call!(parse_timestamp),        |t| AMQPValue::Timestamp(t))      |
    Some(AMQPType::FieldTable)     => map!(call!(parse_field_table),      |t| AMQPValue::FieldTable(t))     |
    Some(AMQPType::Void)           => value!(AMQPValue::Void)
));

named!(pub parse_type<AMQPType>,                   map_opt!(be_u8, |t| AMQPType::from_id(t as char)));

named!(pub parse_boolean<Boolean>,                 map!(be_u8, |b| b != 0));
named!(pub parse_short_short_int<ShortShortInt>,   call!(be_i8));
named!(pub parse_short_short_uint<ShortShortUInt>, call!(be_u8));
named!(pub parse_short_int<ShortInt>,              call!(be_i16));
named!(pub parse_short_uint<ShortUInt>,            call!(be_u16));
named!(pub parse_long_int<LongInt>,                call!(be_i32));
named!(pub parse_long_uint<LongUInt>,              call!(be_u32));
named!(pub parse_long_long_int<LongLongInt>,       call!(be_i64));
named!(pub parse_long_long_uint<LongLongUInt>,     call!(be_u64));
named!(pub parse_float<Float>,                     call!(be_f32));
named!(pub parse_double<Double>,                   call!(be_f64));
named!(pub parse_decimal_value<DecimalValue>,      do_parse!(scale: parse_short_short_uint >> value: parse_long_uint >> (DecimalValue { scale: scale, value: value, })));
named!(pub parse_short_string<ShortString>,        do_parse!(length: parse_short_short_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_long_string<LongString>,          do_parse!(length: parse_long_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_field_array<FieldArray>,          do_parse!(length: parse_long_int >> array: count!(parse_value, length as usize) >> (array)));
named!(pub parse_timestamp<Timestamp>,             call!(parse_long_long_uint));
named!(pub parse_field_table<FieldTable>,          do_parse!(length: parse_long_uint >> table: flat_map!(take!(length as usize), fold_many0!(complete!(pair!(parse_short_string, parse_value)), FieldTable::new(), |mut acc: FieldTable, (key, value)| {
    acc.insert(key, value);
    acc
})) >> (table)));

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

    use nom::IResult;

    const EMPTY: &'static [u8] = b"";

    #[test]
    fn test_parse_value() {
        assert_eq!(parse_value(&[84, 42, 42, 42, 42, 42,  42,  42,  42]),  IResult::Done(EMPTY, AMQPValue::Timestamp(3038287259199220266)));
        assert_eq!(parse_value(&[83, 0,  0,  0,  4,  116, 101, 115, 116]), IResult::Done(EMPTY, AMQPValue::LongString("test".to_string())));
    }

    #[test]
    fn test_parse_type() {
        assert_eq!(parse_type(&[116]), IResult::Done(EMPTY, AMQPType::Boolean));
        assert_eq!(parse_type(&[102]), IResult::Done(EMPTY, AMQPType::Float));
    }

    #[test]
    fn test_parse_boolean() {
        assert_eq!(parse_boolean(&[0]), IResult::Done(EMPTY, false));
        assert_eq!(parse_boolean(&[1]), IResult::Done(EMPTY, true));
    }

    #[test]
    fn test_parse_short_short_uint() {
        assert_eq!(parse_short_short_uint(&[0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_short_uint(&[255]), IResult::Done(EMPTY, 255));
    }

    #[test]
    fn test_parse_short_short_int() {
        assert_eq!(parse_short_short_int(&[0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_short_int(&[255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_short_uint() {
        assert_eq!(parse_short_uint(&[0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_uint(&[255, 255]), IResult::Done(EMPTY, 65535));
    }

    #[test]
    fn test_parse_short_int() {
        assert_eq!(parse_short_int(&[0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_int(&[255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_long_uint() {
        assert_eq!(parse_long_uint(&[0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_uint(&[255, 255, 255, 255]), IResult::Done(EMPTY, 4294967295));
    }

    #[test]
    fn test_parse_long_int() {
        assert_eq!(parse_long_int(&[0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_int(&[255, 255, 255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_long_long_uint() {
        assert_eq!(parse_long_long_uint(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_long_uint(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, 18446744073709551615));
    }

    #[test]
    fn test_parse_long_long_int() {
        assert_eq!(parse_long_long_int(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_long_int(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_float() {
        assert_eq!(parse_float(&[0,  0,  0,  0]),  IResult::Done(EMPTY, 0.));
        assert_eq!(parse_float(&[42, 42, 42, 42]), IResult::Done(EMPTY, 0.00000000000015113662));
    }

    #[test]
    fn test_parse_double() {
        assert_eq!(parse_double(&[0,  0,  0,  0,  0,  0,  0,  0]),  IResult::Done(EMPTY, 0.));
        assert_eq!(parse_double(&[42, 42, 42, 42, 42, 42, 42, 42]), IResult::Done(EMPTY, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014260258159703532));
    }

    #[test]
    fn test_parse_decimal_value() {
        assert_eq!(parse_decimal_value(&[0,   0,   0,   0,   0]),   IResult::Done(EMPTY, DecimalValue { scale: 0,   value: 0          }));
        assert_eq!(parse_decimal_value(&[255, 255, 255, 255, 255]), IResult::Done(EMPTY, DecimalValue { scale: 255, value: 4294967295 }));
    }

    #[test]
    fn test_parse_short_string() {
        assert_eq!(parse_short_string(&[0]),                     IResult::Done(EMPTY, ShortString::new()));
        assert_eq!(parse_short_string(&[4, 116, 101, 115, 116]), IResult::Done(EMPTY, "test".to_string()));
    }

    #[test]
    fn test_parse_long_string() {
        assert_eq!(parse_long_string(&[0, 0, 0, 0]),                     IResult::Done(EMPTY, LongString::new()));
        assert_eq!(parse_long_string(&[0, 0, 0, 4, 116, 101, 115, 116]), IResult::Done(EMPTY, "test".to_string()));
    }

    #[test]
    fn test_parse_field_array() {
        assert_eq!(parse_field_array(&[0, 0, 0, 0]),                                 IResult::Done(EMPTY, FieldArray::new()));
        assert_eq!(parse_field_array(&[0, 0, 0, 2, 115, 4, 116, 101, 115, 116, 86]), IResult::Done(EMPTY, vec![AMQPValue::ShortString("test".to_string()), AMQPValue::Void]));
    }

    #[test]
    fn test_parse_timestamp() {
        assert_eq!(parse_timestamp(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_timestamp(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, 18446744073709551615));
    }

    #[test]
    fn test_parse_field_table() {
        let mut table = FieldTable::new();
        table.insert("test".to_string(), AMQPValue::ShortString("test".to_string()));
        table.insert("tt".to_string(),   AMQPValue::Void);
        assert_eq!(parse_field_table(&[0, 0, 0, 0]),                                                                      IResult::Done(EMPTY, FieldTable::new()));
        assert_eq!(parse_field_table(&[0, 0, 0, 15, 4, 116, 101, 115, 116, 115, 4, 116, 101, 115, 116, 2, 116, 116, 86]), IResult::Done(EMPTY, table));
    }
}
<commit_msg>types: reorder tests<commit_after>use types::*;

use nom::{be_i8, be_u8, be_i16, be_u16, be_i32, be_u32, be_i64, be_u64, be_f32, be_f64};

/* FIXME: we convert to a Some so that nom can happily handle some _ case which would otherwise fail as we're exhaustive */
named!(pub parse_value<AMQPValue>,                 switch!(map!(parse_type, |t| Some(t)),
    Some(AMQPType::Boolean)        => map!(call!(parse_boolean),          |b| AMQPValue::Boolean(b))        |
    Some(AMQPType::ShortShortInt)  => map!(call!(parse_short_short_int),  |i| AMQPValue::ShortShortInt(i))  |
    Some(AMQPType::ShortShortUInt) => map!(call!(parse_short_short_uint), |u| AMQPValue::ShortShortUInt(u)) |
    Some(AMQPType::ShortInt)       => map!(call!(parse_short_int),        |i| AMQPValue::ShortInt(i))       |
    Some(AMQPType::ShortUInt)      => map!(call!(parse_short_uint),       |u| AMQPValue::ShortUInt(u))      |
    Some(AMQPType::LongInt)        => map!(call!(parse_long_int),         |i| AMQPValue::LongInt(i))        |
    Some(AMQPType::LongUInt)       => map!(call!(parse_long_uint),        |u| AMQPValue::LongUInt(u))       |
    Some(AMQPType::LongLongInt)    => map!(call!(parse_long_long_int),    |i| AMQPValue::LongLongInt(i))    |
    Some(AMQPType::LongLongUInt)   => map!(call!(parse_long_long_uint),   |u| AMQPValue::LongLongUInt(u))   |
    Some(AMQPType::Float)          => map!(call!(parse_float),            |f| AMQPValue::Float(f))          |
    Some(AMQPType::Double)         => map!(call!(parse_double),           |d| AMQPValue::Double(d))         |
    Some(AMQPType::DecimalValue)   => map!(call!(parse_decimal_value),    |d| AMQPValue::DecimalValue(d))   |
    Some(AMQPType::ShortString)    => map!(call!(parse_short_string),     |s| AMQPValue::ShortString(s))    |
    Some(AMQPType::LongString)     => map!(call!(parse_long_string),      |s| AMQPValue::LongString(s))     |
    Some(AMQPType::FieldArray)     => map!(call!(parse_field_array),      |a| AMQPValue::FieldArray(a))     |
    Some(AMQPType::Timestamp)      => map!(call!(parse_timestamp),        |t| AMQPValue::Timestamp(t))      |
    Some(AMQPType::FieldTable)     => map!(call!(parse_field_table),      |t| AMQPValue::FieldTable(t))     |
    Some(AMQPType::Void)           => value!(AMQPValue::Void)
));

named!(pub parse_type<AMQPType>,                   map_opt!(be_u8, |t| AMQPType::from_id(t as char)));

named!(pub parse_boolean<Boolean>,                 map!(be_u8, |b| b != 0));
named!(pub parse_short_short_int<ShortShortInt>,   call!(be_i8));
named!(pub parse_short_short_uint<ShortShortUInt>, call!(be_u8));
named!(pub parse_short_int<ShortInt>,              call!(be_i16));
named!(pub parse_short_uint<ShortUInt>,            call!(be_u16));
named!(pub parse_long_int<LongInt>,                call!(be_i32));
named!(pub parse_long_uint<LongUInt>,              call!(be_u32));
named!(pub parse_long_long_int<LongLongInt>,       call!(be_i64));
named!(pub parse_long_long_uint<LongLongUInt>,     call!(be_u64));
named!(pub parse_float<Float>,                     call!(be_f32));
named!(pub parse_double<Double>,                   call!(be_f64));
named!(pub parse_decimal_value<DecimalValue>,      do_parse!(scale: parse_short_short_uint >> value: parse_long_uint >> (DecimalValue { scale: scale, value: value, })));
named!(pub parse_short_string<ShortString>,        do_parse!(length: parse_short_short_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_long_string<LongString>,          do_parse!(length: parse_long_uint >> s: take_str!(length) >> (s.to_string())));
named!(pub parse_field_array<FieldArray>,          do_parse!(length: parse_long_int >> array: count!(parse_value, length as usize) >> (array)));
named!(pub parse_timestamp<Timestamp>,             call!(parse_long_long_uint));
named!(pub parse_field_table<FieldTable>,          do_parse!(length: parse_long_uint >> table: flat_map!(take!(length as usize), fold_many0!(complete!(pair!(parse_short_string, parse_value)), FieldTable::new(), |mut acc: FieldTable, (key, value)| {
    acc.insert(key, value);
    acc
})) >> (table)));

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

    use nom::IResult;

    const EMPTY: &'static [u8] = b"";

    #[test]
    fn test_parse_value() {
        assert_eq!(parse_value(&[84, 42, 42, 42, 42, 42,  42,  42,  42]),  IResult::Done(EMPTY, AMQPValue::Timestamp(3038287259199220266)));
        assert_eq!(parse_value(&[83, 0,  0,  0,  4,  116, 101, 115, 116]), IResult::Done(EMPTY, AMQPValue::LongString("test".to_string())));
    }

    #[test]
    fn test_parse_type() {
        assert_eq!(parse_type(&[116]), IResult::Done(EMPTY, AMQPType::Boolean));
        assert_eq!(parse_type(&[102]), IResult::Done(EMPTY, AMQPType::Float));
    }

    #[test]
    fn test_parse_boolean() {
        assert_eq!(parse_boolean(&[0]), IResult::Done(EMPTY, false));
        assert_eq!(parse_boolean(&[1]), IResult::Done(EMPTY, true));
    }

    #[test]
    fn test_parse_short_short_int() {
        assert_eq!(parse_short_short_int(&[0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_short_int(&[255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_short_short_uint() {
        assert_eq!(parse_short_short_uint(&[0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_short_uint(&[255]), IResult::Done(EMPTY, 255));
    }

    #[test]
    fn test_parse_short_int() {
        assert_eq!(parse_short_int(&[0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_int(&[255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_short_uint() {
        assert_eq!(parse_short_uint(&[0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_short_uint(&[255, 255]), IResult::Done(EMPTY, 65535));
    }

    #[test]
    fn test_parse_long_int() {
        assert_eq!(parse_long_int(&[0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_int(&[255, 255, 255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_long_uint() {
        assert_eq!(parse_long_uint(&[0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_uint(&[255, 255, 255, 255]), IResult::Done(EMPTY, 4294967295));
    }

    #[test]
    fn test_parse_long_long_int() {
        assert_eq!(parse_long_long_int(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_long_int(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, -1));
    }

    #[test]
    fn test_parse_long_long_uint() {
        assert_eq!(parse_long_long_uint(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_long_long_uint(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, 18446744073709551615));
    }

    #[test]
    fn test_parse_float() {
        assert_eq!(parse_float(&[0,  0,  0,  0]),  IResult::Done(EMPTY, 0.));
        assert_eq!(parse_float(&[42, 42, 42, 42]), IResult::Done(EMPTY, 0.00000000000015113662));
    }

    #[test]
    fn test_parse_double() {
        assert_eq!(parse_double(&[0,  0,  0,  0,  0,  0,  0,  0]),  IResult::Done(EMPTY, 0.));
        assert_eq!(parse_double(&[42, 42, 42, 42, 42, 42, 42, 42]), IResult::Done(EMPTY, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014260258159703532));
    }

    #[test]
    fn test_parse_decimal_value() {
        assert_eq!(parse_decimal_value(&[0,   0,   0,   0,   0]),   IResult::Done(EMPTY, DecimalValue { scale: 0,   value: 0          }));
        assert_eq!(parse_decimal_value(&[255, 255, 255, 255, 255]), IResult::Done(EMPTY, DecimalValue { scale: 255, value: 4294967295 }));
    }

    #[test]
    fn test_parse_short_string() {
        assert_eq!(parse_short_string(&[0]),                     IResult::Done(EMPTY, ShortString::new()));
        assert_eq!(parse_short_string(&[4, 116, 101, 115, 116]), IResult::Done(EMPTY, "test".to_string()));
    }

    #[test]
    fn test_parse_long_string() {
        assert_eq!(parse_long_string(&[0, 0, 0, 0]),                     IResult::Done(EMPTY, LongString::new()));
        assert_eq!(parse_long_string(&[0, 0, 0, 4, 116, 101, 115, 116]), IResult::Done(EMPTY, "test".to_string()));
    }

    #[test]
    fn test_parse_field_array() {
        assert_eq!(parse_field_array(&[0, 0, 0, 0]),                                 IResult::Done(EMPTY, FieldArray::new()));
        assert_eq!(parse_field_array(&[0, 0, 0, 2, 115, 4, 116, 101, 115, 116, 86]), IResult::Done(EMPTY, vec![AMQPValue::ShortString("test".to_string()), AMQPValue::Void]));
    }

    #[test]
    fn test_parse_timestamp() {
        assert_eq!(parse_timestamp(&[0,   0,   0,   0,   0,   0,   0,   0]),   IResult::Done(EMPTY, 0));
        assert_eq!(parse_timestamp(&[255, 255, 255, 255, 255, 255, 255, 255]), IResult::Done(EMPTY, 18446744073709551615));
    }

    #[test]
    fn test_parse_field_table() {
        let mut table = FieldTable::new();
        table.insert("test".to_string(), AMQPValue::ShortString("test".to_string()));
        table.insert("tt".to_string(),   AMQPValue::Void);
        assert_eq!(parse_field_table(&[0, 0, 0, 0]),                                                                      IResult::Done(EMPTY, FieldTable::new()));
        assert_eq!(parse_field_table(&[0, 0, 0, 15, 4, 116, 101, 115, 116, 115, 4, 116, 101, 115, 116, 2, 116, 116, 86]), IResult::Done(EMPTY, table));
    }
}
<|endoftext|>


<commit_before><commit_msg>Simplify getting grouped data for a given date.<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate glium;

mod support;

use glium::Surface;
use glium::glutin;
use glium::index::PrimitiveType;
use glium::program::ShaderStage;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
        }

        implement_vertex!(Vertex, position);

        glium::VertexBuffer::new(&display,
            &[
                Vertex { position: [-0.5, -0.5] },
                Vertex { position: [ 0.0,  0.5] },
                Vertex { position: [ 0.5, -0.5] },
            ]
        ).unwrap()
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList,
                                               &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        330 => {
            vertex: "
                #version 330

                uniform mat4 matrix;

                in vec2 position;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                }
            ",

            fragment: "
                #version 330
                #extension GL_ARB_shader_subroutine : require

                out vec4 fragColor;
                subroutine vec4 color_t();

                subroutine uniform color_t Color;

                subroutine(color_t)
                vec4 ColorRed()
                {
                  return vec4(1, 0, 0, 1);
                }

                subroutine(color_t)
                vec4 ColorBlue()
                {
                  return vec4(0, 0.4, 1, 1);
                }

                subroutine(color_t)
                vec4 ColorYellow()
                {
                  return vec4(1, 1, 0, 1);
                }

                void main()
                {
                    fragColor = Color();
                }
            "
        },
    ).unwrap();

    let mut i = 0;
    // the main loop
    support::start_loop(|| {

        let subroutine = if i % 120 < 40 {
            "ColorYellow"
        } else if i % 120 < 80{
            "ColorBlue"
        } else {
            "ColorRed"
        };

        // building the uniforms
        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ],
            Color: (subroutine, ShaderStage::Fragment)
        };

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
        target.finish().unwrap();

        // polling and handling the events received by the window
        for event in display.poll_events() {
            match event {
                glutin::Event::Closed => return support::Action::Stop,
                _ => ()
            }
        }
        i += 1;
        support::Action::Continue
    });
}
<commit_msg>Fix overflow bug in subroutines example<commit_after>#[macro_use]
extern crate glium;

mod support;

use glium::Surface;
use glium::glutin;
use glium::index::PrimitiveType;
use glium::program::ShaderStage;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
        }

        implement_vertex!(Vertex, position);

        glium::VertexBuffer::new(&display,
            &[
                Vertex { position: [-0.5, -0.5] },
                Vertex { position: [ 0.0,  0.5] },
                Vertex { position: [ 0.5, -0.5] },
            ]
        ).unwrap()
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList,
                                               &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        330 => {
            vertex: "
                #version 330

                uniform mat4 matrix;

                in vec2 position;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                }
            ",

            fragment: "
                #version 330
                #extension GL_ARB_shader_subroutine : require

                out vec4 fragColor;
                subroutine vec4 color_t();

                subroutine uniform color_t Color;

                subroutine(color_t)
                vec4 ColorRed()
                {
                  return vec4(1, 0, 0, 1);
                }

                subroutine(color_t)
                vec4 ColorBlue()
                {
                  return vec4(0, 0.4, 1, 1);
                }

                subroutine(color_t)
                vec4 ColorYellow()
                {
                  return vec4(1, 1, 0, 1);
                }

                void main()
                {
                    fragColor = Color();
                }
            "
        },
    ).unwrap();

    let mut i = 0;
    // the main loop
    support::start_loop(|| {
        if i == 120 { i = 0; }
        let subroutine = if i % 120 < 40 {
            "ColorYellow"
        } else if i % 120 < 80{
            "ColorBlue"
        } else {
            "ColorRed"
        };

        // building the uniforms
        let uniforms = uniform! {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ],
            Color: (subroutine, ShaderStage::Fragment)
        };

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
        target.finish().unwrap();

        // polling and handling the events received by the window
        for event in display.poll_events() {
            match event {
                glutin::Event::Closed => return support::Action::Stop,
                _ => ()
            }
        }
        i += 1;
        support::Action::Continue
    });
}
<|endoftext|>


<commit_before><commit_msg>Tilde now properly expands inside a normal word (#398)<commit_after><|endoftext|>


<commit_before><commit_msg>ext: deprecate convert<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test that imports can't circumvent exports<commit_after>// xfail-boot
// error-pattern: unresolved name

import m.unexported;

mod m {
  export exported;

  fn exported() {
  }

  fn unexported() {
  }
}

fn main() {
  unexported();
}
<|endoftext|>


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

// error-pattern:mismatched types
// error-pattern:expected bool, found integral variable
// error-pattern:expected type `bool`
// error-pattern:found type `_`

fn main(){assert!(1,1);}
<commit_msg>Fix up error-pattern style test<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:mismatched types

fn main(){assert!(1,1);}
<|endoftext|>


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

// Test that the parser does not attempt to parse struct literals
// within assignments in if expressions.

struct Foo {
    foo: uint
}

fn main() {
    let x = 1u;
    let y: Foo;

    // `x { ... }` should not be interpreted as a struct literal here
    if x = x {
        //~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
        println!("{}", x);
    }
    // Explicit parentheses on the left should match behavior of above
    if (x = x) {
        //~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
        println!("{}", x);
    }
    // The struct literal interpretation is fine with explicit parentheses on the right
    if y = (Foo { foo: x }) {
        //~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
        println!("{}", x);
    }
}
<|endoftext|>


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

extern crate toml;
extern crate rustc_serialize;

use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};

static HOSTS: &'static [&'static str] = &[
    "aarch64-unknown-linux-gnu",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "armv7-unknown-linux-gnueabihf",
    "i686-apple-darwin",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-linux-gnu",
    "mips-unknown-linux-gnu",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "x86_64-apple-darwin",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-netbsd",
];

static TARGETS: &'static [&'static str] = &[
    "aarch64-apple-ios",
    "aarch64-linux-android",
    "aarch64-unknown-linux-gnu",
    "arm-linux-androideabi",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "arm-unknown-linux-musleabi",
    "arm-unknown-linux-musleabihf",
    "armv7-apple-ios",
    "armv7-linux-androideabi",
    "armv7-unknown-linux-gnueabihf",
    "armv7-unknown-linux-musleabihf",
    "armv7s-apple-ios",
    "asmjs-unknown-emscripten",
    "i386-apple-ios",
    "i586-pc-windows-msvc",
    "i586-unknown-linux-gnu",
    "i686-apple-darwin",
    "i686-linux-android",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-freebsd",
    "i686-unknown-linux-gnu",
    "i686-unknown-linux-musl",
    "mips-unknown-linux-gnu",
    "mips-unknown-linux-musl",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "mipsel-unknown-linux-musl",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "wasm32-unknown-emscripten",
    "x86_64-apple-darwin",
    "x86_64-apple-ios",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-rumprun-netbsd",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-linux-musl",
    "x86_64-unknown-netbsd",
];

static MINGW: &'static [&'static str] = &[
    "i686-pc-windows-gnu",
    "x86_64-pc-windows-gnu",
];

#[derive(RustcEncodable)]
struct Manifest {
    manifest_version: String,
    date: String,
    pkg: HashMap<String, Package>,
}

#[derive(RustcEncodable)]
struct Package {
    version: String,
    target: HashMap<String, Target>,
}

#[derive(RustcEncodable)]
struct Target {
    available: bool,
    url: Option<String>,
    hash: Option<String>,
    components: Option<Vec<Component>>,
    extensions: Option<Vec<Component>>,
}

#[derive(RustcEncodable)]
struct Component {
    pkg: String,
    target: String,
}

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

struct Builder {
    channel: String,
    input: PathBuf,
    output: PathBuf,
    gpg_passphrase: String,
    digests: HashMap<String, String>,
    s3_address: String,
    date: String,
    rust_version: String,
    cargo_version: String,
}

fn main() {
    let mut args = env::args().skip(1);
    let input = PathBuf::from(args.next().unwrap());
    let output = PathBuf::from(args.next().unwrap());
    let date = args.next().unwrap();
    let channel = args.next().unwrap();
    let s3_address = args.next().unwrap();
    let mut passphrase = String::new();
    t!(io::stdin().read_to_string(&mut passphrase));

    Builder {
        channel: channel,
        input: input,
        output: output,
        gpg_passphrase: passphrase,
        digests: HashMap::new(),
        s3_address: s3_address,
        date: date,
        rust_version: String::new(),
        cargo_version: String::new(),
    }.build();
}

impl Builder {
    fn build(&mut self) {
        self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
        self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");

        self.digest_and_sign();
        let manifest = self.build_manifest();
        let manifest = toml::encode(&manifest).to_string();

        let filename = format!("channel-rust-{}.toml", self.channel);
        self.write_manifest(&manifest, &filename);

        if self.channel != "beta" && self.channel != "nightly" {
            self.write_manifest(&manifest, "channel-rust-stable.toml");
        }
    }

    fn digest_and_sign(&mut self) {
        for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
            let filename = file.file_name().unwrap().to_str().unwrap();
            let digest = self.hash(&file);
            self.sign(&file);
            assert!(self.digests.insert(filename.to_string(), digest).is_none());
        }
    }

    fn build_manifest(&mut self) -> Manifest {
        let mut manifest = Manifest {
            manifest_version: "2".to_string(),
            date: self.date.to_string(),
            pkg: HashMap::new(),
        };

        self.package("rustc", &mut manifest.pkg, HOSTS);
        self.package("cargo", &mut manifest.pkg, HOSTS);
        self.package("rust-mingw", &mut manifest.pkg, MINGW);
        self.package("rust-std", &mut manifest.pkg, TARGETS);
        self.package("rust-docs", &mut manifest.pkg, TARGETS);
        self.package("rust-src", &mut manifest.pkg, &["*"]);

        let mut pkg = Package {
            version: self.cached_version("rust").to_string(),
            target: HashMap::new(),
        };
        for host in HOSTS {
            let filename = self.filename("rust", host);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    pkg.target.insert(host.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    });
                    continue
                }
            };
            let mut components = Vec::new();
            let mut extensions = Vec::new();

            // rustc/rust-std/cargo are all required, and so is rust-mingw if it's
            // available for the target.
            components.extend(vec![
                Component { pkg: "rustc".to_string(), target: host.to_string() },
                Component { pkg: "rust-std".to_string(), target: host.to_string() },
                Component { pkg: "cargo".to_string(), target: host.to_string() },
            ]);
            if host.contains("pc-windows-gnu") {
                components.push(Component {
                    pkg: "rust-mingw".to_string(),
                    target: host.to_string(),
                });
            }

            // Docs, other standard libraries, and the source package are all
            // optional.
            extensions.push(Component {
                pkg: "rust-docs".to_string(),
                target: host.to_string(),
            });
            for target in TARGETS {
                if target != host {
                    extensions.push(Component {
                        pkg: "rust-std".to_string(),
                        target: target.to_string(),
                    });
                }
            }
            extensions.push(Component {
                pkg: "rust-src".to_string(),
                target: "*".to_string(),
            });

            pkg.target.insert(host.to_string(), Target {
                available: true,
                url: Some(self.url("rust", host)),
                hash: Some(to_hex(digest.as_ref())),
                components: Some(components),
                extensions: Some(extensions),
            });
        }
        manifest.pkg.insert("rust".to_string(), pkg);

        return manifest
    }

    fn package(&mut self,
               pkgname: &str,
               dst: &mut HashMap<String, Package>,
               targets: &[&str]) {
        let targets = targets.iter().map(|name| {
            let filename = self.filename(pkgname, name);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    return (name.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    })
                }
            };

            (name.to_string(), Target {
                available: true,
                url: Some(self.url(pkgname, name)),
                hash: Some(digest),
                components: None,
                extensions: None,
            })
        }).collect();

        dst.insert(pkgname.to_string(), Package {
            version: self.cached_version(pkgname).to_string(),
            target: targets,
        });
    }

    fn url(&self, component: &str, target: &str) -> String {
        format!("{}/{}/{}",
                self.s3_address,
                self.date,
                self.filename(component, target))
    }

    fn filename(&self, component: &str, target: &str) -> String {
        if component == "rust-src" {
            format!("rust-src-{}.tar.gz", self.channel)
        } else {
            format!("{}-{}-{}.tar.gz", component, self.channel, target)
        }
    }

    fn cached_version(&self, component: &str) -> &str {
        if component == "cargo" {
            &self.cargo_version
        } else {
            &self.rust_version
        }
    }

    fn version(&self, component: &str, target: &str) -> String {
        let mut cmd = Command::new("tar");
        let filename = self.filename(component, target);
        cmd.arg("xf")
           .arg(self.input.join(&filename))
           .arg(format!("{}/version", filename.replace(".tar.gz", "")))
           .arg("-O");
        let version = t!(cmd.output());
        if !version.status.success() {
            panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}",
                   cmd,
                   String::from_utf8_lossy(&version.stdout),
                   String::from_utf8_lossy(&version.stderr));
        }
        String::from_utf8_lossy(&version.stdout).trim().to_string()
    }

    fn hash(&self, path: &Path) -> String {
        let sha = t!(Command::new("shasum")
                        .arg("-a").arg("256")
                        .arg(path)
                        .output());
        assert!(sha.status.success());

        let filename = path.file_name().unwrap().to_str().unwrap();
        let sha256 = self.output.join(format!("{}.sha256", filename));
        t!(t!(File::create(&sha256)).write_all(&sha.stdout));

        let stdout = String::from_utf8_lossy(&sha.stdout);
        stdout.split_whitespace().next().unwrap().to_string()
    }

    fn sign(&self, path: &Path) {
        let filename = path.file_name().unwrap().to_str().unwrap();
        let asc = self.output.join(format!("{}.asc", filename));
        println!("signing: {:?}", path);
        let mut cmd = Command::new("gpg");
        cmd.arg("--no-tty")
            .arg("--yes")
            .arg("--passphrase-fd").arg("0")
            .arg("--armor")
            .arg("--output").arg(&asc)
            .arg("--detach-sign").arg(path)
            .stdin(Stdio::piped());
        let mut child = t!(cmd.spawn());
        t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes()));
        assert!(t!(child.wait()).success());
    }

    fn write_manifest(&self, manifest: &str, name: &str) {
        let dst = self.output.join(name);
        t!(t!(File::create(&dst)).write_all(manifest.as_bytes()));
        self.hash(&dst);
        self.sign(&dst);
    }
}

fn to_hex(digest: &[u8]) -> String {
    let mut ret = String::new();
    for byte in digest {
        ret.push(hex((byte & 0xf0) >> 4));
        ret.push(hex(byte & 0xf));
    }
    return ret;

    fn hex(b: u8) -> char {
        match b {
            0...9 => (b'0' + b) as char,
            _ => (b'a' + b - 10) as char,
        }
    }
}
<commit_msg>Rollup merge of #39630 - alexcrichton:update-manifest, r=brson<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate toml;
extern crate rustc_serialize;

use std::collections::{BTreeMap, HashMap};
use std::env;
use std::fs::File;
use std::io::{self, Read, Write};
use std::path::{PathBuf, Path};
use std::process::{Command, Stdio};

static HOSTS: &'static [&'static str] = &[
    "aarch64-unknown-linux-gnu",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "armv7-unknown-linux-gnueabihf",
    "i686-apple-darwin",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-linux-gnu",
    "mips-unknown-linux-gnu",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "x86_64-apple-darwin",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-netbsd",
];

static TARGETS: &'static [&'static str] = &[
    "aarch64-apple-ios",
    "aarch64-linux-android",
    "aarch64-unknown-linux-gnu",
    "arm-linux-androideabi",
    "arm-unknown-linux-gnueabi",
    "arm-unknown-linux-gnueabihf",
    "arm-unknown-linux-musleabi",
    "arm-unknown-linux-musleabihf",
    "armv7-apple-ios",
    "armv7-linux-androideabi",
    "armv7-unknown-linux-gnueabihf",
    "armv7-unknown-linux-musleabihf",
    "armv7s-apple-ios",
    "asmjs-unknown-emscripten",
    "i386-apple-ios",
    "i586-pc-windows-msvc",
    "i586-unknown-linux-gnu",
    "i686-apple-darwin",
    "i686-linux-android",
    "i686-pc-windows-gnu",
    "i686-pc-windows-msvc",
    "i686-unknown-freebsd",
    "i686-unknown-linux-gnu",
    "i686-unknown-linux-musl",
    "mips-unknown-linux-gnu",
    "mips-unknown-linux-musl",
    "mips64-unknown-linux-gnuabi64",
    "mips64el-unknown-linux-gnuabi64",
    "mipsel-unknown-linux-gnu",
    "mipsel-unknown-linux-musl",
    "powerpc-unknown-linux-gnu",
    "powerpc64-unknown-linux-gnu",
    "powerpc64le-unknown-linux-gnu",
    "s390x-unknown-linux-gnu",
    "wasm32-unknown-emscripten",
    "x86_64-apple-darwin",
    "x86_64-apple-ios",
    "x86_64-pc-windows-gnu",
    "x86_64-pc-windows-msvc",
    "x86_64-rumprun-netbsd",
    "x86_64-unknown-freebsd",
    "x86_64-unknown-linux-gnu",
    "x86_64-unknown-linux-musl",
    "x86_64-unknown-netbsd",
];

static MINGW: &'static [&'static str] = &[
    "i686-pc-windows-gnu",
    "x86_64-pc-windows-gnu",
];

struct Manifest {
    manifest_version: String,
    date: String,
    pkg: HashMap<String, Package>,
}

#[derive(RustcEncodable)]
struct Package {
    version: String,
    target: HashMap<String, Target>,
}

#[derive(RustcEncodable)]
struct Target {
    available: bool,
    url: Option<String>,
    hash: Option<String>,
    components: Option<Vec<Component>>,
    extensions: Option<Vec<Component>>,
}

#[derive(RustcEncodable)]
struct Component {
    pkg: String,
    target: String,
}

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {}", stringify!($e), e),
    })
}

struct Builder {
    channel: String,
    input: PathBuf,
    output: PathBuf,
    gpg_passphrase: String,
    digests: HashMap<String, String>,
    s3_address: String,
    date: String,
    rust_version: String,
    cargo_version: String,
}

fn main() {
    let mut args = env::args().skip(1);
    let input = PathBuf::from(args.next().unwrap());
    let output = PathBuf::from(args.next().unwrap());
    let date = args.next().unwrap();
    let channel = args.next().unwrap();
    let s3_address = args.next().unwrap();
    let mut passphrase = String::new();
    t!(io::stdin().read_to_string(&mut passphrase));

    Builder {
        channel: channel,
        input: input,
        output: output,
        gpg_passphrase: passphrase,
        digests: HashMap::new(),
        s3_address: s3_address,
        date: date,
        rust_version: String::new(),
        cargo_version: String::new(),
    }.build();
}

impl Builder {
    fn build(&mut self) {
        self.rust_version = self.version("rust", "x86_64-unknown-linux-gnu");
        self.cargo_version = self.version("cargo", "x86_64-unknown-linux-gnu");

        self.digest_and_sign();
        let Manifest { manifest_version, date, pkg } = self.build_manifest();

        // Unfortunately we can't use derive(RustcEncodable) here because the
        // version field is called `manifest-version`, not `manifest_version`.
        // In lieu of that just create the table directly here with a `BTreeMap`
        // and wrap it up in a `Value::Table`.
        let mut manifest = BTreeMap::new();
        manifest.insert("manifest-version".to_string(),
                        toml::encode(&manifest_version));
        manifest.insert("date".to_string(), toml::encode(&date));
        manifest.insert("pkg".to_string(), toml::encode(&pkg));
        let manifest = toml::Value::Table(manifest).to_string();

        let filename = format!("channel-rust-{}.toml", self.channel);
        self.write_manifest(&manifest, &filename);

        if self.channel != "beta" && self.channel != "nightly" {
            self.write_manifest(&manifest, "channel-rust-stable.toml");
        }
    }

    fn digest_and_sign(&mut self) {
        for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
            let filename = file.file_name().unwrap().to_str().unwrap();
            let digest = self.hash(&file);
            self.sign(&file);
            assert!(self.digests.insert(filename.to_string(), digest).is_none());
        }
    }

    fn build_manifest(&mut self) -> Manifest {
        let mut manifest = Manifest {
            manifest_version: "2".to_string(),
            date: self.date.to_string(),
            pkg: HashMap::new(),
        };

        self.package("rustc", &mut manifest.pkg, HOSTS);
        self.package("cargo", &mut manifest.pkg, HOSTS);
        self.package("rust-mingw", &mut manifest.pkg, MINGW);
        self.package("rust-std", &mut manifest.pkg, TARGETS);
        self.package("rust-docs", &mut manifest.pkg, TARGETS);
        self.package("rust-src", &mut manifest.pkg, &["*"]);

        let mut pkg = Package {
            version: self.cached_version("rust").to_string(),
            target: HashMap::new(),
        };
        for host in HOSTS {
            let filename = self.filename("rust", host);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    pkg.target.insert(host.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    });
                    continue
                }
            };
            let mut components = Vec::new();
            let mut extensions = Vec::new();

            // rustc/rust-std/cargo are all required, and so is rust-mingw if it's
            // available for the target.
            components.extend(vec![
                Component { pkg: "rustc".to_string(), target: host.to_string() },
                Component { pkg: "rust-std".to_string(), target: host.to_string() },
                Component { pkg: "cargo".to_string(), target: host.to_string() },
            ]);
            if host.contains("pc-windows-gnu") {
                components.push(Component {
                    pkg: "rust-mingw".to_string(),
                    target: host.to_string(),
                });
            }

            // Docs, other standard libraries, and the source package are all
            // optional.
            extensions.push(Component {
                pkg: "rust-docs".to_string(),
                target: host.to_string(),
            });
            for target in TARGETS {
                if target != host {
                    extensions.push(Component {
                        pkg: "rust-std".to_string(),
                        target: target.to_string(),
                    });
                }
            }
            extensions.push(Component {
                pkg: "rust-src".to_string(),
                target: "*".to_string(),
            });

            pkg.target.insert(host.to_string(), Target {
                available: true,
                url: Some(self.url("rust", host)),
                hash: Some(to_hex(digest.as_ref())),
                components: Some(components),
                extensions: Some(extensions),
            });
        }
        manifest.pkg.insert("rust".to_string(), pkg);

        return manifest
    }

    fn package(&mut self,
               pkgname: &str,
               dst: &mut HashMap<String, Package>,
               targets: &[&str]) {
        let targets = targets.iter().map(|name| {
            let filename = self.filename(pkgname, name);
            let digest = match self.digests.remove(&filename) {
                Some(digest) => digest,
                None => {
                    return (name.to_string(), Target {
                        available: false,
                        url: None,
                        hash: None,
                        components: None,
                        extensions: None,
                    })
                }
            };

            (name.to_string(), Target {
                available: true,
                url: Some(self.url(pkgname, name)),
                hash: Some(digest),
                components: None,
                extensions: None,
            })
        }).collect();

        dst.insert(pkgname.to_string(), Package {
            version: self.cached_version(pkgname).to_string(),
            target: targets,
        });
    }

    fn url(&self, component: &str, target: &str) -> String {
        format!("{}/{}/{}",
                self.s3_address,
                self.date,
                self.filename(component, target))
    }

    fn filename(&self, component: &str, target: &str) -> String {
        if component == "rust-src" {
            format!("rust-src-{}.tar.gz", self.channel)
        } else {
            format!("{}-{}-{}.tar.gz", component, self.channel, target)
        }
    }

    fn cached_version(&self, component: &str) -> &str {
        if component == "cargo" {
            &self.cargo_version
        } else {
            &self.rust_version
        }
    }

    fn version(&self, component: &str, target: &str) -> String {
        let mut cmd = Command::new("tar");
        let filename = self.filename(component, target);
        cmd.arg("xf")
           .arg(self.input.join(&filename))
           .arg(format!("{}/version", filename.replace(".tar.gz", "")))
           .arg("-O");
        let version = t!(cmd.output());
        if !version.status.success() {
            panic!("failed to learn version:\n\n{:?}\n\n{}\n\n{}",
                   cmd,
                   String::from_utf8_lossy(&version.stdout),
                   String::from_utf8_lossy(&version.stderr));
        }
        String::from_utf8_lossy(&version.stdout).trim().to_string()
    }

    fn hash(&self, path: &Path) -> String {
        let sha = t!(Command::new("shasum")
                        .arg("-a").arg("256")
                        .arg(path)
                        .output());
        assert!(sha.status.success());

        let filename = path.file_name().unwrap().to_str().unwrap();
        let sha256 = self.output.join(format!("{}.sha256", filename));
        t!(t!(File::create(&sha256)).write_all(&sha.stdout));

        let stdout = String::from_utf8_lossy(&sha.stdout);
        stdout.split_whitespace().next().unwrap().to_string()
    }

    fn sign(&self, path: &Path) {
        let filename = path.file_name().unwrap().to_str().unwrap();
        let asc = self.output.join(format!("{}.asc", filename));
        println!("signing: {:?}", path);
        let mut cmd = Command::new("gpg");
        cmd.arg("--no-tty")
            .arg("--yes")
            .arg("--passphrase-fd").arg("0")
            .arg("--armor")
            .arg("--output").arg(&asc)
            .arg("--detach-sign").arg(path)
            .stdin(Stdio::piped());
        let mut child = t!(cmd.spawn());
        t!(child.stdin.take().unwrap().write_all(self.gpg_passphrase.as_bytes()));
        assert!(t!(child.wait()).success());
    }

    fn write_manifest(&self, manifest: &str, name: &str) {
        let dst = self.output.join(name);
        t!(t!(File::create(&dst)).write_all(manifest.as_bytes()));
        self.hash(&dst);
        self.sign(&dst);
    }
}

fn to_hex(digest: &[u8]) -> String {
    let mut ret = String::new();
    for byte in digest {
        ret.push(hex((byte & 0xf0) >> 4));
        ret.push(hex(byte & 0xf));
    }
    return ret;

    fn hex(b: u8) -> char {
        match b {
            0...9 => (b'0' + b) as char,
            _ => (b'a' + b - 10) as char,
        }
    }
}
<|endoftext|>


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

trait A<T: A<T>> {}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add voice_receive example<commit_after>extern crate discord;

use std::env;
use discord::{Discord, State};
use discord::voice::{VoiceConnection, AudioReceiver};
use discord::model::{Event, UserId};

// A simple voice listener example.
// Use by issuing the "!listen" command in a PM. The bot will join your voice channel and begin
// printing debug information about speaking in the channel. "!listen quit" will cause the bot
// to leave the voice channel.

struct VoiceTest;

impl AudioReceiver for VoiceTest {
	fn speaking_update(&mut self, ssrc: u32, user_id: &UserId, speaking: bool) {
		println!("[{}] is {:?} -> {}", ssrc, user_id, speaking);
	}

	fn voice_packet(&mut self, ssrc: u32, sequence: u16, timestamp: u32, data: &[i16]) {
		println!("[{}] ({}, {}) stereo = {}", ssrc, sequence, timestamp, data.len() == 1920);
	}
}

pub fn main() {
	// log in to the API
	let args: Vec<_> = env::args().collect();
	let discord = Discord::new_cache(
		"tokens.txt",
		args.get(1).expect("No email specified"),
		args.get(2).map(|x| &**x),
	).expect("Login failed");

	// establish websocket and voice connection
	let (mut connection, ready) = discord.connect().expect("connect failed");
	println!("[Ready] {} is serving {} servers", ready.user.username, ready.servers.len());
	let mut voice = VoiceConnection::new(ready.user.id.clone());
	let mut state = State::new(ready);
	let mut current_channel = None;

	// receive events forever
	loop {
		let event = match connection.recv_event() {
			Ok(event) => event,
			Err(err) => {
				println!("[Warning] Receive error: {:?}", err);
				if let discord::Error::WebSocket(..) = err {
					// Handle the websocket connection being dropped
					let (new_connection, ready) = discord.connect().expect("connect failed");
					connection = new_connection;
					state = State::new(ready);
					println!("[Ready] Reconnected successfully.");
				}
				continue
			},
		};
		state.update(&event);
		voice.update(&event);

		match event {
			Event::Closed(n) => {
				println!("[Error] Connection closed with status: {}", n);
				break
			},
			Event::MessageCreate(message) => {
				use std::ascii::AsciiExt;
				// safeguard: stop if the message is from us
				if message.author.id == state.user().id {
					continue
				}

				// reply to a command if there was one
				let mut split = message.content.split(" ");
				let first_word = split.next().unwrap_or("");
				let argument = split.next().unwrap_or("");

				if first_word.eq_ignore_ascii_case("!listen") {
					if argument.eq_ignore_ascii_case("quit") || argument.eq_ignore_ascii_case("stop") {
						connection.voice_disconnect();
					} else {
						let output = (|| {
							for server in state.servers() {
								for vstate in &server.voice_states {
									if vstate.user_id == message.author.id {
										if let Some(ref chan) = vstate.channel_id {
											connection.voice_connect(&server.id, chan);
											voice.set_receiver(Box::new(VoiceTest));
											return String::new()
										}
									}
								}
							}
							"You must be in a voice channel to use !listen".into()
						})();
						if output.len() > 0 {
							warn(discord.send_message(&message.channel_id, &output, "", false));
						}
					}
				}
			}
			Event::VoiceStateUpdate(server_id, voice_state) => {
				if voice_state.user_id == state.user().id {
					current_channel = voice_state.channel_id.map(|c| (server_id, c));
				} else if let Some((ref cur_server, ref cur_channel)) = current_channel {
					// If we are in a voice channel, && someone on our server moves/hangs up,
					if *cur_server == server_id {
						// && our current voice channel is empty, disconnect from voice
						if let Some(srv) = state.servers().iter().find(|srv| srv.id == server_id) {
							if srv.voice_states.iter().filter(|vs| vs.channel_id.as_ref() == Some(cur_channel)).count() <= 1 {
								connection.voice_disconnect();
							}
						}
					}
				}
			}
			_ => {}, // discard other events
		}
	}
}

#[allow(dead_code)]
fn warn<T, E: ::std::fmt::Debug>(result: Result<T, E>) {
	match result {
		Ok(_) => {},
		Err(err) => println!("[Warning] {:?}", err)
	}
}
<|endoftext|>