<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

#![feature(collections)]

extern crate gcc;
extern crate "pkg-config" as pkg_config;

use std::process::Command;
use gcc::Config;
use std::env;
use std::path::PathBuf;

fn main() {
    env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");

    // try to find gtk+-3.0 library
    match pkg_config::find_library("gtk+-3.0") {
        Ok(_) => {},
        Err(e) => panic!("{}", e)
    };

    // call native pkg-config, there is no way to do this with pkg-config for now
    let cmd = Command::new("pkg-config").arg("--cflags").arg("gtk+-3.0")
                .output().unwrap();
    if !cmd.status.success() {
        panic!("{}", String::from_utf8_lossy(&cmd.stderr));
    }

    // make the vector of path to set to gcc::Config
    let output = String::from_utf8(cmd.stdout).unwrap();
    let res: Vec<&str> = output.split(' ').collect();
    let paths: Vec<PathBuf> = res.iter().filter_map(|s| {
        if s.len() > 1 && s.char_at(1) == 'I' { Some(PathBuf::new(&s[2..])) }
        else { None }
    }).collect();

    // build include path
    let mut gcc_conf = Config::new();
    for path in paths {
        gcc_conf.include(&path);
    }
    gcc_conf.file("src/gtk_glue.c");

    // pass the GTK feature flags
    for (key, _) in env::vars() {
        if key.starts_with("CARGO_FEATURE_") {
            let feature = key.trim_left_matches("CARGO_FEATURE_");
            if feature.starts_with("GTK_") {
                let mut flag = String::from_str("-D");
                flag.push_str(feature);
                gcc_conf.flag(&flag);
            }
        }
    }

    // build library
    gcc_conf.compile("librgtk_glue.a");
}
<commit_msg>Replace match...Err block with equivalent unwrap()<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

#![feature(collections)]

extern crate gcc;
extern crate "pkg-config" as pkg_config;

use std::process::Command;
use gcc::Config;
use std::env;
use std::path::PathBuf;

fn main() {
    env::set_var("PKG_CONFIG_ALLOW_CROSS", "1");

    // try to find gtk+-3.0 library
    pkg_config::find_library("gtk+-3.0").unwrap();

    // call native pkg-config, there is no way to do this with pkg-config for now
    let cmd = Command::new("pkg-config").arg("--cflags").arg("gtk+-3.0")
                .output().unwrap();
    if !cmd.status.success() {
        panic!("{}", String::from_utf8_lossy(&cmd.stderr));
    }

    // make the vector of path to set to gcc::Config
    let output = String::from_utf8(cmd.stdout).unwrap();
    let res: Vec<&str> = output.split(' ').collect();
    let paths: Vec<PathBuf> = res.iter().filter_map(|s| {
        if s.len() > 1 && s.char_at(1) == 'I' { Some(PathBuf::new(&s[2..])) }
        else { None }
    }).collect();

    // build include path
    let mut gcc_conf = Config::new();
    for path in paths {
        gcc_conf.include(&path);
    }
    gcc_conf.file("src/gtk_glue.c");

    // pass the GTK feature flags
    for (key, _) in env::vars() {
        if key.starts_with("CARGO_FEATURE_") {
            let feature = key.trim_left_matches("CARGO_FEATURE_");
            if feature.starts_with("GTK_") {
                let mut flag = String::from_str("-D");
                flag.push_str(feature);
                gcc_conf.flag(&flag);
            }
        }
    }

    // build library
    gcc_conf.compile("librgtk_glue.a");
}
<|endoftext|>


<commit_before><commit_msg>Add echo-server example<commit_after>/// This is an implementation of an echo server.

/// One process reads input and sends it to the other process, which outputs it.

#[macro_use]
extern crate session_types;
use session_types::*;

use std::thread::spawn;

type Srv = Offer<Eps, Recv<String, Var<Z>>>;
fn srv(c: Chan<(), Rec<Srv>>) {

    let mut c = c.enter();

    loop {
        c = offer!{ c,
            CLOSE => {
                println!("Closing server.");
                c.close();
                break
            },
            RECV => {
                let (c, s) = c.recv();
                println!("Received: {}", s);
                c.zero()
            }
        };
    }
}

type Cli = <Srv as HasDual>::Dual;
fn cli(c: Chan<(), Rec<Cli>>) {

    let mut stdin = std::io::stdin();
    let mut count = 0usize;

    let mut c = c.enter();
    let mut buf = "".to_string();
    loop {
        stdin.read_line(&mut buf).ok().unwrap();
        if !buf.is_empty() {
            buf.pop();
        }
        match &buf[..] {
            "q" => {
                let c = c.sel2().send(format!("{} lines sent", count));
                c.zero().sel1().close();
                println!("Client quitting");
                break;
            }
            _ => {
                c = c.sel2().send(buf.clone()).zero();
                buf.clear();
                count += 1;
            }
        }
    }
}

fn main() {
    let (c1, c2) = session_channel();
    spawn(move || srv(c1));
    cli(c2);
}
<|endoftext|>


<commit_before>fn give_princess(gift: &str) {
    // Princesses hate snakes, so we need to stop if
    // she expresses her disapproval!
    if gift == "snake" { panic!("AAAaaaaa!!!!"); }

    println!("I love {}s!!!!!", gift);
}

fn main() {
    give_princess("teddy bear");
    give_princess("snake");
}
<commit_msg>Removed code from chapter intro<commit_after><|endoftext|>


<commit_before><commit_msg>Implement 'From<T>' for 'Stream<T>' instead of custom 'from'.<commit_after><|endoftext|>


<commit_before><commit_msg>Add serialization impl's for `response::Note`<commit_after><|endoftext|>


<commit_before><commit_msg>Typo fix.<commit_after><|endoftext|>


<commit_before><commit_msg> #10 Shader binding adjustment<commit_after><|endoftext|>


<commit_before><commit_msg>Allow deprecated usage in the code produced by an error-chain macro<commit_after><|endoftext|>


<commit_before><commit_msg>Added a test for typechecking blowup.<commit_after>// Test for typechecking blow-up
// https://github.com/rust-lang/rust/issues/31849

extern crate parsell;
use parsell::{Parser, UncommittedStr, CHARACTER};

#[test]
fn test_typecheck_time() {
    CHARACTER
        .and_then(CHARACTER)
        .and_then(CHARACTER)
        .and_then(CHARACTER)
        .and_then(CHARACTER)
        .and_then(CHARACTER)
        .and_then(CHARACTER)
        .init_str("hello, world");
}
<|endoftext|>


