<commit_before>// Copyright 2013 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 std::libc::c_void;
use std::uint;
use std::cast::{transmute, transmute_mut_unsafe,
                transmute_region, transmute_mut_region};
use std::unstable::stack;

use stack::StackSegment;

// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// FIXME #7761: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    priv start: ~Option<proc()>,
    /// Hold the registers while the task or scheduler is suspended
    priv regs: ~Registers,
    /// Lower bound and upper bound for the stack
    priv stack_bounds: Option<(uint, uint)>,
}

impl Context {
    pub fn empty() -> Context {
        Context {
            start: ~None,
            regs: new_regs(),
            stack_bounds: None,
        }
    }

    /// Create a new context that will resume execution by running proc()
    pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
        // The C-ABI function that is the task entry point
        extern fn task_start_wrapper(f: &mut Option<proc()>) {
            f.take_unwrap()()
        }

        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            rust_swap_registers(transmute_mut_region(&mut *regs),
                                transmute_region(&*regs));
        };

        // FIXME #7767: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let box = ~Some(start);
        initialize_call_frame(&mut *regs,
                              task_start_wrapper as *c_void,
                              unsafe { transmute(&*box) },
                              sp);

        // Scheduler tasks don't have a stack in the "we allocated it" sense,
        // but rather they run on pthreads stacks. We have complete control over
        // them in terms of the code running on them (and hopefully they don't
        // overflow). Additionally, their coroutine stacks are listed as being
        // zero-length, so that's how we detect what's what here.
        let stack_base: *uint = stack.start();
        let bounds = if sp as uint == stack_base as uint {
            None
        } else {
            Some((stack_base as uint, sp as uint))
        };
        return Context {
            start: box,
            regs: regs,
            stack_bounds: bounds,
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    pub fn swap(out_context: &mut Context, in_context: &Context) {
        rtdebug!("swapping contexts");
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, .. } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, .. } => r
        };

        rtdebug!("noting the stack limit and doing raw swap");

        unsafe {
            // Right before we switch to the new context, set the new context's
            // stack limit in the OS-specified TLS slot. This also  means that
            // we cannot call any more rust functions after record_stack_bounds
            // returns because they would all likely fail due to the limit being
            // invalid for the current task. Lucky for us `rust_swap_registers`
            // is a C function so we don't have to worry about that!
            match in_context.stack_bounds {
                Some((lo, hi)) => stack::record_stack_bounds(lo, hi),
                // If we're going back to one of the original contexts or
                // something that's possibly not a "normal task", then reset
                // the stack limit to 0 to make morestack never fail
                None => stack::record_stack_bounds(0, uint::max_value),
            }
            rust_swap_registers(out_regs, in_regs)
        }
    }
}

#[link(name = "rustrt", kind = "static")]
extern {
    fn rust_swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

// Register contexts used in various architectures
//
// These structures all represent a context of one task throughout its
// execution. Each struct is a representation of the architecture's register
// set. When swapping between tasks, these register sets are used to save off
// the current registers into one struct, and load them all from another.
//
// Note that this is only used for context switching, which means that some of
// the registers may go unused. For example, for architectures with
// callee/caller saved registers, the context will only reflect the callee-saved
// registers. This is because the caller saved registers are already stored
// elsewhere on the stack (if it was necessary anyway).
//
// Additionally, there may be fields on various architectures which are unused
// entirely because they only reflect what is theoretically possible for a
// "complete register set" to show, but user-space cannot alter these registers.
// An example of this would be the segment selectors for x86.
//
// These structures/functions are roughly in-sync with the source files inside
// of src/rt/arch/$arch. The only currently used function from those folders is
// the `rust_swap_registers` function, but that's only because for now segmented
// stacks are disabled.

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint };
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0 }; // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

// windows requires saving more registers (both general and XMM), so the windows
// register context must be larger.
#[cfg(windows, target_arch = "x86_64")]
type Registers = [uint, ..34];
#[cfg(not(windows), target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(windows, target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 34]) }
#[cfg(not(windows), target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {

    // Redefinitions from rt/arch/x86_64/regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr {}", fptr);
    rtdebug!("arg {}", arg);
    rtdebug!("sp {}", sp);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {
    let sp = align_down(sp);
    // sp of arm eabi is 8-byte aligned
    let sp = mut_offset(sp, -2);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {
    let sp = align_down(sp);
    // sp of mips o32 is 8-byte aligned
    let sp = mut_offset(sp, -2);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[25] = fptr as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp: uint = transmute(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// ptr::mut_offset is positive ints only
#[inline]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use std::mem::size_of;
    (ptr as int + count * (size_of::<T>() as int)) as *mut T
}
<commit_msg>rustuv: Fix a memory leak (documented inside)<commit_after>// Copyright 2013 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 std::libc::c_void;
use std::uint;
use std::cast::{transmute, transmute_mut_unsafe,
                transmute_region, transmute_mut_region};
use std::unstable::stack;

use stack::StackSegment;

// FIXME #7761: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// FIXME #7761: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    priv start: Option<~proc()>,
    /// Hold the registers while the task or scheduler is suspended
    priv regs: ~Registers,
    /// Lower bound and upper bound for the stack
    priv stack_bounds: Option<(uint, uint)>,
}

impl Context {
    pub fn empty() -> Context {
        Context {
            start: None,
            regs: new_regs(),
            stack_bounds: None,
        }
    }

    /// Create a new context that will resume execution by running proc()
    pub fn new(start: proc(), stack: &mut StackSegment) -> Context {
        // The C-ABI function that is the task entry point
        //
        // Note that this function is a little sketchy. We're taking a
        // procedure, transmuting it to a stack-closure, and then calling to
        // closure. This leverages the fact that the representation of these two
        // types is the same.
        //
        // The reason that we're doing this is that this procedure is expected
        // to never return. The codegen which frees the environment of the
        // procedure occurs *after* the procedure has completed, and this means
        // that we'll never actually free the procedure.
        //
        // To solve this, we use this transmute (to not trigger the procedure
        // deallocation here), and then store a copy of the procedure in the
        // `Context` structure returned. When the `Context` is deallocated, then
        // the entire procedure box will be deallocated as well.
        extern fn task_start_wrapper(f: &proc()) {
            unsafe {
                let f: &|| = transmute(f);
                (*f)()
            }
        }

        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            rust_swap_registers(transmute_mut_region(&mut *regs),
                                transmute_region(&*regs));
        };

        // FIXME #7767: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let start = ~start;
        initialize_call_frame(&mut *regs,
                              task_start_wrapper as *c_void,
                              unsafe { transmute(&*start) },
                              sp);

        // Scheduler tasks don't have a stack in the "we allocated it" sense,
        // but rather they run on pthreads stacks. We have complete control over
        // them in terms of the code running on them (and hopefully they don't
        // overflow). Additionally, their coroutine stacks are listed as being
        // zero-length, so that's how we detect what's what here.
        let stack_base: *uint = stack.start();
        let bounds = if sp as uint == stack_base as uint {
            None
        } else {
            Some((stack_base as uint, sp as uint))
        };
        return Context {
            start: Some(start),
            regs: regs,
            stack_bounds: bounds,
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    pub fn swap(out_context: &mut Context, in_context: &Context) {
        rtdebug!("swapping contexts");
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, .. } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, .. } => r
        };

        rtdebug!("noting the stack limit and doing raw swap");

        unsafe {
            // Right before we switch to the new context, set the new context's
            // stack limit in the OS-specified TLS slot. This also  means that
            // we cannot call any more rust functions after record_stack_bounds
            // returns because they would all likely fail due to the limit being
            // invalid for the current task. Lucky for us `rust_swap_registers`
            // is a C function so we don't have to worry about that!
            match in_context.stack_bounds {
                Some((lo, hi)) => stack::record_stack_bounds(lo, hi),
                // If we're going back to one of the original contexts or
                // something that's possibly not a "normal task", then reset
                // the stack limit to 0 to make morestack never fail
                None => stack::record_stack_bounds(0, uint::max_value),
            }
            rust_swap_registers(out_regs, in_regs)
        }
    }
}

