<commit_before>use failure::Fail;
use std::env;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

#[derive(Debug, Fail)]
pub enum CompileError {
    #[fail(display = "File not found: {}", _0)]
    FileNotFound(String),
    #[fail(display = "Clang reported error: {}", _0)]
    Execution { stdout: String, stderr: String },
}

impl CompileError {
    pub fn check(output: Output, print: bool) -> Result<(), Self> {
        if print {
            std::io::stdout().write_all(&output.stdout).unwrap();
            std::io::stderr().write_all(&output.stderr).unwrap();
        }
        if output.status.success() {
            Ok(())
        } else {
            Err(CompileError::Execution {
                stdout: String::from_utf8_lossy(&output.stdout).to_string(),
                stderr: String::from_utf8_lossy(&output.stderr).to_string(),
            })
        }
    }
}

fn wasi_sdk_clang() -> PathBuf {
    let mut base = PathBuf::from(env::var("WASI_SDK").unwrap_or("/opt/wasi-sdk".to_owned()));
    base.push("bin");
    base.push("clang");
    base
}

pub struct Compile {
    input: PathBuf,
    cflags: Vec<String>,
    print_output: bool,
}

impl Compile {
    pub fn new<P: AsRef<Path>>(input: P) -> Self {
        Compile {
            input: PathBuf::from(input.as_ref()),
            cflags: Vec::new(),
            print_output: false,
        }
    }

    pub fn cflag<S: AsRef<str>>(mut self, cflag: S) -> Self {
        self.with_cflag(cflag);
        self
    }

    pub fn with_cflag<S: AsRef<str>>(&mut self, cflag: S) {
        self.cflags.push(cflag.as_ref().to_owned());
    }

    pub fn include<S: AsRef<str>>(mut self, include: S) -> Self {
        self.with_include(include);
        self
    }

    pub fn with_include<S: AsRef<str>>(&mut self, include: S) {
        self.cflags.push(format!("-I{}", include.as_ref()));
    }

    pub fn print_output(mut self, print: bool) -> Self {
        self.print_output = print;
        self
    }

    pub fn compile<P: AsRef<Path>>(&self, output: P) -> Result<(), CompileError> {
        let clang = wasi_sdk_clang();
        if !clang.exists() {
            Err(CompileError::FileNotFound(
                clang.to_string_lossy().into_owned(),
            ))?;
        }
        if !self.input.exists() {
            Err(CompileError::FileNotFound(
                self.input.to_string_lossy().into_owned(),
            ))?;
        }
        let mut cmd = Command::new(clang);
        cmd.arg("-c");
        cmd.arg(self.input.clone());
        cmd.arg("-o");
        cmd.arg(output.as_ref());
        for cflag in self.cflags.iter() {
            cmd.arg(cflag);
        }
        let run = cmd.output().expect("clang executable exists");
        CompileError::check(run, self.print_output)
    }
}

pub struct Link {
    input: Vec<PathBuf>,
    cflags: Vec<String>,
    ldflags: Vec<String>,
    print_output: bool,
}

impl Link {
    pub fn new<P: AsRef<Path>>(input: &[P]) -> Self {
        Link {
            input: input.iter().map(|p| PathBuf::from(p.as_ref())).collect(),
            cflags: Vec::new(),
            ldflags: Vec::new(),
            print_output: false,
        }
    }

    pub fn cflag<S: AsRef<str>>(mut self, cflag: S) -> Self {
        self.with_cflag(cflag);
        self
    }

    pub fn with_cflag<S: AsRef<str>>(&mut self, cflag: S) {
        self.cflags.push(cflag.as_ref().to_owned());
    }

    pub fn include<S: AsRef<str>>(mut self, include: S) -> Self {
        self.with_include(include);
        self
    }

    pub fn with_include<S: AsRef<str>>(&mut self, include: S) {
        self.cflags.push(format!("-I{}", include.as_ref()));
    }

    pub fn ldflag<S: AsRef<str>>(mut self, ldflag: S) -> Self {
        self.with_ldflag(ldflag);
        self
    }

    pub fn with_ldflag<S: AsRef<str>>(&mut self, ldflag: S) {
        self.ldflags.push(ldflag.as_ref().to_owned());
    }

    pub fn export<S: AsRef<str>>(mut self, export: S) -> Self {
        self.with_export(export);
        self
    }

    pub fn with_export<S: AsRef<str>>(&mut self, export: S) {
        self.ldflags.push(format!("--export={}", export.as_ref()));
    }

    pub fn print_output(mut self, print: bool) -> Self {
        self.print_output = print;
        self
    }

