<commit_before>//! This build script detects target platforms that lack proper support for
//! atomics and sets `cfg` flags accordingly.

use std::env;
use std::str;

fn main() {
    let target = match rustc_target() {
        Some(target) => target,
        None => return,
    };

    if target_has_atomic_cas(&target) {
        println!("cargo:rustc-cfg=atomic_cas");
    }

    if target_has_atomics(&target) {
        println!("cargo:rustc-cfg=has_atomics");
    }

    println!("cargo:rerun-if-changed=build.rs");
}

fn target_has_atomic_cas(target: &str) -> bool {
    match &target[..] {
        "thumbv6m-none-eabi"
        | "msp430-none-elf"
        | "riscv32i-unknown-none-elf"
        | "riscv32imc-unknown-none-elf" => false,
        _ => true,
    }
}

fn target_has_atomics(target: &str) -> bool {
    match &target[..] {
        "msp430-none-elf" | "riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => false,
        _ => true,
    }
}

fn rustc_target() -> Option<String> {
    env::var("TARGET").ok()
}
<commit_msg>#487 Add thumbv4t-none-eabi to the list of targets that don't support atomics.<commit_after>//! This build script detects target platforms that lack proper support for
//! atomics and sets `cfg` flags accordingly.

use std::env;
use std::str;

fn main() {
    let target = match rustc_target() {
        Some(target) => target,
        None => return,
    };

    if target_has_atomic_cas(&target) {
        println!("cargo:rustc-cfg=atomic_cas");
    }

    if target_has_atomics(&target) {
        println!("cargo:rustc-cfg=has_atomics");
    }

    println!("cargo:rerun-if-changed=build.rs");
}

fn target_has_atomic_cas(target: &str) -> bool {
    match &target[..] {
        "thumbv6m-none-eabi"
        | "msp430-none-elf"
        | "riscv32i-unknown-none-elf"
        | "riscv32imc-unknown-none-elf" => false,
        _ => true,
    }
}

fn target_has_atomics(target: &str) -> bool {
    match &target[..] {
        "thumbv4t-none-eabi" | "msp430-none-elf" | "riscv32i-unknown-none-elf" | "riscv32imc-unknown-none-elf" => false,
        _ => true,
    }
}

fn rustc_target() -> Option<String> {
    env::var("TARGET").ok()
}
<|endoftext|>


<commit_before>use std::io::Command;
use std::os;

#[allow(unused_must_use)]
fn main() {
    let mut build = os::getcwd().unwrap();
    build.push_many(&["ext", "libqmlrswrapper", "build"]);

    /* Ignore error, the return value is not reliable and we'll catch it when chdir'ing anyway. */
    std::io::fs::mkdir(&build, std::io::USER_RWX);

    os::change_dir(&build).ok().expect("Failed to change into build directory");

    let out = Command::new("cmake").arg("..").output();
    if out.unwrap().status != std::io::process::ProcessExit::ExitStatus(0) {
        panic!("Build failed");
    }

    println!("cargo:rustc-flags=-L ext/libqmlrswrapper/build -l qmlrswrapper -l Qt5Core -l Qt5Quick -l Qt5Gui -l Qt5Qml -l stdc++");
}
<commit_msg>Actually compile the C++ code<commit_after>use std::io::Command;
use std::os;

#[allow(unused_must_use)]
fn main() {
    let mut build = os::getcwd().unwrap();
    build.push_many(&["ext", "libqmlrswrapper", "build"]);

    /* Ignore error, the return value is not reliable and we'll catch it when chdir'ing anyway. */
    std::io::fs::mkdir(&build, std::io::USER_RWX);

    os::change_dir(&build).ok().expect("Failed to change into build directory");

    let out = Command::new("cmake").arg("..").output();
    if out.unwrap().status != std::io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run cmake");
    }

    let out = Command::new("make").output();
    if out.unwrap().status != std::io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run make");
    }

    println!("cargo:rustc-flags=-L ext/libqmlrswrapper/build -l qmlrswrapper -l Qt5Core -l Qt5Quick -l Qt5Gui -l Qt5Qml -l stdc++");
}
<|endoftext|>


<commit_before>extern crate pkg_config;

fn main() {
    pkg_config::find_library("sqlite3").unwrap();
}
<commit_msg>Remove unused build.rs.<commit_after><|endoftext|>


<commit_before>use std::env;

fn main() {
  let java_home = env::var("JAVA_HOME").unwrap();

  println!("cargo:rustc-link-search=native={}/jre/lib/server", java_home);
}<commit_msg>Build file isn't used right now<commit_after><|endoftext|>


<commit_before>use std::env;
use std::fs;
use std::io::prelude::*;
use std::io::Write;
use std::path::Path;
use std::collections::HashMap;
use std::cell::RefCell;

struct WordData
{
    name: String,
    count: Option<usize>,
    data: RefCell<Vec<String>>,
}

fn parse_data(data: String) -> Vec<String> {
    let mut word_list : Vec<String> = Vec::new();

    for line in data.lines() {
        let mut l = line.split_whitespace();
        let size = line.split_whitespace().count();
        match size  {
            1 | 2=> {
                match l.next() {
                    Some(frqs) => word_list.push(frqs.to_string()),
                    None => continue,
                };
            },
            _ => continue,
        }
    }
    word_list
}

fn is_rare_and_short(word: &String, rank: u32) -> bool {
    let result = if word.len() < 8 {
        rank >=10u32.pow(word.len() as u32)
    } else {
        false
    };
    result
}

fn filter_data(dicts: &mut Vec<WordData>) {
    let mut best_match : HashMap<String, (usize, String)> = HashMap::new();
    // Build best matches. Shows precedence of words in different dictionaries
    for datum in dicts.iter() {
        if datum.count.is_some() {
            let words = datum.data.borrow();
            for (rank, word) in words.iter().enumerate() {
                if best_match.contains_key(word) {
                    if rank < best_match.get(word).unwrap().0 {
                        best_match.insert(word.clone(),
                                          (rank, datum.name.clone()));
                    }
                } else {
                    best_match.insert(word.clone(),
                                      (rank, datum.name.clone()));
                }
            }
        }
    }

    for datum in dicts {
        if datum.count.is_some() {

            let conditional = |w: &String| {
                best_match.get(w).unwrap().1 == datum.name &&
                    !is_rare_and_short(w, best_match.get(w).unwrap().0 as u32)
            };

            let mut words = datum.data.borrow_mut();
            words.retain(conditional);
            /*for word in words.iter_mut() {
                if best_match.get(word).unwrap().1 != datum.name {

                }
            }*/
        }
    }
}

// Choose word limits for each file...
fn main() {
    // Data files are either lists or frequency tables. Load all files in data
    // and then identify and parse accordingly and generate code
    println!("Generating source from /data/");
    let limits : HashMap<&str, usize> = {
        let mut map = HashMap::new();
        map.insert("us_tv_and_film", 30000);
        map.insert("english_wikipedia", 30000);
        map.insert("passwords", 30000);
        map.insert("surnames", 10000);
        map
    };

    let mut exported_data : Vec<WordData> = Vec::new();

    for entry in fs::read_dir("./data").unwrap() {
        let dir = match entry {
            Ok(dir) => dir,
            Err(_) => continue,
        };
        let path = dir.path();
        let file_name = path.file_stem();
        let mut file = match fs::File::open(dir.path()) {
            Ok(file) => file,
            Err(_) => continue,
        };
        let mut s = String::new();

        match file.read_to_string(&mut s) {
            Err(_) => continue,
            Ok(_) => {
                let name = match file_name.unwrap().to_str() {
                    Some(fname) => fname,
                    None => continue,
                };
                let count = match limits.get(name) {
                    Some(t) => Some(*t),
                    None => None,
                };
                let temp = WordData{ name: name.to_string(), count: count,
                                          data: RefCell::new(parse_data(s)),
                };
                exported_data.push(temp);
            },
        }
    }
    println!("Filtering data");
    filter_data(&mut exported_data);
    println!("Applying size limits");
    // Apply limits
    for lists in exported_data.iter_mut() {
        println!("Looking for limits for {}", lists.name);
        if let Some(limit) = limits.get(lists.name.as_str()) {
            println!("Limit is {}", limit);
            lists.data.borrow_mut().truncate(limit.clone());
        }
    }
    println!("Exporting data");
    let mut source : String = String::new();

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("global_data.rs");
    let mut f = fs::File::create(&dest_path).unwrap();

    for lists in exported_data.iter() {
        let mut line = format!("static {}: &'static [String] = &[ \n",
                               lists.name);

        let data = lists.data.borrow();

        for word in data.iter() {
            let entry = format!("\t\"{}\",\n", word);
            line.push_str(entry.as_str());
        }
        line.push_str("];\n\n");
        source.push_str(line.as_str());
    }

    f.write_all(source.as_bytes()).unwrap();
    panic!("Test");
}
<commit_msg>Added initial version of keyboard adjacency graphs. Currently only slanted so no keypads supported. Function also a bit beastly so looking to refactor and split it out at some point<commit_after>use std::env;
use std::fs;
use std::io::prelude::*;
use std::io::Write;
use std::path::Path;
use std::collections::HashMap;
use std::cell::RefCell;

enum KeyAlignment {
    Slanted,
    Aligned,
}

struct WordData {
    name: String,
    count: Option<usize>,
    data: RefCell<Vec<String>>,
}

fn parse_data(data: String) -> Vec<String> {
    let mut word_list : Vec<String> = Vec::new();

    for line in data.lines() {
        let mut l = line.split_whitespace();
        let size = line.split_whitespace().count();
        match size  {
            1 | 2=> {
                match l.next() {
                    Some(frqs) => word_list.push(frqs.to_string()),
                    None => continue,
                };
            },
            _ => continue,
        }
    }
    word_list
}

fn is_rare_and_short(word: &String, rank: u32) -> bool {
    let result = if word.len() < 8 {
        rank >=10u32.pow(word.len() as u32)
    } else {
        false
    };
    result
}

fn filter_data(dicts: &mut Vec<WordData>) {
    let mut best_match : HashMap<String, (usize, String)> = HashMap::new();
    // Build best matches. Shows precedence of words in different dictionaries
    for datum in dicts.iter() {
        if datum.count.is_some() {
            let words = datum.data.borrow();
            for (rank, word) in words.iter().enumerate() {
                if best_match.contains_key(word) {
                    if rank < best_match.get(word).unwrap().0 {
                        best_match.insert(word.clone(),
                                          (rank, datum.name.clone()));
                    }
                } else {
                    best_match.insert(word.clone(),
                                      (rank, datum.name.clone()));
                }
            }
        }
    }

    for datum in dicts {
        if datum.count.is_some() {

            let conditional = |w: &String| {
                best_match.get(w).unwrap().1 == datum.name &&
                    !is_rare_and_short(w, best_match.get(w).unwrap().0 as u32)
            };

            let mut words = datum.data.borrow_mut();
            words.retain(conditional);
        }
    }
}

