<commit_before><commit_msg>Add Texture YUV example<commit_after>extern crate sdl2;

use sdl2::video::{Window, WindowPos, SHOWN};
use sdl2::render::{RenderDriverIndex, ACCELERATED, Renderer};
use sdl2::pixels::PixelFormatEnum;
use sdl2::rect::Rect;
use sdl2::event::poll_event;
use sdl2::event::Event::{Quit, KeyDown};
use sdl2::keycode::KeyCode;

pub fn main() {
    sdl2::init(sdl2::INIT_VIDEO);

    let window = match Window::new("rust-sdl2 demo: YUV", WindowPos::PosCentered, WindowPos::PosCentered, 800, 600, SHOWN) {
        Ok(window) => window,
        Err(err) => panic!("failed to create window: {}", err)
    };

    let renderer = match Renderer::from_window(window, RenderDriverIndex::Auto, ACCELERATED) {
        Ok(renderer) => renderer,
        Err(err) => panic!("failed to create renderer: {}", err)
    };

    let mut texture = renderer.create_texture_streaming(PixelFormatEnum::IYUV, (256, 256)).unwrap();
    // Create a U-V gradient
    texture.with_lock(None, |buffer: &mut [u8], pitch: usize| {
        // `pitch` is the width of the Y component
        // The U and V components are half the width and height of Y

        let w = 256;
        let h = 256;

        // Set Y (constant)
        for y in 0us..h {
            for x in 0us..w {
                let offset = y*pitch + x;
                buffer[offset] = 128;
            }
        }

        let y_size = pitch*h;

        // Set U and V (X and Y)
        for y in 0us..h/2 {
            for x in 0us..w/2 {
                let u_offset = y_size + y*pitch/2 + x;
                let v_offset = y_size + (pitch/2 * h/2) + y*pitch/2 + x;
                buffer[u_offset] = (x*2) as u8;
                buffer[v_offset] = (y*2) as u8;
            }
        }
    }).unwrap();

    let mut drawer = renderer.drawer();
    drawer.clear();
    drawer.copy(&texture, None, Some(Rect::new(100, 100, 256, 256)));
    drawer.present();

    loop {
        match poll_event() {
            Quit{..} => break,
            KeyDown { keycode: key, .. } => {
                if key == KeyCode::Escape {
                    break;
                }
            }
            _ => {}
        }
    }

    sdl2::quit();
}
<|endoftext|>


<commit_before><commit_msg>Added test for issue #57<commit_after>extern crate ncollide_pipeline;
extern crate ncollide_entities;
extern crate nalgebra;

use ncollide_pipeline::world::{CollisionGroups, CollisionWorld, CollisionWorld2};
use ncollide_entities::shape::Ball;
use ncollide_entities::inspection::Repr2;
use nalgebra::{Vec1, Vec2, Iso2};
use std::sync::Arc;

type ObjectCollisionWorld = CollisionWorld2<f64, ()>;
type ShapeRepr = Repr2<f64>;

#[test]
fn issue_57_object_remove() {
	let mut world: ObjectCollisionWorld = CollisionWorld::new(0.1, 0.1, false);
    let shape = Arc::new(Box::new(Ball::new(1.0)) as Box<ShapeRepr>);
    world.add(0,
              Iso2::new(Vec2::new(1.0, 0.0), Vec1::new(0.0)),
              shape.clone(),
              CollisionGroups::new(),
              ());
   world.add(1,
              Iso2::new(Vec2::new(1.0, 1.0), Vec1::new(0.0)),
              shape.clone(),
              CollisionGroups::new(),
              ());
	world.add(2,
              Iso2::new(Vec2::new(1.0, 2.0), Vec1::new(0.0)),
              shape.clone(),
              CollisionGroups::new(),
              ());
    world.update();
    world.remove(0);
    world.update();
}
<|endoftext|>


<commit_before><commit_msg>sync_events: make account_data optional<commit_after><|endoftext|>


<commit_before>#[deriving(Show)]
struct Triplet {
    one: int,
    two: int,
    three: int,
}

impl Triplet {
    // First attempt: No explicit lifetimes
    // The compiler infers that the field and the struct have the same lifetime
    fn mut_one(&mut self) -> &mut int {
        &mut self.one
    }

    // Second attempt: We explicitly annotate the lifetimes on all the
    // references
    // Error! The compiler doesn't know what is the relationship between the
    // lifetime `structure` and the lifetime `field`
    //fn mut_two<'structure, 'field>(&'structure mut self) -> &'field mut int {
        //&mut self.two
    //}
    // TODO ^ Try uncommenting this method

    // Third attempt: We think! What is the relationship between the lifetimes?
    // Clearly `'field` *can't* outlive `'structure`, because the field will be
    // destroyed when the struct gets destroyed
    // If the fields get destroyed along with the struct, then that means that
    // both the struct and its field have the same lifetime!
    // Ok, so we need to tell the compiler that `'structure` = `'field`
    // We can use a shorter name for the lifetime, it's common to use a single
    // letter lifetime, let's use `'s`, because it's the first letter of
    // structure
    fn mut_three<'s>(&'s mut self) -> &'s mut int {
        &mut self.three
    }
}

fn main() {
    let mut triplet = Triplet { one: 1, two: 2, three: 3 };

    println!("Before: {}", triplet);

    // Use mutable reference to modify the original struct
    *triplet.mut_three() = 0;

    println!("After: {}", triplet);
}
<commit_msg>calling first example in main function<commit_after>#[deriving(Show)]
struct Triplet {
    one: int,
    two: int,
    three: int,
}

impl Triplet {
    // First attempt: No explicit lifetimes
    // The compiler infers that the field and the struct have the same lifetime
    fn mut_one(&mut self) -> &mut int {
        &mut self.one
    }

    // Second attempt: We explicitly annotate the lifetimes on all the
    // references
    // Error! The compiler doesn't know what is the relationship between the
    // lifetime `structure` and the lifetime `field`
    //fn mut_two<'structure, 'field>(&'structure mut self) -> &'field mut int {
        //&mut self.two
    //}
    // TODO ^ Try uncommenting this method

    // Third attempt: We think! What is the relationship between the lifetimes?
    // Clearly `'field` *can't* outlive `'structure`, because the field will be
    // destroyed when the struct gets destroyed
    // If the fields get destroyed along with the struct, then that means that
    // both the struct and its field have the same lifetime!
    // Ok, so we need to tell the compiler that `'structure` = `'field`
    // We can use a shorter name for the lifetime, it's common to use a single
    // letter lifetime, let's use `'s`, because it's the first letter of
    // structure
    fn mut_three<'s>(&'s mut self) -> &'s mut int {
        &mut self.three
    }
}

fn main() {
    let mut triplet = Triplet { one: 1, two: 2, three: 3 };

    println!("Before: {}", triplet);

    *triplet.mut_one() = 0;
    println!("After: {}", triplet);

    // Use mutable reference to modify the original struct
    *triplet.mut_three() = 0;

    println!("After: {}", triplet);
}
<|endoftext|>


<commit_before><commit_msg>Added test for #49579.<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.

// compile-pass

#![feature(nll)]

fn fibs(n: u32) -> impl Iterator<Item=u128> {
    (0 .. n)
    .scan((0, 1), |st, _| {
        *st = (st.1, st.0 + st.1);
        Some(*st)
    })
    .map(&|(f, _)| f)
}

fn main() {
    println!("{:?}", fibs(10).collect::<Vec<_>>());
}
<|endoftext|>


<commit_before>enum DataType {
    Unknown = 0,
    Boolean,
    Byte,
    Int16,
    Uint16,
    Int32,
    Uint32,
    Int64,
    Uint64,
    String, // TODO: What to name this string type?
    ByteArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Int64Array,
    Uint64Array,
    StringArray,
    Hrtime,
    Nvlist, // TODO: What to name this ?
    NvlistArray,
    BooleanValue,
    Int8,
    Uint8,
    BooleanArray,
    Int8Array,
    Uint8Array
}

struct NvPair {
    nvp_size:       i32, // size of this nvpair
    nvp_name_sz:    i16, // length of name string
    nvp_reserve:    i16, // not used
    nvp_value_elem: i32, // number of elements for array types
    nvp_type:       DataType, // type of value
    // name string
    // aligned ptr array for string arrays
    // aligned array of data for value
}

// nvlist header
struct NvList {
    nvl_version: i32
    nvl_nvflag:  u32 // persistent flags
    nvl_priv:    u64 // ptr to private data if not packed
    nvl_flag:    u32
    nvl_pad:     i32 // currently not used, for alignment
}

// nvp implementation version
const NV_VERSION: i32 = 0;