    pub fn link<P: AsRef<Path>>(&self, output: P) -> Result<(), CompileError> {
        let clang = wasi_sdk_clang();
        if !clang.exists() {
            Err(CompileError::FileNotFound(
                clang.to_string_lossy().into_owned(),
            ))?;
        }
        let mut cmd = Command::new(clang);
        for input in self.input.iter() {
            if !input.exists() {
                Err(CompileError::FileNotFound(
                    input.to_string_lossy().into_owned(),
                ))?;
            }
            cmd.arg(input.clone());
        }
        cmd.arg("-o");
        cmd.arg(output.as_ref());
        for cflag in self.cflags.iter() {
            cmd.arg(cflag);
        }
        for ldflag in self.ldflags.iter() {
            cmd.arg(format!("-Wl,{}", ldflag));
        }
        let run = cmd.output().expect("clang executable exists");
        CompileError::check(run, self.print_output)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;
    #[test]
    fn wasi_sdk_installed() {
        let clang = wasi_sdk_clang();
        assert!(clang.exists(), "clang executable exists");
    }

    fn test_file(name: &str) -> PathBuf {
        let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        p.push("test");
        p.push(name);
        assert!(p.exists(), "test file does not exist");
        p
    }

    #[test]
    fn compile_a() {
        let tmp = TempDir::new().expect("create temporary directory");

        let compiler = Compile::new(test_file("a.c"));

        let objfile = tmp.path().join("a.o");

        compiler.compile(objfile.clone()).expect("compile a.c");

        assert!(objfile.exists(), "object file created");

        let mut linker = Link::new(&[objfile]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");

        let wasmfile = tmp.path().join("a.wasm");

        linker.link(wasmfile.clone()).expect("link a.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }

    #[test]
    fn compile_b() {
        let tmp = TempDir::new().expect("create temporary directory");

        let compiler = Compile::new(test_file("b.c"));

        let objfile = tmp.path().join("b.o");

        compiler.compile(objfile.clone()).expect("compile b.c");

        assert!(objfile.exists(), "object file created");

        let mut linker = Link::new(&[objfile]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");
        linker.with_ldflag("--allow-undefined");

        let wasmfile = tmp.path().join("b.wasm");

        linker.link(wasmfile.clone()).expect("link b.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }

    #[test]
    fn compile_a_and_b() {
        let tmp = TempDir::new().expect("create temporary directory");

        let mut linker = Link::new(&[test_file("a.c"), test_file("b.c")]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");

        let wasmfile = tmp.path().join("ab.wasm");

        linker.link(wasmfile.clone()).expect("link ab.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }
}
<commit_msg>lucet-wasi-sdk: disable threading in lld (wasi-ld)<commit_after>use failure::Fail;
use std::env;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};

#[derive(Debug, Fail)]
pub enum CompileError {
    #[fail(display = "File not found: {}", _0)]
    FileNotFound(String),
    #[fail(display = "Clang reported error: {}", _0)]
    Execution { stdout: String, stderr: String },
}

impl CompileError {
    pub fn check(output: Output, print: bool) -> Result<(), Self> {
        if print {
            std::io::stdout().write_all(&output.stdout).unwrap();
            std::io::stderr().write_all(&output.stderr).unwrap();
        }
        if output.status.success() {
            Ok(())
        } else {
            Err(CompileError::Execution {
                stdout: String::from_utf8_lossy(&output.stdout).to_string(),
                stderr: String::from_utf8_lossy(&output.stderr).to_string(),
            })
        }
    }
}

fn wasi_sdk_clang() -> PathBuf {
    let mut base = PathBuf::from(env::var("WASI_SDK").unwrap_or("/opt/wasi-sdk".to_owned()));
    base.push("bin");
    base.push("clang");
    base
}

pub struct Compile {
    input: PathBuf,
    cflags: Vec<String>,
    print_output: bool,
}

impl Compile {
    pub fn new<P: AsRef<Path>>(input: P) -> Self {
        Compile {
            input: PathBuf::from(input.as_ref()),
            cflags: Vec::new(),
            print_output: false,
        }
    }

    pub fn cflag<S: AsRef<str>>(mut self, cflag: S) -> Self {
        self.with_cflag(cflag);
        self
    }

    pub fn with_cflag<S: AsRef<str>>(&mut self, cflag: S) {
        self.cflags.push(cflag.as_ref().to_owned());
    }

    pub fn include<S: AsRef<str>>(mut self, include: S) -> Self {
        self.with_include(include);
        self
    }

    pub fn with_include<S: AsRef<str>>(&mut self, include: S) {
        self.cflags.push(format!("-I{}", include.as_ref()));
    }

    pub fn print_output(mut self, print: bool) -> Self {
        self.print_output = print;
        self
    }

    pub fn compile<P: AsRef<Path>>(&self, output: P) -> Result<(), CompileError> {
        let clang = wasi_sdk_clang();
        if !clang.exists() {
            Err(CompileError::FileNotFound(
                clang.to_string_lossy().into_owned(),
            ))?;
        }
        if !self.input.exists() {
            Err(CompileError::FileNotFound(
                self.input.to_string_lossy().into_owned(),
            ))?;
        }
        let mut cmd = Command::new(clang);
        cmd.arg("-c");
        cmd.arg(self.input.clone());
        cmd.arg("-o");
        cmd.arg(output.as_ref());
        for cflag in self.cflags.iter() {
            cmd.arg(cflag);
        }
        let run = cmd.output().expect("clang executable exists");
        CompileError::check(run, self.print_output)
    }
}

pub struct Link {
    input: Vec<PathBuf>,
    cflags: Vec<String>,
    ldflags: Vec<String>,
    print_output: bool,
}

impl Link {
    pub fn new<P: AsRef<Path>>(input: &[P]) -> Self {
        let mut link = Link {
            input: input.iter().map(|p| PathBuf::from(p.as_ref())).collect(),
            cflags: Vec::new(),
            ldflags: Vec::new(),
            print_output: false,
        };
        link.with_ldflag("--no-threads");
        link
    }

    pub fn cflag<S: AsRef<str>>(mut self, cflag: S) -> Self {
        self.with_cflag(cflag);
        self
    }

    pub fn with_cflag<S: AsRef<str>>(&mut self, cflag: S) {
        self.cflags.push(cflag.as_ref().to_owned());
    }

    pub fn include<S: AsRef<str>>(mut self, include: S) -> Self {
        self.with_include(include);
        self
    }

    pub fn with_include<S: AsRef<str>>(&mut self, include: S) {
        self.cflags.push(format!("-I{}", include.as_ref()));
    }

    pub fn ldflag<S: AsRef<str>>(mut self, ldflag: S) -> Self {
        self.with_ldflag(ldflag);
        self
    }

    pub fn with_ldflag<S: AsRef<str>>(&mut self, ldflag: S) {
        self.ldflags.push(ldflag.as_ref().to_owned());
    }

    pub fn export<S: AsRef<str>>(mut self, export: S) -> Self {
        self.with_export(export);
        self
    }

    pub fn with_export<S: AsRef<str>>(&mut self, export: S) {
        self.ldflags.push(format!("--export={}", export.as_ref()));
    }

    pub fn print_output(mut self, print: bool) -> Self {
        self.print_output = print;
        self
    }

    pub fn link<P: AsRef<Path>>(&self, output: P) -> Result<(), CompileError> {
        let clang = wasi_sdk_clang();
        if !clang.exists() {
            Err(CompileError::FileNotFound(
                clang.to_string_lossy().into_owned(),
            ))?;
        }
        let mut cmd = Command::new(clang);
        for input in self.input.iter() {
            if !input.exists() {
                Err(CompileError::FileNotFound(
                    input.to_string_lossy().into_owned(),
                ))?;
            }
            cmd.arg(input.clone());
        }
        cmd.arg("-o");
        cmd.arg(output.as_ref());
        for cflag in self.cflags.iter() {
            cmd.arg(cflag);
        }
        for ldflag in self.ldflags.iter() {
            cmd.arg(format!("-Wl,{}", ldflag));
        }
        let run = cmd.output().expect("clang executable exists");
        CompileError::check(run, self.print_output)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;
    #[test]
    fn wasi_sdk_installed() {
        let clang = wasi_sdk_clang();
        assert!(clang.exists(), "clang executable exists");
    }

    fn test_file(name: &str) -> PathBuf {
        let mut p = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
        p.push("test");
        p.push(name);
        assert!(p.exists(), "test file does not exist");
        p
    }

    #[test]
    fn compile_a() {
        let tmp = TempDir::new().expect("create temporary directory");

        let compiler = Compile::new(test_file("a.c"));

        let objfile = tmp.path().join("a.o");

        compiler.compile(objfile.clone()).expect("compile a.c");

        assert!(objfile.exists(), "object file created");

        let mut linker = Link::new(&[objfile]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");

        let wasmfile = tmp.path().join("a.wasm");

        linker.link(wasmfile.clone()).expect("link a.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }

    #[test]
    fn compile_b() {
        let tmp = TempDir::new().expect("create temporary directory");

        let compiler = Compile::new(test_file("b.c"));

        let objfile = tmp.path().join("b.o");

        compiler.compile(objfile.clone()).expect("compile b.c");

        assert!(objfile.exists(), "object file created");

        let mut linker = Link::new(&[objfile]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");
        linker.with_ldflag("--allow-undefined");

        let wasmfile = tmp.path().join("b.wasm");

        linker.link(wasmfile.clone()).expect("link b.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }

    #[test]
    fn compile_a_and_b() {
        let tmp = TempDir::new().expect("create temporary directory");

        let mut linker = Link::new(&[test_file("a.c"), test_file("b.c")]);
        linker.with_cflag("-nostartfiles");
        linker.with_ldflag("--no-entry");

        let wasmfile = tmp.path().join("ab.wasm");

        linker.link(wasmfile.clone()).expect("link ab.wasm");

        assert!(wasmfile.exists(), "wasm file created");
    }
}
<|endoftext|>


<commit_before><commit_msg>Initialize arrays with a macro<commit_after><|endoftext|>


<commit_before>extern crate clap;
extern crate rand;
extern crate libshft;

mod output;

use clap::{Arg, ArgMatches, App, SubCommand};
use rand::SeedableRng;
use rand::isaac;
use std::io;
use std::io::{Read, Write};
use std::fs::File;
use std::path::Path;
use std::process;
use libshft::grammar::Grammar;
use libshft::parse::{ParsedFile, slurp};
use libshft::fuzz::fuzz_one;
use output::OutputPattern;

#[cfg(test)]
mod test {
    use libshft::grammar::{Grammar, GrammarDef};
    use libshft::parse::slurp;
    use libshft::fuzz::FuzzFile;

    fn roundtrip(grammar: &Grammar, buf: &[u8]) -> bool {
        let parsed_file = slurp(grammar, buf);
        println!("parsed = {:?}", parsed_file.dump());
        let ff = FuzzFile::new(&parsed_file);
        let serialized = ff.serialize();
        println!("serialized = {:#?}", serialized);
        serialized == buf
    }

    #[test]
    fn test_whitespace() {
        let grammar = Grammar::new(vec![], vec![b" ".to_vec()]);
        let buf = b"1 2 3";
        assert!(roundtrip(&grammar, buf))
    }

    #[test]
    fn test_two_whitespaces() {
        let grammar = Grammar::new(vec![], vec![b" ".to_vec(), b"\r\n".to_vec()]);
        let buf = b"1 2\r\n3 \r\n4";
        assert!(roundtrip(&grammar, buf))
    }

    #[test]
    fn test_delim() {
        let grammar = Grammar::new(vec![
            GrammarDef::Delim(vec![b'<', b'<'], vec![b'>', b'>']),
        ], vec![]);
        assert!(roundtrip(&grammar, b"1<<2<<3>>4>>5"));
        assert!(roundtrip(&grammar, b"1<<2<<3>>4"));
        assert!(roundtrip(&grammar, b"1<<2>>3>>4"));
        assert!(roundtrip(&grammar, b"1<<2"));
        assert!(roundtrip(&grammar, b"1>>2"));
    }
}

fn read_file<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
    let mut f = File::open(path)?;
    let mut buffer = Vec::new();

    match f.read_to_end(&mut buffer) {
        Ok(_) => Ok(buffer),
        Err(err) => Err(err),
    }
}

fn do_fuzz<'buf>(parsed_file: &ParsedFile<'buf>, pattern: &OutputPattern, iterations: usize) {
    let mut rng = isaac::Isaac64Rng::from_seed(&[1, 2, 3, 4]);
    for i in 0..iterations {
        let fuzzed = fuzz_one(parsed_file, &mut rng, 5);

        let out_filename = pattern.with(i);
        let mut file = File::create(out_filename).expect("oops");
        file.write_all(&fuzzed[..]).expect("oops")
    }
}

fn parse_input_file<'buf>(config_filename: &str, buf: &'buf [u8]) -> ParsedFile<'buf> {
    let grammar = Grammar::from_path(config_filename);
    slurp(&grammar, buf)
}

fn die<S: AsRef<str>>(app: &App, msg: S) -> i32 {
    let mut out = io::stdout();
    app.write_help(&mut out).expect("app.write_help");
    write!(out, "\n\n{}\n", msg.as_ref()).expect("write newline");
    1
}

fn lookup<'a>(matches: &'a ArgMatches, key: &str) -> &'a str {
    matches.value_of(key).expect("impossible")
}

fn go() -> i32 {
    let app = App::new("super-happy-fuzz-time")
        .arg(Arg::with_name("INPUT")
            .help("File to fuzz")
            .long("input")
            .short("i")
            .number_of_values(1)
            .required(true))
        .arg(Arg::with_name("CONFIG")
            .help("Config file")
            .long("config")
            .short("c")
            .number_of_values(1)
            .required(true))
        .subcommand(
            SubCommand::with_name("dump")
                .help("Parse and dump input file"))
        .subcommand(
            SubCommand::with_name("fuzz")
                .help("Fuzz input file")
                .arg(Arg::with_name("OUTPUT")
                    .help("Output pattern")
                    .long("output")
                    .short("o")
                    .number_of_values(1)
                    .required(true)));

    let matches = app.clone().get_matches();

    let config_filename = lookup(&matches, "CONFIG");
    let input_filename = lookup(&matches, "INPUT");

    match matches.subcommand() {
        ("dump", _) => {
            let buf = read_file(input_filename).expect("read_file");
            let parsed_file = parse_input_file(config_filename, &buf[..]);
            println!("{}", parsed_file.dump());
            0
        },
        ("fuzz", Some(fuzz_matches)) => {
            let output = lookup(fuzz_matches, "OUTPUT");
            match OutputPattern::from_path(output) {
                Some(pattern) => {
                    let buf = read_file(input_filename).expect("read_file");
                    let parsed_file = parse_input_file(config_filename, &buf[..]);
                    do_fuzz(&parsed_file, &pattern, 10);
                    0
                },
                None => {
                    die(&app, format!("'{}' is an invalid output pattern", output))
                }
            }
        },
        _ => {
            die(&app, "Must provide 'dump' or 'fuzz'")
        },
    }
}

fn main() {
    process::exit(go());
}
<commit_msg>Add --num switch.<commit_after>extern crate clap;
extern crate rand;
extern crate libshft;

mod output;

use clap::{Arg, ArgMatches, App, SubCommand};
use rand::SeedableRng;
use rand::isaac;
use std::io;
use std::io::{Read, Write};
use std::fs::File;
use std::path::Path;
use std::process;
use std::str::FromStr;
use libshft::grammar::Grammar;
use libshft::parse::{ParsedFile, slurp};
use libshft::fuzz::fuzz_one;
use output::OutputPattern;

#[cfg(test)]
mod test {
    use libshft::grammar::{Grammar, GrammarDef};
    use libshft::parse::slurp;
    use libshft::fuzz::FuzzFile;

    fn roundtrip(grammar: &Grammar, buf: &[u8]) -> bool {
        let parsed_file = slurp(grammar, buf);
        println!("parsed = {:?}", parsed_file.dump());
        let ff = FuzzFile::new(&parsed_file);
        let serialized = ff.serialize();
        println!("serialized = {:#?}", serialized);
        serialized == buf
    }

    #[test]
    fn test_whitespace() {
        let grammar = Grammar::new(vec![], vec![b" ".to_vec()]);
        let buf = b"1 2 3";
        assert!(roundtrip(&grammar, buf))
    }

    #[test]
    fn test_two_whitespaces() {
        let grammar = Grammar::new(vec![], vec![b" ".to_vec(), b"\r\n".to_vec()]);
        let buf = b"1 2\r\n3 \r\n4";
        assert!(roundtrip(&grammar, buf))
    }

    #[test]
    fn test_delim() {
        let grammar = Grammar::new(vec![
            GrammarDef::Delim(vec![b'<', b'<'], vec![b'>', b'>']),
        ], vec![]);
        assert!(roundtrip(&grammar, b"1<<2<<3>>4>>5"));
        assert!(roundtrip(&grammar, b"1<<2<<3>>4"));
        assert!(roundtrip(&grammar, b"1<<2>>3>>4"));
        assert!(roundtrip(&grammar, b"1<<2"));
        assert!(roundtrip(&grammar, b"1>>2"));
    }
}

fn read_file<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
    let mut f = File::open(path)?;
    let mut buffer = Vec::new();

    match f.read_to_end(&mut buffer) {
        Ok(_) => Ok(buffer),
        Err(err) => Err(err),
    }
}

fn do_fuzz<'buf>(parsed_file: &ParsedFile<'buf>, pattern: &OutputPattern, iterations: usize) {
    let mut rng = isaac::Isaac64Rng::from_seed(&[1, 2, 3, 4]);
    for i in 0..iterations {
        let fuzzed = fuzz_one(parsed_file, &mut rng, 5);

        let out_filename = pattern.with(i+1);
        let mut file = File::create(out_filename).expect("oops");
        file.write_all(&fuzzed[..]).expect("oops")
    }
}

fn parse_input_file<'buf>(config_filename: &str, buf: &'buf [u8]) -> ParsedFile<'buf> {
    let grammar = Grammar::from_path(config_filename);
    slurp(&grammar, buf)
}

fn die<S: AsRef<str>>(app: &App, msg: S) -> i32 {
    let mut out = io::stdout();
    app.write_help(&mut out).expect("app.write_help");
    write!(out, "\n\n{}\n", msg.as_ref()).expect("write newline");
    1
}

fn lookup<'a>(matches: &'a ArgMatches, key: &str) -> &'a str {
    matches.value_of(key).expect("impossible")
}

fn go() -> i32 {
    let app = App::new("super-happy-fuzz-time")
        .arg(Arg::with_name("INPUT")
            .help("File to fuzz")
            .long("input")
            .short("i")
            .number_of_values(1)
            .required(true))
        .arg(Arg::with_name("CONFIG")
            .help("Config file")
            .long("config")
            .short("c")
            .number_of_values(1)
            .required(true))
        .subcommand(
            SubCommand::with_name("dump")
                .help("Parse and dump input file"))
        .subcommand(
            SubCommand::with_name("fuzz")
                .help("Fuzz input file")
                .arg(Arg::with_name("OUTPUT")
                    .help("Output pattern")
                    .long("output")
                    .short("o")
                    .number_of_values(1)
                    .required(true))
                .arg(Arg::with_name("ITERATIONS")
                    .help("Number of files to generate")
                    .long("num")
                    .short("n")
                    .number_of_values(1)
                    .required(true)));

    let matches = app.clone().get_matches();

    let config_filename = lookup(&matches, "CONFIG");
    let input_filename = lookup(&matches, "INPUT");

    match matches.subcommand() {
        ("dump", _) => {
            let buf = read_file(input_filename).expect("read_file");
            let parsed_file = parse_input_file(config_filename, &buf[..]);
            println!("{}", parsed_file.dump());
            0
        },
        ("fuzz", Some(fuzz_matches)) => {
            let output = lookup(fuzz_matches, "OUTPUT");
            let num_iterations = match usize::from_str(lookup(fuzz_matches, "ITERATIONS")) {
                Ok(n) => n,
                Err(err) => return die(&app, format!("Invalid iterations: {}", err)),
            };
            match OutputPattern::from_path(output) {
                Some(pattern) => {
                    let buf = read_file(input_filename).expect("read_file");
                    let parsed_file = parse_input_file(config_filename, &buf[..]);
                    do_fuzz(&parsed_file, &pattern, num_iterations);
                    0
                },
                None => {
                    die(&app, format!("'{}' is an invalid output pattern", output))
                }
            }
        },
        _ => {
            die(&app, "Must provide 'dump' or 'fuzz'")
        },
    }
}

fn main() {
    process::exit(go());
}
<|endoftext|>


<commit_before>use futures::{BoxFuture, Future, IntoFuture, Async, Sink, Stream as FuturesStream};
use futures::future::Either;
use postgres_shared::params::Host;
use postgres_protocol::message::backend::{self, ParseResult};
use postgres_protocol::message::frontend;
use std::io::{self, Read, Write};
use tokio_core::io::{Io, Codec, EasyBuf, Framed};
use tokio_core::net::TcpStream;
use tokio_core::reactor::Handle;
use tokio_dns;

#[cfg(unix)]
use tokio_uds::UnixStream;

use TlsMode;
use error::ConnectError;
use tls::TlsStream;

pub type PostgresStream = Framed<Box<TlsStream>, PostgresCodec>;

pub fn connect(host: Host,
               port: u16,
               tls_mode: TlsMode,
               handle: &Handle)
               -> BoxFuture<PostgresStream, ConnectError> {
    let inner = match host {
        Host::Tcp(ref host) => {
            Either::A(tokio_dns::tcp_connect((&**host, port), handle.remote().clone())
                .map(|s| Stream(InnerStream::Tcp(s))))
        }
        #[cfg(unix)]
        Host::Unix(ref host) => {
            let addr = host.join(format!(".s.PGSQL.{}", port));
            Either::B(UnixStream::connect(addr, handle)
                .map(|s| Stream(InnerStream::Unix(s)))
                .into_future())
        }
        #[cfg(not(unix))]
        Host::Unix(_) => {
            Either::B(Err(ConnectError::ConnectParams("unix sockets are not supported on this platform")).into_future())
        }
    };

    let (required, handshaker) = match tls_mode {
        TlsMode::Require(h) => (true, h),
        TlsMode::Prefer(h) => (false, h),
        TlsMode::None => {
            return inner.map(|s| {
                    let s: Box<TlsStream> = Box::new(s);
                    s.framed(PostgresCodec)
                })
                .map_err(ConnectError::Io)
                .boxed()
        },
    };

    inner.map(|s| s.framed(SslCodec))
        .and_then(|s| {
            let mut buf = vec![];
            frontend::ssl_request(&mut buf);
            s.send(buf)
        })
        .and_then(|s| s.into_future().map_err(|e| e.0))
        .map_err(ConnectError::Io)
        .and_then(move |(m, s)| {
            let s = s.into_inner();
            match (m, required) {
                (Some(b'N'), true) => {
                    Either::A(Err(ConnectError::Tls("the server does not support TLS".into())).into_future())
                }
                (Some(b'N'), false) => {
                    let s: Box<TlsStream> = Box::new(s);
                    Either::A(Ok(s).into_future())
                },
                (None, _) => Either::A(Err(ConnectError::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF"))).into_future()),
                _ => {
                    let host = match host {
                        Host::Tcp(ref host) => host,
                        Host::Unix(_) => unreachable!(),
                    };
                    Either::B(handshaker.handshake(host, s).map_err(ConnectError::Tls))
                }
            }
        })
        .map(|s| s.framed(PostgresCodec))
        .boxed()
}

/// A raw connection to the database.
pub struct Stream(InnerStream);

enum InnerStream {
    Tcp(TcpStream),
    #[cfg(unix)]
    Unix(UnixStream),
}

impl Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.read(buf),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.read(buf),
        }
    }
}

impl Write for Stream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.write(buf),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.flush(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.flush(),
        }
    }
}

impl Io for Stream {
    fn poll_read(&mut self) -> Async<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.poll_read(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.poll_read(),
        }
    }

