<commit_before>extern crate pkg_config;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Illumos/Solaris requires explicit linking with libnsl
    if target.contains("solaris") {
        println!("cargo:rustc-flags=-l nsl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if try_vcpkg() {
        return;
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-link-lib=ws2_32");
        println!("cargo:rustc-link-lib=crypt32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let openssl_root = register_dep("OPENSSL");
    let zlib_root = register_dep("Z");
    let nghttp2_root = register_dep("NGHTTP2");

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    // For now this build script doesn't support paths with spaces in them. This
    // is arguably a but in curl's configure script, but we could also try to
    // paper over it by using a tmp directory which *doesn't* have spaces in it.
    // As of now though that's not implemented so just give a nicer error for
    // the time being.
    let wants_space_error = windows &&
        (dst.to_str().map(|s| s.contains(" ")).unwrap_or(false) ||
         src.to_str().map(|s| s.contains(" ")).unwrap_or(false));
    if wants_space_error {
        panic!("\n\nunfortunately ./configure of libcurl is known to \
                fail if there's a space in the path to the current \
                directory\n\n\
                there's a space in either\n  {}\n  {}\nand this will cause the \
                build to fail\n\n\
                the MSVC build should work with a directory that has \
                spaces in it, and it would also work to move this to a \
                different directory without spaces\n\n",
               src.display(), dst.display())
    }

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");
    }
    if let Some(root) = openssl_root {
        cmd.arg(format!("--with-ssl={}", msys_compatible(&root)));
    }
    if let Some(root) = zlib_root {
        cmd.arg(format!("--with-zlib={}", msys_compatible(&root)));
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        // NOTE GNU terminology
        // BUILD = machine where we are (cross) compiling curl
        // HOST = machine where the compiled curl will be used
        // TARGET = only relevant when compiling compilers
        if target.contains("windows") {
            // curl's configure can't parse `-windows-` triples when used
            // as `--host`s. In those cases we use this combination of
            // `host` and `target` that appears to do the right thing.
            cmd.arg(format!("--host={}", host));
            cmd.arg(format!("--target={}", target));
        } else {
            cmd.arg(format!("--build={}", host));
            cmd.arg(format!("--host={}", target));
        }
    }

    if let Some(root) = nghttp2_root {
        cmd.arg(format!("--with-nghttp2={}", msys_compatible(&root)));
    } else {
        cmd.arg("--without-nghttp2");
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-libpsl");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-unix-sockets");
    cmd.arg("--disable-versioned-symbols");
    cmd.arg("--enable-hidden-symbols");
    cmd.arg("--disable-libcurl-option");

    run(&mut cmd, "sh");
    run(make()
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(make()
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> Command {
    let cmd = if cfg!(target_os = "freebsd") {"gmake"} else {"make"};
    let mut cmd = Command::new(cmd);
    // We're using the MSYS make which doesn't work with the mingw32-make-style
    // MAKEFLAGS, so remove that from the env if present.
    if cfg!(windows) {
        cmd.env_remove("MAKEFLAGS").env_remove("MFLAGS");
    }
    return cmd
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn register_dep(dep: &str) -> Option<PathBuf> {
    if let Some(s) = env::var_os(&format!("DEP_{}_ROOT", dep)) {
        prepend("PKG_CONFIG_PATH", Path::new(&s).join("lib/pkgconfig"));
        return Some(s.into())
    }
    if let Some(s) = env::var_os(&format!("DEP_{}_INCLUDE", dep)) {
        let root = Path::new(&s).parent().unwrap();
        env::set_var(&format!("DEP_{}_ROOT", dep), root);
        let path = root.join("lib/pkgconfig");
        if path.exists() {
            prepend("PKG_CONFIG_PATH", path);
            return Some(root.to_path_buf())
        }
    }

    return None;

    fn prepend(var: &str, val: PathBuf) {
        let prefix = env::var(var).unwrap_or(String::new());
        let mut v = vec![val];
        v.extend(env::split_paths(&prefix));
        env::set_var(var, &env::join_paths(v).unwrap());
    }
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    cmd.current_dir(src.join("curl/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    // These env vars are intended for `make` usually, not nmake, so remove them
    // unconditionally
    cmd.env_remove("MAKEFLAGS")
       .env_remove("MFLAGS");

    let features = env::var("CARGO_CFG_TARGET_FEATURE")
                      .unwrap_or(String::new());
    if features.contains("crt-static") {
        cmd.arg("RTLIBCFG=static");
    }

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::copy(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = src.join("curl/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(src.join("curl/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}

#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() -> bool {
    false
}

#[cfg(target_env = "msvc")]
fn try_vcpkg() -> bool {

    // the import library for the dll is called libcurl_imp
    let mut successful_probe_details =
        match vcpkg::Config::new().lib_names("libcurl_imp", "libcurl")
                .emit_includes(true).probe("curl") {
            Ok(details) => Some(details),
            Err(e) => {
                println!("first run of vcpkg did not find libcurl: {}", e);
                None
            }
        };

    if successful_probe_details.is_none() {
        match vcpkg::Config::new().lib_name("libcurl")
                .emit_includes(true).probe("curl") {
            Ok(details) => successful_probe_details = Some(details),
            Err(e) => println!("second run of vcpkg did not find libcurl: {}", e),
        }
    }

    if successful_probe_details.is_some() {
        // Found libcurl which depends on openssl, libssh2 and zlib
        // in the a default vcpkg installation. Probe for them
        // but do not fail if they are not present as we may be working
        // with a customized vcpkg installation.
        vcpkg::Config::new()
            .lib_name("libeay32")
            .lib_name("ssleay32")
            .probe("openssl").ok();

        vcpkg::probe_package("libssh2").ok();

        vcpkg::Config::new()
            .lib_names("zlib", "zlib1")
            .probe("zlib").ok();

        println!("cargo:rustc-link-lib=crypt32");
        println!("cargo:rustc-link-lib=gdi32");
        println!("cargo:rustc-link-lib=user32");
        println!("cargo:rustc-link-lib=wldap32");
        return true;
    }
    false
}
<commit_msg>Copy src files into OUT_DIR on msvc<commit_after>extern crate pkg_config;
#[cfg(target_env = "msvc")]
extern crate vcpkg;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Illumos/Solaris requires explicit linking with libnsl
    if target.contains("solaris") {
        println!("cargo:rustc-flags=-l nsl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if try_vcpkg() {
        return;
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search=native={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-link-lib=ws2_32");
        println!("cargo:rustc-link-lib=crypt32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let openssl_root = register_dep("OPENSSL");
    let zlib_root = register_dep("Z");
    let nghttp2_root = register_dep("NGHTTP2");

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    // For now this build script doesn't support paths with spaces in them. This
    // is arguably a but in curl's configure script, but we could also try to
    // paper over it by using a tmp directory which *doesn't* have spaces in it.
    // As of now though that's not implemented so just give a nicer error for
    // the time being.
    let wants_space_error = windows &&
        (dst.to_str().map(|s| s.contains(" ")).unwrap_or(false) ||
         src.to_str().map(|s| s.contains(" ")).unwrap_or(false));
    if wants_space_error {
        panic!("\n\nunfortunately ./configure of libcurl is known to \
                fail if there's a space in the path to the current \
                directory\n\n\
                there's a space in either\n  {}\n  {}\nand this will cause the \
                build to fail\n\n\
                the MSVC build should work with a directory that has \
                spaces in it, and it would also work to move this to a \
                different directory without spaces\n\n",
               src.display(), dst.display())
    }

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");
    }
    if let Some(root) = openssl_root {
        cmd.arg(format!("--with-ssl={}", msys_compatible(&root)));
    }
    if let Some(root) = zlib_root {
        cmd.arg(format!("--with-zlib={}", msys_compatible(&root)));
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        // NOTE GNU terminology
        // BUILD = machine where we are (cross) compiling curl
        // HOST = machine where the compiled curl will be used
        // TARGET = only relevant when compiling compilers
        if target.contains("windows") {
            // curl's configure can't parse `-windows-` triples when used
            // as `--host`s. In those cases we use this combination of
            // `host` and `target` that appears to do the right thing.
            cmd.arg(format!("--host={}", host));
            cmd.arg(format!("--target={}", target));
        } else {
            cmd.arg(format!("--build={}", host));
            cmd.arg(format!("--host={}", target));
        }
    }

    if let Some(root) = nghttp2_root {
        cmd.arg(format!("--with-nghttp2={}", msys_compatible(&root)));
    } else {
        cmd.arg("--without-nghttp2");
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-libpsl");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-unix-sockets");
    cmd.arg("--disable-versioned-symbols");
    cmd.arg("--enable-hidden-symbols");
    cmd.arg("--disable-libcurl-option");

    run(&mut cmd, "sh");
    run(make()
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(make()
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> Command {
    let cmd = if cfg!(target_os = "freebsd") {"gmake"} else {"make"};
    let mut cmd = Command::new(cmd);
    // We're using the MSYS make which doesn't work with the mingw32-make-style
    // MAKEFLAGS, so remove that from the env if present.
    if cfg!(windows) {
        cmd.env_remove("MAKEFLAGS").env_remove("MFLAGS");
    }
    return cmd
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn register_dep(dep: &str) -> Option<PathBuf> {
    if let Some(s) = env::var_os(&format!("DEP_{}_ROOT", dep)) {
        prepend("PKG_CONFIG_PATH", Path::new(&s).join("lib/pkgconfig"));
        return Some(s.into())
    }
    if let Some(s) = env::var_os(&format!("DEP_{}_INCLUDE", dep)) {
        let root = Path::new(&s).parent().unwrap();
        env::set_var(&format!("DEP_{}_ROOT", dep), root);
        let path = root.join("lib/pkgconfig");
        if path.exists() {
            prepend("PKG_CONFIG_PATH", path);
            return Some(root.to_path_buf())
        }
    }

    return None;

    fn prepend(var: &str, val: PathBuf) {
        let prefix = env::var(var).unwrap_or(String::new());
        let mut v = vec![val];
        v.extend(env::split_paths(&prefix));
        env::set_var(var, &env::join_paths(v).unwrap());
    }
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    drop(fs::remove_dir_all(&dst.join("build")));
    cp_r(&src.join("curl"), &dst.join("build"));
    cmd.current_dir(dst.join("build/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    // These env vars are intended for `make` usually, not nmake, so remove them
    // unconditionally
    cmd.env_remove("MAKEFLAGS")
       .env_remove("MFLAGS");

    let features = env::var("CARGO_CFG_TARGET_FEATURE")
                      .unwrap_or(String::new());
    if features.contains("crt-static") {
        cmd.arg("RTLIBCFG=static");
    }

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::copy(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = dst.join("build/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(dst.join("build/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}

#[cfg(not(target_env = "msvc"))]
fn try_vcpkg() -> bool {
    false
}

#[cfg(target_env = "msvc")]
fn try_vcpkg() -> bool {

    // the import library for the dll is called libcurl_imp
    let mut successful_probe_details =
        match vcpkg::Config::new().lib_names("libcurl_imp", "libcurl")
                .emit_includes(true).probe("curl") {
            Ok(details) => Some(details),
            Err(e) => {
                println!("first run of vcpkg did not find libcurl: {}", e);
                None
            }
        };

    if successful_probe_details.is_none() {
        match vcpkg::Config::new().lib_name("libcurl")
                .emit_includes(true).probe("curl") {
            Ok(details) => successful_probe_details = Some(details),
            Err(e) => println!("second run of vcpkg did not find libcurl: {}", e),
        }
    }

    if successful_probe_details.is_some() {
        // Found libcurl which depends on openssl, libssh2 and zlib
        // in the a default vcpkg installation. Probe for them
        // but do not fail if they are not present as we may be working
        // with a customized vcpkg installation.
        vcpkg::Config::new()
            .lib_name("libeay32")
            .lib_name("ssleay32")
            .probe("openssl").ok();

        vcpkg::probe_package("libssh2").ok();

        vcpkg::Config::new()
            .lib_names("zlib", "zlib1")
            .probe("zlib").ok();

        println!("cargo:rustc-link-lib=crypt32");
        println!("cargo:rustc-link-lib=gdi32");
        println!("cargo:rustc-link-lib=user32");
        println!("cargo:rustc-link-lib=wldap32");
        return true;
    }
    false
}

fn cp_r(src: &Path, dst: &Path) {
    t!(fs::create_dir(dst));
    for e in t!(src.read_dir()).map(|e| t!(e)) {
        let src = e.path();
        let dst = dst.join(e.file_name());
        if t!(e.file_type()).is_dir() {
            cp_r(&src, &dst);
        } else {
            t!(fs::copy(&src, &dst));
        }
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Nicholas Juszczak <juszczakn@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::os;
use std::io::fs;
use std::io::FilePermission;
use std::num::strconv;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "mkdir";
static VERSION: &'static str = "1.0.0";

/**
 * Handles option parsing
 */
fn main() {
    let args: Vec<StrBuf> = os::args().iter().map(|x| x.to_strbuf()).collect();

    let opts = ~[
        // Linux-specific options, not implemented
        // getopts::optflag("Z", "context", "set SELinux secutiry context" +
        // " of each created directory to CTX"),
        getopts::optopt("m", "mode", "set file mode", "755"),
        getopts::optflag("p", "parents", "make parent directories as needed"),
        getopts::optflag("v", "verbose",
                        "print a message for each printed directory"),
        getopts::optflag("h", "help", "display this help"),
        getopts::optflag("V", "version", "display this version")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            crash!(1, "Invalid options\n{}", f.to_err_msg());
        }
    };

    if args.len() == 1 || matches.opt_present("help") {
        print_help(opts);
        return;
    }
    if matches.opt_present("version") {
        println!("mkdir v{}", VERSION);
        return;
    }
    let verbose_flag = matches.opt_present("verbose");
    let mk_parents = matches.opt_present("parents");

    // Translate a ~str in octal form to u32, default to 755
    // Not tested on Windows
    let mode_match = matches.opts_str(&["mode".to_strbuf()]);
    let mode: FilePermission = if mode_match.is_some() {
        let m = mode_match.unwrap();
        let res: Option<u32> = strconv::from_str_common(m.as_slice(), 8, false, false, false,
                                                        strconv::ExpNone,
                                                        false, false);
        if res.is_some() {
            unsafe { std::mem::transmute(res.unwrap()) }
        } else {
            crash!(1, "no mode given");
        }
    } else {
        unsafe { std::mem::transmute(0o755 as u32) }
    };

    let dirs = matches.free;
    exec(dirs, mk_parents, mode, verbose_flag);
}

fn print_help(opts: &[getopts::OptGroup]) {
    println!("mkdir v{} - make a new directory with the given path", VERSION);
    println!("");
    println!("Usage:");
    print!("{}", getopts::usage("Create the given DIRECTORY(ies)" +
                               " if they do not exist", opts));
}

/**
 * Create the list of new directories
 */
fn exec(dirs: Vec<StrBuf>, mk_parents: bool, mode: FilePermission, verbose: bool) {
    let mut parent_dirs = Vec::new();
    if mk_parents {
        for dir in dirs.iter() {
            let path = Path::new((*dir).clone());
            // Build list of parent dirs which need to be created
            let parent = path.dirname_str();
            match parent {
                Some(p) => {
                    if !Path::new(p).exists() {
                        parent_dirs.push(p.to_strbuf())
                    }
                },
                None => ()
            }
        }
    }
    // Recursively build parent dirs that are needed
    if !parent_dirs.is_empty() {
        exec(parent_dirs, mk_parents, mode, verbose);
    }

    for dir in dirs.iter() {
        let path = Path::new((*dir).clone());
        // Determine if parent directory to the one to
        // be created exists
        let parent = match path.dirname_str() {
            Some(p) => p,
            None => ""
        };
        let parent_exists = Path::new(parent).exists();
        if parent_exists && !path.exists() {
            mkdir(&path, mode);
            if verbose {println!("{}", *dir);}
        } else if !mk_parents {
            let error_msg =
                if !parent_exists {
                    format!("parent directory '{}' does not exist", parent)
                } else {
                    format!("directory '{}' already exists", *dir)
                };
            show_error!(1, "{}", error_msg);
        }
    }
}

/**
 * Wrapper to catch errors, return false if failed
 */
fn mkdir(path: &Path, mode: FilePermission) {
    match fs::mkdir(path, mode) {
        Ok(_) => {},
        Err(e) => {
            crash!(1, "test {}", e.to_str());
        }
    }
}
<commit_msg>mkdir: exit with error if no directory given<commit_after>#![crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Nicholas Juszczak <juszczakn@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

#![feature(macro_rules)]

extern crate getopts;
extern crate libc;

use std::os;
use std::io::fs;
use std::io::FilePermission;
use std::num::strconv;

#[path = "../common/util.rs"]
mod util;

static NAME: &'static str = "mkdir";
static VERSION: &'static str = "1.0.0";

/**
 * Handles option parsing
 */
fn main() {
    let args: Vec<StrBuf> = os::args().iter().map(|x| x.to_strbuf()).collect();

    let opts = ~[
        // Linux-specific options, not implemented
        // getopts::optflag("Z", "context", "set SELinux secutiry context" +
        // " of each created directory to CTX"),
        getopts::optopt("m", "mode", "set file mode", "755"),
        getopts::optflag("p", "parents", "make parent directories as needed"),
        getopts::optflag("v", "verbose",
                        "print a message for each printed directory"),
        getopts::optflag("h", "help", "display this help"),
        getopts::optflag("V", "version", "display this version")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => {
            crash!(1, "Invalid options\n{}", f.to_err_msg());
        }
    };

    if args.len() == 1 || matches.opt_present("help") {
        print_help(opts);
        return;
    }
    if matches.opt_present("version") {
        println!("mkdir v{}", VERSION);
        return;
    }
    let verbose_flag = matches.opt_present("verbose");
    let mk_parents = matches.opt_present("parents");

    // Translate a ~str in octal form to u32, default to 755
    // Not tested on Windows
    let mode_match = matches.opts_str(&["mode".to_strbuf()]);
    let mode: FilePermission = if mode_match.is_some() {
        let m = mode_match.unwrap();
        let res: Option<u32> = strconv::from_str_common(m.as_slice(), 8, false, false, false,
                                                        strconv::ExpNone,
                                                        false, false);
        if res.is_some() {
            unsafe { std::mem::transmute(res.unwrap()) }
        } else {
            crash!(1, "no mode given");
        }
    } else {
        unsafe { std::mem::transmute(0o755 as u32) }
    };

    let dirs = matches.free;
    if dirs.is_empty() {
        crash!(1, "missing operand");
    }
    exec(dirs, mk_parents, mode, verbose_flag);
}

fn print_help(opts: &[getopts::OptGroup]) {
    println!("mkdir v{} - make a new directory with the given path", VERSION);
    println!("");
    println!("Usage:");
    print!("{}", getopts::usage("Create the given DIRECTORY(ies)" +
                               " if they do not exist", opts));
}

/**
 * Create the list of new directories
 */
fn exec(dirs: Vec<StrBuf>, mk_parents: bool, mode: FilePermission, verbose: bool) {
    let mut parent_dirs = Vec::new();
    if mk_parents {
        for dir in dirs.iter() {
            let path = Path::new((*dir).clone());
            // Build list of parent dirs which need to be created
            let parent = path.dirname_str();
            match parent {
                Some(p) => {
                    if !Path::new(p).exists() {
                        parent_dirs.push(p.to_strbuf())
                    }
                },
                None => ()
            }
        }
    }
    // Recursively build parent dirs that are needed
    if !parent_dirs.is_empty() {
        exec(parent_dirs, mk_parents, mode, verbose);
    }

    for dir in dirs.iter() {
        let path = Path::new((*dir).clone());
        // Determine if parent directory to the one to
        // be created exists
        let parent = match path.dirname_str() {
            Some(p) => p,
            None => ""
        };
        let parent_exists = Path::new(parent).exists();
        if parent_exists && !path.exists() {
            mkdir(&path, mode);
            if verbose {println!("{}", *dir);}
        } else if !mk_parents {
            let error_msg =
                if !parent_exists {
                    format!("parent directory '{}' does not exist", parent)
                } else {
                    format!("directory '{}' already exists", *dir)
                };
            show_error!(1, "{}", error_msg);
        }
    }
}

/**
 * Wrapper to catch errors, return false if failed
 */
fn mkdir(path: &Path, mode: FilePermission) {
    match fs::mkdir(path, mode) {
        Ok(_) => {},
        Err(e) => {
            crash!(1, "test {}", e.to_str());
        }
    }
}
<|endoftext|>


<commit_before>// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

extern mod std;
extern mod zmq;

use dvec::DVec;

fn server(ctx: zmq::Context, ch: comm::Chan<()>, workers: uint) {
    let mut workers = workers;

    let pull_socket = match ctx.socket(zmq::PULL) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match pull_socket.bind("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    match push_socket.bind("tcp://127.0.0.1:3457") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    // Let the main thread know we're ready.
    ch.send(());

    let mut count = 0u;
    while workers != 0 {
        match pull_socket.recv(0) {
            Err(e) => fail e.to_str(),
            Ok(msg) => {
                do msg.with_str |s| {
                    if s == "" {
                        workers -= 1;
                    } else {
                        count += uint::from_str(s).get();
                    }
                }
            }
        }
    }

    match push_socket.send_str(uint::str(count), 0) {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    pull_socket.close();
    push_socket.close();

    ch.send(());
}

fn worker(ctx: zmq::Context, count: uint) {
    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match push_socket.connect("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    for count.times {
        match push_socket.send_str(uint::str(100u), 0) {
          Ok(()) => { }
          Err(e) => fail e.to_str(),
        }
    }

    // Let the server know we're done.
    match push_socket.send_str("", 0) {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    push_socket.close();
}

fn run(ctx: zmq::Context, size: uint, workers: uint) {
    // Spawn the server.
    let po = comm::Port();
    let ch = comm::Chan(&po);
    do task::spawn_sched(task::SingleThreaded) {
        server(ctx, ch, workers);
    }

    // Wait for the server to start.
    po.recv();

    // Create some command/control sockets.
    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match push_socket.connect("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    let pull_socket = match ctx.socket(zmq::PULL) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match pull_socket.connect("tcp://127.0.0.1:3457") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    let start = std::time::precise_time_s();

    // Spawn all the workers.
    let mut worker_results = ~[];

    for workers.times {
        let po = comm::Port();
        let ch = comm::Chan(&po);

        worker_results.push(po);

        do task::spawn_sched(task::SingleThreaded) {
            worker(ctx, size / workers);
            ch.send(());
        }
    }

    // Block until all the workers finish.
    for worker_results.each |po| { po.recv(); }

    /*
    // Shut down the server.
    push_socket.send_str("stop", 0);
    match push_socket.close() {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }
    */

    po.recv();

    // Receive the final count.
    let result = match pull_socket.recv(0) {
      Ok(msg) => msg.with_str(|s| uint::from_str(s).get()),
      Err(e) => fail e.to_str(),
    };

    let end = std::time::precise_time_s();
    let elapsed = end - start;

    io::println(#fmt("Count is %?", result));
    io::println(#fmt("Test took %? seconds", elapsed));
    let thruput = ((size / workers * workers) as float) / (elapsed as float);
    io::println(#fmt("Throughput=%f per sec", thruput));
}

fn main() {
    let args = os::args();

    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"1000000", ~"10000"]
    } else if args.len() <= 1u {
        ~[~"", ~"10000", ~"4"]
    } else {
        args
    };

    let size = uint::from_str(args[1]).get();
    let workers = uint::from_str(args[2]).get();

    let ctx = match zmq::init(1) {
      Ok(ctx) => ctx,
      Err(e) => fail e.to_str(),
    };

    run(ctx, size, workers);

    match ctx.term() {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    };
}
<commit_msg>Update msgsend-zmq to 0.5-rc<commit_after>// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

extern mod std;
extern mod zmq;

use dvec::DVec;

fn server(ctx: zmq::Context, ch: oldcomm::Chan<()>, workers: uint) {
    let mut workers = workers;

    let pull_socket = match ctx.socket(zmq::PULL) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match pull_socket.bind("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    match push_socket.bind("tcp://127.0.0.1:3457") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    // Let the main thread know we're ready.
    ch.send(());

    let mut count = 0u;
    while workers != 0 {
        match pull_socket.recv(0) {
            Err(e) => fail e.to_str(),
            Ok(msg) => {
                do msg.with_str |s| {
                    if s == "" {
                        workers -= 1;
                    } else {
                        count += uint::from_str(s).get();
                    }
                }
            }
        }
    }

    match push_socket.send_str(uint::str(count), 0) {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    pull_socket.close();
    push_socket.close();

    ch.send(());
}

fn worker(ctx: zmq::Context, count: uint) {
    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match push_socket.connect("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    for count.times {
        match push_socket.send_str(uint::str(100u), 0) {
          Ok(()) => { }
          Err(e) => fail e.to_str(),
        }
    }

    // Let the server know we're done.
    match push_socket.send_str("", 0) {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    push_socket.close();
}

fn run(ctx: zmq::Context, size: uint, workers: uint) {
    // Spawn the server.
    let po = oldcomm::Port();
    let ch = oldcomm::Chan(&po);
    do task::spawn_sched(task::SingleThreaded) {
        server(ctx, ch, workers);
    }

    // Wait for the server to start.
    po.recv();

    // Create some oldcommand/control sockets.
    let push_socket = match ctx.socket(zmq::PUSH) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match push_socket.connect("tcp://127.0.0.1:3456") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    let pull_socket = match ctx.socket(zmq::PULL) {
      Ok(move socket) => socket,
      Err(e) => fail e.to_str(),
    };

    match pull_socket.connect("tcp://127.0.0.1:3457") {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }

    let start = std::time::precise_time_s();

    // Spawn all the workers.
    let mut worker_results = ~[];

    for workers.times {
        let po = oldcomm::Port();
        let ch = oldcomm::Chan(&po);

        worker_results.push(po);

        do task::spawn_sched(task::SingleThreaded) {
            worker(ctx, size / workers);
            ch.send(());
        }
    }

    // Block until all the workers finish.
    for worker_results.each |po| { po.recv(); }

    /*
    // Shut down the server.
    push_socket.send_str("stop", 0);
    match push_socket.close() {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    }
    */

    po.recv();

    // Receive the final count.
    let result = match pull_socket.recv(0) {
      Ok(msg) => msg.with_str(|s| uint::from_str(s).get()),
      Err(e) => fail e.to_str(),
    };

    let end = std::time::precise_time_s();
    let elapsed = end - start;

    io::println(fmt!("Count is %?", result));
    io::println(fmt!("Test took %? seconds", elapsed));
    let thruput = ((size / workers * workers) as float) / (elapsed as float);
    io::println(fmt!("Throughput=%f per sec", thruput));
}

fn main() {
    let args = os::args();

    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"1000000", ~"10000"]
    } else if args.len() <= 1u {
        ~[~"", ~"10000", ~"4"]
    } else {
        args
    };

    let size = uint::from_str(args[1]).get();
    let workers = uint::from_str(args[2]).get();

    let ctx = match zmq::init(1) {
      Ok(ctx) => ctx,
      Err(e) => fail e.to_str(),
    };

    run(ctx, size, workers);

    match ctx.term() {
      Ok(()) => { }
      Err(e) => fail e.to_str(),
    };
}
<|endoftext|>


<commit_before>// -*- rust -*-

type point = rec(int x, int y, mutable int z);

fn f(@point p) {
  check (p.z == 12);
  p.z = 13;
  check (p.z == 13);
}

fn main() {
  let point a = rec(x=10, y=11, z=mutable 12);
  let @point b = a;
  check (b.z == 12);
  f(b);
  check (a.z == 12);
  check (b.z == 13);
}
<commit_msg>No more "transplant" behavior in "let @x = y", gotta box explicitly.<commit_after>// -*- rust -*-

type point = rec(int x, int y, mutable int z);

fn f(@point p) {
  check (p.z == 12);
  p.z = 13;
  check (p.z == 13);
}

fn main() {
  let point a = rec(x=10, y=11, z=mutable 12);
  let @point b = @a;
  check (b.z == 12);
  f(b);
  check (a.z == 12);
  check (b.z == 13);
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::io;
use std::net::SocketAddr;

use tokio::io::AsyncRead;
use tokio::io::AsyncWrite;

use crate::socket_unix::SocketAddrUnix;
use crate::ServerConf;
use futures::stream::Stream;
use futures::Future;
use std::pin::Pin;
use tokio::runtime::Handle;

pub trait ToSocketListener {
    fn to_listener(&self, conf: &ServerConf) -> io::Result<Box<dyn ToTokioListener + Send>>;

    fn cleanup(&self);
}

#[derive(Clone, Debug, PartialEq)]
pub enum AnySocketAddr {
    Inet(SocketAddr),
    Unix(SocketAddrUnix),
}

impl Display for AnySocketAddr {
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        match *self {
            AnySocketAddr::Inet(ref inet_addr) => Display::fmt(inet_addr, f),
            AnySocketAddr::Unix(ref unix_addr) => Display::fmt(unix_addr, f),
        }
    }
}

impl AnySocketAddr {
    pub fn port(&self) -> io::Result<u16> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => Ok(inet_addr.port()),
            &AnySocketAddr::Unix(_) => Err(io::Error::new(
                io::ErrorKind::Other,
                "Cannot get port from unix domain socket",
            )),
        }
    }
}

impl ToSocketListener for AnySocketAddr {
    fn to_listener(&self, conf: &ServerConf) -> io::Result<Box<dyn ToTokioListener + Send>> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.to_listener(conf),
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.to_listener(conf),
        }
    }

    fn cleanup(&self) {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.cleanup(),
            #[cfg(unix)]
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.cleanup(),
            #[cfg(not(unix))]
            &AnySocketAddr::Unix(..) => {}
        }
    }
}

impl ToClientStream for AnySocketAddr {
    fn connect(
        &self,
        handle: &Handle,
    ) -> Pin<Box<dyn Future<Output = io::Result<Pin<Box<dyn SocketStream + Send>>>> + Send>> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.connect(handle),
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.connect(handle),
        }
    }

    fn socket_addr(&self) -> AnySocketAddr {
        self.clone()
    }
}

pub trait ToTokioListener {
    fn to_tokio_listener(self: Box<Self>, handle: &Handle) -> Box<dyn ToServerStream>;

    fn local_addr(&self) -> io::Result<AnySocketAddr>;
}

pub trait ToServerStream {
    fn incoming(
        self: Box<Self>,
    ) -> Pin<
        Box<
            dyn Stream<Item = io::Result<(Pin<Box<dyn SocketStream + Send>>, AnySocketAddr)>>
                + Send,
        >,
    >;
}

pub trait ToClientStream: Display + Send + Sync {
    fn connect(
        &self,
        handle: &Handle,
    ) -> Pin<Box<dyn Future<Output = io::Result<Pin<Box<dyn SocketStream + Send>>>> + Send>>;

    fn socket_addr(&self) -> AnySocketAddr;
}

pub trait SocketStream: AsyncRead + AsyncWrite + Debug + Send + Sync {
    fn is_tcp(&self) -> bool;

    fn set_nodelay(&self, no_delay: bool) -> io::Result<()>;
}
<commit_msg>Rustdoc<commit_after>use std::fmt::Debug;
use std::fmt::Display;
use std::fmt::Formatter;
use std::io;
use std::net::SocketAddr;

use tokio::io::AsyncRead;
use tokio::io::AsyncWrite;

use crate::socket_unix::SocketAddrUnix;
use crate::ServerConf;
use futures::stream::Stream;
use futures::Future;
use std::pin::Pin;
use tokio::runtime::Handle;

pub trait ToSocketListener {
    fn to_listener(&self, conf: &ServerConf) -> io::Result<Box<dyn ToTokioListener + Send>>;

    fn cleanup(&self);
}

#[derive(Clone, Debug, PartialEq)]
pub enum AnySocketAddr {
    Inet(SocketAddr),
    Unix(SocketAddrUnix),
}

impl Display for AnySocketAddr {
    fn fmt(&self, f: &mut Formatter) -> ::std::fmt::Result {
        match *self {
            AnySocketAddr::Inet(ref inet_addr) => Display::fmt(inet_addr, f),
            AnySocketAddr::Unix(ref unix_addr) => Display::fmt(unix_addr, f),
        }
    }
}

impl AnySocketAddr {
    pub fn port(&self) -> io::Result<u16> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => Ok(inet_addr.port()),
            &AnySocketAddr::Unix(_) => Err(io::Error::new(
                io::ErrorKind::Other,
                "Cannot get port from unix domain socket",
            )),
        }
    }
}

impl ToSocketListener for AnySocketAddr {
    fn to_listener(&self, conf: &ServerConf) -> io::Result<Box<dyn ToTokioListener + Send>> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.to_listener(conf),
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.to_listener(conf),
        }
    }

    fn cleanup(&self) {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.cleanup(),
            #[cfg(unix)]
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.cleanup(),
            #[cfg(not(unix))]
            &AnySocketAddr::Unix(..) => {}
        }
    }
}

impl ToClientStream for AnySocketAddr {
    fn connect(
        &self,
        handle: &Handle,
    ) -> Pin<Box<dyn Future<Output = io::Result<Pin<Box<dyn SocketStream + Send>>>> + Send>> {
        match self {
            &AnySocketAddr::Inet(ref inet_addr) => inet_addr.connect(handle),
            &AnySocketAddr::Unix(ref unix_addr) => unix_addr.connect(handle),
        }
    }

    fn socket_addr(&self) -> AnySocketAddr {
        self.clone()
    }
}

pub trait ToTokioListener {
    fn to_tokio_listener(self: Box<Self>, handle: &Handle) -> Box<dyn ToServerStream>;

    fn local_addr(&self) -> io::Result<AnySocketAddr>;
}

pub trait ToServerStream {
    fn incoming(
        self: Box<Self>,
    ) -> Pin<
        Box<
            dyn Stream<Item = io::Result<(Pin<Box<dyn SocketStream + Send>>, AnySocketAddr)>>
                + Send,
        >,
    >;
}

pub trait ToClientStream: Display + Send + Sync {
    fn connect(
        &self,
        handle: &Handle,
    ) -> Pin<Box<dyn Future<Output = io::Result<Pin<Box<dyn SocketStream + Send>>>> + Send>>;

    fn socket_addr(&self) -> AnySocketAddr;
}

/// TCP stream or socket stream; basically any async stream useable in http2
pub trait SocketStream: AsyncRead + AsyncWrite + Debug + Send + Sync {
    fn is_tcp(&self) -> bool;

    fn set_nodelay(&self, no_delay: bool) -> io::Result<()>;
}
<|endoftext|>


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

use Mathf;

use std::ops::*;
use std::cmp::PartialEq;

/*================================================================================================*/
/*------STRUCTS-----------------------------------------------------------------------------------*/
/*================================================================================================*/

/// The Vec2f struct
///
/// It is used mainly for 2D releated mathematics (e.g. texture and UV coordinates).
/// 32-bit floats are used for the values.
#[derive (Copy, Clone)]
pub struct Vec2f {

    // Public
    /// X-axis coordinate
    pub x : f32,
    /// Y-axis coordinate
    pub y : f32
}

/*================================================================================================*/
/*------PUBLIC FUNCTIONS--------------------------------------------------------------------------*/
/*================================================================================================*/

impl Vec2f {

    /// Formats the vector as a string.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec2f {x : 10.0, y : 5.0};
    /// println! ("Vector = {}", vec.to_string ());
    /// ```
    /// ```c
    /// Output : Vector = 10.0, 5.0
    pub fn to_string (&self) -> String {

        format! ("{}, {}", self.x, self.y)
    }

/*================================================================================================*/
/*------PUBLIC STATIC FUNCTIONS-------------------------------------------------------------------*/
/*================================================================================================*/

    /// Creates a vector with a default value of zero.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec2f::new ();
    pub fn new () -> Vec2f {

        Vec2f {x : 0.0,
               y : 0.0}
    }

/*================================================================================================*/

    /// Returns the dot product of two vectors.
    pub fn dot (lhs : &Vec2f, rhs : &Vec2f) -> f32 {

        (lhs.x * rhs.x) +
        (lhs.y * rhs.y)
    }

/*================================================================================================*/

    /// Returns the distance between two vectors
    pub fn distance (start : &Vec2f, end : &Vec2f) -> f32 {

        Vec2f::length (& (*start - *end))
    }

/*================================================================================================*/

    /// Returns the length of a vector
    pub fn length (vector : &Vec2f) -> f32 {

        (vector.x * vector.x +
         vector.y * vector.y).sqrt ()
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors.
    pub fn lerp (start : &Vec2f, end : &Vec2f, percentage : f32) -> Vec2f {

        Vec2f {x : Mathf::lerp (start.x, end.x, percentage),
               y : Mathf::lerp (start.y, end.y, percentage)}
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors without clamping
    pub fn lerp_unclamped (start : &Vec2f, end : &Vec2f, percentage : f32) -> Vec2f {

        Vec2f {x : Mathf::lerp_unclamped (start.x, end.x, percentage),
               y : Mathf::lerp_unclamped (start.y, end.y, percentage)}
    }

/*================================================================================================*/

    /// Get a normalized vector.
    pub fn normalize (vector : &Vec2f) -> Vec2f {

        let length = Vec2f::length (vector);

        if length != 0.0 {

            return Vec2f {x : vector.x / length,
                          y : vector.y / length}
        }

        Vec2f::new ()
    }
}

/*================================================================================================*/
/*------OPERATOR OVERLOADS------------------------------------------------------------------------*/
/*================================================================================================*/

impl Add for Vec2f {

    type Output = Vec2f;

    // Addition operator (vector)
    fn add (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x + rhs.x,
               y : self.y + rhs.y}
    }
}

/*================================================================================================*/

impl Add <f32> for Vec2f {

    type Output = Vec2f;

    // Addition operator (f32)
    fn add (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x + rhs,
               y : self.y + rhs}
    }
}

/*================================================================================================*/

impl AddAssign for Vec2f {

    // Addition assignment operator (vector)
    fn add_assign (&mut self, rhs : Vec2f) {

        self.x += rhs.x;
        self.y += rhs.y;
    }
}

/*================================================================================================*/

impl AddAssign <f32> for Vec2f {

    // Addition assignment operator (f32)
    fn add_assign (&mut self, rhs : f32) {

        self.x += rhs;
        self.y += rhs;
    }
}

/*================================================================================================*/

impl Sub for Vec2f {

    type Output = Vec2f;

    // Subtraction operator (vector)
    fn sub (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x - rhs.x,
               y : self.y - rhs.y}
    }
}

/*================================================================================================*/

impl Sub <f32> for Vec2f {

    type Output = Vec2f;

    // Subtraction operator (f32)
    fn sub (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x - rhs,
               y : self.y - rhs}
    }
}

/*================================================================================================*/

impl SubAssign for Vec2f {

    // Subtraction assignment operator (vector)
    fn sub_assign (&mut self, rhs : Vec2f) {

        self.x -= rhs.x;
        self.y -= rhs.y;
    }
}

/*================================================================================================*/

impl SubAssign <f32> for Vec2f {

    // Subtraction assignment operator (f32)
    fn sub_assign (&mut self, rhs : f32) {

        self.x += rhs;
        self.y += rhs;
    }
}

/*================================================================================================*/

impl Neg for Vec2f {

    type Output = Vec2f;

    // Unary minus operator
    fn neg (self) -> Vec2f {

        Vec2f {x : -self.x,
               y : -self.y}
    }
}

/*================================================================================================*/

impl Mul for Vec2f {

    type Output = Vec2f;

    // Multiplication operator (vector)
    fn mul (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x * rhs.x,
               y : self.y * rhs.y}
    }
}

/*================================================================================================*/

impl Mul <f32> for Vec2f {

    type Output = Vec2f;

    // Multiplication operator (f32)
    fn mul (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x * rhs,
               y : self.y * rhs}
    }
}

/*================================================================================================*/

impl MulAssign for Vec2f {

    // Multiplication assignment operator (vector)
    fn mul_assign (&mut self, rhs : Vec2f) {

        self.x *= rhs.x;
        self.y *= rhs.y;
    }
}

/*================================================================================================*/

impl MulAssign <f32> for Vec2f {

    // Multiplication assignment operator (f32)
    fn mul_assign (&mut self, rhs : f32) {

        self.x *= rhs;
        self.y *= rhs;
    }
}

/*================================================================================================*/

impl Div for Vec2f {

    type Output = Vec2f;

    // Division operator (vector)
    fn div (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x / rhs.x,
               y : self.y / rhs.y}
    }
}

/*================================================================================================*/

impl Div <f32> for Vec2f {

    type Output = Vec2f;

    // Division operator (f32)
    fn div (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x / rhs,
               y : self.y / rhs}
    }
}

/*================================================================================================*/

impl DivAssign for Vec2f {

    // Division assignment operator (vector)
    fn div_assign (&mut self, rhs : Vec2f) {

        self.x /= rhs.x;
        self.y /= rhs.y;
    }
}

/*================================================================================================*/

impl DivAssign <f32> for Vec2f {

    // Division assignment operator (f32)
    fn div_assign (&mut self, rhs : f32) {

        self.x /= rhs;
        self.y /= rhs;
    }
}

/*================================================================================================*/

impl PartialEq for Vec2f {

    // Equal to operator
    fn eq (&self, rhs : &Vec2f) -> bool {

        self.x == rhs.x &&
        self.y == rhs.y
    }

/*================================================================================================*/

    // Not equal to operator
    fn ne (&self, rhs : &Vec2f) -> bool {

        self.x != rhs.x ||
        self.y != rhs.y
    }
}

/*================================================================================================*/

impl Index <u8> for Vec2f {

    type Output = f32;

    // Index operator (immutable)
    fn index (&self, index : u8) -> &f32 {

        match index {

            0 => &self.x,
            1 => &self.y,
            _ => unreachable! ("Index out of range for Vec2f")
        }
    }
}

/*================================================================================================*/

impl IndexMut <u8> for Vec2f {

    // Index operator (mutable)
    fn index_mut (&mut self, index : u8) -> &mut f32 {

        match index {

            0 => &mut self.x,
            1 => &mut self.y,
            _ => unreachable! ("Index out of range for Vec2f")
        }
    }
}
<commit_msg>Fixed small error is sub assignment operator<commit_after>/*================================================================================================*/
// Copyright 2016 Kyle Finlay
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*================================================================================================*/

use Mathf;

use std::ops::*;
use std::cmp::PartialEq;

/*================================================================================================*/
/*------STRUCTS-----------------------------------------------------------------------------------*/
/*================================================================================================*/

/// The Vec2f struct
///
/// It is used mainly for 2D releated mathematics (e.g. texture and UV coordinates).
/// 32-bit floats are used for the values.
#[derive (Copy, Clone)]
pub struct Vec2f {

    // Public
    /// X-axis coordinate
    pub x : f32,
    /// Y-axis coordinate
    pub y : f32
}

/*================================================================================================*/
/*------PUBLIC FUNCTIONS--------------------------------------------------------------------------*/
/*================================================================================================*/

impl Vec2f {

    /// Formats the vector as a string.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec2f {x : 10.0, y : 5.0};
    /// println! ("Vector = {}", vec.to_string ());
    /// ```
    /// ```c
    /// Output : Vector = 10.0, 5.0
    pub fn to_string (&self) -> String {

        format! ("{}, {}", self.x, self.y)
    }

/*================================================================================================*/
/*------PUBLIC STATIC FUNCTIONS-------------------------------------------------------------------*/
/*================================================================================================*/

    /// Creates a vector with a default value of zero.
    ///
    /// # Examples
    /// ```
    /// let vec = Vec2f::new ();
    pub fn new () -> Vec2f {

        Vec2f {x : 0.0,
               y : 0.0}
    }

/*================================================================================================*/

    /// Returns the dot product of two vectors.
    pub fn dot (lhs : &Vec2f, rhs : &Vec2f) -> f32 {

        (lhs.x * rhs.x) +
        (lhs.y * rhs.y)
    }

/*================================================================================================*/

    /// Returns the distance between two vectors
    pub fn distance (start : &Vec2f, end : &Vec2f) -> f32 {

        Vec2f::length (& (*start - *end))
    }

/*================================================================================================*/

    /// Returns the length of a vector
    pub fn length (vector : &Vec2f) -> f32 {

        (vector.x * vector.x +
         vector.y * vector.y).sqrt ()
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors.
    pub fn lerp (start : &Vec2f, end : &Vec2f, percentage : f32) -> Vec2f {

        Vec2f {x : Mathf::lerp (start.x, end.x, percentage),
               y : Mathf::lerp (start.y, end.y, percentage)}
    }

/*================================================================================================*/

    /// Linearly interpolates between two vectors without clamping
    pub fn lerp_unclamped (start : &Vec2f, end : &Vec2f, percentage : f32) -> Vec2f {

        Vec2f {x : Mathf::lerp_unclamped (start.x, end.x, percentage),
               y : Mathf::lerp_unclamped (start.y, end.y, percentage)}
    }

/*================================================================================================*/

    /// Get a normalized vector.
    pub fn normalize (vector : &Vec2f) -> Vec2f {

        let length = Vec2f::length (vector);

        if length != 0.0 {

            return Vec2f {x : vector.x / length,
                          y : vector.y / length}
        }

        Vec2f::new ()
    }
}

/*================================================================================================*/
/*------OPERATOR OVERLOADS------------------------------------------------------------------------*/
/*================================================================================================*/

impl Add for Vec2f {

    type Output = Vec2f;

    // Addition operator (vector)
    fn add (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x + rhs.x,
               y : self.y + rhs.y}
    }
}

/*================================================================================================*/

impl Add <f32> for Vec2f {

    type Output = Vec2f;

    // Addition operator (f32)
    fn add (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x + rhs,
               y : self.y + rhs}
    }
}

/*================================================================================================*/

impl AddAssign for Vec2f {

    // Addition assignment operator (vector)
    fn add_assign (&mut self, rhs : Vec2f) {

        self.x += rhs.x;
        self.y += rhs.y;
    }
}

/*================================================================================================*/

impl AddAssign <f32> for Vec2f {

    // Addition assignment operator (f32)
    fn add_assign (&mut self, rhs : f32) {

        self.x += rhs;
        self.y += rhs;
    }
}

/*================================================================================================*/

impl Sub for Vec2f {

    type Output = Vec2f;

    // Subtraction operator (vector)
    fn sub (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x - rhs.x,
               y : self.y - rhs.y}
    }
}

/*================================================================================================*/

impl Sub <f32> for Vec2f {

    type Output = Vec2f;

    // Subtraction operator (f32)
    fn sub (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x - rhs,
               y : self.y - rhs}
    }
}

/*================================================================================================*/

impl SubAssign for Vec2f {

    // Subtraction assignment operator (vector)
    fn sub_assign (&mut self, rhs : Vec2f) {

        self.x -= rhs.x;
        self.y -= rhs.y;
    }
}

/*================================================================================================*/

impl SubAssign <f32> for Vec2f {

    // Subtraction assignment operator (f32)
    fn sub_assign (&mut self, rhs : f32) {

        self.x -= rhs;
        self.y -= rhs;
    }
}

/*================================================================================================*/

impl Neg for Vec2f {

    type Output = Vec2f;

    // Unary minus operator
    fn neg (self) -> Vec2f {

        Vec2f {x : -self.x,
               y : -self.y}
    }
}

/*================================================================================================*/

impl Mul for Vec2f {

    type Output = Vec2f;

    // Multiplication operator (vector)
    fn mul (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x * rhs.x,
               y : self.y * rhs.y}
    }
}

/*================================================================================================*/

impl Mul <f32> for Vec2f {

    type Output = Vec2f;

    // Multiplication operator (f32)
    fn mul (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x * rhs,
               y : self.y * rhs}
    }
}

/*================================================================================================*/

impl MulAssign for Vec2f {

    // Multiplication assignment operator (vector)
    fn mul_assign (&mut self, rhs : Vec2f) {

        self.x *= rhs.x;
        self.y *= rhs.y;
    }
}

/*================================================================================================*/

impl MulAssign <f32> for Vec2f {

    // Multiplication assignment operator (f32)
    fn mul_assign (&mut self, rhs : f32) {

        self.x *= rhs;
        self.y *= rhs;
    }
}

/*================================================================================================*/

impl Div for Vec2f {

    type Output = Vec2f;

    // Division operator (vector)
    fn div (self, rhs : Vec2f) -> Vec2f {

        Vec2f {x : self.x / rhs.x,
               y : self.y / rhs.y}
    }
}

/*================================================================================================*/

impl Div <f32> for Vec2f {

    type Output = Vec2f;

    // Division operator (f32)
    fn div (self, rhs : f32) -> Vec2f {

        Vec2f {x : self.x / rhs,
               y : self.y / rhs}
    }
}

/*================================================================================================*/

impl DivAssign for Vec2f {

    // Division assignment operator (vector)
    fn div_assign (&mut self, rhs : Vec2f) {

        self.x /= rhs.x;
        self.y /= rhs.y;
    }
}

/*================================================================================================*/

impl DivAssign <f32> for Vec2f {

    // Division assignment operator (f32)
    fn div_assign (&mut self, rhs : f32) {

        self.x /= rhs;
        self.y /= rhs;
    }
}

/*================================================================================================*/

impl PartialEq for Vec2f {

    // Equal to operator
    fn eq (&self, rhs : &Vec2f) -> bool {

        self.x == rhs.x &&
        self.y == rhs.y
    }

/*================================================================================================*/

    // Not equal to operator
    fn ne (&self, rhs : &Vec2f) -> bool {

        self.x != rhs.x ||
        self.y != rhs.y
    }
}

/*================================================================================================*/

impl Index <u8> for Vec2f {

    type Output = f32;

    // Index operator (immutable)
    fn index (&self, index : u8) -> &f32 {

        match index {

            0 => &self.x,
            1 => &self.y,
            _ => unreachable! ("Index out of range for Vec2f")
        }
    }
}

/*================================================================================================*/

impl IndexMut <u8> for Vec2f {

    // Index operator (mutable)
    fn index_mut (&mut self, index : u8) -> &mut f32 {

        match index {

            0 => &mut self.x,
            1 => &mut self.y,
            _ => unreachable! ("Index out of range for Vec2f")
        }
    }
}
<|endoftext|>