// nvlist pack encoding
const NV_ENCODE_NATIVE: u8 = 0;
const NV_ENCODE_XDR:    u8 = 1;

// nvlist persistent unique name flags, stored in nvl_nvflags
const NV_UNIQUE_NAME:      u32 = 0x1;
const NV_UNIQUE_NAME_TYPE: u32 = 0x2;

// nvlist lookup pairs related flags
const NV_FLAG_NOENTOK: isize = 0x1;

/* What to do about these macros?
// convenience macros
#define NV_ALIGN(x)     (((ulong_t)(x) + 7ul) & ~7ul)
#define NV_ALIGN4(x)        (((x) + 3) & ~3)

#define NVP_SIZE(nvp)       ((nvp)->nvp_size)
#define NVP_NAME(nvp)       ((char *)(nvp) + sizeof (nvpair_t))
#define NVP_TYPE(nvp)       ((nvp)->nvp_type)
#define NVP_NELEM(nvp)      ((nvp)->nvp_value_elem)
#define NVP_VALUE(nvp)      ((char *)(nvp) + NV_ALIGN(sizeof (nvpair_t) \
                + (nvp)->nvp_name_sz))

#define NVL_VERSION(nvl)    ((nvl)->nvl_version)
#define NVL_SIZE(nvl)       ((nvl)->nvl_size)
#define NVL_FLAG(nvl)       ((nvl)->nvl_flag)
*/

// NV allocator framework
struct NvAllocOps;

struct NvAlloc<> {
    nva_ops: &'static NvAllocOps,
    nva_arg: Any, // This was a void pointer type.
                  // Not sure if Any is the correct type.
}

/*
struct NvAllocOps {
    int (*nv_ao_init)(nv_alloc_t *, __va_list);
    void (*nv_ao_fini)(nv_alloc_t *);
    void *(*nv_ao_alloc)(nv_alloc_t *, size_t);
    void (*nv_ao_free)(nv_alloc_t *, void *, size_t);
    void (*nv_ao_reset)(nv_alloc_t *);
}
*/
<commit_msg>Fix the enum variant naming for consistency<commit_after>enum DataType {
    Unknown = 0,
    Boolean,
    Byte,
    Int16,
    Uint16,
    Int32,
    Uint32,
    Int64,
    Uint64,
    String,
    ByteArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Int64Array,
    Uint64Array,
    StringArray,
    HrTime,
    NvList,
    NvListArray,
    BooleanValue,
    Int8,
    Uint8,
    BooleanArray,
    Int8Array,
    Uint8Array
}

struct NvPair {
    nvp_size:       i32, // size of this nvpair
    nvp_name_sz:    i16, // length of name string
    nvp_reserve:    i16, // not used
    nvp_value_elem: i32, // number of elements for array types
    nvp_type:       DataType, // type of value
    // name string
    // aligned ptr array for string arrays
    // aligned array of data for value
}

// nvlist header
struct NvList {
    nvl_version: i32
    nvl_nvflag:  u32 // persistent flags
    nvl_priv:    u64 // ptr to private data if not packed
    nvl_flag:    u32
    nvl_pad:     i32 // currently not used, for alignment
}

// nvp implementation version
const NV_VERSION: i32 = 0;

// nvlist pack encoding
const NV_ENCODE_NATIVE: u8 = 0;
const NV_ENCODE_XDR:    u8 = 1;

// nvlist persistent unique name flags, stored in nvl_nvflags
const NV_UNIQUE_NAME:      u32 = 0x1;
const NV_UNIQUE_NAME_TYPE: u32 = 0x2;

// nvlist lookup pairs related flags
const NV_FLAG_NOENTOK: isize = 0x1;

/* What to do about these macros?
// convenience macros
#define NV_ALIGN(x)     (((ulong_t)(x) + 7ul) & ~7ul)
#define NV_ALIGN4(x)        (((x) + 3) & ~3)

#define NVP_SIZE(nvp)       ((nvp)->nvp_size)
#define NVP_NAME(nvp)       ((char *)(nvp) + sizeof (nvpair_t))
#define NVP_TYPE(nvp)       ((nvp)->nvp_type)
#define NVP_NELEM(nvp)      ((nvp)->nvp_value_elem)
#define NVP_VALUE(nvp)      ((char *)(nvp) + NV_ALIGN(sizeof (nvpair_t) \
                + (nvp)->nvp_name_sz))

#define NVL_VERSION(nvl)    ((nvl)->nvl_version)
#define NVL_SIZE(nvl)       ((nvl)->nvl_size)
#define NVL_FLAG(nvl)       ((nvl)->nvl_flag)
*/

// NV allocator framework
struct NvAllocOps;

struct NvAlloc<> {
    nva_ops: &'static NvAllocOps,
    nva_arg: Any, // This was a void pointer type.
                  // Not sure if Any is the correct type.
}

/*
struct NvAllocOps {
    int (*nv_ao_init)(nv_alloc_t *, __va_list);
    void (*nv_ao_fini)(nv_alloc_t *);
    void *(*nv_ao_alloc)(nv_alloc_t *, size_t);
    void (*nv_ao_free)(nv_alloc_t *, void *, size_t);
    void (*nv_ao_reset)(nv_alloc_t *);
}
*/
<|endoftext|>


<commit_before><commit_msg>0-offset is also not always okay<commit_after>// error-pattern: outside bounds of allocation

fn main() {
    let x = Box::into_raw(Box::new(0u32));
    let x = x.wrapping_offset(8); // okay, this has no inbounds tag
    let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is not inbounds of the only object it can point to
}
<|endoftext|>


<commit_before><commit_msg>Add test to ensure unadjusted stays unstable<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.

extern "unadjusted" fn foo() {
//~^ ERROR: unadjusted ABI is an implementation detail and perma-unstable
}

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


<commit_before><commit_msg>Add solution to problem 30<commit_after>#[macro_use] extern crate libeuler;

/// Surprisingly there are only three numbers that can be written as the sum of fourth powers of
/// their digits:
///
///     1634 = 1^4 + 6^4 + 3^4 + 4^4
///     8208 = 8^4 + 2^4 + 0^4 + 8^4
///     9474 = 9^4 + 4^4 + 7^4 + 4^4
///
/// As 1 = 1^4 is not a sum it is not included.
///
/// The sum of these numbers is 1634 + 8208 + 9474 = 19316.
///
/// Find the sum of all the numbers that can be written as the sum of fifth powers of their digits.
fn main() {
    solutions! {
        sol naive {
            let mut sum = 0;
            // 10 million should be enough.
            for i in 2..10_000_000 {
                if sum_of_fifths(i) == i {
                    sum += i;
                }
            }

            sum
        }
    }
}