/// Use trailing spaces at the start of lines to represent non character keys
/// such as caps tab and shift.
fn generate_adjacencies(keyboard: String,
                        align: KeyAlignment) -> HashMap<String, String> {
    let mut adj_list : HashMap<String, String> = HashMap::new();
    let rows = keyboard.lines()
        .map(|x| x.split(' ').collect::<Vec<&str>>())
        .collect::<Vec<Vec<&str>>>();

    for (i, row) in rows.iter().enumerate() {
        for (j, key) in row.iter().enumerate() {
            if !key.is_empty() {
                let mut value : String = String::new();
                // Values for row above
                if i>0 {
                    let prev = rows.get(i-1).unwrap();
                    let ap = format!("{} ", prev.get(j).unwrap());
                    value.push_str(ap.as_str());
                    if let Some(pchar) = prev.get(j+1) {
                        let ap = format!("{} ", pchar);
                        value.push_str(ap.as_str());
                    }
                }
                // Values for this row
                if j > 0 {
                    let ap = format!("{} ", row.get(j-1).unwrap());
                    value.push_str(ap.as_str());
                }
                if let Some(next) = row.get(j+1) {
                    let ap = format!("{} ", next);
                    value.push_str(ap.as_str());
                }
                // Values for next row
                if let Some(next) = rows.get(i+1) {
                    if let Some(nchar) = next.get(j) {
                        if !nchar.is_empty()
                        {
                            let ap = format!("{} ", nchar);
                            value.push_str(ap.as_str());

                            if let Some(nchar) = next.get(j+1) {
                                let ap = format!("{} ", nchar);
                                value.push_str(ap.as_str());
                            }
                        }
                    }
                }
                adj_list.insert(key.to_string(), value);
            }
        }
    }
    adj_list
}

// Choose word limits for each file...
fn main() {
    // Data files are either lists or frequency tables. Load all files in data
    // and then identify and parse accordingly and generate code
    println!("Generating source from /data/");
    let limits : HashMap<&str, usize> = {
        let mut map = HashMap::new();
        map.insert("us_tv_and_film", 30000);
        map.insert("english_wikipedia", 30000);
        map.insert("passwords", 30000);
        map.insert("surnames", 10000);
        map
    };

    let mut exported_data : Vec<WordData> = Vec::new();

    for entry in fs::read_dir("./data").unwrap() {
        let dir = match entry {
            Ok(dir) => dir,
            Err(_) => continue,
        };
        let path = dir.path();
        let file_name = path.file_stem();
        let mut file = match fs::File::open(dir.path()) {
            Ok(file) => file,
            Err(_) => continue,
        };
        let mut s = String::new();

        match file.read_to_string(&mut s) {
            Err(_) => continue,
            Ok(_) => {
                let name = match file_name.unwrap().to_str() {
                    Some(fname) => fname,
                    None => continue,
                };
                let count = match limits.get(name) {
                    Some(t) => Some(*t),
                    None => None,
                };
                let temp = WordData{ name: name.to_string(), count: count,
                                          data: RefCell::new(parse_data(s)),
                };
                exported_data.push(temp);
            },
        }
    }
    println!("Filtering data");
    filter_data(&mut exported_data);
    println!("Applying size limits");
    // Apply limits
    for lists in exported_data.iter_mut() {
        if let Some(limit) = limits.get(lists.name.as_str()) {
            lists.data.borrow_mut().truncate(limit.clone());
        }
    }
    println!("Exporting data");
    let mut source : String = String::new();

    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("global_data.rs");
    let mut f = fs::File::create(&dest_path).unwrap();

    for lists in exported_data.iter() {
        let mut line = format!("static {}: &'static [String] = &[ \n",
                               lists.name);

        let data = lists.data.borrow();

        for word in data.iter() {
            let entry = format!("\t\"{}\",\n", word);
            line.push_str(entry.as_str());
        }
        line.push_str("];\n\n");
        source.push_str(line.as_str());
    }
    // Trailing space after \n is to represent offset of keyboard. (¬ is hard)
    let qwerty_uk = "¬` 1! 2\" 3£ 4$ %5 6^ 7& 8* 9( 0) -_ =+ \n \
    qQ wW eE rR tT yY uU iI oO pP [{ ]}\n \
    aA sS dD fF gG hH jJ kK lL ;: '@ #~\n \
    \\| zZ xX cC vV bB nN mM ,< /?".to_string();

    generate_adjacencies(qwerty_uk, KeyAlignment::Slanted);
    f.write_all(source.as_bytes()).unwrap();
    panic!("Test");
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]

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

#[macro_use]
extern crate error_chain;

mod errors {
    use std::io;

    error_chain! {
        foreign_links {
            Io(io::Error);
        }
    }
}

use errors::*;

fn run() -> Result<()> {
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

    let status = Command::new("cp")
        .args(&["-r", "static", out_dir.to_str().unwrap()])
        .stderr(Stdio::inherit())
        .status()
        .chain_err(|| "failed to run `cp`")?;
    if !status.success() {
        bail!("failed to copy static files to the target directory");
    }

    let scss_out = out_dir.join("styles.css");
    let status = Command::new("sass")
        .args(&["scss/main.scss", scss_out.to_str().unwrap()])
        .stderr(Stdio::inherit())
        .status()
        .chain_err(|| "failed to run `sass`")?;
    if !status.success() {
        bail!("SCSS compilation failed");
    }

    let css_out = out_dir.join("static/css/");
    fs::create_dir_all(&css_out)?;
    let status = Command::new("postcss")
        .args(&["--use", "autoprefixer"])
        .arg(scss_out.to_str().unwrap())
        .args(&["-d", css_out.to_str().unwrap()])
        .status()
        .chain_err(|| "failed to run `postcss`")?;
    if !status.success() {
        bail!("failed postprocessing CSS");
    }

    Ok(())
}

quick_main!(run);
<commit_msg>feat(build): use sassc instead of sass<commit_after>#![recursion_limit = "1024"]

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

#[macro_use]
extern crate error_chain;

mod errors {
    use std::io;

    error_chain! {
        foreign_links {
            Io(io::Error);
        }
    }
}

use errors::*;

fn run() -> Result<()> {
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());

    let status = Command::new("cp")
        .args(&["-r", "static", out_dir.to_str().unwrap()])
        .stderr(Stdio::inherit())
        .status()
        .chain_err(|| "failed to run `cp`")?;
    if !status.success() {
        bail!("failed to copy static files to the target directory");
    }

    let scss_out = out_dir.join("styles.css");
    let status = Command::new("sassc")
        .args(&["scss/main.scss", scss_out.to_str().unwrap()])
        .stderr(Stdio::inherit())
        .status()
        .chain_err(|| "failed to run `sassc`")?;
    if !status.success() {
        bail!("SCSS compilation failed");
    }

    let css_out = out_dir.join("static/css/");
    fs::create_dir_all(&css_out)?;
    let status = Command::new("postcss")
        .args(&["--use", "autoprefixer"])
        .arg(scss_out.to_str().unwrap())
        .args(&["-d", css_out.to_str().unwrap()])
        .status()
        .chain_err(|| "failed to run `postcss`")?;
    if !status.success() {
        bail!("failed postprocessing CSS");
    }

    Ok(())
}

quick_main!(run);
<|endoftext|>


<commit_before>#![cfg(feature = "full")]
#![warn(rust_2018_idioms)]
#![cfg(unix)]

use std::io;
use std::task::Poll;

use tokio::io::{AsyncReadExt, AsyncWriteExt, Interest};
use tokio::net::{UnixListener, UnixStream};
use tokio_test::{assert_ok, assert_pending, assert_ready_ok, task};

use futures::future::{poll_fn, try_join};

#[tokio::test]
async fn accept_read_write() -> std::io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;

    let accept = listener.accept();
    let connect = UnixStream::connect(&sock_path);
    let ((mut server, _), mut client) = try_join(accept, connect).await?;

    // Write to the client. TODO: Switch to write_all.
    let write_len = client.write(b"hello").await?;
    assert_eq!(write_len, 5);
    drop(client);
    // Read from the server. TODO: Switch to read_to_end.
    let mut buf = [0u8; 5];
    server.read_exact(&mut buf).await?;
    assert_eq!(&buf, b"hello");
    let len = server.read(&mut buf).await?;
    assert_eq!(len, 0);
    Ok(())
}

#[tokio::test]
async fn shutdown() -> std::io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;

    let accept = listener.accept();
    let connect = UnixStream::connect(&sock_path);
    let ((mut server, _), mut client) = try_join(accept, connect).await?;

    // Shut down the client
    AsyncWriteExt::shutdown(&mut client).await?;
    // Read from the server should return 0 to indicate the channel has been closed.
    let mut buf = [0u8; 1];
    let n = server.read(&mut buf).await?;
    assert_eq!(n, 0);
    Ok(())
}

