<commit_before>// Copyright 2016 Kyle Mayes
//
// 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.

//! Provides helper functionality.

use std::env;
use std::process::{Command};
use std::path::{Path, PathBuf};

use glob;

use libc::{c_int};

use super::{CXVersion};

//================================================
// Structs
//================================================

// try_opt! ______________________________________

macro_rules! try_opt {
    ($option:expr) => ({
        match $option {
            Some(some) => some,
            None => return None,
        }
    });
}

//================================================
// Structs
//================================================

/// A `clang` executable.
#[derive(Clone, Debug)]
pub struct Clang {
    /// The path to this `clang` executable.
    pub path: PathBuf,
    /// The version of this `clang` executable if it could be parsed.
    pub version: Option<CXVersion>,
    /// The directories searched by this `clang` executable for C headers.
    pub c_search_paths: Vec<PathBuf>,
    /// The directories searched by this `clang` executable for C++ headers.
    pub cpp_search_paths: Vec<PathBuf>,
}

impl Clang {
    //- Constructors -----------------------------

    fn new(path: PathBuf) -> Clang {
        let version = parse_version(&path);
        let c_search_paths = parse_search_paths(&path, "c");
        let cpp_search_paths = parse_search_paths(&path, "c++");
        Clang {
            path: path,
            version: version,
            c_search_paths: c_search_paths,
            cpp_search_paths: cpp_search_paths,
        }
    }

    /// Returns a `clang` executable if one can be found.
    ///
    /// If a path is supplied, that is the first directory searched. Otherwise, the directories in
    /// the system's `PATH` are searched.
    pub fn find(path: Option<&Path>) -> Option<Clang> {
        let default = format!("clang{}", env::consts::EXE_SUFFIX);
        let versioned = format!("clang-[0-9]*{}", env::consts::EXE_SUFFIX);
        let patterns = &[&default[..], &versioned[..]];
        if let Some(path) = path.and_then(|p| find(p, patterns)) {
            return Some(Clang::new(path));
        }
        for path in env::split_paths(&env::var("PATH").unwrap()) {
            if let Some(path) = find(&path, patterns) {
                return Some(Clang::new(path));
            }
        }
        None
    }
}

//================================================
// Functions
//================================================

/// Returns the first match to the supplied glob patterns in the supplied directory if there are any
/// matches.
fn find(directory: &Path, patterns: &[&str]) -> Option<PathBuf> {
    for pattern in patterns {
        let pattern = directory.join(pattern).to_string_lossy().into_owned();
        if let Some(path) = try_opt!(glob::glob(&pattern).ok()).filter_map(|p| p.ok()).next() {
            return Some(path);
        }
    }
    None
}

/// Runs a `clang` executable, returning the output.
fn run_clang(path: &Path, arguments: &[&str], stdout: bool) -> String {
    Command::new(path.to_string_lossy().into_owned()).args(arguments).output().map(|o| {
        let output = if stdout {
            &o.stdout
        } else {
            &o.stderr
        };
        String::from_utf8_lossy(output).into_owned()
    }).unwrap()
}

/// Parses a version number if possible, ignoring trailing non-digit characters.
fn parse_version_number(number: &str) -> Option<c_int> {
    number.chars().take_while(|c| c.is_digit(10)).collect::<String>().parse().ok()
}

/// Parses the version from the output of a `clang` executable if possible.
fn parse_version(path: &Path) -> Option<CXVersion> {
    let output = run_clang(path, &["--version"], true);
    let start = try_opt!(output.find("version ")) + 8;
    let mut numbers = try_opt!(output[start..].split_whitespace().nth(0)).split('.');
    let major = try_opt!(numbers.next().and_then(parse_version_number));
    let minor = try_opt!(numbers.next().and_then(parse_version_number));
    let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0);
    Some(CXVersion { Major: major, Minor: minor, Subminor: subminor })
}

/// Parses the search paths from the output of a `clang` executable.
fn parse_search_paths(path: &Path, language: &str) -> Vec<PathBuf> {
    let output = run_clang(path, &["-E", "-x", language, "-", "-v"], false);
    let include_start = "#include <...> search starts here:";
    let start = output.find(include_start).expect(include_start)
              + include_start.len();
    let end = output.find("End of search list.").expect("End of search list");
    output[start..end].split_whitespace().map(|l| Path::new(l.trim()).into()).collect()
}
<commit_msg>Reformat<commit_after>// Copyright 2016 Kyle Mayes
//
// 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.

//! Provides helper functionality.

use std::env;
use std::process::{Command};
use std::path::{Path, PathBuf};

use glob;

use libc::{c_int};

use super::{CXVersion};

//================================================
// Structs
//================================================

// try_opt! ______________________________________

macro_rules! try_opt {
    ($option:expr) => ({
        match $option {
            Some(some) => some,
            None => return None,
        }
    });
}

//================================================
// Structs
//================================================

/// A `clang` executable.
#[derive(Clone, Debug)]
pub struct Clang {
    /// The path to this `clang` executable.
    pub path: PathBuf,
    /// The version of this `clang` executable if it could be parsed.
    pub version: Option<CXVersion>,
    /// The directories searched by this `clang` executable for C headers.
    pub c_search_paths: Vec<PathBuf>,
    /// The directories searched by this `clang` executable for C++ headers.
    pub cpp_search_paths: Vec<PathBuf>,
}

impl Clang {
    //- Constructors -----------------------------

    fn new(path: PathBuf) -> Clang {
        let version = parse_version(&path);
        let c_search_paths = parse_search_paths(&path, "c");
        let cpp_search_paths = parse_search_paths(&path, "c++");
        Clang {
            path: path,
            version: version,
            c_search_paths: c_search_paths,
            cpp_search_paths: cpp_search_paths,
        }
    }

    /// Returns a `clang` executable if one can be found.
    ///
    /// If a path is supplied, that is the first directory searched. Otherwise, the directories in
    /// the system's `PATH` are searched.
    pub fn find(path: Option<&Path>) -> Option<Clang> {
        let default = format!("clang{}", env::consts::EXE_SUFFIX);
        let versioned = format!("clang-[0-9]*{}", env::consts::EXE_SUFFIX);
        let patterns = &[&default[..], &versioned[..]];
        if let Some(path) = path.and_then(|p| find(p, patterns)) {
            return Some(Clang::new(path));
        }
        for path in env::split_paths(&env::var("PATH").unwrap()) {
            if let Some(path) = find(&path, patterns) {
                return Some(Clang::new(path));
            }
        }
        None
    }
}

//================================================
// Functions
//================================================

/// Returns the first match to the supplied glob patterns in the supplied directory if there are any
/// matches.
fn find(directory: &Path, patterns: &[&str]) -> Option<PathBuf> {
    for pattern in patterns {
        let pattern = directory.join(pattern).to_string_lossy().into_owned();
        if let Some(path) = try_opt!(glob::glob(&pattern).ok()).filter_map(|p| p.ok()).next() {
            return Some(path);
        }
    }
    None
}

/// Runs a `clang` executable, returning the output.
fn run_clang(path: &Path, arguments: &[&str], stdout: bool) -> String {
    Command::new(path.to_string_lossy().into_owned()).args(arguments).output().map(|o| {
        let output = if stdout {
            &o.stdout
        } else {
            &o.stderr
        };
        String::from_utf8_lossy(output).into_owned()
    }).unwrap()
}

/// Parses a version number if possible, ignoring trailing non-digit characters.
fn parse_version_number(number: &str) -> Option<c_int> {
    number.chars().take_while(|c| c.is_digit(10)).collect::<String>().parse().ok()
}

/// Parses the version from the output of a `clang` executable if possible.
fn parse_version(path: &Path) -> Option<CXVersion> {
    let output = run_clang(path, &["--version"], true);
    let start = try_opt!(output.find("version ")) + 8;
    let mut numbers = try_opt!(output[start..].split_whitespace().nth(0)).split('.');
    let major = try_opt!(numbers.next().and_then(parse_version_number));
    let minor = try_opt!(numbers.next().and_then(parse_version_number));
    let subminor = numbers.next().and_then(parse_version_number).unwrap_or(0);
    Some(CXVersion { Major: major, Minor: minor, Subminor: subminor })
}

/// Parses the search paths from the output of a `clang` executable.
fn parse_search_paths(path: &Path, language: &str) -> Vec<PathBuf> {
    let output = run_clang(path, &["-E", "-x", language, "-", "-v"], false);
    let include_start = "#include <...> search starts here:";
    let start = output.find(include_start).expect(include_start) + include_start.len();
    let end = output.find("End of search list.").expect("End of search list");
    output[start..end].split_whitespace().map(|l| Path::new(l.trim()).into()).collect()
}
<|endoftext|>


<commit_before>//!
//! Interpreter Compiler for Expressions
//!

use std::boxed::Box;
use std::ops;

use common::constant::VECTOR_SIZE;
use common::err::{Error, TResult, Void, void_ok};
use eval::{Eval, MapEval};
use eval::primitives::*;
use expr::{Datum, Expr, Visitor};
use rows::RowBlock;
use rows::vector::Vector;
use schema::{Column, Schema};
use types::{DataTy, HasDataTy, HasTy, result_data_ty, Ty};