    fn poll_write(&mut self) -> Async<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.poll_write(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.poll_write(),
        }
    }
}

pub struct PostgresCodec;

impl Codec for PostgresCodec {
    type In = backend::Message<Vec<u8>>;
    type Out = Vec<u8>;

    // FIXME ideally we'd avoid re-copying the data
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        match backend::Message::parse_owned(buf.as_ref())? {
            ParseResult::Complete { message, consumed } => {
                buf.drain_to(consumed);
                Ok(Some(message))
            }
            ParseResult::Incomplete { .. } => Ok(None)
        }
    }

    fn encode(&mut self, msg: Vec<u8>, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend_from_slice(&msg);
        Ok(())
    }
}

struct SslCodec;

impl Codec for SslCodec {
    type In = u8;
    type Out = Vec<u8>;

    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<u8>> {
        if buf.as_slice().is_empty() {
            Ok(None)
        } else {
            let byte = buf.as_slice()[0];
            buf.drain_to(1);
            Ok(Some(byte))
        }
    }

    fn encode(&mut self, msg: Vec<u8>, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend_from_slice(&msg);
        Ok(())
    }
}
<commit_msg>Fix build<commit_after>use futures::{BoxFuture, Future, IntoFuture, Async, Sink, Stream as FuturesStream};
use futures::future::Either;
use postgres_shared::params::Host;
use postgres_protocol::message::backend::{self, ParseResult};
use postgres_protocol::message::frontend;
use std::io::{self, Read, Write};
use tokio_core::io::{Io, Codec, EasyBuf, Framed};
use tokio_core::net::TcpStream;
use tokio_core::reactor::Handle;
use tokio_dns;