fn sum_of_fifths(mut n: i64) -> i64 {
    let mut sum = 0;
    while n > 0 {
        let digit = n % 10;
        n /= 10;

        sum += digit.pow(5);
    }

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

//! Compilation of native dependencies like LLVM.
//!
//! Native projects like LLVM unfortunately aren't suited just yet for
//! compilation in build scripts that Cargo has. This is because thie
//! compilation takes a *very* long time but also because we don't want to
//! compile LLVM 3 times as part of a normal bootstrap (we want it cached).
//!
//! LLVM and compiler-rt are essentially just wired up to everything else to
//! ensure that they're always in place if needed.

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use std::process::Command;

use build_helper::output;
use cmake;
use gcc;

use Build;
use util;
use build_helper::up_to_date;

/// Compile LLVM for `target`.
pub fn llvm(build: &Build, target: &str) {
    // If we're using a custom LLVM bail out here, but we can only use a
    // custom LLVM for the build triple.
    if let Some(config) = build.config.target_config.get(target) {
        if let Some(ref s) = config.llvm_config {
            return check_llvm_version(build, s);
        }
    }

    let rebuild_trigger = build.src.join("src/rustllvm/llvm-rebuild-trigger");
    let mut rebuild_trigger_contents = String::new();
    t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents));

    let out_dir = build.llvm_out(target);
    let done_stamp = out_dir.join("llvm-finished-building");
    if done_stamp.exists() {
        let mut done_contents = String::new();
        t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents));

        // If LLVM was already built previously and contents of the rebuild-trigger file
        // didn't change from the previous build, then no action is required.
        if done_contents == rebuild_trigger_contents {
            return
        }
    }
    if build.config.llvm_clean_rebuild {
        t!(fs::remove_dir_all(&out_dir));
    }

    println!("Building LLVM for {}", target);
    let _time = util::timeit();
    t!(fs::create_dir_all(&out_dir));

    // http://llvm.org/docs/CMake.html
    let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
    if build.config.ninja {
        cfg.generator("Ninja");
    }

    let profile = match (build.config.llvm_optimize, build.config.llvm_release_debuginfo) {
        (false, _) => "Debug",
        (true, false) => "Release",
        (true, true) => "RelWithDebInfo",
    };

    // NOTE: remember to also update `config.toml.example` when changing the defaults!
    let llvm_targets = match build.config.llvm_targets {
        Some(ref s) => s,
        None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX",
    };

    let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};

    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&out_dir)
       .profile(profile)
       .define("LLVM_ENABLE_ASSERTIONS", assertions)
       .define("LLVM_TARGETS_TO_BUILD", llvm_targets)
       .define("LLVM_INCLUDE_EXAMPLES", "OFF")
       .define("LLVM_INCLUDE_TESTS", "OFF")
       .define("LLVM_INCLUDE_DOCS", "OFF")
       .define("LLVM_ENABLE_ZLIB", "OFF")
       .define("WITH_POLLY", "OFF")
       .define("LLVM_ENABLE_TERMINFO", "OFF")
       .define("LLVM_ENABLE_LIBEDIT", "OFF")
       .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string())
       .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
       .define("LLVM_DEFAULT_TARGET_TRIPLE", target);

    if target.contains("msvc") {
        cfg.define("LLVM_USE_CRT_DEBUG", "MT");
        cfg.define("LLVM_USE_CRT_RELEASE", "MT");
        cfg.define("LLVM_USE_CRT_RELWITHDEBINFO", "MT");
    }

    if target.starts_with("i686") {
        cfg.define("LLVM_BUILD_32_BITS", "ON");
    }

    if let Some(num_linkers) = build.config.llvm_link_jobs {
        if num_linkers > 0 {
            cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());
        }
    }

    // http://llvm.org/docs/HowToCrossCompileLLVM.html
    if target != build.config.build {
        // FIXME: if the llvm root for the build triple is overridden then we
        //        should use llvm-tblgen from there, also should verify that it
        //        actually exists most of the time in normal installs of LLVM.
        let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
        cfg.define("CMAKE_CROSSCOMPILING", "True")
           .define("LLVM_TABLEGEN", &host);
    }

    // MSVC handles compiler business itself
    if !target.contains("msvc") {
        if let Some(ref ccache) = build.config.ccache {
           cfg.define("CMAKE_C_COMPILER", ccache)
              .define("CMAKE_C_COMPILER_ARG1", build.cc(target))
              .define("CMAKE_CXX_COMPILER", ccache)
              .define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
        } else {
           cfg.define("CMAKE_C_COMPILER", build.cc(target))
              .define("CMAKE_CXX_COMPILER", build.cxx(target));
        }
        cfg.build_arg("-j").build_arg(build.jobs().to_string());

        cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
        cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
    }

    // FIXME: we don't actually need to build all LLVM tools and all LLVM
    //        libraries here, e.g. we just want a few components and a few
    //        tools. Figure out how to filter them down and only build the right
    //        tools and libs on all platforms.
    cfg.build();

    t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes()));
}

fn check_llvm_version(build: &Build, llvm_config: &Path) {
    if !build.config.llvm_version_check {
        return
    }

    let mut cmd = Command::new(llvm_config);
    let version = output(cmd.arg("--version"));
    if version.starts_with("3.5") || version.starts_with("3.6") ||
       version.starts_with("3.7") {
        return
    }
    panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
}

/// Compiles the `rust_test_helpers.c` library which we used in various
/// `run-pass` test suites for ABI testing.
pub fn test_helpers(build: &Build, target: &str) {
    let dst = build.test_helpers_out(target);
    let src = build.src.join("src/rt/rust_test_helpers.c");
    if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
        return
    }

    println!("Building test helpers");
    t!(fs::create_dir_all(&dst));
    let mut cfg = gcc::Config::new();

    // We may have found various cross-compilers a little differently due to our
    // extra configuration, so inform gcc of these compilers. Note, though, that
    // on MSVC we still need gcc's detection of env vars (ugh).
    if !target.contains("msvc") {
        if let Some(ar) = build.ar(target) {
            cfg.archiver(ar);
        }
        cfg.compiler(build.cc(target));
    }

    cfg.cargo_metadata(false)
       .out_dir(&dst)
       .target(target)
       .host(&build.config.build)
       .opt_level(0)
       .debug(false)
       .file(build.src.join("src/rt/rust_test_helpers.c"))
       .compile("librust_test_helpers.a");
}
const OPENSSL_VERS: &'static str = "1.0.2k";
const OPENSSL_SHA256: &'static str =
    "6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0";

pub fn openssl(build: &Build, target: &str) {
    let out = match build.openssl_dir(target) {
        Some(dir) => dir,
        None => return,
    };

    let stamp = out.join(".stamp");
    let mut contents = String::new();
    drop(File::open(&stamp).and_then(|mut f| f.read_to_string(&mut contents)));
    if contents == OPENSSL_VERS {
        return
    }
    t!(fs::create_dir_all(&out));

    let name = format!("openssl-{}.tar.gz", OPENSSL_VERS);
    let tarball = out.join(&name);
    if !tarball.exists() {
        let tmp = tarball.with_extension("tmp");
        build.run(Command::new("curl")
                        .arg("-o").arg(&tmp)
                        .arg(format!("https://www.openssl.org/source/{}", name)));
        let mut shasum = if target.contains("apple") {
            let mut cmd = Command::new("shasum");
            cmd.arg("-a").arg("256");
            cmd
        } else {
            Command::new("sha256sum")
        };
        let output = output(&mut shasum.arg(&tmp));
        let found = output.split_whitespace().next().unwrap();
        if found != OPENSSL_SHA256 {
            panic!("downloaded openssl sha256 different\n\
                    expected: {}\n\
                    found:    {}\n", OPENSSL_SHA256, found);
        }
        t!(fs::rename(&tmp, &tarball));
    }
    let obj = out.join(format!("openssl-{}", OPENSSL_VERS));
    let dst = build.openssl_install_dir(target).unwrap();
    drop(fs::remove_dir_all(&obj));
    drop(fs::remove_dir_all(&dst));
    build.run(Command::new("tar").arg("xf").arg(&tarball).current_dir(&out));

    let mut configure = Command::new(obj.join("Configure"));
    configure.arg(format!("--prefix={}", dst.display()));
    configure.arg("no-dso");
    configure.arg("no-ssl2");
    configure.arg("no-ssl3");

    let os = match target {
        "aarch64-unknown-linux-gnu" => "linux-aarch64",
        "arm-unknown-linux-gnueabi" => "linux-armv4",
        "arm-unknown-linux-gnueabihf" => "linux-armv4",
        "armv7-unknown-linux-gnueabihf" => "linux-armv4",
        "i686-apple-darwin" => "darwin-i386-cc",
        "i686-unknown-freebsd" => "BSD-x86-elf",
        "i686-unknown-linux-gnu" => "linux-elf",
        "i686-unknown-linux-musl" => "linux-elf",
        "mips-unknown-linux-gnu" => "linux-mips32",
        "mips64-unknown-linux-gnuabi64" => "linux64-mips64",
        "mips64el-unknown-linux-gnuabi64" => "linux64-mips64",
        "mipsel-unknown-linux-gnu" => "linux-mips32",
        "powerpc-unknown-linux-gnu" => "linux-ppc",
        "powerpc64-unknown-linux-gnu" => "linux-ppc64",
        "powerpc64le-unknown-linux-gnu" => "linux-ppc64le",
        "s390x-unknown-linux-gnu" => "linux64-s390x",
        "x86_64-apple-darwin" => "darwin64-x86_64-cc",
        "x86_64-unknown-freebsd" => "BSD-x86_64",
        "x86_64-unknown-linux-gnu" => "linux-x86_64",
        "x86_64-unknown-linux-musl" => "linux-x86_64",
        "x86_64-unknown-netbsd" => "BSD-x86_64",
        _ => panic!("don't know how to configure OpenSSL for {}", target),
    };
    configure.arg(os);
    configure.env("CC", build.cc(target));
    for flag in build.cflags(target) {
        configure.arg(flag);
    }
    configure.current_dir(&obj);
    println!("Configuring openssl for {}", target);
    build.run_quiet(&mut configure);
    println!("Building openssl for {}", target);
    build.run_quiet(Command::new("make").current_dir(&obj));
    println!("Installing openssl for {}", target);
    build.run_quiet(Command::new("make").arg("install").current_dir(&obj));

    let mut f = t!(File::create(&stamp));
    t!(f.write_all(OPENSSL_VERS.as_bytes()));
}
<commit_msg>Allow cleaning llvm build dir to fail<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.

