<commit_before>#![no_std]
#![no_main]
#![feature(lang_items)]
#![feature(globs)]
#![feature(asm)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(link,plugin)]
extern crate core;
use core::prelude::*;
use chip::rom::SysCtl;
use chip::rom::GPIO;
use chip::rom::UART;

#[cfg(chip_tm4c123gh6pm)]
#[allow(dead_code)]
#[path="src/tm4c123gh6pm/mod.rs"]
mod chip;

#[lang = "fail_fmt"]
fn fail_impl() -> ! {
    loop {}
}
#[lang = "stack_exhausted" ] fn stack_exhausted() {}
#[lang = "eh_personality" ] fn eh_personality() {}

const RED:   u8 = GPIO::PIN_1;
const GREEN: u8 = GPIO::PIN_2;
const BLUE:  u8 = GPIO::PIN_3;

#[no_mangle]
pub extern "C" fn main() -> ! {
    SysCtl::ClockSet(
        SysCtl::SYSDIV_4 |
        SysCtl::USE_PLL |
        SysCtl::XTAL_16MHZ |
        SysCtl::OSC_MAIN);

    SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOF);
    GPIO::PinTypeGPIOOutput(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE);

    SysCtl::PeripheralEnable(SysCtl::PERIPH_UART0);
    SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOA);
    GPIO::PinConfigure(chip::pinmap::PA0_U0RX);
    GPIO::PinConfigure(chip::pinmap::PA1_U0TX);
    GPIO::PinTypeUART(chip::GPIO_PORTA_BASE, GPIO::PIN_0 | GPIO::PIN_1);
    UART::ConfigSetExpClk(chip::UART0_BASE, SysCtl::ClockGet(), 115200,
        UART::CONFIG_WLEN_8 |
        UART::CONFIG_STOP_ONE |
        UART::CONFIG_PAR_NONE);

    loop {
        GPIO::PinWrite(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE, RED|GREEN|BLUE);
        SysCtl::Delay(500000);
        GPIO::PinWrite(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE, 0);
        SysCtl::Delay(5000000);

        UART::CharPut(chip::UART0_BASE, '!' as u8);
    }
}
<commit_msg>add more tiva-C test code<commit_after>#![no_std]
#![no_main]
#![feature(lang_items)]
#![feature(globs)]
#![feature(asm)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(link,plugin)]
extern crate core;
use core::prelude::*;
use core::intrinsics::{volatile_load,volatile_store};
use chip::rom::GPIO;
use chip::rom::SysCtl;
use chip::rom::UART;
use chip::rom::USB;

#[cfg(chip_tm4c123gh6pm)]
#[allow(dead_code)]
#[macro_escape]
#[path="src/tm4c123gh6pm/mod.rs"]
mod chip;

#[lang = "fail_fmt"]         fn fail_impl() -> ! { loop {} }
#[lang = "stack_exhausted" ] fn stack_exhausted() {}
#[lang = "eh_personality" ]  fn eh_personality() {}

const RED:   u8 = GPIO::PIN_1;
const BLUE:  u8 = GPIO::PIN_2;
const GREEN: u8 = GPIO::PIN_3;

#[allow(non_snake_case)]
fn USBClockEnable(base: u32, div: u32, flags: u32) {
    unsafe {
        volatile_store((base + chip::usb::O_CC as u32) as *mut u32, (div-1) | flags);
    }
}

struct Uart {
    base: u32,
}

impl Uart {
    fn write(&self, data: &[u8]) {
        for ch in data.iter() {
            UART::CharPut(self.base, *ch);
        }
    }
}

//static S0: Uart = Uart{ base: chip::UART0_BASE };

#[no_mangle]
pub extern "C" fn main() -> ! {
    let s0: Uart = Uart{ base: chip::UART0_BASE };
    // Initialize clock
    SysCtl::ClockSet(
        SysCtl::SYSDIV_4 |
        SysCtl::USE_PLL |
        SysCtl::XTAL_16MHZ |
        SysCtl::OSC_MAIN);

    // Initialize LEDs
    SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOF);
    GPIO::PinTypeGPIOOutput(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE);

    // Initialize serial port
    SysCtl::PeripheralEnable(SysCtl::PERIPH_UART0);
    SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOA);
    GPIO::PinConfigure(chip::pinmap::PA0_U0RX);
    GPIO::PinConfigure(chip::pinmap::PA1_U0TX);
    GPIO::PinTypeUART(chip::GPIO_PORTA_BASE, GPIO::PIN_0 | GPIO::PIN_1);
    UART::ConfigSetExpClk(chip::UART0_BASE, SysCtl::ClockGet(), 115200,
        UART::CONFIG_WLEN_8 |
        UART::CONFIG_STOP_ONE |
        UART::CONFIG_PAR_NONE);

    // Initialize USB
    SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOD);
    GPIO::PinTypeUSBAnalog(chip::GPIO_PORTD_BASE, GPIO::PIN_4 | GPIO::PIN_5);
    //SysCtl::PeripheralEnable(SysCtl::PERIPH_GPIOB);
    //GPIO::PinTypeUSBAnalog(chip::GPIO_PORTB_BASE, GPIO::PIN_0 | GPIO::PIN_1);

    // Reset the USB controller.
    SysCtl::PeripheralReset(SysCtl::PERIPH_USB0);
    // Enable Clocking to the USB controller.
    SysCtl::PeripheralEnable(SysCtl::PERIPH_USB0);
    // Turn on USB Phy clock.
    SysCtl::USBPLLEnable();
    // Set the PLL to USB clock divider.
    USBClockEnable(chip::USB0_BASE, 8, USB::CLOCK_INTERNAL);
    // Force device mode
    USB::DevMode(chip::USB0_BASE);
    // Get the current interrupt status to clear all pending USB
    // interrupts.
    USB::IntStatusControl(chip::USB0_BASE);
    USB::IntStatusEndpoint(chip::USB0_BASE);
    // Enable USB Interrupts.
    USB::IntEnableControl(chip::USB0_BASE,
                          USB::INTCTRL_RESET |
                          USB::INTCTRL_DISCONNECT |
                          USB::INTCTRL_RESUME |
                          USB::INTCTRL_SUSPEND |
                          USB::INTCTRL_SOF);
    USB::IntEnableEndpoint(chip::USB0_BASE, USB::INTEP_ALL);
    // Attach the device using the soft connect.
    USB::DevConnect(chip::USB0_BASE);

    chip::interrupts::enable();
    let mut line = [ 0, 0, /* '\r' as u8, */ '\n' as u8 ];
    loop {
        GPIO::PinWrite(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE, GREEN);
        SysCtl::Delay(1000000);
        GPIO::PinWrite(chip::GPIO_PORTF_BASE, RED|GREEN|BLUE, 0);
        SysCtl::Delay(10000000);

        let mut txlevel = 0;
        let mut rxlevel = 0;
        UART::FIFOLevelGet(chip::UART0_BASE, &mut txlevel, &mut rxlevel);

        line[0] = match txlevel {
            UART::FIFO_TX1_8 => '1',
            UART::FIFO_TX2_8 => '2',
            UART::FIFO_TX4_8 => '4',
            UART::FIFO_TX6_8 => '6',
            UART::FIFO_TX7_8 => '7',
            _ => '!',
        } as u8;
        line[1] = match rxlevel {
            UART::FIFO_RX1_8 => '1',
            UART::FIFO_RX2_8 => '2',
            UART::FIFO_RX4_8 => '4',
            UART::FIFO_RX6_8 => '6',
            UART::FIFO_RX7_8 => '7',
            _ => '!',
        } as u8;

        s0.write(&line);
    }
}
<|endoftext|>


<commit_before>extern crate gtk;

use gtk::prelude::*;
use std::ops::Not;
use std::sync::{Arc, RwLock};

fn main() {
    if gtk::init().is_err() {
        println!("Failed to initialize GTK.");
        return;
    }

    let window = gtk::Window::new(gtk::WindowType::Toplevel);

    window.connect_delete_event(|_, _| {
        gtk::main_quit();
        Inhibit(false)
    });

    let button = gtk::Button::new_with_label("Hello World! ");

    window.add(&button);

    let lock = Arc::new(RwLock::new(false));

    let lock_button = lock.clone();
    button.connect_clicked(move |_| {
        let mut reverse = lock_button.write().unwrap();
        *reverse = reverse.not();
    });

    let lock_thread = lock.clone();
    gtk::timeout_add(100, move || {
        let reverse = lock_thread.read().unwrap();
        let mut text = button.get_label().unwrap();
        let len = &text.len();

        if *reverse {
            let begin = &text.split_off(1);
            text.insert_str(0, begin);
        } else {
            let end = &text.split_off(len - 1);
            text.insert_str(0, end);
        }

        button.set_label(&text);

        gtk::Continue(true)
    });

    window.show_all();
    gtk::main();
}
<commit_msg>Refactor to make the task look like the other gtk related tasks<commit_after>#[cfg(feature = "gtk")]
mod graphical {
    extern crate gtk;

    use self::gtk::traits::*;
    use self::gtk::{Inhibit, Window, WindowType};
    use std::ops::Not;
    use std::sync::{Arc, RwLock};

    pub fn create_window() {
        gtk::init().expect("Failed to initialize GTK");

        let window = Window::new(WindowType::Toplevel);
        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(false)
        });
        let button = gtk::Button::new_with_label("Hello World! ");
        window.add(&button);

        let lock = Arc::new(RwLock::new(false));

        let lock_button = lock.clone();
        button.connect_clicked(move |_| {
            let mut reverse = lock_button.write().unwrap();
            *reverse = reverse.not();
        });

        let lock_thread = lock.clone();
        gtk::timeout_add(100, move || {
            let reverse = lock_thread.read().unwrap();
            let mut text = button.get_label().unwrap();
            let len = &text.len();

            if *reverse {
                let begin = &text.split_off(1);
                text.insert_str(0, begin);
            } else {
                let end = &text.split_off(len - 1);
                text.insert_str(0, end);
            }

            button.set_label(&text);

            gtk::Continue(true)
        });

        window.show_all();
        gtk::main();
    }
}

#[cfg(feature = "gtk")]
fn main() {
    graphical::create_window();
}

#[cfg(not(feature = "gtk"))]
fn main() {}
<|endoftext|>


<commit_before>#[cfg(test)]
mod test {
    #[test]
    fn it_works() {
    }
}
<commit_msg>Add initial Kudu FFI bindings<commit_after>#![allow(non_camel_case_types)]

use std::os::raw::c_char;

pub enum kudu_client_builder_t {}
pub enum kudu_client_t {}
pub enum kudu_status_t {}
pub enum kudu_table_list_t {}