#[cfg(unix)]
use tokio_uds::UnixStream;

use TlsMode;
use error::ConnectError;
use tls::TlsStream;

pub type PostgresStream = Framed<Box<TlsStream>, PostgresCodec>;

pub fn connect(host: Host,
               port: u16,
               tls_mode: TlsMode,
               handle: &Handle)
               -> BoxFuture<PostgresStream, ConnectError> {
    let inner = match host {
        Host::Tcp(ref host) => {
            Either::A(tokio_dns::tcp_connect((&**host, port), handle.remote().clone())
                .map(|s| Stream(InnerStream::Tcp(s)))
                .map_err(ConnectError::Io))
        }
        #[cfg(unix)]
        Host::Unix(ref host) => {
            let addr = host.join(format!(".s.PGSQL.{}", port));
            Either::B(UnixStream::connect(addr, handle)
                .map(|s| Stream(InnerStream::Unix(s)))
                .map_err(ConnectError::Io)
                .into_future())
        }
        #[cfg(not(unix))]
        Host::Unix(_) => {
            Either::B(Err(ConnectError::ConnectParams("unix sockets are not supported on this platform".into())).into_future())
        }
    };

    let (required, handshaker) = match tls_mode {
        TlsMode::Require(h) => (true, h),
        TlsMode::Prefer(h) => (false, h),
        TlsMode::None => {
            return inner.map(|s| {
                    let s: Box<TlsStream> = Box::new(s);
                    s.framed(PostgresCodec)
                })
                .boxed()
        },
    };

    inner.map(|s| s.framed(SslCodec))
        .and_then(|s| {
            let mut buf = vec![];
            frontend::ssl_request(&mut buf);
            s.send(buf)
                .map_err(ConnectError::Io)
        })
        .and_then(|s| s.into_future().map_err(|e| ConnectError::Io(e.0)))
        .and_then(move |(m, s)| {
            let s = s.into_inner();
            match (m, required) {
                (Some(b'N'), true) => {
                    Either::A(Err(ConnectError::Tls("the server does not support TLS".into())).into_future())
                }
                (Some(b'N'), false) => {
                    let s: Box<TlsStream> = Box::new(s);
                    Either::A(Ok(s).into_future())
                },
                (None, _) => Either::A(Err(ConnectError::Io(io::Error::new(io::ErrorKind::UnexpectedEof, "unexpected EOF"))).into_future()),
                _ => {
                    let host = match host {
                        Host::Tcp(ref host) => host,
                        Host::Unix(_) => unreachable!(),
                    };
                    Either::B(handshaker.handshake(host, s).map_err(ConnectError::Tls))
                }
            }
        })
        .map(|s| s.framed(PostgresCodec))
        .boxed()
}

/// A raw connection to the database.
pub struct Stream(InnerStream);

enum InnerStream {
    Tcp(TcpStream),
    #[cfg(unix)]
    Unix(UnixStream),
}

impl Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.read(buf),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.read(buf),
        }
    }
}

impl Write for Stream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.write(buf),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.flush(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.flush(),
        }
    }
}

impl Io for Stream {
    fn poll_read(&mut self) -> Async<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.poll_read(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.poll_read(),
        }
    }

    fn poll_write(&mut self) -> Async<()> {
        match self.0 {
            InnerStream::Tcp(ref mut s) => s.poll_write(),
            #[cfg(unix)]
            InnerStream::Unix(ref mut s) => s.poll_write(),
        }
    }
}

pub struct PostgresCodec;

impl Codec for PostgresCodec {
    type In = backend::Message<Vec<u8>>;
    type Out = Vec<u8>;

    // FIXME ideally we'd avoid re-copying the data
    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<Self::In>> {
        match backend::Message::parse_owned(buf.as_ref())? {
            ParseResult::Complete { message, consumed } => {
                buf.drain_to(consumed);
                Ok(Some(message))
            }
            ParseResult::Incomplete { .. } => Ok(None)
        }
    }

    fn encode(&mut self, msg: Vec<u8>, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend_from_slice(&msg);
        Ok(())
    }
}

struct SslCodec;

impl Codec for SslCodec {
    type In = u8;
    type Out = Vec<u8>;

    fn decode(&mut self, buf: &mut EasyBuf) -> io::Result<Option<u8>> {
        if buf.as_slice().is_empty() {
            Ok(None)
        } else {
            let byte = buf.as_slice()[0];
            buf.drain_to(1);
            Ok(Some(byte))
        }
    }