// Unary Expressions
pub struct Not {child: Box<Eval>}
pub struct IsNull {child: Box<Eval>}

// Binary Comparison Expressions
pub struct And {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Or {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Equal {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct NotEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}

// Binary Arithmetic Evalessions
pub struct Plus {data_ty: DataTy, pub lhs: Box<MapEval>, pub rhs: Box<MapEval>}
pub struct Minus {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Multiply {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Divide {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Modular {lhs: Box<Eval>, rhs: Box<Eval>}

// String operators or pattern matching predicates
pub struct Concatenate {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Like {pattern: String, child: Box<Eval>}
pub struct SimilarTo {pattern: String, child: Box<Eval>}
pub struct RegexMatch {pattern: String, child: Box<Eval>}

pub struct Between {pred: Box<Eval>, begin: Box<Eval>, end: Box<Eval>}
pub struct In {pred: Box<Eval>, row: Box<Row>}

pub struct Row {values: Vec<Box<Eval>>}
pub struct Field {column: Column, field_id: usize}
pub struct Const {datum: Datum, res_type: DataTy}

impl Eval for Plus {
  fn bind(&mut self, schema: &Schema) -> Void {
    self.data_ty = result_data_ty(self.lhs.data_ty(), self.rhs.data_ty());
    void_ok()
  }

  fn is_const(&self) -> bool { false }
}

impl MapEval for Plus {
  fn eval<'r>(&'r self, r: &'r RowBlock) -> &'r Vector {
    let l: &Vector = self.lhs.eval(r);
    let r: &Vector = self.rhs.eval(r);

    let f: Option<fn(&mut Vector, &Vector, &Vector, Option<&[usize]>)> = Some(if true {
      map_plus_vv::<i32>
    } else {
      map_plus_vv::<i64>
    });

    l
  }
}

impl HasDataTy for Plus {
  #[inline]
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}

impl Field {
  pub fn new(column: &Column) -> Field {
    Field {
      column: column.clone(),
      field_id: 0
    }
  }
}

impl HasDataTy for Field {
  fn data_ty(&self) -> &DataTy {
    &self.column.data_ty
  }
}

impl Eval for Field {

  fn bind(&mut self, schema: &Schema) -> Void {

    match schema.column_id(&self.column.name) {

     Some(id) => {
      self.field_id = id;
      void_ok()
     },

     None => Err(Error::UndefinedColumn)
    }
  }

  fn is_const(&self) -> bool { false }
}

impl MapEval for Field {
  fn eval<'r>(&'r self, r: &'r RowBlock) -> &'r Vector {
    r.vector(self.field_id)
  }
}

impl Const {
  fn new(datum: &Datum) -> Const {
    Const {
        datum: datum.clone(),
        res_type: DataTy::new(datum.ty())
    }
  }
}

impl HasDataTy for Const {
  fn data_ty(&self) -> &DataTy {
    &self.res_type
  }
}

impl Eval for Const {

  fn bind(&mut self, schema: &Schema) -> Void {
    self.res_type = DataTy::new(self.datum.ty());
    void_ok()
  }

  fn is_const(&self) -> bool { true }
}

pub struct InterpreterCompiler {
  tree: Option<Box<Eval>>,
  err: Option<Error>,
  node_num: u32
}

impl<'v> Visitor<'v> for InterpreterCompiler {
  fn visit_field(&mut self, c: &'v Column) {
    println!("column: {}", c.name);
  }
}<commit_msg>Add ArithmMapEval.<commit_after>//!
//! Interpreter Compiler for Expressions
//!

use std::boxed::Box;
use std::ops;

use common::constant::VECTOR_SIZE;
use common::err::{Error, TResult, Void, void_ok};
use eval::{Eval, MapEval};
use eval::primitives::*;
use expr::{ArithmOp, Datum, Expr, Visitor};
use rows::RowBlock;
use rows::vector::Vector;
use schema::{Column, Schema};
use types::{DataTy, HasDataTy, HasTy, result_data_ty, Ty};

// Unary Expressions
pub struct Not {child: Box<Eval>}
pub struct IsNull {child: Box<Eval>}

// Binary Comparison Expressions
pub struct And {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Or {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Equal {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct NotEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct LessThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThan {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct GreaterThanOrEqual {lhs: Box<Eval>, rhs: Box<Eval>}

// Binary Arithmetic Evalessions
pub struct ArithmMapEval {
  pub op: ArithmOp,
  pub data_ty: Option<DataTy>,
  pub lhs: Box<MapEval>,
  pub rhs: Box<MapEval>,
  f: Option<fn(&mut Vector, &Vector, &Vector, Option<&[usize]>)>
}

pub struct Plus {data_ty: DataTy, pub lhs: Box<MapEval>, pub rhs: Box<MapEval>}
pub struct Minus {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Multiply {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Divide {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Modular {lhs: Box<Eval>, rhs: Box<Eval>}

// String operators or pattern matching predicates
pub struct Concatenate {lhs: Box<Eval>, rhs: Box<Eval>}
pub struct Like {pattern: String, child: Box<Eval>}
pub struct SimilarTo {pattern: String, child: Box<Eval>}
pub struct RegexMatch {pattern: String, child: Box<Eval>}

pub struct Between {pred: Box<Eval>, begin: Box<Eval>, end: Box<Eval>}
pub struct In {pred: Box<Eval>, row: Box<Row>}

pub struct Row {values: Vec<Box<Eval>>}
pub struct Field {column: Column, field_id: usize}
pub struct Const {datum: Datum, res_type: DataTy}

fn get_arithm_primitive(op: ArithmOp, res_ty: &DataTy,
                        lty: &DataTy, rty: &DataTy)
                        -> fn(&mut Vector, &Vector, &Vector, Option<&[usize]>) {

  let f: Option<fn(&mut Vector, &Vector, &Vector, Option<&[usize]>)> = Some(if true {
      map_plus_vv::<i32>
    } else {
      map_plus_vv::<i64>
    });

  map_plus_vv::<i32>
}

impl Eval for ArithmMapEval {

  fn bind(&mut self, schema: &Schema) -> Void {
    self.data_ty = Some(result_data_ty(self.lhs.data_ty(), self.rhs.data_ty()));
    void_ok()
  }

  fn is_const(&self) -> bool { false }
}

impl HasDataTy for ArithmMapEval {
  fn data_ty(&self) -> &DataTy {
    self.data_ty.as_ref().unwrap()
  }
}

impl MapEval for ArithmMapEval {
  fn eval<'r>(&'r self, r: &'r RowBlock) -> &'r Vector {
    let l: &Vector = self.lhs.eval(r);
    let r: &Vector = self.rhs.eval(r);

    l
  }
}

impl HasDataTy for Plus {
  #[inline]
  fn data_ty(&self) -> &DataTy {
    &self.data_ty
  }
}

impl Field {
  pub fn new(column: &Column) -> Field {
    Field {
      column: column.clone(),
      field_id: 0
    }
  }
}

impl HasDataTy for Field {
  fn data_ty(&self) -> &DataTy {
    &self.column.data_ty
  }
}

impl Eval for Field {

  fn bind(&mut self, schema: &Schema) -> Void {

    match schema.column_id(&self.column.name) {

     Some(id) => {
      self.field_id = id;
      void_ok()
     },

     None => Err(Error::UndefinedColumn)
    }
  }

  fn is_const(&self) -> bool { false }
}

impl MapEval for Field {
  fn eval<'r>(&'r self, r: &'r RowBlock) -> &'r Vector {
    r.vector(self.field_id)
  }
}

impl Const {
  fn new(datum: &Datum) -> Const {
    Const {
        datum: datum.clone(),
        res_type: DataTy::new(datum.ty())
    }
  }
}

impl HasDataTy for Const {
  fn data_ty(&self) -> &DataTy {
    &self.res_type
  }
}

impl Eval for Const {

  fn bind(&mut self, schema: &Schema) -> Void {
    self.res_type = DataTy::new(self.datum.ty());
    void_ok()
  }

  fn is_const(&self) -> bool { true }
}

pub struct InterpreterCompiler {
  tree: Option<Box<Eval>>,
  err: Option<Error>,
  node_num: u32
}

impl<'v> Visitor<'v> for InterpreterCompiler {
  fn visit_field(&mut self, c: &'v Column) {
    println!("column: {}", c.name);
  }
}<|endoftext|>


<commit_before>//! Tape is a representation of the Turing machine infinite tape.
//!
//! You can read from it, write to it and move it left and right.

/// The contract a concrete Tape should adhere to.
pub trait Tape<S: Clone> {
    /// Reads the symbol at the location of the head of the Turing machine
    fn read(&self) -> S;

    /// Writes symbol at the location of the head of the Turing machine
    fn write(&self, symbol: S) -> Self;

    /// The blank symbol for this tape
    fn blank(&self) -> S;

    /// Move the head of the Turing machine to the left on this tape
    fn left(&self) -> Self;