extern "C" {

    ////////////////////////////////////////////////////////////////////////////
    // Kudu Status
    ////////////////////////////////////////////////////////////////////////////

    pub fn kudu_status_destroy(status: *const kudu_status_t);
    pub fn kudu_status_code(status: *const kudu_status_t) -> i8;
    pub fn kudu_status_posix_code(status: *const kudu_status_t) -> i16;
    pub fn kudu_status_message(status: *const kudu_status_t, len: *mut usize) -> *const c_char;

    ////////////////////////////////////////////////////////////////////////////
    // Kudu Client Builder
    ////////////////////////////////////////////////////////////////////////////

    pub fn kudu_client_builder_create() -> *mut kudu_client_builder_t;
    pub fn kudu_client_builder_destroy(builder: *mut kudu_client_builder_t);
    pub fn kudu_client_builder_add_master_server_addr(builder: *mut kudu_client_builder_t,
                                                      addr: *const c_char);
    pub fn kudu_client_builder_clear_master_server_addrs(builder: *mut kudu_client_builder_t);
    pub fn kudu_client_builder_set_default_admin_operation_timeout(builder: *mut kudu_client_builder_t,
                                                                   timeout_millis: i64);
    pub fn kudu_client_builder_set_default_rpc_timeout(builder: *mut kudu_client_builder_t,
                                                       timeout_millis: i64);
    pub fn kudu_client_builder_build(builder: *mut kudu_client_builder_t,
                                     client: *const *mut kudu_client_t)
                                     -> *const kudu_status_t;

    ////////////////////////////////////////////////////////////////////////////
    // Kudu Table List
    ////////////////////////////////////////////////////////////////////////////

    pub fn kudu_table_list_destroy(list: *mut kudu_table_list_t);
    pub fn kudu_table_list_size(list: *const kudu_table_list_t) -> usize;
    pub fn kudu_table_list_table_name(list: *const kudu_table_list_t,
                                      index: usize)
                                      -> *const c_char;

    ////////////////////////////////////////////////////////////////////////////
    // Kudu Client
    ////////////////////////////////////////////////////////////////////////////

    pub fn kudu_client_destroy(client: *mut kudu_client_t);
    pub fn kudu_client_list_tables(client: *const kudu_client_t,
                                   tables: *const *mut kudu_table_list_t)
                                   -> *const kudu_status_t;
}
<|endoftext|>


<commit_before>use rss::ChannelBuilder;
use rss::Item;
use std::fs;

mod decoration;
mod markdown;
mod paths;
mod printing;

fn main() {
    printing::heading("Creating website build directory.");

    printing::subheading("Cleaning the build directory.");
    paths::remove_dir(&paths::build());

    printing::subheading("Generating the build directory.");
    paths::create_dir(&paths::build());
    generate_pages();
}

fn generate_pages() {
    let mut markdown_links_to_routes = Vec::new();
    let mut rss_items = Vec::new();

    match fs::read_dir(&paths::pages()) {
        Ok(markdown_files) => {
            for markdown_file in markdown_files {
                let markdown_file = match &markdown_file {
                    Ok(markdown_file) => markdown_file.path(),
                    Err(error) => panic!("There was a problem: {:?}", error),
                };

                let markdown_file_contents = match fs::read_to_string(&markdown_file) {
                    Ok(contents) => contents,
                    Err(error) => panic!("There was a problem: {:?}", error),
                };

                let route = &paths::file_stem(markdown_file);

                let mut lines = markdown_file_contents.lines();

                let title = match lines.next() {
                    Some(title) => title.replace("# ", ""),
                    None => panic!("Cannot find a title in {}.", &route),
                };

                match lines.next() {
                    Some(_) => (),
                    None => panic!(
                        "Cannot find a break between title and description in {}.",
                        &route
                    ),
                };

                let description = match lines.next() {
                    Some(description) => description.replace("_", ""),
                    None => panic!("Cannot find a description in {}.", &route),
                };

                paths::create_dir(&paths::build().join(route));
                paths::create_file(
                    &paths::build().join(route).join("index.html"),
                    &markdown::to_html(&markdown_file_contents, &title, &description),
                );

                let is_post = route != "about" && route != "resume" && route != "projects";

                if is_post {
                    markdown_links_to_routes.push(
                        format!("- [{}: {}](/{}/)", &title, &description, &route).to_string(),
                    );

                    let mut rss_item = Item::default();
                    rss_item.set_link(format!("https://trevordmiller.com/{}/", &route));
                    rss_item.set_title(title);
                    rss_item.set_description(description);
                    rss_item.set_author("Trevor D. Miller".to_string());
                    rss_items.push(rss_item);
                }
            }
        }
        Err(error) => panic!("There was a problem: {:?}", error),
    };

    let markdown_index_contents = format!(
        "# Posts\n_My posts about software development._\n{}",
        markdown_links_to_routes.join("\n")
    );

    paths::create_file(
        &paths::build().join("index.html"),
        &markdown::to_html(
            &markdown_index_contents,
            "Posts",
            "My posts about software development.",
        ),
    );

    let channel = match ChannelBuilder::default()
        .language("en-us".to_string())
        .link("https://trevordmiller.com")
        .title("trevordmiller")
        .description("trevordmiller RSS feed.")
        .items(rss_items)
        .build()
    {
        Ok(channel) => channel.to_string(),
        Err(error) => panic!("There was a problem: {:?}", error),
    };

    paths::create_file(&paths::build().join("rss.xml"), &channel);
}
<commit_msg>Keep period punctuation consistent<commit_after>use rss::ChannelBuilder;
use rss::Item;
use std::fs;

mod decoration;
mod markdown;
mod paths;
mod printing;

fn main() {
    printing::heading("Creating website build directory.");

    printing::subheading("Cleaning the build directory.");
    paths::remove_dir(&paths::build());

    printing::subheading("Generating the build directory.");
    paths::create_dir(&paths::build());
    generate_pages();
}

fn generate_pages() {
    let mut markdown_links_to_routes = Vec::new();
    let mut rss_items = Vec::new();

    match fs::read_dir(&paths::pages()) {
        Ok(markdown_files) => {
            for markdown_file in markdown_files {
                let markdown_file = match &markdown_file {
                    Ok(markdown_file) => markdown_file.path(),
                    Err(error) => panic!("There was a problem: {:?}", error),
                };

                let markdown_file_contents = match fs::read_to_string(&markdown_file) {
                    Ok(contents) => contents,
                    Err(error) => panic!("There was a problem: {:?}", error),
                };

                let route = &paths::file_stem(markdown_file);

                let mut lines = markdown_file_contents.lines();

                let title = match lines.next() {
                    Some(title) => title.replace("# ", ""),
                    None => panic!("Cannot find a title in {}.", &route),
                };

                match lines.next() {
                    Some(_) => (),
                    None => panic!(
                        "Cannot find a break between title and description in {}.",
                        &route
                    ),
                };

                let description = match lines.next() {
                    Some(description) => description.replace("_", "").replace(".", ""),
                    None => panic!("Cannot find a description in {}.", &route),
                };

                paths::create_dir(&paths::build().join(route));
                paths::create_file(
                    &paths::build().join(route).join("index.html"),
                    &markdown::to_html(&markdown_file_contents, &title, &description),
                );

                let is_post = route != "about" && route != "resume" && route != "projects";

                if is_post {
                    markdown_links_to_routes.push(
                        format!("- [{}: {}](/{}/).", &title, &description, &route).to_string(),
                    );

                    let mut rss_item = Item::default();
                    rss_item.set_link(format!("https://trevordmiller.com/{}/", &route));
                    rss_item.set_title(title);
                    rss_item.set_description(format!("{}.", description));
                    rss_item.set_author("Trevor D. Miller".to_string());
                    rss_items.push(rss_item);
                }
            }
        }
        Err(error) => panic!("There was a problem: {:?}", error),
    };

    let markdown_index_contents = format!(
        "# Posts\n_My posts about software development._\n{}",
        markdown_links_to_routes.join("\n")
    );

    paths::create_file(
        &paths::build().join("index.html"),
        &markdown::to_html(
            &markdown_index_contents,
            "Posts",
            "My posts about software development.",
        ),
    );

    let channel = match ChannelBuilder::default()
        .language("en-us".to_string())
        .link("https://trevordmiller.com")
        .title("trevordmiller")
        .description("trevordmiller RSS feed.")
        .items(rss_items)
        .build()
    {
        Ok(channel) => channel.to_string(),
        Err(error) => panic!("There was a problem: {:?}", error),
    };

    paths::create_file(&paths::build().join("rss.xml"), &channel);
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate hamcrest;
extern crate libc;
extern crate rustc_serialize;
extern crate tar;
extern crate tempdir;
extern crate term;
extern crate url;
#[cfg(windows)] extern crate kernel32;
#[cfg(windows)] extern crate winapi;

#[macro_use]
extern crate log;

use cargo::util::Rustc;
use std::ffi::OsStr;

mod support;
macro_rules! test {
    ($name:ident $expr:expr) => (
        #[test]
        fn $name() {
            ::support::paths::setup();
            setup();
            $expr;
        }
    )
}

mod test_bad_config;
mod test_bad_manifest_path;
mod test_cargo;
mod test_cargo_bench;
mod test_cargo_build_auth;
mod test_cargo_build_lib;
mod test_cargo_clean;
mod test_cargo_compile;
mod test_cargo_compile_custom_build;
mod test_cargo_compile_git_deps;
mod test_cargo_compile_path_deps;
mod test_cargo_compile_plugins;
mod test_cargo_compile_rustflags;
mod test_cargo_cross_compile;
mod test_cargo_doc;
mod test_cargo_features;
mod test_cargo_fetch;
mod test_cargo_freshness;
mod test_cargo_generate_lockfile;
mod test_cargo_init;
mod test_cargo_install;
mod test_cargo_metadata;
mod test_cargo_new;
mod test_cargo_package;
mod test_cargo_profiles;
mod test_cargo_overrides;
mod test_cargo_publish;
mod test_cargo_read_manifest;
mod test_cargo_registry;
mod test_cargo_run;
mod test_cargo_concurrent;
mod test_cargo_rustc;
mod test_cargo_rustdoc;
mod test_cargo_search;
mod test_cargo_test;
mod test_cargo_tool_paths;
mod test_cargo_config;
mod test_cargo_verify_project;
mod test_cargo_version;
mod test_shell;
mod test_cargo_death;
mod test_cargo_cfg;

thread_local!(static RUSTC: Rustc = Rustc::new("rustc").unwrap());

fn rustc_host() -> String {
    RUSTC.with(|r| r.host.clone())
}

fn is_nightly() -> bool {
    RUSTC.with(|r| {
        r.verbose_version.contains("-nightly") ||
            r.verbose_version.contains("-dev")
    })
}

fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
    let mut p = cargo::util::process(t.as_ref());
    p.cwd(&support::paths::root())
     .env("HOME", &support::paths::home())
     .env_remove("CARGO_HOME")
     .env_remove("RUSTC")
     .env_remove("XDG_CONFIG_HOME")      // see #2345
     .env("GIT_CONFIG_NOSYSTEM", "1")    // keep trying to sandbox ourselves
     .env_remove("CARGO_TARGET_DIR")     // we assume 'target'
     .env_remove("MSYSTEM");             // assume cmd.exe everywhere on windows
    return p
}

fn cargo_process() -> cargo::util::ProcessBuilder {
    process(&support::cargo_dir().join("cargo"))
}

#[allow(deprecated)] // sleep_ms is now deprecated in favor of sleep()
fn sleep_ms(ms: u32) {
    std::thread::sleep_ms(ms);
}
<commit_msg>Reset RUSTFLAGS when running tests<commit_after>#![deny(warnings)]

extern crate bufstream;
extern crate cargo;
extern crate filetime;
extern crate flate2;
extern crate git2;
extern crate hamcrest;
extern crate libc;
extern crate rustc_serialize;
extern crate tar;
extern crate tempdir;
extern crate term;
extern crate url;
#[cfg(windows)] extern crate kernel32;
#[cfg(windows)] extern crate winapi;

#[macro_use]
extern crate log;

use cargo::util::Rustc;
use std::ffi::OsStr;

mod support;
macro_rules! test {
    ($name:ident $expr:expr) => (
        #[test]
        fn $name() {
            ::support::paths::setup();
            setup();
            $expr;
        }
    )
}