    fn encode(&mut self, msg: Vec<u8>, buf: &mut Vec<u8>) -> io::Result<()> {
        buf.extend_from_slice(&msg);
        Ok(())
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate regex;

include!("../clap-test.rs");

use clap::{App, SubCommand, ErrorKind, Arg};

static HELP: &'static str = "clap-test v1.4.8
Kevin K. <kbknapp@gmail.com>
tests clap library

USAGE:
    clap-test [FLAGS] [OPTIONS] [ARGS] [SUBCOMMAND]

FLAGS:
    -f, --flag       tests flags
    -F               tests flags with exclusions
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -O, --Option <option3>           specific vals [values: fast, slow]
        --long-option-2 <option2>    tests long options with exclusions
        --maxvals3 <maxvals>...      Tests 3 max vals
        --minvals2 <minvals>...      Tests 2 min vals
        --multvals <one> <two>       Tests mutliple values, not mult occs
        --multvalsmo <one> <two>     Tests mutliple values, and mult occs
    -o, --option <opt>...            tests options

ARGS:
    <positional>        tests positionals
    <positional2>       tests positionals with exclusions
    <positional3>...    tests specific values [values: vi, emacs]

SUBCOMMANDS:
    help      Prints this message or the help of the given subcommand(s)
    subcmd    tests subcommands";

static AFTER_HELP: &'static str = "some text that comes before the help

clap-test v1.4.8
tests clap library

USAGE:
    clap-test

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

some text that comes after the help";

static SC_HELP: &'static str = "subcmd 0.1
Kevin K. <kbknapp@gmail.com>
tests subcommands

USAGE:
    subcmd [FLAGS] [OPTIONS] [--] [scpositional]

FLAGS:
    -f, --flag    tests flags

OPTIONS:
    -o, --option <scoption>...    tests options

ARGS:
    <scpositional>    tests positionals";

static MULTI_SC_HELP: &'static str = "ctest-subcmd-multi 0.1
Kevin K. <kbknapp@gmail.com>
tests subcommands

USAGE:
    ctest subcmd multi [FLAGS] [OPTIONS]

FLAGS:
    -f, --flag       tests flags
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -o, --option <scoption>...    tests options";

static ISSUE_626_CUTOFF: &'static str = "ctest 0.1

USAGE:
    ctest [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --cafe <FILE>
        A coffeehouse, coffee shop, or café is an establishment which
        primarily serves hot coffee, related coffee beverages
        (e.g., café latte, cappuccino, espresso), tea, and other
        hot beverages. Some coffeehouses also serve cold beverages
        such as iced coffee and iced tea. Many cafés also serve
        some type of food, such as light snacks, muffins, or pastries.";

static ISSUE_626_PANIC: &'static str = "ctest 0.1

USAGE:
    ctest [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --cafe <FILE>
        La culture du café est très développée dans
        de nombreux pays à climat chaud
        d\'Amérique, d\'Afrique et d\'Asie, dans
        des plantations qui sont cultivées pour
        les marchés d\'exportation. Le café est
        souvent une contribution majeure aux
        exportations des régions productrices.";

#[test]
fn help_short() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "-h"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn help_long() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "--help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn help_no_subcommand() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
}

#[test]
fn help_subcommand() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .subcommand(SubCommand::with_name("test")
            .about("tests things")
            .arg_from_usage("-v --verbose 'with verbosity'"))
        .get_matches_from_safe(vec!["myprog", "help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_short_help() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "subcmd", "-h"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_long_help() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "subcmd", "--help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_help_rev() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "help", "subcmd"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn complex_help_output() {
    test::check_help(test::complex_app(), HELP);
}

#[test]
fn after_and_before_help_output() {
    let app = App::new("clap-test")
        .version("v1.4.8")
        .about("tests clap library")
        .before_help("some text that comes before the help")
        .after_help("some text that comes after the help");
    test::check_help(app, AFTER_HELP);
}

#[test]
fn multi_level_sc_help() {
    let app = App::new("ctest")
        .subcommand(SubCommand::with_name("subcmd")
            .subcommand(SubCommand::with_name("multi")
                .about("tests subcommands")
                .author("Kevin K. <kbknapp@gmail.com>")
                .version("0.1")
                .args_from_usage("
                    -f, --flag                    'tests flags'
                    -o, --option [scoption]...    'tests options'
                ")));
    test::check_err_output(app, "ctest help subcmd multi", MULTI_SC_HELP, false);
}

#[test]
fn no_wrap_help() {
    let app = App::new("ctest")
        .set_term_width(0)
        .help(MULTI_SC_HELP);
    test::check_err_output(app, "ctest --help", MULTI_SC_HELP, false);
}

#[test]
fn complex_subcommand_help_output() {
    let mut a = test::complex_app();
    let _ = a.get_matches_from_safe_borrow(vec![""]);
    let sc = a.p.subcommands.iter().filter(|s| s.p.meta.name == "subcmd").next().unwrap();
    // Now we check the output of print_help()
    let mut help = vec![];
    sc.write_help(&mut help).ok().expect("failed to print help");
    assert_eq!(&*String::from_utf8(help).unwrap(), SC_HELP);
}

#[test]
fn issue_626_unicode_cutoff() {
    let app = App::new("ctest")
        .version("0.1")
        .set_term_width(70)
        .arg(Arg::with_name("cafe")
           .short("c")
           .long("cafe")
           .value_name("FILE")
           .help("A coffeehouse, coffee shop, or café is an establishment \
           which primarily serves hot coffee, related coffee beverages \
           (e.g., café latte, cappuccino, espresso), tea, and other hot \
           beverages. Some coffeehouses also serve cold beverages such as \
           iced coffee and iced tea. Many cafés also serve some type of \
           food, such as light snacks, muffins, or pastries.")
           .takes_value(true));
    test::check_err_output(app, "ctest --help", ISSUE_626_CUTOFF, false);
}

#[test]
fn issue_626_panic() {
    let app = App::new("ctest")
        .version("0.1")
        .set_term_width(52)
        .arg(Arg::with_name("cafe")
           .short("c")
           .long("cafe")
           .value_name("FILE")
           .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
           d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
           Le café est souvent une contribution majeure aux exportations des régions productrices.")
           .takes_value(true));
    test::check_err_output(app, "ctest --help", ISSUE_626_PANIC, false);
}

#[test]
fn issue_626_variable_panic() {
    for i in 10..320 {
        let _ = App::new("ctest")
            .version("0.1")
            .set_term_width(i)
            .arg(Arg::with_name("cafe")
               .short("c")
               .long("cafe")
               .value_name("FILE")
               .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
               d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
               Le café est souvent une contribution majeure aux exportations des régions productrices.")
               .takes_value(true))
            .get_matches_from_safe(vec!["ctest", "--help"]);
    }
}
<commit_msg>tests: updates test to new help improvements<commit_after>extern crate clap;
extern crate regex;

include!("../clap-test.rs");

use clap::{App, SubCommand, ErrorKind, Arg};

static HELP: &'static str = "clap-test v1.4.8
Kevin K. <kbknapp@gmail.com>
tests clap library

USAGE:
    clap-test [FLAGS] [OPTIONS] [ARGS] [SUBCOMMAND]

FLAGS:
    -f, --flag       tests flags
    -F               tests flags with exclusions
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -O, --Option <option3>           specific vals [values: fast, slow]
        --long-option-2 <option2>    tests long options with exclusions
        --maxvals3 <maxvals>...      Tests 3 max vals
        --minvals2 <minvals>...      Tests 2 min vals
        --multvals <one> <two>       Tests mutliple values, not mult occs
        --multvalsmo <one> <two>     Tests mutliple values, and mult occs
    -o, --option <opt>...            tests options

ARGS:
    <positional>        tests positionals
    <positional2>       tests positionals with exclusions
    <positional3>...    tests specific values [values: vi, emacs]

SUBCOMMANDS:
    help      Prints this message or the help of the given subcommand(s)
    subcmd    tests subcommands";

static AFTER_HELP: &'static str = "some text that comes before the help

clap-test v1.4.8
tests clap library

USAGE:
    clap-test

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

some text that comes after the help";

static SC_HELP: &'static str = "subcmd 0.1
Kevin K. <kbknapp@gmail.com>
tests subcommands

USAGE:
    subcmd [FLAGS] [OPTIONS] [--] [scpositional]

FLAGS:
    -f, --flag    tests flags

OPTIONS:
    -o, --option <scoption>...    tests options

ARGS:
    <scpositional>    tests positionals";

static MULTI_SC_HELP: &'static str = "ctest-subcmd-multi 0.1
Kevin K. <kbknapp@gmail.com>
tests subcommands

USAGE:
    ctest subcmd multi [FLAGS] [OPTIONS]

FLAGS:
    -f, --flag       tests flags
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -o, --option <scoption>...    tests options";

static ISSUE_626_CUTOFF: &'static str = "ctest 0.1

USAGE:
    ctest [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --cafe <FILE>    A coffeehouse, coffee shop, or café is an
                         establishment which primarily serves hot
                         coffee, related coffee beverages (e.g.,
                         café latte, cappuccino, espresso), tea,
                         and other hot beverages. Some
                         coffeehouses also serve cold beverages
                         such as iced coffee and iced tea. Many
                         cafés also serve some type of food, such
                         as light snacks, muffins, or pastries.";

static ISSUE_626_PANIC: &'static str = "ctest 0.1

USAGE:
    ctest [OPTIONS]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

OPTIONS:
    -c, --cafe <FILE>
            La culture du café est très développée
            dans de nombreux pays à climat chaud
            d\'Amérique, d\'Afrique et d\'Asie,
            dans des plantations qui sont
            cultivées pour les marchés
            d\'exportation. Le café est souvent
            une contribution majeure aux
            exportations des régions productrices.";

#[test]
fn help_short() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "-h"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn help_long() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "--help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn help_no_subcommand() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .get_matches_from_safe(vec!["myprog", "help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::UnknownArgument);
}

#[test]
fn help_subcommand() {
    let m = App::new("test")
        .author("Kevin K.")
        .about("tests stuff")
        .version("1.3")
        .subcommand(SubCommand::with_name("test")
            .about("tests things")
            .arg_from_usage("-v --verbose 'with verbosity'"))
        .get_matches_from_safe(vec!["myprog", "help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_short_help() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "subcmd", "-h"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_long_help() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "subcmd", "--help"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn subcommand_help_rev() {
    let m = test::complex_app()
        .get_matches_from_safe(vec!["clap-test", "help", "subcmd"]);

    assert!(m.is_err());
    assert_eq!(m.unwrap_err().kind, ErrorKind::HelpDisplayed);
}

#[test]
fn complex_help_output() {
    test::check_help(test::complex_app(), HELP);
}

#[test]
fn after_and_before_help_output() {
    let app = App::new("clap-test")
        .version("v1.4.8")
        .about("tests clap library")
        .before_help("some text that comes before the help")
        .after_help("some text that comes after the help");
    test::check_help(app, AFTER_HELP);
}

#[test]
fn multi_level_sc_help() {
    let app = App::new("ctest")
        .subcommand(SubCommand::with_name("subcmd")
            .subcommand(SubCommand::with_name("multi")
                .about("tests subcommands")
                .author("Kevin K. <kbknapp@gmail.com>")
                .version("0.1")
                .args_from_usage("
                    -f, --flag                    'tests flags'
                    -o, --option [scoption]...    'tests options'
                ")));
    test::check_err_output(app, "ctest help subcmd multi", MULTI_SC_HELP, false);
}

#[test]
fn no_wrap_help() {
    let app = App::new("ctest")
        .set_term_width(0)
        .help(MULTI_SC_HELP);
    test::check_err_output(app, "ctest --help", MULTI_SC_HELP, false);
}

#[test]
fn complex_subcommand_help_output() {
    let mut a = test::complex_app();
    let _ = a.get_matches_from_safe_borrow(vec![""]);
    let sc = a.p.subcommands.iter().filter(|s| s.p.meta.name == "subcmd").next().unwrap();
    // Now we check the output of print_help()
    let mut help = vec![];
    sc.write_help(&mut help).ok().expect("failed to print help");
    assert_eq!(&*String::from_utf8(help).unwrap(), SC_HELP);
}

#[test]
fn issue_626_unicode_cutoff() {
    let app = App::new("ctest")
        .version("0.1")
        .set_term_width(70)
        .arg(Arg::with_name("cafe")
           .short("c")
           .long("cafe")
           .value_name("FILE")
           .help("A coffeehouse, coffee shop, or café is an establishment \
           which primarily serves hot coffee, related coffee beverages \
           (e.g., café latte, cappuccino, espresso), tea, and other hot \
           beverages. Some coffeehouses also serve cold beverages such as \
           iced coffee and iced tea. Many cafés also serve some type of \
           food, such as light snacks, muffins, or pastries.")
           .takes_value(true));
    test::check_err_output(app, "ctest --help", ISSUE_626_CUTOFF, false);
}

#[test]
fn issue_626_panic() {
    let app = App::new("ctest")
        .version("0.1")
        .set_term_width(52)
        .arg(Arg::with_name("cafe")
           .short("c")
           .long("cafe")
           .value_name("FILE")
           .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
           d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
           Le café est souvent une contribution majeure aux exportations des régions productrices.")
           .takes_value(true));
    test::check_err_output(app, "ctest --help", ISSUE_626_PANIC, false);
}

#[test]
fn issue_626_variable_panic() {
    for i in 10..320 {
        let _ = App::new("ctest")
            .version("0.1")
            .set_term_width(i)
            .arg(Arg::with_name("cafe")
               .short("c")
               .long("cafe")
               .value_name("FILE")
               .help("La culture du café est très développée dans de nombreux pays à climat chaud d'Amérique, \
               d'Afrique et d'Asie, dans des plantations qui sont cultivées pour les marchés d'exportation. \
               Le café est souvent une contribution majeure aux exportations des régions productrices.")
               .takes_value(true))
            .get_matches_from_safe(vec!["ctest", "--help"]);
    }
}
<|endoftext|>


<commit_before>extern crate mpd;

mod helpers;

#[test]
fn idle() {
    let mut mpd = helpers::connect();
    let idle = mpd.idle(&[]).unwrap();

    let mut mpd1 = helpers::connect();
    mpd1.volume(0).unwrap();

    let sys = idle.get().unwrap();
    assert_eq!(&*sys, &[mpd::Subsystem::Mixer]);
}
<commit_msg>fix idle test for travis<commit_after>extern crate mpd;

mod helpers;

#[test]
fn idle() {
    let mut mpd = helpers::connect();
    let idle = mpd.idle(&[]).unwrap();

    let mut mpd1 = helpers::connect();
    mpd1.consume(true).unwrap();
    mpd1.consume(false).unwrap();

    let sys = idle.get().unwrap();
    assert_eq!(&*sys, &[mpd::Subsystem::Options]);
}
<|endoftext|>


<commit_before>#![cfg(feature = "discovery")]

extern crate rusoto_core;
extern crate rusoto_discovery;
extern crate env_logger;
extern crate log;

use rusoto_discovery::{Discovery, DiscoveryClient, DescribeTagsRequest, ListConfigurationsRequest};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

#[test]
fn should_describe_tags() {
    let _ = env_logger::init();
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DiscoveryClient::new(default_tls_client().unwrap(), credentials, Region::UsWest2);
    let request = DescribeTagsRequest::default();

    // The AWS CLI also returns this error:
    match client.describe_tags(&request) {
        Ok(response) => println!("Response: {:?}", response),
        Err(e) => assert!(format!("{}", e).contains("is not whitelisted to access")),
    }
}

#[test]
fn should_list_configurations() {
    let _ = env_logger::init();
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DiscoveryClient::new(default_tls_client().unwrap(), credentials, Region::UsWest2);
    let request = ListConfigurationsRequest{
        configuration_type: "SERVER".to_owned(),
        ..Default::default()
    };

    // The AWS CLI also returns this error:
    match client.list_configurations(&request) {
        Ok(response) => println!("Response: {:?}", response),
        Err(e) => assert!(format!("{}", e).contains("is not whitelisted to access")),
    }
}<commit_msg>Add note about Discovery service needing extra actions to work.<commit_after>#![cfg(feature = "discovery")]

extern crate rusoto_core;
extern crate rusoto_discovery;
extern crate env_logger;
extern crate log;

use rusoto_discovery::{Discovery, DiscoveryClient, DescribeTagsRequest, ListConfigurationsRequest};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

// These tests require the calling AWS account to be whitelisted.
// See http://docs.aws.amazon.com/application-discovery/latest/userguide/console_walkthrough.html
// For now we'll accept the error message returned if the account is not whitelisted.
#[test]
fn should_describe_tags() {
    let _ = env_logger::init();
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DiscoveryClient::new(default_tls_client().unwrap(), credentials, Region::UsWest2);
    let request = DescribeTagsRequest::default();

    match client.describe_tags(&request) {
        Ok(response) => println!("Response: {:?}", response),
        Err(e) => assert!(format!("{}", e).contains("is not whitelisted to access")),
    }
}

#[test]
fn should_list_configurations() {
    let _ = env_logger::init();
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DiscoveryClient::new(default_tls_client().unwrap(), credentials, Region::UsWest2);
    let request = ListConfigurationsRequest{
        configuration_type: "SERVER".to_owned(),
        ..Default::default()
    };

    match client.list_configurations(&request) {
        Ok(response) => println!("Response: {:?}", response),
        Err(e) => assert!(format!("{}", e).contains("is not whitelisted to access")),
    }
}<|endoftext|>


<commit_before>use crate::dep_graph;
use crate::hir::exports::Export;
use crate::hir::map;
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintLevelMap;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::cstore::{CrateDepKind, CrateSource};
use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::AccessLevels;
use crate::middle::region;
use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput};
use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult};
use crate::mir::mono::CodegenUnit;
use crate::traits::query::{
    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
};
use crate::traits::query::{
    DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
    OutlivesBound,
};
use crate::traits::specialization_graph;
use crate::traits::{self, ImplSource};
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::StableVec;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{ErrorReported, Handler};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_serialize::opaque;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::utils::NativeLibKind;
use rustc_session::CrateDisambiguator;
use rustc_target::spec::PanicStrategy;

use rustc_ast as ast;
use rustc_attr as attr;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use std::collections::BTreeMap;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;

pub(crate) use rustc_query_system::query::QueryJobId;
use rustc_query_system::query::*;

pub mod on_disk_cache;
pub use self::on_disk_cache::OnDiskCache;

#[derive(Copy, Clone)]
pub struct TyCtxtAt<'tcx> {
    pub tcx: TyCtxt<'tcx>,
    pub span: Span,
}

impl Deref for TyCtxtAt<'tcx> {
    type Target = TyCtxt<'tcx>;
    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        &self.tcx
    }
}

#[derive(Copy, Clone)]
pub struct TyCtxtEnsure<'tcx> {
    pub tcx: TyCtxt<'tcx>,
}

impl TyCtxt<'tcx> {
    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
    /// are executed instead of just returning their results.
    #[inline(always)]
    pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
        TyCtxtEnsure { tcx: self }
    }

    /// Returns a transparent wrapper for `TyCtxt` which uses
    /// `span` as the location of queries performed through it.
    #[inline(always)]
    pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
        TyCtxtAt { tcx: self, span }
    }

    pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
        self.queries.try_mark_green(self, dep_node)
    }
}

macro_rules! query_helper_param_ty {
    (DefId) => { impl IntoQueryParam<DefId> };
    ($K:ty) => { $K };
}

macro_rules! query_storage {
    ([][$K:ty, $V:ty]) => {
        <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
    };
    ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
        <$ty as CacheSelector<$K, $V>>::Cache
    };
    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
        query_storage!([$($($modifiers)*)*][$($args)*])
    };
}