<commit_before><commit_msg>Add build_entry_path(), Copy of imag-store/src/util/build_entry_path()<commit_after>use std::path::PathBuf;

use semver::Version;

use libimagrt::runtime::Runtime;

pub fn build_entry_path(rt: &Runtime, path_elem: &str) -> PathBuf {
    debug!("Checking path element for version");
    {
        let contains_version = {
            path_elem.split("~")
                .last()
                .map(|version| Version::parse(version).is_ok())
                .unwrap_or(false)
        };

        if !contains_version {
            debug!("Version cannot be parsed inside {:?}", path_elem);
            warn!("Path does not contain version. Will panic now!");
            panic!("No version in path");
        }
    }
    debug!("Version checking succeeded");

    debug!("Building path from {:?}", path_elem);
    let mut path = rt.store().path().clone();

    if path_elem.chars().next() == Some('/') {
        path.push(&path_elem[1..path_elem.len()]);
    } else {
        path.push(path_elem);
    }

    path
}

<|endoftext|>


<commit_before><commit_msg>use new abs API<commit_after><|endoftext|>


<commit_before>// -*- rust -*-

/*
  A parallel version of fibonacci numbers.
*/

use std;

import std::vec;
import std::uint;
import std::time;
import std::str;

fn recv[T](&port[T] p) -> T {
    let T x;
    p |> x;
    ret x;
}

fn fib(int n) -> int {
    fn pfib(chan[int] c, int n) {
        if (n == 0) {
            c <| 0;
        }
        else if (n <= 2) {
            c <| 1;
        }
        else {
            let port[int] p = port();

            auto t1 = spawn pfib(chan(p), n - 1);
            auto t2 = spawn pfib(chan(p), n - 2);

            c <| recv(p) + recv(p);
        }
    }

    let port[int] p = port();
    auto t = spawn pfib(chan(p), n);
    ret recv(p);
}

fn main(vec[str] argv) {
    if(vec::len(argv) == 1u) {
        assert (fib(8) == 21);
        assert (fib(15) == 610);
        log fib(8);
        log fib(15);
    }
    else {
        // Interactive mode! Wooo!!!!

        auto n = uint::parse_buf(str::bytes(argv.(1)), 10u) as int;
        auto start = time::precise_time_ns();
        auto fibn = fib(n);
        auto stop = time::precise_time_ns();

        assert(stop >= start);

        auto elapsed = stop - start;
        auto us_task = elapsed / (fibn as u64) / (1000 as u64);

        log_err #fmt("Determined that fib(%d) = %d in %d%d ns (%d us / task)",
                     n, fibn,
                     (elapsed / (1000000 as u64)) as int,
                     (elapsed % (1000000 as u64)) as int,
                     us_task as int);
    }
}
<commit_msg>Commenting out the huge-memory-using lines in pfib.<commit_after>// -*- rust -*-

/*
  A parallel version of fibonacci numbers.
*/

use std;

import std::vec;
import std::uint;
import std::time;
import std::str;

fn recv[T](&port[T] p) -> T {
    let T x;
    p |> x;
    ret x;
}

fn fib(int n) -> int {
    fn pfib(chan[int] c, int n) {
        if (n == 0) {
            c <| 0;
        }
        else if (n <= 2) {
            c <| 1;
        }
        else {
            let port[int] p = port();

            auto t1 = spawn pfib(chan(p), n - 1);
            auto t2 = spawn pfib(chan(p), n - 2);

            c <| recv(p) + recv(p);
        }
    }

    let port[int] p = port();
    auto t = spawn pfib(chan(p), n);
    ret recv(p);
}

