<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use string_cache::Atom;
use webrender_traits::NativeFontHandle;

#[derive(Deserialize, Serialize, Debug)]
pub struct FontTemplateData {
    pub bytes: Vec<u8>,
    pub identifier: Atom,
}

impl FontTemplateData {
    pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> FontTemplateData {
        let bytes = match font_data {
            Some(bytes) => {
                bytes
            },
            None => {
                unimplemented!()
            }
        };

        FontTemplateData {
            bytes: bytes,
            identifier: identifier,
        }
    }
    pub fn bytes(&self) -> Vec<u8> {
        self.bytes.clone()
    }
    pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
        Some(self.bytes())
    }
    pub fn native_font(&self) -> Option<NativeFontHandle> {
        None
    }
}
<commit_msg>Auto merge of #13322 - jdm:msvc-build-fix, r=KiChjang<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::io::Error;
use string_cache::Atom;
use webrender_traits::NativeFontHandle;

#[derive(Deserialize, Serialize, Debug)]
pub struct FontTemplateData {
    pub bytes: Vec<u8>,
    pub identifier: Atom,
}

impl FontTemplateData {
    pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> Result<FontTemplateData, Error> {
        let bytes = match font_data {
            Some(bytes) => {
                bytes
            },
            None => {
                unimplemented!()
            }
        };

        Ok(FontTemplateData {
            bytes: bytes,
            identifier: identifier,
        })
    }
    pub fn bytes(&self) -> Vec<u8> {
        self.bytes.clone()
    }
    pub fn bytes_if_in_memory(&self) -> Option<Vec<u8>> {
        Some(self.bytes())
    }
    pub fn native_font(&self) -> Option<NativeFontHandle> {
        None
    }
}
<|endoftext|>


<commit_before>extern crate gui;

use std::collections::DList;
use gui::components::*;
use gui::{Widget, Context, App};

//this is the model which will be rendered

#[derive(Show)]
pub struct Task{
    pub done: bool,
    ///the description of the Task
    pub desc: String,
}

impl Widget for Task{
    fn render(&self, ctx: &mut Context){
        println!("render Task");
        ctx.add(1, Label::new(self.desc.as_slice()).font_size(16.0));
    }
}

#[derive(Show)]
pub struct TodoApp{
    ///All Tasks
    pub tasks: DList<Task>,
    ///value for the task going to be inserted
    pub input: String,
}
impl TodoApp{
    fn new() -> TodoApp{
        TodoApp{
            tasks: DList::new(),
            input: String::new(),
        }
    }
    /// append a new task to the todo list
    fn appendItem(&mut self, desc: &str){
        self.tasks.push_back(Task{
            done: false,
            desc: desc.to_string(),
        });
    }
}
impl App for TodoApp{
    fn render(&mut self, ctx: &mut Context){
        ctx.draw(|cr|{//make background gray
            cr.set_source_rgb(0.18, 0.18, 0.18);
            cr.paint();
        });
        ctx.add(1, Label::new("test-label").font_size(100.0).font_face("Arial"));
        ctx.add(2, &Button::new("test-button",100.0,20.0));
        let mut i = 3;
        for task in self.tasks.iter(){
            ctx.add(i, task);
            i+=1;
        }
        println!("do the Work of drawing.");
    }
}

fn main(){
    let mut ta = TodoApp::new();
    ta.appendItem("Sichtbar Machen");
    ta.appendItem("Hausaufgaben erledigen");
    gui::Window::new("todo-app", 480, 640).app(&mut ta);
}
<commit_msg>fix warning<commit_after>extern crate gui;

use std::collections::DList;
use gui::components::*;
use gui::{Widget, Context, App};

//this is the model which will be rendered

#[derive(Debug)]
pub struct Task{
    pub done: bool,
    ///the description of the Task
    pub desc: String,
}

impl Widget for Task{
    fn render(&self, ctx: &mut Context){
        println!("render Task");
        ctx.add(1, Label::new(&self.desc[0..]).font_size(16.0));
    }
}

#[derive(Show)]
pub struct TodoApp{
    ///All Tasks
    pub tasks: DList<Task>,
    ///value for the task going to be inserted
    pub input: String,
}
impl TodoApp{
    fn new() -> TodoApp{
        TodoApp{
            tasks: DList::new(),
            input: String::new(),
        }
    }
    /// append a new task to the todo list
    fn append_item(&mut self, desc: &str){
        self.tasks.push_back(Task{
            done: false,
            desc: desc.to_string(),
        });
    }
}
impl App for TodoApp{
    fn render(&mut self, ctx: &mut Context){
        ctx.draw(|cr|{//make background gray
            cr.set_source_rgb(0.18, 0.18, 0.18);
            cr.paint();
        });
        ctx.add(1, Label::new("test-label").font_size(100.0).font_face("Arial"));
        ctx.add(2, &Button::new("test-button",100.0,20.0));
        let mut i = 3;
        for task in self.tasks.iter(){
            ctx.add(i, task);
            i+=1;
        }
        println!("do the Work of drawing.");
    }
}

fn main(){
    let mut ta = TodoApp::new();
    ta.append_item("Sichtbar Machen");
    ta.append_item("Hausaufgaben erledigen");
    gui::Window::new("todo-app", 480, 640).app(&mut ta);
}
<|endoftext|>


<commit_before>use super::from_bytes::FromBytes;

const SPACE_MAP_HISTOGRAM_SIZE: usize = 32;

#[derive(Debug)]
pub struct SpaceMapPhys {
    object: u64,   // on-disk space map object
    objsize: u64,  // size of the object
    alloc: u64,    // space allocated from the map
    pad: [u64; 5], // reserved

    /*
     * The smp_histogram maintains a histogram of free regions. Each
     * bucket, smp_histogram[i], contains the number of free regions
     * whose size is:
     * 2^(i+sm_shift) <= size of free region in bytes < 2^(i+sm_shift+1)
     */
    histogram: [u64; SPACE_MAP_HISTOGRAM_SIZE],
}

impl FromBytes for SpaceMapPhys { }
<commit_msg>Documentation for SpaceMapPhys<commit_after>use super::from_bytes::FromBytes;

const SPACE_MAP_HISTOGRAM_SIZE: usize = 32;

/// The `SpaceMapPhys` is the on-disk representation of the space map.
/// Consumers of space maps should never reference any of the members of this
/// structure directly. These members may only be updated in syncing context.
///
/// Note the smp_object is no longer used but remains in the structure
/// for backward compatibility.
///
/// The smp_histogram maintains a histogram of free regions. Each
/// bucket, smp_histogram[i], contains the number of free regions
/// whose size is:
/// 2^(i+sm_shift) <= size of free region in bytes < 2^(i+sm_shift+1)

#[derive(Debug)]
pub struct SpaceMapPhys {
    object: u64,   // on-disk space map object
    objsize: u64,  // size of the object
    alloc: u64,    // space allocated from the map
    pad: [u64; 5], // reserved
    histogram: [u64; SPACE_MAP_HISTOGRAM_SIZE],
}

impl FromBytes for SpaceMapPhys { }
<|endoftext|>


<commit_before>extern crate gcc;
extern crate bindgen;
#[cfg(feature = "static")]
extern crate meson;
extern crate gl_generator;

use std::env;
#[allow(unused_imports)]
use std::path::{Path, PathBuf};
use std::fs::File;
use gl_generator::{Registry, Api, Profile, Fallbacks, StaticGenerator};

fn main() {
    let generated = bindgen::builder()
        .derive_debug(true)
        .derive_default(true)
        .generate_comments(true)
        .header("src/wlroots.h")
        .whitelisted_type(r"^wlr_.*$")
        .whitelisted_type(r"^xkb_.*$")
        .whitelisted_function(r"^wlr_.*$")
        .whitelisted_function(r"^xkb_.*$")
        .ctypes_prefix("libc")
        .clang_arg("-Iwlroots/include")
        .clang_arg("-Iwlroots/include/wlr")
        .clang_arg("-Iwlroots/include/xcursor")
        .clang_arg("-I/usr/include/pixman-1")
        // Work around bug https://github.com/rust-lang-nursery/rust-bindgen/issues/687
        .hide_type("FP_NAN")
        .hide_type("FP_INFINITE")
        .hide_type("FP_ZERO")
        .hide_type("FP_SUBNORMAL")
        .hide_type("FP_NORMAL")
        .generate().unwrap();

    println!("cargo:rustc-link-lib=dylib=X11");
    println!("cargo:rustc-link-lib=dylib=X11-xcb");
    println!("cargo:rustc-link-lib=dylib=xkbcommon");
    println!("cargo:rustc-link-lib=dylib=xcb");
    println!("cargo:rustc-link-lib=dylib=cap");
    println!("cargo:rustc-link-lib=dylib=wayland-egl");
    println!("cargo:rustc-link-lib=dylib=wayland-client");
    println!("cargo:rustc-link-lib=dylib=wayland-server");
    println!("cargo:rustc-link-lib=dylib=EGL");
    println!("cargo:rustc-link-lib=dylib=GL");
    println!("cargo:rustc-link-lib=dylib=gbm");
    println!("cargo:rustc-link-lib=dylib=drm");
    println!("cargo:rustc-link-lib=dylib=input");
    println!("cargo:rustc-link-lib=dylib=udev");
    println!("cargo:rustc-link-lib=dylib=systemd");
    println!("cargo:rustc-link-lib=dylib=dbus-1");
    println!("cargo:rustc-link-lib=dylib=pixman-1");

    if !cfg!(feature = "static") {
        println!("cargo:rustc-link-lib=dylib=wlroots");
        println!("cargo:rustc-link-search=native=/usr/local/lib");
    }

    // generate the bindings
    generated.write_to_file("src/gen.rs").unwrap();

    meson();

    if cfg!(feature = "example") {

        // Example Khronos building stuff
        let dest = env::var("OUT_DIR").unwrap();
        let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap();
        Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
            .write_bindings(StaticGenerator, &mut file)
            .unwrap();

        // Build share.d for examples
        let example_generated = bindgen::builder()
            .derive_debug(true)
            .derive_default(true)
            .generate_comments(true)
            .header("wlroots/examples/shared.h")
            .clang_arg("-Iwlroots/include")
            .clang_arg("-Iwlroots/include/wlr")
            .clang_arg("-Iwlroots/include/xcursor")
            .clang_arg("-I/usr/include/pixman-1")
            // Work around bug https://github.com/rust-lang-nursery/rust-bindgen/issues/687
            .hide_type("FP_NAN")
            .hide_type("FP_INFINITE")
            .hide_type("FP_ZERO")
            .hide_type("FP_SUBNORMAL")
            .hide_type("FP_NORMAL")
            .generate().unwrap();
        example_generated.write_to_file(format!("{}/shared.rs", dest)).unwrap();

        // Build shared.c for examples
        let mut config = gcc::Build::new();
        config.flag("-Wall");
        config.flag("-Wpedantic");
        config.flag("-Iwlroots/include");
        config.flag("-Iwlroots/include/wlr");
        config.file("wlroots/examples/shared.c");
        config.compile("libshared.a");

        // Link against libpam
        println!("cargo:rustc-flags=-l shared")
    }
}