mod test_bad_config;
mod test_bad_manifest_path;
mod test_cargo;
mod test_cargo_bench;
mod test_cargo_build_auth;
mod test_cargo_build_lib;
mod test_cargo_clean;
mod test_cargo_compile;
mod test_cargo_compile_custom_build;
mod test_cargo_compile_git_deps;
mod test_cargo_compile_path_deps;
mod test_cargo_compile_plugins;
mod test_cargo_compile_rustflags;
mod test_cargo_cross_compile;
mod test_cargo_doc;
mod test_cargo_features;
mod test_cargo_fetch;
mod test_cargo_freshness;
mod test_cargo_generate_lockfile;
mod test_cargo_init;
mod test_cargo_install;
mod test_cargo_metadata;
mod test_cargo_new;
mod test_cargo_package;
mod test_cargo_profiles;
mod test_cargo_overrides;
mod test_cargo_publish;
mod test_cargo_read_manifest;
mod test_cargo_registry;
mod test_cargo_run;
mod test_cargo_concurrent;
mod test_cargo_rustc;
mod test_cargo_rustdoc;
mod test_cargo_search;
mod test_cargo_test;
mod test_cargo_tool_paths;
mod test_cargo_config;
mod test_cargo_verify_project;
mod test_cargo_version;
mod test_shell;
mod test_cargo_death;
mod test_cargo_cfg;

thread_local!(static RUSTC: Rustc = Rustc::new("rustc").unwrap());

fn rustc_host() -> String {
    RUSTC.with(|r| r.host.clone())
}

fn is_nightly() -> bool {
    RUSTC.with(|r| {
        r.verbose_version.contains("-nightly") ||
            r.verbose_version.contains("-dev")
    })
}

fn process<T: AsRef<OsStr>>(t: T) -> cargo::util::ProcessBuilder {
    let mut p = cargo::util::process(t.as_ref());
    p.cwd(&support::paths::root())
     .env("HOME", &support::paths::home())
     .env_remove("CARGO_HOME")
     .env_remove("RUSTC")
     .env_remove("RUSTFLAGS")
     .env_remove("XDG_CONFIG_HOME")      // see #2345
     .env("GIT_CONFIG_NOSYSTEM", "1")    // keep trying to sandbox ourselves
     .env_remove("CARGO_TARGET_DIR")     // we assume 'target'
     .env_remove("MSYSTEM");             // assume cmd.exe everywhere on windows
    return p
}

fn cargo_process() -> cargo::util::ProcessBuilder {
    process(&support::cargo_dir().join("cargo"))
}

#[allow(deprecated)] // sleep_ms is now deprecated in favor of sleep()
fn sleep_ms(ms: u32) {
    std::thread::sleep_ms(ms);
}
<|endoftext|>


<commit_before>//! Definitions for uclibc on 64bit systems
pub type blkcnt_t = i64;
pub type blksize_t = i64;
pub type clock_t = i64;
pub type c_char = u8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type fsblkcnt_t = ::c_ulong;
pub type fsfilcnt_t = ::c_ulong;
pub type fsword_t = ::c_long;
pub type ino_t = ::c_ulong;
pub type nlink_t = ::c_uint;
pub type off_t = ::c_long;
pub type rlim_t = c_ulong;
// [uClibc docs] Note stat64 has the same shape as stat for x86-64.
pub type stat64 = stat;
pub type suseconds_t = ::c_long;
pub type time_t = ::c_int;
pub type wchar_t = ::c_int;

pub type fsblkcnt64_t = u64;
pub type fsfilcnt64_t = u64;
pub type __u64 = ::c_ulong;

s! {
    pub struct ipc_perm {
        pub __key: ::key_t,
        pub uid: ::uid_t,
        pub gid: ::gid_t,
        pub cuid: ::uid_t,
        pub cgid: ::gid_t,
        pub mode: ::c_ushort, // read / write
        __pad1: ::c_ushort,
        pub __seq: ::c_ushort,
        __pad2: ::c_ushort,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    #[cfg(not(target_os = "l4re"))]
    pub struct pthread_attr_t {
        __detachstate: ::c_int,
        __schedpolicy: ::c_int,
        __schedparam: __sched_param,
        __inheritsched: ::c_int,
        __scope: ::c_int,
        __guardsize: ::size_t,
        __stackaddr_set: ::c_int,
        __stackaddr: *mut ::c_void, // better don't use it
        __stacksize: ::size_t,
    }

    pub struct __sched_param {
        __sched_priority: ::c_int,
    }

    pub struct siginfo_t {
        si_signo: ::c_int, // signal number
        si_errno: ::c_int, // if not zero: error value of signal, see errno.h
        si_code: ::c_int,  // signal code
        pub _pad: [::c_int; 28], // unported union
        _align: [usize; 0],
    }

    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t, // segment size in bytes
        pub shm_atime: ::time_t, // time of last shmat()
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_cpid: ::pid_t,
        pub shm_lpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    pub struct msqid_ds {
        pub msg_perm: ::ipc_perm,
        pub msg_stime: ::time_t,
        pub msg_rtime: ::time_t,
        pub msg_ctime: ::time_t,
        __msg_cbytes: ::c_ulong,
        pub msg_qnum: ::msgqnum_t,
        pub msg_qbytes: ::msglen_t,
        pub msg_lspid: ::pid_t,
        pub msg_lrpid: ::pid_t,
        __ignored1: ::c_ulong,
        __ignored2: ::c_ulong,
    }

    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    // ------------------------------------------------------------
    // definitions below are *unverified* and might **break** the software
//    pub struct in_addr {
//        pub s_addr: in_addr_t,
//    }
//
//    pub struct in6_addr {
//        pub s6_addr: [u8; 16],
//        #[cfg(not(libc_align))]
//        __align: [u32; 0],
//    }

    pub struct stat {
        pub st_dev: ::c_ulong,
        pub st_ino: ::ino_t,
        // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of
        // nlink and mode are swapped on 64 bit systems.
        pub st_nlink: ::nlink_t,
        pub st_mode: ::mode_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulong, // dev_t
        pub st_size: off_t, // file size
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_atime: ::time_t,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::time_t,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::time_t,
        pub st_ctime_nsec: ::c_ulong,
        st_pad4: [::c_long; 3]
    }

    pub struct sigaction {
        pub sa_handler: ::sighandler_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::Option<extern fn()>,
        pub sa_mask: ::sigset_t,
    }

    pub struct stack_t { // FIXME
        pub ss_sp: *mut ::c_void,
        pub ss_flags: ::c_int,
        pub ss_size: ::size_t
    }

    pub struct statfs { // FIXME
        pub f_type: fsword_t,
        pub f_bsize: fsword_t,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: fsword_t,
        pub f_frsize: fsword_t,
        f_spare: [fsword_t; 5],
    }

    pub struct statfs64 {
        pub f_type: ::c_int,
        pub f_bsize: ::c_int,
        pub f_blocks: ::fsblkcnt64_t,
        pub f_bfree: ::fsblkcnt64_t,
        pub f_bavail: ::fsblkcnt64_t,
        pub f_files: ::fsfilcnt64_t,
        pub f_ffree: ::fsfilcnt64_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: ::c_int,
        pub f_frsize: ::c_int,
        pub f_flags: ::c_int,
        pub f_spare: [::c_int; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        pub f_favail: u64,
        pub f_fsid: ::c_ulong,
        __f_unused: ::c_int,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct msghdr { // FIXME
        pub msg_name: *mut ::c_void,
        pub msg_namelen: ::socklen_t,
        pub msg_iov: *mut ::iovec,
        pub msg_iovlen: ::size_t,
        pub msg_control: *mut ::c_void,
        pub msg_controllen: ::size_t,
        pub msg_flags: ::c_int,
    }

    pub struct termios { // FIXME
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
    }

    pub struct sigset_t { // FIXME
        __val: [::c_ulong; 16],
    }

    pub struct sysinfo { // FIXME
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 0],
    }

    pub struct glob_t { // FIXME
        pub gl_pathc: ::size_t,
        pub gl_pathv: *mut *mut c_char,
        pub gl_offs: ::size_t,
        pub gl_flags: ::c_int,
        __unused1: *mut ::c_void,
        __unused2: *mut ::c_void,
        __unused3: *mut ::c_void,
        __unused4: *mut ::c_void,
        __unused5: *mut ::c_void,
    }

    pub struct cpu_set_t { // FIXME
        #[cfg(target_pointer_width = "32")]
        bits: [u32; 32],
        #[cfg(target_pointer_width = "64")]
        bits: [u64; 16],
    }

    pub struct fsid_t { // FIXME
        __val: [::c_int; 2],
    }

    // FIXME this is actually a union
    pub struct sem_t {
        #[cfg(target_pointer_width = "32")]
        __size: [::c_char; 16],
        #[cfg(target_pointer_width = "64")]
        __size: [::c_char; 32],
        __align: [::c_long; 0],
    }

    pub struct cmsghdr {
        pub cmsg_len: ::size_t,
        pub cmsg_level: ::c_int,
        pub cmsg_type: ::c_int,
    }
}

s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    pub struct dirent {
        pub d_ino: ::ino64_t,
        pub d_off: ::off64_t,
        pub d_reclen: u16,
        pub d_type: u8,
        pub d_name: [::c_char; 256],
    }
}

// constants
pub const ENAMETOOLONG: ::c_int = 36; // File name too long
pub const ENOTEMPTY: ::c_int = 39; // Directory not empty
pub const ELOOP: ::c_int = 40; // Too many symbolic links encountered
pub const EADDRINUSE: ::c_int = 98; // Address already in use
pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address
pub const ENETDOWN: ::c_int = 100; // Network is down
pub const ENETUNREACH: ::c_int = 101; // Network is unreachable
pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort
pub const ECONNREFUSED: ::c_int = 111; // Connection refused
pub const ECONNRESET: ::c_int = 104; // Connection reset by peer
pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur
pub const ENOSYS: ::c_int = 38; // Function not implemented
pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected
pub const ETIMEDOUT: ::c_int = 110; // connection timed out
pub const ESTALE: ::c_int = 116; // Stale file handle
pub const EHOSTUNREACH: ::c_int = 113; // No route to host
pub const EDQUOT: ::c_int = 122; // Quota exceeded
pub const EOPNOTSUPP: ::c_int = 0x5f;
pub const ENODATA: ::c_int = 0x3d;
pub const O_APPEND: ::c_int = 02000;
pub const O_ACCMODE: ::c_int = 0003;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_CREAT: ::c_int = 0100;
pub const O_DIRECTORY: ::c_int = 0200000;
pub const O_EXCL: ::c_int = 0200;
pub const O_NONBLOCK: ::c_int = 04000;
pub const O_TRUNC: ::c_int = 01000;
pub const NCCS: usize = 32;
pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams
pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h
pub const RLIM_INFINITY: u64 = 0xffffffffffffffff;
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

cfg_if! {
    if #[cfg(target_os = "l4re")] {
        mod l4re;
        pub use self::l4re::*;
    } else {
        mod other;
        pub use other::*;
    }
}
<commit_msg>add O_NOFOLLOW flag to uclibc<commit_after>//! Definitions for uclibc on 64bit systems
pub type blkcnt_t = i64;
pub type blksize_t = i64;
pub type clock_t = i64;
pub type c_char = u8;
pub type c_long = i64;
pub type c_ulong = u64;
pub type fsblkcnt_t = ::c_ulong;
pub type fsfilcnt_t = ::c_ulong;
pub type fsword_t = ::c_long;
pub type ino_t = ::c_ulong;
pub type nlink_t = ::c_uint;
pub type off_t = ::c_long;
pub type rlim_t = c_ulong;
// [uClibc docs] Note stat64 has the same shape as stat for x86-64.
pub type stat64 = stat;
pub type suseconds_t = ::c_long;
pub type time_t = ::c_int;
pub type wchar_t = ::c_int;