fn main(vec[str] argv) {
    if(vec::len(argv) == 1u) {
        assert (fib(8) == 21);
        //assert (fib(15) == 610);
        log fib(8);
        //log fib(15);
    }
    else {
        // Interactive mode! Wooo!!!!

        auto n = uint::parse_buf(str::bytes(argv.(1)), 10u) as int;
        auto start = time::precise_time_ns();
        auto fibn = fib(n);
        auto stop = time::precise_time_ns();

        assert(stop >= start);

        auto elapsed = stop - start;
        auto us_task = elapsed / (fibn as u64) / (1000 as u64);

        log_err #fmt("Determined that fib(%d) = %d in %d%d ns (%d us / task)",
                     n, fibn,
                     (elapsed / (1000000 as u64)) as int,
                     (elapsed % (1000000 as u64)) as int,
                     us_task as int);
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove inline attributes.<commit_after><|endoftext|>


<commit_before><commit_msg>Added a function for parsing codepoint from &[u8]<commit_after>use std::char;

// More details: http://en.wikipedia.org/wiki/UTF-8#Description
static UTF8_1BYTE_FOLLOWING: u8 = 0b11000000;
static UTF8_2BYTE_FOLLOWING: u8 = 0b11100000;
static UTF8_3BYTE_FOLLOWING: u8 = 0b11110000;

pub fn readCodepoint( input: &[u8] ) -> Option< char > {
  fn bytesFollowing( byte: u8 ) -> Option< uint > {
    if byte & 0b11100000 == UTF8_1BYTE_FOLLOWING {
      return Some( 1 );
    }
    if byte & 0b11110000 == UTF8_2BYTE_FOLLOWING {
      return Some( 2 );
    }
    if byte & 0b11111000 == UTF8_3BYTE_FOLLOWING {
      return Some( 3 );
    }
    return None;
  }

  fn isAscii( byte: u8 ) -> bool {
    return byte & 0b10000000 == 0;
  }

  fn isContinuationByte( byte: u8 ) -> bool {
    byte & 0b11000000 == 0b10000000
  }

  fn codepointBitsFromLeadingByte( byte: u8 ) -> u32 {
    let good_bits =
      if byte & 0b11100000 == UTF8_1BYTE_FOLLOWING {
        byte & 0b00011111
      } else if byte & 0b11110000 == UTF8_2BYTE_FOLLOWING {
        byte & 0b00001111
      } else {
        byte & 0b00000111
      };
    good_bits as u32
  }

  fn codepointBitsFromContinuationByte( byte: u8 ) -> u32 {
    ( byte & 0b00111111 ) as u32
  }

  match input.get( 0 ) {
    Some( first_byte ) if isAscii( *first_byte ) => {
      char::from_u32( *first_byte as u32 )
    }

    Some( first_byte ) => {
      match bytesFollowing( *first_byte ) {
        Some( num_following ) => {
          let mut codepoint: u32 =
            codepointBitsFromLeadingByte( *first_byte ) << 6 * num_following;
          for i in range( 1, num_following + 1 ) {
            match input.get( i ) {
              Some( byte ) if isContinuationByte( *byte ) => {
                codepoint |= codepointBitsFromContinuationByte( *byte ) <<
                  6 * ( num_following - i );
              }
              _ => return None
            }
          }
          char::from_u32( codepoint )
        }
        _ => None
      }
    }
    _ => None
  }
}

pub fn charToUtf8( input: char ) -> ~[u8] {
  let utf8chars: &mut [u8] = [0, ..4];
  let num_written = input.encode_utf8( utf8chars );
  let mut out: ~[u8] = ~[];
  for i in range( 0, num_written ) {
    out.push( *utf8chars.get( i ).unwrap() );
  }
  out
}

#[cfg(test)]
mod tests {
  use super::{readCodepoint, charToUtf8, UTF8_1BYTE_FOLLOWING};

  #[test]
  fn readCodepoint_Roundtrip_SimpleAscii() {
    assert_eq!( 'a', readCodepoint( bytes!( 'a' ) ).unwrap() );
    assert_eq!( 'z', readCodepoint( bytes!( 'z' ) ).unwrap() );
    assert_eq!( 'A', readCodepoint( bytes!( 'A' ) ).unwrap() );
    assert_eq!( '9', readCodepoint( bytes!( '9' ) ).unwrap() );
    assert_eq!( '*', readCodepoint( bytes!( '*' ) ).unwrap() );
    assert_eq!( '\n', readCodepoint( bytes!( '\n' ) ).unwrap() );
    assert_eq!( '\0', readCodepoint( bytes!( '\0' ) ).unwrap() );
  }

  #[test]
  fn readCodepoint_Roundtrip_NonAscii() {
    // 2 UTF-8 bytes
    assert_eq!( '¢', readCodepoint( charToUtf8( '¢' ) ).unwrap() );

    // 3 UTF-8 bytes
    assert_eq!( '€', readCodepoint( charToUtf8( '€' ) ).unwrap() );

    // 4 UTF-8 bytes
    assert_eq!( '𤭢', readCodepoint( charToUtf8( '𤭢' ) ).unwrap() );

    // Some extras
    assert_eq!( 'Ć', readCodepoint( charToUtf8( 'Ć' ) ).unwrap() );
    assert_eq!( 'Ө', readCodepoint( charToUtf8( 'Ө' ) ).unwrap() );
    assert_eq!( '自', readCodepoint( charToUtf8( '自' ) ).unwrap() );
    assert_eq!( '由', readCodepoint( charToUtf8( '由' ) ).unwrap() );
  }

  #[test]
  fn readCodepoint_FailsOnBadChars() {
    assert!( readCodepoint( [ 0b11111111 ] ).is_none() );
    assert!( readCodepoint( [ 0b10000000 ] ).is_none() );
    assert!( readCodepoint( [ UTF8_1BYTE_FOLLOWING, 0b11000000 ] ).is_none() );
  }
}
<|endoftext|>


<commit_before><commit_msg>Improve the documentation for flush_st()<commit_after><|endoftext|>


<commit_before><commit_msg>Adding 2D plotting examples<commit_after>extern crate image;
extern crate bspline;

use std::ops::{Mul, Add};
use std::iter;

#[derive(Copy, Clone, Debug)]
struct Point {
    x: f32,
    y: f32,
}
impl Point {
    fn new(x: f32, y: f32) -> Point {
        Point { x: x, y: y }
    }
}
impl Mul<f32> for Point {
    type Output = Point;
    fn mul(self, rhs: f32) -> Point {
        Point { x: self.x * rhs, y: self.y * rhs }
    }
}
impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Point) -> Point {
        Point { x: self.x + rhs.x, y: self.y + rhs.y }
    }
}

/// Evaluate the B-spline and plot it to the image buffer passed
fn plot_2d(spline: &bspline::BSpline<Point>, plot: &mut [u8], plot_dim: (usize, usize), scale: (f32, f32),
           offset: (f32, f32), t_range: (f32, f32)) {
    let step_size = 0.001;
    let steps = ((t_range.1 - t_range.0) / step_size) as usize;
    for s in 0..steps {
        let t = step_size * s as f32 + t_range.0;
        let pt = spline.point(t);
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        if iy >= 0 && iy < plot_dim.1 as isize {
            let px = (plot_dim.1 - 1 - iy as usize) * plot_dim.0 * 3 + ix as usize * 3;
            for i in 0..3 {
                plot[px + i] = 0;
            }
        }
    }
}

/// Plot a simple 2D quadratic B-spline
fn plot_quadratic() {
    let points = vec![Point::new(-1.0, 0.0), Point::new(-1.0, 0.0), Point::new(0.0, 1.0),
                      Point::new(1.0, 0.0), Point::new(1.0, 0.0)];
    let knots = vec![0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 3.0, 3.0];
    let t_start = knots[0];
    let t_end = knots[knots.len() - 1];

    let plot_dim = (720, 540);
    let scale = (plot_dim.0 as f32 / 4.0, plot_dim.1 as f32 / 4.0);
    let offset = (2.0, 2.0);

    let mut plot: Vec<_> = iter::repeat(255u8).take(plot_dim.0 * plot_dim.1 * 3).collect();

    println!("Plotting Quadratic B-spline with:\n\tpoints = {:?}\n\tknots = {:?}",
             points, knots);
    println!("\tStarting at {}, ending at {}", t_start, t_end);
    let spline = bspline::BSpline::new(2, points.clone(), knots);

    plot_2d(&spline, &mut plot[..], plot_dim, scale, offset, (t_start, t_end));

    // Draw the control points
    for pt in points.iter() {
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        // Plot a 4x4 red marker for each control point
        for y in iy - 2..iy + 2 {
            for x in ix - 2..ix + 2 {
                if y >= 0 && y < plot_dim.1 as isize {
                    let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                    plot[px] = 255;
                    plot[px + 1] = 0;
                    plot[px + 2] = 0;
                }
            }
        }
    }
    match image::save_buffer("quadratic_2d.png", &plot[..], plot_dim.0 as u32, plot_dim.1 as u32, image::RGB(8)) {
        Ok(_) => println!("2D Quadratic B-spline saved to quadratic_2d.png"),
        Err(e) => println!("Error saving quadratic_2d.png,  {}", e),
    }
}