#[link(name = "rustrt", kind = "static")]
extern {
    fn rust_swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

// Register contexts used in various architectures
//
// These structures all represent a context of one task throughout its
// execution. Each struct is a representation of the architecture's register
// set. When swapping between tasks, these register sets are used to save off
// the current registers into one struct, and load them all from another.
//
// Note that this is only used for context switching, which means that some of
// the registers may go unused. For example, for architectures with
// callee/caller saved registers, the context will only reflect the callee-saved
// registers. This is because the caller saved registers are already stored
// elsewhere on the stack (if it was necessary anyway).
//
// Additionally, there may be fields on various architectures which are unused
// entirely because they only reflect what is theoretically possible for a
// "complete register set" to show, but user-space cannot alter these registers.
// An example of this would be the segment selectors for x86.
//
// These structures/functions are roughly in-sync with the source files inside
// of src/rt/arch/$arch. The only currently used function from those folders is
// the `rust_swap_registers` function, but that's only because for now segmented
// stacks are disabled.

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint };
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0 }; // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

// windows requires saving more registers (both general and XMM), so the windows
// register context must be larger.
#[cfg(windows, target_arch = "x86_64")]
type Registers = [uint, ..34];
#[cfg(not(windows), target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(windows, target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 34]) }
#[cfg(not(windows), target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {

    // Redefinitions from rt/arch/x86_64/regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr {}", fptr);
    rtdebug!("arg {}", arg);
    rtdebug!("sp {}", sp);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {
    let sp = align_down(sp);
    // sp of arm eabi is 8-byte aligned
    let sp = mut_offset(sp, -2);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
                         sp: *mut uint) {
    let sp = align_down(sp);
    // sp of mips o32 is 8-byte aligned
    let sp = mut_offset(sp, -2);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[25] = fptr as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp: uint = transmute(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// ptr::mut_offset is positive ints only
#[inline]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use std::mem::size_of;
    (ptr as int + count * (size_of::<T>() as int)) as *mut T
}
<|endoftext|>


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

#[allow(dead_code)]
static X: &'static str = &*"";
fn main() {}
<|endoftext|>


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

#![feature(box_syntax)]

struct Node<T: ?Sized>(T);

fn main() {
    let x: Box<Node<[isize]>> = box Node([]);
}
<|endoftext|>


<commit_before><commit_msg>fix some doc<commit_after><|endoftext|>


<commit_before><commit_msg>fix entity upgrade<commit_after><|endoftext|>


<commit_before><commit_msg>Implement Changing Keybindings w/ set -o<commit_after><|endoftext|>


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

extern crate rustfmt;
extern crate diff;
extern crate regex;
extern crate term;

use std::collections::HashMap;
use std::fs;
use std::io::{self, Read, BufRead, BufReader};
use std::path::{Path, PathBuf};

use rustfmt::*;
use rustfmt::filemap::{write_system_newlines, FileMap};
use rustfmt::config::{Config, ReportTactic};
use rustfmt::rustfmt_diff::*;

const DIFF_CONTEXT_SIZE: usize = 3;

fn get_path_string(dir_entry: io::Result<fs::DirEntry>) -> String {
    let path = dir_entry.expect("Couldn't get DirEntry").path();

    path.to_str().expect("Couldn't stringify path").to_owned()
}

// Integration tests. The files in the tests/source are formatted and compared
// to their equivalent in tests/target. The target file and config can be
// overriden by annotations in the source file. The input and output must match
// exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at
// least report.
#[test]
fn system_tests() {
    // Get all files in the tests/source directory.
    let files = fs::read_dir("tests/source").expect("Couldn't read source dir");
    // Turn a DirEntry into a String that represents the relative path to the
    // file.
    let files = files.map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    // Display results.
    println!("Ran {} system tests.", count);
    assert!(fails == 0, "{} system tests failed", fails);
}

// Do the same for tests/coverage-source directory
// the only difference is the coverage mode
#[test]
fn coverage_tests() {
    let files = fs::read_dir("tests/coverage/source").expect("Couldn't read source dir");
    let files = files.map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    println!("Ran {} tests in coverage mode.", count);
    assert!(fails == 0, "{} tests failed", fails);
}

#[test]
fn checkstyle_test() {
    let filename = "tests/writemode/source/fn-single-line.rs";
    let expected_filename = "tests/writemode/target/checkstyle.xml";
    assert_output(filename, expected_filename);
}

// Helper function for comparing the results of rustfmt
// to a known output file generated by one of the write modes.
fn assert_output(source: &str, expected_filename: &str) {
    let config = read_config(&source);
    let (file_map, _report) = format_file(source, &config);

    // Populate output by writing to a vec.
    let mut out = vec![];
    let _ = filemap::write_all_files(&file_map, &mut out, &config);
    let output = String::from_utf8(out).unwrap();

    let mut expected_file = fs::File::open(&expected_filename).expect("Couldn't open target");
    let mut expected_text = String::new();
    expected_file.read_to_string(&mut expected_text)
        .expect("Failed reading target");

    let compare = make_diff(&expected_text, &output, DIFF_CONTEXT_SIZE);
    if compare.len() > 0 {
        let mut failures = HashMap::new();
        failures.insert(source.to_string(), compare);
        print_mismatches(failures);
        assert!(false, "Text does not match expected output");
    }
}

// Idempotence tests. Files in tests/target are checked to be unaltered by
// rustfmt.
#[test]
fn idempotence_tests() {
    // Get all files in the tests/target directory.
    let files = fs::read_dir("tests/target")
        .expect("Couldn't read target dir")
        .map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    // Display results.
    println!("Ran {} idempotent tests.", count);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Run rustfmt on itself. This operation must be idempotent. We also check that
// no warnings are emitted.
#[test]
fn self_tests() {
    let files = fs::read_dir("src/bin")
        .expect("Couldn't read src dir")
        .chain(fs::read_dir("tests").expect("Couldn't read tests dir"))
        .map(get_path_string);
    // Hack because there's no `IntoIterator` impl for `[T; N]`.
    let files = files.chain(Some("src/lib.rs".to_owned()).into_iter());
    let files = files.chain(Some("build.rs".to_owned()).into_iter());

    let (reports, count, fails) = check_files(files);
    let mut warnings = 0;

    // Display results.
    println!("Ran {} self tests.", count);
    assert!(fails == 0, "{} self tests failed", fails);

    for format_report in reports {
        println!("{}", format_report);
        warnings += format_report.warning_count();
    }

    assert!(warnings == 0,
            "Rustfmt's code generated {} warnings",
            warnings);
}

#[test]
fn stdin_formatting_smoke_test() {
    let input = Input::Text("fn main () {}".to_owned());
    let config = Config::default();
    let (error_summary, file_map, _report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    assert!(error_summary.has_no_errors());
    for &(ref file_name, ref text) in &file_map {
        if file_name == "stdin" {
            assert!(text.to_string() == "fn main() {}\n");
            return;
        }
    }
    panic!("no stdin");
}

#[test]
fn format_lines_errors_are_reported() {
    let long_identifier = String::from_utf8(vec![b'a'; 239]).unwrap();
    let input = Input::Text(format!("fn {}() {{}}", long_identifier));
    let config = Config::default();
    let (error_summary, _file_map, _report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    assert!(error_summary.has_formatting_errors());
}

// For each file, run rustfmt and collect the output.
// Returns the number of files checked and the number of failures.
fn check_files<I>(files: I) -> (Vec<FormatReport>, u32, u32)
    where I: Iterator<Item = String>
{
    let mut count = 0;
    let mut fails = 0;
    let mut reports = vec![];

    for file_name in files.filter(|f| f.ends_with(".rs")) {
        println!("Testing '{}'...", file_name);

        match idempotent_check(file_name) {
            Ok(report) => reports.push(report),
            Err(msg) => {
                print_mismatches(msg);
                fails += 1;
            }
        }

        count += 1;
    }

    (reports, count, fails)
}

fn print_mismatches(result: HashMap<String, Vec<Mismatch>>) {
    let mut t = term::stdout().unwrap();

    for (file_name, diff) in result {
        print_diff(diff,
                   |line_num| format!("\nMismatch at {}:{}:", file_name, line_num));
    }

    t.reset().unwrap();
}

fn read_config(filename: &str) -> Config {
    let sig_comments = read_significant_comments(&filename);
    let mut config = if !sig_comments.is_empty() {
        get_config(sig_comments.get("config").map(|x| &(*x)[..]))
    } else {
        get_config(Path::new(filename).with_extension("toml").file_name().and_then(std::ffi::OsStr::to_str))
    };

    for (key, val) in &sig_comments {
        if key != "target" && key != "config" {
            config.override_value(key, val);
        }
    }

    // Don't generate warnings for to-do items.
    config.report_todo = ReportTactic::Never;

    config
}

fn format_file<P: Into<PathBuf>>(filename: P, config: &Config) -> (FileMap, FormatReport) {
    let input = Input::File(filename.into());
    let (_error_summary, file_map, report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    return (file_map, report);
}

pub fn idempotent_check(filename: String) -> Result<FormatReport, HashMap<String, Vec<Mismatch>>> {
    let sig_comments = read_significant_comments(&filename);
    let config = read_config(&filename);
    let (file_map, format_report) = format_file(filename, &config);

    let mut write_result = HashMap::new();
    for &(ref filename, ref text) in &file_map {
        let mut v = Vec::new();
        // Won't panic, as we're not doing any IO.
        write_system_newlines(&mut v, text, &config).unwrap();
        // Won't panic, we are writing correct utf8.
        let one_result = String::from_utf8(v).unwrap();
        write_result.insert(filename.clone(), one_result);
    }

    let target = sig_comments.get("target").map(|x| &(*x)[..]);

    handle_result(write_result, target).map(|_| format_report)
}

// Reads test config file from comments and reads its contents.
fn get_config(config_file: Option<&str>) -> Config {
    let config_file_name = match config_file {
        None => return Default::default(),
        Some(file_name) => {
            let mut full_path = "tests/config/".to_owned();
            full_path.push_str(&file_name);
            if !Path::new(&full_path).exists() {
                return Default::default();
            };
            full_path
        }
    };

    let mut def_config_file = fs::File::open(config_file_name).expect("Couldn't open config");
    let mut def_config = String::new();
    def_config_file.read_to_string(&mut def_config).expect("Couldn't read config");

    Config::from_toml(&def_config)
}

// Reads significant comments of the form: // rustfmt-key: value
// into a hash map.
fn read_significant_comments(file_name: &str) -> HashMap<String, String> {
    let file = fs::File::open(file_name).expect(&format!("Couldn't read file {}", file_name));
    let reader = BufReader::new(file);
    let pattern = r"^\s*//\s*rustfmt-([^:]+):\s*(\S+)";
    let regex = regex::Regex::new(&pattern).expect("Failed creating pattern 1");

    // Matches lines containing significant comments or whitespace.
    let line_regex = regex::Regex::new(r"(^\s*$)|(^\s*//\s*rustfmt-[^:]+:\s*\S+)")
        .expect("Failed creating pattern 2");

    reader.lines()
        .map(|line| line.expect("Failed getting line"))
        .take_while(|line| line_regex.is_match(&line))
        .filter_map(|line| {
            regex.captures_iter(&line).next().map(|capture| {
                (capture.at(1).expect("Couldn't unwrap capture").to_owned(),
                 capture.at(2).expect("Couldn't unwrap capture").to_owned())
            })
        })
        .collect()
}

// Compare output to input.
// TODO: needs a better name, more explanation.
fn handle_result(result: HashMap<String, String>,
                 target: Option<&str>)
                 -> Result<(), HashMap<String, Vec<Mismatch>>> {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        // If file is in tests/source, compare to file with same name in tests/target.
        let target = get_target(&file_name, target);
        let mut f = fs::File::open(&target).expect("Couldn't open target");

        let mut text = String::new();
        f.read_to_string(&mut text).expect("Failed reading target");

        if fmt_text != text {
            let diff = make_diff(&text, &fmt_text, DIFF_CONTEXT_SIZE);
            assert!(!diff.is_empty(),
                    "Empty diff? Maybe due to a missing a newline at the end of a file?");
            failures.insert(file_name, diff);
        }
    }

    if failures.is_empty() {
        Ok(())
    } else {
        Err(failures)
    }
}

// Map source file paths to their target paths.
fn get_target(file_name: &str, target: Option<&str>) -> String {
    if file_name.contains("source") {
        let target_file_name = file_name.replace("source", "target");
        if let Some(replace_name) = target {
            Path::new(&target_file_name)
                .with_file_name(replace_name)
                .into_os_string()
                .into_string()
                .unwrap()
        } else {
            target_file_name
        }
    } else {
        // This is either and idempotence check or a self check
        file_name.to_owned()
    }
}

#[test]
fn rustfmt_diff_make_diff_tests() {
    let diff = make_diff("a\nb\nc\nd", "a\ne\nc\nd", 3);
    assert_eq!(diff,
               vec![Mismatch {
                        line_number: 1,
                        lines: vec![DiffLine::Context("a".into()),
                                    DiffLine::Resulting("b".into()),
                                    DiffLine::Expected("e".into()),
                                    DiffLine::Context("c".into()),
                                    DiffLine::Context("d".into())],
                    }]);
}
<commit_msg>Reformat the source to actually pass the tests!<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate rustfmt;
extern crate diff;
extern crate regex;
extern crate term;

use std::collections::HashMap;
use std::fs;
use std::io::{self, Read, BufRead, BufReader};
use std::path::{Path, PathBuf};

use rustfmt::*;
use rustfmt::filemap::{write_system_newlines, FileMap};
use rustfmt::config::{Config, ReportTactic};
use rustfmt::rustfmt_diff::*;

const DIFF_CONTEXT_SIZE: usize = 3;

fn get_path_string(dir_entry: io::Result<fs::DirEntry>) -> String {
    let path = dir_entry.expect("Couldn't get DirEntry").path();

    path.to_str().expect("Couldn't stringify path").to_owned()
}

// Integration tests. The files in the tests/source are formatted and compared
// to their equivalent in tests/target. The target file and config can be
// overriden by annotations in the source file. The input and output must match
// exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at
// least report.
#[test]
fn system_tests() {
    // Get all files in the tests/source directory.
    let files = fs::read_dir("tests/source").expect("Couldn't read source dir");
    // Turn a DirEntry into a String that represents the relative path to the
    // file.
    let files = files.map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    // Display results.
    println!("Ran {} system tests.", count);
    assert!(fails == 0, "{} system tests failed", fails);
}

// Do the same for tests/coverage-source directory
// the only difference is the coverage mode
#[test]
fn coverage_tests() {
    let files = fs::read_dir("tests/coverage/source").expect("Couldn't read source dir");
    let files = files.map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    println!("Ran {} tests in coverage mode.", count);
    assert!(fails == 0, "{} tests failed", fails);
}

#[test]
fn checkstyle_test() {
    let filename = "tests/writemode/source/fn-single-line.rs";
    let expected_filename = "tests/writemode/target/checkstyle.xml";
    assert_output(filename, expected_filename);
}

// Helper function for comparing the results of rustfmt
// to a known output file generated by one of the write modes.
fn assert_output(source: &str, expected_filename: &str) {
    let config = read_config(&source);
    let (file_map, _report) = format_file(source, &config);

    // Populate output by writing to a vec.
    let mut out = vec![];
    let _ = filemap::write_all_files(&file_map, &mut out, &config);
    let output = String::from_utf8(out).unwrap();

    let mut expected_file = fs::File::open(&expected_filename).expect("Couldn't open target");
    let mut expected_text = String::new();
    expected_file.read_to_string(&mut expected_text)
        .expect("Failed reading target");

    let compare = make_diff(&expected_text, &output, DIFF_CONTEXT_SIZE);
    if compare.len() > 0 {
        let mut failures = HashMap::new();
        failures.insert(source.to_string(), compare);
        print_mismatches(failures);
        assert!(false, "Text does not match expected output");
    }
}

// Idempotence tests. Files in tests/target are checked to be unaltered by
// rustfmt.
#[test]
fn idempotence_tests() {
    // Get all files in the tests/target directory.
    let files = fs::read_dir("tests/target")
        .expect("Couldn't read target dir")
        .map(get_path_string);
    let (_reports, count, fails) = check_files(files);

    // Display results.
    println!("Ran {} idempotent tests.", count);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Run rustfmt on itself. This operation must be idempotent. We also check that
// no warnings are emitted.
#[test]
fn self_tests() {
    let files = fs::read_dir("src/bin")
        .expect("Couldn't read src dir")
        .chain(fs::read_dir("tests").expect("Couldn't read tests dir"))
        .map(get_path_string);
    // Hack because there's no `IntoIterator` impl for `[T; N]`.
    let files = files.chain(Some("src/lib.rs".to_owned()).into_iter());
    let files = files.chain(Some("build.rs".to_owned()).into_iter());

    let (reports, count, fails) = check_files(files);
    let mut warnings = 0;

    // Display results.
    println!("Ran {} self tests.", count);
    assert!(fails == 0, "{} self tests failed", fails);

    for format_report in reports {
        println!("{}", format_report);
        warnings += format_report.warning_count();
    }

    assert!(warnings == 0,
            "Rustfmt's code generated {} warnings",
            warnings);
}

#[test]
fn stdin_formatting_smoke_test() {
    let input = Input::Text("fn main () {}".to_owned());
    let config = Config::default();
    let (error_summary, file_map, _report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    assert!(error_summary.has_no_errors());
    for &(ref file_name, ref text) in &file_map {
        if file_name == "stdin" {
            assert!(text.to_string() == "fn main() {}\n");
            return;
        }
    }
    panic!("no stdin");
}

#[test]
fn format_lines_errors_are_reported() {
    let long_identifier = String::from_utf8(vec![b'a'; 239]).unwrap();
    let input = Input::Text(format!("fn {}() {{}}", long_identifier));
    let config = Config::default();
    let (error_summary, _file_map, _report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    assert!(error_summary.has_formatting_errors());
}

// For each file, run rustfmt and collect the output.
// Returns the number of files checked and the number of failures.
fn check_files<I>(files: I) -> (Vec<FormatReport>, u32, u32)
    where I: Iterator<Item = String>
{
    let mut count = 0;
    let mut fails = 0;
    let mut reports = vec![];

    for file_name in files.filter(|f| f.ends_with(".rs")) {
        println!("Testing '{}'...", file_name);

        match idempotent_check(file_name) {
            Ok(report) => reports.push(report),
            Err(msg) => {
                print_mismatches(msg);
                fails += 1;
            }
        }

        count += 1;
    }

    (reports, count, fails)
}

fn print_mismatches(result: HashMap<String, Vec<Mismatch>>) {
    let mut t = term::stdout().unwrap();

    for (file_name, diff) in result {
        print_diff(diff,
                   |line_num| format!("\nMismatch at {}:{}:", file_name, line_num));
    }

    t.reset().unwrap();
}

fn read_config(filename: &str) -> Config {
    let sig_comments = read_significant_comments(&filename);
    let mut config = if !sig_comments.is_empty() {
        get_config(sig_comments.get("config").map(|x| &(*x)[..]))
    } else {
        get_config(Path::new(filename)
            .with_extension("toml")
            .file_name()
            .and_then(std::ffi::OsStr::to_str))
    };

    for (key, val) in &sig_comments {
        if key != "target" && key != "config" {
            config.override_value(key, val);
        }
    }

    // Don't generate warnings for to-do items.
    config.report_todo = ReportTactic::Never;

    config
}

fn format_file<P: Into<PathBuf>>(filename: P, config: &Config) -> (FileMap, FormatReport) {
    let input = Input::File(filename.into());
    let (_error_summary, file_map, report) = format_input::<io::Stdout>(input, &config, None)
        .unwrap();
    return (file_map, report);
}

pub fn idempotent_check(filename: String) -> Result<FormatReport, HashMap<String, Vec<Mismatch>>> {
    let sig_comments = read_significant_comments(&filename);
    let config = read_config(&filename);
    let (file_map, format_report) = format_file(filename, &config);

    let mut write_result = HashMap::new();
    for &(ref filename, ref text) in &file_map {
        let mut v = Vec::new();
        // Won't panic, as we're not doing any IO.
        write_system_newlines(&mut v, text, &config).unwrap();
        // Won't panic, we are writing correct utf8.
        let one_result = String::from_utf8(v).unwrap();
        write_result.insert(filename.clone(), one_result);
    }

    let target = sig_comments.get("target").map(|x| &(*x)[..]);

    handle_result(write_result, target).map(|_| format_report)
}

// Reads test config file from comments and reads its contents.
fn get_config(config_file: Option<&str>) -> Config {
    let config_file_name = match config_file {
        None => return Default::default(),
        Some(file_name) => {
            let mut full_path = "tests/config/".to_owned();
            full_path.push_str(&file_name);
            if !Path::new(&full_path).exists() {
                return Default::default();
            };
            full_path
        }
    };

    let mut def_config_file = fs::File::open(config_file_name).expect("Couldn't open config");
    let mut def_config = String::new();
    def_config_file.read_to_string(&mut def_config).expect("Couldn't read config");

    Config::from_toml(&def_config)
}

// Reads significant comments of the form: // rustfmt-key: value
// into a hash map.
fn read_significant_comments(file_name: &str) -> HashMap<String, String> {
    let file = fs::File::open(file_name).expect(&format!("Couldn't read file {}", file_name));
    let reader = BufReader::new(file);
    let pattern = r"^\s*//\s*rustfmt-([^:]+):\s*(\S+)";
    let regex = regex::Regex::new(&pattern).expect("Failed creating pattern 1");

    // Matches lines containing significant comments or whitespace.
    let line_regex = regex::Regex::new(r"(^\s*$)|(^\s*//\s*rustfmt-[^:]+:\s*\S+)")
        .expect("Failed creating pattern 2");

    reader.lines()
        .map(|line| line.expect("Failed getting line"))
        .take_while(|line| line_regex.is_match(&line))
        .filter_map(|line| {
            regex.captures_iter(&line).next().map(|capture| {
                (capture.at(1).expect("Couldn't unwrap capture").to_owned(),
                 capture.at(2).expect("Couldn't unwrap capture").to_owned())
            })
        })
        .collect()
}

// Compare output to input.
// TODO: needs a better name, more explanation.
fn handle_result(result: HashMap<String, String>,
                 target: Option<&str>)
                 -> Result<(), HashMap<String, Vec<Mismatch>>> {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        // If file is in tests/source, compare to file with same name in tests/target.
        let target = get_target(&file_name, target);
        let mut f = fs::File::open(&target).expect("Couldn't open target");

        let mut text = String::new();
        f.read_to_string(&mut text).expect("Failed reading target");

        if fmt_text != text {
            let diff = make_diff(&text, &fmt_text, DIFF_CONTEXT_SIZE);
            assert!(!diff.is_empty(),
                    "Empty diff? Maybe due to a missing a newline at the end of a file?");
            failures.insert(file_name, diff);
        }
    }

    if failures.is_empty() {
        Ok(())
    } else {
        Err(failures)
    }
}

// Map source file paths to their target paths.
fn get_target(file_name: &str, target: Option<&str>) -> String {
    if file_name.contains("source") {
        let target_file_name = file_name.replace("source", "target");
        if let Some(replace_name) = target {
            Path::new(&target_file_name)
                .with_file_name(replace_name)
                .into_os_string()
                .into_string()
                .unwrap()
        } else {
            target_file_name
        }
    } else {
        // This is either and idempotence check or a self check
        file_name.to_owned()
    }
}

#[test]
fn rustfmt_diff_make_diff_tests() {
    let diff = make_diff("a\nb\nc\nd", "a\ne\nc\nd", 3);
    assert_eq!(diff,
               vec![Mismatch {
                        line_number: 1,
                        lines: vec![DiffLine::Context("a".into()),
                                    DiffLine::Resulting("b".into()),
                                    DiffLine::Expected("e".into()),
                                    DiffLine::Context("c".into()),
                                    DiffLine::Context("d".into())],
                    }]);
}
<|endoftext|>


<commit_before><commit_msg>Revert "docs(examples): De-duplicate subcommand examples"<commit_after>// Working with subcommands is simple. There are a few key points to remember when working with
// subcommands in clap. First, Subcommands are really just Apps. This means they can have their own
// settings, version, authors, args, and even their own subcommands. The next thing to remember is
// that subcommands are set up in a tree like hierarchy.
//
// An ASCII art depiction may help explain this better. Using a fictional version of git as the demo
// subject. Imagine the following are all subcommands of git (note, the author is aware these aren't
// actually all subcommands in the real git interface, but it makes explanation easier)
//
//            Top Level App (git)                         TOP
//                           |
//    -----------------------------------------
//   /             |                \          \
// clone          push              add       commit      LEVEL 1
//   |           /    \            /    \       |
//  url      origin   remote    ref    name   message     LEVEL 2
//           /                  /\
//        path            remote  local                   LEVEL 3
//
// Given the above fictional subcommand hierarchy, valid runtime uses would be (not an all inclusive
// list):
//
// $ git clone url
// $ git push origin path
// $ git add ref local
// $ git commit message
//
// Notice only one command per "level" may be used. You could not, for example, do:
//
// $ git clone url push origin path
//
// It's also important to know that subcommands each have their own set of matches and may have args
// with the same name as other subcommands in a different part of the tree hierarchy (i.e. the arg
// names aren't in a flat namespace).
//
// In order to use subcommands in clap, you only need to know which subcommand you're at in your
// tree, and which args are defined on that subcommand.
//
// Let's make a quick program to illustrate. We'll be using the same example as above but for
// brevity sake we won't implement all of the subcommands, only a few.

use clap::{App, AppSettings, Arg};

fn main() {
    let matches = App::new("git")
        .about("A fictional versioning CLI")
        .version("1.0")
        .author("Me")
        .subcommand(
            App::new("clone")
                .about("clones repos")
                .arg(Arg::new("repo").about("The repo to clone").required(true)),
        )
        .subcommand(
            App::new("push")
                .about("pushes things")
                .setting(AppSettings::SubcommandRequiredElseHelp)
                .subcommand(
                    App::new("remote") // Subcommands can have their own subcommands,
                        // which in turn have their own subcommands
                        .about("pushes remote things")
                        .arg(
                            Arg::new("repo")
                                .required(true)
                                .about("The remote repo to push things to"),
                        ),
                )
                .subcommand(App::new("local").about("pushes local things")),
        )
        .subcommand(
            App::new("add")
                .about("adds things")
                .author("Someone Else") // Subcommands can list different authors
                .version("v2.0 (I'm versioned differently") // or different version from their parents
                .setting(AppSettings::ArgRequiredElseHelp) // They can even have different settings
                .arg(
                    Arg::new("stuff")
                        .long("stuff")
                        .about("Stuff to add")
                        .takes_value(true)
                        .multiple_occurrences(true),
                ),
        )
        .get_matches();

    // At this point, the matches we have point to git. Keep this in mind...

    // You can see which subcommand was used
    if let Some(subcommand) = matches.subcommand_name() {
        println!("'git {}' was used", subcommand);

        // It's important to note, this *only* check's git's DIRECT children, **NOT** it's
        // grandchildren, great grandchildren, etc.
        //
        // i.e. if the command `git push remove --stuff foo` was run, the above will only print out,
        // `git push` was used. We'd need to get push's matches to see further into the tree
    }

    // An alternative to checking the name is matching on known names. Again notice that only the
    // direct children are matched here.
    match matches.subcommand_name() {
        Some("clone") => println!("'git clone' was used"),
        Some("push") => println!("'git push' was used"),
        Some("add") => println!("'git add' was used"),
        None => println!("No subcommand was used"),
        _ => unreachable!(), // Assuming you've listed all direct children above, this is unreachable
    }

    // You could get the independent subcommand matches, although this is less common
    if let Some(clone_matches) = matches.subcommand_matches("clone") {
        // Now we have a reference to clone's matches
        println!("Cloning repo: {}", clone_matches.value_of("repo").unwrap());
    }

    // The most common way to handle subcommands is via a combined approach using
    // `ArgMatches::subcommand` which returns a tuple of both the name and matches
    match matches.subcommand() {
        Some(("clone", clone_matches)) => {
            // Now we have a reference to clone's matches
            println!("Cloning {}", clone_matches.value_of("repo").unwrap());
        }
        Some(("push", push_matches)) => {
            // Now we have a reference to push's matches
            match push_matches.subcommand() {
                Some(("remote", remote_matches)) => {
                    // Now we have a reference to remote's matches
                    println!("Pushing to {}", remote_matches.value_of("repo").unwrap());
                }
                Some(("local", _)) => {
                    println!("'git push local' was used");
                }
                _ => unreachable!(),
            }
        }
        Some(("add", add_matches)) => {
            // Now we have a reference to add's matches
            println!(
                "Adding {}",
                add_matches
                    .values_of("stuff")
                    .unwrap()
                    .collect::<Vec<_>>()
                    .join(", ")
            );
        }
        None => println!("No subcommand was used"), // If no subcommand was used it'll match the tuple ("", None)
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
    }

    // Continued program logic goes here...
}
<|endoftext|>


<commit_before>use runtime::Runtime;
use std::error::Error;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::fmt::Display;
use std::result::Result;
use std::collections::HashMap;

use storage::backend::{StorageBackend, StorageBackendError};

pub mod bm;

#[derive(Debug)]
pub struct ModuleError {
    desc: String,
}

impl ModuleError {
    fn mk(desc: &'static str) -> ModuleError {
        ModuleError {
            desc: desc.to_owned().to_string(),
        }
    }
}

impl Error for ModuleError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        None
    }

}

impl Display for ModuleError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "ModuleError: {}", self.description())
    }
}

pub type ModuleResult = Result<(), ModuleError>;
pub type CommandMap<'a> = HashMap<&'a str, fn(&Runtime, &StorageBackend)>;

pub trait Module {

    fn new(rt : &Runtime) -> Self;
    fn callnames() -> &'static [&'static str];
    fn name(&self) -> &'static str;
    fn shutdown(&self, rt : &Runtime) -> ModuleResult;

    fn get_commands(&self, rt: &Runtime) -> CommandMap;

}