pub type fsblkcnt64_t = u64;
pub type fsfilcnt64_t = u64;
pub type __u64 = ::c_ulong;

s! {
    pub struct ipc_perm {
        pub __key: ::key_t,
        pub uid: ::uid_t,
        pub gid: ::gid_t,
        pub cuid: ::uid_t,
        pub cgid: ::gid_t,
        pub mode: ::c_ushort, // read / write
        __pad1: ::c_ushort,
        pub __seq: ::c_ushort,
        __pad2: ::c_ushort,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    #[cfg(not(target_os = "l4re"))]
    pub struct pthread_attr_t {
        __detachstate: ::c_int,
        __schedpolicy: ::c_int,
        __schedparam: __sched_param,
        __inheritsched: ::c_int,
        __scope: ::c_int,
        __guardsize: ::size_t,
        __stackaddr_set: ::c_int,
        __stackaddr: *mut ::c_void, // better don't use it
        __stacksize: ::size_t,
    }

    pub struct __sched_param {
        __sched_priority: ::c_int,
    }

    pub struct siginfo_t {
        si_signo: ::c_int, // signal number
        si_errno: ::c_int, // if not zero: error value of signal, see errno.h
        si_code: ::c_int,  // signal code
        pub _pad: [::c_int; 28], // unported union
        _align: [usize; 0],
    }

    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t, // segment size in bytes
        pub shm_atime: ::time_t, // time of last shmat()
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_cpid: ::pid_t,
        pub shm_lpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        __unused1: ::c_ulong,
        __unused2: ::c_ulong
    }

    pub struct msqid_ds {
        pub msg_perm: ::ipc_perm,
        pub msg_stime: ::time_t,
        pub msg_rtime: ::time_t,
        pub msg_ctime: ::time_t,
        __msg_cbytes: ::c_ulong,
        pub msg_qnum: ::msgqnum_t,
        pub msg_qbytes: ::msglen_t,
        pub msg_lspid: ::pid_t,
        pub msg_lrpid: ::pid_t,
        __ignored1: ::c_ulong,
        __ignored2: ::c_ulong,
    }

    pub struct sockaddr {
        pub sa_family: ::sa_family_t,
        pub sa_data: [::c_char; 14],
    }

    pub struct sockaddr_in {
        pub sin_family: ::sa_family_t,
        pub sin_port: ::in_port_t,
        pub sin_addr: ::in_addr,
        pub sin_zero: [u8; 8],
    }

    pub struct sockaddr_in6 {
        pub sin6_family: ::sa_family_t,
        pub sin6_port: ::in_port_t,
        pub sin6_flowinfo: u32,
        pub sin6_addr: ::in6_addr,
        pub sin6_scope_id: u32,
    }

    // ------------------------------------------------------------
    // definitions below are *unverified* and might **break** the software
//    pub struct in_addr {
//        pub s_addr: in_addr_t,
//    }
//
//    pub struct in6_addr {
//        pub s6_addr: [u8; 16],
//        #[cfg(not(libc_align))]
//        __align: [u32; 0],
//    }

    pub struct stat {
        pub st_dev: ::c_ulong,
        pub st_ino: ::ino_t,
        // According to uclibc/libc/sysdeps/linux/x86_64/bits/stat.h, order of
        // nlink and mode are swapped on 64 bit systems.
        pub st_nlink: ::nlink_t,
        pub st_mode: ::mode_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::c_ulong, // dev_t
        pub st_size: off_t, // file size
        pub st_blksize: ::blksize_t,
        pub st_blocks: ::blkcnt_t,
        pub st_atime: ::time_t,
        pub st_atime_nsec: ::c_ulong,
        pub st_mtime: ::time_t,
        pub st_mtime_nsec: ::c_ulong,
        pub st_ctime: ::time_t,
        pub st_ctime_nsec: ::c_ulong,
        st_pad4: [::c_long; 3]
    }

    pub struct sigaction {
        pub sa_handler: ::sighandler_t,
        pub sa_flags: ::c_ulong,
        pub sa_restorer: ::Option<extern fn()>,
        pub sa_mask: ::sigset_t,
    }

    pub struct stack_t { // FIXME
        pub ss_sp: *mut ::c_void,
        pub ss_flags: ::c_int,
        pub ss_size: ::size_t
    }

    pub struct statfs { // FIXME
        pub f_type: fsword_t,
        pub f_bsize: fsword_t,
        pub f_blocks: ::fsblkcnt_t,
        pub f_bfree: ::fsblkcnt_t,
        pub f_bavail: ::fsblkcnt_t,
        pub f_files: ::fsfilcnt_t,
        pub f_ffree: ::fsfilcnt_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: fsword_t,
        pub f_frsize: fsword_t,
        f_spare: [fsword_t; 5],
    }

    pub struct statfs64 {
        pub f_type: ::c_int,
        pub f_bsize: ::c_int,
        pub f_blocks: ::fsblkcnt64_t,
        pub f_bfree: ::fsblkcnt64_t,
        pub f_bavail: ::fsblkcnt64_t,
        pub f_files: ::fsfilcnt64_t,
        pub f_ffree: ::fsfilcnt64_t,
        pub f_fsid: ::fsid_t,
        pub f_namelen: ::c_int,
        pub f_frsize: ::c_int,
        pub f_flags: ::c_int,
        pub f_spare: [::c_int; 4],
    }

    pub struct statvfs64 {
        pub f_bsize: ::c_ulong,
        pub f_frsize: ::c_ulong,
        pub f_blocks: u64,
        pub f_bfree: u64,
        pub f_bavail: u64,
        pub f_files: u64,
        pub f_ffree: u64,
        pub f_favail: u64,
        pub f_fsid: ::c_ulong,
        __f_unused: ::c_int,
        pub f_flag: ::c_ulong,
        pub f_namemax: ::c_ulong,
        __f_spare: [::c_int; 6],
    }

    pub struct msghdr { // FIXME
        pub msg_name: *mut ::c_void,
        pub msg_namelen: ::socklen_t,
        pub msg_iov: *mut ::iovec,
        pub msg_iovlen: ::size_t,
        pub msg_control: *mut ::c_void,
        pub msg_controllen: ::size_t,
        pub msg_flags: ::c_int,
    }

    pub struct termios { // FIXME
        pub c_iflag: ::tcflag_t,
        pub c_oflag: ::tcflag_t,
        pub c_cflag: ::tcflag_t,
        pub c_lflag: ::tcflag_t,
        pub c_line: ::cc_t,
        pub c_cc: [::cc_t; ::NCCS],
    }

    pub struct sigset_t { // FIXME
        __val: [::c_ulong; 16],
    }

    pub struct sysinfo { // FIXME
        pub uptime: ::c_long,
        pub loads: [::c_ulong; 3],
        pub totalram: ::c_ulong,
        pub freeram: ::c_ulong,
        pub sharedram: ::c_ulong,
        pub bufferram: ::c_ulong,
        pub totalswap: ::c_ulong,
        pub freeswap: ::c_ulong,
        pub procs: ::c_ushort,
        pub pad: ::c_ushort,
        pub totalhigh: ::c_ulong,
        pub freehigh: ::c_ulong,
        pub mem_unit: ::c_uint,
        pub _f: [::c_char; 0],
    }

    pub struct glob_t { // FIXME
        pub gl_pathc: ::size_t,
        pub gl_pathv: *mut *mut c_char,
        pub gl_offs: ::size_t,
        pub gl_flags: ::c_int,
        __unused1: *mut ::c_void,
        __unused2: *mut ::c_void,
        __unused3: *mut ::c_void,
        __unused4: *mut ::c_void,
        __unused5: *mut ::c_void,
    }

    pub struct cpu_set_t { // FIXME
        #[cfg(target_pointer_width = "32")]
        bits: [u32; 32],
        #[cfg(target_pointer_width = "64")]
        bits: [u64; 16],
    }

    pub struct fsid_t { // FIXME
        __val: [::c_int; 2],
    }

    // FIXME this is actually a union
    pub struct sem_t {
        #[cfg(target_pointer_width = "32")]
        __size: [::c_char; 16],
        #[cfg(target_pointer_width = "64")]
        __size: [::c_char; 32],
        __align: [::c_long; 0],
    }

    pub struct cmsghdr {
        pub cmsg_len: ::size_t,
        pub cmsg_level: ::c_int,
        pub cmsg_type: ::c_int,
    }
}

s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    pub struct dirent {
        pub d_ino: ::ino64_t,
        pub d_off: ::off64_t,
        pub d_reclen: u16,
        pub d_type: u8,
        pub d_name: [::c_char; 256],
    }
}

// constants
pub const ENAMETOOLONG: ::c_int = 36; // File name too long
pub const ENOTEMPTY: ::c_int = 39; // Directory not empty
pub const ELOOP: ::c_int = 40; // Too many symbolic links encountered
pub const EADDRINUSE: ::c_int = 98; // Address already in use
pub const EADDRNOTAVAIL: ::c_int = 99; // Cannot assign requested address
pub const ENETDOWN: ::c_int = 100; // Network is down
pub const ENETUNREACH: ::c_int = 101; // Network is unreachable
pub const ECONNABORTED: ::c_int = 103; // Software caused connection abort
pub const ECONNREFUSED: ::c_int = 111; // Connection refused
pub const ECONNRESET: ::c_int = 104; // Connection reset by peer
pub const EDEADLK: ::c_int = 35; // Resource deadlock would occur
pub const ENOSYS: ::c_int = 38; // Function not implemented
pub const ENOTCONN: ::c_int = 107; // Transport endpoint is not connected
pub const ETIMEDOUT: ::c_int = 110; // connection timed out
pub const ESTALE: ::c_int = 116; // Stale file handle
pub const EHOSTUNREACH: ::c_int = 113; // No route to host
pub const EDQUOT: ::c_int = 122; // Quota exceeded
pub const EOPNOTSUPP: ::c_int = 0x5f;
pub const ENODATA: ::c_int = 0x3d;
pub const O_APPEND: ::c_int = 02000;
pub const O_ACCMODE: ::c_int = 0003;
pub const O_CLOEXEC: ::c_int = 0x80000;
pub const O_CREAT: ::c_int = 0100;
pub const O_DIRECTORY: ::c_int = 0200000;
pub const O_EXCL: ::c_int = 0200;
pub const O_NOFOLLOW: ::c_int = 0x20000;
pub const O_NONBLOCK: ::c_int = 04000;
pub const O_TRUNC: ::c_int = 01000;
pub const NCCS: usize = 32;
pub const SIG_SETMASK: ::c_int = 2; // Set the set of blocked signals
pub const __SIZEOF_PTHREAD_MUTEX_T: usize = 40;
pub const __SIZEOF_PTHREAD_MUTEXATTR_T: usize = 4;
pub const SOCK_DGRAM: ::c_int = 2; // connectionless, unreliable datagrams
pub const SOCK_STREAM: ::c_int = 1; // …/common/bits/socket_type.h
pub const RLIM_INFINITY: u64 = 0xffffffffffffffff;
pub const __SIZEOF_PTHREAD_COND_T: usize = 48;
pub const __SIZEOF_PTHREAD_CONDATTR_T: usize = 4;
pub const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56;
pub const __SIZEOF_PTHREAD_RWLOCKATTR_T: usize = 8;