fn main() {
    let divider: String = iter::repeat('-').take(80).collect();
    plot_quadratic();
}

<|endoftext|>


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

use core::prelude::*;

use core::cell::Cell;
use core::cmp;
use core::os;
use core::result;
use core::run;
use core::run::ProgramOutput;
use core::vec;
use core::result::Result;
use std::getopts;

/// The type of document to output
pub enum OutputFormat {
    /// Markdown
    pub Markdown,
    /// HTML, via markdown and pandoc
    pub PandocHtml
}

impl cmp::Eq for OutputFormat {
    pure fn eq(&self, other: &OutputFormat) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &OutputFormat) -> bool { !(*self).eq(other) }
}

/// How to organize the output
pub enum OutputStyle {
    /// All in a single document
    pub DocPerCrate,
    /// Each module in its own document
    pub DocPerMod
}

impl cmp::Eq for OutputStyle {
    pure fn eq(&self, other: &OutputStyle) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &OutputStyle) -> bool { !(*self).eq(other) }
}

/// The configuration for a rustdoc session
pub struct Config {
    input_crate: Path,
    output_dir: Path,
    output_format: OutputFormat,
    output_style: OutputStyle,
    pandoc_cmd: Option<~str>
}

impl Clone for Config {
    fn clone(&self) -> Config { copy *self }
}

fn opt_output_dir() -> ~str { ~"output-dir" }
fn opt_output_format() -> ~str { ~"output-format" }
fn opt_output_style() -> ~str { ~"output-style" }
fn opt_pandoc_cmd() -> ~str { ~"pandoc-cmd" }
fn opt_help() -> ~str { ~"h" }

fn opts() -> ~[(getopts::Opt, ~str)] {
    ~[
        (getopts::optopt(opt_output_dir()),
         ~"--output-dir <val>     put documents here"),
        (getopts::optopt(opt_output_format()),
         ~"--output-format <val>  either 'markdown' or 'html'"),
        (getopts::optopt(opt_output_style()),
         ~"--output-style <val>   either 'doc-per-crate' or 'doc-per-mod'"),
        (getopts::optopt(opt_pandoc_cmd()),
         ~"--pandoc-cmd <val>     the command for running pandoc"),
        (getopts::optflag(opt_help()),
         ~"-h                     print help")
    ]
}

pub fn usage() {
    use core::io::println;

    println(~"Usage: rustdoc [options] <cratefile>\n");
    println(~"Options:\n");
    for opts().each |opt| {
        println(fmt!("    %s", opt.second()));
    }
    println(~"");
}

pub fn default_config(input_crate: &Path) -> Config {
    Config {
        input_crate: copy *input_crate,
        output_dir: Path("."),
        output_format: PandocHtml,
        output_style: DocPerMod,
        pandoc_cmd: None
    }
}

type Process = ~fn((&str), (&[~str])) -> ProgramOutput;

pub fn mock_program_output(_prog: &str, _args: &[~str]) -> ProgramOutput {
    ProgramOutput {
        status: 0,
        out: ~"",
        err: ~""
    }
}

pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput {
    run::program_output(prog, args)
}

pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
    parse_config_(args, program_output)
}

pub fn parse_config_(
    args: &[~str],
    program_output: Process
) -> Result<Config, ~str> {
    let args = args.tail();
    let opts = vec::unzip(opts()).first();
    match getopts::getopts(args, opts) {
        result::Ok(matches) => {
            if matches.free.len() == 1 {
                let input_crate = Path(vec::head(matches.free));
                config_from_opts(&input_crate, &matches, program_output)
            } else if matches.free.is_empty() {
                result::Err(~"no crates specified")
            } else {
                result::Err(~"multiple crates specified")
            }
        }
        result::Err(f) => {
            result::Err(getopts::fail_str(f))
        }
    }
}

fn config_from_opts(
    input_crate: &Path,
    matches: &getopts::Matches,
    program_output: Process
) -> Result<Config, ~str> {

    let config = default_config(input_crate);
    let result = result::Ok(config);
    let result = do result::chain(result) |config| {
        let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
        let output_dir = output_dir.map(|s| Path(*s));
        result::Ok(Config {
            output_dir: output_dir.get_or_default(copy config.output_dir),
            .. config
        })
    };
    let result = do result::chain(result) |config| {
        let output_format = getopts::opt_maybe_str(
            matches, opt_output_format());
        do output_format.map_default(result::Ok(copy config))
            |output_format| {
            do result::chain(parse_output_format(*output_format))
                |output_format| {

                result::Ok(Config {
                    output_format: output_format,
                    .. copy config
                })
            }
        }
    };
    let result = do result::chain(result) |config| {
        let output_style =
            getopts::opt_maybe_str(matches, opt_output_style());
        do output_style.map_default(result::Ok(copy config))
            |output_style| {
            do result::chain(parse_output_style(*output_style))
                |output_style| {
                result::Ok(Config {
                    output_style: output_style,
                    .. copy config
                })
            }
        }
    };
    let program_output = Cell(program_output);
    let result = do result::chain(result) |config| {
        let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
        let pandoc_cmd = maybe_find_pandoc(
            &config, pandoc_cmd, program_output.take());
        do result::chain(pandoc_cmd) |pandoc_cmd| {
            result::Ok(Config {
                pandoc_cmd: pandoc_cmd,
                .. copy config
            })
        }
    };
    return result;
}

fn parse_output_format(output_format: &str) -> Result<OutputFormat, ~str> {
    match output_format.to_str() {
      ~"markdown" => result::Ok(Markdown),
      ~"html" => result::Ok(PandocHtml),
      _ => result::Err(fmt!("unknown output format '%s'", output_format))
    }
}

fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
    match output_style.to_str() {
      ~"doc-per-crate" => result::Ok(DocPerCrate),
      ~"doc-per-mod" => result::Ok(DocPerMod),
      _ => result::Err(fmt!("unknown output style '%s'", output_style))
    }
}