<commit_msg>Fix: ModuleError::mk() -> pub ModuleError::new()<commit_after>use runtime::Runtime;
use std::error::Error;
use std::fmt::Formatter;
use std::fmt::Result as FMTResult;
use std::fmt::Display;
use std::result::Result;
use std::collections::HashMap;

use storage::backend::{StorageBackend, StorageBackendError};

pub mod bm;

#[derive(Debug)]
pub struct ModuleError {
    desc: String,
}

impl ModuleError {
    pub fn new(desc: &'static str) -> ModuleError {
        ModuleError {
            desc: desc.to_owned().to_string(),
        }
    }
}

impl Error for ModuleError {

    fn description(&self) -> &str {
        &self.desc[..]
    }

    fn cause(&self) -> Option<&Error> {
        None
    }

}

impl Display for ModuleError {
    fn fmt(&self, f: &mut Formatter) -> FMTResult {
        write!(f, "ModuleError: {}", self.description())
    }
}

pub type ModuleResult = Result<(), ModuleError>;
pub type CommandMap<'a> = HashMap<&'a str, fn(&Runtime, &StorageBackend)>;

pub trait Module {

    fn new(rt : &Runtime) -> Self;
    fn callnames() -> &'static [&'static str];
    fn name(&self) -> &'static str;
    fn shutdown(&self, rt : &Runtime) -> ModuleResult;

    fn get_commands(&self, rt: &Runtime) -> CommandMap;

}