#[tokio::test]
async fn try_read_write() -> std::io::Result<()> {
    let msg = b"hello world";

    let dir = tempfile::tempdir()?;
    let bind_path = dir.path().join("bind.sock");

    // Create listener
    let listener = UnixListener::bind(&bind_path)?;

    // Create socket pair
    let client = UnixStream::connect(&bind_path).await?;

    let (server, _) = listener.accept().await?;
    let mut written = msg.to_vec();

    // Track the server receiving data
    let mut readable = task::spawn(server.readable());
    assert_pending!(readable.poll());

    // Write data.
    client.writable().await?;
    assert_eq!(msg.len(), client.try_write(msg)?);

    // The task should be notified
    while !readable.is_woken() {
        tokio::task::yield_now().await;
    }

    // Fill the write buffer using non-vectored I/O
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write(msg) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end using non-vectored I/O
        let mut read = vec![0; written.len()];
        let mut i = 0;

        while i < read.len() {
            server.readable().await?;

            match server.try_read(&mut read[i..]) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    written.clear();
    client.writable().await.unwrap();

    // Fill the write buffer using vectored I/O
    let msg_bufs: Vec<_> = msg.chunks(3).map(io::IoSlice::new).collect();
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write_vectored(&msg_bufs) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end using vectored I/O
        let mut read = vec![0; written.len()];
        let mut i = 0;

        while i < read.len() {
            server.readable().await?;

            let mut bufs: Vec<_> = read[i..]
                .chunks_mut(0x10000)
                .map(io::IoSliceMut::new)
                .collect();
            match server.try_read_vectored(&mut bufs) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    // Now, we listen for shutdown
    drop(client);

    loop {
        let ready = server.ready(Interest::READABLE).await?;

        if ready.is_read_closed() {
            break;
        } else {
            tokio::task::yield_now().await;
        }
    }

    Ok(())
}

async fn create_pair() -> (UnixStream, UnixStream) {
    let dir = assert_ok!(tempfile::tempdir());
    let bind_path = dir.path().join("bind.sock");

    let listener = assert_ok!(UnixListener::bind(&bind_path));

    let accept = listener.accept();
    let connect = UnixStream::connect(&bind_path);
    let ((server, _), client) = assert_ok!(try_join(accept, connect).await);

    (client, server)
}

macro_rules! assert_readable_by_polling {
    ($stream:expr) => {
        assert_ok!(poll_fn(|cx| $stream.poll_read_ready(cx)).await);
    };
}

macro_rules! assert_not_readable_by_polling {
    ($stream:expr) => {
        poll_fn(|cx| {
            assert_pending!($stream.poll_read_ready(cx));
            Poll::Ready(())
        })
        .await;
    };
}

macro_rules! assert_writable_by_polling {
    ($stream:expr) => {
        assert_ok!(poll_fn(|cx| $stream.poll_write_ready(cx)).await);
    };
}

macro_rules! assert_not_writable_by_polling {
    ($stream:expr) => {
        poll_fn(|cx| {
            assert_pending!($stream.poll_write_ready(cx));
            Poll::Ready(())
        })
        .await;
    };
}

#[tokio::test]
async fn poll_read_ready() {
    let (mut client, mut server) = create_pair().await;

    // Initial state - not readable.
    assert_not_readable_by_polling!(server);

    // There is data in the buffer - readable.
    assert_ok!(client.write_all(b"ping").await);
    assert_readable_by_polling!(server);

    // Readable until calls to `poll_read` return `Poll::Pending`.
    let mut buf = [0u8; 4];
    assert_ok!(server.read_exact(&mut buf).await);
    assert_readable_by_polling!(server);
    read_until_pending(&mut server);
    assert_not_readable_by_polling!(server);

    // Detect the client disconnect.
    drop(client);
    assert_readable_by_polling!(server);
}

#[tokio::test]
async fn poll_write_ready() {
    let (mut client, server) = create_pair().await;

    // Initial state - writable.
    assert_writable_by_polling!(client);

    // No space to write - not writable.
    write_until_pending(&mut client);
    assert_not_writable_by_polling!(client);

    // Detect the server disconnect.
    drop(server);
    assert_writable_by_polling!(client);
}

fn read_until_pending(stream: &mut UnixStream) {
    let mut buf = vec![0u8; 1024 * 1024];
    loop {
        match stream.try_read(&mut buf) {
            Ok(_) => (),
            Err(err) => {
                assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
                break;
            }
        }
    }
}

fn write_until_pending(stream: &mut UnixStream) {
    let buf = vec![0u8; 1024 * 1024];
    loop {
        match stream.try_write(&buf) {
            Ok(_) => (),
            Err(err) => {
                assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
                break;
            }
        }
    }
}

#[tokio::test]
async fn try_read_buf() -> std::io::Result<()> {
    let msg = b"hello world";

    let dir = tempfile::tempdir()?;
    let bind_path = dir.path().join("bind.sock");

    // Create listener
    let listener = UnixListener::bind(&bind_path)?;

    // Create socket pair
    let client = UnixStream::connect(&bind_path).await?;

    let (server, _) = listener.accept().await?;
    let mut written = msg.to_vec();

    // Track the server receiving data
    let mut readable = task::spawn(server.readable());
    assert_pending!(readable.poll());

    // Write data.
    client.writable().await?;
    assert_eq!(msg.len(), client.try_write(msg)?);

    // The task should be notified
    while !readable.is_woken() {
        tokio::task::yield_now().await;
    }

    // Fill the write buffer
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write(msg) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end
        let mut read = Vec::with_capacity(written.len());
        let mut i = 0;

        while i < read.capacity() {
            server.readable().await?;

            match server.try_read_buf(&mut read) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    // Now, we listen for shutdown
    drop(client);

    loop {
        let ready = server.ready(Interest::READABLE).await?;

        if ready.is_read_closed() {
            break;
        } else {
            tokio::task::yield_now().await;
        }
    }

    Ok(())
}

// https://github.com/tokio-rs/tokio/issues/3879
#[tokio::test]
#[cfg(not(target_os = "macos"))]
async fn epollhup() -> io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;
    let connect = UnixStream::connect(&sock_path);
    tokio::pin!(connect);

    // Poll `connect` once.
    poll_fn(|cx| {
        use std::future::Future;

        assert_pending!(connect.as_mut().poll(cx));
        Poll::Ready(())
    })
    .await;

    drop(listener);

    let err = connect.await.unwrap_err();
    assert_eq!(err.kind(), io::ErrorKind::ConnectionReset);
    Ok(())
}
<commit_msg>tests: complete TODOs in `uds_stream` (#4587)<commit_after>#![cfg(feature = "full")]
#![warn(rust_2018_idioms)]
#![cfg(unix)]

use std::io;
use std::task::Poll;

use tokio::io::{AsyncReadExt, AsyncWriteExt, Interest};
use tokio::net::{UnixListener, UnixStream};
use tokio_test::{assert_ok, assert_pending, assert_ready_ok, task};

use futures::future::{poll_fn, try_join};

#[tokio::test]
async fn accept_read_write() -> std::io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;

    let accept = listener.accept();
    let connect = UnixStream::connect(&sock_path);
    let ((mut server, _), mut client) = try_join(accept, connect).await?;

    // Write to the client.
    client.write_all(b"hello").await?;
    drop(client);

    // Read from the server.
    let mut buf = vec![];
    server.read_to_end(&mut buf).await?;
    assert_eq!(&buf, b"hello");
    let len = server.read(&mut buf).await?;
    assert_eq!(len, 0);
    Ok(())
}

#[tokio::test]
async fn shutdown() -> std::io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;

    let accept = listener.accept();
    let connect = UnixStream::connect(&sock_path);
    let ((mut server, _), mut client) = try_join(accept, connect).await?;

    // Shut down the client
    AsyncWriteExt::shutdown(&mut client).await?;
    // Read from the server should return 0 to indicate the channel has been closed.
    let mut buf = [0u8; 1];
    let n = server.read(&mut buf).await?;
    assert_eq!(n, 0);
    Ok(())
}

#[tokio::test]
async fn try_read_write() -> std::io::Result<()> {
    let msg = b"hello world";

    let dir = tempfile::tempdir()?;
    let bind_path = dir.path().join("bind.sock");

    // Create listener
    let listener = UnixListener::bind(&bind_path)?;

    // Create socket pair
    let client = UnixStream::connect(&bind_path).await?;

    let (server, _) = listener.accept().await?;
    let mut written = msg.to_vec();

    // Track the server receiving data
    let mut readable = task::spawn(server.readable());
    assert_pending!(readable.poll());

    // Write data.
    client.writable().await?;
    assert_eq!(msg.len(), client.try_write(msg)?);

    // The task should be notified
    while !readable.is_woken() {
        tokio::task::yield_now().await;
    }

    // Fill the write buffer using non-vectored I/O
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write(msg) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end using non-vectored I/O
        let mut read = vec![0; written.len()];
        let mut i = 0;

        while i < read.len() {
            server.readable().await?;

            match server.try_read(&mut read[i..]) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    written.clear();
    client.writable().await.unwrap();

    // Fill the write buffer using vectored I/O
    let msg_bufs: Vec<_> = msg.chunks(3).map(io::IoSlice::new).collect();
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write_vectored(&msg_bufs) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end using vectored I/O
        let mut read = vec![0; written.len()];
        let mut i = 0;

        while i < read.len() {
            server.readable().await?;

            let mut bufs: Vec<_> = read[i..]
                .chunks_mut(0x10000)
                .map(io::IoSliceMut::new)
                .collect();
            match server.try_read_vectored(&mut bufs) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    // Now, we listen for shutdown
    drop(client);

    loop {
        let ready = server.ready(Interest::READABLE).await?;

        if ready.is_read_closed() {
            break;
        } else {
            tokio::task::yield_now().await;
        }
    }

    Ok(())
}

async fn create_pair() -> (UnixStream, UnixStream) {
    let dir = assert_ok!(tempfile::tempdir());
    let bind_path = dir.path().join("bind.sock");

    let listener = assert_ok!(UnixListener::bind(&bind_path));

    let accept = listener.accept();
    let connect = UnixStream::connect(&bind_path);
    let ((server, _), client) = assert_ok!(try_join(accept, connect).await);

    (client, server)
}

macro_rules! assert_readable_by_polling {
    ($stream:expr) => {
        assert_ok!(poll_fn(|cx| $stream.poll_read_ready(cx)).await);
    };
}

macro_rules! assert_not_readable_by_polling {
    ($stream:expr) => {
        poll_fn(|cx| {
            assert_pending!($stream.poll_read_ready(cx));
            Poll::Ready(())
        })
        .await;
    };
}

macro_rules! assert_writable_by_polling {
    ($stream:expr) => {
        assert_ok!(poll_fn(|cx| $stream.poll_write_ready(cx)).await);
    };
}

macro_rules! assert_not_writable_by_polling {
    ($stream:expr) => {
        poll_fn(|cx| {
            assert_pending!($stream.poll_write_ready(cx));
            Poll::Ready(())
        })
        .await;
    };
}

#[tokio::test]
async fn poll_read_ready() {
    let (mut client, mut server) = create_pair().await;

    // Initial state - not readable.
    assert_not_readable_by_polling!(server);

    // There is data in the buffer - readable.
    assert_ok!(client.write_all(b"ping").await);
    assert_readable_by_polling!(server);

    // Readable until calls to `poll_read` return `Poll::Pending`.
    let mut buf = [0u8; 4];
    assert_ok!(server.read_exact(&mut buf).await);
    assert_readable_by_polling!(server);
    read_until_pending(&mut server);
    assert_not_readable_by_polling!(server);

    // Detect the client disconnect.
    drop(client);
    assert_readable_by_polling!(server);
}

#[tokio::test]
async fn poll_write_ready() {
    let (mut client, server) = create_pair().await;

    // Initial state - writable.
    assert_writable_by_polling!(client);

    // No space to write - not writable.
    write_until_pending(&mut client);
    assert_not_writable_by_polling!(client);

    // Detect the server disconnect.
    drop(server);
    assert_writable_by_polling!(client);
}

fn read_until_pending(stream: &mut UnixStream) {
    let mut buf = vec![0u8; 1024 * 1024];
    loop {
        match stream.try_read(&mut buf) {
            Ok(_) => (),
            Err(err) => {
                assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
                break;
            }
        }
    }
}

fn write_until_pending(stream: &mut UnixStream) {
    let buf = vec![0u8; 1024 * 1024];
    loop {
        match stream.try_write(&buf) {
            Ok(_) => (),
            Err(err) => {
                assert_eq!(err.kind(), io::ErrorKind::WouldBlock);
                break;
            }
        }
    }
}

#[tokio::test]
async fn try_read_buf() -> std::io::Result<()> {
    let msg = b"hello world";

    let dir = tempfile::tempdir()?;
    let bind_path = dir.path().join("bind.sock");

    // Create listener
    let listener = UnixListener::bind(&bind_path)?;

    // Create socket pair
    let client = UnixStream::connect(&bind_path).await?;

    let (server, _) = listener.accept().await?;
    let mut written = msg.to_vec();

    // Track the server receiving data
    let mut readable = task::spawn(server.readable());
    assert_pending!(readable.poll());

    // Write data.
    client.writable().await?;
    assert_eq!(msg.len(), client.try_write(msg)?);

    // The task should be notified
    while !readable.is_woken() {
        tokio::task::yield_now().await;
    }

    // Fill the write buffer
    loop {
        // Still ready
        let mut writable = task::spawn(client.writable());
        assert_ready_ok!(writable.poll());

        match client.try_write(msg) {
            Ok(n) => written.extend(&msg[..n]),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                break;
            }
            Err(e) => panic!("error = {:?}", e),
        }
    }

    {
        // Write buffer full
        let mut writable = task::spawn(client.writable());
        assert_pending!(writable.poll());

        // Drain the socket from the server end
        let mut read = Vec::with_capacity(written.len());
        let mut i = 0;

        while i < read.capacity() {
            server.readable().await?;

            match server.try_read_buf(&mut read) {
                Ok(n) => i += n,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => continue,
                Err(e) => panic!("error = {:?}", e),
            }
        }

        assert_eq!(read, written);
    }

    // Now, we listen for shutdown
    drop(client);

    loop {
        let ready = server.ready(Interest::READABLE).await?;

        if ready.is_read_closed() {
            break;
        } else {
            tokio::task::yield_now().await;
        }
    }

    Ok(())
}

// https://github.com/tokio-rs/tokio/issues/3879
#[tokio::test]
#[cfg(not(target_os = "macos"))]
async fn epollhup() -> io::Result<()> {
    let dir = tempfile::Builder::new()
        .prefix("tokio-uds-tests")
        .tempdir()
        .unwrap();
    let sock_path = dir.path().join("connect.sock");

    let listener = UnixListener::bind(&sock_path)?;
    let connect = UnixStream::connect(&sock_path);
    tokio::pin!(connect);

    // Poll `connect` once.
    poll_fn(|cx| {
        use std::future::Future;

        assert_pending!(connect.as_mut().poll(cx));
        Poll::Ready(())
    })
    .await;

    drop(listener);

    let err = connect.await.unwrap_err();
    assert_eq!(err.kind(), io::ErrorKind::ConnectionReset);
    Ok(())
}
<|endoftext|>


<commit_before>use std::iter::Empty;
use std::ops::Range;
use std::sync::Arc;

use command_buffer::Submission;
use device::Device;
use format::FormatDesc;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
use image::sys::Usage;
use image::traits::AccessRange;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

pub struct AttachmentImage<F> {
    image: UnsafeImage,
    view: UnsafeImageView,
    memory: DeviceMemory,
    format: F,
}

impl<F> AttachmentImage<F> {
    pub fn new(device: &Arc<Device>, dimensions: [u32; 2], format: F)
               -> Result<Arc<AttachmentImage<F>>, OomError>
        where F: FormatDesc
    {
        let usage = Usage {
            transfer_source: true,
            sampled: true,
            color_attachment: true,
            depth_stencil_attachment: true,
            .. Usage::none()
        };

        let (image, mem_reqs) = unsafe {
            try!(UnsafeImage::new(device, &usage, format.format(),
                                  Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] },
                                  1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        unsafe { try!(image.bind_memory(&mem, 0 .. mem_reqs.size)); }

        let view = unsafe {
            try!(UnsafeImageView::new(&image))
        };

        Ok(Arc::new(AttachmentImage {
            image: image,
            view: view,
            memory: mem,
            format: format,
        }))
    }

    #[inline]
    pub fn dimensions(&self) -> Dimensions {
        self.image.dimensions()
    }
}

unsafe impl<F> Image for AttachmentImage<F> {
    #[inline]
    fn inner_image(&self) -> &UnsafeImage {
        &self.image
    }

    #[inline]
    fn blocks(&self, _: Range<u32>, _: Range<u32>) -> Vec<(u32, u32)> {
        vec![(0, 0)]
    }

    #[inline]
    fn initial_layout(&self, block: (u32, u32), first_required_layout: Layout) -> Layout {
        Layout::ColorAttachmentOptimal      // FIXME:
    }

    #[inline]
    fn final_layout(&self, block: (u32, u32), last_required_layout: Layout) -> Layout {
        Layout::ColorAttachmentOptimal      // FIXME:
    }

    fn needs_fence(&self, access: &mut Iterator<Item = AccessRange>) -> Option<bool> {
        Some(false)
    }

    unsafe fn gpu_access(&self, access: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> Vec<Arc<Submission>>
    {
        vec![]
    }
}

unsafe impl<P, F> ImageContent<P> for AttachmentImage<F> {
    #[inline]
    fn matches_format(&self) -> bool {
        true        // FIXME:
    }
}

unsafe impl<F: 'static> ImageView for AttachmentImage<F> {
    #[inline]
    fn parent(&self) -> &Image {
        self
    }

    #[inline]
    fn parent_arc(me: &Arc<Self>) -> Arc<Image> where Self: Sized {
        me.clone() as Arc<_>
    }

    #[inline]
    fn inner_view(&self) -> &UnsafeImageView {
        &self.view
    }

    #[inline]
    fn descriptor_set_storage_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_combined_image_sampler_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_sampled_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_input_attachment_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn identity_swizzle(&self) -> bool {
        true
    }
}
<commit_msg>Improve the handling of AttachmentImage<commit_after>use std::iter::Empty;
use std::ops::Range;
use std::sync::Arc;

use command_buffer::Submission;
use device::Device;
use format::FormatDesc;
use format::FormatTy;
use image::sys::Dimensions;
use image::sys::Layout;
use image::sys::UnsafeImage;
use image::sys::UnsafeImageView;
use image::sys::Usage;
use image::traits::AccessRange;
use image::traits::Image;
use image::traits::ImageContent;
use image::traits::ImageView;
use memory::DeviceMemory;
use sync::Sharing;

use OomError;

pub struct AttachmentImage<F> {
    image: UnsafeImage,
    view: UnsafeImageView,
    memory: DeviceMemory,
    format: F,

    // Layout to use when the image is used as a framebuffer attachment.
    // Should be either "depth-stencil optimal" or "color optimal".
    attachment_layout: Layout,
}

impl<F> AttachmentImage<F> {
    pub fn new(device: &Arc<Device>, dimensions: [u32; 2], format: F)
               -> Result<Arc<AttachmentImage<F>>, OomError>
        where F: FormatDesc
    {
        let is_depth = match format.format().ty() {
            FormatTy::Depth => true,
            FormatTy::DepthStencil => true,
            FormatTy::Compressed => panic!(),
            _ => false
        };

        let usage = Usage {
            transfer_source: true,
            sampled: true,
            color_attachment: !is_depth,
            depth_stencil_attachment: is_depth,
            .. Usage::none()
        };

        let (image, mem_reqs) = unsafe {
            try!(UnsafeImage::new(device, &usage, format.format(),
                                  Dimensions::Dim2d { width: dimensions[0], height: dimensions[1] },
                                  1, 1, Sharing::Exclusive::<Empty<u32>>, false, false))
        };

        let mem_ty = {
            let device_local = device.physical_device().memory_types()
                                     .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0)
                                     .filter(|t| t.is_device_local());
            let any = device.physical_device().memory_types()
                            .filter(|t| (mem_reqs.memory_type_bits & (1 << t.id())) != 0);
            device_local.chain(any).next().unwrap()
        };

        // note: alignment doesn't need to be checked because allocating memory is guaranteed to
        //       fulfill any alignment requirement

        let mem = try!(DeviceMemory::alloc(device, &mem_ty, mem_reqs.size));
        unsafe { try!(image.bind_memory(&mem, 0 .. mem_reqs.size)); }

        let view = unsafe {
            try!(UnsafeImageView::new(&image))
        };

        Ok(Arc::new(AttachmentImage {
            image: image,
            view: view,
            memory: mem,
            format: format,
            attachment_layout: if is_depth { Layout::DepthStencilAttachmentOptimal }
                               else { Layout::ColorAttachmentOptimal },
        }))
    }

    #[inline]
    pub fn dimensions(&self) -> Dimensions {
        self.image.dimensions()
    }
}

unsafe impl<F> Image for AttachmentImage<F> {
    #[inline]
    fn inner_image(&self) -> &UnsafeImage {
        &self.image
    }

    #[inline]
    fn blocks(&self, _: Range<u32>, _: Range<u32>) -> Vec<(u32, u32)> {
        vec![(0, 0)]
    }

    #[inline]
    fn initial_layout(&self, _: (u32, u32), _: Layout) -> Layout {
        self.attachment_layout
    }

    #[inline]
    fn final_layout(&self, _: (u32, u32), _: Layout) -> Layout {
        self.attachment_layout
    }

    fn needs_fence(&self, access: &mut Iterator<Item = AccessRange>) -> Option<bool> {
        Some(false)
    }

    unsafe fn gpu_access(&self, access: &mut Iterator<Item = AccessRange>,
                         submission: &Arc<Submission>) -> Vec<Arc<Submission>>
    {
        vec![]
    }
}

unsafe impl<P, F> ImageContent<P> for AttachmentImage<F> {
    #[inline]
    fn matches_format(&self) -> bool {
        true        // FIXME:
    }
}

unsafe impl<F: 'static> ImageView for AttachmentImage<F> {
    #[inline]
    fn parent(&self) -> &Image {
        self
    }

    #[inline]
    fn parent_arc(me: &Arc<Self>) -> Arc<Image> where Self: Sized {
        me.clone() as Arc<_>
    }

    #[inline]
    fn inner_view(&self) -> &UnsafeImageView {
        &self.view
    }

    #[inline]
    fn descriptor_set_storage_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_combined_image_sampler_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_sampled_image_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn descriptor_set_input_attachment_layout(&self, _: AccessRange) -> Layout {
        Layout::ColorAttachmentOptimal
    }

    #[inline]
    fn identity_swizzle(&self) -> bool {
        true
    }
}
<|endoftext|>


<commit_before>extern crate glob;
#[macro_use]
extern crate log;
extern crate env_logger;

extern crate protoc;
extern crate protoc_rust;

use std::io::Read;
use std::io::Write;
use std::fs;
use std::path;

fn glob_simple(pattern: &str) -> Vec<String> {
    glob::glob(pattern).expect("glob")
        .map(|g| {
            g.expect("item").as_path().to_str().expect("utf-8").to_owned()
        })
        .collect()
}

fn clean_old_files() {
    for f in glob_simple("src/*/pb_*.rs") {
        fs::remove_file(f).expect("rm");
    }
}

fn generate_v_from_common() {
    let v3 = protoc::Protoc::from_env_path().version().expect("version").is_3();

    let mut mod_v2 = fs::File::create("src/common/v2/mod.rs").expect("mod.rs");
    let mut mod_v3 = fs::File::create("src/common/v3/mod.rs").expect("mod.rs");

    write!(mod_v2, "// generated\n").expect("write");
    write!(mod_v3, "// generated\n").expect("write");

    for f in glob_simple("src/common/v2/*.rs") {
        let f = path::PathBuf::from(f);
        let base_name = f.as_path().file_name().expect("file_name").to_str().expect("to_str");

        let without_suffix = &base_name[.. base_name.len() - ".rs".len()];

        if without_suffix == "mod" {
            continue;
        }

        if without_suffix.ends_with("_pb") {
            continue;
        }

        let carllerche = without_suffix.contains("carllerche");

        for mod_v in &mut [&mut mod_v2, &mut mod_v3] {
            for suffix in &["", "_pb"] {
                if carllerche {
                    write!(mod_v, "#[cfg(feature = \"bytes\")]").expect("write");
                }
                write!(mod_v, "mod {}{};\n", without_suffix, suffix).expect("write");
            }
        }

        let mut p2f = fs::File::open(&format!("src/common/v2/{}_pb.proto", without_suffix))
            .expect("open v2 .proto");
        let mut proto = String::new();
        p2f.read_to_string(&mut proto).expect("read .proto");
        drop(p2f);

        let mut r2f = fs::File::open(&format!("src/common/v2/{}.rs", without_suffix))
            .expect("open v2 .rs");
        let mut rs = String::new();
        r2f.read_to_string(&mut rs).expect("read .rs");
        drop(r2f);

        let mut p3f = fs::File::create(&format!("src/common/v3/{}_pb.proto", without_suffix))
            .expect("create v3 .proto");
        let mut r3f = fs::File::create(&format!("src/common/v3/{}.rs", without_suffix))
            .expect("create v3 .rs");

        // convert proto2 to proto3
        let proto = proto.replace("optional ", "");
        let proto = proto.replace("required ", "");
        let proto = proto.replace("syntax = \"proto2\";", "syntax = \"proto3\";");
        write!(p3f, "// generated\n").expect("write");
        write!(p3f, "{}", proto).expect("write");
        p3f.flush().expect("flush");

        write!(r3f, "// generated\n").expect("write");
        write!(r3f, "{}", rs).expect("write");
        r3f.flush().expect("flush");

        for &v in &[2, 3] {
            if v == 3 && !v3 {
                continue;
            }

            protoc_rust::run(protoc_rust::Args {
                out_dir: &format!("src/common/v{}", v),
                includes: &[&format!("src/common/v{}", v), "../proto"],
                input: &[&format!("src/common/v{}/{}_pb.proto", v, without_suffix)],
            }).expect("protoc");
        }
    }

    mod_v2.flush().expect("flush");
    mod_v3.flush().expect("flush");
}

fn generate_pb_rs() {

    fn gen_v2_v3(dir: &str) {
        info!("generating protos in {}", dir);

        let protos = glob_simple(&format!("{}/*.proto", dir));

        assert!(!protos.is_empty());

        protoc_rust::run(protoc_rust::Args {
            out_dir: dir,
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", dir],
        }).expect("protoc");
    }

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        gen_v2_v3("src/v3");

        let protos = glob_simple("src/google/protobuf/*.proto");
        protoc_rust::run(protoc_rust::Args {
            out_dir: "src/google/protobuf",
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", "src"],
        }).expect("protoc");
    } else {
        info!("generating stubs in src/v3");

        // Because `#[cfg(nonexistent)]` still requires module files to exist
        // https://github.com/rust-lang/rust/pull/36482

        let g1 = glob::glob("src/v3/*.proto").expect("g1");
        let g2 = glob::glob("src/google/protobuf/*.proto").expect("g2");

        for f in g1.chain(g2) {
            let mut f: String = f.expect("f").as_path().to_str().expect("utf-8").to_owned();
            let suffix = ".proto";
            let len = f.len();
            f.truncate(len - suffix.len());

            let mut f = fs::File::create(f).expect("create");
            let content = b"// generated\n// empty file because protobuf 3 is not available\n";
            f.write_all(content).expect("write");
            f.flush().expect("flush");
        }
    }
}