//! Compilation of native dependencies like LLVM.
//!
//! Native projects like LLVM unfortunately aren't suited just yet for
//! compilation in build scripts that Cargo has. This is because thie
//! compilation takes a *very* long time but also because we don't want to
//! compile LLVM 3 times as part of a normal bootstrap (we want it cached).
//!
//! LLVM and compiler-rt are essentially just wired up to everything else to
//! ensure that they're always in place if needed.

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use std::process::Command;

use build_helper::output;
use cmake;
use gcc;

use Build;
use util;
use build_helper::up_to_date;

/// Compile LLVM for `target`.
pub fn llvm(build: &Build, target: &str) {
    // If we're using a custom LLVM bail out here, but we can only use a
    // custom LLVM for the build triple.
    if let Some(config) = build.config.target_config.get(target) {
        if let Some(ref s) = config.llvm_config {
            return check_llvm_version(build, s);
        }
    }

    let rebuild_trigger = build.src.join("src/rustllvm/llvm-rebuild-trigger");
    let mut rebuild_trigger_contents = String::new();
    t!(t!(File::open(&rebuild_trigger)).read_to_string(&mut rebuild_trigger_contents));

    let out_dir = build.llvm_out(target);
    let done_stamp = out_dir.join("llvm-finished-building");
    if done_stamp.exists() {
        let mut done_contents = String::new();
        t!(t!(File::open(&done_stamp)).read_to_string(&mut done_contents));

        // If LLVM was already built previously and contents of the rebuild-trigger file
        // didn't change from the previous build, then no action is required.
        if done_contents == rebuild_trigger_contents {
            return
        }
    }
    if build.config.llvm_clean_rebuild {
        drop(fs::remove_dir_all(&out_dir));
    }

    println!("Building LLVM for {}", target);
    let _time = util::timeit();
    t!(fs::create_dir_all(&out_dir));

    // http://llvm.org/docs/CMake.html
    let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
    if build.config.ninja {
        cfg.generator("Ninja");
    }

    let profile = match (build.config.llvm_optimize, build.config.llvm_release_debuginfo) {
        (false, _) => "Debug",
        (true, false) => "Release",
        (true, true) => "RelWithDebInfo",
    };

    // NOTE: remember to also update `config.toml.example` when changing the defaults!
    let llvm_targets = match build.config.llvm_targets {
        Some(ref s) => s,
        None => "X86;ARM;AArch64;Mips;PowerPC;SystemZ;JSBackend;MSP430;Sparc;NVPTX",
    };

    let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};

    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&out_dir)
       .profile(profile)
       .define("LLVM_ENABLE_ASSERTIONS", assertions)
       .define("LLVM_TARGETS_TO_BUILD", llvm_targets)
       .define("LLVM_INCLUDE_EXAMPLES", "OFF")
       .define("LLVM_INCLUDE_TESTS", "OFF")
       .define("LLVM_INCLUDE_DOCS", "OFF")
       .define("LLVM_ENABLE_ZLIB", "OFF")
       .define("WITH_POLLY", "OFF")
       .define("LLVM_ENABLE_TERMINFO", "OFF")
       .define("LLVM_ENABLE_LIBEDIT", "OFF")
       .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string())
       .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
       .define("LLVM_DEFAULT_TARGET_TRIPLE", target);

    if target.contains("msvc") {
        cfg.define("LLVM_USE_CRT_DEBUG", "MT");
        cfg.define("LLVM_USE_CRT_RELEASE", "MT");
        cfg.define("LLVM_USE_CRT_RELWITHDEBINFO", "MT");
    }

    if target.starts_with("i686") {
        cfg.define("LLVM_BUILD_32_BITS", "ON");
    }

    if let Some(num_linkers) = build.config.llvm_link_jobs {
        if num_linkers > 0 {
            cfg.define("LLVM_PARALLEL_LINK_JOBS", num_linkers.to_string());
        }
    }

    // http://llvm.org/docs/HowToCrossCompileLLVM.html
    if target != build.config.build {
        // FIXME: if the llvm root for the build triple is overridden then we
        //        should use llvm-tblgen from there, also should verify that it
        //        actually exists most of the time in normal installs of LLVM.
        let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
        cfg.define("CMAKE_CROSSCOMPILING", "True")
           .define("LLVM_TABLEGEN", &host);
    }

    // MSVC handles compiler business itself
    if !target.contains("msvc") {
        if let Some(ref ccache) = build.config.ccache {
           cfg.define("CMAKE_C_COMPILER", ccache)
              .define("CMAKE_C_COMPILER_ARG1", build.cc(target))
              .define("CMAKE_CXX_COMPILER", ccache)
              .define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
        } else {
           cfg.define("CMAKE_C_COMPILER", build.cc(target))
              .define("CMAKE_CXX_COMPILER", build.cxx(target));
        }
        cfg.build_arg("-j").build_arg(build.jobs().to_string());

        cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
        cfg.define("CMAKE_CXX_FLAGS", build.cflags(target).join(" "));
    }

    // FIXME: we don't actually need to build all LLVM tools and all LLVM
    //        libraries here, e.g. we just want a few components and a few
    //        tools. Figure out how to filter them down and only build the right
    //        tools and libs on all platforms.
    cfg.build();

    t!(t!(File::create(&done_stamp)).write_all(rebuild_trigger_contents.as_bytes()));
}

fn check_llvm_version(build: &Build, llvm_config: &Path) {
    if !build.config.llvm_version_check {
        return
    }

    let mut cmd = Command::new(llvm_config);
    let version = output(cmd.arg("--version"));
    if version.starts_with("3.5") || version.starts_with("3.6") ||
       version.starts_with("3.7") {
        return
    }
    panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
}

/// Compiles the `rust_test_helpers.c` library which we used in various
/// `run-pass` test suites for ABI testing.
pub fn test_helpers(build: &Build, target: &str) {
    let dst = build.test_helpers_out(target);
    let src = build.src.join("src/rt/rust_test_helpers.c");
    if up_to_date(&src, &dst.join("librust_test_helpers.a")) {
        return
    }

    println!("Building test helpers");
    t!(fs::create_dir_all(&dst));
    let mut cfg = gcc::Config::new();

    // We may have found various cross-compilers a little differently due to our
    // extra configuration, so inform gcc of these compilers. Note, though, that
    // on MSVC we still need gcc's detection of env vars (ugh).
    if !target.contains("msvc") {
        if let Some(ar) = build.ar(target) {
            cfg.archiver(ar);
        }
        cfg.compiler(build.cc(target));
    }

    cfg.cargo_metadata(false)
       .out_dir(&dst)
       .target(target)
       .host(&build.config.build)
       .opt_level(0)
       .debug(false)
       .file(build.src.join("src/rt/rust_test_helpers.c"))
       .compile("librust_test_helpers.a");
}
const OPENSSL_VERS: &'static str = "1.0.2k";
const OPENSSL_SHA256: &'static str =
    "6b3977c61f2aedf0f96367dcfb5c6e578cf37e7b8d913b4ecb6643c3cb88d8c0";