#[cfg(not(feature = "static"))]
fn meson() {}

#[cfg(feature = "static")]
fn meson() {
    let build_path = PathBuf::from(env::var("OUT_DIR")
        .expect("Could not get OUT_DIR env variable"));
    build_path.join("build");
    let build_path_str = build_path.to_str()
        .expect("Could not turn build path into a string");
    println!("cargo:rustc-link-search=native=wlroots");
    println!("cargo:rustc-link-search=native={}/lib", build_path_str);
    println!("cargo:rustc-link-search=native={}/lib64", build_path_str);
    println!("cargo:rustc-link-search=native={}/build/", build_path_str);
    if cfg!(feature = "static") {
        println!("cargo:rustc-link-search=native={}/util/", build_path_str);
        println!("cargo:rustc-link-search=native={}/types/", build_path_str);
        println!("cargo:rustc-link-search=native={}/protocol/", build_path_str);
        println!("cargo:rustc-link-search=native={}/xcursor/", build_path_str);
        println!("cargo:rustc-link-search=native={}/xwayland/", build_path_str);
        println!("cargo:rustc-link-search=native={}/backend/", build_path_str);
        println!("cargo:rustc-link-search=native={}/render/", build_path_str);

        println!("cargo:rustc-link-lib=static=wlr_util");
        println!("cargo:rustc-link-lib=static=wlr_types");
        println!("cargo:rustc-link-lib=static=wlr_xcursor");
        println!("cargo:rustc-link-lib=static=wlr_xwayland");
        println!("cargo:rustc-link-lib=static=wlr_backend");
        println!("cargo:rustc-link-lib=static=wlr_render");
        // wayland protocols
        println!("cargo:rustc-link-lib=static=wl_protos");
    }

    meson::build("wlroots", build_path_str);
}
<commit_msg>Whitelisted _wlr functions (e.g _wlr_log)<commit_after>extern crate gcc;
extern crate bindgen;
#[cfg(feature = "static")]
extern crate meson;
extern crate gl_generator;

use std::env;
#[allow(unused_imports)]
use std::path::{Path, PathBuf};
use std::fs::File;
use gl_generator::{Registry, Api, Profile, Fallbacks, StaticGenerator};

fn main() {
    let generated = bindgen::builder()
        .derive_debug(true)
        .derive_default(true)
        .generate_comments(true)
        .header("src/wlroots.h")
        .whitelisted_type(r"^wlr_.*$")
        .whitelisted_type(r"^xkb_.*$")
        .whitelisted_function(r"^_?wlr_.*$")
        .whitelisted_function(r"^xkb_.*$")
        .ctypes_prefix("libc")
        .clang_arg("-Iwlroots/include")
        .clang_arg("-Iwlroots/include/wlr")
        .clang_arg("-Iwlroots/include/xcursor")
        .clang_arg("-I/usr/include/pixman-1")
        // Work around bug https://github.com/rust-lang-nursery/rust-bindgen/issues/687
        .hide_type("FP_NAN")
        .hide_type("FP_INFINITE")
        .hide_type("FP_ZERO")
        .hide_type("FP_SUBNORMAL")
        .hide_type("FP_NORMAL")
        .generate().unwrap();

    println!("cargo:rustc-link-lib=dylib=X11");
    println!("cargo:rustc-link-lib=dylib=X11-xcb");
    println!("cargo:rustc-link-lib=dylib=xkbcommon");
    println!("cargo:rustc-link-lib=dylib=xcb");
    println!("cargo:rustc-link-lib=dylib=cap");
    println!("cargo:rustc-link-lib=dylib=wayland-egl");
    println!("cargo:rustc-link-lib=dylib=wayland-client");
    println!("cargo:rustc-link-lib=dylib=wayland-server");
    println!("cargo:rustc-link-lib=dylib=EGL");
    println!("cargo:rustc-link-lib=dylib=GL");
    println!("cargo:rustc-link-lib=dylib=gbm");
    println!("cargo:rustc-link-lib=dylib=drm");
    println!("cargo:rustc-link-lib=dylib=input");
    println!("cargo:rustc-link-lib=dylib=udev");
    println!("cargo:rustc-link-lib=dylib=systemd");
    println!("cargo:rustc-link-lib=dylib=dbus-1");
    println!("cargo:rustc-link-lib=dylib=pixman-1");

    if !cfg!(feature = "static") {
        println!("cargo:rustc-link-lib=dylib=wlroots");
        println!("cargo:rustc-link-search=native=/usr/local/lib");
    }

    // generate the bindings
    generated.write_to_file("src/gen.rs").unwrap();

    meson();

    if cfg!(feature = "example") {

        // Example Khronos building stuff
        let dest = env::var("OUT_DIR").unwrap();
        let mut file = File::create(&Path::new(&dest).join("bindings.rs")).unwrap();
        Registry::new(Api::Gl, (4, 5), Profile::Core, Fallbacks::All, [])
            .write_bindings(StaticGenerator, &mut file)
            .unwrap();

        // Build share.d for examples
        let example_generated = bindgen::builder()
            .derive_debug(true)
            .derive_default(true)
            .generate_comments(true)
            .header("wlroots/examples/shared.h")
            .clang_arg("-Iwlroots/include")
            .clang_arg("-Iwlroots/include/wlr")
            .clang_arg("-Iwlroots/include/xcursor")
            .clang_arg("-I/usr/include/pixman-1")
            // Work around bug https://github.com/rust-lang-nursery/rust-bindgen/issues/687
            .hide_type("FP_NAN")
            .hide_type("FP_INFINITE")
            .hide_type("FP_ZERO")
            .hide_type("FP_SUBNORMAL")
            .hide_type("FP_NORMAL")
            .generate().unwrap();
        example_generated.write_to_file(format!("{}/shared.rs", dest)).unwrap();

        // Build shared.c for examples
        let mut config = gcc::Build::new();
        config.flag("-Wall");
        config.flag("-Wpedantic");
        config.flag("-Iwlroots/include");
        config.flag("-Iwlroots/include/wlr");
        config.file("wlroots/examples/shared.c");
        config.compile("libshared.a");

        // Link against libpam
        println!("cargo:rustc-flags=-l shared")
    }
}

#[cfg(not(feature = "static"))]
fn meson() {}

#[cfg(feature = "static")]
fn meson() {
    let build_path = PathBuf::from(env::var("OUT_DIR")
        .expect("Could not get OUT_DIR env variable"));
    build_path.join("build");
    let build_path_str = build_path.to_str()
        .expect("Could not turn build path into a string");
    println!("cargo:rustc-link-search=native=wlroots");
    println!("cargo:rustc-link-search=native={}/lib", build_path_str);
    println!("cargo:rustc-link-search=native={}/lib64", build_path_str);
    println!("cargo:rustc-link-search=native={}/build/", build_path_str);
    if cfg!(feature = "static") {
        println!("cargo:rustc-link-search=native={}/util/", build_path_str);
        println!("cargo:rustc-link-search=native={}/types/", build_path_str);
        println!("cargo:rustc-link-search=native={}/protocol/", build_path_str);
        println!("cargo:rustc-link-search=native={}/xcursor/", build_path_str);
        println!("cargo:rustc-link-search=native={}/xwayland/", build_path_str);
        println!("cargo:rustc-link-search=native={}/backend/", build_path_str);
        println!("cargo:rustc-link-search=native={}/render/", build_path_str);

        println!("cargo:rustc-link-lib=static=wlr_util");
        println!("cargo:rustc-link-lib=static=wlr_types");
        println!("cargo:rustc-link-lib=static=wlr_xcursor");
        println!("cargo:rustc-link-lib=static=wlr_xwayland");
        println!("cargo:rustc-link-lib=static=wlr_backend");
        println!("cargo:rustc-link-lib=static=wlr_render");
        // wayland protocols
        println!("cargo:rustc-link-lib=static=wl_protos");
    }

    meson::build("wlroots", build_path_str);
}
<|endoftext|>


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

extern crate rusoto_core;
extern crate rusoto_lambda;

use rusoto_lambda::{Lambda, LambdaClient, ListFunctionsRequest, InvocationRequest, InvokeError};
use rusoto_core::Region;

#[test]
fn should_list_functions() {
    let client = LambdaClient::new(Region::UsEast1);
    let request = ListFunctionsRequest::default();

    let result = client.list_functions(request).sync().unwrap();
    println!("{:#?}", result);
}

#[test]
fn should_function_not_found() {
    let client = LambdaClient::new(Region::UsEast1);
    {
        let request = InvocationRequest{
            function_name: "no-such-a-function".to_string(),
            invocation_type: Some("RequestResponse".to_string()),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::Unknown(resp)) = result {
            assert_eq!(resp.status, 404);
        }else{
            assert!(false, format!("expect Err(InvokeError::Unknown(_), found {:?}", result));
        }
    }
    {
        // ARN with colons
        let request = InvocationRequest{
            function_name: "function:no-such-a-function".to_string(),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::Unknown(resp)) = result {
            assert_eq!(resp.status, 404);
        }else{
            assert!(false, format!("expect Err(InvokeError::Unknown(_), found {:?}", result));
        }
    }
}
<commit_msg>Fix Lambda integration test.<commit_after>#![cfg(feature = "lambda")]

extern crate rusoto_core;
extern crate rusoto_lambda;

use rusoto_lambda::{Lambda, LambdaClient, ListFunctionsRequest, InvocationRequest, InvokeError};
use rusoto_core::Region;

#[test]
fn should_list_functions() {
    let client = LambdaClient::new(Region::UsEast1);
    let request = ListFunctionsRequest::default();

    let result = client.list_functions(request).sync().unwrap();
    println!("{:#?}", result);
}

#[test]
fn should_function_not_found() {
    let client = LambdaClient::new(Region::UsEast1);
    {
        let request = InvocationRequest{
            function_name: "no-such-a-function".to_string(),
            invocation_type: Some("RequestResponse".to_string()),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::ResourceNotFound(resp)) = result {
            assert!(resp.contains("Function not found:"));
        } else {
            assert!(false, format!("expect Err(InvokeError::ResourceNotFound(_), found {:?}", result));
        }
    }
    {
        // ARN with colons
        let request = InvocationRequest{
            function_name: "function:no-such-a-function".to_string(),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::ResourceNotFound(resp)) = result {
            assert!(resp.contains("Function not found:"));
        } else {
            assert!(false, format!("expect Err(InvokeError::ResourceNotFound(_), found {:?}", result));
        }
    }
}
<|endoftext|>


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