fn main() {
    env_logger::init().expect("env_logger");

    clean_old_files();
    generate_v_from_common();
    generate_pb_rs();

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        println!("cargo:rustc-cfg=proto3");
    }
}
<commit_msg>Fix test build<commit_after>extern crate glob;
#[macro_use]
extern crate log;
extern crate env_logger;

extern crate protoc;
extern crate protoc_rust;

use std::io::Read;
use std::io::Write;
use std::fs;
use std::path;

fn glob_simple(pattern: &str) -> Vec<String> {
    glob::glob(pattern).expect("glob")
        .map(|g| {
            g.expect("item").as_path().to_str().expect("utf-8").to_owned()
        })
        .collect()
}

fn clean_old_files() {
    for f in glob_simple("src/**/*_pb.rs") {
        fs::remove_file(f).expect("rm");
    }
}

fn generate_v_from_common() {
    let v3 = protoc::Protoc::from_env_path().version().expect("version").is_3();

    let mut mod_v2 = fs::File::create("src/common/v2/mod.rs").expect("mod.rs");
    let mut mod_v3 = fs::File::create("src/common/v3/mod.rs").expect("mod.rs");

    write!(mod_v2, "// generated\n").expect("write");
    write!(mod_v3, "// generated\n").expect("write");

    for f in glob_simple("src/common/v2/*.rs") {
        let f = path::PathBuf::from(f);
        let base_name = f.as_path().file_name().expect("file_name").to_str().expect("to_str");

        let without_suffix = &base_name[.. base_name.len() - ".rs".len()];

        if without_suffix == "mod" {
            continue;
        }

        if without_suffix.ends_with("_pb") {
            continue;
        }

        let carllerche = without_suffix.contains("carllerche");

        for mod_v in &mut [&mut mod_v2, &mut mod_v3] {
            for suffix in &["", "_pb"] {
                if carllerche {
                    write!(mod_v, "#[cfg(feature = \"bytes\")]").expect("write");
                }
                write!(mod_v, "mod {}{};\n", without_suffix, suffix).expect("write");
            }
        }

        let mut p2f = fs::File::open(&format!("src/common/v2/{}_pb.proto", without_suffix))
            .expect("open v2 .proto");
        let mut proto = String::new();
        p2f.read_to_string(&mut proto).expect("read .proto");
        drop(p2f);

        let mut r2f = fs::File::open(&format!("src/common/v2/{}.rs", without_suffix))
            .expect("open v2 .rs");
        let mut rs = String::new();
        r2f.read_to_string(&mut rs).expect("read .rs");
        drop(r2f);

        let mut p3f = fs::File::create(&format!("src/common/v3/{}_pb.proto", without_suffix))
            .expect("create v3 .proto");
        let mut r3f = fs::File::create(&format!("src/common/v3/{}.rs", without_suffix))
            .expect("create v3 .rs");

        // convert proto2 to proto3
        let proto = proto.replace("optional ", "");
        let proto = proto.replace("required ", "");
        let proto = proto.replace("syntax = \"proto2\";", "syntax = \"proto3\";");
        write!(p3f, "// generated\n").expect("write");
        write!(p3f, "{}", proto).expect("write");
        p3f.flush().expect("flush");

        write!(r3f, "// generated\n").expect("write");
        write!(r3f, "{}", rs).expect("write");
        r3f.flush().expect("flush");

        for &v in &[2, 3] {
            if v == 3 && !v3 {
                continue;
            }

            protoc_rust::run(protoc_rust::Args {
                out_dir: &format!("src/common/v{}", v),
                includes: &[&format!("src/common/v{}", v), "../proto"],
                input: &[&format!("src/common/v{}/{}_pb.proto", v, without_suffix)],
            }).expect("protoc");
        }
    }

    mod_v2.flush().expect("flush");
    mod_v3.flush().expect("flush");
}