<|endoftext|>


<commit_before><commit_msg>Add a simple trait for single time parsing<commit_after>use nom::IResult;

pub trait StreamProducer {
  fn parse<F, T>(&mut self, f: F) -> Result<T, ErrorKind>
   where F: FnOnce(&[u8]) -> IResult<&[u8], T>;
}
<|endoftext|>


<commit_before><commit_msg>Add else end and fn to grammar<commit_after><|endoftext|>


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

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail and cause
//! chain information:
//!
//! ```
//! trait Error: Send {
//!     fn description(&self) -> &str;
//!
//!     fn detail(&self) -> Option<String> { None }
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.
//!
//! The trait inherits from `Any` to allow *downcasting*: converting from a
//! trait object to a specific concrete type when applicable.
//!
//! # The `FromError` trait
//!
//! `FromError` is a simple trait that expresses conversions between different
//! error types. To provide maximum flexibility, it does not require either of
//! the types to actually implement the `Error` trait, although this will be the
//! common case.
//!
//! The main use of this trait is in the `try!` macro, which uses it to
//! automatically convert a given error to the error specified in a function's
//! return type.
//!
//! For example,
//!
//! ```
//! use std::error::FromError;
//! use std::io::{File, IoError};
//! use std::os::{MemoryMap, MapError};
//! use std::path::Path;
//!
//! enum MyError {
//!     Io(IoError),
//!     Map(MapError)
//! }
//!
//! impl FromError<IoError> for MyError {
//!     fn from_error(err: IoError) -> MyError {
//!         Io(err)
//!     }
//! }
//!
//! impl FromError<MapError> for MyError {
//!     fn from_error(err: MapError) -> MyError {
//!         Map(err)
//!     }
//! }
//!
//! #[allow(unused_variables)]
//! fn open_and_map() -> Result<(), MyError> {
//!     let f = try!(File::open(&Path::new("foo.txt")));
//!     let m = try!(MemoryMap::new(0, &[]));
//!     // do something interesting here...
//!     Ok(())
//! }
//! ```