fn maybe_find_pandoc(
    config: &Config,
    maybe_pandoc_cmd: Option<~str>,
    program_output: Process
) -> Result<Option<~str>, ~str> {
    if config.output_format != PandocHtml {
        return result::Ok(maybe_pandoc_cmd);
    }

    let possible_pandocs = match maybe_pandoc_cmd {
      Some(pandoc_cmd) => ~[pandoc_cmd],
      None => {
        ~[~"pandoc"] + match os::homedir() {
          Some(dir) => {
            ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()]
          }
          None => ~[]
        }
      }
    };

    let pandoc = do vec::find(possible_pandocs) |pandoc| {
        let output = program_output(*pandoc, ~[~"--version"]);
        debug!("testing pandoc cmd %s: %?", *pandoc, output);
        output.status == 0
    };

    if pandoc.is_some() {
        result::Ok(pandoc)
    } else {
        result::Err(~"couldn't find pandoc")
    }
}

#[test]
fn should_find_pandoc() {
    let config = Config {
        output_format: PandocHtml,
        .. default_config(&Path("test"))
    };
    let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |prog, _| {
        ProgramOutput { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" }
    };
    let result = maybe_find_pandoc(&config, None, mock_program_output);
    assert result == result::Ok(Some(~"pandoc"));
}

#[test]
fn should_error_with_no_pandoc() {
    let config = Config {
        output_format: PandocHtml,
        .. default_config(&Path("test"))
    };
    let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
        ProgramOutput { status: 1, out: ~"", err: ~"" }
    };
    let result = maybe_find_pandoc(&config, None, mock_program_output);
    assert result == result::Err(~"couldn't find pandoc");
}

#[cfg(test)]
mod test {
    use config::{Config, mock_program_output, parse_config_};

    use core::result::Result;

    pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
        parse_config_(args, mock_program_output)
    }
}

#[test]
fn should_error_with_no_crates() {
    let config = test::parse_config(~[~"rustdoc"]);
    assert config.get_err() == ~"no crates specified";
}

#[test]
fn should_error_with_multiple_crates() {
    let config =
        test::parse_config(~[~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
    assert config.get_err() == ~"multiple crates specified";
}

#[test]
fn should_set_output_dir_to_cwd_if_not_provided() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_dir == Path(".");
}

#[test]
fn should_set_output_dir_if_provided() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
    ]);
    assert config.get().output_dir == Path("snuggles");
}

#[test]
fn should_set_output_format_to_pandoc_html_if_not_provided() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_format == PandocHtml;
}

#[test]
fn should_set_output_format_to_markdown_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
    ]);
    assert config.get().output_format == Markdown;
}

#[test]
fn should_set_output_format_to_pandoc_html_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
    ]);
    assert config.get().output_format == PandocHtml;
}

#[test]
fn should_error_on_bogus_format() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
    ]);
    assert config.get_err() == ~"unknown output format 'bogus'";
}

#[test]
fn should_set_output_style_to_doc_per_mod_by_default() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_style == DocPerMod;
}

#[test]
fn should_set_output_style_to_one_doc_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
    ]);
    assert config.get().output_style == DocPerCrate;
}

#[test]
fn should_set_output_style_to_doc_per_mod_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
    ]);
    assert config.get().output_style == DocPerMod;
}

#[test]
fn should_error_on_bogus_output_style() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
    ]);
    assert config.get_err() == ~"unknown output style 'bogus'";
}

#[test]
fn should_set_pandoc_command_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
    ]);
    assert config.get().pandoc_cmd == Some(~"panda-bear-doc");
}

#[test]
fn should_set_pandoc_command_when_using_pandoc() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().pandoc_cmd == Some(~"pandoc");
}
<commit_msg>rustdoc: Remove a unused variable warning<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::prelude::*;

use core::cell::Cell;
use core::cmp;
use core::os;
use core::result;
use core::run;
use core::run::ProgramOutput;
use core::vec;
use core::result::Result;
use std::getopts;

/// The type of document to output
pub enum OutputFormat {
    /// Markdown
    pub Markdown,
    /// HTML, via markdown and pandoc
    pub PandocHtml
}

impl cmp::Eq for OutputFormat {
    pure fn eq(&self, other: &OutputFormat) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &OutputFormat) -> bool { !(*self).eq(other) }
}

/// How to organize the output
pub enum OutputStyle {
    /// All in a single document
    pub DocPerCrate,
    /// Each module in its own document
    pub DocPerMod
}

impl cmp::Eq for OutputStyle {
    pure fn eq(&self, other: &OutputStyle) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &OutputStyle) -> bool { !(*self).eq(other) }
}

/// The configuration for a rustdoc session
pub struct Config {
    input_crate: Path,
    output_dir: Path,
    output_format: OutputFormat,
    output_style: OutputStyle,
    pandoc_cmd: Option<~str>
}

impl Clone for Config {
    fn clone(&self) -> Config { copy *self }
}

fn opt_output_dir() -> ~str { ~"output-dir" }
fn opt_output_format() -> ~str { ~"output-format" }
fn opt_output_style() -> ~str { ~"output-style" }
fn opt_pandoc_cmd() -> ~str { ~"pandoc-cmd" }
fn opt_help() -> ~str { ~"h" }

fn opts() -> ~[(getopts::Opt, ~str)] {
    ~[
        (getopts::optopt(opt_output_dir()),
         ~"--output-dir <val>     put documents here"),
        (getopts::optopt(opt_output_format()),
         ~"--output-format <val>  either 'markdown' or 'html'"),
        (getopts::optopt(opt_output_style()),
         ~"--output-style <val>   either 'doc-per-crate' or 'doc-per-mod'"),
        (getopts::optopt(opt_pandoc_cmd()),
         ~"--pandoc-cmd <val>     the command for running pandoc"),
        (getopts::optflag(opt_help()),
         ~"-h                     print help")
    ]
}

pub fn usage() {
    use core::io::println;

    println(~"Usage: rustdoc [options] <cratefile>\n");
    println(~"Options:\n");
    for opts().each |opt| {
        println(fmt!("    %s", opt.second()));
    }
    println(~"");
}

pub fn default_config(input_crate: &Path) -> Config {
    Config {
        input_crate: copy *input_crate,
        output_dir: Path("."),
        output_format: PandocHtml,
        output_style: DocPerMod,
        pandoc_cmd: None
    }
}

type Process = ~fn((&str), (&[~str])) -> ProgramOutput;

pub fn mock_program_output(_prog: &str, _args: &[~str]) -> ProgramOutput {
    ProgramOutput {
        status: 0,
        out: ~"",
        err: ~""
    }
}

pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput {
    run::program_output(prog, args)
}

pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
    parse_config_(args, program_output)
}

pub fn parse_config_(
    args: &[~str],
    program_output: Process
) -> Result<Config, ~str> {
    let args = args.tail();
    let opts = vec::unzip(opts()).first();
    match getopts::getopts(args, opts) {
        result::Ok(matches) => {
            if matches.free.len() == 1 {
                let input_crate = Path(vec::head(matches.free));
                config_from_opts(&input_crate, &matches, program_output)
            } else if matches.free.is_empty() {
                result::Err(~"no crates specified")
            } else {
                result::Err(~"multiple crates specified")
            }
        }
        result::Err(f) => {
            result::Err(getopts::fail_str(f))
        }
    }
}

fn config_from_opts(
    input_crate: &Path,
    matches: &getopts::Matches,
    program_output: Process
) -> Result<Config, ~str> {

    let config = default_config(input_crate);
    let result = result::Ok(config);
    let result = do result::chain(result) |config| {
        let output_dir = getopts::opt_maybe_str(matches, opt_output_dir());
        let output_dir = output_dir.map(|s| Path(*s));
        result::Ok(Config {
            output_dir: output_dir.get_or_default(copy config.output_dir),
            .. config
        })
    };
    let result = do result::chain(result) |config| {
        let output_format = getopts::opt_maybe_str(
            matches, opt_output_format());
        do output_format.map_default(result::Ok(copy config))
            |output_format| {
            do result::chain(parse_output_format(*output_format))
                |output_format| {

                result::Ok(Config {
                    output_format: output_format,
                    .. copy config
                })
            }
        }
    };
    let result = do result::chain(result) |config| {
        let output_style =
            getopts::opt_maybe_str(matches, opt_output_style());
        do output_style.map_default(result::Ok(copy config))
            |output_style| {
            do result::chain(parse_output_style(*output_style))
                |output_style| {
                result::Ok(Config {
                    output_style: output_style,
                    .. copy config
                })
            }
        }
    };
    let program_output = Cell(program_output);
    let result = do result::chain(result) |config| {
        let pandoc_cmd = getopts::opt_maybe_str(matches, opt_pandoc_cmd());
        let pandoc_cmd = maybe_find_pandoc(
            &config, pandoc_cmd, program_output.take());
        do result::chain(pandoc_cmd) |pandoc_cmd| {
            result::Ok(Config {
                pandoc_cmd: pandoc_cmd,
                .. copy config
            })
        }
    };
    return result;
}

fn parse_output_format(output_format: &str) -> Result<OutputFormat, ~str> {
    match output_format.to_str() {
      ~"markdown" => result::Ok(Markdown),
      ~"html" => result::Ok(PandocHtml),
      _ => result::Err(fmt!("unknown output format '%s'", output_format))
    }
}

fn parse_output_style(output_style: &str) -> Result<OutputStyle, ~str> {
    match output_style.to_str() {
      ~"doc-per-crate" => result::Ok(DocPerCrate),
      ~"doc-per-mod" => result::Ok(DocPerMod),
      _ => result::Err(fmt!("unknown output style '%s'", output_style))
    }
}

fn maybe_find_pandoc(
    config: &Config,
    maybe_pandoc_cmd: Option<~str>,
    program_output: Process
) -> Result<Option<~str>, ~str> {
    if config.output_format != PandocHtml {
        return result::Ok(maybe_pandoc_cmd);
    }

    let possible_pandocs = match maybe_pandoc_cmd {
      Some(pandoc_cmd) => ~[pandoc_cmd],
      None => {
        ~[~"pandoc"] + match os::homedir() {
          Some(dir) => {
            ~[dir.push_rel(&Path(".cabal/bin/pandoc")).to_str()]
          }
          None => ~[]
        }
      }
    };

    let pandoc = do vec::find(possible_pandocs) |pandoc| {
        let output = program_output(*pandoc, ~[~"--version"]);
        debug!("testing pandoc cmd %s: %?", *pandoc, output);
        output.status == 0
    };

    if pandoc.is_some() {
        result::Ok(pandoc)
    } else {
        result::Err(~"couldn't find pandoc")
    }
}

#[test]
fn should_find_pandoc() {
    let config = Config {
        output_format: PandocHtml,
        .. default_config(&Path("test"))
    };
    let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
        ProgramOutput { status: 0, out: ~"pandoc 1.8.2.1", err: ~"" }
    };
    let result = maybe_find_pandoc(&config, None, mock_program_output);
    assert result == result::Ok(Some(~"pandoc"));
}

#[test]
fn should_error_with_no_pandoc() {
    let config = Config {
        output_format: PandocHtml,
        .. default_config(&Path("test"))
    };
    let mock_program_output: ~fn(&str, &[~str]) -> ProgramOutput = |_, _| {
        ProgramOutput { status: 1, out: ~"", err: ~"" }
    };
    let result = maybe_find_pandoc(&config, None, mock_program_output);
    assert result == result::Err(~"couldn't find pandoc");
}

#[cfg(test)]
mod test {
    use config::{Config, mock_program_output, parse_config_};

    use core::result::Result;

    pub fn parse_config(args: &[~str]) -> Result<Config, ~str> {
        parse_config_(args, mock_program_output)
    }
}

#[test]
fn should_error_with_no_crates() {
    let config = test::parse_config(~[~"rustdoc"]);
    assert config.get_err() == ~"no crates specified";
}

#[test]
fn should_error_with_multiple_crates() {
    let config =
        test::parse_config(~[~"rustdoc", ~"crate1.rc", ~"crate2.rc"]);
    assert config.get_err() == ~"multiple crates specified";
}

#[test]
fn should_set_output_dir_to_cwd_if_not_provided() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_dir == Path(".");
}

#[test]
fn should_set_output_dir_if_provided() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-dir", ~"snuggles"
    ]);
    assert config.get().output_dir == Path("snuggles");
}

#[test]
fn should_set_output_format_to_pandoc_html_if_not_provided() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_format == PandocHtml;
}

#[test]
fn should_set_output_format_to_markdown_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"markdown"
    ]);
    assert config.get().output_format == Markdown;
}

#[test]
fn should_set_output_format_to_pandoc_html_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"html"
    ]);
    assert config.get().output_format == PandocHtml;
}

#[test]
fn should_error_on_bogus_format() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-format", ~"bogus"
    ]);
    assert config.get_err() == ~"unknown output format 'bogus'";
}