    /// Move the head of the Turing machine to the right on this tape
    fn right(&self) -> Self;
}

/// An type implementing the `Tape` trait.
#[derive(Clone)]
pub struct ConcreteTape<S: Clone> {
    blank: S,
    left: HalfTape<S>,
    current: S,
    right: HalfTape<S>,
}

#[derive(Clone)]
enum HalfTape<S: Clone> {
    Cell(S, Box<HalfTape<S>>),
    Empty,
}

impl<S: Clone> HalfTape<S> {
    fn empty() -> HalfTape<S> {
        HalfTape::Empty
    }

    fn pop(&self) -> (Option<S>, HalfTape<S>) {
        match *self {
            HalfTape::Cell(ref symbol, ref boxed_tail) => {
                (Some(symbol.clone()), *boxed_tail.clone())
            },
            HalfTape::Empty => (None, HalfTape::Empty)
        }
    }

    fn push(self, symbol: S) -> HalfTape<S> {
        HalfTape::Cell(symbol, Box::new(self))
    }
}

impl<S:Clone> ConcreteTape<S> {
    /// Create an empty `ConcreteTape`. The argument will be used to as the
    /// blank symbol for this tape. This is necessary when the read/write head
    /// moves into unexplored territory. If there is nothing on the tape yet, it
    /// will provide the blank symbol.
    pub fn empty(blank: S) -> ConcreteTape<S> {
        ConcreteTape {
            blank: blank.clone(),
            left: HalfTape::empty(),
            current: blank.clone(),
            right: HalfTape::empty()
        }
    }
}

impl<S: Clone> Tape<S> for ConcreteTape<S> {
    fn read(&self) -> S {
        self.current.clone()
    }

    fn write(&self, symbol: S) -> ConcreteTape<S> {
        ConcreteTape {
            current: symbol, .. self.clone()
        }
    }

    fn blank(&self) -> S {
        self.blank.clone()
    }

    fn left(&self) -> ConcreteTape<S> {
        let (option, left_tail) = self.left.pop();
        match option {
            Some(symbol) => ConcreteTape {
                left: left_tail,
                current: symbol,
                right: self.right.clone().push(self.current.clone()),
                .. self.clone()
            },
            None => ConcreteTape {
                left: left_tail,
                current: self.blank(),
                right: self.right.clone().push(self.current.clone()),
                .. self.clone()
            }
        }
    }

    fn right(&self) -> ConcreteTape<S> {
        let (option, right_tail) = self.right.pop();
        match option {
            Some(symbol) => ConcreteTape {
                left: self.right.clone().push(self.current.clone()),
                current: symbol,
                right: right_tail,
                .. self.clone()
            },
            None => ConcreteTape {
                left: self.left.clone().push(self.current.clone()),
                current: self.blank(),
                right: right_tail,
                .. self.clone()
            }
        }
    }
}

/// Builder for `ConcreteTape`.
pub struct TapeBuilder<S: Clone> {
    tape : ConcreteTape<S>,
}

impl<S: Clone> TapeBuilder<S> {
    /// Set the blank symbol for this tape.
    pub fn with_blank(blank: S) -> TapeBuilder<S> {
        TapeBuilder { tape: ConcreteTape::empty(blank) }
    }

    /// Set the symbol the read/write head is currently scanning
    pub fn with_current(&self, symbol: S) -> TapeBuilder<S> {
        TapeBuilder { tape: self.tape.write(symbol) }
    }

    /// Sets the tape to the right of the read/write head.
    pub fn with_right_tape(&self, mut symbols: Vec<S>) -> TapeBuilder<S> {
        symbols.reverse();

        let mut half_tape: HalfTape<S> = HalfTape::empty();
        for symbol in symbols {
            half_tape = half_tape.push(symbol)
        }

        TapeBuilder {
            tape: ConcreteTape {
                right: half_tape,
                .. self.tape.clone()
            }
        }
    }

    /// Sets the tape to the left of the read/write head.
    pub fn with_left_tape(&self, mut symbols: Vec<S>) -> TapeBuilder<S> {
        symbols.reverse();

        let mut half_tape: HalfTape<S> = HalfTape::empty();
        for symbol in symbols {
            half_tape = half_tape.push(symbol)
        }

        TapeBuilder {
            tape: ConcreteTape {
                left: half_tape,
                .. self.tape.clone()
            }
        }
    }

    /// Build the described tape.
    pub fn build(&self) -> ConcreteTape<S> {
        self.tape.clone()
    }
}

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