extern crate rusoto_core;
extern crate rusoto_lambda;

use rusoto_lambda::{Lambda, LambdaClient, ListFunctionsRequest};
use rusoto_core::Region;

#[test]
fn should_list_functions() {
    let client = LambdaClient::new(Region::UsEast1);
    let request = ListFunctionsRequest::default();

    let result = client.list_functions(request).sync().unwrap();
    println!("{:#?}", result);
}
<commit_msg>add lambda invoke test<commit_after>#![cfg(feature = "lambda")]

extern crate rusoto_core;
extern crate rusoto_lambda;

use rusoto_lambda::{Lambda, LambdaClient, ListFunctionsRequest, InvocationRequest, InvokeError};
use rusoto_core::Region;

#[test]
fn should_list_functions() {
    let client = LambdaClient::new(Region::UsEast1);
    let request = ListFunctionsRequest::default();

    let result = client.list_functions(request).sync().unwrap();
    println!("{:#?}", result);
}

#[test]
fn should_function_not_found() {
    let client = LambdaClient::new(Region::UsEast1);
    {
        let request = InvocationRequest{
            function_name: "no-such-a-function".to_string(),
            invocation_type: Some("RequestResponse".to_string()),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::Unknown(resp)) = result {
            assert_eq!(resp.status, 404);
        }else{
            assert!(false, format!("expect Err(InvokeError::Unknown(_), found {:?}", result));
        }
    }
    {
        // ARN with colons
        let request = InvocationRequest{
            function_name: "function:no-such-a-function".to_string(),
            ..Default::default()
        };

        let result = client.invoke(request).sync();

        assert!(result.is_err());
        if let Err(InvokeError::Unknown(resp)) = result {
            assert_eq!(resp.status, 404);
        }else{
            assert!(false, format!("expect Err(InvokeError::Unknown(_), found {:?}", result));
        }
    }
}
<|endoftext|>


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

//! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
//!
//! Rust targets a wide variety of usecases, and in the interest of flexibility,
//! allows new target triples to be defined in configuration files. Most users
//! will not need to care about these, but this is invaluable when porting Rust
//! to a new platform, and allows for an unprecedented level of control over how
//! the compiler works.
//!
//! # Using custom targets
//!
//! A target triple, as passed via `rustc --target=TRIPLE`, will first be
//! compared against the list of built-in targets. This is to ease distributing
//! rustc (no need for configuration files) and also to hold these built-in
//! targets as immutable and sacred. If `TRIPLE` is not one of the built-in
//! targets, rustc will check if a file named `TRIPLE` exists. If it does, it
//! will be loaded as the target configuration. If the file does not exist,
//! rustc will search each directory in the environment variable
//! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will
//! be loaded. If no file is found in any of those directories, a fatal error
//! will be given.  `RUST_TARGET_PATH` includes `/etc/rustc` as its last entry,
//! to be searched by default.
//!
//! Projects defining their own targets should use
//! `--target=path/to/my-awesome-platform.json` instead of adding to
//! `RUST_TARGET_PATH`.
//!
//! # Defining a new target
//!
//! Targets are defined using [JSON](http://json.org/). The `Target` struct in
//! this module defines the format the JSON file should take, though each
//! underscore in the field names should be replaced with a hyphen (`-`) in the
//! JSON file. Some fields are required in every target specification, such as
//! `data-layout`, `llvm-target`, `target-endian`, `target-word-size`, and
//! `arch`. In general, options passed to rustc with `-C` override the target's
//! settings, though `target-feature` and `link-args` will *add* to the list
//! specified by the target, rather than replace.

use serialize::json::Json;
use syntax::{diagnostic, abi};
use std::default::Default;
use std::io::fs::PathExtensions;

mod windows_base;
mod linux_base;
mod apple_base;
mod freebsd_base;
mod dragonfly_base;

mod arm_apple_ios;
mod arm_linux_androideabi;
mod arm_unknown_linux_gnueabi;
mod arm_unknown_linux_gnueabihf;
mod i686_apple_darwin;
mod i386_apple_ios;
mod i686_pc_windows_gnu;
mod i686_unknown_dragonfly;
mod i686_unknown_linux_gnu;
mod mips_unknown_linux_gnu;
mod mipsel_unknown_linux_gnu;
mod x86_64_apple_darwin;
mod x86_64_pc_windows_gnu;
mod x86_64_unknown_freebsd;
mod x86_64_unknown_dragonfly;
mod x86_64_unknown_linux_gnu;

/// Everything `rustc` knows about how to compile for a specific target.
///
/// Every field here must be specified, and has no default value.
#[deriving(Clone, Show)]
pub struct Target {
    /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
    pub data_layout: String,
    /// Target triple to pass to LLVM.
    pub llvm_target: String,
    /// String to use as the `target_endian` `cfg` variable.
    pub target_endian: String,
    /// String to use as the `target_word_size` `cfg` variable.
    pub target_word_size: String,
    /// OS name to use for conditional compilation.
    pub target_os: String,
    /// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm", and
    /// "mips". "mips" includes "mipsel".
    pub arch: String,
    /// Optional settings with defaults.
    pub options: TargetOptions,
}

/// Optional aspects of a target specification.
///
/// This has an implementation of `Default`, see each field for what the default is. In general,
/// these try to take "minimal defaults" that don't assume anything about the runtime they run in.
#[deriving(Clone, Show)]
pub struct TargetOptions {
    /// Linker to invoke. Defaults to "cc".
    pub linker: String,
    /// Linker arguments that are unconditionally passed *before* any user-defined libraries.
    pub pre_link_args: Vec<String>,
    /// Linker arguments that are unconditionally passed *after* any user-defined libraries.
    pub post_link_args: Vec<String>,
    /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults to "default".
    pub cpu: String,
    /// Default target features to pass to LLVM. These features will *always* be passed, and cannot
    /// be disabled even via `-C`. Corresponds to `llc -mattr=$features`.
    pub features: String,
    /// Whether dynamic linking is available on this target. Defaults to false.
    pub dynamic_linking: bool,
    /// Whether executables are available on this target. iOS, for example, only allows static
    /// libraries. Defaults to false.
    pub executables: bool,
    /// Whether LLVM's segmented stack prelude is supported by whatever runtime is available.
    /// Will emit stack checks and calls to __morestack. Defaults to false.
    pub morestack: bool,
    /// Relocation model to use in object file. Corresponds to `llc
    /// -relocation-model=$relocation_model`. Defaults to "pic".
    pub relocation_model: String,
    /// Code model to use. Corresponds to `llc -code-model=$code_model`. Defaults to "default".
    pub code_model: String,
    /// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
    pub disable_redzone: bool,
    /// Eliminate frame pointers from stack frames if possible. Defaults to true.
    pub eliminate_frame_pointer: bool,
    /// Emit each function in its own section. Defaults to true.
    pub function_sections: bool,
    /// String to prepend to the name of every dynamic library. Defaults to "lib".
    pub dll_prefix: String,
    /// String to append to the name of every dynamic library. Defaults to ".so".
    pub dll_suffix: String,
    /// String to append to the name of every executable.
    pub exe_suffix: String,
    /// String to prepend to the name of every static library. Defaults to "lib".
    pub staticlib_prefix: String,
    /// String to append to the name of every static library. Defaults to ".a".
    pub staticlib_suffix: String,
    /// Whether the target toolchain is like OSX's. Only useful for compiling against iOS/OS X, in
    /// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
    pub is_like_osx: bool,
    /// Whether the target toolchain is like Windows'. Only useful for compiling against Windows,
    /// only realy used for figuring out how to find libraries, since Windows uses its own
    /// library naming convention. Defaults to false.
    pub is_like_windows: bool,
    /// Whether the linker support GNU-like arguments such as -O. Defaults to false.
    pub linker_is_gnu: bool,
    /// Whether the linker support rpaths or not. Defaults to false.
    pub has_rpath: bool,
    /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM will emit references
    /// to the functions that compiler-rt provides.
    pub no_compiler_rt: bool,
    /// Dynamically linked executables can be compiled as position independent if the default
    /// relocation model of position independent code is not changed. This is a requirement to take
    /// advantage of ASLR, as otherwise the functions in the executable are not randomized and can
    /// be used during an exploit of a vulnerability in any code.
    pub position_independent_executables: bool,
}

impl Default for TargetOptions {
    /// Create a set of "sane defaults" for any target. This is still incomplete, and if used for
    /// compilation, will certainly not work.
    fn default() -> TargetOptions {
        TargetOptions {
            linker: "cc".to_string(),
            pre_link_args: Vec::new(),
            post_link_args: Vec::new(),
            cpu: "generic".to_string(),
            features: "".to_string(),
            dynamic_linking: false,
            executables: false,
            morestack: false,
            relocation_model: "pic".to_string(),
            code_model: "default".to_string(),
            disable_redzone: false,
            eliminate_frame_pointer: true,
            function_sections: true,
            dll_prefix: "lib".to_string(),
            dll_suffix: ".so".to_string(),
            exe_suffix: "".to_string(),
            staticlib_prefix: "lib".to_string(),
            staticlib_suffix: ".a".to_string(),
            is_like_osx: false,
            is_like_windows: false,
            linker_is_gnu: false,
            has_rpath: false,
            no_compiler_rt: false,
            position_independent_executables: false,
        }
    }
}

impl Target {
    /// Given a function ABI, turn "System" into the correct ABI for this target.
    pub fn adjust_abi(&self, abi: abi::Abi) -> abi::Abi {
        match abi {
            abi::System => {
                if self.options.is_like_windows && self.arch == "x86" {
                    abi::Stdcall
                } else {
                    abi::C
                }
            },
            abi => abi
        }
    }