use option::{Option, None};
use kinds::Send;
use string::String;

/// Base functionality for all errors in Rust.
pub trait Error: Send {
    /// A short description of the error; usually a static string.
    fn description(&self) -> &str;

    /// A detailed description of the error, usually including dynamic information.
    fn detail(&self) -> Option<String> { None }

    /// The lower-level cause of this error, if any.
    fn cause(&self) -> Option<&Error> { None }
}

/// A trait for types that can be converted from a given error type `E`.
pub trait FromError<E> {
    /// Perform the conversion.
    fn from_error(err: E) -> Self;
}

// Any type is convertable from itself
impl<E> FromError<E> for E {
    fn from_error(err: E) -> E {
        err
    }
}
<commit_msg>rollup merge of #18628 : aturon/fixup-error-comment<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.

//! Traits for working with Errors.
//!
//! # The `Error` trait
//!
//! `Error` is a trait representing the basic expectations for error values,
//! i.e. values of type `E` in `Result<T, E>`. At a minimum, errors must provide
//! a description, but they may optionally provide additional detail and cause
//! chain information:
//!
//! ```
//! trait Error: Send {
//!     fn description(&self) -> &str;
//!
//!     fn detail(&self) -> Option<String> { None }
//!     fn cause(&self) -> Option<&Error> { None }
//! }
//! ```
//!
//! The `cause` method is generally used when errors cross "abstraction
//! boundaries", i.e.  when a one module must report an error that is "caused"
//! by an error from a lower-level module. This setup makes it possible for the
//! high-level module to provide its own errors that do not commit to any
//! particular implementation, but also reveal some of its implementation for
//! debugging via `cause` chains.
//!
//! # The `FromError` trait
//!
//! `FromError` is a simple trait that expresses conversions between different
//! error types. To provide maximum flexibility, it does not require either of
//! the types to actually implement the `Error` trait, although this will be the
//! common case.
//!
//! The main use of this trait is in the `try!` macro, which uses it to
//! automatically convert a given error to the error specified in a function's
//! return type.
//!
//! For example,
//!
//! ```
//! use std::error::FromError;
//! use std::io::{File, IoError};
//! use std::os::{MemoryMap, MapError};
//! use std::path::Path;
//!
//! enum MyError {
//!     Io(IoError),
//!     Map(MapError)
//! }
//!
//! impl FromError<IoError> for MyError {
//!     fn from_error(err: IoError) -> MyError {
//!         Io(err)
//!     }
//! }
//!
//! impl FromError<MapError> for MyError {
//!     fn from_error(err: MapError) -> MyError {
//!         Map(err)
//!     }
//! }
//!
//! #[allow(unused_variables)]
//! fn open_and_map() -> Result<(), MyError> {
//!     let f = try!(File::open(&Path::new("foo.txt")));
//!     let m = try!(MemoryMap::new(0, &[]));
//!     // do something interesting here...
//!     Ok(())
//! }
//! ```