    #[test]
    fn empty_tape_should_read_head() {
        let t = ConcreteTape::empty("_");

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn empty_tape_should_introduce_blanks_when_moved_left() {
        let mut t = ConcreteTape::empty("_");
        t = t.left();

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn empty_tape_should_introduce_blanks_when_moved_right() {
        let mut t = ConcreteTape::empty("_");
        t = t.right();

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn tape_should_be_loaded_with_initial_symbols_on_the_right() {
        let mut t = TapeBuilder::with_blank("_")
            .with_current("a")
            .with_right_tape(vec!["b", "c", "d"])
            .build();

        let mut symbol = t.read();
        assert_eq!(symbol, "a");

        t = t.right();
        symbol = t.read();
        assert_eq!(symbol, "b");
    }

    #[test]
    fn tape_should_be_loaded_with_initial_symbols_on_the_left() {
        let mut t = TapeBuilder::with_blank("_")
            .with_current("a")
            .with_left_tape(vec!["b", "c", "d"])
            .build();

        let mut symbol = t.read();
        assert_eq!(symbol, "a");

        t = t.left();
        symbol = t.read();
        assert_eq!(symbol, "b");
    }
}
<commit_msg>Document in an example how a Tape can be build<commit_after>//! Tape is a representation of the Turing machine infinite tape.
//!
//! You can read from it, write to it and move it left and right.

/// The contract a concrete Tape should adhere to.
pub trait Tape<S: Clone> {
    /// Reads the symbol at the location of the head of the Turing machine
    fn read(&self) -> S;

    /// Writes symbol at the location of the head of the Turing machine
    fn write(&self, symbol: S) -> Self;

    /// The blank symbol for this tape
    fn blank(&self) -> S;

    /// Move the head of the Turing machine to the left on this tape
    fn left(&self) -> Self;

    /// Move the head of the Turing machine to the right on this tape
    fn right(&self) -> Self;
}

/// An type implementing the `Tape` trait.
#[derive(Clone)]
pub struct ConcreteTape<S: Clone> {
    blank: S,
    left: HalfTape<S>,
    current: S,
    right: HalfTape<S>,
}

#[derive(Clone)]
enum HalfTape<S: Clone> {
    Cell(S, Box<HalfTape<S>>),
    Empty,
}

impl<S: Clone> HalfTape<S> {
    fn empty() -> HalfTape<S> {
        HalfTape::Empty
    }

    fn pop(&self) -> (Option<S>, HalfTape<S>) {
        match *self {
            HalfTape::Cell(ref symbol, ref boxed_tail) => {
                (Some(symbol.clone()), *boxed_tail.clone())
            },
            HalfTape::Empty => (None, HalfTape::Empty)
        }
    }

    fn push(self, symbol: S) -> HalfTape<S> {
        HalfTape::Cell(symbol, Box::new(self))
    }
}

impl<S:Clone> ConcreteTape<S> {
    /// Create an empty `ConcreteTape`. The argument will be used to as the
    /// blank symbol for this tape. This is necessary when the read/write head
    /// moves into unexplored territory. If there is nothing on the tape yet, it
    /// will provide the blank symbol.
    pub fn empty(blank: S) -> ConcreteTape<S> {
        ConcreteTape {
            blank: blank.clone(),
            left: HalfTape::empty(),
            current: blank.clone(),
            right: HalfTape::empty()
        }
    }
}

impl<S: Clone> Tape<S> for ConcreteTape<S> {
    fn read(&self) -> S {
        self.current.clone()
    }

    fn write(&self, symbol: S) -> ConcreteTape<S> {
        ConcreteTape {
            current: symbol, .. self.clone()
        }
    }

    fn blank(&self) -> S {
        self.blank.clone()
    }

    fn left(&self) -> ConcreteTape<S> {
        let (option, left_tail) = self.left.pop();
        match option {
            Some(symbol) => ConcreteTape {
                left: left_tail,
                current: symbol,
                right: self.right.clone().push(self.current.clone()),
                .. self.clone()
            },
            None => ConcreteTape {
                left: left_tail,
                current: self.blank(),
                right: self.right.clone().push(self.current.clone()),
                .. self.clone()
            }
        }
    }

    fn right(&self) -> ConcreteTape<S> {
        let (option, right_tail) = self.right.pop();
        match option {
            Some(symbol) => ConcreteTape {
                left: self.right.clone().push(self.current.clone()),
                current: symbol,
                right: right_tail,
                .. self.clone()
            },
            None => ConcreteTape {
                left: self.left.clone().push(self.current.clone()),
                current: self.blank(),
                right: right_tail,
                .. self.clone()
            }
        }
    }
}

/// Builder for `ConcreteTape`.
///
/// # Example
/// The builder can be used to construct a `ConcreteTape`.
///
/// ```
/// use parsimony::tm::tape::TapeBuilder;
///
/// let tape = TapeBuilder::with_blank("_")
///     .with_current("a")
///     .with_right_tape(vec!["b", "c"])
///     .build();
/// ```
pub struct TapeBuilder<S: Clone> {
    tape : ConcreteTape<S>,
}

impl<S: Clone> TapeBuilder<S> {
    /// Set the blank symbol for this tape.
    pub fn with_blank(blank: S) -> TapeBuilder<S> {
        TapeBuilder { tape: ConcreteTape::empty(blank) }
    }

    /// Set the symbol the read/write head is currently scanning
    pub fn with_current(&self, symbol: S) -> TapeBuilder<S> {
        TapeBuilder { tape: self.tape.write(symbol) }
    }

    /// Sets the tape to the right of the read/write head.
    pub fn with_right_tape(&self, mut symbols: Vec<S>) -> TapeBuilder<S> {
        symbols.reverse();

        let mut half_tape: HalfTape<S> = HalfTape::empty();
        for symbol in symbols {
            half_tape = half_tape.push(symbol)
        }

        TapeBuilder {
            tape: ConcreteTape {
                right: half_tape,
                .. self.tape.clone()
            }
        }
    }

    /// Sets the tape to the left of the read/write head.
    pub fn with_left_tape(&self, mut symbols: Vec<S>) -> TapeBuilder<S> {
        symbols.reverse();

        let mut half_tape: HalfTape<S> = HalfTape::empty();
        for symbol in symbols {
            half_tape = half_tape.push(symbol)
        }

        TapeBuilder {
            tape: ConcreteTape {
                left: half_tape,
                .. self.tape.clone()
            }
        }
    }

    /// Build the described tape.
    pub fn build(&self) -> ConcreteTape<S> {
        self.tape.clone()
    }
}

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

    #[test]
    fn empty_tape_should_read_head() {
        let t = ConcreteTape::empty("_");

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn empty_tape_should_introduce_blanks_when_moved_left() {
        let mut t = ConcreteTape::empty("_");
        t = t.left();

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn empty_tape_should_introduce_blanks_when_moved_right() {
        let mut t = ConcreteTape::empty("_");
        t = t.right();

        let symbol = t.read();

        assert_eq!(symbol, t.blank());
    }

    #[test]
    fn tape_should_be_loaded_with_initial_symbols_on_the_right() {
        let mut t = TapeBuilder::with_blank("_")
            .with_current("a")
            .with_right_tape(vec!["b", "c", "d"])
            .build();

        let mut symbol = t.read();
        assert_eq!(symbol, "a");

        t = t.right();
        symbol = t.read();
        assert_eq!(symbol, "b");
    }

    #[test]
    fn tape_should_be_loaded_with_initial_symbols_on_the_left() {
        let mut t = TapeBuilder::with_blank("_")
            .with_current("a")
            .with_left_tape(vec!["b", "c", "d"])
            .build();

        let mut symbol = t.read();
        assert_eq!(symbol, "a");

        t = t.left();
        symbol = t.read();
        assert_eq!(symbol, "b");
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::iter::Iterator;
use std::rc::Rc;
use std::ops::Deref;

use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, Rc<RefCell<File>>);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        for file in files {
            self.print_file(file);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> String
    {
        info!("{}", f(file));
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> String
    {
        for file in files {
            self.print_file_custom(file, f);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> String
    {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f(file));
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", &*f.deref().borrow());
        } else {
            info!("[File]: {}", f.deref().borrow().id());
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<commit_msg>Impl FilePrinter for SimplePrinter ::print_file_custom()<commit_after>use std::cell::RefCell;
use std::iter::Iterator;
use std::rc::Rc;
use std::ops::Deref;

use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, Rc<RefCell<File>>);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        for file in files {
            self.print_file(file);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> String
    {
        info!("{}", f(file));
    }

    fn print_files_custom<F, I>(&self, files: I, f: &F)
        where I: Iterator<Item = Rc<RefCell<File>>>,
              F: Fn(Rc<RefCell<File>>) -> String
    {
        for file in files {
            self.print_file_custom(file, f);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> String
    {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f(file));
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", &*f.deref().borrow());
        } else {
            info!("[File]: {}", f.deref().borrow().id());
        }
    }

    fn print_file_custom<F>(&self, file: Rc<RefCell<File>>, f: &F)
        where F: Fn(Rc<RefCell<File>>) -> String
    {
        let s = f(file);
        if self.debug {
            debug!("{:?}", s);
        } else if self.verbose {
            info!("{}", s);
        } else {
            info!("[File]: {}", s);
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<|endoftext|>


<commit_before>use std::iter::Iterator;

use runtime::Runtime;
use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, &File);

    /*
     * Print a list of files
     */
    fn print_files<'a, I: Iterator<Item = File<'a>>>(&self, files: I) {
        for file in files {
            self.print_file(&file);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(verbose: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", f);
        } else {
            info!("[File]: {}", f.id());
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: &File) {
        self.sp.print_file(f);
    }

    fn print_files<'a, I: Iterator<Item = File<'a>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.owner().name())[..]);

            let id : String = file.id().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        tab.printstd();
    }

}
<commit_msg>Print table only if there are entries<commit_after>use std::iter::Iterator;

use runtime::Runtime;
use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, &File);

    /*
     * Print a list of files
     */
    fn print_files<'a, I: Iterator<Item = File<'a>>>(&self, files: I) {
        for file in files {
            self.print_file(&file);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(verbose: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", f);
        } else {
            info!("[File]: {}", f.id());
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: &File) {
        self.sp.print_file(f);
    }

    fn print_files<'a, I: Iterator<Item = File<'a>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.owner().name())[..]);

            let id : String = file.id().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<|endoftext|>


<commit_before>use std::ffi::CStr;
use std::fmt;
use std::str;

use curl_sys;
use libc::{c_char, c_int};

/// Version information about libcurl and the capabilities that it supports.
pub struct Version {
    inner: *mut curl_sys::curl_version_info_data,
}

unsafe impl Send for Version {}
unsafe impl Sync for Version {}

/// An iterator over the list of protocols a version supports.
#[derive(Clone)]
pub struct Protocols<'a> {
    cur: *const *const c_char,
    _inner: &'a Version,
}

impl Version {
    /// Returns the libcurl version that this library is currently linked against.
    pub fn num() -> &'static str {
        unsafe {
            let s = CStr::from_ptr(curl_sys::curl_version() as *const _);
            str::from_utf8(s.to_bytes()).unwrap()
        }
    }

    /// Returns the libcurl version that this library is currently linked against.
    pub fn get() -> Version {
        unsafe {
            let ptr = curl_sys::curl_version_info(curl_sys::CURLVERSION_NOW);
            assert!(!ptr.is_null());
            Version { inner: ptr }
        }
    }

    /// Returns the human readable version string,
    pub fn version(&self) -> &str {
        unsafe { ::opt_str((*self.inner).version).unwrap() }
    }

    /// Returns a numeric representation of the version number
    ///
    /// This is a 24 bit number made up of the major number, minor, and then
    /// patch number. For example 7.9.8 will return 0x070908.
    pub fn version_num(&self) -> u32 {
        unsafe { (*self.inner).version_num as u32 }
    }

    /// Returns a human readable string of the host libcurl is built for.
    ///
    /// This is discovered as part of the build environment.
    pub fn host(&self) -> &str {
        unsafe { ::opt_str((*self.inner).host).unwrap() }
    }

    /// Returns whether libcurl supports IPv6
    pub fn feature_ipv6(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_IPV6)
    }

    /// Returns whether libcurl supports SSL
    pub fn feature_ssl(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SSL)
    }

    /// Returns whether libcurl supports HTTP deflate via libz
    pub fn feature_libz(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_LIBZ)
    }

    /// Returns whether libcurl supports HTTP NTLM
    pub fn feature_ntlm(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_NTLM)
    }

    /// Returns whether libcurl supports HTTP GSSNEGOTIATE
    pub fn feature_gss_negotiate(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_GSSNEGOTIATE)
    }

    /// Returns whether libcurl was built with debug capabilities
    pub fn feature_debug(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_DEBUG)
    }

    /// Returns whether libcurl was built with SPNEGO authentication
    pub fn feature_spnego(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SPNEGO)
    }

    /// Returns whether libcurl was built with large file support
    pub fn feature_largefile(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_LARGEFILE)
    }

    /// Returns whether libcurl was built with support for IDNA, domain names
    /// with international letters.
    pub fn feature_idn(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_IDN)
    }

    /// Returns whether libcurl was built with support for SSPI.
    pub fn feature_sspi(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SSPI)
    }

    /// Returns whether libcurl was built with asynchronous name lookups.
    pub fn feature_async_dns(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_ASYNCHDNS)
    }

    /// Returns whether libcurl was built with support for character
    /// conversions.
    pub fn feature_conv(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_CONV)
    }

    /// Returns whether libcurl was built with support for TLS-SRP.
    pub fn feature_tlsauth_srp(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_TLSAUTH_SRP)
    }

    /// Returns whether libcurl was built with support for NTLM delegation to
    /// winbind helper.
    pub fn feature_ntlm_wb(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_NTLM_WB)
    }