    /// Load a target descriptor from a JSON object.
    pub fn from_json(obj: Json) -> Target {
        // this is 1. ugly, 2. error prone.

        let handler = diagnostic::default_handler(diagnostic::Auto, None);

        let get_req_field = |name: &str| {
            match obj.find(name)
                     .map(|s| s.as_string())
                     .and_then(|os| os.map(|s| s.to_string())) {
                Some(val) => val,
                None =>
                    handler.fatal((format!("Field {} in target specification is required", name))
                                  [])
            }
        };

        let mut base = Target {
            data_layout: get_req_field("data-layout"),
            llvm_target: get_req_field("llvm-target"),
            target_endian: get_req_field("target-endian"),
            target_word_size: get_req_field("target-word-size"),
            arch: get_req_field("arch"),
            target_os: get_req_field("os"),
            options: Default::default(),
        };

        macro_rules! key (
            ($key_name:ident) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_string()
                                    .map(|s| base.options.$key_name = s.to_string()));
            } );
            ($key_name:ident, bool) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_boolean().map(|s| base.options.$key_name = s));
            } );
            ($key_name:ident, list) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_array()
                    .map(|v| base.options.$key_name = v.iter()
                        .map(|a| a.as_string().unwrap().to_string()).collect()
                        )
                    );
            } );
        );

        key!(cpu);
        key!(linker);
        key!(relocation_model);
        key!(code_model);
        key!(dll_prefix);
        key!(dll_suffix);
        key!(exe_suffix);
        key!(staticlib_prefix);
        key!(staticlib_suffix);
        key!(features);
        key!(dynamic_linking, bool);
        key!(executables, bool);
        key!(morestack, bool);
        key!(disable_redzone, bool);
        key!(eliminate_frame_pointer, bool);
        key!(function_sections, bool);
        key!(is_like_osx, bool);
        key!(is_like_windows, bool);
        key!(linker_is_gnu, bool);
        key!(has_rpath, bool);
        key!(no_compiler_rt, bool);
        key!(pre_link_args, list);
        key!(post_link_args, list);

        base
    }

    /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
    /// could also just be a bare filename already, so also check for that. If one of the hardcoded
    /// targets we know about, just return it directly.
    ///
    /// The error string could come from any of the APIs called, including filesystem access and
    /// JSON decoding.
    pub fn search(target: &str) -> Result<Target, String> {
        use std::os;
        use std::io::File;
        use std::path::Path;
        use serialize::json;

        fn load_file(path: &Path) -> Result<Target, String> {
            let mut f = try!(File::open(path).map_err(|e| e.to_string()));
            let obj = try!(json::from_reader(&mut f).map_err(|e| e.to_string()));
            Ok(Target::from_json(obj))
        }

        // this would use a match if stringify! were allowed in pattern position
        macro_rules! load_specific (
            ( $($name:ident),+ ) => (
                {
                    let target = target.replace("-", "_");
                    if false { }
                    $(
                        else if target == stringify!($name) {
                            let t = $name::target();
                            debug!("Got builtin target: {}", t);
                            return Ok(t);
                        }
                    )*
                    else if target == "x86_64-w64-mingw32" {
                        let t = x86_64_pc_windows_gnu::target();
                        return Ok(t);
                    } else if target == "i686-w64-mingw32" {
                        let t = i686_pc_windows_gnu::target();
                        return Ok(t);
                    }
                }
            )
        );

        load_specific!(
            x86_64_unknown_linux_gnu,
            i686_unknown_linux_gnu,
            mips_unknown_linux_gnu,
            mipsel_unknown_linux_gnu,
            arm_linux_androideabi,
            arm_unknown_linux_gnueabi,
            arm_unknown_linux_gnueabihf,

            x86_64_unknown_freebsd,

            i686_unknown_dragonfly,
            x86_64_unknown_dragonfly,

            x86_64_apple_darwin,
            i686_apple_darwin,
            i386_apple_ios,
            arm_apple_ios,

            x86_64_pc_windows_gnu,
            i686_pc_windows_gnu
        );

        let path = Path::new(target);

        if path.is_file() {
            return load_file(&path);
        }

        let path = {
            let mut target = target.to_string();
            target.push_str(".json");
            Path::new(target)
        };

        let target_path = os::getenv("RUST_TARGET_PATH").unwrap_or(String::new());

        let paths = os::split_paths(target_path[]);
        // FIXME 16351: add a sane default search path?

        for dir in paths.iter() {
            let p =  dir.join(path.clone());
            if p.is_file() {
                return load_file(&p);
            }
        }

        Err(format!("Could not find specification for target {}", target))
    }
}
<commit_msg>rustc_back: unbox closures used in let bindings<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! [Flexible target specification.](https://github.com/rust-lang/rfcs/pull/131)
//!
//! Rust targets a wide variety of usecases, and in the interest of flexibility,
//! allows new target triples to be defined in configuration files. Most users
//! will not need to care about these, but this is invaluable when porting Rust
//! to a new platform, and allows for an unprecedented level of control over how
//! the compiler works.
//!
//! # Using custom targets
//!
//! A target triple, as passed via `rustc --target=TRIPLE`, will first be
//! compared against the list of built-in targets. This is to ease distributing
//! rustc (no need for configuration files) and also to hold these built-in
//! targets as immutable and sacred. If `TRIPLE` is not one of the built-in
//! targets, rustc will check if a file named `TRIPLE` exists. If it does, it
//! will be loaded as the target configuration. If the file does not exist,
//! rustc will search each directory in the environment variable
//! `RUST_TARGET_PATH` for a file named `TRIPLE.json`. The first one found will
//! be loaded. If no file is found in any of those directories, a fatal error
//! will be given.  `RUST_TARGET_PATH` includes `/etc/rustc` as its last entry,
//! to be searched by default.
//!
//! Projects defining their own targets should use
//! `--target=path/to/my-awesome-platform.json` instead of adding to
//! `RUST_TARGET_PATH`.
//!
//! # Defining a new target
//!
//! Targets are defined using [JSON](http://json.org/). The `Target` struct in
//! this module defines the format the JSON file should take, though each
//! underscore in the field names should be replaced with a hyphen (`-`) in the
//! JSON file. Some fields are required in every target specification, such as
//! `data-layout`, `llvm-target`, `target-endian`, `target-word-size`, and
//! `arch`. In general, options passed to rustc with `-C` override the target's
//! settings, though `target-feature` and `link-args` will *add* to the list
//! specified by the target, rather than replace.

use serialize::json::Json;
use syntax::{diagnostic, abi};
use std::default::Default;
use std::io::fs::PathExtensions;

mod windows_base;
mod linux_base;
mod apple_base;
mod freebsd_base;
mod dragonfly_base;

mod arm_apple_ios;
mod arm_linux_androideabi;
mod arm_unknown_linux_gnueabi;
mod arm_unknown_linux_gnueabihf;
mod i686_apple_darwin;
mod i386_apple_ios;
mod i686_pc_windows_gnu;
mod i686_unknown_dragonfly;
mod i686_unknown_linux_gnu;
mod mips_unknown_linux_gnu;
mod mipsel_unknown_linux_gnu;
mod x86_64_apple_darwin;
mod x86_64_pc_windows_gnu;
mod x86_64_unknown_freebsd;
mod x86_64_unknown_dragonfly;
mod x86_64_unknown_linux_gnu;

/// Everything `rustc` knows about how to compile for a specific target.
///
/// Every field here must be specified, and has no default value.
#[deriving(Clone, Show)]
pub struct Target {
    /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM.
    pub data_layout: String,
    /// Target triple to pass to LLVM.
    pub llvm_target: String,
    /// String to use as the `target_endian` `cfg` variable.
    pub target_endian: String,
    /// String to use as the `target_word_size` `cfg` variable.
    pub target_word_size: String,
    /// OS name to use for conditional compilation.
    pub target_os: String,
    /// Architecture to use for ABI considerations. Valid options: "x86", "x86_64", "arm", and
    /// "mips". "mips" includes "mipsel".
    pub arch: String,
    /// Optional settings with defaults.
    pub options: TargetOptions,
}

/// Optional aspects of a target specification.
///
/// This has an implementation of `Default`, see each field for what the default is. In general,
/// these try to take "minimal defaults" that don't assume anything about the runtime they run in.
#[deriving(Clone, Show)]
pub struct TargetOptions {
    /// Linker to invoke. Defaults to "cc".
    pub linker: String,
    /// Linker arguments that are unconditionally passed *before* any user-defined libraries.
    pub pre_link_args: Vec<String>,
    /// Linker arguments that are unconditionally passed *after* any user-defined libraries.
    pub post_link_args: Vec<String>,
    /// Default CPU to pass to LLVM. Corresponds to `llc -mcpu=$cpu`. Defaults to "default".
    pub cpu: String,
    /// Default target features to pass to LLVM. These features will *always* be passed, and cannot
    /// be disabled even via `-C`. Corresponds to `llc -mattr=$features`.
    pub features: String,
    /// Whether dynamic linking is available on this target. Defaults to false.
    pub dynamic_linking: bool,
    /// Whether executables are available on this target. iOS, for example, only allows static
    /// libraries. Defaults to false.
    pub executables: bool,
    /// Whether LLVM's segmented stack prelude is supported by whatever runtime is available.
    /// Will emit stack checks and calls to __morestack. Defaults to false.
    pub morestack: bool,
    /// Relocation model to use in object file. Corresponds to `llc
    /// -relocation-model=$relocation_model`. Defaults to "pic".
    pub relocation_model: String,
    /// Code model to use. Corresponds to `llc -code-model=$code_model`. Defaults to "default".
    pub code_model: String,
    /// Do not emit code that uses the "red zone", if the ABI has one. Defaults to false.
    pub disable_redzone: bool,
    /// Eliminate frame pointers from stack frames if possible. Defaults to true.
    pub eliminate_frame_pointer: bool,
    /// Emit each function in its own section. Defaults to true.
    pub function_sections: bool,
    /// String to prepend to the name of every dynamic library. Defaults to "lib".
    pub dll_prefix: String,
    /// String to append to the name of every dynamic library. Defaults to ".so".
    pub dll_suffix: String,
    /// String to append to the name of every executable.
    pub exe_suffix: String,
    /// String to prepend to the name of every static library. Defaults to "lib".
    pub staticlib_prefix: String,
    /// String to append to the name of every static library. Defaults to ".a".
    pub staticlib_suffix: String,
    /// Whether the target toolchain is like OSX's. Only useful for compiling against iOS/OS X, in
    /// particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
    pub is_like_osx: bool,
    /// Whether the target toolchain is like Windows'. Only useful for compiling against Windows,
    /// only realy used for figuring out how to find libraries, since Windows uses its own
    /// library naming convention. Defaults to false.
    pub is_like_windows: bool,
    /// Whether the linker support GNU-like arguments such as -O. Defaults to false.
    pub linker_is_gnu: bool,
    /// Whether the linker support rpaths or not. Defaults to false.
    pub has_rpath: bool,
    /// Whether to disable linking to compiler-rt. Defaults to false, as LLVM will emit references
    /// to the functions that compiler-rt provides.
    pub no_compiler_rt: bool,
    /// Dynamically linked executables can be compiled as position independent if the default
    /// relocation model of position independent code is not changed. This is a requirement to take
    /// advantage of ASLR, as otherwise the functions in the executable are not randomized and can
    /// be used during an exploit of a vulnerability in any code.
    pub position_independent_executables: bool,
}

impl Default for TargetOptions {
    /// Create a set of "sane defaults" for any target. This is still incomplete, and if used for
    /// compilation, will certainly not work.
    fn default() -> TargetOptions {
        TargetOptions {
            linker: "cc".to_string(),
            pre_link_args: Vec::new(),
            post_link_args: Vec::new(),
            cpu: "generic".to_string(),
            features: "".to_string(),
            dynamic_linking: false,
            executables: false,
            morestack: false,
            relocation_model: "pic".to_string(),
            code_model: "default".to_string(),
            disable_redzone: false,
            eliminate_frame_pointer: true,
            function_sections: true,
            dll_prefix: "lib".to_string(),
            dll_suffix: ".so".to_string(),
            exe_suffix: "".to_string(),
            staticlib_prefix: "lib".to_string(),
            staticlib_suffix: ".a".to_string(),
            is_like_osx: false,
            is_like_windows: false,
            linker_is_gnu: false,
            has_rpath: false,
            no_compiler_rt: false,
            position_independent_executables: false,
        }
    }
}

impl Target {
    /// Given a function ABI, turn "System" into the correct ABI for this target.
    pub fn adjust_abi(&self, abi: abi::Abi) -> abi::Abi {
        match abi {
            abi::System => {
                if self.options.is_like_windows && self.arch == "x86" {
                    abi::Stdcall
                } else {
                    abi::C
                }
            },
            abi => abi
        }
    }

    /// Load a target descriptor from a JSON object.
    pub fn from_json(obj: Json) -> Target {
        // this is 1. ugly, 2. error prone.

        let handler = diagnostic::default_handler(diagnostic::Auto, None);

        let get_req_field = |&: name: &str| {
            match obj.find(name)
                     .map(|s| s.as_string())
                     .and_then(|os| os.map(|s| s.to_string())) {
                Some(val) => val,
                None =>
                    handler.fatal((format!("Field {} in target specification is required", name))
                                  [])
            }
        };

        let mut base = Target {
            data_layout: get_req_field("data-layout"),
            llvm_target: get_req_field("llvm-target"),
            target_endian: get_req_field("target-endian"),
            target_word_size: get_req_field("target-word-size"),
            arch: get_req_field("arch"),
            target_os: get_req_field("os"),
            options: Default::default(),
        };

        macro_rules! key (
            ($key_name:ident) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_string()
                                    .map(|s| base.options.$key_name = s.to_string()));
            } );
            ($key_name:ident, bool) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_boolean().map(|s| base.options.$key_name = s));
            } );
            ($key_name:ident, list) => ( {
                let name = (stringify!($key_name)).replace("_", "-");
                obj.find(name[]).map(|o| o.as_array()
                    .map(|v| base.options.$key_name = v.iter()
                        .map(|a| a.as_string().unwrap().to_string()).collect()
                        )
                    );
            } );
        );

        key!(cpu);
        key!(linker);
        key!(relocation_model);
        key!(code_model);
        key!(dll_prefix);
        key!(dll_suffix);
        key!(exe_suffix);
        key!(staticlib_prefix);
        key!(staticlib_suffix);
        key!(features);
        key!(dynamic_linking, bool);
        key!(executables, bool);
        key!(morestack, bool);
        key!(disable_redzone, bool);
        key!(eliminate_frame_pointer, bool);
        key!(function_sections, bool);
        key!(is_like_osx, bool);
        key!(is_like_windows, bool);
        key!(linker_is_gnu, bool);
        key!(has_rpath, bool);
        key!(no_compiler_rt, bool);
        key!(pre_link_args, list);
        key!(post_link_args, list);

        base
    }

    /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
    /// could also just be a bare filename already, so also check for that. If one of the hardcoded
    /// targets we know about, just return it directly.
    ///
    /// The error string could come from any of the APIs called, including filesystem access and
    /// JSON decoding.
    pub fn search(target: &str) -> Result<Target, String> {
        use std::os;
        use std::io::File;
        use std::path::Path;
        use serialize::json;

        fn load_file(path: &Path) -> Result<Target, String> {
            let mut f = try!(File::open(path).map_err(|e| e.to_string()));
            let obj = try!(json::from_reader(&mut f).map_err(|e| e.to_string()));
            Ok(Target::from_json(obj))
        }

        // this would use a match if stringify! were allowed in pattern position
        macro_rules! load_specific (
            ( $($name:ident),+ ) => (
                {
                    let target = target.replace("-", "_");
                    if false { }
                    $(
                        else if target == stringify!($name) {
                            let t = $name::target();
                            debug!("Got builtin target: {}", t);
                            return Ok(t);
                        }
                    )*
                    else if target == "x86_64-w64-mingw32" {
                        let t = x86_64_pc_windows_gnu::target();
                        return Ok(t);
                    } else if target == "i686-w64-mingw32" {
                        let t = i686_pc_windows_gnu::target();
                        return Ok(t);
                    }
                }
            )
        );

        load_specific!(
            x86_64_unknown_linux_gnu,
            i686_unknown_linux_gnu,
            mips_unknown_linux_gnu,
            mipsel_unknown_linux_gnu,
            arm_linux_androideabi,
            arm_unknown_linux_gnueabi,
            arm_unknown_linux_gnueabihf,

            x86_64_unknown_freebsd,

            i686_unknown_dragonfly,
            x86_64_unknown_dragonfly,

            x86_64_apple_darwin,
            i686_apple_darwin,
            i386_apple_ios,
            arm_apple_ios,

            x86_64_pc_windows_gnu,
            i686_pc_windows_gnu
        );

        let path = Path::new(target);

        if path.is_file() {
            return load_file(&path);
        }

        let path = {
            let mut target = target.to_string();
            target.push_str(".json");
            Path::new(target)
        };

        let target_path = os::getenv("RUST_TARGET_PATH").unwrap_or(String::new());

        let paths = os::split_paths(target_path[]);
        // FIXME 16351: add a sane default search path?

        for dir in paths.iter() {
            let p =  dir.join(path.clone());
            if p.is_file() {
                return load_file(&p);
            }
        }

        Err(format!("Could not find specification for target {}", target))
    }
}
<|endoftext|>