use option::{Option, None};
use kinds::Send;
use string::String;

/// Base functionality for all errors in Rust.
pub trait Error: Send {
    /// A short description of the error; usually a static string.
    fn description(&self) -> &str;

    /// A detailed description of the error, usually including dynamic information.
    fn detail(&self) -> Option<String> { None }

    /// The lower-level cause of this error, if any.
    fn cause(&self) -> Option<&Error> { None }
}

/// A trait for types that can be converted from a given error type `E`.
pub trait FromError<E> {
    /// Perform the conversion.
    fn from_error(err: E) -> Self;
}

// Any type is convertable from itself
impl<E> FromError<E> for E {
    fn from_error(err: E) -> E {
        err
    }
}
<|endoftext|>


<commit_before><commit_msg>Added match bindings example<commit_after>// A function `age` which returns a `u32`.
fn age() -> u32 {
    15
}

fn main() {
    println!("Tell me type of person you are");

    match age() {
        0             => println!("I'm not born yet I guess"),
        // Could `match` 1 ... 12 directly but then what age
        // would the child be? Instead, bind to `n` for the
        // sequence of 1 .. 12. Now the age can be reported.
        n @ 1  ... 12 => println!("I'm a child of age {:?}", n),
        n @ 13 ... 19 => println!("I'm a teen of age {:?}", n),
        // Nothing bound. Return the result.
        n             => println!("I'm an old person of age {:?}", n),
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor: reorg code a little bit<commit_after><|endoftext|>


<commit_before>//! HTTP Server
use std::io::net::tcp::{TcpListener, TcpAcceptor};
use std::io::{Acceptor, Listener, IoResult, EndOfFile};
use std::io::net::ip::{IpAddr, Port, SocketAddr};

pub use self::request::Request;
pub use self::response::Response;

pub mod request;
pub mod response;

/// A server can listen on a TCP socket.
///
/// Once listening, it will create a `Request`/`Response` pair for each
/// incoming connection, and hand them to the provided handler.
pub struct Server {
    ip: IpAddr,
    port: Port
}

impl Server {

    /// Creates a server to be used for `http` conenctions.
    pub fn http(ip: IpAddr, port: Port) -> Server {
        Server {
            ip: ip,
            port: port
        }
    }

    /// Binds to a socket, and starts handling connections.
    pub fn listen<H: Handler + 'static>(self, mut handler: H) -> IoResult<Listening> {
        let mut listener = try!(TcpListener::bind(self.ip.to_string().as_slice(), self.port));
        let socket = try!(listener.socket_name());
        let acceptor = try!(listener.listen());
        let worker = acceptor.clone();

        spawn(proc() {
            let mut acceptor = worker;
            for conn in acceptor.incoming() {
                match conn {
                    Ok(stream) => {
                        debug!("Incoming stream");
                        let clone = stream.clone();
                        let req = match Request::new(stream) {
                            Ok(r) => r,
                            Err(err) => {
                                error!("creating Request: {}", err);
                                continue;
                            }
                        };
                        let mut res = Response::new(clone);
                        res.version = req.version;
                        match handler.handle(req, res) {
                            Ok(..) => debug!("Stream handled"),
                            Err(e) => {
                                error!("Error from handler: {}", e)
                                //TODO try to send a status code
                            }
                        }
                    },
                    Err(ref e) if e.kind == EndOfFile => break, // server closed
                    Err(e) => {
                        error!("Connection failed: {}", e);
                    }
                }
            }
        });

        Ok(Listening {
            acceptor: acceptor,
            socket_addr: socket,
        })
    }

}

/// A listening server, which can later be closed.
pub struct Listening {
    acceptor: TcpAcceptor,
    /// The socket address that the server is bound to.
    pub socket_addr: SocketAddr,
}

impl Listening {
    /// Stop the server from listening to it's socket address.
    pub fn close(mut self) -> IoResult<()> {
        debug!("closing server");
        self.acceptor.close_accept()
    }
}

/// A handler that can handle incoming requests for a server.
pub trait Handler: Send {
    /// Receives a `Request`/`Response` pair, and should perform some action on them.
    ///
    /// This could reading from the request, and writing to the response.
    fn handle(&mut self, req: Request, res: Response) -> IoResult<()>;
}

impl Handler for fn(Request, Response) -> IoResult<()> {
    fn handle(&mut self, req: Request, res: Response) -> IoResult<()> {
        (*self)(req, res)
    }
}
<commit_msg>Change the Handler trait to receive an Iterator of (Request, Response) pairs.<commit_after>//! HTTP Server
use std::io::net::tcp::{TcpListener, TcpAcceptor};
use std::io::{Acceptor, Listener, IoResult, EndOfFile, IncomingConnections};
use std::io::net::ip::{IpAddr, Port, SocketAddr};

pub use self::request::Request;
pub use self::response::Response;

pub mod request;
pub mod response;

/// A server can listen on a TCP socket.
///
/// Once listening, it will create a `Request`/`Response` pair for each
/// incoming connection, and hand them to the provided handler.
pub struct Server {
    ip: IpAddr,
    port: Port
}

impl Server {

    /// Creates a server to be used for `http` conenctions.
    pub fn http(ip: IpAddr, port: Port) -> Server {
        Server {
            ip: ip,
            port: port
        }
    }

    /// Binds to a socket, and starts handling connections.
    pub fn listen<H: Handler + 'static>(self, handler: H) -> IoResult<Listening> {
        let mut listener = try!(TcpListener::bind(self.ip.to_string().as_slice(), self.port));
        let socket = try!(listener.socket_name());
        let acceptor = try!(listener.listen());
        let worker = acceptor.clone();

        spawn(proc() {
            let mut acceptor = worker;
            handler.handle(Incoming { from: acceptor.incoming() });
        });

        Ok(Listening {
            acceptor: acceptor,
            socket_addr: socket,
        })
    }

}