    /// Returns whether libcurl was built with support for unix domain socket
    pub fn feature_unix_domain_socket(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_UNIX_SOCKETS)
    }

    /// Returns whether libcurl was built with support for HTTP2.
    pub fn feature_http2(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_HTTP2)
    }

    fn flag(&self, flag: c_int) -> bool {
        unsafe { (*self.inner).features & flag != 0 }
    }

    /// Returns the version of OpenSSL that is used, or None if there is no SSL
    /// support.
    pub fn ssl_version(&self) -> Option<&str> {
        unsafe { ::opt_str((*self.inner).ssl_version) }
    }

    /// Returns the version of libz that is used, or None if there is no libz
    /// support.
    pub fn libz_version(&self) -> Option<&str> {
        unsafe { ::opt_str((*self.inner).libz_version) }
    }

    /// Returns an iterator over the list of protocols that this build of
    /// libcurl supports.
    pub fn protocols(&self) -> Protocols {
        unsafe {
            Protocols {
                _inner: self,
                cur: (*self.inner).protocols,
            }
        }
    }

    /// If available, the human readable version of ares that libcurl is linked
    /// against.
    pub fn ares_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
                ::opt_str((*self.inner).ares)
            } else {
                None
            }
        }
    }

    /// If available, the version of ares that libcurl is linked against.
    pub fn ares_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
                Some((*self.inner).ares_num as u32)
            } else {
                None
            }
        }
    }

    /// If available, the version of libidn that libcurl is linked against.
    pub fn libidn_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_THIRD {
                ::opt_str((*self.inner).libidn)
            } else {
                None
            }
        }
    }

    /// If available, the version of iconv libcurl is linked against.
    pub fn iconv_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
                Some((*self.inner).iconv_ver_num as u32)
            } else {
                None
            }
        }
    }

    /// If available, the version of libssh that libcurl is linked against.
    pub fn libssh_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
                ::opt_str((*self.inner).libssh_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of brotli libcurl is linked against.
    pub fn brotli_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
                Some((*self.inner).brotli_ver_num)
            } else {
                None
            }
        }
    }

    /// If available, the version of brotli libcurl is linked against.
    pub fn brotli_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
                ::opt_str((*self.inner).brotli_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of nghttp2 libcurl is linked against.
    pub fn nghttp2_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                Some((*self.inner).nghttp2_ver_num)
            } else {
                None
            }
        }
    }

    /// If available, the version of nghttp2 libcurl is linked against.
    pub fn nghttp2_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                ::opt_str((*self.inner).nghttp2_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of quic libcurl is linked against.
    pub fn quic_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                ::opt_str((*self.inner).quic_version)
            } else {
                None
            }
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_struct("Version");
        f.field("version", &self.version())
            .field("host", &self.host())
            .field("feature_ipv6", &self.feature_ipv6())
            .field("feature_ssl", &self.feature_ssl())
            .field("feature_libz", &self.feature_libz())
            .field("feature_ntlm", &self.feature_ntlm())
            .field("feature_gss_negotiate", &self.feature_gss_negotiate())
            .field("feature_debug", &self.feature_debug())
            .field("feature_spnego", &self.feature_debug())
            .field("feature_largefile", &self.feature_debug())
            .field("feature_idn", &self.feature_debug())
            .field("feature_sspi", &self.feature_debug())
            .field("feature_async_dns", &self.feature_debug())
            .field("feature_conv", &self.feature_debug())
            .field("feature_tlsauth_srp", &self.feature_debug())
            .field("feature_ntlm_wb", &self.feature_debug())
            .field("feature_unix_domain_socket", &self.feature_debug());

        if let Some(s) = self.ssl_version() {
            f.field("ssl_version", &s);
        }
        if let Some(s) = self.libz_version() {
            f.field("libz_version", &s);
        }
        if let Some(s) = self.ares_version() {
            f.field("ares_version", &s);
        }
        if let Some(s) = self.libidn_version() {
            f.field("libidn_version", &s);
        }
        if let Some(s) = self.iconv_version_num() {
            f.field("iconv_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.libssh_version() {
            f.field("libssh_version", &s);
        }
        if let Some(s) = self.brotli_version_num() {
            f.field("brotli_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.brotli_version() {
            f.field("brotli_version", &s);
        }
        if let Some(s) = self.nghttp2_version_num() {
            f.field("nghttp2_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.nghttp2_version() {
            f.field("nghttp2_version", &s);
        }
        if let Some(s) = self.quic_version() {
            f.field("quic_version", &s);
        }

        f.field("protocols", &self.protocols().collect::<Vec<_>>());

        f.finish()
    }
}

impl<'a> Iterator for Protocols<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        unsafe {
            if (*self.cur).is_null() {
                return None;
            }
            let ret = ::opt_str(*self.cur).unwrap();
            self.cur = self.cur.offset(1);
            Some(ret)
        }
    }
}

impl<'a> fmt::Debug for Protocols<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}
<commit_msg>Fix fmt::Debug for Version feature list (#306)<commit_after>use std::ffi::CStr;
use std::fmt;
use std::str;

use curl_sys;
use libc::{c_char, c_int};

/// Version information about libcurl and the capabilities that it supports.
pub struct Version {
    inner: *mut curl_sys::curl_version_info_data,
}

unsafe impl Send for Version {}
unsafe impl Sync for Version {}

/// An iterator over the list of protocols a version supports.
#[derive(Clone)]
pub struct Protocols<'a> {
    cur: *const *const c_char,
    _inner: &'a Version,
}

impl Version {
    /// Returns the libcurl version that this library is currently linked against.
    pub fn num() -> &'static str {
        unsafe {
            let s = CStr::from_ptr(curl_sys::curl_version() as *const _);
            str::from_utf8(s.to_bytes()).unwrap()
        }
    }

    /// Returns the libcurl version that this library is currently linked against.
    pub fn get() -> Version {
        unsafe {
            let ptr = curl_sys::curl_version_info(curl_sys::CURLVERSION_NOW);
            assert!(!ptr.is_null());
            Version { inner: ptr }
        }
    }

    /// Returns the human readable version string,
    pub fn version(&self) -> &str {
        unsafe { ::opt_str((*self.inner).version).unwrap() }
    }

    /// Returns a numeric representation of the version number
    ///
    /// This is a 24 bit number made up of the major number, minor, and then
    /// patch number. For example 7.9.8 will return 0x070908.
    pub fn version_num(&self) -> u32 {
        unsafe { (*self.inner).version_num as u32 }
    }

    /// Returns a human readable string of the host libcurl is built for.
    ///
    /// This is discovered as part of the build environment.
    pub fn host(&self) -> &str {
        unsafe { ::opt_str((*self.inner).host).unwrap() }
    }

    /// Returns whether libcurl supports IPv6
    pub fn feature_ipv6(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_IPV6)
    }

    /// Returns whether libcurl supports SSL
    pub fn feature_ssl(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SSL)
    }

    /// Returns whether libcurl supports HTTP deflate via libz
    pub fn feature_libz(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_LIBZ)
    }

    /// Returns whether libcurl supports HTTP NTLM
    pub fn feature_ntlm(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_NTLM)
    }

    /// Returns whether libcurl supports HTTP GSSNEGOTIATE
    pub fn feature_gss_negotiate(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_GSSNEGOTIATE)
    }

    /// Returns whether libcurl was built with debug capabilities
    pub fn feature_debug(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_DEBUG)
    }

    /// Returns whether libcurl was built with SPNEGO authentication
    pub fn feature_spnego(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SPNEGO)
    }

    /// Returns whether libcurl was built with large file support
    pub fn feature_largefile(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_LARGEFILE)
    }

    /// Returns whether libcurl was built with support for IDNA, domain names
    /// with international letters.
    pub fn feature_idn(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_IDN)
    }

    /// Returns whether libcurl was built with support for SSPI.
    pub fn feature_sspi(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_SSPI)
    }

    /// Returns whether libcurl was built with asynchronous name lookups.
    pub fn feature_async_dns(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_ASYNCHDNS)
    }

    /// Returns whether libcurl was built with support for character
    /// conversions.
    pub fn feature_conv(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_CONV)
    }

    /// Returns whether libcurl was built with support for TLS-SRP.
    pub fn feature_tlsauth_srp(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_TLSAUTH_SRP)
    }

    /// Returns whether libcurl was built with support for NTLM delegation to
    /// winbind helper.
    pub fn feature_ntlm_wb(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_NTLM_WB)
    }

    /// Returns whether libcurl was built with support for unix domain socket
    pub fn feature_unix_domain_socket(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_UNIX_SOCKETS)
    }

    /// Returns whether libcurl was built with support for HTTP2.
    pub fn feature_http2(&self) -> bool {
        self.flag(curl_sys::CURL_VERSION_HTTP2)
    }

    fn flag(&self, flag: c_int) -> bool {
        unsafe { (*self.inner).features & flag != 0 }
    }

    /// Returns the version of OpenSSL that is used, or None if there is no SSL
    /// support.
    pub fn ssl_version(&self) -> Option<&str> {
        unsafe { ::opt_str((*self.inner).ssl_version) }
    }

    /// Returns the version of libz that is used, or None if there is no libz
    /// support.
    pub fn libz_version(&self) -> Option<&str> {
        unsafe { ::opt_str((*self.inner).libz_version) }
    }

    /// Returns an iterator over the list of protocols that this build of
    /// libcurl supports.
    pub fn protocols(&self) -> Protocols {
        unsafe {
            Protocols {
                _inner: self,
                cur: (*self.inner).protocols,
            }
        }
    }

    /// If available, the human readable version of ares that libcurl is linked
    /// against.
    pub fn ares_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
                ::opt_str((*self.inner).ares)
            } else {
                None
            }
        }
    }

    /// If available, the version of ares that libcurl is linked against.
    pub fn ares_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SECOND {
                Some((*self.inner).ares_num as u32)
            } else {
                None
            }
        }
    }

    /// If available, the version of libidn that libcurl is linked against.
    pub fn libidn_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_THIRD {
                ::opt_str((*self.inner).libidn)
            } else {
                None
            }
        }
    }

    /// If available, the version of iconv libcurl is linked against.
    pub fn iconv_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
                Some((*self.inner).iconv_ver_num as u32)
            } else {
                None
            }
        }
    }

    /// If available, the version of libssh that libcurl is linked against.
    pub fn libssh_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FOURTH {
                ::opt_str((*self.inner).libssh_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of brotli libcurl is linked against.
    pub fn brotli_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
                Some((*self.inner).brotli_ver_num)
            } else {
                None
            }
        }
    }

    /// If available, the version of brotli libcurl is linked against.
    pub fn brotli_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_FIFTH {
                ::opt_str((*self.inner).brotli_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of nghttp2 libcurl is linked against.
    pub fn nghttp2_version_num(&self) -> Option<u32> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                Some((*self.inner).nghttp2_ver_num)
            } else {
                None
            }
        }
    }

    /// If available, the version of nghttp2 libcurl is linked against.
    pub fn nghttp2_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                ::opt_str((*self.inner).nghttp2_version)
            } else {
                None
            }
        }
    }

    /// If available, the version of quic libcurl is linked against.
    pub fn quic_version(&self) -> Option<&str> {
        unsafe {
            if (*self.inner).age >= curl_sys::CURLVERSION_SIXTH {
                ::opt_str((*self.inner).quic_version)
            } else {
                None
            }
        }
    }
}