#[test]
fn should_set_output_style_to_doc_per_mod_by_default() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().output_style == DocPerMod;
}

#[test]
fn should_set_output_style_to_one_doc_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-crate"
    ]);
    assert config.get().output_style == DocPerCrate;
}

#[test]
fn should_set_output_style_to_doc_per_mod_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"doc-per-mod"
    ]);
    assert config.get().output_style == DocPerMod;
}

#[test]
fn should_error_on_bogus_output_style() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--output-style", ~"bogus"
    ]);
    assert config.get_err() == ~"unknown output style 'bogus'";
}

#[test]
fn should_set_pandoc_command_if_requested() {
    let config = test::parse_config(~[
        ~"rustdoc", ~"crate.rc", ~"--pandoc-cmd", ~"panda-bear-doc"
    ]);
    assert config.get().pandoc_cmd == Some(~"panda-bear-doc");
}

#[test]
fn should_set_pandoc_command_when_using_pandoc() {
    let config = test::parse_config(~[~"rustdoc", ~"crate.rc"]);
    assert config.get().pandoc_cmd == Some(~"pandoc");
}
<|endoftext|>


<commit_before><commit_msg>deal with struct epoll_event stuff<commit_after><|endoftext|>


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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0161,
    E0170,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0306, // expected positive integer for repeat count
    E0307, // expected constant integer for repeat count
    E0308,
    E0309, // thing may not live long enough
    E0310, // thing may not live long enough
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

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

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this one
is too specific or the ordering is incorrect.
"##,

E0002: r##"
This error indicates that an empty match expression is illegal because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired.  This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`.
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. To match against NaN values, you should
instead use the `is_nan` method in a guard, as in: x if x.is_nan() => ...
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution.

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else".
"##,

// FIXME: Remove duplication here?
E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0006: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee that a
name will be extracted in all cases. If you encounter this error you probably need
to use a `match` or `if let` to deal with the possibility of failure.
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code like
the following is invalid as it requires the entire Option<String> to be moved
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.

let x = Some("s".to_string());
match x {
    op_string @ Some(s) => ...
    None => ...
}

See also Error 303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => // use s.
    ...
}

The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
of the arm, so the value would be moved into this anonymous scope and therefore
become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => // use s.
    ...
}

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0152: r##"
Lang items are already implemented in the standard library. Unless you are
writing a free-standing application (e.g. a kernel), you do not need to provide
them yourself.

You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:

#![feature(no_std)]
#![no_std]

See also https://doc.rust-lang.org/book/no-stdlib.html
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

static FORTY_TWO: i32 = 42;
match Some(42) {
    Some(x) if x == FORTY_TWO => ...
    ...
}
"##,

E0161: r##"
In Rust, you can only move a value when its size is known at compile time.

To work around this restriction, consider "hiding" the value behind a reference:
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
it around as usual.
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}

// Try this instead:
let Irrefutable(x) = irr;
foo(x);
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:

struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

// Try this instead:
loop {
    let Irrefutable(x) = irr;
    ...
}
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

// This fails because `None` is not covered.
for Some(x) in xs {
    ...
}

// Match inside the loop instead:
for item in xs {
    match item {
        Some(x) => ...
        None => ...
    }
}

// Or use `if let`:
for item in xs {
    if let Some(x) = item {
        ...
    }
}
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

match Some(()) {
    None => { },
    option if option.take().is_none() => { /* impossible, option is `Some` */ },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

// Code like this...
match Some(5) {
    ref op_num @ Some(num) => ...
    None => ...
}

// ... should be updated to code like this.
match Some(5) {
    Some(num) => {
        let op_num = &Some(num);
        ...
    }
    None => ...
}

See also https://github.com/rust-lang/rust/issues/14587
"##

}

register_diagnostics! {
    E0009,
    E0010,
    E0011,
    E0012,
    E0013,
    E0014,
    E0015,
    E0016,
    E0017,
    E0018,
    E0019,
    E0020,
    E0022,
    E0079, // enum variant: expected signed integer constant
    E0080, // enum variant: constant evaluation error
    E0109,
    E0110,
    E0133,
    E0134,
    E0135,
    E0136,
    E0137,
    E0138,
    E0139,
    E0170,
    E0261, // use of undeclared lifetime name
    E0262, // illegal lifetime parameter name
    E0263, // lifetime name declared twice in same scope
    E0264, // unknown external lang item
    E0265, // recursive constant
    E0266, // expected item
    E0267, // thing inside of a closure
    E0268, // thing outside of a loop
    E0269, // not all control paths return a value
    E0270, // computation may converge in a function marked as diverging
    E0271, // type mismatch resolving
    E0272, // rustc_on_unimplemented attribute refers to non-existent type parameter
    E0273, // rustc_on_unimplemented must have named format arguments
    E0274, // rustc_on_unimplemented must have a value
    E0275, // overflow evaluating requirement
    E0276, // requirement appears on impl method but not on corresponding trait method
    E0277, // trait is not implemented for type
    E0278, // requirement is not satisfied
    E0279, // requirement is not satisfied
    E0280, // requirement is not satisfied
    E0281, // type implements trait but other trait is required
    E0282, // unable to infer enough type information about
    E0283, // cannot resolve type
    E0284, // cannot resolve type
    E0285, // overflow evaluation builtin bounds
    E0296, // malformed recursion limit attribute
    E0298, // mismatched types between arms
    E0299, // mismatched types between arms
    E0300, // unexpanded macro
    E0304, // expected signed integer constant
    E0305, // expected constant
    E0306, // expected positive integer for repeat count
    E0307, // expected constant integer for repeat count
    E0308,
    E0309, // thing may not live long enough
    E0310, // thing may not live long enough
    E0311, // thing may not live long enough
    E0312, // lifetime of reference outlives lifetime of borrowed content
    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
    E0314, // closure outlives stack frame
    E0315, // cannot invoke closure outside of its lifetime
    E0316, // nested quantification of lifetimes
    E0370  // discriminant overflow
}

__build_diagnostic_array! { DIAGNOSTICS }
<|endoftext|>


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

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::path::Path;
use std::time::Duration;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<usize> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut u = Some(u);
    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u.take().unwrap()))
        })
    };
    let rv = rv.unwrap();

    println!("{}time: {} \t{}", repeat("  ").take(old).collect::<String>(),
             dur, what);
    DEPTH.with(|slot| slot.set(old));

    rv
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Examples
/// ```
/// struct Context {
///    cache: RefCell<HashMap<usize, usize>>
/// }
///
/// fn factorial(ctxt: &Context, n: usize) -> usize {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).cloned();
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}
<commit_msg>Don't use <Duration as Display>::display() in time passes<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_camel_case_types)]