macro_rules! define_callbacks {
    (<$tcx:tt>
     $($(#[$attr:meta])*
        [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {

        // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
        // below, but using type aliases instead of associated types, to bypass
        // the limitations around normalizing under HRTB - for example, this:
        // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
        // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
        // This is primarily used by the `provide!` macro in `rustc_metadata`.
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_keys {
            use super::*;

            $(pub type $name<$tcx> = $($K)*;)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_values {
            use super::*;

            $(pub type $name<$tcx> = $V;)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_storage {
            use super::*;

            $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_stored {
            use super::*;

            $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
        }

        #[derive(Default)]
        pub struct QueryCaches<$tcx> {
            $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
        }

        impl TyCtxtEnsure<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
                let key = key.into_query_param();
                let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {});

                let lookup = match cached {
                    Ok(()) => return,
                    Err(lookup) => lookup,
                };

                self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
            })*
        }

        impl TyCtxt<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            #[must_use]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
            {
                self.at(DUMMY_SP).$name(key)
            })*
        }

        impl TyCtxtAt<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
            {
                let key = key.into_query_param();
                let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| {
                    value.clone()
                });

                let lookup = match cached {
                    Ok(value) => return value,
                    Err(lookup) => lookup,
                };

                self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
            })*
        }

        pub struct Providers {
            $(pub $name: for<'tcx> fn(
                TyCtxt<'tcx>,
                query_keys::$name<'tcx>,
            ) -> query_values::$name<'tcx>,)*
        }

        impl Default for Providers {
            fn default() -> Self {
                Providers {
                    $($name: |_, key| bug!(
                        "`tcx.{}({:?})` unsupported by its crate",
                         stringify!($name), key
                    ),)*
                }
            }
        }

        impl Copy for Providers {}
        impl Clone for Providers {
            fn clone(&self) -> Self { *self }
        }

        pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
            unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry);

            fn encode_query_results(
                &'tcx self,
                tcx: TyCtxt<'tcx>,
                encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
                query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
            ) -> opaque::FileEncodeResult;

            fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>);

            fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;

            fn try_print_query_stack(
                &'tcx self,
                tcx: TyCtxt<'tcx>,
                query: Option<QueryJobId<dep_graph::DepKind>>,
                handler: &Handler,
                num_frames: Option<usize>,
            ) -> usize;

            $($(#[$attr])*
            fn $name(
                &'tcx self,
                tcx: TyCtxt<$tcx>,
                span: Span,
                key: query_keys::$name<$tcx>,
                lookup: QueryLookup,
                mode: QueryMode,
            ) -> Option<query_stored::$name<$tcx>>;)*
        }
    };
}

// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
// which memoizes and does dep-graph tracking, wrapping around the actual
// `Providers` that the driver creates (using several `rustc_*` crates).
//
// The result type of each query must implement `Clone`, and additionally
// `ty::query::values::Value`, which produces an appropriate placeholder
// (error) value if the query resulted in a query cycle.
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.

rustc_query_append! { [define_callbacks!][<'tcx>] }

mod sealed {
    use super::{DefId, LocalDefId};

    /// An analogue of the `Into` trait that's intended only for query paramaters.
    ///
    /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
    /// user call `to_def_id` to convert between them everywhere else.
    pub trait IntoQueryParam<P> {
        fn into_query_param(self) -> P;
    }

    impl<P> IntoQueryParam<P> for P {
        #[inline(always)]
        fn into_query_param(self) -> P {
            self
        }
    }

    impl IntoQueryParam<DefId> for LocalDefId {
        #[inline(always)]
        fn into_query_param(self) -> DefId {
            self.to_def_id()
        }
    }
}

use sealed::IntoQueryParam;

impl TyCtxt<'tcx> {
    pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
        let def_id = def_id.into_query_param();
        self.opt_def_kind(def_id)
            .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
    }
}

impl TyCtxtAt<'tcx> {
    pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
        let def_id = def_id.into_query_param();
        self.opt_def_kind(def_id)
            .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
    }
}
<commit_msg>Rollup merge of #83367 - richkadel:query-err-msg, r=jyn514<commit_after>use crate::dep_graph;
use crate::hir::exports::Export;
use crate::hir::map;
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintLevelMap;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::cstore::{CrateDepKind, CrateSource};
use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use crate::middle::lib_features::LibFeatures;
use crate::middle::privacy::AccessLevels;
use crate::middle::region;
use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
use crate::middle::stability::{self, DeprecationEntry};
use crate::mir;
use crate::mir::interpret::GlobalId;
use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput};
use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult};
use crate::mir::mono::CodegenUnit;
use crate::traits::query::{
    CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
    CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
    CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
};
use crate::traits::query::{
    DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
    OutlivesBound,
};
use crate::traits::specialization_graph;
use crate::traits::{self, ImplSource};
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::StableVec;
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{ErrorReported, Handler};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
use rustc_hir::lang_items::{LangItem, LanguageItems};
use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
use rustc_serialize::opaque;
use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
use rustc_session::utils::NativeLibKind;
use rustc_session::CrateDisambiguator;
use rustc_target::spec::PanicStrategy;

use rustc_ast as ast;
use rustc_attr as attr;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use std::collections::BTreeMap;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;

pub(crate) use rustc_query_system::query::QueryJobId;
use rustc_query_system::query::*;

pub mod on_disk_cache;
pub use self::on_disk_cache::OnDiskCache;

#[derive(Copy, Clone)]
pub struct TyCtxtAt<'tcx> {
    pub tcx: TyCtxt<'tcx>,
    pub span: Span,
}

impl Deref for TyCtxtAt<'tcx> {
    type Target = TyCtxt<'tcx>;
    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        &self.tcx
    }
}

#[derive(Copy, Clone)]
pub struct TyCtxtEnsure<'tcx> {
    pub tcx: TyCtxt<'tcx>,
}

impl TyCtxt<'tcx> {
    /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
    /// are executed instead of just returning their results.
    #[inline(always)]
    pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
        TyCtxtEnsure { tcx: self }
    }

    /// Returns a transparent wrapper for `TyCtxt` which uses
    /// `span` as the location of queries performed through it.
    #[inline(always)]
    pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
        TyCtxtAt { tcx: self, span }
    }

    pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
        self.queries.try_mark_green(self, dep_node)
    }
}

macro_rules! query_helper_param_ty {
    (DefId) => { impl IntoQueryParam<DefId> };
    ($K:ty) => { $K };
}