impl fmt::Debug for Version {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_struct("Version");
        f.field("version", &self.version())
            .field("host", &self.host())
            .field("feature_ipv6", &self.feature_ipv6())
            .field("feature_ssl", &self.feature_ssl())
            .field("feature_libz", &self.feature_libz())
            .field("feature_ntlm", &self.feature_ntlm())
            .field("feature_gss_negotiate", &self.feature_gss_negotiate())
            .field("feature_debug", &self.feature_debug())
            .field("feature_spnego", &self.feature_spnego())
            .field("feature_largefile", &self.feature_largefile())
            .field("feature_idn", &self.feature_idn())
            .field("feature_sspi", &self.feature_sspi())
            .field("feature_async_dns", &self.feature_async_dns())
            .field("feature_conv", &self.feature_conv())
            .field("feature_tlsauth_srp", &self.feature_tlsauth_srp())
            .field("feature_ntlm_wb", &self.feature_ntlm_wb())
            .field(
                "feature_unix_domain_socket",
                &self.feature_unix_domain_socket(),
            );

        if let Some(s) = self.ssl_version() {
            f.field("ssl_version", &s);
        }
        if let Some(s) = self.libz_version() {
            f.field("libz_version", &s);
        }
        if let Some(s) = self.ares_version() {
            f.field("ares_version", &s);
        }
        if let Some(s) = self.libidn_version() {
            f.field("libidn_version", &s);
        }
        if let Some(s) = self.iconv_version_num() {
            f.field("iconv_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.libssh_version() {
            f.field("libssh_version", &s);
        }
        if let Some(s) = self.brotli_version_num() {
            f.field("brotli_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.brotli_version() {
            f.field("brotli_version", &s);
        }
        if let Some(s) = self.nghttp2_version_num() {
            f.field("nghttp2_version_num", &format!("{:x}", s));
        }
        if let Some(s) = self.nghttp2_version() {
            f.field("nghttp2_version", &s);
        }
        if let Some(s) = self.quic_version() {
            f.field("quic_version", &s);
        }

        f.field("protocols", &self.protocols().collect::<Vec<_>>());

        f.finish()
    }
}

impl<'a> Iterator for Protocols<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        unsafe {
            if (*self.cur).is_null() {
                return None;
            }
            let ret = ::opt_str(*self.cur).unwrap();
            self.cur = self.cur.offset(1);
            Some(ret)
        }
    }
}

impl<'a> fmt::Debug for Protocols<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}
<|endoftext|>


<commit_before>/*
    TODO:
    1. Copy downloaded files to other places.
    2. Verify the downloaded package.
    3. Make it support repos someday.
*/
crate hyper;
use self::hyper::client;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => panic!("An error occured during package downloading.", why),
    });
}

fn download_package(url: &str) -> Vec<u8> {
    let client = Client::new();
    let response = custom_try!(client.get(url).send());
    let content = Vec::new();
    custom_try!(response.read_to_end(&mut content));
    return content;
}<commit_msg>Write into a file instead of buffer.<commit_after>/*
    TODO:
    1. Copy downloaded files to other places. (Completed)
    2. Verify the downloaded package.
    3. Make it support repos someday.
*/
crate hyper;
use self::hyper::client;

macro_rules! custom_try {
    ($x:expr) => (match $x {
        Ok(x) => x,
        Err(why) => panic!("An error occured during package downloading.", why),
    });
}

fn download_package(url: &str, output: &Path) {
    let client = Client::new();
    let response = custom_try!(client.get(url).send());
    let mut target = custom_try!(File::create(output));

    for byte in response.bytes() {
        target.write(&[byte.unwrap()]);
    }
}<|endoftext|>


<commit_before>use std::str::Chars;
use std::iter::Peekable;
use std::iter::Enumerate;

use ::syntax::lexer::{Token, Lexer, Span};
use ::syntax::next_is;

pub struct RustSyntax;

impl Lexer for RustSyntax {
    fn handle_char(&self, ch: char, mut iter: &mut Peekable<Enumerate<Chars>>, y_pos: usize, idx: usize) -> Option<Span> {
        match ch {
            '#' => {
                let st = idx;
                let mut end = idx;
                if next_is(&mut iter, '!') || next_is(&mut iter, '[') {
                    let mut s = String::from("#");
                    while let Some(&(e, c)) = iter.peek() {
                        if c == '\n' { break }
                        end = e;
                        s.push(iter.next().unwrap().1)
                    }
                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: end,
                        token: Token::Attribute(s),
                    });
                }
                return Some(Span{y_pos: y_pos, start: idx, end: idx + 1, token: Token::Hash})
            }

            '/' => {
                let st = idx;
                let mut end = idx;
                if next_is(&mut iter, '/') {
                    let mut s = String::from("/");
                    s.push(iter.next().unwrap().1);

                    let mut doc_comment = false;
                    if next_is(&mut iter, '/') {
                        doc_comment = true;
                    }

                    while let Some(&(e, c)) = iter.peek() {
                        if c == '\n' { break }
                        end = e;
                        s.push(iter.next().unwrap().1)
                    }

                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: end,
                        token: if doc_comment{ Token::DocComment(s) } else { Token::SingleLineComment(s) },
                    });
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::ForwardSlash,
                });
            }

            '"' => {
                let st = idx;
                let mut end = idx;
                let mut s = String::from("\"");
                while let Some(&(e, c)) = iter.peek() {
                    end = e;
                    s.push(iter.next().unwrap().1);
                    if c == '"' {
                        break;
                    }
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::String(s),
                });
            }

            '\'' => {
                let st = idx;
                let mut end = idx;
                let mut s = String::from("\'");
                while let Some(&(e, c)) = iter.peek() {
                    end = e;
                    s.push(iter.next().unwrap().1);
                    if c == '\\' {
                        if let Some(&(e, c_)) = iter.peek() {
                            // this is handling escaped single quotes...
                            if c_ == '\'' {
                                s.push(iter.next().unwrap().1);
                                continue;
                            }
                        }
                    }
                    if c == '\'' {
                        break;
                    }
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::Special(s),
                });
            }

            _ => None,
        }

    }

    fn handle_ident(&self, ch: char, mut iter: &mut Peekable<Enumerate<Chars>>, y_pos: usize) -> Span {
        let mut ident = String::new();
        ident.push(ch);
        let start = iter.peek().unwrap().0 - 1;

        while self.is_ident(iter.peek()) {
            ident.push(iter.next().unwrap().1)
        }

        Span {
            y_pos: y_pos,
            start: start,
            end: start + ident.len() - 1,
            token: Token::Ident(ident),
        }
    }
}

<commit_msg>Highlight :: in rust<commit_after>use std::str::Chars;
use std::iter::Peekable;
use std::iter::Enumerate;

use ::syntax::lexer::{Token, Lexer, Span};
use ::syntax::next_is;