<commit_before>use crate::command_prelude::*;

use cargo::ops::{self, DocOptions};

pub fn cli() -> App {
    subcommand("doc")
        // subcommand aliases are handled in aliased_command()
        // .alias("d")
        .about("Build a package's documentation")
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(opt(
            "open",
            "Opens the docs in a browser after the operation",
        ))
        .arg(opt("examples", "Document all examples"))
        .arg_package_spec(
            "Package to document",
            "Document all packages in the workspace",
            "Exclude packages from the build",
        )
        .arg(opt("no-deps", "Don't build documentation for dependencies"))
        .arg(opt("document-private-items", "Document private items"))
        .arg_jobs()
        .arg_targets_lib_bin_example(
            "Document only this package's library",
            "Document only the specified binary",
            "Document all binaries",
            "Document only the specified binary",
            "Document all examples",
        )
        .arg_release("Build artifacts in release mode, with optimizations")
        .arg_profile("Build artifacts with the specified profile")
        .arg_features()
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg_manifest_path()
        .arg_message_format()
        .arg_ignore_rust_version()
        .arg_unit_graph()
        .after_help("Run `cargo help doc` for more detailed information.\n")
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    let ws = args.workspace(config)?;
    let mode = CompileMode::Doc {
        deps: !args.is_present("no-deps"),
    };
    let mut compile_opts =
        args.compile_options(config, mode, Some(&ws), ProfileChecking::Custom)?;
    compile_opts.rustdoc_document_private_items = args.is_present("document-private-items");

    let doc_opts = DocOptions {
        open_result: args.is_present("open"),
        compile_opts,
    };
    ops::doc(&ws, &doc_opts)?;
    Ok(())
}
<commit_msg>fix bug<commit_after>use crate::command_prelude::*;

use cargo::ops::{self, DocOptions};

pub fn cli() -> App {
    subcommand("doc")
        // subcommand aliases are handled in aliased_command()
        // .alias("d")
        .about("Build a package's documentation")
        .arg(opt("quiet", "No output printed to stdout").short("q"))
        .arg(opt(
            "open",
            "Opens the docs in a browser after the operation",
        ))
        .arg(opt("examples", "Document all examples"))
        .arg_package_spec(
            "Package to document",
            "Document all packages in the workspace",
            "Exclude packages from the build",
        )
        .arg(opt("no-deps", "Don't build documentation for dependencies"))
        .arg(opt("document-private-items", "Document private items"))
        .arg_jobs()
        .arg_targets_lib_bin_example(
            "Document only this package's library",
            "Document only the specified binary",
            "Document all binaries",
            "Document only the specified example",
            "Document all examples",
        )
        .arg_release("Build artifacts in release mode, with optimizations")
        .arg_profile("Build artifacts with the specified profile")
        .arg_features()
        .arg_target_triple("Build for the target triple")
        .arg_target_dir()
        .arg_manifest_path()
        .arg_message_format()
        .arg_ignore_rust_version()
        .arg_unit_graph()
        .after_help("Run `cargo help doc` for more detailed information.\n")
}

pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
    let ws = args.workspace(config)?;
    let mode = CompileMode::Doc {
        deps: !args.is_present("no-deps"),
    };
    let mut compile_opts =
        args.compile_options(config, mode, Some(&ws), ProfileChecking::Custom)?;
    compile_opts.rustdoc_document_private_items = args.is_present("document-private-items");

    let doc_opts = DocOptions {
        open_result: args.is_present("open"),
        compile_opts,
    };
    ops::doc(&ws, &doc_opts)?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate card_engine;
extern crate rand;
extern crate ndarray;
#[macro_use]
extern crate lazy_static;

use ndarray::prelude::*;
use card_engine::learning::neural_net::*;
use rand::{Rng, thread_rng};

const FL: ActivationFunction = ActivationFunction::SymmetricSigmoid;

fn f(v: &ArrayView<f32, Ix1>) -> f32 {
    lazy_static! {
        static ref A: Array<f32, Ix1> = arr1(&[0.3, 0.4, -0.5, 0.8, 0.2]);
    }
    FL.af()(v.dot(&A) - 0.11)
}

fn main() {
    let layers = [LayerDesc::new(5, 1, FL)];
    let mut nn = NeuralNet::new(&layers, 0.1).unwrap();

    let mut rng = thread_rng();
    let mut grad = Array::zeros(nn.num_parameters());

    for i in 0..1000 {
        let sample: Vec<_> = (0..5).map(|_| { rng.gen_range(-1.0, 1.0) }).collect();
        let v = aview1(&sample);
        let out = f(&v);

        let nn_out = nn.evaluate_with_gradient(&v, grad.view_mut())[0];

        let err = out - nn_out;
        if i % 99 == 0 {
            println!("Iteration {} Err = {}", i+1, err);
        }
        nn.update_weights(err, grad.view());
    }
}
<commit_msg>add dual-layer learner<commit_after>extern crate card_engine;
extern crate rand;
extern crate ndarray;
#[macro_use]
extern crate lazy_static;