pub fn openssl(build: &Build, target: &str) {
    let out = match build.openssl_dir(target) {
        Some(dir) => dir,
        None => return,
    };

    let stamp = out.join(".stamp");
    let mut contents = String::new();
    drop(File::open(&stamp).and_then(|mut f| f.read_to_string(&mut contents)));
    if contents == OPENSSL_VERS {
        return
    }
    t!(fs::create_dir_all(&out));

    let name = format!("openssl-{}.tar.gz", OPENSSL_VERS);
    let tarball = out.join(&name);
    if !tarball.exists() {
        let tmp = tarball.with_extension("tmp");
        build.run(Command::new("curl")
                        .arg("-o").arg(&tmp)
                        .arg(format!("https://www.openssl.org/source/{}", name)));
        let mut shasum = if target.contains("apple") {
            let mut cmd = Command::new("shasum");
            cmd.arg("-a").arg("256");
            cmd
        } else {
            Command::new("sha256sum")
        };
        let output = output(&mut shasum.arg(&tmp));
        let found = output.split_whitespace().next().unwrap();
        if found != OPENSSL_SHA256 {
            panic!("downloaded openssl sha256 different\n\
                    expected: {}\n\
                    found:    {}\n", OPENSSL_SHA256, found);
        }
        t!(fs::rename(&tmp, &tarball));
    }
    let obj = out.join(format!("openssl-{}", OPENSSL_VERS));
    let dst = build.openssl_install_dir(target).unwrap();
    drop(fs::remove_dir_all(&obj));
    drop(fs::remove_dir_all(&dst));
    build.run(Command::new("tar").arg("xf").arg(&tarball).current_dir(&out));

    let mut configure = Command::new(obj.join("Configure"));
    configure.arg(format!("--prefix={}", dst.display()));
    configure.arg("no-dso");
    configure.arg("no-ssl2");
    configure.arg("no-ssl3");

    let os = match target {
        "aarch64-unknown-linux-gnu" => "linux-aarch64",
        "arm-unknown-linux-gnueabi" => "linux-armv4",
        "arm-unknown-linux-gnueabihf" => "linux-armv4",
        "armv7-unknown-linux-gnueabihf" => "linux-armv4",
        "i686-apple-darwin" => "darwin-i386-cc",
        "i686-unknown-freebsd" => "BSD-x86-elf",
        "i686-unknown-linux-gnu" => "linux-elf",
        "i686-unknown-linux-musl" => "linux-elf",
        "mips-unknown-linux-gnu" => "linux-mips32",
        "mips64-unknown-linux-gnuabi64" => "linux64-mips64",
        "mips64el-unknown-linux-gnuabi64" => "linux64-mips64",
        "mipsel-unknown-linux-gnu" => "linux-mips32",
        "powerpc-unknown-linux-gnu" => "linux-ppc",
        "powerpc64-unknown-linux-gnu" => "linux-ppc64",
        "powerpc64le-unknown-linux-gnu" => "linux-ppc64le",
        "s390x-unknown-linux-gnu" => "linux64-s390x",
        "x86_64-apple-darwin" => "darwin64-x86_64-cc",
        "x86_64-unknown-freebsd" => "BSD-x86_64",
        "x86_64-unknown-linux-gnu" => "linux-x86_64",
        "x86_64-unknown-linux-musl" => "linux-x86_64",
        "x86_64-unknown-netbsd" => "BSD-x86_64",
        _ => panic!("don't know how to configure OpenSSL for {}", target),
    };
    configure.arg(os);
    configure.env("CC", build.cc(target));
    for flag in build.cflags(target) {
        configure.arg(flag);
    }
    configure.current_dir(&obj);
    println!("Configuring openssl for {}", target);
    build.run_quiet(&mut configure);
    println!("Building openssl for {}", target);
    build.run_quiet(Command::new("make").current_dir(&obj));
    println!("Installing openssl for {}", target);
    build.run_quiet(Command::new("make").arg("install").current_dir(&obj));

    let mut f = t!(File::create(&stamp));
    t!(f.write_all(OPENSSL_VERS.as_bytes()));
}
<|endoftext|>


<commit_before>use redox::get_slice::GetSlice;
use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::*;
use redox::io::*;
use redox::env::*;
use redox::time::Duration;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application<'static> = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     main: box|args: &Vec<String>| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command<'a> {
    pub name: &'a str,
    pub main: Box<Fn(&Vec<String>)>,
}

impl<'a> Command<'a> {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();