cfg_if! {
    if #[cfg(target_os = "l4re")] {
        mod l4re;
        pub use self::l4re::*;
    } else {
        mod other;
        pub use other::*;
    }
}
<|endoftext|>


<commit_before>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate log;
extern crate env_logger;
extern crate iron;
extern crate mount;
extern crate staticfile;
extern crate bodyparser;
extern crate serde;
extern crate serde_json;
extern crate mktemp;
#[macro_use]
extern crate quick_error;

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

use mount::Mount;
use staticfile::Static;
use iron::prelude::*;
use iron::status;

use sandbox::Sandbox;

const DEFAULT_ADDRESS: &'static str = "127.0.0.1";
const DEFAULT_PORT: u16 = 5000;

mod sandbox;

fn main() {
    env_logger::init().expect("Unable to initialize logger");

    let root: PathBuf = env::var_os("PLAYGROUND_UI_ROOT").expect("Must specify PLAYGROUND_UI_ROOT").into();
    let address = env::var("PLAYGROUND_UI_ADDRESS").unwrap_or(DEFAULT_ADDRESS.to_string());
    let port = env::var("PLAYGROUND_UI_PORT").ok().and_then(|p| p.parse().ok()).unwrap_or(DEFAULT_PORT);

    let mut mount = Mount::new();
    mount.mount("/", Static::new(&root));
    mount.mount("/compile", compile);
    mount.mount("/execute", execute);
    mount.mount("/format", format);

    info!("Starting the server on {}:{}", address, port);
    Iron::new(mount).http((&*address, port)).expect("Unable to start server");
}

fn compile(req: &mut Request) -> IronResult<Response> {
    match req.get::<bodyparser::Struct<CompileRequest>>() {
        Ok(Some(req)) => {
            let sandbox = Sandbox::new().expect("Unable to create sandbox");
            let resp = CompileResponse::from(sandbox.compile(&req.into()).expect("Unable to compile"));
            let body = serde_json::ser::to_string(&resp).expect("Can't serialize");

            Ok(Response::with((status::Ok, body)))
        }
        Ok(None) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL1" }"#)))
        },
        Err(_) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL2" }"#)))
        }
    }
}

fn execute(req: &mut Request) -> IronResult<Response> {
    match req.get::<bodyparser::Struct<ExecuteRequest>>() {
        Ok(Some(req)) => {
            let sandbox = Sandbox::new().expect("Unable to create sandbox");;
            let resp = ExecuteResponse::from(sandbox.execute(&req.into()).expect("Unable to execute"));
            let body = serde_json::ser::to_string(&resp).expect("Can't serialize");

            Ok(Response::with((status::Ok, body)))
        }
        Ok(None) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL1" }"#)))
        },
        Err(_) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL2" }"#)))
        }
    }
}

fn format(req: &mut Request) -> IronResult<Response> {
    match req.get::<bodyparser::Struct<FormatRequest>>() {
        Ok(Some(req)) => {
            let sandbox = Sandbox::new().expect("Unable to create sandbox");;
            let resp = FormatResponse::from(sandbox.format(&req.into()).expect("Unable to format"));
            let body = serde_json::ser::to_string(&resp).expect("Can't serialize");
            Ok(Response::with((status::Ok, body)))
        }
        Ok(None) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "code": "FAIL1" }"#)))
        },
        Err(_) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "code": "FAIL2" }"#)))
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
struct CompileRequest {
    target: String,
    channel: String,
    mode: String,
    tests: bool,
    code: String,
}