fn generate_pb_rs() {

    fn gen_v2_v3(dir: &str) {
        info!("generating protos in {}", dir);

        let protos = glob_simple(&format!("{}/*.proto", dir));

        assert!(!protos.is_empty());

        protoc_rust::run(protoc_rust::Args {
            out_dir: dir,
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", dir],
        }).expect("protoc");
    }

    gen_v2_v3("src/v2");

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        gen_v2_v3("src/v3");

        let protos = glob_simple("src/google/protobuf/*.proto");
        protoc_rust::run(protoc_rust::Args {
            out_dir: "src/google/protobuf",
            input: &protos.iter().map(|a| a.as_ref()).collect::<Vec<&str>>(),
            includes: &["../proto", "src"],
        }).expect("protoc");
    } else {
        info!("generating stubs in src/v3");

        // Because `#[cfg(nonexistent)]` still requires module files to exist
        // https://github.com/rust-lang/rust/pull/36482

        let g1 = glob::glob("src/v3/*.proto").expect("g1");
        let g2 = glob::glob("src/google/protobuf/*.proto").expect("g2");

        for f in g1.chain(g2) {
            let mut f: String = f.expect("f").as_path().to_str().expect("utf-8").to_owned();
            let suffix = ".proto";
            let len = f.len();
            f.truncate(len - suffix.len());

            let mut f = fs::File::create(f).expect("create");
            let content = b"// generated\n// empty file because protobuf 3 is not available\n";
            f.write_all(content).expect("write");
            f.flush().expect("flush");
        }
    }
}