        commands.push(Command {
            name: "cat",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read: {}", path),
                    }
                } else {
                    println!("Failed to open file: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "cd",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(path) => {
                        if !change_cwd(&path) {
                            println!("Bad path: {}", path);
                        }
                    }
                    None => println!("No path given")
                }
            }),
        });

        // Simple command to create a file, in the current directory
        // The file has got the name given as the first argument of the command
        // If the command have no arguments, the command don't create the file
        commands.push(Command {
            name: "cfile",
            main: box |args: &Vec<String>| {
                match args.get(1) {
                    Some(file_name) => {
                        File::create(file_name);
                    }
                    None => {
                        println!("Could not create a file without a name");
                    }
                }
            }
        });

        commands.push(Command {
            name: "echo",
            main: Box::new(|args: &Vec<String>| {
                let echo = args.iter()
                    .skip(1)
                    .fold(String::new(), |string, arg| string + " " + arg);
                println!("{}", echo.trim());
            }),
        });

        commands.push(Command {
            name: "else",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "exec",
            main: Box::new(|args: &Vec<String>| {
                if let Some(arg) = args.get(1) {
                    let mut args_str: Vec<&str> = Vec::new();
                    for arg in args.get_slice(Some(2), None) {
                        args_str.push(arg);
                    }

                    File::exec(arg, &args_str);
                }
            }),
        });

        commands.push(Command {
            name: "exit",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "fi",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "if",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "ls",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(dir) = read_dir(&path) {
                    for entry in dir {
                        println!("{}", entry.path());
                    }
                } else {
                    println!("Failed to open directory: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "pwd",
            main: Box::new(|_: &Vec<String>| {
                if let Some(file) = File::open("") {
                    if let Some(path) = file.path() {
                        println!("{}", path);
                    } else {
                        println!("Could not get the path");
                    }
                } else {
                    println!("Could not open the working directory");
                }
            }),
        });

        commands.push(Command {
            name: "read",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "run",
            main: Box::new(|args: &Vec<String>| {
                if let Some(path) = args.get(1) {

                    let mut commands = String::new();
                    if let Some(mut file) = File::open(path) {
                        file.read_to_string(&mut commands);
                    }

                    for command in commands.split('\n') {
                        exec!(command);
                    }
                }
            }),
        });

        commands.push(Command {
            name: "sleep",
            main: Box::new(|args: &Vec<String>| {
                let secs = {
                    match args.get(1) {
                        Some(arg) => arg.to_num() as i64,
                        None => 0,
                    }
                };

                let nanos = {
                    match args.get(2) {
                        Some(arg) => arg.to_num() as i32,
                        None => 0,
                    }
                };

                println!("Sleep: {} {}", secs, nanos);
                let remaining = Duration::new(secs, nanos).sleep();
                println!("Remaining: {} {}", remaining.secs, remaining.nanos);
            }),
        });

        commands.push(Command {
            name: "send",
            main: Box::new(|args: &Vec<String>| {
                if args.len() < 3 {
                    println!("Error: incorrect arguments");
                    println!("Usage: send [url] [data]");
                    return;
                }

                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    println!("URL: {:?}", file.path());

                    let string: String = args.iter()
                        .skip(2)
                        .fold(String::new(), |s, arg| s + " " + arg)
                        + "\r\n\r\n";

                    match file.write(string.trim_left().as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        // Simple command to create a file, in the current directory
        // The file has got the name given as the first argument of the command
        // If the command have no arguments, the command don't create the file
        commands.push(Command {
            name: "touch",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(file_name) => if File::create(file_name).is_none() {
                        println!("Failed to create: {}", file_name);
                    },
                    None => println!("No name provided")
                }
            }),
        });

        commands.push(Command {
            name: "url_hex",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        commands.push(Command {
            name: "wget",
            main: Box::new(|args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            }),
        });

        let command_list = commands.iter().fold(String::new(), |l , c| l + " " + c.name);

        commands.push(Command {
            name: "help",
            main: Box::new(move |_: &Vec<String>| {
                println!("Commands:{}", command_list);
            }),
         });

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application<'a> {
    commands: Vec<Command<'a>>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl<'a> Application<'a> {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &str) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if command_string == "$" {
            for variable in self.variables.iter() {
                println!("{}={}", variable.name, variable.value);
            }
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if !arg.is_empty() {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        if let Some(cmd) = args.get(0) {
            if cmd == "if" {
                let mut value = false;

                if let Some(left) = args.get(1) {
                    if let Some(cmp) = args.get(2) {
                        if let Some(right) = args.get(3) {
                            if cmp == "==" {
                                value = *left == *right;
                            } else if cmp == "!=" {
                                value = *left != *right;
                            } else if cmp == ">" {
                                value = left.to_num_signed() > right.to_num_signed();
                            } else if cmp == ">=" {
                                value = left.to_num_signed() >= right.to_num_signed();
                            } else if cmp == "<" {
                                value = left.to_num_signed() < right.to_num_signed();
                            } else if cmp == "<=" {
                                value = left.to_num_signed() <= right.to_num_signed();
                            } else {
                                println!("Unknown comparison: {}", cmp);
                            }
                        } else {
                            println!("No right hand side");
                        }
                    } else {
                        println!("No comparison operator");
                    }
                } else {
                    println!("No left hand side");
                }

                self.modes.insert(0, Mode { value: value });
                return;
            }

            if cmd == "else" {
                let mut syntax_error = false;
                match self.modes.get_mut(0) {
                    Some(mode) => mode.value = !mode.value,
                    None => syntax_error = true,
                }
                if syntax_error {
                    println!("Syntax error: else found with no previous if");
                }
                return;
            }

            if cmd == "fi" {
                let mut syntax_error = false;
                if !self.modes.is_empty() {
                    self.modes.remove(0);
                } else {
                    syntax_error = true;
                }
                if syntax_error {
                    println!("Syntax error: fi found with no previous if");
                }
                return;
            }

            for mode in self.modes.iter() {
                if !mode.value {
                    return;
                }
            }

            if cmd == "read" {
                for i in 1..args.len() {
                    if let Some(arg_original) = args.get(i) {
                        let arg = arg_original.trim();
                        print!("{}=", arg);
                        if let Some(value_original) = readln!() {
                            let value = value_original.trim();
                            self.set_var(arg, value);
                        }
                    }
                }
            }

            //Set variables
            if let Some(i) = cmd.find('=') {
                let name = cmd[0 .. i].trim();
                let mut value = cmd[i + 1 .. cmd.len()].trim().to_string();

                for i in 1..args.len() {
                    if let Some(arg) = args.get(i) {
                        value = value + " " + &arg;
                    }
                }

                self.set_var(name, &value);
                return;
            }

            //Commands
            for command in self.commands.iter() {
                if &command.name == cmd {
                    (*command.main)(&args);
                    return;
                }
            }

            println!("Unknown command: '{}'", cmd);
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str){
        if name.is_empty() {
            return;
        }

        if value.is_empty() {
            let mut remove = -1;
            for i in 0..self.variables.len() {
                match self.variables.get(i) {
                    Some(variable) => if variable.name == name {
                        remove = i as isize;
                        break;
                    },
                    None => break,
                }
            }

            if remove >= 0 {
                self.variables.remove(remove as usize);
            }
        } else {
            for variable in self.variables.iter_mut() {
                if variable.name == name {
                    variable.value = value.to_string();
                    return;
                }
            }

            self.variables.push(Variable {
                name: name.to_string(),
                value: value.to_string(),
            });
        }
    }

    /// Method to return the current directory
    /// If the current directory cannot be found, a default string ("?") will be returned
    pub fn get_current_directory(&mut self) -> String {
        // Return the current path
        File::open("")
            .and_then(|file| file.path())
            .unwrap_or("?".to_string())
    }

    /// Run the application
    pub fn main(&mut self) {
        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("user@redox:{}# {}", self.get_current_directory(), command);
            self.on_command(&command);
        }

        loop {
            for mode in self.modes.iter().rev() {
                if mode.value {
                    print!("+ ");
                } else {
                    print!("- ");
                }
            }
            print!("user@redox:{}# ", self.get_current_directory());
            if let Some(command_original) = readln!() {
                let command = command_original.trim();
                if command == "exit" {
                    println!("Exit temporarily blocked (due to using terminal as init)")
                    //break;
                } else if !command.is_empty() {
                    self.on_command(&command);
                }
            } else {
                println!("Failed to read from stdin");
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = Box::new(Application::new());
        application = app.deref_mut();
        app.main();
    }
}
<commit_msg>Remove duplicate code<commit_after>use redox::get_slice::GetSlice;
use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::*;
use redox::io::*;
use redox::env::*;
use redox::time::Duration;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application<'static> = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     main: box|args: &Vec<String>| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command<'a> {
    pub name: &'a str,
    pub main: Box<Fn(&Vec<String>)>,
}

impl<'a> Command<'a> {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();

        commands.push(Command {
            name: "cat",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read: {}", path),
                    }
                } else {
                    println!("Failed to open file: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "cd",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(path) => {
                        if !change_cwd(&path) {
                            println!("Bad path: {}", path);
                        }
                    }
                    None => println!("No path given")
                }
            }),
        });

        commands.push(Command {
            name: "echo",
            main: Box::new(|args: &Vec<String>| {
                let echo = args.iter()
                    .skip(1)
                    .fold(String::new(), |string, arg| string + " " + arg);
                println!("{}", echo.trim());
            }),
        });

        commands.push(Command {
            name: "else",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "exec",
            main: Box::new(|args: &Vec<String>| {
                if let Some(arg) = args.get(1) {
                    let mut args_str: Vec<&str> = Vec::new();
                    for arg in args.get_slice(Some(2), None) {
                        args_str.push(arg);
                    }

                    File::exec(arg, &args_str);
                }
            }),
        });

        commands.push(Command {
            name: "exit",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "fi",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "if",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "ls",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(dir) = read_dir(&path) {
                    for entry in dir {
                        println!("{}", entry.path());
                    }
                } else {
                    println!("Failed to open directory: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "pwd",
            main: Box::new(|_: &Vec<String>| {
                if let Some(file) = File::open("") {
                    if let Some(path) = file.path() {
                        println!("{}", path);
                    } else {
                        println!("Could not get the path");
                    }
                } else {
                    println!("Could not open the working directory");
                }
            }),
        });

        commands.push(Command {
            name: "read",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "run",
            main: Box::new(|args: &Vec<String>| {
                if let Some(path) = args.get(1) {

                    let mut commands = String::new();
                    if let Some(mut file) = File::open(path) {
                        file.read_to_string(&mut commands);
                    }

                    for command in commands.split('\n') {
                        exec!(command);
                    }
                }
            }),
        });

        commands.push(Command {
            name: "sleep",
            main: Box::new(|args: &Vec<String>| {
                let secs = {
                    match args.get(1) {
                        Some(arg) => arg.to_num() as i64,
                        None => 0,
                    }
                };

                let nanos = {
                    match args.get(2) {
                        Some(arg) => arg.to_num() as i32,
                        None => 0,
                    }
                };

                println!("Sleep: {} {}", secs, nanos);
                let remaining = Duration::new(secs, nanos).sleep();
                println!("Remaining: {} {}", remaining.secs, remaining.nanos);
            }),
        });

        commands.push(Command {
            name: "send",
            main: Box::new(|args: &Vec<String>| {
                if args.len() < 3 {
                    println!("Error: incorrect arguments");
                    println!("Usage: send [url] [data]");
                    return;
                }

                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    println!("URL: {:?}", file.path());

                    let string: String = args.iter()
                        .skip(2)
                        .fold(String::new(), |s, arg| s + " " + arg)
                        + "\r\n\r\n";

                    match file.write(string.trim_left().as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        // Simple command to create a file, in the current directory
        // The file has got the name given as the first argument of the command
        // If the command have no arguments, the command don't create the file
        commands.push(Command {
            name: "touch",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(file_name) => if File::create(file_name).is_none() {
                        println!("Failed to create: {}", file_name);
                    },
                    None => println!("No name provided")
                }
            }),
        });

        commands.push(Command {
            name: "url_hex",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        commands.push(Command {
            name: "wget",
            main: Box::new(|args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            }),
        });

        let command_list = commands.iter().fold(String::new(), |l , c| l + " " + c.name);

        commands.push(Command {
            name: "help",
            main: Box::new(move |_: &Vec<String>| {
                println!("Commands:{}", command_list);
            }),
         });

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application<'a> {
    commands: Vec<Command<'a>>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl<'a> Application<'a> {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &str) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if command_string == "$" {
            for variable in self.variables.iter() {
                println!("{}={}", variable.name, variable.value);
            }
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if !arg.is_empty() {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        if let Some(cmd) = args.get(0) {
            if cmd == "if" {
                let mut value = false;

                if let Some(left) = args.get(1) {
                    if let Some(cmp) = args.get(2) {
                        if let Some(right) = args.get(3) {
                            if cmp == "==" {
                                value = *left == *right;
                            } else if cmp == "!=" {
                                value = *left != *right;
                            } else if cmp == ">" {
                                value = left.to_num_signed() > right.to_num_signed();
                            } else if cmp == ">=" {
                                value = left.to_num_signed() >= right.to_num_signed();
                            } else if cmp == "<" {
                                value = left.to_num_signed() < right.to_num_signed();
                            } else if cmp == "<=" {
                                value = left.to_num_signed() <= right.to_num_signed();
                            } else {
                                println!("Unknown comparison: {}", cmp);
                            }
                        } else {
                            println!("No right hand side");
                        }
                    } else {
                        println!("No comparison operator");
                    }
                } else {
                    println!("No left hand side");
                }

                self.modes.insert(0, Mode { value: value });
                return;
            }

            if cmd == "else" {
                let mut syntax_error = false;
                match self.modes.get_mut(0) {
                    Some(mode) => mode.value = !mode.value,
                    None => syntax_error = true,
                }
                if syntax_error {
                    println!("Syntax error: else found with no previous if");
                }
                return;
            }

            if cmd == "fi" {
                let mut syntax_error = false;
                if !self.modes.is_empty() {
                    self.modes.remove(0);
                } else {
                    syntax_error = true;
                }
                if syntax_error {
                    println!("Syntax error: fi found with no previous if");
                }
                return;
            }

            for mode in self.modes.iter() {
                if !mode.value {
                    return;
                }
            }

            if cmd == "read" {
                for i in 1..args.len() {
                    if let Some(arg_original) = args.get(i) {
                        let arg = arg_original.trim();
                        print!("{}=", arg);
                        if let Some(value_original) = readln!() {
                            let value = value_original.trim();
                            self.set_var(arg, value);
                        }
                    }
                }
            }

            //Set variables
            if let Some(i) = cmd.find('=') {
                let name = cmd[0 .. i].trim();
                let mut value = cmd[i + 1 .. cmd.len()].trim().to_string();

                for i in 1..args.len() {
                    if let Some(arg) = args.get(i) {
                        value = value + " " + &arg;
                    }
                }

                self.set_var(name, &value);
                return;
            }

            //Commands
            for command in self.commands.iter() {
                if &command.name == cmd {
                    (*command.main)(&args);
                    return;
                }
            }

            println!("Unknown command: '{}'", cmd);
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str){
        if name.is_empty() {
            return;
        }

        if value.is_empty() {
            let mut remove = -1;
            for i in 0..self.variables.len() {
                match self.variables.get(i) {
                    Some(variable) => if variable.name == name {
                        remove = i as isize;
                        break;
                    },
                    None => break,
                }
            }

            if remove >= 0 {
                self.variables.remove(remove as usize);
            }
        } else {
            for variable in self.variables.iter_mut() {
                if variable.name == name {
                    variable.value = value.to_string();
                    return;
                }
            }

            self.variables.push(Variable {
                name: name.to_string(),
                value: value.to_string(),
            });
        }
    }

    /// Method to return the current directory
    /// If the current directory cannot be found, a default string ("?") will be returned
    pub fn get_current_directory(&mut self) -> String {
        // Return the current path
        File::open("")
            .and_then(|file| file.path())
            .unwrap_or("?".to_string())
    }

    /// Run the application
    pub fn main(&mut self) {
        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("user@redox:{}# {}", self.get_current_directory(), command);
            self.on_command(&command);
        }

        loop {
            for mode in self.modes.iter().rev() {
                if mode.value {
                    print!("+ ");
                } else {
                    print!("- ");
                }
            }
            print!("user@redox:{}# ", self.get_current_directory());
            if let Some(command_original) = readln!() {
                let command = command_original.trim();
                if command == "exit" {
                    println!("Exit temporarily blocked (due to using terminal as init)")
                    //break;
                } else if !command.is_empty() {
                    self.on_command(&command);
                }
            } else {
                println!("Failed to read from stdin");
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = Box::new(Application::new());
        application = app.deref_mut();
        app.main();
    }
}
<|endoftext|>


<commit_before><commit_msg>Wrote some warnings about the lack of checking statements in enclosed scopes. To fix that will require more work than I'm willing to do right now.<commit_after><|endoftext|>


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

use std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
}

const TEST_REPOS: &'static [Test] = &[
    Test {
        name: "cargo",
        repo: "https://github.com/rust-lang/cargo",
        sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
        lock: None,
    },
    Test {
        name: "iron",
        repo: "https://github.com/iron/iron",
        sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
        lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
    },
];

fn main() {
    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock")).expect("")
            .write_all(lockfile.as_bytes()).expect("");
    }
    if !run_cargo_test(cargo, &dir) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
            .arg("init")
            .arg(&out_dir)
            .status()
            .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                .arg("fetch")
                .arg(test.repo)
                .arg("master")
                .arg(&format!("--depth={}", depth))
                .current_dir(&out_dir)
                .status()
                .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
            .arg("reset")
            .arg(test.sha)
            .arg("--hard")
            .current_dir(&out_dir)
            .status()
            .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
        .arg("clean")
        .arg("-fdx")
        .current_dir(&out_dir)
        .status()
        .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
    let status = Command::new(cargo_path)
        .arg("test")
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<commit_msg>Auto merge of #34220 - srinivasreddy:rf_cargotest, 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.

use std::env;
use std::process::Command;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::Write;

struct Test {
    repo: &'static str,
    name: &'static str,
    sha: &'static str,
    lock: Option<&'static str>,
}

const TEST_REPOS: &'static [Test] = &[Test {
                                          name: "cargo",
                                          repo: "https://github.com/rust-lang/cargo",
                                          sha: "7d79da08238e3d47e0bc4406155bdcc45ccb8c82",
                                          lock: None,
                                      },
                                      Test {
                                          name: "iron",
                                          repo: "https://github.com/iron/iron",
                                          sha: "16c858ec2901e2992fe5e529780f59fa8ed12903",
                                          lock: Some(include_str!("lockfiles/iron-Cargo.lock")),
                                      }];

fn main() {
    let args = env::args().collect::<Vec<_>>();
    let ref cargo = args[1];
    let out_dir = Path::new(&args[2]);
    let ref cargo = Path::new(cargo);

    for test in TEST_REPOS.iter().rev() {
        test_repo(cargo, out_dir, test);
    }
}

fn test_repo(cargo: &Path, out_dir: &Path, test: &Test) {
    println!("testing {}", test.repo);
    let dir = clone_repo(test, out_dir);
    if let Some(lockfile) = test.lock {
        File::create(&dir.join("Cargo.lock"))
            .expect("")
            .write_all(lockfile.as_bytes())
            .expect("");
    }
    if !run_cargo_test(cargo, &dir) {
        panic!("tests failed for {}", test.repo);
    }
}

fn clone_repo(test: &Test, out_dir: &Path) -> PathBuf {
    let out_dir = out_dir.join(test.name);

    if !out_dir.join(".git").is_dir() {
        let status = Command::new("git")
                         .arg("init")
                         .arg(&out_dir)
                         .status()
                         .expect("");
        assert!(status.success());
    }

    // Try progressively deeper fetch depths to find the commit
    let mut found = false;
    for depth in &[0, 1, 10, 100, 1000, 100000] {
        if *depth > 0 {
            let status = Command::new("git")
                             .arg("fetch")
                             .arg(test.repo)
                             .arg("master")
                             .arg(&format!("--depth={}", depth))
                             .current_dir(&out_dir)
                             .status()
                             .expect("");
            assert!(status.success());
        }

        let status = Command::new("git")
                         .arg("reset")
                         .arg(test.sha)
                         .arg("--hard")
                         .current_dir(&out_dir)
                         .status()
                         .expect("");

        if status.success() {
            found = true;
            break;
        }
    }

    if !found {
        panic!("unable to find commit {}", test.sha)
    }
    let status = Command::new("git")
                     .arg("clean")
                     .arg("-fdx")
                     .current_dir(&out_dir)
                     .status()
                     .unwrap();
    assert!(status.success());

    out_dir
}

fn run_cargo_test(cargo_path: &Path, crate_path: &Path) -> bool {
    let status = Command::new(cargo_path)
        .arg("test")
        // Disable rust-lang/cargo's cross-compile tests
        .env("CFG_DISABLE_CROSS_TESTS", "1")
        .current_dir(crate_path)
        .status()
        .expect("");

    status.success()
}
<|endoftext|>


<commit_before><commit_msg>Day 2 part 2.<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed compilation error on 32bit systems<commit_after><|endoftext|>


<commit_before><commit_msg>refactor: fixes a typo in the arg settings<commit_after><|endoftext|>


<commit_before><commit_msg>Split out filename maker.<commit_after><|endoftext|>


<commit_before><commit_msg>Add input_multiline example<commit_after>use rustyline::validate::{
    MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
};
use rustyline::{Editor, Result};
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};

#[derive(Completer, Helper, Highlighter, Hinter)]
struct InputValidator {
    brackets: MatchingBracketValidator,
}

impl Validator for InputValidator {
    fn validate(&self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
        self.brackets.validate(ctx)
    }
}

fn main() -> Result<()> {
    let h = InputValidator {
        brackets: MatchingBracketValidator::new(),
    };
    let mut rl = Editor::new();
    rl.set_helper(Some(h));

    let input = rl.readline("> ")?;
    println!("Input: {}", input);

    Ok(())
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]

extern crate getopts;
extern crate miri;
extern crate rustc;
extern crate rustc_driver;
extern crate env_logger;
extern crate log_settings;
extern crate syntax;
#[macro_use] extern crate log;

use miri::{
    EvalContext,
    CachedMir,
    step,
    EvalError,
    Frame,
};
use rustc::session::Session;
use rustc_driver::{driver, CompilerCalls, Compilation};
use rustc::ty::{TyCtxt, subst};
use rustc::hir::def_id::DefId;

struct MiriCompilerCalls;

impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
    fn build_controller(
        &mut self,
        _: &Session,
        _: &getopts::Matches
    ) -> driver::CompileController<'a> {
        let mut control = driver::CompileController::basic();

        control.after_analysis.stop = Compilation::Stop;
        control.after_analysis.callback = Box::new(|state| {
            state.session.abort_if_errors();

            let tcx = state.tcx.unwrap();
            let mir_map = state.mir_map.unwrap();

            let (node_id, span) = state.session.entry_fn.borrow().expect("no main or start function found");
            debug!("found `main` function at: {:?}", span);

            let mir = mir_map.map.get(&node_id).expect("no mir for main function");
            let def_id = tcx.map.local_def_id(node_id);
            let mut ecx = EvalContext::new(tcx, mir_map);
            let substs = tcx.mk_substs(subst::Substs::empty());
            let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs).expect("main function should not be diverging");

            ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, Some(return_ptr));

            if mir.arg_decls.len() == 2 {
                // start function
                let ptr_size = ecx.memory().pointer_size;
                let nargs = ecx.memory_mut().allocate(ptr_size);
                ecx.memory_mut().write_usize(nargs, 0).unwrap();
                let args = ecx.memory_mut().allocate(ptr_size);
                ecx.memory_mut().write_usize(args, 0).unwrap();
                ecx.frame_mut().locals[0] = nargs;
                ecx.frame_mut().locals[1] = args;
            }

            loop {
                match step(&mut ecx) {
                    Ok(true) => {}
                    Ok(false) => break,
                    // FIXME: diverging functions can end up here in some future miri
                    Err(e) => {
                        report(tcx, &ecx, e);
                        break;
                    }
                }
            }
            state.session.abort_if_errors();
        });

        control
    }
}

fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
    let frame = ecx.stack().last().expect("stackframe was empty");
    let block = &frame.mir.basic_blocks()[frame.block];
    let span = if frame.stmt < block.statements.len() {
        block.statements[frame.stmt].source_info.span
    } else {
        block.terminator().source_info.span
    };
    let mut err = tcx.sess.struct_span_err(span, &e.to_string());
    for &Frame { def_id, substs, span, .. } in ecx.stack().iter().rev() {
        // FIXME(solson): Find a way to do this without this Display impl hack.
        use rustc::util::ppaux;
        use std::fmt;
        struct Instance<'tcx>(DefId, &'tcx subst::Substs<'tcx>);
        impl<'tcx> fmt::Display for Instance<'tcx> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                ppaux::parameterized(f, self.1, self.0, ppaux::Ns::Value, &[],
                    |tcx| Some(tcx.lookup_item_type(self.0).generics))
            }
        }
        err.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
    }
    err.emit();
}

fn init_logger() {
    const NSPACES: usize = 40;
    let format = |record: &log::LogRecord| {
        if record.level() == log::LogLevel::Trace {
            // prepend spaces to indent the final string
            let indentation = log_settings::settings().indentation;
            format!("{lvl}:{module}{depth:2}{indent:<indentation$} {text}",
                lvl = record.level(),
                module = record.location().module_path(),
                depth = indentation / NSPACES,
                indentation = indentation % NSPACES,
                indent = "",
                text = record.args())
        } else {
            format!("{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.location().module_path(),
                text = record.args())
        }
    };

    let mut builder = env_logger::LogBuilder::new();
    builder.format(format).filter(None, log::LogLevelFilter::Info);

    if std::env::var("MIRI_LOG").is_ok() {
        builder.parse(&std::env::var("MIRI_LOG").unwrap());
    }

    builder.init().unwrap();
}