/// An iterator over incoming connections, represented as pairs of
/// hyper Requests and Responses.
pub struct Incoming<'a> {
    from: IncomingConnections<'a, TcpAcceptor>
}

impl<'a> Iterator<(Request, Response)> for Incoming<'a> {
    fn next(&mut self) -> Option<(Request, Response)> {
        for conn in self.from {
            match conn {
                Ok(stream) => {
                    debug!("Incoming stream");
                    let clone = stream.clone();
                    let req = match Request::new(stream) {
                        Ok(r) => r,
                        Err(err) => {
                            error!("creating Request: {}", err);
                            continue;
                        }
                    };
                    let mut res = Response::new(clone);
                    res.version = req.version;
                    return Some((req, res))
                },
                Err(ref e) if e.kind == EndOfFile => return None, // server closed
                Err(e) => {
                    error!("Connection failed: {}", e);
                    continue;
                }
            }
        }
        None
    }
}

/// A listening server, which can later be closed.
pub struct Listening {
    acceptor: TcpAcceptor,
    /// The socket address that the server is bound to.
    pub socket_addr: SocketAddr,
}

impl Listening {
    /// Stop the server from listening to it's socket address.
    pub fn close(mut self) -> IoResult<()> {
        debug!("closing server");
        self.acceptor.close_accept()
    }
}

/// A handler that can handle incoming requests for a server.
pub trait Handler: Send {
    /// Receives a `Request`/`Response` pair, and should perform some action on them.
    ///
    /// This could reading from the request, and writing to the response.
    fn handle(self, Incoming);
}

impl Handler for fn(Incoming) {
    fn handle(self, incoming: Incoming) {
        (self)(incoming)
    }
}

<|endoftext|>


<commit_before><commit_msg>Added Rot-13<commit_after>fn rot13 (string: ~str) -> ~str {
	fn rot13u8 (c: u8) -> u8 {
		match c {
			97..109 => c+13,
			65..77 => c+13,
			110..122 => c-13,
			78..90 => c-13,
			_ => c
		}
	}
	std::str::from_utf8_owned(string.as_bytes().map(|c| rot13u8(*c))).unwrap()
}

fn main () {
	let a =  rot13(~"abc");
	assert_eq!(a, ~"nop");
}<|endoftext|>


<commit_before><commit_msg>tuple like structure added<commit_after><|endoftext|>


<commit_before>use errors::crypto::CryptoError;

extern crate openssl;

use self::openssl::bn::{BigNum, BigNumRef, BigNumContext, MSB_MAYBE_ZERO};
use self::openssl::error::ErrorStack;
use self::openssl::hash::{hash, MessageDigest};
use std::cmp::Ord;
use std::cmp::Ordering;

use std::error::Error;

pub struct BigNumberContext {
    openssl_bn_context: BigNumContext
}

#[derive(Debug)]
pub struct BigNumber {
    openssl_bn: BigNum
}

impl BigNumber {
    pub fn new_context() -> Result<BigNumberContext, CryptoError> {
        let ctx = try!(BigNumContext::new());
        Ok(BigNumberContext {
            openssl_bn_context: ctx
        })
    }