fn main() {
    env_logger::init().expect("env_logger");

    clean_old_files();
    generate_v_from_common();
    generate_pb_rs();

    if protoc::Protoc::from_env_path().version().expect("version").is_3() {
        println!("cargo:rustc-cfg=proto3");
    }
}
<|endoftext|>


<commit_before>// spell-checker:ignore (utils) chgrp chmod chown chroot cksum dircolors hashsum hostid logname mkdir mkfifo mknod mktemp nohup nproc numfmt pathchk printenv printf readlink realpath relpath rmdir shuf stdbuf tsort uname unexpand whoami
// spell-checker:ignore () uutils uumain rustfmt rustc macos krate

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    if let Ok(profile) = env::var("PROFILE") {
        println!("cargo:rustc-cfg=build={:?}", profile);
    }

    let feature_prefix = "CARGO_FEATURE_";
    let out_dir = env::var("OUT_DIR").unwrap();

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(feature_prefix) {
            let krate = key[feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
                "default" | "macos" | "unix" | "windows" => continue,
                "nightly" | "test_unimplemented" => continue,
                s if s.starts_with("feat_") => continue,
                _ => {}
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();

    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();

    mf.write_all(
        "
    type UtilityMap = HashMap<&'static str, fn(Vec<String>) -> i32>;

    fn util_map() -> UtilityMap {
    let mut map: UtilityMap = HashMap::new();\n"
            .as_bytes(),
    )
    .unwrap();

    for krate in crates {
        match krate.as_ref() {
            // ToDO: add another bypass method for publishing name collisions requiring a non-`uu_` prefix for a util
            // * use "uu_" prefix as bypass method to avoid name collisions with imported crates, when necessary (eg, 'test')
            k if k.starts_with("uu_")
                => mf
                    .write_all(
                        format!("map.insert(\"{k}\", {krate}::uumain);\n", k = krate.clone().remove("uu_".len()), krate = krate)
                            .as_bytes(),
                    )
                    .unwrap(),
            "false" | "true" => mf
                .write_all(
                    format!("map.insert(\"{krate}\", r#{krate}::uumain);\n", krate = krate)
                        .as_bytes(),
                )
                .unwrap(),
            "hashsum" => mf
                .write_all(
                    format!(
                        "
                        map.insert(\"{krate}\", {krate}::uumain);
                            map.insert(\"md5sum\", {krate}::uumain);
                            map.insert(\"sha1sum\", {krate}::uumain);
                            map.insert(\"sha224sum\", {krate}::uumain);
                            map.insert(\"sha256sum\", {krate}::uumain);
                            map.insert(\"sha384sum\", {krate}::uumain);
                            map.insert(\"sha512sum\", {krate}::uumain);
                            map.insert(\"sha3sum\", {krate}::uumain);
                            map.insert(\"sha3-224sum\", {krate}::uumain);
                            map.insert(\"sha3-256sum\", {krate}::uumain);
                            map.insert(\"sha3-384sum\", {krate}::uumain);
                            map.insert(\"sha3-512sum\", {krate}::uumain);
                            map.insert(\"shake128sum\", {krate}::uumain);
                            map.insert(\"shake256sum\", {krate}::uumain);\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
            _ => mf
                .write_all(
                    format!(
                        "map.insert(\"{krate}\", {krate}::uumain);\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
        }
    }

    mf.write_all(b"map\n}\n").unwrap();

    mf.flush().unwrap();
}
<commit_msg>build/fix ~ (build.rs) fix 'feature => sub-crate/util' translation logic + improved output formatting<commit_after>// spell-checker:ignore (utils) chgrp chmod chown chroot cksum dircolors hashsum hostid logname mkdir mkfifo mknod mktemp nohup nproc numfmt pathchk printenv printf readlink realpath relpath rmdir shuf stdbuf tsort uname unexpand whoami
// spell-checker:ignore () uutils uumain rustfmt rustc macos krate

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    if let Ok(profile) = env::var("PROFILE") {
        println!("cargo:rustc-cfg=build={:?}", profile);
    }

    let env_feature_prefix: &str = "CARGO_FEATURE_";
    let feature_prefix: &str = "feat_";
    let override_prefix: &str = "uu_";

    let out_dir = env::var("OUT_DIR").unwrap();

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(env_feature_prefix) {
            let krate = key[env_feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
                "default" | "macos" | "unix" | "windows" => continue, // common/standard feature names
                "nightly" | "test_unimplemented" => continue,         // crate-local custom features
                "test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
                s if s.starts_with(feature_prefix) => continue, // crate feature sets
                _ => {}             // util feature name
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();

    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();

    mf.write_all(
        "type UtilityMap = HashMap<&'static str, fn(Vec<String>) -> i32>;\n\
        \n\
        fn util_map() -> UtilityMap {\n\
        \tlet mut map: UtilityMap = HashMap::new();\n\
        "
        .as_bytes(),
    )
    .unwrap();

    for krate in crates {
        match krate.as_ref() {
            k if k.starts_with(override_prefix) => mf
                .write_all(
                    format!(
                        "\tmap.insert(\"{k}\", {krate}::uumain);\n",
                        k = krate[override_prefix.len()..].to_string(),
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
            "false" | "true" => mf
                .write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", r#{krate}::uumain);\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
            "hashsum" => mf
                .write_all(
                    format!(
                        "\
                        \tmap.insert(\"{krate}\", {krate}::uumain);\n\
                        \t\tmap.insert(\"md5sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha1sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha224sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha256sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha384sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha512sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha3sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha3-224sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha3-256sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha3-384sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"sha3-512sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"shake128sum\", {krate}::uumain);\n\
                        \t\tmap.insert(\"shake256sum\", {krate}::uumain);\n\
                        ",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
            _ => mf
                .write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", {krate}::uumain);\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap(),
        }
    }

    mf.write_all(b"map\n}\n").unwrap();

    mf.flush().unwrap();
}
<|endoftext|>


<commit_before>use std::process::Command;

fn main() {
    let git_version = Command::new("git").arg("describe").arg("--tags").output()
        .expect("Failed to get git description");
    if git_version.status.success() {
        let git_version = String::from_utf8(git_version.stdout)
            .expect("Failed to decode git description");
        print!("cargo:rustc-env=BUILD_VERSION={}", git_version);
    }
}
<commit_msg>Fix git version<commit_after>use std::process::Command;

fn main() {
    let git_version = Command::new("git").arg("describe").arg("--tags").output()
        .expect("Failed to get git description");
    if git_version.status.success() {
        let git_version = String::from_utf8(git_version.stdout)
            .expect("Failed to decode git description");
        print!("cargo:rustc-env=GIT_VERSION={}", git_version);
    }
}
<|endoftext|>


<commit_before>use flate2::{Compression, GzBuilder};
use std::ffi::OsStr;
use std::fs;
use std::path::Path;

fn main() {
    compress_man();
}

fn compress_man() {
    let out_path = Path::new(&std::env::var("OUT_DIR").unwrap()).join("man.tgz");
    let dst = fs::File::create(out_path).unwrap();
    let encoder = GzBuilder::new()
        .filename("man.tar")
        .write(dst, Compression::best());
    let mut ar = tar::Builder::new(encoder);

    let mut add_files = |dir, extension| {
        for entry in fs::read_dir(dir).unwrap() {
            let path = entry.unwrap().path();
            if path.extension() != Some(extension) {
                continue;
            }
            println!("cargo:rerun-if-changed={}", path.display());
            ar.append_path_with_name(&path, path.file_name().unwrap())
                .unwrap();
        }
    };

    add_files(Path::new("src/etc/man"), OsStr::new("1"));
    add_files(Path::new("src/doc/man/generated_txt"), OsStr::new("txt"));
    let encoder = ar.into_inner().unwrap();
    encoder.finish().unwrap();
}
<commit_msg>Auto merge of #8600 - alexcrichton:deterministic, r=ehuss<commit_after>use flate2::{Compression, GzBuilder};
use std::ffi::OsStr;
use std::fs;
use std::path::Path;

fn main() {
    compress_man();
}

fn compress_man() {
    let out_path = Path::new(&std::env::var("OUT_DIR").unwrap()).join("man.tgz");
    let dst = fs::File::create(out_path).unwrap();
    let encoder = GzBuilder::new()
        .filename("man.tar")
        .write(dst, Compression::best());
    let mut ar = tar::Builder::new(encoder);
    ar.mode(tar::HeaderMode::Deterministic);

    let mut add_files = |dir, extension| {
        let mut files = fs::read_dir(dir)
            .unwrap()
            .map(|e| e.unwrap().path())
            .collect::<Vec<_>>();
        files.sort();
        for path in files {
            if path.extension() != Some(extension) {
                continue;
            }
            println!("cargo:rerun-if-changed={}", path.display());
            ar.append_path_with_name(&path, path.file_name().unwrap())
                .unwrap();
        }
    };

    add_files(Path::new("src/etc/man"), OsStr::new("1"));
    add_files(Path::new("src/doc/man/generated_txt"), OsStr::new("txt"));
    let encoder = ar.into_inner().unwrap();
    encoder.finish().unwrap();
}
<|endoftext|>


<commit_before>use std::env;

fn main() {
    let cfgs = env::var("OVERRIDE_GTK_CFG")
        .or_else(|_| env::var("DEP_GTK_CFG"))
        .unwrap_or_else(|e| panic!("Failed to read `DEP_GTK_CFG`: {}", e));
    for cfg in cfgs.split(' ') {
        println!("cargo:rustc-cfg={}", cfg);
    }
}
<commit_msg>build.rs: avoid returning empty cfg directives<commit_after>use std::env;

fn main() {
    let cfgs = env::var("OVERRIDE_GTK_CFG")
        .or_else(|_| env::var("DEP_GTK_CFG"))
        .unwrap_or_else(|e| panic!("Failed to read `DEP_GTK_CFG`: {}", e));
    for cfg in cfgs.split(' ').filter(|s| !s.is_empty()) {
        println!("cargo:rustc-cfg={}", cfg);
    }
}
<|endoftext|>


<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate gcc;

use std::env;
use std::path::Path;

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    if target.contains("msvc") && host.contains("windows") {
        let mut config = gcc::Config::new();
        config.file("src/util_helpers.asm");
        config.file("src/aesni_helpers.asm");
        if target.contains("x86_64") {
            config.define("X64", None);
        }
        config.compile("lib_rust_crypto_helpers.a");
    }
    else {
        let mut cfg = gcc::Config::new();
        cfg.file("src/util_helpers.c");
        cfg.file("src/aesni_helpers.c");
        if env::var_os("CC").is_none() {
            if host.contains("openbsd") {
                // Use clang on openbsd since there have been reports that
                // GCC doesn't like some of the assembly that we use on that
                // platform.
                cfg.compiler(Path::new("clang"));
            } else {
                cfg.compiler(Path::new("cc"));
            }
        }
        cfg.compile("lib_rust_crypto_helpers.a");
    }
}

<commit_msg>This fixes cross-compilation.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern crate gcc;

use std::env;
use std::path::Path;

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    if target.contains("msvc") && host.contains("windows") {
        let mut config = gcc::Config::new();
        config.file("src/util_helpers.asm");
        config.file("src/aesni_helpers.asm");
        if target.contains("x86_64") {
            config.define("X64", None);
        }
        config.compile("lib_rust_crypto_helpers.a");
    }
    else {
        let mut cfg = gcc::Config::new();
        cfg.file("src/util_helpers.c");
        cfg.file("src/aesni_helpers.c");
        if env::var_os("CC").is_none() {
            if host.contains("openbsd") {
                // Use clang on openbsd since there have been reports that
                // GCC doesn't like some of the assembly that we use on that
                // platform.
                cfg.compiler(Path::new("clang"));
            } else if target == host {
                cfg.compiler(Path::new("cc"));
            }
        }
        cfg.compile("lib_rust_crypto_helpers.a");
    }
}

<|endoftext|>


<commit_before>use std::env;
use std::process::Command;
use std::str;

fn main() {
    // Avoid unnecessary re-building.
    println!("cargo:rerun-if-changed=build.rs");

    let (rustc_minor_ver, is_nightly) = rustc_minor_nightly().expect("Failed to get rustc version");
    let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
    let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok();
    let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok();
    let libc_ci = env::var("LIBC_CI").is_ok();

    if env::var("CARGO_FEATURE_USE_STD").is_ok() {
        println!(
            "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \
             please consider using the `std` cargo feature instead\""
        );
    }

    // The ABI of libc used by libstd is backward compatible with FreeBSD 10.
    // The ABI of libc from crates.io is backward compatible with FreeBSD 11.
    //
    // On CI, we detect the actual FreeBSD version and match its ABI exactly,
    // running tests to ensure that the ABI is correct.
    match which_freebsd() {
        Some(10) => println!("cargo:rustc-cfg=freebsd10"),
        Some(11) => println!("cargo:rustc-cfg=freebsd11"),
        Some(12) => println!("cargo:rustc-cfg=freebsd12"),
        Some(13) => println!("cargo:rustc-cfg=freebsd13"),
        Some(14) => println!("cargo:rustc-cfg=freebsd14"),
        Some(_) | None => println!("cargo:rustc-cfg=freebsd11"),
    }

    // On CI: deny all warnings
    if libc_ci {
        println!("cargo:rustc-cfg=libc_deny_warnings");
    }

    // Rust >= 1.15 supports private module use:
    if rustc_minor_ver >= 15 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_priv_mod_use");
    }

    // Rust >= 1.19 supports unions:
    if rustc_minor_ver >= 19 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_union");
    }

    // Rust >= 1.24 supports const mem::size_of:
    if rustc_minor_ver >= 24 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_const_size_of");
    }

    // Rust >= 1.25 supports repr(align):
    if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
        println!("cargo:rustc-cfg=libc_align");
    }

    // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
    // Otherwise, it defines an incompatible type to retaining
    // backwards-compatibility.
    if rustc_minor_ver >= 30 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_core_cvoid");
    }

    // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor).
    if rustc_minor_ver >= 33 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_packedN");
        println!("cargo:rustc-cfg=libc_cfg_target_vendor");
    }

    // Rust >= 1.40 supports #[non_exhaustive].
    if rustc_minor_ver >= 40 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_non_exhaustive");
    }

    if rustc_minor_ver >= 51 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_ptr_addr_of");
    }

    // #[thread_local] is currently unstable
    if rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_thread_local");
    }

    if const_extern_fn_cargo_feature {
        if !is_nightly || rustc_minor_ver < 40 {
            panic!("const-extern-fn requires a nightly compiler >= 1.40")
        }
        println!("cargo:rustc-cfg=libc_const_extern_fn");
    }
}

fn rustc_minor_nightly() -> Option<(u32, bool)> {
    macro_rules! otry {
        ($e:expr) => {
            match $e {
                Some(e) => e,
                None => return None,
            }
        };
    }

    let rustc = otry!(env::var_os("RUSTC"));
    let output = otry!(Command::new(rustc).arg("--version").output().ok());
    let version = otry!(str::from_utf8(&output.stdout).ok());
    let mut pieces = version.split('.');

    if pieces.next() != Some("rustc 1") {
        return None;
    }

    let minor = pieces.next();

    // If `rustc` was built from a tarball, its version string
    // will have neither a git hash nor a commit date
    // (e.g. "rustc 1.39.0"). Treat this case as non-nightly,
    // since a nightly build should either come from CI
    // or a git checkout
    let nightly_raw = otry!(pieces.next()).split('-').nth(1);
    let nightly = nightly_raw
        .map(|raw| raw.starts_with("dev") || raw.starts_with("nightly"))
        .unwrap_or(false);
    let minor = otry!(otry!(minor).parse().ok());

    Some((minor, nightly))
}

fn which_freebsd() -> Option<i32> {
    let output = std::process::Command::new("freebsd-version").output().ok();
    if output.is_none() {
        return None;
    }
    let output = output.unwrap();
    if !output.status.success() {
        return None;
    }

    let stdout = String::from_utf8(output.stdout).ok();
    if stdout.is_none() {
        return None;
    }
    let stdout = stdout.unwrap();

    match &stdout {
        s if s.starts_with("10") => Some(10),
        s if s.starts_with("11") => Some(11),
        s if s.starts_with("12") => Some(12),
        s if s.starts_with("13") => Some(13),
        s if s.starts_with("14") => Some(14),
        _ => None,
    }
}
<commit_msg>Revert "Fix invalid freebsd version selection"<commit_after>use std::env;
use std::process::Command;
use std::str;

fn main() {
    // Avoid unnecessary re-building.
    println!("cargo:rerun-if-changed=build.rs");

    let (rustc_minor_ver, is_nightly) = rustc_minor_nightly().expect("Failed to get rustc version");
    let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok();
    let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok();
    let const_extern_fn_cargo_feature = env::var("CARGO_FEATURE_CONST_EXTERN_FN").is_ok();
    let libc_ci = env::var("LIBC_CI").is_ok();

    if env::var("CARGO_FEATURE_USE_STD").is_ok() {
        println!(
            "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \
             please consider using the `std` cargo feature instead\""
        );
    }

    // The ABI of libc used by libstd is backward compatible with FreeBSD 10.
    // The ABI of libc from crates.io is backward compatible with FreeBSD 11.
    //
    // On CI, we detect the actual FreeBSD version and match its ABI exactly,
    // running tests to ensure that the ABI is correct.
    match which_freebsd() {
        Some(10) if libc_ci || rustc_dep_of_std => {
            println!("cargo:rustc-cfg=freebsd10")
        }
        Some(11) if libc_ci => println!("cargo:rustc-cfg=freebsd11"),
        Some(12) if libc_ci => println!("cargo:rustc-cfg=freebsd12"),
        Some(13) if libc_ci => println!("cargo:rustc-cfg=freebsd13"),
        Some(14) if libc_ci => println!("cargo:rustc-cfg=freebsd14"),
        Some(_) | None => println!("cargo:rustc-cfg=freebsd11"),
    }

    // On CI: deny all warnings
    if libc_ci {
        println!("cargo:rustc-cfg=libc_deny_warnings");
    }

    // Rust >= 1.15 supports private module use:
    if rustc_minor_ver >= 15 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_priv_mod_use");
    }

    // Rust >= 1.19 supports unions:
    if rustc_minor_ver >= 19 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_union");
    }

    // Rust >= 1.24 supports const mem::size_of:
    if rustc_minor_ver >= 24 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_const_size_of");
    }

    // Rust >= 1.25 supports repr(align):
    if rustc_minor_ver >= 25 || rustc_dep_of_std || align_cargo_feature {
        println!("cargo:rustc-cfg=libc_align");
    }

    // Rust >= 1.30 supports `core::ffi::c_void`, so libc can just re-export it.
    // Otherwise, it defines an incompatible type to retaining
    // backwards-compatibility.
    if rustc_minor_ver >= 30 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_core_cvoid");
    }

    // Rust >= 1.33 supports repr(packed(N)) and cfg(target_vendor).
    if rustc_minor_ver >= 33 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_packedN");
        println!("cargo:rustc-cfg=libc_cfg_target_vendor");
    }

    // Rust >= 1.40 supports #[non_exhaustive].
    if rustc_minor_ver >= 40 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_non_exhaustive");
    }

    if rustc_minor_ver >= 51 || rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_ptr_addr_of");
    }

    // #[thread_local] is currently unstable
    if rustc_dep_of_std {
        println!("cargo:rustc-cfg=libc_thread_local");
    }

    if const_extern_fn_cargo_feature {
        if !is_nightly || rustc_minor_ver < 40 {
            panic!("const-extern-fn requires a nightly compiler >= 1.40")
        }
        println!("cargo:rustc-cfg=libc_const_extern_fn");
    }
}

fn rustc_minor_nightly() -> Option<(u32, bool)> {
    macro_rules! otry {
        ($e:expr) => {
            match $e {
                Some(e) => e,
                None => return None,
            }
        };
    }

    let rustc = otry!(env::var_os("RUSTC"));
    let output = otry!(Command::new(rustc).arg("--version").output().ok());
    let version = otry!(str::from_utf8(&output.stdout).ok());
    let mut pieces = version.split('.');

    if pieces.next() != Some("rustc 1") {
        return None;
    }

    let minor = pieces.next();

    // If `rustc` was built from a tarball, its version string
    // will have neither a git hash nor a commit date
    // (e.g. "rustc 1.39.0"). Treat this case as non-nightly,
    // since a nightly build should either come from CI
    // or a git checkout
    let nightly_raw = otry!(pieces.next()).split('-').nth(1);
    let nightly = nightly_raw
        .map(|raw| raw.starts_with("dev") || raw.starts_with("nightly"))
        .unwrap_or(false);
    let minor = otry!(otry!(minor).parse().ok());

    Some((minor, nightly))
}

fn which_freebsd() -> Option<i32> {
    let output = std::process::Command::new("freebsd-version").output().ok();
    if output.is_none() {
        return None;
    }
    let output = output.unwrap();
    if !output.status.success() {
        return None;
    }

    let stdout = String::from_utf8(output.stdout).ok();
    if stdout.is_none() {
        return None;
    }
    let stdout = stdout.unwrap();

    match &stdout {
        s if s.starts_with("10") => Some(10),
        s if s.starts_with("11") => Some(11),
        s if s.starts_with("12") => Some(12),
        s if s.starts_with("13") => Some(13),
        s if s.starts_with("14") => Some(14),
        _ => None,
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "gen")]
extern crate bindgen;

#[cfg(feature = "gen")]
fn gen() {
    use std::env;
    use std::path::PathBuf;
    let bindings = bindgen::Builder::default()
        .header("darknet-sys/include/darknet.h")
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

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

fn main() {
    gen();

    println!("cargo:rustc-link-lib=darknet");

    if cfg!(feature = "nnpack") {
        println!("cargo:rustc-link-lib=nnpack");
        println!("cargo:rustc-link-lib=pthreadpool");
        println!("cargo:rustc-link-lib=pthread");
    }

    if cfg!(feature = "cuda") {
        println!("cargo:rustc-link-search=native=/usr/local/cuda/lib");
        println!("cargo:rustc-link-lib=cuda");
        println!("cargo:rustc-link-lib=cudart");
        println!("cargo:rustc-link-lib=cublas");
        println!("cargo:rustc-link-lib=curand");
    }
}
<commit_msg>cuda search lib64 as well<commit_after>#[cfg(feature = "gen")]
extern crate bindgen;

#[cfg(feature = "gen")]
fn gen() {
    use std::env;
    use std::path::PathBuf;
    let bindings = bindgen::Builder::default()
        .header("darknet-sys/include/darknet.h")
        .generate()
        .expect("Unable to generate bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");
}

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

fn main() {
    gen();

    println!("cargo:rustc-link-lib=darknet");

    if cfg!(feature = "nnpack") {
        println!("cargo:rustc-link-lib=nnpack");
        println!("cargo:rustc-link-lib=pthreadpool");
        println!("cargo:rustc-link-lib=pthread");
    }

    if cfg!(feature = "cuda") {
        println!("cargo:rustc-link-search=native=/usr/local/cuda/lib");
        println!("cargo:rustc-link-search=native=/usr/local/cuda/lib64");
        println!("cargo:rustc-link-lib=cuda");
        println!("cargo:rustc-link-lib=cudart");
        println!("cargo:rustc-link-lib=cublas");
        println!("cargo:rustc-link-lib=curand");
    }
}
<|endoftext|>


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

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;

fn main() {
    let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());

    File::create(out_dir.join("commit-info.txt"))
        .unwrap()
        .write_all(commit_info().as_bytes())
        .unwrap();
}

// Try to get hash and date of the last commit on a best effort basis. If anything goes wrong
// (git not installed or if this is not a git repository) just return an empty string.
fn commit_info() -> String {
    match (channel(), commit_hash(), commit_date()) {
        (channel, Some(hash), Some(date)) => {
            format!("{} ({} {})", channel, hash.trim_right(), date)
        }
        _ => String::new(),
    }
}

fn channel() -> String {
    if let Ok(channel) = env::var("CFG_RELEASE_CHANNEL") {
        channel
    } else {
        "nightly".to_owned()
    }
}

fn commit_hash() -> Option<String> {
    Command::new("git")
        .args(&["rev-parse", "--short", "HEAD"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}

fn commit_date() -> Option<String> {
    Command::new("git")
        .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}
<commit_msg>Rerun build.rs only when .git/HEAD or CFG_RELEASE_CHANNEL is changed<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;

fn main() {
    println!("cargo:rerun-if-changed=.git/HEAD");
    println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL");

    let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());

    File::create(out_dir.join("commit-info.txt"))
        .unwrap()
        .write_all(commit_info().as_bytes())
        .unwrap();
}

// Try to get hash and date of the last commit on a best effort basis. If anything goes wrong
// (git not installed or if this is not a git repository) just return an empty string.
fn commit_info() -> String {
    match (channel(), commit_hash(), commit_date()) {
        (channel, Some(hash), Some(date)) => {
            format!("{} ({} {})", channel, hash.trim_right(), date)
        }
        _ => String::new(),
    }
}

fn channel() -> String {
    if let Ok(channel) = env::var("CFG_RELEASE_CHANNEL") {
        channel
    } else {
        "nightly".to_owned()
    }
}

fn commit_hash() -> Option<String> {
    Command::new("git")
        .args(&["rev-parse", "--short", "HEAD"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}

fn commit_date() -> Option<String> {
    Command::new("git")
        .args(&["log", "-1", "--date=short", "--pretty=format:%cd"])
        .output()
        .ok()
        .and_then(|r| String::from_utf8(r.stdout).ok())
}
<|endoftext|>


<commit_before>extern crate cheddar;
#[cfg(windows)]
extern crate winres;

use std::env;
use std::path::MAIN_SEPARATOR;

fn build_header_file() {
    let profile = env::var("PROFILE").unwrap();

    cheddar::Cheddar::new()
        .expect("could not read manifest")
        .run_build(
            "target".to_owned() + &MAIN_SEPARATOR.to_string() + &profile +
                &MAIN_SEPARATOR.to_string() + "ctehxk2.h",
        );
}

#[cfg(windows)]
fn main() {
    build_header_file();

    if cfg!(target_os = "windows") {
        let res = winres::WindowsResource::new();
        res.compile().unwrap();
    }
}

#[cfg(not(windows))]
fn main() {
    build_header_file();
}
<commit_msg>use format to build header file in target folder<commit_after>extern crate cheddar;
#[cfg(windows)]
extern crate winres;

use std::env;
use std::path::MAIN_SEPARATOR;

fn build_header_file() {
    let target = format!("{}{}{}{}{}",
        "target".to_owned(),
        MAIN_SEPARATOR.to_string(),
        env::var("PROFILE").unwrap(),
        MAIN_SEPARATOR.to_string(),
        "ctehxk2.h"
    );

    cheddar::Cheddar::new()
        .expect("could not read manifest")
        .run_build(target);
}

#[cfg(windows)]
fn main() {
    build_header_file();

    if cfg!(target_os = "windows") {
        let res = winres::WindowsResource::new();
        res.compile().unwrap();
    }
}

#[cfg(not(windows))]
fn main() {
    build_header_file();
}
<|endoftext|>


<commit_before>use std::os;
use std::old_io::fs::PathExtensions;

const LINUX_CLANG_DIRS: &'static [&'static str] = &["/usr/lib", "/usr/lib/llvm", "/usr/lib64/llvm"];
const MAC_CLANG_DIR: &'static str = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib";

fn main() {
    let possible_clang_dirs = if let Some(dir) = os::getenv("LIBCLANG_PATH") {
        vec![dir]
    } else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
        LINUX_CLANG_DIRS.iter().map(ToString::to_string).collect()
    } else if cfg!(target_os = "macos") {
        vec![MAC_CLANG_DIR.to_string()]
    } else {
        panic!("Platform not supported");
    };

    let clang_lib = os::dll_filename("clang");

    let maybe_clang_dir = possible_clang_dirs.into_iter().filter_map(|candidate_dir| {
        let clang_dir = Path::new(candidate_dir);
        let clang_path = clang_dir.join(clang_lib.clone());

        if clang_path.exists() {
            Some(clang_dir)
        } else {
            None
        }
    }).next();

    if let Some(clang_dir) = maybe_clang_dir {
        println!("cargo:rustc-flags=-l clang -L {}", clang_dir.as_str().unwrap());
    } else {
        panic!("Unable to find {}", clang_lib);
    }
}
<commit_msg>Solve warnings on build script<commit_after>#![feature(path, io, env)]

use std::env;
use std::old_io::fs::PathExtensions;

const LINUX_CLANG_DIRS: &'static [&'static str] = &["/usr/lib", "/usr/lib/llvm", "/usr/lib64/llvm"];
const MAC_CLANG_DIR: &'static str = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib";

fn main() {
    let possible_clang_dirs = if let Ok(dir) = env::var_string("LIBCLANG_PATH") {
        vec![dir]
    } else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
        LINUX_CLANG_DIRS.iter().map(ToString::to_string).collect()
    } else if cfg!(target_os = "macos") {
        vec![MAC_CLANG_DIR.to_string()]
    } else {
        panic!("Platform not supported");
    };

    let clang_lib = format!("{}clang{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX);

    let maybe_clang_dir = possible_clang_dirs.into_iter().filter_map(|candidate_dir| {
        let clang_dir = Path::new(candidate_dir);
        let clang_path = clang_dir.join(clang_lib.clone());

        if clang_path.exists() {
            Some(clang_dir)
        } else {
            None
        }
    }).next();

    if let Some(clang_dir) = maybe_clang_dir {
        println!("cargo:rustc-flags=-l clang -L {}", clang_dir.as_str().unwrap());
    } else {
        panic!("Unable to find {}", clang_lib);
    }
}
<|endoftext|>


<commit_before>extern crate pkg_config;

fn main() {
    match pkg_config::find_library("freetype2") {
        Ok(_) => return,
        Err(_) => {
            if cfg!(windows) {
                println!("cargo:rustc-link-lib=dylib=freetype-6");
            } else {
                println!("cargo:rustc-link-lib=dylib=freetype");
            }
        }
    }
}
<commit_msg>Remove "-6" suffix<commit_after>extern crate pkg_config;

fn main() {
    match pkg_config::find_library("freetype2") {
        Ok(_) => return,
        Err(_) => {
            println!("cargo:rustc-link-lib=dylib=freetype");
        }
    }
}
<|endoftext|>