fn find_sysroot() -> String {
    // Taken from https://github.com/Manishearth/rust-clippy/pull/911.
    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => option_env!("RUST_SYSROOT")
            .expect("need to specify RUST_SYSROOT env var or use rustup or multirust")
            .to_owned(),
    }
}

fn main() {
    init_logger();
    let mut args: Vec<String> = std::env::args().collect();

    let sysroot_flag = String::from("--sysroot");
    if !args.contains(&sysroot_flag) {
        args.push(sysroot_flag);
        args.push(find_sysroot());
    }

    rustc_driver::run_compiler(&args, &mut MiriCompilerCalls);
}
<commit_msg>Rename max indentation constant for clarity.<commit_after>#![feature(rustc_private)]

extern crate getopts;
extern crate miri;
extern crate rustc;
extern crate rustc_driver;
extern crate env_logger;
extern crate log_settings;
extern crate syntax;
#[macro_use] extern crate log;

use miri::{
    EvalContext,
    CachedMir,
    step,
    EvalError,
    Frame,
};
use rustc::session::Session;
use rustc_driver::{driver, CompilerCalls, Compilation};
use rustc::ty::{TyCtxt, subst};
use rustc::hir::def_id::DefId;

struct MiriCompilerCalls;

impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
    fn build_controller(
        &mut self,
        _: &Session,
        _: &getopts::Matches
    ) -> driver::CompileController<'a> {
        let mut control = driver::CompileController::basic();

        control.after_analysis.stop = Compilation::Stop;
        control.after_analysis.callback = Box::new(|state| {
            state.session.abort_if_errors();

            let tcx = state.tcx.unwrap();
            let mir_map = state.mir_map.unwrap();

            let (node_id, span) = state.session.entry_fn.borrow().expect("no main or start function found");
            debug!("found `main` function at: {:?}", span);

            let mir = mir_map.map.get(&node_id).expect("no mir for main function");
            let def_id = tcx.map.local_def_id(node_id);
            let mut ecx = EvalContext::new(tcx, mir_map);
            let substs = tcx.mk_substs(subst::Substs::empty());
            let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs).expect("main function should not be diverging");

            ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, Some(return_ptr));

            if mir.arg_decls.len() == 2 {
                // start function
                let ptr_size = ecx.memory().pointer_size;
                let nargs = ecx.memory_mut().allocate(ptr_size);
                ecx.memory_mut().write_usize(nargs, 0).unwrap();
                let args = ecx.memory_mut().allocate(ptr_size);
                ecx.memory_mut().write_usize(args, 0).unwrap();
                ecx.frame_mut().locals[0] = nargs;
                ecx.frame_mut().locals[1] = args;
            }

            loop {
                match step(&mut ecx) {
                    Ok(true) => {}
                    Ok(false) => break,
                    // FIXME: diverging functions can end up here in some future miri
                    Err(e) => {
                        report(tcx, &ecx, e);
                        break;
                    }
                }
            }
            state.session.abort_if_errors();
        });

        control
    }
}

fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
    let frame = ecx.stack().last().expect("stackframe was empty");
    let block = &frame.mir.basic_blocks()[frame.block];
    let span = if frame.stmt < block.statements.len() {
        block.statements[frame.stmt].source_info.span
    } else {
        block.terminator().source_info.span
    };
    let mut err = tcx.sess.struct_span_err(span, &e.to_string());
    for &Frame { def_id, substs, span, .. } in ecx.stack().iter().rev() {
        // FIXME(solson): Find a way to do this without this Display impl hack.
        use rustc::util::ppaux;
        use std::fmt;
        struct Instance<'tcx>(DefId, &'tcx subst::Substs<'tcx>);
        impl<'tcx> fmt::Display for Instance<'tcx> {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                ppaux::parameterized(f, self.1, self.0, ppaux::Ns::Value, &[],
                    |tcx| Some(tcx.lookup_item_type(self.0).generics))
            }
        }
        err.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
    }
    err.emit();
}

fn init_logger() {
    const MAX_INDENT: usize = 40;

    let format = |record: &log::LogRecord| {
        if record.level() == log::LogLevel::Trace {
            // prepend spaces to indent the final string
            let indentation = log_settings::settings().indentation;
            format!("{lvl}:{module}{depth:2}{indent:<indentation$} {text}",
                lvl = record.level(),
                module = record.location().module_path(),
                depth = indentation / MAX_INDENT,
                indentation = indentation % MAX_INDENT,
                indent = "",
                text = record.args())
        } else {
            format!("{lvl}:{module}: {text}",
                lvl = record.level(),
                module = record.location().module_path(),
                text = record.args())
        }
    };

    let mut builder = env_logger::LogBuilder::new();
    builder.format(format).filter(None, log::LogLevelFilter::Info);

    if std::env::var("MIRI_LOG").is_ok() {
        builder.parse(&std::env::var("MIRI_LOG").unwrap());
    }

    builder.init().unwrap();
}

fn find_sysroot() -> String {
    // Taken from https://github.com/Manishearth/rust-clippy/pull/911.
    let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
    let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
    match (home, toolchain) {
        (Some(home), Some(toolchain)) => format!("{}/toolchains/{}", home, toolchain),
        _ => option_env!("RUST_SYSROOT")
            .expect("need to specify RUST_SYSROOT env var or use rustup or multirust")
            .to_owned(),
    }
}

fn main() {
    init_logger();
    let mut args: Vec<String> = std::env::args().collect();

    let sysroot_flag = String::from("--sysroot");
    if !args.contains(&sysroot_flag) {
        args.push(sysroot_flag);
        args.push(find_sysroot());
    }

    rustc_driver::run_compiler(&args, &mut MiriCompilerCalls);
}
<|endoftext|>