use ndarray::prelude::*;
use card_engine::learning::neural_net::*;
use rand::{Rng, thread_rng};
use ndarray::linalg::general_mat_vec_mul;

const FL: ActivationFunction = ActivationFunction::Linear;

fn f1(v: &ArrayView<f32, Ix1>) -> f32 {
    lazy_static! {
        static ref A: Array<f32, Ix1> = arr1(&[0.3, 0.4, -0.5, 0.8, 0.2]);
    }
    FL.af()(v.dot(&A) - 0.11)
}

fn f2(v: &ArrayView<f32, Ix1>) -> f32 {
    lazy_static! {
        static ref A1: Array<f32, Ix2> = arr2(&[[0.3, 0.4, -0.5, 0.8, 0.2],
                                                [0.14, -0.4, -0.5, 0.28, 0.2],
                                                [0.56, 0.4, 0.75, -0.1, -0.2]]);
        static ref B1: Array<f32, Ix1> = arr1(&[0.3, 0.4, -0.5]);

        static ref A2: Array<f32, Ix1> = arr1(&[0.3, 0.4, -0.5]);
    }
    const B2: f32 = -0.12;

    let mut l1: ArrayBase<_, Ix1> = B1.to_owned();
    general_mat_vec_mul(1.0, &A1, &v, 1.0, &mut l1);
    let x1 = l1.map(|x| FL.af()(*x));
    FL.af()(x1.dot(&A2) + B2)
}

#[allow(unused)]
fn train_single_layer() {
    let layers = [LayerDesc::new(5, 1, FL)];
    let nn = NeuralNet::new(&layers, 0.1).unwrap();

    train_nn(nn, f1);
}

fn train_dual_layer() {
    let layers = [LayerDesc::new(5, 3, FL), LayerDesc::new(3, 1, FL)];
    let nn = NeuralNet::new(&layers, 0.1).unwrap();

    train_nn(nn, f2);
}

fn train_nn(mut nn: NeuralNet, target: fn(&ArrayView<f32, Ix1>) -> f32) {
    let mut rng = thread_rng();
    let mut grad = Array::zeros(nn.num_parameters());

    nn.dump();

    for i in 0..1000 {
        let sample: Vec<_> = (0..5).map(|_| { rng.gen_range(-1.0, 1.0) }).collect();
        let v = aview1(&sample);
        let out = target(&v);

        let nn_out = nn.evaluate_with_gradient(&v, grad.view_mut())[0];
        let nn_out_nog = nn.evaluate(&v)[0];

        let err = out - nn_out;
        println!("*****\n{}, {}\n*******", err, grad);

        if i % 100 == 99 {
            println!("Iteration {}, Target {}, Predict {} / {}, Err = {}", i+1, out, nn_out, nn_out_nog, err);
        }
        nn.update_weights(err, grad.view());
        println!("{}", nn.weights());
    }
}

fn main() {
    train_dual_layer()
}
<|endoftext|>


<commit_before>use std::{
    io::{stdin, stdout, BufRead, Write},
    thread::sleep,
    time::Duration,
};

use isahc::{
    auth::{Authentication, Credentials},
    config::Configurable,
    http::StatusCode,
    HttpClient, ReadResponseExt, Request,
};
use semver::Version;
use serde_json::json;

use crate::{cargo::Package, cmd, util::ask_yes_no, GithubConfig, Metadata, Result};

const GITHUB_API_RUMA: &str = "https://api.github.com/repos/ruma/ruma";

/// Task to create a new release of the given crate.
#[derive(Debug)]
pub struct ReleaseTask {
    /// The metadata of the cargo workspace.
    metadata: Metadata,

    /// The crate to release.
    package: Package,

    /// The new version of the crate.
    version: Version,

    /// The http client to use for requests.
    http_client: HttpClient,

    /// The github configuration required to publish a release.
    config: GithubConfig,
}

impl ReleaseTask {
    /// Create a new `ReleaseTask` with the given `name` and `version`.
    pub(crate) fn new(name: String, version: Version) -> Result<Self> {
        let metadata = Metadata::load()?;

        let package = metadata
            .packages
            .clone()
            .into_iter()
            .find(|p| p.name == name)
            .ok_or(format!("Package {} not found in cargo metadata", name))?;

        let config = crate::Config::load()?.github;

        let http_client = HttpClient::new()?;

        Ok(Self { metadata, package, version, http_client, config })
    }

    /// Run the task to effectively create a release.
    pub(crate) fn run(&mut self) -> Result<()> {
        let title = &self.title();
        let prerelease = !self.version.pre.is_empty();
        let publish_only = self.package.name == "ruma-identifiers-validation";

        if let Some(name) = self.package.name.strip_suffix("-macros") {
            return Err(format!(
                "Macro crates are always released together with their parent crate.\n\
                 To release both {main_cr} and {macro_cr}, simply run\n\
                 \n\
                 cargo xtask release {main_cr}",
                main_cr = name,
                macro_cr = self.package.name,
            )
            .into());
        }

        println!(
            "Starting {} for {}…",
            match prerelease {
                true => "pre-release",
                false => "release",
            },
            title
        );

        if self.is_released()? {
            return Err("This crate version is already released".into());
        }

        let remote = Self::git_remote()?;

        println!("Checking status of git repository…");
        if !cmd!("git status -s -uno").read()?.is_empty()
            && !ask_yes_no("This git repository contains uncommitted changes. Continue?")?
        {
            return Ok(());
        }

        if self.package.version != self.version
            && !self.package.version.is_next(&self.version)
            && !ask_yes_no(&format!(
                "Version {} should not follow version {}. Do you really want to continue?",
                self.version, self.package.version,
            ))?
        {
            return Ok(());
        }

        let mut macros = self.macros();

        let create_commit = if self.package.version != self.version {
            if let Some(m) = macros.as_mut() {
                println!("Found macros crate {}.", m.name);

                m.update_version(&self.version)?;
                m.update_dependants(&self.metadata)?;

                println!("Resuming release of {}…", self.title());
            }

            self.package.update_version(&self.version)?;
            self.package.update_dependants(&self.metadata)?;
            true
        } else if !ask_yes_no(&format!(
            "Package is already version {}. Skip creating a commit and continue?",
            &self.version
        ))? {
            return Ok(());
        } else {
            false
        };

        let changes = &self.package.changes(!prerelease)?;

        if create_commit {
            self.commit()?;
        }

        if let Some(m) = macros {
            let published = m.publish(&self.http_client)?;

            if published {
                // Crate was published, instead of publishing skipped (because release already
                // existed).
                println!("Waiting 20 seconds for the release to make it into the crates.io index…");
                sleep(Duration::from_secs(20));
            }
        }

        self.package.publish(&self.http_client)?;

        let branch = cmd!("git rev-parse --abbrev-ref HEAD").read()?;
        if publish_only {
            println!("Pushing to remote repository…");
            cmd!("git push {remote} {branch}").run()?;

            println!("Crate published successfully!");
            return Ok(());
        }

        let tag = &self.tag_name();

        println!("Creating git tag…");
        if cmd!("git tag -l {tag}").read()?.is_empty() {
            cmd!("git tag -s {tag} -m {title} -m {changes}").read()?;
        } else if !ask_yes_no("This tag already exists. Skip this step and continue?")? {
            return Ok(());
        }

        println!("Pushing to remote repository…");
        if cmd!("git ls-remote --tags {remote} {tag}").read()?.is_empty() {
            cmd!("git push {remote} {branch} {tag}").run()?;
        } else if !ask_yes_no("This tag has already been pushed. Skip this step and continue?")? {
            return Ok(());
        }

        if prerelease {
            println!("Pre-release created successfully!");
            return Ok(());
        }

        println!("Creating release on GitHub…");
        let request_body = &json!({
            "tag_name": tag,
            "name": title,
            "body": changes.trim_softbreaks(),
        })
        .to_string();

        self.release(request_body)?;

        println!("Release created successfully!");

        Ok(())
    }

    /// Get the associated `-macros` crate of the current crate, if any.
    fn macros(&self) -> Option<Package> {
        self.metadata
            .packages
            .clone()
            .into_iter()
            .find(|p| p.name == format!("{}-macros", self.package.name))
    }

    /// Get the title of this release.
    fn title(&self) -> String {
        format!("{} {}", self.package.name, self.version)
    }

    /// Get the tag name for this release.
    fn tag_name(&self) -> String {
        format!("{}-{}", self.package.name, self.version)
    }

    /// Load the GitHub config from the config file.
    fn git_remote() -> Result<String> {
        let branch = cmd!("git rev-parse --abbrev-ref HEAD").read()?;
        let remote = cmd!("git config branch.{branch}.remote").read()?;

        if remote.is_empty() {
            return Err("Could not get current git remote".into());
        }

        Ok(remote)
    }

    /// Commit and push all the changes in the git repository.
    fn commit(&self) -> Result<()> {
        let stdin = stdin();

        let instructions = "Ready to commit the changes. [continue/abort/diff]: ";
        print!("{}", instructions);
        stdout().flush()?;

        let mut handle = stdin.lock();

        let mut input = String::new();
        loop {
            let eof = handle.read_line(&mut input)? == 0;
            if eof {
                return Err("User aborted commit".into());
            }

            match input.trim().to_ascii_lowercase().as_str() {
                "c" | "con" | "continue" => {
                    break;
                }
                "a" | "abort" => {
                    return Err("User aborted commit".into());
                }
                "d" | "diff" => {
                    cmd!("git diff").run()?;
                }
                _ => {
                    println!("Unknown command.");
                }
            }
            print!("{}", instructions);
            stdout().flush()?;

            input.clear();
        }

        let message = format!("Release {}", self.title());

        println!("Creating commit…");
        cmd!("git commit -a -m {message}").read()?;

        Ok(())
    }

    /// Check if the tag for the current version of the crate has been pushed on GitHub.
    fn is_released(&self) -> Result<bool> {
        let response = self.http_client.get(format!(
            "{}/releases/tags/{}",
            GITHUB_API_RUMA,
            self.tag_name()
        ))?;

        Ok(response.status() == StatusCode::OK)
    }

    /// Create the release on GitHub with the given `config` and `credentials`.
    fn release(&self, body: &str) -> Result<()> {
        let request = Request::post(format!("{}/releases", GITHUB_API_RUMA))
            .authentication(Authentication::basic())
            .credentials(Credentials::new(&self.config.user, &self.config.token))
            .header("Accept", "application/vnd.github.v3+json")
            .body(body)?;

        let mut response = self.http_client.send(request)?;

        if response.status() == StatusCode::CREATED {
            Ok(())
        } else {
            Err(format!("{}: {}", response.status(), response.text()?).into())
        }
    }
}