pub struct RustSyntax;

impl Lexer for RustSyntax {
    fn handle_char(&self, ch: char, mut iter: &mut Peekable<Enumerate<Chars>>, y_pos: usize, idx: usize) -> Option<Span> {
        match ch {
            '#' => {
                let st = idx;
                let mut end = idx;
                if next_is(&mut iter, '!') || next_is(&mut iter, '[') {
                    let mut s = String::from("#");
                    while let Some(&(e, c)) = iter.peek() {
                        if c == '\n' { break }
                        end = e;
                        s.push(iter.next().unwrap().1)
                    }
                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: end,
                        token: Token::Attribute(s),
                    });
                }
                return Some(Span{y_pos: y_pos, start: idx, end: idx + 1, token: Token::Hash})
            }

            '/' => {
                let st = idx;
                let mut end = idx;
                if next_is(&mut iter, '/') {
                    let mut s = String::from("/");
                    s.push(iter.next().unwrap().1);

                    let mut doc_comment = false;
                    if next_is(&mut iter, '/') {
                        doc_comment = true;
                    }

                    while let Some(&(e, c)) = iter.peek() {
                        if c == '\n' { break }
                        end = e;
                        s.push(iter.next().unwrap().1)
                    }

                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: end,
                        token: if doc_comment{ Token::DocComment(s) } else { Token::SingleLineComment(s) },
                    });
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::ForwardSlash,
                });
            }

            '"' => {
                let st = idx;
                let mut end = idx;
                let mut s = String::from("\"");
                while let Some(&(e, c)) = iter.peek() {
                    end = e;
                    s.push(iter.next().unwrap().1);
                    if c == '"' {
                        break;
                    }
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::String(s),
                });
            }

            '\'' => {
                let st = idx;
                let mut end = idx;
                let mut s = String::from("\'");
                while let Some(&(e, c)) = iter.peek() {
                    end = e;
                    s.push(iter.next().unwrap().1);
                    if c == '\\' {
                        if let Some(&(e, c_)) = iter.peek() {
                            // this is handling escaped single quotes...
                            if c_ == '\'' {
                                s.push(iter.next().unwrap().1);
                                continue;
                            }
                        }
                    }
                    if c == '\'' {
                        break;
                    }
                }
                return Some(Span {
                    y_pos: y_pos,
                    start: st,
                    end: end,
                    token: Token::Special(s),
                });
            }

            ':' => {
                let st = idx;
                let mut end = idx;
                if next_is(&mut iter, ':') {
                    let (e, c) = iter.next().unwrap();
                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: e,
                        token: Token::Special(String::from("::")),
                    });
                } else {
                    return Some(Span {
                        y_pos: y_pos,
                        start: st,
                        end: end,
                        token: Token::Colon,
                    });
                }
            }

            _ => None,
        }

    }

    fn handle_ident(&self, ch: char, mut iter: &mut Peekable<Enumerate<Chars>>, y_pos: usize) -> Span {
        let mut ident = String::new();
        ident.push(ch);
        let start = iter.peek().unwrap().0 - 1;

        while self.is_ident(iter.peek()) {
            ident.push(iter.next().unwrap().1)
        }

        Span {
            y_pos: y_pos,
            start: start,
            end: start + ident.len() - 1,
            token: Token::Ident(ident),
        }
    }
}

<|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.

use prelude::v1::*;
use io::prelude::*;

use any::Any;
use cell::RefCell;
use rt::{backtrace, unwind};
use sys::stdio::Stderr;
use sys_common::thread_info;

thread_local! {
    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
        RefCell::new(None)
    }
}

pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
    let msg = match obj.downcast_ref::<&'static str>() {
        Some(s) => *s,
        None => match obj.downcast_ref::<String>() {
            Some(s) => &s[..],
            None => "Box<Any>",
        }
    };
    let mut err = match Stderr::new() {
        Ok(err) => err,
        _ => return,
    };
    let thread = thread_info::current_thread();
    let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
    let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
    match prev {
        Some(mut stderr) => {
            // FIXME: what to do when the thread printing panics?
            let _ = writeln!(stderr,
                             "thread '{}' panicked at '{}', {}:{}\n",
                             name, msg, file, line);
            if backtrace::log_enabled() {
                let _ = backtrace::write(&mut *stderr);
            }
            let mut s = Some(stderr);
            LOCAL_STDERR.with(|slot| {
                *slot.borrow_mut() = s.take();
            });
        }
        None => {
            let _ = writeln!(&mut err, "thread '{}' panicked at '{}', {}:{}",
                             name, msg, file, line);
            if backtrace::log_enabled() {
                let _ = backtrace::write(&mut err);
            }
        }
    }

    // If this is a double panic, make sure that we printed a backtrace
    // for this panic.
    if unwind::panicking() && !backtrace::log_enabled() {
        let _ = backtrace::write(&mut err);
    }
}
<commit_msg>Fix logic in panic printing with no stderr<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.

use prelude::v1::*;
use io::prelude::*;

use any::Any;
use cell::RefCell;
use rt::{backtrace, unwind};
use sys::stdio::Stderr;
use sys_common::thread_info;

thread_local! {
    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
        RefCell::new(None)
    }
}

pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
    let msg = match obj.downcast_ref::<&'static str>() {
        Some(s) => *s,
        None => match obj.downcast_ref::<String>() {
            Some(s) => &s[..],
            None => "Box<Any>",
        }
    };
    let mut err = Stderr::new().ok();
    let thread = thread_info::current_thread();
    let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
    let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
    match (prev, err.as_mut()) {
        (Some(mut stderr), _) => {
            // FIXME: what to do when the thread printing panics?
            let _ = writeln!(stderr,
                             "thread '{}' panicked at '{}', {}:{}\n",
                             name, msg, file, line);
            if backtrace::log_enabled() {
                let _ = backtrace::write(&mut *stderr);
            }
            let mut s = Some(stderr);
            LOCAL_STDERR.with(|slot| {
                *slot.borrow_mut() = s.take();
            });
        }
        (None, Some(ref mut err)) => {
            let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
                             name, msg, file, line);
            if backtrace::log_enabled() {
                let _ = backtrace::write(err);
            }
        }
        _ => {}
    }

    // If this is a double panic, make sure that we printed a backtrace
    // for this panic.
    match err {
        Some(ref mut err) if unwind::panicking() && !backtrace::log_enabled() => {
            let _ = backtrace::write(err);
        }
        _ => {}
    }
}
<|endoftext|>


<commit_before>pub trait Dominate<Rhs=Self> {
    fn dominates(&self, other: &Rhs) -> bool;
}

/// Stop after we have found `n` solutions. As we include the whole pareto
/// front, there are probably more solutions returned.
pub fn fast_non_dominated_sort<P: Dominate>(solutions: &[P], n: usize) -> Vec<Vec<usize>> {
    let mut fronts: Vec<Vec<usize>> = Vec::new();
    let mut current_front = Vec::new();

    let mut domination_count: Vec<usize> = (0..solutions.len()).map(|_| 0).collect();
    let mut dominated_solutions: Vec<Vec<usize>> = (0..solutions.len())
                                                       .map(|_| Vec::new())
                                                       .collect();
    let mut found_solutions: usize = 0;

    for (i, p) in solutions.iter().enumerate() {
        for (j, q) in solutions.iter().enumerate() {
            if i == j {
                continue;
            }
            if p.dominates(q) {
                // Add `q` to the set of solutions dominated by `p`.
                dominated_solutions[i].push(j);
            } else if q.dominates(p) {
                // Increment domination counter of `p`.
                domination_count[i] += 1;
            }
        }

        if domination_count[i] == 0 {
            // `p` belongs to the first front as it is not dominated by any
            // other solution.
            current_front.push(i);
        }
    }

    while !current_front.is_empty() {
        found_solutions += current_front.len();
        if found_solutions >= n {
            fronts.push(current_front);
            break;
        } else {
            // we haven't found enough solutions yet.
            let mut next_front = Vec::new();
            for &p_i in current_front.iter() {
                for &q_i in dominated_solutions[p_i].iter() {
                    domination_count[q_i] -= 1;
                    if domination_count[q_i] == 0 {
                        // q belongs to the next front
                        next_front.push(q_i);
                    }
                }
            }
            fronts.push(current_front);
            current_front = next_front;
        }
    }

    return fronts;
}

<commit_msg>whitespace<commit_after>pub trait Dominate<Rhs=Self> {
    fn dominates(&self, other: &Rhs) -> bool;
}