    pub fn new() -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::new());
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn safe_prime(&self, size: usize) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::generate_prime(&mut bn.openssl_bn, size as i32, true, None, None));
        Ok(bn)
    }

    pub fn rand(&self, size: usize) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::rand(&mut bn.openssl_bn, size as i32, MSB_MAYBE_ZERO, false));
        Ok(bn)
    }

    pub fn rand_range(&self) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::rand_range(&self.openssl_bn, &mut bn.openssl_bn));
        Ok(bn)
    }

    pub fn from_u32(n: u32) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_u32(n));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_dec(dec: &str) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_dec_str(dec));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_hex(hex: &str) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_hex_str(hex));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_slice(bytes));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn to_dec(&self) -> Result<String, CryptoError> {
        let result = try!(self.openssl_bn.to_dec_str());
        Ok(result.to_string())
    }

    pub fn to_hex(&self) -> Result<String, CryptoError> {
        let result = try!(self.openssl_bn.to_hex_str());
        Ok(result.to_string())
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        Ok(self.openssl_bn.to_vec())
    }

    pub fn add(&self, a: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::checked_add(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn));
        Ok(bn)
    }

    pub fn sub(&self, a: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::checked_sub(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn));
        Ok(bn)
    }

    pub fn mul(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::checked_mul(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::checked_mul(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn div(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::checked_div(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::checked_div(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn add_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::add_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn sub_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::sub_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn mul_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::mul_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn div_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::div_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn mod_exp(&self, a: &BigNumber, b: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::mod_exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &b.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::mod_exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &b.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn modulus(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::nnmod(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::nnmod(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn exp(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn inverse(&self, n: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::mod_inverse(&mut bn.openssl_bn, &self.openssl_bn, &n.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::mod_inverse(&mut bn.openssl_bn, &self.openssl_bn, &n.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn mod_div(&self, b: &BigNumber, p: &BigNumber) -> Result<BigNumber, CryptoError> {
        //(a*  (1/b mod p) mod p)

        let mut context = try!(BigNumber::new_context());

        let mut res = try!(b.inverse(p, Some(&mut context)));
        res = try!(self.mul(&res, Some(&mut context)));
        res = try!(res.modulus(&p, Some(&mut context)));
        Ok(res)
    }

    pub fn compare(&self, other: &BigNumber) -> bool {
        self.openssl_bn == other.openssl_bn
    }

    pub fn clone(&self) -> Result<BigNumber, CryptoError> {
        let bytes = try!(self.to_bytes());
        let mut bn = try!(BigNumber::from_bytes(bytes.as_slice()));
        Ok(bn)
    }
}

impl Ord for BigNumber {
    fn cmp(&self, other: &BigNumber) -> Ordering {
        self.openssl_bn.ucmp(&other.openssl_bn)
    }
}

impl Eq for BigNumber {}

impl PartialOrd for BigNumber {
    fn partial_cmp(&self, other: &BigNumber) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for BigNumber {
    fn eq(&self, other: &BigNumber) -> bool {
        self.openssl_bn == other.openssl_bn
    }
}

impl From<ErrorStack> for CryptoError {
    fn from(err: ErrorStack) -> CryptoError {
        CryptoError::CryptoBackendError(err.description().to_string())
    }
}
<commit_msg>Small refactoring<commit_after>use errors::crypto::CryptoError;

extern crate openssl;

use self::openssl::bn::{BigNum, BigNumRef, BigNumContext, MSB_MAYBE_ZERO};
use self::openssl::error::ErrorStack;
use self::openssl::hash::{hash, MessageDigest};
use std::cmp::Ord;
use std::cmp::Ordering;

use std::error::Error;

pub struct BigNumberContext {
    openssl_bn_context: BigNumContext
}

#[derive(Debug)]
pub struct BigNumber {
    openssl_bn: BigNum
}

impl BigNumber {
    pub fn new_context() -> Result<BigNumberContext, CryptoError> {
        let ctx = try!(BigNumContext::new());
        Ok(BigNumberContext {
            openssl_bn_context: ctx
        })
    }

    pub fn new() -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::new());
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn safe_prime(&self, size: usize) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::generate_prime(&mut bn.openssl_bn, size as i32, true, None, None));
        Ok(bn)
    }

    pub fn rand(&self, size: usize) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::rand(&mut bn.openssl_bn, size as i32, MSB_MAYBE_ZERO, false));
        Ok(bn)
    }

    pub fn rand_range(&self) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::rand_range(&self.openssl_bn, &mut bn.openssl_bn));
        Ok(bn)
    }

    pub fn from_u32(n: u32) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_u32(n));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_dec(dec: &str) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_dec_str(dec));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_hex(hex: &str) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_hex_str(hex));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<BigNumber, CryptoError> {
        let bn = try!(BigNum::from_slice(bytes));
        Ok(BigNumber {
            openssl_bn: bn
        })
    }

    pub fn to_dec(&self) -> Result<String, CryptoError> {
        let result = try!(self.openssl_bn.to_dec_str());
        Ok(result.to_string())
    }

    pub fn to_hex(&self) -> Result<String, CryptoError> {
        let result = try!(self.openssl_bn.to_hex_str());
        Ok(result.to_string())
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        Ok(self.openssl_bn.to_vec())
    }

    pub fn add(&self, a: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::checked_add(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn));
        Ok(bn)
    }

    pub fn sub(&self, a: &BigNumber) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        try!(BigNumRef::checked_sub(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn));
        Ok(bn)
    }

    pub fn mul(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::checked_mul(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::checked_mul(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn div(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::checked_div(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::checked_div(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn add_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::add_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn sub_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::sub_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn mul_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::mul_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn div_word(&mut self, w: u32) -> Result<&mut BigNumber, CryptoError> {
        try!(BigNumRef::div_word(&mut self.openssl_bn, w));
        Ok(self)
    }

    pub fn mod_exp(&self, a: &BigNumber, b: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::mod_exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &b.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::mod_exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &b.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn modulus(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::nnmod(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::nnmod(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn exp(&self, a: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::exp(&mut bn.openssl_bn, &self.openssl_bn, &a.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn inverse(&self, n: &BigNumber, ctx: Option<&mut BigNumberContext>) -> Result<BigNumber, CryptoError> {
        let mut bn = try!(BigNumber::new());
        match ctx {
            Some(context) => try!(BigNumRef::mod_inverse(&mut bn.openssl_bn, &self.openssl_bn, &n.openssl_bn, &mut context.openssl_bn_context)),
            None => {
                let mut ctx = try!(BigNumber::new_context());
                try!(BigNumRef::mod_inverse(&mut bn.openssl_bn, &self.openssl_bn, &n.openssl_bn, &mut ctx.openssl_bn_context));
            }
        }
        Ok(bn)
    }

    pub fn mod_div(&self, b: &BigNumber, p: &BigNumber) -> Result<BigNumber, CryptoError> {
        //(a*  (1/b mod p) mod p)

        let mut context = try!(BigNumber::new_context());

        let mut res = try!(
            b
                .inverse(p, Some(&mut context))?
                .mul(&self, Some(&mut context))?
                .modulus(&p, Some(&mut context))
        );
        Ok(res)
    }

    pub fn compare(&self, other: &BigNumber) -> bool {
        self.openssl_bn == other.openssl_bn
    }

    pub fn clone(&self) -> Result<BigNumber, CryptoError> {
        let bytes = try!(self.to_bytes());
        let mut bn = try!(BigNumber::from_bytes(bytes.as_slice()));
        Ok(bn)
    }
}

impl Ord for BigNumber {
    fn cmp(&self, other: &BigNumber) -> Ordering {
        self.openssl_bn.ucmp(&other.openssl_bn)
    }
}

impl Eq for BigNumber {}

impl PartialOrd for BigNumber {
    fn partial_cmp(&self, other: &BigNumber) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for BigNumber {
    fn eq(&self, other: &BigNumber) -> bool {
        self.openssl_bn == other.openssl_bn
    }
}

impl From<ErrorStack> for CryptoError {
    fn from(err: ErrorStack) -> CryptoError {
        CryptoError::CryptoBackendError(err.description().to_string())
    }
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #38486 - est31:master, r=petrochenkov<commit_after>// Copyright 2016 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.

const x: () = {
    return; //~ ERROR return statement outside of function body
};

fn main() {}
<|endoftext|>