/// String manipulations for crate release.
trait StrExt {
    /// Remove soft line breaks as defined in CommonMark spec.
    fn trim_softbreaks(&self) -> String;
}

impl StrExt for str {
    fn trim_softbreaks(&self) -> String {
        let mut string = String::new();
        let mut s = self;

        while let Some(pos) = s.find('\n') {
            string.push_str(&s[..pos]);
            let pos_s = &s[pos..];

            if pos_s.starts_with("\n\n") {
                // Keep new paragraphs (multiple `\n`s).
                let next = pos_s.find(|c: char| c != '\n').unwrap_or(0);
                let (push, next_s) = pos_s.split_at(next);

                string.push_str(push);
                s = next_s;
            } else if s[..pos].ends_with("  ") || s[..pos].ends_with('\\') {
                // Keep hard line breaks (two spaces or a backslash before the line break).
                string.push('\n');
                s = &pos_s[1..];
            } else if let Some(p) = pos_s.find(|c: char| !c.is_ascii_whitespace()) {
                // Keep line break before list items (`\n` + whitespaces + `*` + whitespaces).
                // Remove line break and keep one space otherwise.
                let mut chars = pos_s.char_indices();
                let (_, char) = chars.find(|(i, _)| *i == p).unwrap();

                if char == '*' || char == '-' {
                    match chars.next() {
                        Some((_, next_char)) if next_char.is_ascii_whitespace() => {
                            string.push('\n');
                            s = &pos_s[1..];
                            continue;
                        }
                        _ => {}
                    }
                }

                string.push(' ');
                s = &pos_s[p..];
            }
        }

        string + s
    }
}

/// Extra Version increment methods for crate release.
trait VersionExt {
    /// Adds a pre-release label and number if there is none.
    fn add_pre_release(&mut self);

    /// Increments the pre-release number, if this is a pre-release.
    fn increment_pre_number(&mut self);

    /// Increments the pre-release label from `alpha` to `beta` if this is a pre-release and it is
    /// possible, otherwise does nothing.
    fn increment_pre_label(&mut self);

    /// If the given version can be the next after this one.
    ///
    /// This checks all the version bumps of the format MAJOR.MINOR.PATCH-PRE_LABEL.PRE_NUMBER, with
    /// PRE_LABEL = alpha or beta.
    fn is_next(&self, version: &Version) -> bool;
}

impl VersionExt for Version {
    fn add_pre_release(&mut self) {
        if self.pre.is_empty() {
            self.pre = semver::Prerelease::new("alpha.1").unwrap();
        }
    }

    fn increment_pre_number(&mut self) {
        if let Some((prefix, num)) = self.pre.as_str().rsplit_once('.') {
            if let Ok(num) = num.parse::<u8>() {
                self.pre = semver::Prerelease::new(&format!("{}.{}", prefix, num + 1)).unwrap();
            }
        }
    }

    fn increment_pre_label(&mut self) {
        if self.pre.as_str().starts_with("alpha.") {
            self.pre = semver::Prerelease::new("beta.1").unwrap();
        }
    }

    fn is_next(&self, version: &Version) -> bool {
        let mut next = self.clone();

        if !self.pre.is_empty() {
            next.increment_pre_number();
            if next == *version {
                return true;
            }

            next.increment_pre_label();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
        } else {
            next.patch += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
            next.patch = 0;
            next.minor += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
            next.minor = 0;
            next.major += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
        }

        next == *version
    }
}
<commit_msg>xtask: Release ruma-macros with ruma-common<commit_after>use std::{
    io::{stdin, stdout, BufRead, Write},
    thread::sleep,
    time::Duration,
};

use isahc::{
    auth::{Authentication, Credentials},
    config::Configurable,
    http::StatusCode,
    HttpClient, ReadResponseExt, Request,
};
use semver::Version;
use serde_json::json;

use crate::{cargo::Package, cmd, util::ask_yes_no, GithubConfig, Metadata, Result};

const GITHUB_API_RUMA: &str = "https://api.github.com/repos/ruma/ruma";

/// Task to create a new release of the given crate.
#[derive(Debug)]
pub struct ReleaseTask {
    /// The metadata of the cargo workspace.
    metadata: Metadata,

    /// The crate to release.
    package: Package,

    /// The new version of the crate.
    version: Version,

    /// The http client to use for requests.
    http_client: HttpClient,

    /// The github configuration required to publish a release.
    config: GithubConfig,
}

impl ReleaseTask {
    /// Create a new `ReleaseTask` with the given `name` and `version`.
    pub(crate) fn new(name: String, version: Version) -> Result<Self> {
        let metadata = Metadata::load()?;

        let package = metadata
            .packages
            .clone()
            .into_iter()
            .find(|p| p.name == name)
            .ok_or(format!("Package {} not found in cargo metadata", name))?;

        let config = crate::Config::load()?.github;

        let http_client = HttpClient::new()?;

        Ok(Self { metadata, package, version, http_client, config })
    }

    /// Run the task to effectively create a release.
    pub(crate) fn run(&mut self) -> Result<()> {
        if self.package.name == "ruma-macros" {
            return Err(
                "The ruma-macros crate is always released together with the ruma-common crate.\n\
                 To release both, simply run\n\
                 \n\
                 cargo xtask release ruma-common"
                    .into(),
            );
        }

        let title = &self.title();
        let prerelease = !self.version.pre.is_empty();
        let publish_only = self.package.name == "ruma-identifiers-validation";

        println!(
            "Starting {} for {}…",
            match prerelease {
                true => "pre-release",
                false => "release",
            },
            title
        );

        if self.is_released()? {
            return Err("This crate version is already released".into());
        }

        let remote = Self::git_remote()?;

        println!("Checking status of git repository…");
        if !cmd!("git status -s -uno").read()?.is_empty()
            && !ask_yes_no("This git repository contains uncommitted changes. Continue?")?
        {
            return Ok(());
        }

        if self.package.version != self.version
            && !self.package.version.is_next(&self.version)
            && !ask_yes_no(&format!(
                "Version {} should not follow version {}. Do you really want to continue?",
                self.version, self.package.version,
            ))?
        {
            return Ok(());
        }

        let mut macros = if self.package.name == "ruma-common" {
            self.metadata.packages.iter().find(|p| p.name == "ruma-macros").map(ToOwned::to_owned)
        } else {
            None
        };

        let create_commit = if self.package.version != self.version {
            if let Some(m) = macros.as_mut() {
                println!("Updating version of ruma-macros crate…");

                m.update_version(&self.version)?;
                m.update_dependants(&self.metadata)?;

                println!("Resuming release of {}…", self.title());
            }

            self.package.update_version(&self.version)?;
            self.package.update_dependants(&self.metadata)?;
            true
        } else if !ask_yes_no(&format!(
            "Package is already version {}. Skip creating a commit and continue?",
            &self.version
        ))? {
            return Ok(());
        } else {
            false
        };

        let changes = &self.package.changes(!prerelease)?;

        if create_commit {
            self.commit()?;
        }

        if let Some(m) = macros {
            let published = m.publish(&self.http_client)?;

            if published {
                // Crate was published, instead of publishing skipped (because release already
                // existed).
                println!("Waiting 20 seconds for the release to make it into the crates.io index…");
                sleep(Duration::from_secs(20));
            }
        }

        self.package.publish(&self.http_client)?;

        let branch = cmd!("git rev-parse --abbrev-ref HEAD").read()?;
        if publish_only {
            println!("Pushing to remote repository…");
            cmd!("git push {remote} {branch}").run()?;

            println!("Crate published successfully!");
            return Ok(());
        }

        let tag = &self.tag_name();

        println!("Creating git tag…");
        if cmd!("git tag -l {tag}").read()?.is_empty() {
            cmd!("git tag -s {tag} -m {title} -m {changes}").read()?;
        } else if !ask_yes_no("This tag already exists. Skip this step and continue?")? {
            return Ok(());
        }

        println!("Pushing to remote repository…");
        if cmd!("git ls-remote --tags {remote} {tag}").read()?.is_empty() {
            cmd!("git push {remote} {branch} {tag}").run()?;
        } else if !ask_yes_no("This tag has already been pushed. Skip this step and continue?")? {
            return Ok(());
        }

        if prerelease {
            println!("Pre-release created successfully!");
            return Ok(());
        }

        println!("Creating release on GitHub…");
        let request_body = &json!({
            "tag_name": tag,
            "name": title,
            "body": changes.trim_softbreaks(),
        })
        .to_string();

        self.release(request_body)?;

        println!("Release created successfully!");

        Ok(())
    }

    /// Get the title of this release.
    fn title(&self) -> String {
        format!("{} {}", self.package.name, self.version)
    }

    /// Get the tag name for this release.
    fn tag_name(&self) -> String {
        format!("{}-{}", self.package.name, self.version)
    }

    /// Load the GitHub config from the config file.
    fn git_remote() -> Result<String> {
        let branch = cmd!("git rev-parse --abbrev-ref HEAD").read()?;
        let remote = cmd!("git config branch.{branch}.remote").read()?;

        if remote.is_empty() {
            return Err("Could not get current git remote".into());
        }

        Ok(remote)
    }

    /// Commit and push all the changes in the git repository.
    fn commit(&self) -> Result<()> {
        let stdin = stdin();

        let instructions = "Ready to commit the changes. [continue/abort/diff]: ";
        print!("{}", instructions);
        stdout().flush()?;

        let mut handle = stdin.lock();

        let mut input = String::new();
        loop {
            let eof = handle.read_line(&mut input)? == 0;
            if eof {
                return Err("User aborted commit".into());
            }

            match input.trim().to_ascii_lowercase().as_str() {
                "c" | "con" | "continue" => {
                    break;
                }
                "a" | "abort" => {
                    return Err("User aborted commit".into());
                }
                "d" | "diff" => {
                    cmd!("git diff").run()?;
                }
                _ => {
                    println!("Unknown command.");
                }
            }
            print!("{}", instructions);
            stdout().flush()?;

            input.clear();
        }

        let message = format!("Release {}", self.title());

        println!("Creating commit…");
        cmd!("git commit -a -m {message}").read()?;

        Ok(())
    }

    /// Check if the tag for the current version of the crate has been pushed on GitHub.
    fn is_released(&self) -> Result<bool> {
        let response = self.http_client.get(format!(
            "{}/releases/tags/{}",
            GITHUB_API_RUMA,
            self.tag_name()
        ))?;

        Ok(response.status() == StatusCode::OK)
    }