impl From<CompileRequest> for sandbox::CompileRequest {
    fn from(me: CompileRequest) -> Self {
        sandbox::CompileRequest {
            target: parse_target(&me.target),
            channel: parse_channel(&me.channel),
            mode: parse_mode(&me.mode),
            tests: me.tests,
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct CompileResponse {
    success: bool,
    code: String,
    stdout: String,
    stderr: String,
}

impl From<sandbox::CompileResponse> for CompileResponse {
    fn from(me: sandbox::CompileResponse) -> Self {
        CompileResponse {
            success: me.success,
            code: me.code,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
struct ExecuteRequest {
    channel: String,
    mode: String,
    tests: bool,
    code: String,
}

impl From<ExecuteRequest> for sandbox::ExecuteRequest {
    fn from(me: ExecuteRequest) -> Self {
        sandbox::ExecuteRequest {
            channel: parse_channel(&me.channel),
            mode: parse_mode(&me.mode),
            tests: me.tests,
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct ExecuteResponse {
    success: bool,
    stdout: String,
    stderr: String,
}

impl From<sandbox::ExecuteResponse> for ExecuteResponse {
    fn from(me: sandbox::ExecuteResponse) -> Self {
        ExecuteResponse {
            success: me.success,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
struct FormatRequest {
    code: String,
}

impl From<FormatRequest> for sandbox::FormatRequest {
    fn from(me: FormatRequest) -> Self {
        sandbox::FormatRequest {
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct FormatResponse {
    success: bool,
    code: String,
    stdout: String,
    stderr: String,
}

impl From<sandbox::FormatResponse> for FormatResponse {
    fn from(me: sandbox::FormatResponse) -> Self {
        FormatResponse {
            success: me.success,
            code: me.code,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

fn parse_target(s: &str) -> sandbox::CompileTarget {
    match s {
        "asm" => sandbox::CompileTarget::Assembly,
        "llvm-ir" => sandbox::CompileTarget::LlvmIr,
        _ => panic!("Unknown compilation target {}", s),
    }
}

fn parse_channel(s: &str) -> sandbox::Channel {
    match s {
        "stable" => sandbox::Channel::Stable,
        "beta" => sandbox::Channel::Beta,
        "nightly" => sandbox::Channel::Nightly,
        _ => panic!("Unknown channel {}", s),
    }
}

fn parse_mode(s: &str) -> sandbox::Mode {
    match s {
        "debug" => sandbox::Mode::Debug,
        "release" => sandbox::Mode::Release,
        _ => panic!("Unknown mode {}", s),
    }
}
<commit_msg>DRY up sandbox-related HTTP endpoints<commit_after>#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate log;
extern crate env_logger;
extern crate iron;
extern crate mount;
extern crate staticfile;
extern crate bodyparser;
extern crate serde;
extern crate serde_json;
extern crate mktemp;
#[macro_use]
extern crate quick_error;

use std::any::Any;
use std::env;
use std::path::PathBuf;

use iron::prelude::*;
use iron::status;
use mount::Mount;
use serde::{Serialize, Deserialize};
use staticfile::Static;

use sandbox::Sandbox;

const DEFAULT_ADDRESS: &'static str = "127.0.0.1";
const DEFAULT_PORT: u16 = 5000;

mod sandbox;

fn main() {
    env_logger::init().expect("Unable to initialize logger");

    let root: PathBuf = env::var_os("PLAYGROUND_UI_ROOT").expect("Must specify PLAYGROUND_UI_ROOT").into();
    let address = env::var("PLAYGROUND_UI_ADDRESS").unwrap_or(DEFAULT_ADDRESS.to_string());
    let port = env::var("PLAYGROUND_UI_PORT").ok().and_then(|p| p.parse().ok()).unwrap_or(DEFAULT_PORT);

    let mut mount = Mount::new();
    mount.mount("/", Static::new(&root));
    mount.mount("/compile", compile);
    mount.mount("/execute", execute);
    mount.mount("/format", format);

    info!("Starting the server on {}:{}", address, port);
    Iron::new(mount).http((&*address, port)).expect("Unable to start server");
}

fn compile(req: &mut Request) -> IronResult<Response> {
    with_sandbox(req, |sandbox, req: CompileRequest| {
        sandbox.compile(&req.into()).map(CompileResponse::from)
    })
}

fn execute(req: &mut Request) -> IronResult<Response> {
    with_sandbox(req, |sandbox, req: ExecuteRequest| {
        sandbox.execute(&req.into()).map(ExecuteResponse::from)
    })
}

fn format(req: &mut Request) -> IronResult<Response> {
    with_sandbox(req, |sandbox, req: FormatRequest| {
        sandbox.format(&req.into()).map(FormatResponse::from)
    })
}

fn with_sandbox<Req, Resp, F>(req: &mut Request, f: F) -> IronResult<Response>
    where F: FnOnce(Sandbox, Req) -> sandbox::Result<Resp>,
          Req: Deserialize + Clone + Any + 'static,
          Resp: Serialize,
{
    match req.get::<bodyparser::Struct<Req>>() {
        Ok(Some(req)) => {
            let sandbox = Sandbox::new().expect("Unable to create sandbox");

            let resp = f(sandbox, req).expect("Sandbox request failed");
            let body = serde_json::ser::to_string(&resp).expect("Can't serialize response");

            Ok(Response::with((status::Ok, body)))
        },
        Ok(None) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL1" }"#)))
        },
        Err(_) => {
            // TODO: real error
            Ok(Response::with((status::Ok, r#"{ "output": "FAIL2" }"#)))
        },
    }
}

#[derive(Debug, Clone, Deserialize)]
struct CompileRequest {
    target: String,
    channel: String,
    mode: String,
    tests: bool,
    code: String,
}

impl From<CompileRequest> for sandbox::CompileRequest {
    fn from(me: CompileRequest) -> Self {
        sandbox::CompileRequest {
            target: parse_target(&me.target),
            channel: parse_channel(&me.channel),
            mode: parse_mode(&me.mode),
            tests: me.tests,
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct CompileResponse {
    success: bool,
    code: String,
    stdout: String,
    stderr: String,
}

impl From<sandbox::CompileResponse> for CompileResponse {
    fn from(me: sandbox::CompileResponse) -> Self {
        CompileResponse {
            success: me.success,
            code: me.code,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
struct ExecuteRequest {
    channel: String,
    mode: String,
    tests: bool,
    code: String,
}

impl From<ExecuteRequest> for sandbox::ExecuteRequest {
    fn from(me: ExecuteRequest) -> Self {
        sandbox::ExecuteRequest {
            channel: parse_channel(&me.channel),
            mode: parse_mode(&me.mode),
            tests: me.tests,
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct ExecuteResponse {
    success: bool,
    stdout: String,
    stderr: String,
}

impl From<sandbox::ExecuteResponse> for ExecuteResponse {
    fn from(me: sandbox::ExecuteResponse) -> Self {
        ExecuteResponse {
            success: me.success,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

#[derive(Debug, Clone, Deserialize)]
struct FormatRequest {
    code: String,
}

impl From<FormatRequest> for sandbox::FormatRequest {
    fn from(me: FormatRequest) -> Self {
        sandbox::FormatRequest {
            code: me.code,
        }
    }
}

#[derive(Debug, Clone, Serialize)]
struct FormatResponse {
    success: bool,
    code: String,
    stdout: String,
    stderr: String,
}

impl From<sandbox::FormatResponse> for FormatResponse {
    fn from(me: sandbox::FormatResponse) -> Self {
        FormatResponse {
            success: me.success,
            code: me.code,
            stdout: me.stdout,
            stderr: me.stderr,
        }
    }
}

fn parse_target(s: &str) -> sandbox::CompileTarget {
    match s {
        "asm" => sandbox::CompileTarget::Assembly,
        "llvm-ir" => sandbox::CompileTarget::LlvmIr,
        _ => panic!("Unknown compilation target {}", s),
    }
}

fn parse_channel(s: &str) -> sandbox::Channel {
    match s {
        "stable" => sandbox::Channel::Stable,
        "beta" => sandbox::Channel::Beta,
        "nightly" => sandbox::Channel::Nightly,
        _ => panic!("Unknown channel {}", s),
    }
}

fn parse_mode(s: &str) -> sandbox::Mode {
    match s {
        "debug" => sandbox::Mode::Debug,
        "release" => sandbox::Mode::Release,
        _ => panic!("Unknown mode {}", s),
    }
}
<|endoftext|>


<commit_before>use std::io::{BufferedReader, File};
use material::materials::CookTorranceMaterial;
use geometry::{Mesh, Prim};
use geometry::prims::Triangle;
use vec3::Vec3;

/// This is limited to only CookTorranceMaterials, as I couldn't get a Box<Material> to clone
/// a new material for each triangle primitive in the object model.
#[allow(dead_code)]
pub fn from_obj(position: Vec3, scale: f64, material: CookTorranceMaterial /*Box<Material>*/, flip_normals: bool, filename: &str) -> Mesh {
    let path = Path::new(filename);
    let mut file = BufferedReader::new(File::open(&path));

    let mut vertices: Vec<Vec3> = Vec::new();
    let mut tex_coords: Vec<Vec3> = Vec::new();
    let mut normals: Vec<Vec3> = Vec::new();
    let mut triangles: Vec<Box<Prim+Send+Share>> = Vec::new();

    let start_time = ::time::get_time();
    let print_progress_every = 1024u;
    let mut current_line = 0;
    let mut processed_bytes = 0;
    let total_bytes = match path.stat() {
        Ok(stat) => stat.size,
        Err(e) => fail!(e),
    };

    for line_iter in file.lines() {
        let line: String = match line_iter {
            Ok(x) => {x},
            Err(e) => {fail!(e)}
        };

        let tokens: Vec<&str> = line.as_slice().words().collect();
        if tokens.len() < 4 { continue }

        match tokens[0].as_slice() {
            "v" => {
                vertices.push(Vec3 {
                    x: match from_str::<f64>(tokens[1].as_slice()) { Some(f) => f * scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) },
                    y: match from_str::<f64>(tokens[2].as_slice()) { Some(f) => f * scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) },
                    z: match from_str::<f64>(tokens[3].as_slice()) { Some(f) => f * scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) }
                });
            },
            "vt" => {
                tex_coords.push(Vec3 {
                    x: match from_str::<f64>(tokens[1].as_slice()) { Some(f) => f * scale, None => fail!(format!("Bad texture coordinate in file. w-coord not supported. `{}`", line)) },
                    y: match from_str::<f64>(tokens[2].as_slice()) { Some(f) => f * scale, None => fail!(format!("Bad texture coordinate in file. w-coord not supported. `{}`", line)) },
                    z: 0.0
                });
            },
            "vn" => {
                let normals_flip_scale = if flip_normals { -1.0 } else { 1.0 };
                normals.push(Vec3 {
                    x: match from_str::<f64>(tokens[1].as_slice()) { Some(f) => f * scale * normals_flip_scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) },
                    y: match from_str::<f64>(tokens[2].as_slice()) { Some(f) => f * scale * normals_flip_scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) },
                    z: match from_str::<f64>(tokens[3].as_slice()) { Some(f) => f * scale * normals_flip_scale, None => fail!(format!("Bad vertex coordinate in file. `{}`", line)) }
                });
            },
            "f" => {
                // let pairs: Vec<&str> = tokens.tail().iter().map( |token| {
                //     token.to_string().as_slice().split('/').collect()
                // }).collect();

                let v0: Vec<&str> = tokens[1].split('/').collect();
                let v1: Vec<&str> = tokens[2].split('/').collect();
                let v2: Vec<&str> = tokens[3].split('/').collect();

                // If no texture coordinates were supplied, default to zero.
                let mut u = Vec3::zero();
                let mut v = Vec3::zero();

                if v0[1].len() > 0 {
                    u = Vec3 {
                        x: match from_str::<uint>(v0[1]) { Some(x) => {(tex_coords[x-1u as uint]).x}, None => {fail!("Bad texture")} },
                        y: match from_str::<uint>(v1[1]) { Some(x) => {(tex_coords[x-1u as uint]).x}, None => {fail!("Bad texture")} },
                        z: match from_str::<uint>(v2[1]) { Some(x) => {(tex_coords[x-1u as uint]).x}, None => {fail!("Bad texture")} }
                    };

                    v = Vec3 {
                        x: match from_str::<uint>(v0[1]) { Some(x) => {(tex_coords[x-1u as uint]).y}, None => {fail!("Bad texture")} },
                        y: match from_str::<uint>(v1[1]) { Some(x) => {(tex_coords[x-1u as uint]).y}, None => {fail!("Bad texture")} },
                        z: match from_str::<uint>(v2[1]) { Some(x) => {(tex_coords[x-1u as uint]).y}, None => {fail!("Bad texture")} }
                    };
                }

                triangles.push(box Triangle {
                    v0: match from_str::<uint>(v0[0]) { Some(x) => {(vertices[x-1u as uint])}, None => {fail!("Bad vertex")} },
                    v1: match from_str::<uint>(v1[0]) { Some(x) => {(vertices[x-1u as uint])}, None => {fail!("Bad vertex")} },
                    v2: match from_str::<uint>(v2[0]) { Some(x) => {(vertices[x-1u as uint])}, None => {fail!("Bad vertex")} },

                    n0: match from_str::<uint>(v0[2]) { Some(x) => {(normals[x-1u as uint])}, None => {fail!("Bad normal")} },
                    n1: match from_str::<uint>(v1[2]) { Some(x) => {(normals[x-1u as uint])}, None => {fail!("Bad normal")} },
                    n2: match from_str::<uint>(v2[2]) { Some(x) => {(normals[x-1u as uint])}, None => {fail!("Bad normal")} },

                    u: u,
                    v: v,
                    material: box material.clone()
                });
            },
            _ => {}
        }

        current_line += 1;
        processed_bytes += line.as_bytes().len();
        if current_line % print_progress_every == 0 {
            ::util::print_progress("Bytes", start_time, processed_bytes, total_bytes as uint);
        }
    }

    // Cheat the progress meter
    ::util::print_progress("Bytes", start_time, total_bytes as uint, total_bytes as uint);

    Mesh {
        position: position,
        scale: scale,
        triangles: triangles
    }
}
<commit_msg>Clean up OBJ import code.<commit_after>use std::io::{BufferedReader, File};
use material::materials::CookTorranceMaterial;
use geometry::{Mesh, Prim};
use geometry::prims::Triangle;
use vec3::Vec3;

/// This is limited to only CookTorranceMaterials, as I couldn't get a Box<Material> to clone
/// a new material for each triangle primitive in the object model.
#[allow(dead_code)]
pub fn from_obj(position: Vec3, scale: f64, material: CookTorranceMaterial /*Box<Material>*/, flip_normals: bool, filename: &str) -> Mesh {
    let path = Path::new(filename);
    let mut file = BufferedReader::new(File::open(&path));

    let mut vertices:   Vec<Vec3> = Vec::new();
    let mut tex_coords: Vec<Vec3> = Vec::new();
    let mut normals:    Vec<Vec3> = Vec::new();
    let mut triangles:  Vec<Box<Prim+Send+Share>> = Vec::new();

    let start_time = ::time::get_time();
    let print_progress_every = 1024u;
    let mut current_line = 0;
    let mut processed_bytes = 0;
    let total_bytes = match path.stat() {
        Ok(stat) => stat.size,
        Err(e) => fail!(e)
    };

    for line_iter in file.lines() {
        let line: String = match line_iter {
            Ok(x) => x,
            Err(e) => fail!(e)
        };

        let tokens: Vec<&str> = line.as_slice().words().collect();
        if tokens.len() < 4 { continue }

        match tokens[0].as_slice() {
            "v" => {
                vertices.push(Vec3 {
                    x: parse_coord_str(tokens[1].as_slice(), scale, line.as_slice()),
                    y: parse_coord_str(tokens[2].as_slice(), scale, line.as_slice()),
                    z: parse_coord_str(tokens[3].as_slice(), scale, line.as_slice()),
                });
            },
            "vt" => {
                tex_coords.push(Vec3 {
                    x: parse_coord_str(tokens[1].as_slice(), scale, line.as_slice()),
                    y: parse_coord_str(tokens[2].as_slice(), scale, line.as_slice()),
                    z: 0.0
                });
            },
            "vn" => {
                let normals_flip_scale = if flip_normals { -1.0 } else { 1.0 } * scale;
                normals.push(Vec3 {
                    x: parse_coord_str(tokens[1].as_slice(), scale * normals_flip_scale, line.as_slice()),
                    y: parse_coord_str(tokens[2].as_slice(), scale * normals_flip_scale, line.as_slice()),
                    z: parse_coord_str(tokens[3].as_slice(), scale * normals_flip_scale, line.as_slice()),
                });
            },
            "f" => {
                // let pairs: Vec<&str> = tokens.tail().iter().map( |token| {
                //     token.to_string().as_slice().split('/').collect()
                // }).collect();

                let v0: Vec<&str> = tokens[1].split('/').collect();
                let v1: Vec<&str> = tokens[2].split('/').collect();
                let v2: Vec<&str> = tokens[3].split('/').collect();

                // If no texture coordinates were supplied, default to zero.
                let mut u = Vec3::zero();
                let mut v = Vec3::zero();

                if v0[1].len() > 0 {
                    u = Vec3 {
                        x: get_tex_coord(v0[1], &tex_coords),
                        y: get_tex_coord(v1[1], &tex_coords),
                        z: get_tex_coord(v2[1], &tex_coords)
                    };

                    v = Vec3 {
                        x: get_tex_coord(v0[2], &tex_coords),
                        y: get_tex_coord(v1[2], &tex_coords),
                        z: get_tex_coord(v2[2], &tex_coords)
                    };
                }

                triangles.push(box Triangle {
                    v0: get_string_index(v0[0], &vertices),
                    v1: get_string_index(v1[0], &vertices),
                    v2: get_string_index(v2[0], &vertices),

                    n0: get_string_index(v0[2], &normals),
                    n1: get_string_index(v1[2], &normals),
                    n2: get_string_index(v2[2], &normals),

                    u: u,
                    v: v,
                    material: box material.clone()
                });
            },
            _ => {}
        }

        current_line += 1;
        processed_bytes += line.as_bytes().len();
        if current_line % print_progress_every == 0 {
            ::util::print_progress("Bytes", start_time, processed_bytes, total_bytes as uint);
        }
    }

    // Cheat the progress meter
    ::util::print_progress("Bytes", start_time, total_bytes as uint, total_bytes as uint);

    Mesh {
        position: position,
        scale: scale,
        triangles: triangles
    }
}

fn parse_coord_str(coord: &str, scale: f64, line: &str) -> f64 {
    match from_str::<f64>(coord.as_slice()) {
        Some(f) => f * scale,
        None => fail!(format!("Bad vertex or texture coordinate in file. `{}`", line))
    }
}

fn get_tex_coord(i: &str, tex_coords: &Vec<Vec3>) -> f64 {
    match from_str::<uint>(i) {
        Some(x) => (tex_coords[x-1u as uint]).x,
        None => fail!("Bad texture")
    }
}

fn get_string_index(i: &str, vec: &Vec<Vec3>) -> Vec3 {
    match from_str::<uint>(i) {
        Some(x) => vec[x-1u as uint],
        None => fail!("Bad index")
    }
}
<|endoftext|>


<commit_before>extern crate gcc;

fn main() {
  gcc::Config::new()
    .compiler("gcc-4.9")
    .opt_level(3)
    .pic(true)
    //.flag("-march=native")
    .flag("--std=gnu99")
    .file("extkernels/activate.c")
    .file("extkernels/batchnorm.c")
    .file("extkernels/conv.c")
    .file("extkernels/image.c")
    .file("extkernels/interpolate.c")
    .file("extkernels/pool.c")
    .compile("libneuralops_extkernels.a");

  //println!("cargo:rustc-flags=-L /usr/local/cuda/lib64");
  println!("cargo:rustc-link-search=native={}", "/opt/intel/mkl/lib/intel64");
}
<commit_msg>Remove the top-level build script, now unused.<commit_after><|endoftext|>


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

#![feature(io)]

use std::old_io::process::{Command, ProcessExit, StdioContainer};
use std::os;

fn main() {
    let out_dir = os::getenv("OUT_DIR").unwrap();
    let result = Command::new("make")
        .args(&["-f", "makefile.cargo"])
        .stdout(StdioContainer::InheritFd(1))
        .stderr(StdioContainer::InheritFd(2))
        .status()
        .unwrap();
    assert_eq!(result, ProcessExit::ExitStatus(0));
    println!("cargo:rustc-flags=-L native={}", out_dir);
}

<commit_msg>Update to modern Rust.<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::process::{Command, Stdio};
use std::env;

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let jobs = format!("-j{}", env::var("NUM_JOBS").unwrap());
    let result = Command::new("make")
        .args(&["-f", "makefile.cargo", &jobs])
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .status()
        .unwrap();
    assert!(result.success());
    println!("cargo:rustc-flags=-L native={}", out_dir);
}
<|endoftext|>


<commit_before>use std::env;
use std::fs;
use std::path;

extern crate genecs;
extern crate copy_dir;

fn main() {
    genecs::generate_ecs("ecs.toml", format!("src{}ecs{}generated.rs", path::MAIN_SEPARATOR, path::MAIN_SEPARATOR));
    copy_resources("resources");
}

fn target_dir_name() -> Result<String, env::VarError> {
    let target = env::var("TARGET")?;
    let host = env::var("HOST")?;
    let profile = env::var("PROFILE")?;

    if target == host {
        Ok(format!("target{}{}", path::MAIN_SEPARATOR, profile).to_string())
    } else {
        Ok(format!("target{}{}{}{}", path::MAIN_SEPARATOR, target, path::MAIN_SEPARATOR, profile).to_string())
    }
}

fn copy_resources(resources_dir_name: &str) {
    let target_dir_name = target_dir_name().expect("Failed to locate target directory");
    let dest_name = format!("{}{}{}", target_dir_name, path::MAIN_SEPARATOR, resources_dir_name);
    let dest_path = path::PathBuf::from(dest_name);
    if dest_path.is_dir() {
        fs::remove_dir_all(&dest_path).expect("Failed to remove old resources directory");
    }
    if dest_path.is_file() {
        fs::remove_file(&dest_path).expect("Failed to remove file in place of resources directory");
    }
    copy_dir::copy_dir(resources_dir_name, &dest_path).expect("Failed to copy resources");
}
<commit_msg>Fixed build script for target == host<commit_after>use std::env;
use std::fs;
use std::path;

extern crate genecs;
extern crate copy_dir;

fn main() {
    genecs::generate_ecs("ecs.toml", format!("src{}ecs{}generated.rs", path::MAIN_SEPARATOR, path::MAIN_SEPARATOR));
    copy_resources("resources");
}

fn target_dir_names() -> Result<Vec<String>, env::VarError> {
    let target = env::var("TARGET")?;
    let host = env::var("HOST")?;
    let profile = env::var("PROFILE")?;

    if target == host {
        Ok(vec![
            format!("target{}{}", path::MAIN_SEPARATOR, profile).to_string(),
            format!("target{}{}{}{}", path::MAIN_SEPARATOR, target, path::MAIN_SEPARATOR, profile).to_string(),
        ])
    } else {
        Ok(vec![format!("target{}{}{}{}", path::MAIN_SEPARATOR, target, path::MAIN_SEPARATOR, profile).to_string()])
    }
}

fn copy_resources(resources_dir_name: &str) {
    let target_dir_names = target_dir_names().expect("Failed to locate target directory");

    for target_dir_name in target_dir_names {

        if !path::PathBuf::from(&target_dir_name).is_dir() {
            continue;
        }

        let dest_name = format!("{}{}{}", target_dir_name, path::MAIN_SEPARATOR, resources_dir_name);
        let dest_path = path::PathBuf::from(dest_name);
        if dest_path.is_dir() {
            fs::remove_dir_all(&dest_path).expect("Failed to remove old resources directory");
        }
        if dest_path.is_file() {
            fs::remove_file(&dest_path).expect("Failed to remove file in place of resources directory");
        }
        copy_dir::copy_dir(resources_dir_name, &dest_path).expect("Failed to copy resources");
    }
}
<|endoftext|>


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

#![feature(io)]

use std::old_io::process::{Command, ProcessExit, StdioContainer};

fn main() {
    let result = Command::new("make")
        .args(&["-f", "makefile.cargo"])
        .stdout(StdioContainer::InheritFd(1))
        .stderr(StdioContainer::InheritFd(2))
        .status()
        .unwrap();
    assert_eq!(result, ProcessExit::ExitStatus(0));
}
<commit_msg>Add link flags.<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/. */

#![feature(io)]

use std::old_io::process::{Command, ProcessExit, StdioContainer};
use std::os;

fn main() {
    let out_dir = os::getenv("OUT_DIR").unwrap();
    let result = Command::new("make")
        .args(&["-f", "makefile.cargo"])
        .stdout(StdioContainer::InheritFd(1))
        .stderr(StdioContainer::InheritFd(2))
        .status()
        .unwrap();
    assert_eq!(result, ProcessExit::ExitStatus(0));
    println!("cargo:rustc-flags=-L native={}", out_dir);
}
<|endoftext|>


<commit_before>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

use std::fmt::Debug;

/// Quicksort
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
// pub fn sort<T: PartialOrd>(array: &mut Vec<T>) {
pub fn sort<T: PartialOrd + Debug>(array: &mut [T]) {
    let n = array.len();

    println!("");
    println!("  array: {:?}", array);

    if n <= 1 {
        return;
    } else if n == 2 {
        if array.first() <= array.last() {
            return;
        } else {
            array.swap(0, 1);
            // (array[0], array[1]) = (array[1], array[0]);
            return;
        }
    } else {
        // Pick a pivot: Pick the middle element by skipping half the length and keeping just one.
        // let it_pivot = array.iter().skip(n / 2).take(1);
        // Take the first element as the pivot.
        // let it_pivot = array.iter().take(1);
        //
        // for it in it_pivot {
        //     println!("  0. it: {:?}", it);
        // }

        // Loop over array, finding smaller elements than the pivot.
        // for it in array.iter().skip(1) {
        //     //println!("  1. it: {:?}", it);
        //     if it < it_pivot {
        //         println!("  1. it: {:?} smaller than pivot!", it);
        //     }
        // }
        // array.swap(0,1);

        // array.iter().enumerate().map(|(i,x)| {});

        // // Take the first element as pivot.
        // let a = array.iter_mut().skip(1).enumerate().fold(
        //     (0, array[0]), |acc, item| {
        //         if acc.1 > item.1 {
        //             // Element is smaller than pivot; swap them!
        //             array.swap(acc.0, item.0);
        //             // Return the accumulator as being the new index of pivot (which is now at
        //             // at the location of the fold()) with the pivot value which shouldn't change.
        //             (item.0, acc.1)
        //         } else {
        //             // Nothing to do as element is larger than pivot. Just return new accumulator.
        //             (acc.0, acc.1)
        //         }
        //     }
        // );

        let mut pivot = 0;
        for i in 1..n {
            println!("---------------");
            println!("  array[pivot={:?}]: {:?}    array[i={:?}]: {:?}", pivot, array[pivot], i, array[i]);
            if array[pivot] > array[i] {
                println!("    Swapping array[pivot={:?}]: {:?} with array[i={:?}]: {:?}", pivot, array[pivot], i, array[i]);
                array.swap(pivot, i);
                println!("  array: {:?}", array);
                if i == pivot+1 {
                    pivot = i;
                    println!("      pivot is now at {:?}", pivot);
                } else {
                    println!("      swapping i={:?} and pivot+1={:?}", i, pivot+1);
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                    println!("        pivot is now at {:?}", pivot);
                }
            }
            println!("  array: {:?}", array);
        }
        println!("array: {:?}", array);
        println!("array[pivot={:?}] = {:?}", pivot, array[pivot]);

        unimplemented!();
    }
}
<commit_msg>Quicksort works! Uses recursion.<commit_after>//! Quicksort algorithm.
//!
//! The `efficient` module contains the efficient sorting algorithm "Quicksort".
//!
//! Source: https://en.wikipedia.org/wiki/Quicksort

use std::fmt::Debug;

/// Quicksort
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
/// None
///
/// # Notes
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::efficientsorts::quick::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
// pub fn sort<T: PartialOrd>(array: &mut Vec<T>) {
pub fn sort<T: PartialOrd + Debug>(array: &mut [T]) {
    println!("");
    println!("##########################################################################");
    let n = array.len();

    println!("  array: {:?}", array);

    if n <= 1 {
        // Don't do anything
    } else if n == 2 {
        if array.first() > array.last() {
            array.swap(0, 1);
        }
    } else {
        // Pick a pivot: Pick the middle element by skipping half the length and keeping just one.
        // let it_pivot = array.iter().skip(n / 2).take(1);
        // Take the first element as the pivot.
        // let it_pivot = array.iter().take(1);
        //
        // for it in it_pivot {
        //     println!("  0. it: {:?}", it);
        // }

        // Loop over array, finding smaller elements than the pivot.
        // for it in array.iter().skip(1) {
        //     //println!("  1. it: {:?}", it);
        //     if it < it_pivot {
        //         println!("  1. it: {:?} smaller than pivot!", it);
        //     }
        // }
        // array.swap(0,1);

        // array.iter().enumerate().map(|(i,x)| {});

        // // Take the first element as pivot.
        // let a = array.iter_mut().skip(1).enumerate().fold(
        //     (0, array[0]), |acc, item| {
        //         if acc.1 > item.1 {
        //             // Element is smaller than pivot; swap them!
        //             array.swap(acc.0, item.0);
        //             // Return the accumulator as being the new index of pivot (which is now at
        //             // at the location of the fold()) with the pivot value which shouldn't change.
        //             (item.0, acc.1)
        //         } else {
        //             // Nothing to do as element is larger than pivot. Just return new accumulator.
        //             (acc.0, acc.1)
        //         }
        //     }
        // );

        let mut pivot = 0;
        for i in 1..n {
            println!("---------------");
            println!("  array[pivot={:?}]: {:?}    array[i={:?}]: {:?}", pivot, array[pivot], i, array[i]);
            if array[pivot] > array[i] {
                println!("    Swapping array[pivot={:?}]: {:?} with array[i={:?}]: {:?}", pivot, array[pivot], i, array[i]);

                array.swap(pivot, i);
                println!("  array: {:?}", array);
                if i == pivot+1 {
                    pivot = i;
                    println!("      pivot is now at {:?}", pivot);
                } else {
                    println!("      swapping i={:?} and pivot+1={:?}", i, pivot+1);
                    array.swap(i, pivot+1);
                    pivot = pivot+1;
                    println!("        pivot is now at {:?}", pivot);
                }
            }
            println!("  array: {:?}", array);
        }
        println!("array: {:?}", array);
        println!("array[pivot={:?}] = {:?}", pivot, array[pivot]);

        sort(&mut array[0..pivot+1]);
        sort(&mut array[pivot+1..n]);
    }

    println!("FINAL array: {:?}", array);
}
<|endoftext|>


<commit_before>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](/diesel/expression/trait.Expression.html) or
//! [`AsExpression`](/diesel/expression/trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html). You can also call
//! numeric operators on types which have been passed to
//! [`operator_allowed!`](../macro.operator_allowed.html) or
//! [`numeric_expr!`](../macro.numeric_expr.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod coerce;
#[doc(hidden)]
pub mod count;
#[doc(hidden)]
pub mod exists;
#[doc(hidden)]
#[macro_use]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
#[macro_use]
pub mod helper_types;
#[doc(hidden)]
pub mod nullable;
#[doc(hidden)]
#[macro_use]
pub mod predicates;
pub mod sql_literal;
mod unchecked_bind;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)] pub use super::count::{count, count_star};
    #[doc(inline)] pub use super::functions::date_and_time::*;
    #[doc(inline)] pub use super::functions::aggregate_ordering::*;
    #[doc(inline)] pub use super::functions::aggregate_folding::*;
    #[doc(inline)] pub use super::sql_literal::sql;
    #[doc(inline)] pub use super::exists::exists;

    #[cfg(feature = "postgres")]
    pub use pg::expression::dsl::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use backend::Backend;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType;
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/type.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that all elements of an expression are valid given a from clause.
/// This is used to ensure that `users.filter(posts::id.eq(1))` fails to
/// compile. This constraint is only used in places where the nullability of a
/// SQL type doesn't matter (everything except `select` and `returning`). For
/// places where nullability is important, `SelectableExpression` is used
/// instead.
pub trait AppearsOnTable<QS: ?Sized>: Expression {
}

impl<T: ?Sized, QS> AppearsOnTable<QS> for Box<T> where
    T: AppearsOnTable<QS>,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, QS> AppearsOnTable<QS> for &'a T where
    T: AppearsOnTable<QS>,
    &'a T: Expression,
{
}

/// Indicates that an expression can be selected from a source. Columns will
/// implement this for their table. Certain special types, like `CountStar` and
/// `Bound` will implement this for all sources. Most compound expressions will
/// implement this if each of their parts implement it.
///
/// Notably, columns will not implement this trait for the right side of a left
/// join. To select a column or expression using a column from the right side of
/// a left join, you must call `.nullable()` on it.
pub trait SelectableExpression<QS: ?Sized>: AppearsOnTable<QS> {
}

impl<T: ?Sized, QS> SelectableExpression<QS> for Box<T> where
    T: SelectableExpression<QS>,
    Box<T>: AppearsOnTable<QS>,
{
}

impl<'a, T: ?Sized, QS> SelectableExpression<QS> for &'a T where
    T: SelectableExpression<QS>,
    &'a T: AppearsOnTable<QS>,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

use query_builder::{QueryFragment, QueryId};

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
pub trait BoxableExpression<QS, DB> where
    DB: Backend,
    Self: Expression,
    Self: SelectableExpression<QS>,
    Self: NonAggregate,
    Self: QueryFragment<DB>,
{}

impl<QS, T, DB> BoxableExpression<QS, DB> for T where
    DB: Backend,
    T: Expression,
    T: SelectableExpression<QS>,
    T: NonAggregate,
    T: QueryFragment<DB>,
{
}

impl<QS, ST, DB> QueryId for BoxableExpression<QS, DB, SqlType=ST> {
    type QueryId = ();

    fn has_static_query_id() -> bool {
        false
    }
}
<commit_msg>Add an example/doctest for BoxableExpression<commit_after>//! AST types representing various typed SQL expressions. Almost all types
//! implement either [`Expression`](/diesel/expression/trait.Expression.html) or
//! [`AsExpression`](/diesel/expression/trait.AsExpression.html).
//!
//! The most common expression to work with is a
//! [`Column`](../query_source/trait.Column.html). There are various methods
//! that you can call on these, found in
//! [`expression_methods`](expression_methods/index.html). You can also call
//! numeric operators on types which have been passed to
//! [`operator_allowed!`](../macro.operator_allowed.html) or
//! [`numeric_expr!`](../macro.numeric_expr.html).
//!
//! Any primitive which implements [`ToSql`](../types/trait.ToSql.html) will
//! also implement [`AsExpression`](trait.AsExpression.html), allowing it to be
//! used as an argument to any of the methods described here.
#[macro_use]
#[doc(hidden)]
pub mod ops;

#[doc(hidden)]
pub mod array_comparison;
#[doc(hidden)]
pub mod bound;
#[doc(hidden)]
pub mod coerce;
#[doc(hidden)]
pub mod count;
#[doc(hidden)]
pub mod exists;
#[doc(hidden)]
#[macro_use]
pub mod functions;
#[doc(hidden)]
pub mod grouped;
#[macro_use]
pub mod helper_types;
#[doc(hidden)]
pub mod nullable;
#[doc(hidden)]
#[macro_use]
pub mod predicates;
pub mod sql_literal;
mod unchecked_bind;

/// Reexports various top level functions and core extensions that are too
/// generic to export by default. This module exists to conveniently glob import
/// in functions where you need them.
pub mod dsl {
    #[doc(inline)] pub use super::count::{count, count_star};
    #[doc(inline)] pub use super::functions::date_and_time::*;
    #[doc(inline)] pub use super::functions::aggregate_ordering::*;
    #[doc(inline)] pub use super::functions::aggregate_folding::*;
    #[doc(inline)] pub use super::sql_literal::sql;
    #[doc(inline)] pub use super::exists::exists;

    #[cfg(feature = "postgres")]
    pub use pg::expression::dsl::*;
}

pub use self::dsl::*;
pub use self::sql_literal::SqlLiteral;

use backend::Backend;

/// Represents a typed fragment of SQL. Apps should not need to implement this
/// type directly, but it may be common to use this as type boundaries.
/// Libraries should consider using
/// [`infix_predicate!`](../macro.infix_predicate.html) or
/// [`postfix_predicate!`](../macro.postfix_predicate.html) instead of
/// implementing this directly.
pub trait Expression {
    type SqlType;
}

impl<T: Expression + ?Sized> Expression for Box<T> {
    type SqlType = T::SqlType;
}

impl<'a, T: Expression + ?Sized> Expression for &'a T {
    type SqlType = T::SqlType;
}

/// Describes how a type can be represented as an expression for a given type.
/// These types couldn't just implement [`Expression`](trait.Expression.html)
/// directly, as many things can be used as an expression of multiple types.
/// (`String` for example, can be used as either
/// [`VarChar`](../types/type.VarChar.html) or
/// [`Text`](../types/struct.Text.html)).
///
/// This trait allows us to use primitives on the right hand side of various
/// expressions. For example `name.eq("Sean")`
pub trait AsExpression<T> {
    type Expression: Expression<SqlType=T>;

    fn as_expression(self) -> Self::Expression;
}

impl<T: Expression> AsExpression<T::SqlType> for T {
    type Expression = Self;

    fn as_expression(self) -> Self {
        self
    }
}

/// Indicates that all elements of an expression are valid given a from clause.
/// This is used to ensure that `users.filter(posts::id.eq(1))` fails to
/// compile. This constraint is only used in places where the nullability of a
/// SQL type doesn't matter (everything except `select` and `returning`). For
/// places where nullability is important, `SelectableExpression` is used
/// instead.
pub trait AppearsOnTable<QS: ?Sized>: Expression {
}

impl<T: ?Sized, QS> AppearsOnTable<QS> for Box<T> where
    T: AppearsOnTable<QS>,
    Box<T>: Expression,
{
}

impl<'a, T: ?Sized, QS> AppearsOnTable<QS> for &'a T where
    T: AppearsOnTable<QS>,
    &'a T: Expression,
{
}

/// Indicates that an expression can be selected from a source. Columns will
/// implement this for their table. Certain special types, like `CountStar` and
/// `Bound` will implement this for all sources. Most compound expressions will
/// implement this if each of their parts implement it.
///
/// Notably, columns will not implement this trait for the right side of a left
/// join. To select a column or expression using a column from the right side of
/// a left join, you must call `.nullable()` on it.
pub trait SelectableExpression<QS: ?Sized>: AppearsOnTable<QS> {
}

impl<T: ?Sized, QS> SelectableExpression<QS> for Box<T> where
    T: SelectableExpression<QS>,
    Box<T>: AppearsOnTable<QS>,
{
}

impl<'a, T: ?Sized, QS> SelectableExpression<QS> for &'a T where
    T: SelectableExpression<QS>,
    &'a T: AppearsOnTable<QS>,
{
}

/// Marker trait to indicate that an expression does not include any aggregate
/// functions. Used to ensure that aggregate expressions aren't mixed with
/// non-aggregate expressions in a select clause, and that they're never
/// included in a where clause.
pub trait NonAggregate {
}

impl<T: NonAggregate + ?Sized> NonAggregate for Box<T> {
}

impl<'a, T: NonAggregate + ?Sized> NonAggregate for &'a T {
}

use query_builder::{QueryFragment, QueryId};

/// Helper trait used when boxing expressions. This exists to work around the
/// fact that Rust will not let us use non-core types as bounds on a trait
/// object (you could not return `Box<Expression+NonAggregate>`)
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel_codegen;
/// # #[macro_use] extern crate diesel;
/// # use diesel::types;
/// # include!("src/doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #     }
/// # }
///
/// # #[derive(PartialEq, Eq, Debug)]
/// #[derive(Queryable)]
/// struct User {
///     id: i32,
///     name: String,
/// }
///
/// fn main() {
///     let conn = establish_connection();
///     let where_clause: Box<BoxableExpression<users::table, _, SqlType=types::Bool>>;
///     let search_by_id = true;
///
///     if search_by_id {
///         where_clause = Box::new(users::id.eq(1))
///     } else {
///         where_clause = Box::new(users::name.eq("Tess".to_string()))
///     }
///
///     // BoxableExpression can be chained
///     let where_clause = where_clause.and(Box::new(users::id.ne(10)));
///
///     let result = users::table.filter(where_clause).load::<User>(&conn);
///     assert_eq!(result, Ok(vec![User { id: 1, name: "Sean".into() }]));
/// }
/// ```
pub trait BoxableExpression<QS, DB> where
    DB: Backend,
    Self: Expression,
    Self: SelectableExpression<QS>,
    Self: NonAggregate,
    Self: QueryFragment<DB>,
{}

impl<QS, T, DB> BoxableExpression<QS, DB> for T where
    DB: Backend,
    T: Expression,
    T: SelectableExpression<QS>,
    T: NonAggregate,
    T: QueryFragment<DB>,
{
}

impl<QS, ST, DB> QueryId for BoxableExpression<QS, DB, SqlType=ST> {
    type QueryId = ();

    fn has_static_query_id() -> bool {
        false
    }
}
<|endoftext|>