/// Stop after we have found `n` solutions. As we include the whole pareto
/// front, there are probably more solutions returned.
pub fn fast_non_dominated_sort<P: Dominate>(solutions: &[P], n: usize) -> Vec<Vec<usize>> {
    let mut fronts: Vec<Vec<usize>> = Vec::new();
    let mut current_front = Vec::new();

    let mut domination_count: Vec<usize> = (0..solutions.len()).map(|_| 0).collect();
    let mut dominated_solutions: Vec<Vec<usize>> = (0..solutions.len())
                                                       .map(|_| Vec::new())
                                                       .collect();
    let mut found_solutions: usize = 0;

    for (i, p) in solutions.iter().enumerate() {
        for (j, q) in solutions.iter().enumerate() {
            if i == j {
                continue;
            }
            if p.dominates(q) {
                // Add `q` to the set of solutions dominated by `p`.
                dominated_solutions[i].push(j);
            } else if q.dominates(p) {
                // Increment domination counter of `p`.
                domination_count[i] += 1;
            }
        }

        if domination_count[i] == 0 {
            // `p` belongs to the first front as it is not dominated by any
            // other solution.
            current_front.push(i);
        }
    }

    while !current_front.is_empty() {
        found_solutions += current_front.len();
        if found_solutions >= n {
            fronts.push(current_front);
            break;
        } else {
            // we haven't found enough solutions yet.
            let mut next_front = Vec::new();
            for &p_i in current_front.iter() {
                for &q_i in dominated_solutions[p_i].iter() {
                    domination_count[q_i] -= 1;
                    if domination_count[q_i] == 0 {
                        // q belongs to the next front
                        next_front.push(q_i);
                    }
                }
            }
            fronts.push(current_front);
            current_front = next_front;
        }
    }

    return fronts;
}
<|endoftext|>


<commit_before>use parser::Block;
use parser::Block::Paragraph;
use parser::Span::{Text, Break};
use parser::span::parse_spans;

mod atx_header;
mod setext_header;
mod hr;
mod code_block;
mod blockquote;
mod unordered_list;
use self::atx_header::parse_atx_header;
use self::setext_header::parse_setext_header;
use self::hr::parse_hr;
use self::code_block::parse_code_block;
use self::blockquote::parse_blockquote;
use self::unordered_list::parse_unordered_list;

pub fn parse_blocks (md : &str) -> Vec<Block> {
    let mut blocks = vec![];
    let mut t = vec![];
    let lines : Vec<&str> = md.lines().collect();
    let mut i = 0;
    while i < lines.len() {
        match parse_block(&lines[i .. lines.len()]){
            // if a block is found
            Some((block, consumed_lines)) => {
                // the current paragraph has ended,
                // push it to our blocks
                if !t.is_empty(){
                    blocks.push(Paragraph(t));
                    t = Vec::new();
                }
                blocks.push(block);
                i += consumed_lines;
            }
            // no known element, let's make this a paragraph
            None => {

                // empty linebreak => new paragraph
                if lines[i].is_empty() && !t.is_empty(){
                    blocks.push(Paragraph(t));
                    t = Vec::new();
                }

                let spans = parse_spans(lines[i]);

                // add a whitespace between linebreaks
                // except when we have a break element or nothing
                match (t.last(), spans.first()) {
                    (Some(&Break), _) => {},
                    (_, None) => {},
                    (None, _) => {},
                    _ => t.push(Text(" ".to_owned()))
                }

                // TODO use push_all once it's stable
                for span in spans {
                    t.push(span);
                }
                i += 1;
            }
        }
    }
    if !t.is_empty(){
        blocks.push(Paragraph(t));
    }
    blocks
}

fn parse_block (lines: &[&str]) -> Option<(Block, usize)>{
    pipe_opt!(
        lines
        => parse_hr
        => parse_atx_header
        => parse_setext_header
        => parse_code_block
        => parse_blockquote
        => parse_unordered_list
        )
}

#[cfg(test)]
mod test {
    use super::parse_blocks;
    use parser::Block::{Header, Hr, CodeBlock, Paragraph, Blockquote};
    use parser::Span::Text;

    #[test]
    fn finds_atx_header() {
        assert_eq!(
            parse_blocks("### Test"),
            vec![Header(vec![Text("Test".to_owned())], 3)]
            );
    }

    #[test]
    fn finds_setext_header() {
        assert_eq!(
            parse_blocks("Test\n-------"),
            vec![Header(vec![Text("Test".to_owned())], 2)]
            );
        assert_eq!(
            parse_blocks("Test\n======="),
            vec![Header(vec![Text("Test".to_owned())], 1)]
            );
    }

    #[test]
    fn finds_hr() {
        assert_eq!(
            parse_blocks("-------"),
            vec![Hr]
            );
        assert_eq!(
            parse_blocks("======="),
            vec![Hr]
            );
    }

    #[test]
    fn finds_code_block() {
        assert_eq!(
            parse_blocks("    this is code\n    and this as well"),
            vec![CodeBlock("this is code\nand this as well".to_owned())]
            );
    }

    #[test]
    fn finds_blockquotes() {
        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> ## H2 \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]), Header(vec![Text("H2".to_owned())], 2)])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> > Another blockquote\n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),
            Blockquote(vec![Paragraph(vec![Text("Another blockquote".to_owned())])])])]
            );

        assert_eq!(
            parse_blocks("> > One Paragraph\n> >\n> > Another blockquote\n>\n"),
            vec![Blockquote(vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),
            Paragraph(vec![Text("Another blockquote".to_owned())])])])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph, just > text \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph, just > text".to_owned())])])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> just > text \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),Paragraph(vec![Text("just > text".to_owned())])])]
            );
    }
}

<commit_msg>Replace for loop with .extend_from_slice()<commit_after>use parser::Block;
use parser::Block::Paragraph;
use parser::Span::{Text, Break};
use parser::span::parse_spans;

mod atx_header;
mod setext_header;
mod hr;
mod code_block;
mod blockquote;
mod unordered_list;
use self::atx_header::parse_atx_header;
use self::setext_header::parse_setext_header;
use self::hr::parse_hr;
use self::code_block::parse_code_block;
use self::blockquote::parse_blockquote;
use self::unordered_list::parse_unordered_list;

pub fn parse_blocks (md : &str) -> Vec<Block> {
    let mut blocks = vec![];
    let mut t = vec![];
    let lines : Vec<&str> = md.lines().collect();
    let mut i = 0;
    while i < lines.len() {
        match parse_block(&lines[i .. lines.len()]){
            // if a block is found
            Some((block, consumed_lines)) => {
                // the current paragraph has ended,
                // push it to our blocks
                if !t.is_empty(){
                    blocks.push(Paragraph(t));
                    t = Vec::new();
                }
                blocks.push(block);
                i += consumed_lines;
            }
            // no known element, let's make this a paragraph
            None => {

                // empty linebreak => new paragraph
                if lines[i].is_empty() && !t.is_empty(){
                    blocks.push(Paragraph(t));
                    t = Vec::new();
                }

                let spans = parse_spans(lines[i]);

                // add a whitespace between linebreaks
                // except when we have a break element or nothing
                match (t.last(), spans.first()) {
                    (Some(&Break), _) => {},
                    (_, None) => {},
                    (None, _) => {},
                    _ => t.push(Text(" ".to_owned()))
                }

                t.extend_from_slice(&spans);
                i += 1;
            }
        }
    }
    if !t.is_empty(){
        blocks.push(Paragraph(t));
    }
    blocks
}

fn parse_block (lines: &[&str]) -> Option<(Block, usize)>{
    pipe_opt!(
        lines
        => parse_hr
        => parse_atx_header
        => parse_setext_header
        => parse_code_block
        => parse_blockquote
        => parse_unordered_list
        )
}

#[cfg(test)]
mod test {
    use super::parse_blocks;
    use parser::Block::{Header, Hr, CodeBlock, Paragraph, Blockquote};
    use parser::Span::Text;

    #[test]
    fn finds_atx_header() {
        assert_eq!(
            parse_blocks("### Test"),
            vec![Header(vec![Text("Test".to_owned())], 3)]
            );
    }

    #[test]
    fn finds_setext_header() {
        assert_eq!(
            parse_blocks("Test\n-------"),
            vec![Header(vec![Text("Test".to_owned())], 2)]
            );
        assert_eq!(
            parse_blocks("Test\n======="),
            vec![Header(vec![Text("Test".to_owned())], 1)]
            );
    }

    #[test]
    fn finds_hr() {
        assert_eq!(
            parse_blocks("-------"),
            vec![Hr]
            );
        assert_eq!(
            parse_blocks("======="),
            vec![Hr]
            );
    }

    #[test]
    fn finds_code_block() {
        assert_eq!(
            parse_blocks("    this is code\n    and this as well"),
            vec![CodeBlock("this is code\nand this as well".to_owned())]
            );
    }

    #[test]
    fn finds_blockquotes() {
        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> ## H2 \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]), Header(vec![Text("H2".to_owned())], 2)])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> > Another blockquote\n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),
            Blockquote(vec![Paragraph(vec![Text("Another blockquote".to_owned())])])])]
            );

        assert_eq!(
            parse_blocks("> > One Paragraph\n> >\n> > Another blockquote\n>\n"),
            vec![Blockquote(vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),
            Paragraph(vec![Text("Another blockquote".to_owned())])])])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph, just > text \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph, just > text".to_owned())])])]
            );

        assert_eq!(
            parse_blocks("> One Paragraph\n>\n> just > text \n>\n"),
            vec![Blockquote(vec![Paragraph(vec![Text("One Paragraph".to_owned())]),Paragraph(vec![Text("just > text".to_owned())])])]
            );
    }
}

<|endoftext|>