    /// Create the release on GitHub with the given `config` and `credentials`.
    fn release(&self, body: &str) -> Result<()> {
        let request = Request::post(format!("{}/releases", GITHUB_API_RUMA))
            .authentication(Authentication::basic())
            .credentials(Credentials::new(&self.config.user, &self.config.token))
            .header("Accept", "application/vnd.github.v3+json")
            .body(body)?;

        let mut response = self.http_client.send(request)?;

        if response.status() == StatusCode::CREATED {
            Ok(())
        } else {
            Err(format!("{}: {}", response.status(), response.text()?).into())
        }
    }
}

/// String manipulations for crate release.
trait StrExt {
    /// Remove soft line breaks as defined in CommonMark spec.
    fn trim_softbreaks(&self) -> String;
}

impl StrExt for str {
    fn trim_softbreaks(&self) -> String {
        let mut string = String::new();
        let mut s = self;

        while let Some(pos) = s.find('\n') {
            string.push_str(&s[..pos]);
            let pos_s = &s[pos..];

            if pos_s.starts_with("\n\n") {
                // Keep new paragraphs (multiple `\n`s).
                let next = pos_s.find(|c: char| c != '\n').unwrap_or(0);
                let (push, next_s) = pos_s.split_at(next);

                string.push_str(push);
                s = next_s;
            } else if s[..pos].ends_with("  ") || s[..pos].ends_with('\\') {
                // Keep hard line breaks (two spaces or a backslash before the line break).
                string.push('\n');
                s = &pos_s[1..];
            } else if let Some(p) = pos_s.find(|c: char| !c.is_ascii_whitespace()) {
                // Keep line break before list items (`\n` + whitespaces + `*` + whitespaces).
                // Remove line break and keep one space otherwise.
                let mut chars = pos_s.char_indices();
                let (_, char) = chars.find(|(i, _)| *i == p).unwrap();

                if char == '*' || char == '-' {
                    match chars.next() {
                        Some((_, next_char)) if next_char.is_ascii_whitespace() => {
                            string.push('\n');
                            s = &pos_s[1..];
                            continue;
                        }
                        _ => {}
                    }
                }

                string.push(' ');
                s = &pos_s[p..];
            }
        }

        string + s
    }
}

/// Extra Version increment methods for crate release.
trait VersionExt {
    /// Adds a pre-release label and number if there is none.
    fn add_pre_release(&mut self);

    /// Increments the pre-release number, if this is a pre-release.
    fn increment_pre_number(&mut self);

    /// Increments the pre-release label from `alpha` to `beta` if this is a pre-release and it is
    /// possible, otherwise does nothing.
    fn increment_pre_label(&mut self);

    /// If the given version can be the next after this one.
    ///
    /// This checks all the version bumps of the format MAJOR.MINOR.PATCH-PRE_LABEL.PRE_NUMBER, with
    /// PRE_LABEL = alpha or beta.
    fn is_next(&self, version: &Version) -> bool;
}

impl VersionExt for Version {
    fn add_pre_release(&mut self) {
        if self.pre.is_empty() {
            self.pre = semver::Prerelease::new("alpha.1").unwrap();
        }
    }

    fn increment_pre_number(&mut self) {
        if let Some((prefix, num)) = self.pre.as_str().rsplit_once('.') {
            if let Ok(num) = num.parse::<u8>() {
                self.pre = semver::Prerelease::new(&format!("{}.{}", prefix, num + 1)).unwrap();
            }
        }
    }

    fn increment_pre_label(&mut self) {
        if self.pre.as_str().starts_with("alpha.") {
            self.pre = semver::Prerelease::new("beta.1").unwrap();
        }
    }

    fn is_next(&self, version: &Version) -> bool {
        let mut next = self.clone();

        if !self.pre.is_empty() {
            next.increment_pre_number();
            if next == *version {
                return true;
            }

            next.increment_pre_label();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
        } else {
            next.patch += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
            next.patch = 0;
            next.minor += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
            if next == *version {
                return true;
            }

            next.pre = semver::Prerelease::EMPTY;
            next.minor = 0;
            next.major += 1;
            if next == *version {
                return true;
            }

            next.add_pre_release();
        }

        next == *version
    }
}
<|endoftext|>


<commit_before>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::fs;
use std::io;
use std::path::PathBuf;

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_DIRECTORY: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory() -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(XI_DIRECTORY);
            Ok(log_dir)
        }
        None => Err(io::Error::new(
            io::ErrorKind::NotFound,
            "The dir library was not able to find a directory for this platform",
        )),
    }
}

fn path_for_log_file<P: AsRef<str>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory()?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    match path_for_log_file(XI_LOG_FILE) {
        Ok(logging_file_path) => {
            fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?)
        }
        Err(e) => {
            let error_message =
                "[WARNING] There was an issue getting the path for the log file, falling back to stderr.";
            eprintln!("{}\nError:\n{:?}", error_message, e)
        }
    }
    fern_dispatch.apply()?;
    info!("Logging with fern is setup");
    Ok(())
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<commit_msg>Swapped `str` to `Path` to make the function's intent clearer.<commit_after>// Copyright 2016 The xi-editor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate log;
extern crate chrono;
extern crate fern;

extern crate dirs;

extern crate xi_core_lib;
extern crate xi_rpc;

use std::fs;
use std::io;
use std::path::{Path, PathBuf};

use xi_core_lib::XiCore;
use xi_rpc::RpcLoop;

const XI_DIRECTORY: &str = "xi-core";
const XI_LOG_FILE: &str = "xi-core.log";

fn get_logging_directory() -> Result<PathBuf, io::Error> {
    match dirs::data_local_dir() {
        Some(mut log_dir) => {
            log_dir.push(XI_DIRECTORY);
            Ok(log_dir)
        }
        None => Err(io::Error::new(
            io::ErrorKind::NotFound,
            "The dir library was not able to find a directory for this platform",
        )),
    }
}

fn path_for_log_file<P: AsRef<Path>>(filename: P) -> Result<PathBuf, io::Error> {
    let mut logging_directory = get_logging_directory()?;
    // Create the logging directory
    fs::create_dir_all(&logging_directory)?;
    logging_directory.push(filename.as_ref());
    Ok(logging_directory)
}

fn setup_logging() -> Result<(), fern::InitError> {
    let level_filter = match std::env::var("XI_LOG") {
        Ok(level) => match level.to_lowercase().as_ref() {
            "trace" => log::LevelFilter::Trace,
            "debug" => log::LevelFilter::Debug,
            _ => log::LevelFilter::Info,
        },
        // Default to info
        Err(_) => log::LevelFilter::Info,
    };

    let mut fern_dispatch = fern::Dispatch::new()
        .format(|out, message, record| {
            out.finish(format_args!(
                "{}[{}][{}] {}",
                chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
                record.target(),
                record.level(),
                message,
            ))
        }).level(level_filter)
        .chain(io::stderr());

    match path_for_log_file(XI_LOG_FILE) {
        Ok(logging_file_path) => {
            fern_dispatch = fern_dispatch.chain(fern::log_file(logging_file_path)?)
        }
        Err(e) => {
            let error_message =
                "[WARNING] There was an issue getting the path for the log file, falling back to stderr.";
            eprintln!("{}\nError:\n{:?}", error_message, e)
        }
    }
    fern_dispatch.apply()?;
    info!("Logging with fern is setup");
    Ok(())
}

fn main() {
    let mut state = XiCore::new();
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut rpc_looper = RpcLoop::new(stdout);

    if let Err(e) = setup_logging() {
        eprintln!(
            "[ERROR] setup_logging returned error, logging disabled: {:?}",
            e
        );
    }

    match rpc_looper.mainloop(|| stdin.lock(), &mut state) {
        Ok(_) => (),
        Err(err) => error!("xi-core exited with error:\n{:?}", err),
    }
}
<|endoftext|>


<commit_before>extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    let torch_path = env::var("TORCH_PATH").expect("TORCH_PATH not defined");
    println!("cargo:rustc-link-search=native={}/torch/lib/build/TH", torch_path);
    //println!("cargo:rustc-link-search=native={}/build/lib.linux-x86_64-3.6/torch/lib", torch_path);
    println!("cargo:rustc-link-lib=TH");

    //let cuda_path = env::var("CUDA_PATH").expect("CUDA_PATH not defined");
    //let mut inc = String::from("-I");
    //inc.push_str(&cuda_path);
    //inc.push_str("/include");
    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()

        // Do not generate unstable Rust code that
        // requires a nightly rustc and enabling
        // unstable features.
        .no_unstable_rust()
        .clang_arg(format!("-I{}/torch/lib/include/TH", torch_path))
        .clang_arg(format!("-I{}/torch/lib/include/THNN", torch_path))
 	    .clang_arg(format!("-I{}/torch/lib", torch_path))
        //.clang_arg("-Ipytorch/torch/lib/include/THC")
        //.clang_arg(inc)
        // The input header we would like to generate
        // bindings for.
        .header("src/wrapper.h")
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

}
<commit_msg>link in THNN<commit_after>extern crate bindgen;

use std::env;
use std::path::PathBuf;

fn main() {
    let torch_path = env::var("TORCH_PATH").expect("TORCH_PATH not defined");
    println!("cargo:rustc-link-search=native={}/torch/lib/build/TH", torch_path);
    println!("cargo:rustc-link-search=native={}/torch/lib/build/THNN", torch_path);
    //println!("cargo:rustc-link-search=native={}/build/lib.linux-x86_64-3.6/torch/lib", torch_path);
    println!("cargo:rustc-link-lib=TH");
    println!("cargo:rustc-link-lib=THNN");

    //let cuda_path = env::var("CUDA_PATH").expect("CUDA_PATH not defined");
    //let mut inc = String::from("-I");
    //inc.push_str(&cuda_path);
    //inc.push_str("/include");
    // The bindgen::Builder is the main entry point
    // to bindgen, and lets you build up options for
    // the resulting bindings.
    let bindings = bindgen::Builder::default()

        // Do not generate unstable Rust code that
        // requires a nightly rustc and enabling
        // unstable features.
        .no_unstable_rust()
        .clang_arg(format!("-I{}/torch/lib/include/TH", torch_path))
        .clang_arg(format!("-I{}/torch/lib/include/THNN", torch_path))
 	    .clang_arg(format!("-I{}/torch/lib", torch_path))
        //.clang_arg("-Ipytorch/torch/lib/include/THC")
        //.clang_arg(inc)
        // The input header we would like to generate
        // bindings for.
        .header("src/wrapper.h")
        // Finish the builder and generate the bindings.
        .generate()
        // Unwrap the Result and panic on failure.
        .expect("Unable to generate bindings");

    // Write the bindings to the $OUT_DIR/bindings.rs file.
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

}
<|endoftext|>