macro_rules! query_storage {
    ([][$K:ty, $V:ty]) => {
        <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
    };
    ([storage($ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
        <$ty as CacheSelector<$K, $V>>::Cache
    };
    ([$other:ident $(($($other_args:tt)*))* $(, $($modifiers:tt)*)*][$($args:tt)*]) => {
        query_storage!([$($($modifiers)*)*][$($args)*])
    };
}

macro_rules! define_callbacks {
    (<$tcx:tt>
     $($(#[$attr:meta])*
        [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {

        // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
        // below, but using type aliases instead of associated types, to bypass
        // the limitations around normalizing under HRTB - for example, this:
        // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
        // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
        // This is primarily used by the `provide!` macro in `rustc_metadata`.
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_keys {
            use super::*;

            $(pub type $name<$tcx> = $($K)*;)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_values {
            use super::*;

            $(pub type $name<$tcx> = $V;)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_storage {
            use super::*;

            $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
        }
        #[allow(nonstandard_style, unused_lifetimes)]
        pub mod query_stored {
            use super::*;

            $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
        }

        #[derive(Default)]
        pub struct QueryCaches<$tcx> {
            $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
        }

        impl TyCtxtEnsure<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
                let key = key.into_query_param();
                let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |_| {});

                let lookup = match cached {
                    Ok(()) => return,
                    Err(lookup) => lookup,
                };

                self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
            })*
        }

        impl TyCtxt<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            #[must_use]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
            {
                self.at(DUMMY_SP).$name(key)
            })*
        }

        impl TyCtxtAt<$tcx> {
            $($(#[$attr])*
            #[inline(always)]
            pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
            {
                let key = key.into_query_param();
                let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, |value| {
                    value.clone()
                });

                let lookup = match cached {
                    Ok(value) => return value,
                    Err(lookup) => lookup,
                };

                self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
            })*
        }

        pub struct Providers {
            $(pub $name: for<'tcx> fn(
                TyCtxt<'tcx>,
                query_keys::$name<'tcx>,
            ) -> query_values::$name<'tcx>,)*
        }

        impl Default for Providers {
            fn default() -> Self {
                Providers {
                    $($name: |_, key| bug!(
                        "`tcx.{}({:?})` unsupported by its crate; \
                         perhaps the `{}` query was never assigned a provider function",
                        stringify!($name),
                        key,
                        stringify!($name),
                    ),)*
                }
            }
        }

        impl Copy for Providers {}
        impl Clone for Providers {
            fn clone(&self) -> Self { *self }
        }

        pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
            unsafe fn deadlock(&'tcx self, tcx: TyCtxt<'tcx>, registry: &rustc_rayon_core::Registry);

            fn encode_query_results(
                &'tcx self,
                tcx: TyCtxt<'tcx>,
                encoder: &mut on_disk_cache::CacheEncoder<'a, 'tcx, opaque::FileEncoder>,
                query_result_index: &mut on_disk_cache::EncodedQueryResultIndex,
            ) -> opaque::FileEncodeResult;

            fn exec_cache_promotions(&'tcx self, tcx: TyCtxt<'tcx>);

            fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;

            fn try_print_query_stack(
                &'tcx self,
                tcx: TyCtxt<'tcx>,
                query: Option<QueryJobId<dep_graph::DepKind>>,
                handler: &Handler,
                num_frames: Option<usize>,
            ) -> usize;

            $($(#[$attr])*
            fn $name(
                &'tcx self,
                tcx: TyCtxt<$tcx>,
                span: Span,
                key: query_keys::$name<$tcx>,
                lookup: QueryLookup,
                mode: QueryMode,
            ) -> Option<query_stored::$name<$tcx>>;)*
        }
    };
}

// Each of these queries corresponds to a function pointer field in the
// `Providers` struct for requesting a value of that type, and a method
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
// which memoizes and does dep-graph tracking, wrapping around the actual
// `Providers` that the driver creates (using several `rustc_*` crates).
//
// The result type of each query must implement `Clone`, and additionally
// `ty::query::values::Value`, which produces an appropriate placeholder
// (error) value if the query resulted in a query cycle.
// Queries marked with `fatal_cycle` do not need the latter implementation,
// as they will raise an fatal error on query cycles instead.

rustc_query_append! { [define_callbacks!][<'tcx>] }

mod sealed {
    use super::{DefId, LocalDefId};

    /// An analogue of the `Into` trait that's intended only for query paramaters.
    ///
    /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
    /// user call `to_def_id` to convert between them everywhere else.
    pub trait IntoQueryParam<P> {
        fn into_query_param(self) -> P;
    }

    impl<P> IntoQueryParam<P> for P {
        #[inline(always)]
        fn into_query_param(self) -> P {
            self
        }
    }

    impl IntoQueryParam<DefId> for LocalDefId {
        #[inline(always)]
        fn into_query_param(self) -> DefId {
            self.to_def_id()
        }
    }
}

use sealed::IntoQueryParam;

impl TyCtxt<'tcx> {
    pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
        let def_id = def_id.into_query_param();
        self.opt_def_kind(def_id)
            .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
    }
}

impl TyCtxtAt<'tcx> {
    pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
        let def_id = def_id.into_query_param();
        self.opt_def_kind(def_id)
            .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 Chef Software Inc. and/or applicable contributors
//
// 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.

use serde_json::{self,
                 json,
                 Value as Json};
use std::{fs::{create_dir_all,
               read_to_string,
               File},
          io::Write,
          path::Path};
use toml::Value;

use crate::{common::{templating::TemplateRenderer,
                     ui::{Status,
                          UIWriter,
                          UI}},
            error::Result};

pub fn start(ui: &mut UI,
             template_path: &Path,
             default_toml_path: &Path,
             user_toml_path: Option<&Path>,
             mock_data_path: Option<&Path>,
             print: bool,
             render: bool,
             render_dir: &Path,
             quiet: bool)
             -> Result<()> {
    // Strip the file name out of our passed template
    let file_name = match Path::new(&template_path).file_name() {
        Some(name) => Path::new(name),
        None => {
            panic!(format!("Something went wrong getting filename of {:?}",
                           &template_path))
        }
    };

    if !quiet {
        ui.begin(format!("Rendering: {:?} into: {:?} as: {:?}",
                         template_path, render_dir, file_name))?;
        ui.br()?;
    }

    // read our template from file
    let template = read_to_string(&template_path)?;

    // create a "data" json struct
    let mut data = json!({});

    if !quiet {
        // import default.toml values, convert to JSON
        ui.begin(format!("Importing default.toml: {:?}", &default_toml_path))?;
    }

    // we should always have a default.toml, would be nice to "autodiscover" based on package name,
    // for now assume we're working in the plan dir if --default-toml not passed
    let default_toml = read_to_string(&default_toml_path)?;

    // merge default into data struct
    merge(&mut data, toml_to_json(&default_toml)?);

    // import default.toml values, convert to JSON
    let user_toml = match user_toml_path {
        Some(path) => {
            if !quiet {
                // print helper message, maybe only print if '--verbose'? how?
                ui.begin(format!("Importing user.toml: {:?}", path))?;
            }
            read_to_string(path)?
        }
        None => String::new(),
    };
    // merge default into data struct
    merge(&mut data, toml_to_json(&user_toml)?);

    // read mock data if provided
    let mock_data = match mock_data_path {
        Some(path) => {
            if !quiet {
                // print helper message, maybe only print if '--verbose'? how?
                ui.begin(format!("Importing override file: {:?}", path))?;
            }
            read_to_string(path)?
        }
        // return an empty json block if '--mock-data' isn't defined.
        // this allows us to merge an empty JSON block
        None => "{}".to_string(),
    };
    // merge mock data into data
    merge(&mut data, serde_json::from_str(&mock_data)?);

    // create a template renderer
    let mut renderer = TemplateRenderer::new();
    // register our template
    renderer.register_template_string(&template, &template)
            .expect("Could not register template content");
    // render our JSON override in our template.
    let rendered_template = renderer.render(&template, &data)?;

    if print {
        if !quiet {
            ui.br()?;
            ui.warn(format!("###======== Rendered template: {:?}", &template_path))?;
        }

        println!("{}", rendered_template);

        if !quiet {
            ui.warn(format!("========### End rendered template: {:?}", &template_path))?;
        }
    }

    if render {
        // Render our template file
        create_with_template(ui, &render_dir, &file_name, &rendered_template, quiet)?;
    }

    if !quiet {
        ui.br()?;
    }
    Ok(())
}

fn toml_to_json(cfg: &str) -> Result<Json> {
    let toml_value = cfg.parse::<Value>()?;
    let toml_string = serde_json::to_string(&toml_value)?;
    let json = serde_json::from_str(&format!(r#"{{ "cfg": {} }}"#, &toml_string))?;
    Ok(json)
}

// merge two Json structs
fn merge(a: &mut Json, b: Json) {
    if let Json::Object(a_map) = a {
        if let Json::Object(b_map) = b {
            for (k, v) in b_map {
                merge(a_map.entry(k).or_insert(Json::Null), v);
            }
            return;
        }
    }
    *a = b;
}

fn create_with_template(ui: &mut UI,
                        render_dir: &std::path::Path,
                        file_name: &std::path::Path,
                        template: &str,
                        quiet: bool)
                        -> Result<()> {
    let path = Path::new(&render_dir).join(&file_name);
    if !quiet {
        ui.status(Status::Creating, format!("file: {:?}", path))?;
    }

    create_dir_all(render_dir)?;

    // Write file to disk
    File::create(path).and_then(|mut file| file.write(template.as_bytes()))?;
    Ok(())
}
<commit_msg>{:?} to {}<commit_after>// Copyright (c) 2019 Chef Software Inc. and/or applicable contributors
//
// 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.

use serde_json::{self,
                 json,
                 Value as Json};
use std::{fs::{create_dir_all,
               read_to_string,
               File},
          io::Write,
          path::Path};
use toml::Value;

use crate::{common::{templating::TemplateRenderer,
                     ui::{Status,
                          UIWriter,
                          UI}},
            error::Result};

pub fn start(ui: &mut UI,
             template_path: &Path,
             default_toml_path: &Path,
             user_toml_path: Option<&Path>,
             mock_data_path: Option<&Path>,
             print: bool,
             render: bool,
             render_dir: &Path,
             quiet: bool)
             -> Result<()> {
    // Strip the file name out of our passed template
    let file_name = match Path::new(&template_path).file_name() {
        Some(name) => Path::new(name),
        None => {
            panic!(format!("Something went wrong getting filename of {:?}",
                           &template_path))
        }
    };

    if !quiet {
        ui.begin(format!("Rendering: {} into: {} as: {}",
                         template_path.display(), render_dir.display(), file_name.display()))?;
        ui.br()?;
    }

    // read our template from file
    let template = read_to_string(&template_path)?;

    // create a "data" json struct
    let mut data = json!({});

    if !quiet {
        // import default.toml values, convert to JSON
        ui.begin(format!("Importing default.toml: {}", &default_toml_path.display()))?;
    }

    // we should always have a default.toml, would be nice to "autodiscover" based on package name,
    // for now assume we're working in the plan dir if --default-toml not passed
    let default_toml = read_to_string(&default_toml_path)?;

    // merge default into data struct
    merge(&mut data, toml_to_json(&default_toml)?);

    // import default.toml values, convert to JSON
    let user_toml = match user_toml_path {
        Some(path) => {
            if !quiet {
                // print helper message, maybe only print if '--verbose'? how?
                ui.begin(format!("Importing user.toml: {}", path.display()))?;
            }
            read_to_string(path)?
        }
        None => String::new(),
    };
    // merge default into data struct
    merge(&mut data, toml_to_json(&user_toml)?);

    // read mock data if provided
    let mock_data = match mock_data_path {
        Some(path) => {
            if !quiet {
                // print helper message, maybe only print if '--verbose'? how?
                ui.begin(format!("Importing override file: {}", path.display()))?;
            }
            read_to_string(path)?
        }
        // return an empty json block if '--mock-data' isn't defined.
        // this allows us to merge an empty JSON block
        None => "{}".to_string(),
    };
    // merge mock data into data
    merge(&mut data, serde_json::from_str(&mock_data)?);

    // create a template renderer
    let mut renderer = TemplateRenderer::new();
    // register our template
    renderer.register_template_string(&template, &template)
            .expect("Could not register template content");
    // render our JSON override in our template.
    let rendered_template = renderer.render(&template, &data)?;

    if print {
        if !quiet {
            ui.br()?;
            ui.warn(format!("###======== Rendered template: {}", &template_path.display()))?;
        }

        println!("{}", rendered_template);

        if !quiet {
            ui.warn(format!("========### End rendered template: {}", &template_path.display()))?;
        }
    }

    if render {
        // Render our template file
        create_with_template(ui, &render_dir, &file_name, &rendered_template, quiet)?;
    }

    if !quiet {
        ui.br()?;
    }
    Ok(())
}

fn toml_to_json(cfg: &str) -> Result<Json> {
    let toml_value = cfg.parse::<Value>()?;
    let toml_string = serde_json::to_string(&toml_value)?;
    let json = serde_json::from_str(&format!(r#"{{ "cfg": {} }}"#, &toml_string))?;
    Ok(json)
}

// merge two Json structs
fn merge(a: &mut Json, b: Json) {
    if let Json::Object(a_map) = a {
        if let Json::Object(b_map) = b {
            for (k, v) in b_map {
                merge(a_map.entry(k).or_insert(Json::Null), v);
            }
            return;
        }
    }
    *a = b;
}

fn create_with_template(ui: &mut UI,
                        render_dir: &std::path::Path,
                        file_name: &std::path::Path,
                        template: &str,
                        quiet: bool)
                        -> Result<()> {
    let path = Path::new(&render_dir).join(&file_name);
    if !quiet {
        ui.status(Status::Creating, format!("file: {}", path.display()))?;
    }

    create_dir_all(render_dir)?;

    // Write file to disk
    File::create(path).and_then(|mut file| file.write(template.as_bytes()))?;
    Ok(())
}
<|endoftext|>