use std::cell::{RefCell, Cell};
use std::collections::HashMap;
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
use std::path::Path;
use std::time::Duration;

use syntax::ast;
use syntax::visit;
use syntax::visit::Visitor;

// The name of the associated type for `Fn` return types
pub const FN_OUTPUT_NAME: &'static str = "Output";

// Useful type to use with `Result<>` indicate that an error has already
// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
    F: FnOnce(U) -> T,
{
    thread_local!(static DEPTH: Cell<usize> = Cell::new(0));
    if !do_it { return f(u); }

    let old = DEPTH.with(|slot| {
        let r = slot.get();
        slot.set(r + 1);
        r
    });

    let mut rv = None;
    let dur = {
        let ref mut rvp = rv;

        Duration::span(move || {
            *rvp = Some(f(u))
        })
    };
    let rv = rv.unwrap();

    // Hack up our own formatting for the duration to make it easier for scripts
    // to parse (always use the same number of decimal places and the same unit).
    const NANOS_PER_SEC: f64 = 1_000_000_000.0;
    let secs = dur.secs() as f64;
    let secs = secs + dur.extra_nanos() as f64 / NANOS_PER_SEC;
    println!("{}time: {:.3} \t{}", repeat("  ").take(old).collect::<String>(),
             secs, what);

    DEPTH.with(|slot| slot.set(old));

    rv
}

pub fn indent<R, F>(op: F) -> R where
    R: Debug,
    F: FnOnce() -> R,
{
    // Use in conjunction with the log post-processor like `src/etc/indenter`
    // to make debug output more readable.
    debug!(">>");
    let r = op();
    debug!("<< (Result = {:?})", r);
    r
}

pub struct Indenter {
    _cannot_construct_outside_of_this_module: ()
}

impl Drop for Indenter {
    fn drop(&mut self) { debug!("<<"); }
}

pub fn indenter() -> Indenter {
    debug!(">>");
    Indenter { _cannot_construct_outside_of_this_module: () }
}

struct LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for LoopQueryVisitor<P> where P: FnMut(&ast::Expr_) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(&e.node);
        match e.node {
          // Skip inner loops, since a break in the inner loop isn't a
          // break inside the outer loop
          ast::ExprLoop(..) | ast::ExprWhile(..) => {}
          _ => visit::walk_expr(self, e)
        }
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn loop_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr_) -> bool {
    let mut v = LoopQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, b);
    return v.flag;
}

struct BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    p: P,
    flag: bool,
}

impl<'v, P> Visitor<'v> for BlockQueryVisitor<P> where P: FnMut(&ast::Expr) -> bool {
    fn visit_expr(&mut self, e: &ast::Expr) {
        self.flag |= (self.p)(e);
        visit::walk_expr(self, e)
    }
}

// Takes a predicate p, returns true iff p is true for any subexpressions
// of b -- skipping any inner loops (loop, while, loop_body)
pub fn block_query<P>(b: &ast::Block, p: P) -> bool where P: FnMut(&ast::Expr) -> bool {
    let mut v = BlockQueryVisitor {
        p: p,
        flag: false,
    };
    visit::walk_block(&mut v, &*b);
    return v.flag;
}

/// K: Eq + Hash<S>, V, S, H: Hasher<S>
///
/// Determines whether there exists a path from `source` to `destination`.  The
/// graph is defined by the `edges_map`, which maps from a node `S` to a list of
/// its adjacent nodes `T`.
///
/// Efficiency note: This is implemented in an inefficient way because it is
/// typically invoked on very small graphs. If the graphs become larger, a more
/// efficient graph representation and algorithm would probably be advised.
pub fn can_reach<T, S>(edges_map: &HashMap<T, Vec<T>, S>, source: T,
                       destination: T) -> bool
    where S: HashState, T: Hash + Eq + Clone,
{
    if source == destination {
        return true;
    }

    // Do a little breadth-first-search here.  The `queue` list
    // doubles as a way to detect if we've seen a particular FR
    // before.  Note that we expect this graph to be an *extremely
    // shallow* tree.
    let mut queue = vec!(source);
    let mut i = 0;
    while i < queue.len() {
        match edges_map.get(&queue[i]) {
            Some(edges) => {
                for target in edges {
                    if *target == destination {
                        return true;
                    }

                    if !queue.iter().any(|x| x == target) {
                        queue.push((*target).clone());
                    }
                }
            }
            None => {}
        }
        i += 1;
    }
    return false;
}

/// Memoizes a one-argument closure using the given RefCell containing
/// a type implementing MutableMap to serve as a cache.
///
/// In the future the signature of this function is expected to be:
/// ```
/// pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
///    cache: &RefCell<M>,
///    f: &|T| -> U
/// ) -> impl |T| -> U {
/// ```
/// but currently it is not possible.
///
/// # Examples
/// ```
/// struct Context {
///    cache: RefCell<HashMap<usize, usize>>
/// }
///
/// fn factorial(ctxt: &Context, n: usize) -> usize {
///     memoized(&ctxt.cache, n, |n| match n {
///         0 | 1 => n,
///         _ => factorial(ctxt, n - 2) + factorial(ctxt, n - 1)
///     })
/// }
/// ```
#[inline(always)]
pub fn memoized<T, U, S, F>(cache: &RefCell<HashMap<T, U, S>>, arg: T, f: F) -> U
    where T: Clone + Hash + Eq,
          U: Clone,
          S: HashState,
          F: FnOnce(T) -> U,
{
    let key = arg.clone();
    let result = cache.borrow().get(&key).cloned();
    match result {
        Some(result) => result,
        None => {
            let result = f(arg);
            cache.borrow_mut().insert(key, result.clone());
            result
        }
    }
}

#[cfg(unix)]
pub fn path2cstr(p: &Path) -> CString {
    use std::os::unix::prelude::*;
    use std::ffi::OsStr;
    let p: &OsStr = p.as_ref();
    CString::new(p.as_bytes()).unwrap()
}
#[cfg(windows)]
pub fn path2cstr(p: &Path) -> CString {
    CString::new(p.to_str().unwrap()).unwrap()
}
<|endoftext|>