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

extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, EnumAccess,
                      VariantAccess, Error};

use {Level, LevelFilter, LOG_LEVEL_NAMES};

use std::fmt;
use std::str::FromStr;

// The Deserialize impls are handwritten to be case insensitive using FromStr.

impl Serialize for Level {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        match *self {
            Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"),
            Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"),
            Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"),
            Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"),
            Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for Level {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        struct LevelIdentifier;

        impl<'de> Visitor<'de> for LevelIdentifier {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: Error
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..]))
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelIdentifier {
            type Value = Level;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
                where D: Deserializer<'de>
            {
                deserializer.deserialize_identifier(LevelIdentifier)
            }
        }

        struct LevelEnum;

        impl<'de> Visitor<'de> for LevelEnum {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
                where A: EnumAccess<'de>
            {
                let (level, variant) = value.variant_seed(LevelIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level)
            }
        }

        deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum)
    }
}

impl Serialize for LevelFilter {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        match *self {
            LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"),
            LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"),
            LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"),
            LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"),
            LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"),
            LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for LevelFilter {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        struct LevelFilterIdentifier;

        impl<'de> Visitor<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: Error
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
                where D: Deserializer<'de>
            {
                deserializer.deserialize_identifier(LevelFilterIdentifier)
            }
        }

        struct LevelFilterEnum;

        impl<'de> Visitor<'de> for LevelFilterEnum {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
                where A: EnumAccess<'de>
            {
                let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level_filter)
            }
        }

        deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum)
    }
}

#[cfg(test)]
mod tests {
    extern crate serde_test;
    use self::serde_test::{Token, assert_tokens, assert_de_tokens, assert_de_tokens_error};

    use {Level, LevelFilter};

    #[test]
    fn test_level_ser_de() {
        let cases = [(Level::Error,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "ERROR",
                       }]),
                     (Level::Warn,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "WARN",
                       }]),
                     (Level::Info,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "INFO",
                       }]),
                     (Level::Debug,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "DEBUG",
                       }]),
                     (Level::Trace,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "TRACE",
                       }])];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_case_insensitive() {
        let cases = [(Level::Error,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "error",
                       }]),
                     (Level::Warn,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "warn",
                       }]),
                     (Level::Info,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "info",
                       }]),
                     (Level::Debug,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "debug",
                       }]),
                     (Level::Trace,
                      [Token::UnitVariant {
                           name: "Level",
                           variant: "trace",
                       }])];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_de_error() {
        assert_de_tokens_error::<Level>(&[Token::UnitVariant {
                                             name: "Level",
                                             variant: "errorx",
                                         }],
                                        "unknown variant `errorx`, expected one of `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`");
    }

    #[test]
    fn test_level_filter_ser_de() {
        let cases = [(LevelFilter::Off,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "OFF",
                       }]),
                     (LevelFilter::Error,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "ERROR",
                       }]),
                     (LevelFilter::Warn,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "WARN",
                       }]),
                     (LevelFilter::Info,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "INFO",
                       }]),
                     (LevelFilter::Debug,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "DEBUG",
                       }]),
                     (LevelFilter::Trace,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "TRACE",
                       }])];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_case_insensitive() {
        let cases = [(LevelFilter::Off,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "off",
                       }]),
                     (LevelFilter::Error,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "error",
                       }]),
                     (LevelFilter::Warn,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "warn",
                       }]),
                     (LevelFilter::Info,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "info",
                       }]),
                     (LevelFilter::Debug,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "debug",
                       }]),
                     (LevelFilter::Trace,
                      [Token::UnitVariant {
                           name: "LevelFilter",
                           variant: "trace",
                       }])];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_de_error() {
        assert_de_tokens_error::<LevelFilter>(&[Token::UnitVariant {
                                                   name: "LevelFilter",
                                                   variant: "errorx",
                                               }],
                                              "unknown variant `errorx`, expected one of `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`");
    }
}
<commit_msg>Clean up serde test formatting after rustfmt<commit_after>#![cfg(feature = "serde")]

extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, EnumAccess,
                      VariantAccess, Error};

use {Level, LevelFilter, LOG_LEVEL_NAMES};

use std::fmt;
use std::str::FromStr;

// The Deserialize impls are handwritten to be case insensitive using FromStr.

impl Serialize for Level {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        match *self {
            Level::Error => serializer.serialize_unit_variant("Level", 0, "ERROR"),
            Level::Warn => serializer.serialize_unit_variant("Level", 1, "WARN"),
            Level::Info => serializer.serialize_unit_variant("Level", 2, "INFO"),
            Level::Debug => serializer.serialize_unit_variant("Level", 3, "DEBUG"),
            Level::Trace => serializer.serialize_unit_variant("Level", 4, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for Level {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        struct LevelIdentifier;

        impl<'de> Visitor<'de> for LevelIdentifier {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: Error
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES[1..]))
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelIdentifier {
            type Value = Level;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
                where D: Deserializer<'de>
            {
                deserializer.deserialize_identifier(LevelIdentifier)
            }
        }

        struct LevelEnum;

        impl<'de> Visitor<'de> for LevelEnum {
            type Value = Level;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
                where A: EnumAccess<'de>
            {
                let (level, variant) = value.variant_seed(LevelIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level)
            }
        }

        deserializer.deserialize_enum("Level", &LOG_LEVEL_NAMES[1..], LevelEnum)
    }
}

impl Serialize for LevelFilter {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        match *self {
            LevelFilter::Off => serializer.serialize_unit_variant("LevelFilter", 0, "OFF"),
            LevelFilter::Error => serializer.serialize_unit_variant("LevelFilter", 1, "ERROR"),
            LevelFilter::Warn => serializer.serialize_unit_variant("LevelFilter", 2, "WARN"),
            LevelFilter::Info => serializer.serialize_unit_variant("LevelFilter", 3, "INFO"),
            LevelFilter::Debug => serializer.serialize_unit_variant("LevelFilter", 4, "DEBUG"),
            LevelFilter::Trace => serializer.serialize_unit_variant("LevelFilter", 5, "TRACE"),
        }
    }
}

impl<'de> Deserialize<'de> for LevelFilter {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        struct LevelFilterIdentifier;

        impl<'de> Visitor<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
                where E: Error
            {
                // Case insensitive.
                FromStr::from_str(s).map_err(|_| Error::unknown_variant(s, &LOG_LEVEL_NAMES))
            }
        }

        impl<'de> DeserializeSeed<'de> for LevelFilterIdentifier {
            type Value = LevelFilter;

            fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
                where D: Deserializer<'de>
            {
                deserializer.deserialize_identifier(LevelFilterIdentifier)
            }
        }

        struct LevelFilterEnum;

        impl<'de> Visitor<'de> for LevelFilterEnum {
            type Value = LevelFilter;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("log level filter")
            }

            fn visit_enum<A>(self, value: A) -> Result<Self::Value, A::Error>
                where A: EnumAccess<'de>
            {
                let (level_filter, variant) = value.variant_seed(LevelFilterIdentifier)?;
                // Every variant is a unit variant.
                variant.unit_variant()?;
                Ok(level_filter)
            }
        }

        deserializer.deserialize_enum("LevelFilter", &LOG_LEVEL_NAMES, LevelFilterEnum)
    }
}

#[cfg(test)]
mod tests {
    extern crate serde_test;
    use self::serde_test::{Token, assert_tokens, assert_de_tokens, assert_de_tokens_error};

    use {Level, LevelFilter};

    fn level_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "Level",
            variant: variant,
        }
    }

    fn level_filter_token(variant: &'static str) -> Token {
        Token::UnitVariant {
            name: "LevelFilter",
            variant: variant,
        }
    }

    #[test]
    fn test_level_ser_de() {
        let cases = [(Level::Error, [level_token("ERROR")]),
                     (Level::Warn, [level_token("WARN")]),
                     (Level::Info, [level_token("INFO")]),
                     (Level::Debug, [level_token("DEBUG")]),
                     (Level::Trace, [level_token("TRACE")])];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_case_insensitive() {
        let cases = [(Level::Error, [level_token("error")]),
                     (Level::Warn, [level_token("warn")]),
                     (Level::Info, [level_token("info")]),
                     (Level::Debug, [level_token("debug")]),
                     (Level::Trace, [level_token("trace")])];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<Level>(&[level_token("errorx")], msg);
    }

    #[test]
    fn test_level_filter_ser_de() {
        let cases = [(LevelFilter::Off, [level_filter_token("OFF")]),
                     (LevelFilter::Error, [level_filter_token("ERROR")]),
                     (LevelFilter::Warn, [level_filter_token("WARN")]),
                     (LevelFilter::Info, [level_filter_token("INFO")]),
                     (LevelFilter::Debug, [level_filter_token("DEBUG")]),
                     (LevelFilter::Trace, [level_filter_token("TRACE")])];

        for &(s, expected) in &cases {
            assert_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_case_insensitive() {
        let cases = [(LevelFilter::Off, [level_filter_token("off")]),
                     (LevelFilter::Error, [level_filter_token("error")]),
                     (LevelFilter::Warn, [level_filter_token("warn")]),
                     (LevelFilter::Info, [level_filter_token("info")]),
                     (LevelFilter::Debug, [level_filter_token("debug")]),
                     (LevelFilter::Trace, [level_filter_token("trace")])];

        for &(s, expected) in &cases {
            assert_de_tokens(&s, &expected);
        }
    }

    #[test]
    fn test_level_filter_de_error() {
        let msg = "unknown variant `errorx`, expected one of \
                   `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`";
        assert_de_tokens_error::<LevelFilter>(&[level_filter_token("errorx")], msg);
    }
}
<|endoftext|>


<commit_before>#![allow(unused_imports, dead_code, unused_variables)]

#[cfg(feature = "pkg-config")]
extern crate pkg_config;
#[cfg(feature = "bindgen")]
extern crate bindgen;
#[cfg(feature="bundled")]
extern crate cmake;
#[cfg(feature="bundled")]
extern crate tar;
#[cfg(feature="bundled")]
extern crate flate2;
#[cfg(feature="bundled")]
extern crate reqwest;

#[macro_use]
extern crate cfg_if;

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

// corresponds to the headers that we have in sdl2-sys/SDL2-{version}
const SDL2_HEADERS_BUNDLED_VERSION: &str = "2.0.6";

// means the lastest stable version that can be downloaded from SDL2's source
const LASTEST_SDL2_VERSION: &str = "2.0.5";

#[cfg(feature="bundled")]
fn download_to<T: io::Write>(url: &str, mut dest: T) {
    use io::BufRead;

    let resp = reqwest::get(url).expect(&format!("Failed to GET resource: {:?}", url));
    let size = resp.headers()
        .get::<reqwest::header::ContentLength>()
        .map(|ct_len| **ct_len)
        .unwrap_or(0);
    if !resp.status().is_success() { panic!("Download request failed with status: {:?}", resp.status()) }
    if size == 0 { panic!("Size of content was returned was 0") }

    let mut src = io::BufReader::new(resp);
    loop {
        let n = {
            let mut buf = src.fill_buf().unwrap();
            dest.write_all(&mut buf).unwrap();
            buf.len()
        };
        if n == 0 { break; }
        src.consume(n);
    }
}

#[cfg(feature = "use-pkgconfig")]
#[cfg(feature = "static-link")]
fn get_pkg_config() -> pkg_config::Library {
    pkg_config::Config::new()
        .statik(false)
        .probe("sdl2").unwrap()
}

#[cfg(feature = "use-pkgconfig")]
#[cfg(not(feature = "static-link"))]
fn get_pkg_config() -> pkg_config::Library {
    pkg_config::Config::new()
        .statik(true)
        .probe("sdl2").unwrap()
}

// returns the location of the downloaded source
#[cfg(feature = "bundled")]
fn download_sdl2() -> PathBuf {
    let out_dir = env::var("OUT_DIR").unwrap();

    let sdl2_archive_name = format!("SDL2-{}.tar.gz", LASTEST_SDL2_VERSION);
    let sdl2_archive_url = format!("http://libsdl.org/release/{}", sdl2_archive_name);

    let sdl2_archive_path = Path::new(&out_dir).join(sdl2_archive_name);
    let sdl2_build_path = Path::new(&out_dir).join(format!("SDL2-{}", LASTEST_SDL2_VERSION));

    // avoid re-downloading the archive if it already exists
    if !sdl2_archive_path.exists() {
        let sdl2_archive = fs::File::create(&sdl2_archive_path).unwrap();
        download_to(&sdl2_archive_url, &sdl2_archive);
    }

    let reader = flate2::read::GzDecoder::new(
        fs::File::open(&sdl2_archive_path).unwrap()
    ).unwrap();
    let mut ar = tar::Archive::new(reader);
    ar.unpack(&out_dir).unwrap();

    sdl2_build_path
}

// compile a shared or static lib depending on the feature
#[cfg(feature = "bundled")]
fn compile_sdl2(sdl2_build_path: &Path) -> PathBuf {
    let install_path = if cfg!(feature = "static-link") {
        cmake::Config::new(sdl2_build_path)
            .define("SDL_SHARED", "OFF")
            .define("SDL_STATIC", "ON")
            .build()
    } else {
        cmake::Config::new(sdl2_build_path)
            .define("SDL_SHARED", "ON")
            .define("SDL_STATIC", "OFF")
            .build()
    };

    install_path
}

#[cfg(not(feature = "bundled"))]
fn compute_include_paths() -> Vec<String> {
    let mut include_paths: Vec<String> = vec!();

    if let Ok(include_path) = env::var("SDL2_INCLUDE_PATH") {
        include_paths.push(format!("{}", include_path));
    };

    #[cfg(feature = "pkg-config")] {
        // don't print the "cargo:xxx" directives, we're just trying to get the include paths here
        let pkg_config_library = pkg_config::Config::new().print_system_libs(false).probe("sdl2").unwrap();
        for path in pkg_config_library.include_paths {
            include_paths.push(format!("{}", path.display()));
        };
    }

    include_paths
}

fn link_sdl2(target_os: &str) {
    #[cfg(all(feature = "use-pkgconfig", not(feature = "bundled")))] {
        // prints the appropriate linking parameters when using pkg-config
        // useless when using "bundled"
        get_pkg_config();
    }

    #[cfg(not(feature = "static-link"))] {
        if target_os == "ios" {
            // iOS requires additional linking to function properly
            println!("cargo:rustc-flags=-l framework=AVFoundation");
            println!("cargo:rustc-flags=-l framework=AudioToolbox");
            println!("cargo:rustc-flags=-l framework=CoreAudio");
            println!("cargo:rustc-flags=-l framework=CoreGraphics");
            println!("cargo:rustc-flags=-l framework=CoreMotion");
            println!("cargo:rustc-flags=-l framework=Foundation");
            println!("cargo:rustc-flags=-l framework=GameController");
            println!("cargo:rustc-flags=-l framework=OpenGLES");
            println!("cargo:rustc-flags=-l framework=QuartzCore");
            println!("cargo:rustc-flags=-l framework=UIKit");
        }

        // pkg-config automatically prints this output when probing,
        // however pkg_config isn't used with the feature "bundled"
        if cfg!(feature = "bundled") || cfg!(not(feature = "use-pkgconfig")) {
            if cfg!(feature = "use_mac_framework") && target_os == "darwin" {
                println!("cargo:rustc-flags=-l framework=SDL2");
            } else {
                println!("cargo:rustc-flags=-l SDL2");
            }
        }
    }

    #[cfg(feature = "static-link")] {
        if cfg!(feature = "bundled") || cfg!(feature = "use-pkgconfig") == false {
            println!("cargo:rustc-link-lib=static=SDL2main");
            println!("cargo:rustc-link-lib=static=SDL2");
        }

        // Also linked to any required libraries for each supported platform
        if target_os == "windows-msvc" {
            println!("cargo:rustc-link-lib=user32");
            println!("cargo:rustc-link-lib=gdi32");
            println!("cargo:rustc-link-lib=winmm");
            println!("cargo:rustc-link-lib=imm32");
            println!("cargo:rustc-link-lib=ole32");
            println!("cargo:rustc-link-lib=oleaut32");
            println!("cargo:rustc-link-lib=version");
            println!("cargo:rustc-link-lib=uuid");
            println!("cargo:rustc-link-lib=dinput8");
            println!("cargo:rustc-link-lib=dxguid");
        } else if target_os.contains("linux") {
            println!("cargo:rustc-link-lib=sndio");
        } else if target_os == "darwin" {
            println!("cargo:rustc-link-lib=framework=Cocoa");
            println!("cargo:rustc-link-lib=framework=IOKit");
            println!("cargo:rustc-link-lib=framework=Carbon");
            println!("cargo:rustc-link-lib=framework=ForceFeedback");
            println!("cargo:rustc-link-lib=framework=CoreVideo");
            println!("cargo:rustc-link-lib=framework=CoreAudio");
            println!("cargo:rustc-link-lib=framework=AudioToolbox");
            println!("cargo:rustc-link-lib=iconv");
        } else {
            // TODO: Add other platform linker options here.
        }
    }
}

fn main() {
    let target = env::var("TARGET").expect("Cargo build scripts always have TARGET");
    let host = env::var("HOST").expect("Cargo build scripts always have HOST");
    let target_os = get_os_from_triple(target.as_str()).unwrap();

    #[cfg(feature = "bundled")] {
        let sdl2_source_path = download_sdl2();
        let sdl2_compiled_path = compile_sdl2(sdl2_source_path.as_path());

        let sdl2_downloaded_include_path = sdl2_source_path.join("include");
        let sdl2_compiled_lib_path = sdl2_compiled_path.join("lib");

        println!("cargo:rustc-link-search={}", sdl2_compiled_lib_path.display());

        #[cfg(feature = "bindgen")] {
            let include_paths = vec!(String::from(sdl2_downloaded_include_path.to_str().unwrap()));
            generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
        }
    };

    #[cfg(all(not(feature = "bundled"), feature = "bindgen"))] {
        let include_paths: Vec<String> = compute_include_paths();
        generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
    }

    #[cfg(not(feature = "bindgen"))] {
        copy_pregenerated_bindings();
    }

    link_sdl2(target_os);
}

#[cfg(not(feature = "bindgen"))]
fn copy_pregenerated_bindings() {
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    let crate_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    fs::copy(crate_path.join("pregenerated_bindings.rs"), out_path.join("bindings.rs"))
        .expect("Couldn't find pregenerated bindings!");
}

#[cfg(feature = "bindgen")]
// headers_path is a list of directories where the SDL2 headers are expected
// to be found by bindgen (should point to the include/ directories)
fn generate_bindings<S: AsRef<str> + ::std::fmt::Debug>(target: &str, host: &str, headers_paths: &[S]) {
    let target_os = get_os_from_triple(target).unwrap();
    let mut bindings = bindgen::Builder::default();

    // Set correct target triple for bindgen when cross-compiling
    if target != host {
        bindings = bindings.clang_arg("-target");
        bindings = bindings.clang_arg(target.clone());
    }

    if headers_paths.len() == 0 {
        // if no paths are being provided, fall back to the headers included in this repo
        let mut include_path: PathBuf = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
        include_path.push(format!("SDL2-{}", SDL2_HEADERS_BUNDLED_VERSION));
        include_path.push("include");
        bindings = bindings.clang_arg(format!("-I{}", include_path.display()));
    } else {
        // if paths are included, use them for bindgen. Bindgen should use the first one.
        for headers_path in headers_paths {
            bindings = bindings.clang_arg(format!("-I{}", headers_path.as_ref()))
        }
    }

    // SDL2 hasn't a default configuration for Linux
    if target_os == "linux" {
        bindings = bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
        bindings = bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
    }

    let bindings = bindings
        .header("wrapper.h")
        .hide_type("_")
        .hide_type("FP_NAN")
        .hide_type("FP_INFINITE")
        .hide_type("FP_ZERO")
        .hide_type("FP_SUBNORMAL")
        .hide_type("FP_NORMAL") // Until https://github.com/rust-lang-nursery/rust-bindgen/issues/687 gets fixed
        .hide_type("max_align_t") // Until https://github.com/rust-lang-nursery/rust-bindgen/issues/550 gets fixed
        .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!");
}

fn get_os_from_triple(triple: &str) -> Option<&str>
{
    triple.splitn(3, "-").nth(2)
}<commit_msg>Fixed build.rs with static & pkgconfig<commit_after>#![allow(unused_imports, dead_code, unused_variables)]

#[cfg(feature = "pkg-config")]
extern crate pkg_config;
#[cfg(feature = "bindgen")]
extern crate bindgen;
#[cfg(feature="bundled")]
extern crate cmake;
#[cfg(feature="bundled")]
extern crate tar;
#[cfg(feature="bundled")]
extern crate flate2;
#[cfg(feature="bundled")]
extern crate reqwest;

#[macro_use]
extern crate cfg_if;

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

// corresponds to the headers that we have in sdl2-sys/SDL2-{version}
const SDL2_HEADERS_BUNDLED_VERSION: &str = "2.0.6";

// means the lastest stable version that can be downloaded from SDL2's source
const LASTEST_SDL2_VERSION: &str = "2.0.5";

#[cfg(feature="bundled")]
fn download_to<T: io::Write>(url: &str, mut dest: T) {
    use io::BufRead;

    let resp = reqwest::get(url).expect(&format!("Failed to GET resource: {:?}", url));
    let size = resp.headers()
        .get::<reqwest::header::ContentLength>()
        .map(|ct_len| **ct_len)
        .unwrap_or(0);
    if !resp.status().is_success() { panic!("Download request failed with status: {:?}", resp.status()) }
    if size == 0 { panic!("Size of content was returned was 0") }

    let mut src = io::BufReader::new(resp);
    loop {
        let n = {
            let mut buf = src.fill_buf().unwrap();
            dest.write_all(&mut buf).unwrap();
            buf.len()
        };
        if n == 0 { break; }
        src.consume(n);
    }
}

#[cfg(feature = "use-pkgconfig")]
#[cfg(feature = "static-link")]
fn get_pkg_config() -> pkg_config::Library {
    pkg_config::Config::new()
        .statik(true)
        .probe("sdl2").unwrap()
}

#[cfg(feature = "use-pkgconfig")]
#[cfg(not(feature = "static-link"))]
fn get_pkg_config() -> pkg_config::Library {
    pkg_config::Config::new()
        .statik(false)
        .probe("sdl2").unwrap()
}

// returns the location of the downloaded source
#[cfg(feature = "bundled")]
fn download_sdl2() -> PathBuf {
    let out_dir = env::var("OUT_DIR").unwrap();

    let sdl2_archive_name = format!("SDL2-{}.tar.gz", LASTEST_SDL2_VERSION);
    let sdl2_archive_url = format!("http://libsdl.org/release/{}", sdl2_archive_name);

    let sdl2_archive_path = Path::new(&out_dir).join(sdl2_archive_name);
    let sdl2_build_path = Path::new(&out_dir).join(format!("SDL2-{}", LASTEST_SDL2_VERSION));

    // avoid re-downloading the archive if it already exists
    if !sdl2_archive_path.exists() {
        let sdl2_archive = fs::File::create(&sdl2_archive_path).unwrap();
        download_to(&sdl2_archive_url, &sdl2_archive);
    }

    let reader = flate2::read::GzDecoder::new(
        fs::File::open(&sdl2_archive_path).unwrap()
    ).unwrap();
    let mut ar = tar::Archive::new(reader);
    ar.unpack(&out_dir).unwrap();

    sdl2_build_path
}

// compile a shared or static lib depending on the feature
#[cfg(feature = "bundled")]
fn compile_sdl2(sdl2_build_path: &Path) -> PathBuf {
    let install_path = if cfg!(feature = "static-link") {
        cmake::Config::new(sdl2_build_path)
            .define("SDL_SHARED", "OFF")
            .define("SDL_STATIC", "ON")
            .build()
    } else {
        cmake::Config::new(sdl2_build_path)
            .define("SDL_SHARED", "ON")
            .define("SDL_STATIC", "OFF")
            .build()
    };

    install_path
}

#[cfg(not(feature = "bundled"))]
fn compute_include_paths() -> Vec<String> {
    let mut include_paths: Vec<String> = vec!();

    if let Ok(include_path) = env::var("SDL2_INCLUDE_PATH") {
        include_paths.push(format!("{}", include_path));
    };

    #[cfg(feature = "pkg-config")] {
        // don't print the "cargo:xxx" directives, we're just trying to get the include paths here
        let pkg_config_library = pkg_config::Config::new().print_system_libs(false).probe("sdl2").unwrap();
        for path in pkg_config_library.include_paths {
            include_paths.push(format!("{}", path.display()));
        };
    }

    include_paths
}

fn link_sdl2(target_os: &str) {
    #[cfg(all(feature = "use-pkgconfig", not(feature = "bundled")))] {
        // prints the appropriate linking parameters when using pkg-config
        // useless when using "bundled"
        get_pkg_config();
    }

    #[cfg(not(feature = "static-link"))] {
        if target_os == "ios" {
            // iOS requires additional linking to function properly
            println!("cargo:rustc-flags=-l framework=AVFoundation");
            println!("cargo:rustc-flags=-l framework=AudioToolbox");
            println!("cargo:rustc-flags=-l framework=CoreAudio");
            println!("cargo:rustc-flags=-l framework=CoreGraphics");
            println!("cargo:rustc-flags=-l framework=CoreMotion");
            println!("cargo:rustc-flags=-l framework=Foundation");
            println!("cargo:rustc-flags=-l framework=GameController");
            println!("cargo:rustc-flags=-l framework=OpenGLES");
            println!("cargo:rustc-flags=-l framework=QuartzCore");
            println!("cargo:rustc-flags=-l framework=UIKit");
        }

        // pkg-config automatically prints this output when probing,
        // however pkg_config isn't used with the feature "bundled"
        if cfg!(feature = "bundled") || cfg!(not(feature = "use-pkgconfig")) {
            if cfg!(feature = "use_mac_framework") && target_os == "darwin" {
                println!("cargo:rustc-flags=-l framework=SDL2");
            } else {
                println!("cargo:rustc-flags=-l SDL2");
            }
        }
    }

    #[cfg(feature = "static-link")] {
        if cfg!(feature = "bundled") || cfg!(feature = "use-pkgconfig") == false {
            println!("cargo:rustc-link-lib=static=SDL2main");
            println!("cargo:rustc-link-lib=static=SDL2");
        }

        // Also linked to any required libraries for each supported platform
        if target_os == "windows-msvc" {
            println!("cargo:rustc-link-lib=user32");
            println!("cargo:rustc-link-lib=gdi32");
            println!("cargo:rustc-link-lib=winmm");
            println!("cargo:rustc-link-lib=imm32");
            println!("cargo:rustc-link-lib=ole32");
            println!("cargo:rustc-link-lib=oleaut32");
            println!("cargo:rustc-link-lib=version");
            println!("cargo:rustc-link-lib=uuid");
            println!("cargo:rustc-link-lib=dinput8");
            println!("cargo:rustc-link-lib=dxguid");
        } else if target_os.contains("linux") {
            println!("cargo:rustc-link-lib=sndio");
        } else if target_os == "darwin" {
            println!("cargo:rustc-link-lib=framework=Cocoa");
            println!("cargo:rustc-link-lib=framework=IOKit");
            println!("cargo:rustc-link-lib=framework=Carbon");
            println!("cargo:rustc-link-lib=framework=ForceFeedback");
            println!("cargo:rustc-link-lib=framework=CoreVideo");
            println!("cargo:rustc-link-lib=framework=CoreAudio");
            println!("cargo:rustc-link-lib=framework=AudioToolbox");
            println!("cargo:rustc-link-lib=iconv");
        } else {
            // TODO: Add other platform linker options here.
        }
    }
}

fn main() {
    let target = env::var("TARGET").expect("Cargo build scripts always have TARGET");
    let host = env::var("HOST").expect("Cargo build scripts always have HOST");
    let target_os = get_os_from_triple(target.as_str()).unwrap();

    #[cfg(feature = "bundled")] {
        let sdl2_source_path = download_sdl2();
        let sdl2_compiled_path = compile_sdl2(sdl2_source_path.as_path());

        let sdl2_downloaded_include_path = sdl2_source_path.join("include");
        let sdl2_compiled_lib_path = sdl2_compiled_path.join("lib");

        println!("cargo:rustc-link-search={}", sdl2_compiled_lib_path.display());

        #[cfg(feature = "bindgen")] {
            let include_paths = vec!(String::from(sdl2_downloaded_include_path.to_str().unwrap()));
            generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
        }
    };

    #[cfg(all(not(feature = "bundled"), feature = "bindgen"))] {
        let include_paths: Vec<String> = compute_include_paths();
        generate_bindings(target.as_str(), host.as_str(), include_paths.as_slice())
    }

    #[cfg(not(feature = "bindgen"))] {
        copy_pregenerated_bindings();
    }

    link_sdl2(target_os);
}

#[cfg(not(feature = "bindgen"))]
fn copy_pregenerated_bindings() {
    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    let crate_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    fs::copy(crate_path.join("pregenerated_bindings.rs"), out_path.join("bindings.rs"))
        .expect("Couldn't find pregenerated bindings!");
}

#[cfg(feature = "bindgen")]
// headers_path is a list of directories where the SDL2 headers are expected
// to be found by bindgen (should point to the include/ directories)
fn generate_bindings<S: AsRef<str> + ::std::fmt::Debug>(target: &str, host: &str, headers_paths: &[S]) {
    let target_os = get_os_from_triple(target).unwrap();
    let mut bindings = bindgen::Builder::default();

    // Set correct target triple for bindgen when cross-compiling
    if target != host {
        bindings = bindings.clang_arg("-target");
        bindings = bindings.clang_arg(target.clone());
    }

    if headers_paths.len() == 0 {
        // if no paths are being provided, fall back to the headers included in this repo
        let mut include_path: PathBuf = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
        include_path.push(format!("SDL2-{}", SDL2_HEADERS_BUNDLED_VERSION));
        include_path.push("include");
        bindings = bindings.clang_arg(format!("-I{}", include_path.display()));
    } else {
        // if paths are included, use them for bindgen. Bindgen should use the first one.
        for headers_path in headers_paths {
            bindings = bindings.clang_arg(format!("-I{}", headers_path.as_ref()))
        }
    }

    // SDL2 hasn't a default configuration for Linux
    if target_os == "linux" {
        bindings = bindings.clang_arg("-DSDL_VIDEO_DRIVER_X11");
        bindings = bindings.clang_arg("-DSDL_VIDEO_DRIVER_WAYLAND");
    }

    let bindings = bindings
        .header("wrapper.h")
        .hide_type("_")
        .hide_type("FP_NAN")
        .hide_type("FP_INFINITE")
        .hide_type("FP_ZERO")
        .hide_type("FP_SUBNORMAL")
        .hide_type("FP_NORMAL") // Until https://github.com/rust-lang-nursery/rust-bindgen/issues/687 gets fixed
        .hide_type("max_align_t") // Until https://github.com/rust-lang-nursery/rust-bindgen/issues/550 gets fixed
        .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!");
}

fn get_os_from_triple(triple: &str) -> Option<&str>
{
    triple.splitn(3, "-").nth(2)
}
<|endoftext|>


<commit_before>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkError, ZooKeeper};
use zookeeper::acls;

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, _e: &WatchedEvent) {
        // println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
    default_acl: Vec<Acl>,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $min:expr, $max:expr, $params:expr) => (
        if $args.len() < $min || $args.len() > $max {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        } else {
            $args.len()
        })
}

fn report_error(error: ZkError, path: &str) {
    match error {
        ZkError::NoNode => println!("Path {} does not exist.", path),
        ZkError::NotEmpty => println!("Path {} is not empty.", path),
        unknown => println!("Unknown error: {:?}", unknown),
    }
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5,
            default_acl: acls::OPEN_ACL_UNSAFE.clone(),
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                "ls" => self.ls(args),
                "create" => self.create(args),
                "rm" => self.rm(args),
                "exists" => self.exists(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        let _ = check_args!(args, 1, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_data(path, false);

        match ret {
            Ok(data_stat) =>  {
                let (bytes, _) = data_stat;
                let datastr = str::from_utf8(&bytes[..]).unwrap().to_string();
                println!("{}", datastr);
            },
            Err(err) => report_error(err, path),
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        let _ = check_args!(args, 2, 2, "<path> <data>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, -1);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn ls(&mut self, args: Vec<&str>) {
        let _ = check_args!(args, 1, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_children(path, false);

        match ret {
            Ok(children) => println!("{}", children.join(" ")),
            Err(err) => report_error(err, path),
        }
    }

    fn create(&mut self, args: Vec<&str>) {
        let mut mode: CreateMode = CreateMode::Persistent;

        let argc = check_args!(args, 2, 4, "<path> <data> [ephemeral] [sequential]");
        if argc >= 3 {
            if args[2].to_lowercase() == "true" {
                mode = CreateMode::Ephemeral;
            }
        }

        if argc == 4 {
            if args[3].to_lowercase() == "true" {
                mode = match mode {
                    CreateMode::Ephemeral => CreateMode::EphemeralSequential,
                    _ => CreateMode::PersistentSequential
                }
            }
        }

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();

        let ret = zk.create(
            path, data, self.default_acl.clone(), mode);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn rm(&mut self, args: Vec<&str>) {
        let _ = check_args!(args, 1, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.delete(path, -1);

        match ret {
            Ok(()) =>  (),
            Err(err) => report_error(err, path),
        }
    }

    fn exists(&mut self, args: Vec<&str>) {
        let _ = check_args!(args, 1, 1, "<path>");
        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.exists(path, false);

        match ret {
            Ok(stat) => println!("{:?}", stat),
            Err(err) => report_error(err, path),
        }
    }
}
<commit_msg>feature(shell): support optional parameters (version/watch)<commit_after>use std::io::stdin;
use std::io::stdout;
use std::io::Write;
use std::str;
use std::time::Duration;

use zookeeper::{Acl, CreateMode, Watcher, WatchedEvent, ZkError, ZooKeeper};
use zookeeper::acls;

struct MyWatcher;

impl Watcher for MyWatcher {
    fn handle(&self, e: &WatchedEvent) {
        println!("{:?}", e)
    }
}

pub struct Shell {
    hosts: String,
    zk: Option<ZooKeeper>,
    session_timeout: u64,
    default_acl: Vec<Acl>,
}

// are we connected?
macro_rules! fetch_zk {
    ($e:expr) => (
        match $e {
            Some(ref __zk) => __zk,
            _ => {
                println!("Not connected.");
                return;
            }
        })
}

macro_rules! check_args {
    ($args:ident, $min:expr, $max:expr, $params:expr) => (
        if $args.len() < $min || $args.len() > $max {
            println!("Wrong number of arguments, expected parameters: {}", $params);
            return;
        } else {
            $args.len()
        })
}

fn report_error(error: ZkError, path: &str) {
    match error {
        ZkError::NoNode => println!("Path {} does not exist.", path),
        ZkError::NotEmpty => println!("Path {} is not empty.", path),
        unknown => println!("Unknown error: {:?}", unknown),
    }
}

impl Shell {
    pub fn new(hosts: &str) -> Shell {
        Shell {
            hosts: hosts.to_string(),
            zk: None,
            session_timeout: 5,
            default_acl: acls::OPEN_ACL_UNSAFE.clone(),
        }
    }

    pub fn run(&mut self) {
        if !self.hosts.is_empty() {
            println!("Connecting...");
            let zk = ZooKeeper::connect(
                &self.hosts,
                Duration::from_secs(self.session_timeout),
                MyWatcher).unwrap();
            self.zk = Some(zk);
        }

        loop {
            let mut line = String::new();

            print!("> ");
            let _ = stdout().flush();

            stdin()
                .read_line(&mut line)
                .ok()
                .expect("Failed to read line");

            let pieces: Vec<&str>  = line.trim().split_whitespace().collect();

            if pieces.len() == 0 {
                continue;
            }

            // dispatch the command
            let args = pieces[1..].to_vec();
            match pieces[0] {
                "get" => self.get(args),
                "set" => self.set(args),
                "ls" => self.ls(args),
                "create" => self.create(args),
                "rm" => self.rm(args),
                "exists" => self.exists(args),
                unknown => println!("Unknown command: {}", unknown)
            }
        }

    }

    fn get(&mut self, args: Vec<&str>) {
        let argc = check_args!(args, 1, 2, "<path> [watch]");
        let watch = match argc {
            1 => false,
            _ => args[1].to_lowercase() == "true"
        };

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_data(path, watch);

        match ret {
            Ok(data_stat) =>  {
                let (bytes, _) = data_stat;
                let datastr = str::from_utf8(&bytes[..]).unwrap().to_string();
                println!("{}", datastr);
            },
            Err(err) => report_error(err, path),
        }
    }

    fn set(&mut self, args: Vec<&str>) {
        let argc = check_args!(args, 2, 3, "<path> <data> [version]");
        let version = match argc {
            3 => match args[2].parse::<i32>() {
                Ok(version) => version,
                Err(_) => -1
            },
            _ => -1
        };

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();
        let ret = zk.set_data(path, data, version);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn ls(&mut self, args: Vec<&str>) {
        let argc = check_args!(args, 1, 2, "<path> [watch]");
        let watch = match argc {
            1 => false,
            _ => args[1].to_lowercase() == "true"
        };

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.get_children(path, watch);

        match ret {
            Ok(children) => println!("{}", children.join(" ")),
            Err(err) => report_error(err, path),
        }
    }

    fn create(&mut self, args: Vec<&str>) {
        let mut mode: CreateMode = CreateMode::Persistent;

        let argc = check_args!(args, 2, 4, "<path> <data> [ephemeral] [sequential]");
        if argc >= 3 {
            if args[2].to_lowercase() == "true" {
                mode = CreateMode::Ephemeral;
            }
        }

        if argc == 4 {
            if args[3].to_lowercase() == "true" {
                mode = match mode {
                    CreateMode::Ephemeral => CreateMode::EphemeralSequential,
                    _ => CreateMode::PersistentSequential
                }
            }
        }

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let data = args[1].as_bytes().to_vec();

        let ret = zk.create(
            path, data, self.default_acl.clone(), mode);

        match ret {
            Ok(_) => (),
            Err(err) => report_error(err, path),
        }
    }

    fn rm(&mut self, args: Vec<&str>) {
        let argc = check_args!(args, 1, 2, "<path> [version]");
        let version = match argc {
            2 => match args[1].parse::<i32>() {
                Ok(version) => version,
                Err(_) => -1
            },
            _ => -1
        };

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.delete(path, version);

        match ret {
            Ok(()) =>  (),
            Err(err) => report_error(err, path),
        }
    }

    fn exists(&mut self, args: Vec<&str>) {
        let argc = check_args!(args, 1, 2, "<path> [watch]");
        let watch = match argc {
            1 => false,
            _ => args[1].to_lowercase() == "true"
        };

        let zk = fetch_zk!(self.zk);
        let path = args[0];
        let ret = zk.exists(path, watch);

        match ret {
            Ok(stat) => println!("{:?}", stat),
            Err(err) => report_error(err, path),
        }
    }
}
<|endoftext|>


<commit_before>pub fn clear() -> String {
    "\x1b[2J".to_string()
}

pub fn begin() -> String {
    "\x1bPq".to_string()
}

pub fn end() -> String {
    "\x1b\\".to_string()
}

pub fn from(memory: &[u32], width: usize, height: usize, border: bool) -> String {
    let mut pixels: Vec<u8> = Vec::new();
    let mut row = 0;

    if border {
        for _ in 0..(width + 2) {
            pixels.push(95);
        }
        pixels.push(36);
        pixels.push(45);
    }

    while row < height {
        if border {
            pixels.push(126);
        }

        for x in 0..width {
            let mut byte: u8 = 0;

            for y in 0..6 {
                let offset = x + (y * width);
                if memory[offset] > 0 {
                    byte = byte | (1 << y);
                }
            }

            pixels.push(byte + 63);
        }

        if border {
            pixels.push(126);
        }

        // Push "$-" to move to the next row.
        pixels.push(36);
        pixels.push(45);
        row += 6;
    }

    if border {
        for _ in 0..(width + 2) {
            pixels.push(64);
        }
        pixels.push(36);
        pixels.push(45);
    }

    String::from_utf8(pixels).unwrap()
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_converts_000000_to_question_mark() {
        assert_eq!(super::from(&[0, 0, 0, 0, 0, 0], 1, 6, false), "?$-");
    }

    #[test]
    fn it_converts_000111_to_w() {
        assert_eq!(super::from(&[0, 0, 0, 1, 1, 1], 1, 6, false), "w$-");
    }

    #[test]
    fn it_converts_111000_to_capital_f() {
        assert_eq!(super::from(&[1, 1, 1, 0, 0, 0], 1, 6, false), "F$-");
    }

    #[test]
    fn it_converts_111111_to_tilde() {
        assert_eq!(super::from(&[1, 1, 1, 1, 1, 1], 1, 6, false), "~$-");
    }

    #[test]
    fn it_displays_capital_a() {
        assert_eq!(super::from(&[0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0,
                                 0, 0, 0],
                               4,
                               6,
                               false),
                   "]DD]$-");
    }
}
<commit_msg>Clear the screen by moving the cursor to the top left corner.<commit_after>pub fn clear() -> String {
    "\x1b[0;0H".to_string()
}

pub fn begin() -> String {
    "\x1bPq".to_string()
}

pub fn end() -> String {
    "\x1b\\".to_string()
}

pub fn from(memory: &[u32], width: usize, height: usize, border: bool) -> String {
    let mut pixels: Vec<u8> = Vec::new();
    let mut row = 0;

    if border {
        for _ in 0..(width + 2) {
            pixels.push(95);
        }
        pixels.push(36);
        pixels.push(45);
    }

    while row < height {
        if border {
            pixels.push(126);
        }

        for x in 0..width {
            let mut byte: u8 = 0;

            for y in 0..6 {
                let offset = x + (y * width);
                if memory[offset] > 0 {
                    byte = byte | (1 << y);
                }
            }

            pixels.push(byte + 63);
        }

        if border {
            pixels.push(126);
        }

        // Push "$-" to move to the next row.
        pixels.push(36);
        pixels.push(45);
        row += 6;
    }

    if border {
        for _ in 0..(width + 2) {
            pixels.push(64);
        }
        pixels.push(36);
        pixels.push(45);
    }

    String::from_utf8(pixels).unwrap()
}

#[cfg(test)]
mod tests {
    #[test]
    fn it_converts_000000_to_question_mark() {
        assert_eq!(super::from(&[0, 0, 0, 0, 0, 0], 1, 6, false), "?$-");
    }

    #[test]
    fn it_converts_000111_to_w() {
        assert_eq!(super::from(&[0, 0, 0, 1, 1, 1], 1, 6, false), "w$-");
    }

    #[test]
    fn it_converts_111000_to_capital_f() {
        assert_eq!(super::from(&[1, 1, 1, 0, 0, 0], 1, 6, false), "F$-");
    }

    #[test]
    fn it_converts_111111_to_tilde() {
        assert_eq!(super::from(&[1, 1, 1, 1, 1, 1], 1, 6, false), "~$-");
    }

    #[test]
    fn it_displays_capital_a() {
        assert_eq!(super::from(&[0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0,
                                 0, 0, 0],
                               4,
                               6,
                               false),
                   "]DD]$-");
    }
}
<|endoftext|>


<commit_before>use std::cmp::min;
use std::fmt::{Display, Formatter, Result};

use settings::MAX_GAME_LEVEL;

const LEVEL_THRESHOLD: u32 = 10;

pub struct GameStats {
    score: u32,
    lines: u32,
}
impl GameStats {
    pub fn new() -> GameStats {
        GameStats {
            score: 0,
            lines: 0
        }
    }

    pub fn score_soft_drop(&mut self) {
        self.score += 1;
    }

    pub fn score_hard_drop(&mut self, rows_dropped: u32) {
        self.score += 2 * rows_dropped;
    }

    pub fn score_completed_lines(&mut self, lines: u32) {
        self.score += match lines {
            1 => 100,
            2 => 300,
            3 => 500,
            4 => 800,
            _ => 0
        } * self.get_level();

        self.lines += lines;
    }

    pub fn get_score(&self) -> u32 {
        self.score
    }

    pub fn get_lines(&self) -> u32 {
        self.lines
    }

    pub fn get_level(&self) -> u32 {
        let level = (self.lines / LEVEL_THRESHOLD) + 1;
        min(level, MAX_GAME_LEVEL)
    }
}
impl Display for GameStats {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(
            f, "score: {}, level: {}, lines: {}",
            self.get_score(), self.get_level(), self.get_lines()
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use settings::MAX_GAME_LEVEL;

    #[test]
    fn test_score_completed_lines() {
        let mut stats = GameStats::new();
        stats.score_completed_lines(1);
        assert_eq!(stats.get_score(), 100);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 1);

        stats.score_completed_lines(2);
        assert_eq!(stats.get_score(), 400);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 3);

        stats.score_completed_lines(3);
        assert_eq!(stats.get_score(), 900);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 6);

        stats.score_completed_lines(4);
        assert_eq!(stats.get_score(), 1700);
        assert_eq!(stats.get_level(), 2);
        assert_eq!(stats.get_lines(), 10);
    }

    #[test]
    fn test_score_soft_drop() {
        let mut stats = GameStats::new();
        stats.score_soft_drop();
        assert_eq!(stats.get_score(), 1);
        for _ in 0..20 {
            stats.score_soft_drop();
        }
        assert_eq!(stats.get_score(), 21);
    }

    #[test]
    fn test_score_hard_drop() {
        let mut stats = GameStats::new();
        stats.score_hard_drop(10);
        assert_eq!(stats.get_score(), 20);
    }

    #[test]
    fn test_get_level() {
        let mut stats = GameStats::new();
        assert_eq!(stats.get_level(), 1);
        stats.lines = 89;
        assert_eq!(stats.get_level(), 9);
        stats.lines = 150;
        assert_eq!(stats.get_level(), MAX_GAME_LEVEL);
    }
}

<commit_msg>remove the unused implementation of Display for GameStats. Also found out that the reason I wanted this in the first place would have been solved by using the debug syntax of '{:?}' on println!<commit_after>use std::cmp::min;

use settings::MAX_GAME_LEVEL;

const LEVEL_THRESHOLD: u32 = 10;

pub struct GameStats {
    score: u32,
    lines: u32,
}
impl GameStats {
    pub fn new() -> GameStats {
        GameStats {
            score: 0,
            lines: 0
        }
    }

    pub fn score_soft_drop(&mut self) {
        self.score += 1;
    }

    pub fn score_hard_drop(&mut self, rows_dropped: u32) {
        self.score += 2 * rows_dropped;
    }

    pub fn score_completed_lines(&mut self, lines: u32) {
        self.score += match lines {
            1 => 100,
            2 => 300,
            3 => 500,
            4 => 800,
            _ => 0
        } * self.get_level();

        self.lines += lines;
    }

    pub fn get_score(&self) -> u32 {
        self.score
    }

    pub fn get_lines(&self) -> u32 {
        self.lines
    }

    pub fn get_level(&self) -> u32 {
        let level = (self.lines / LEVEL_THRESHOLD) + 1;
        min(level, MAX_GAME_LEVEL)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use settings::MAX_GAME_LEVEL;

    #[test]
    fn test_score_completed_lines() {
        let mut stats = GameStats::new();
        stats.score_completed_lines(1);
        assert_eq!(stats.get_score(), 100);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 1);

        stats.score_completed_lines(2);
        assert_eq!(stats.get_score(), 400);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 3);

        stats.score_completed_lines(3);
        assert_eq!(stats.get_score(), 900);
        assert_eq!(stats.get_level(), 1);
        assert_eq!(stats.get_lines(), 6);

        stats.score_completed_lines(4);
        assert_eq!(stats.get_score(), 1700);
        assert_eq!(stats.get_level(), 2);
        assert_eq!(stats.get_lines(), 10);
    }

    #[test]
    fn test_score_soft_drop() {
        let mut stats = GameStats::new();
        stats.score_soft_drop();
        assert_eq!(stats.get_score(), 1);
        for _ in 0..20 {
            stats.score_soft_drop();
        }
        assert_eq!(stats.get_score(), 21);
    }

    #[test]
    fn test_score_hard_drop() {
        let mut stats = GameStats::new();
        stats.score_hard_drop(10);
        assert_eq!(stats.get_score(), 20);
    }

    #[test]
    fn test_get_level() {
        let mut stats = GameStats::new();
        assert_eq!(stats.get_level(), 1);
        stats.lines = 89;
        assert_eq!(stats.get_level(), 9);
        stats.lines = 150;
        assert_eq!(stats.get_level(), MAX_GAME_LEVEL);
    }
}

<|endoftext|>


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

// chameneos

extern mod extra;

use extra::sort;
use std::cell::Cell;
use std::comm::*;
use std::io;
use std::option;
use std::os;
use std::task;
use std::uint;
use std::vec;

fn print_complements() {
    let all = [Blue, Red, Yellow];
    for all.iter().advance |aa| {
        for all.iter().advance |bb| {
            println(show_color(*aa) + " + " + show_color(*bb) +
                    " -> " + show_color(transform(*aa, *bb)));
        }
    }
}

enum color { Red, Yellow, Blue }

struct CreatureInfo {
    name: uint,
    color: color
}

fn show_color(cc: color) -> ~str {
    match (cc) {
        Red    => {~"red"}
        Yellow => {~"yellow"}
        Blue   => {~"blue"}
    }
}

fn show_color_list(set: ~[color]) -> ~str {
    let mut out = ~"";
    for set.iter().advance |col| {
        out += " ";
        out += show_color(*col);
    }
    return out;
}

fn show_digit(nn: uint) -> ~str {
    match (nn) {
        0 => {~"zero"}
        1 => {~"one"}
        2 => {~"two"}
        3 => {~"three"}
        4 => {~"four"}
        5 => {~"five"}
        6 => {~"six"}
        7 => {~"seven"}
        8 => {~"eight"}
        9 => {~"nine"}
        _ => {fail!("expected digits from 0 to 9...")}
    }
}

fn show_number(nn: uint) -> ~str {
    let mut out = ~"";
    let mut num = nn;
    let mut dig;

    if num == 0 { out = show_digit(0) };

    while num != 0 {
        dig = num % 10;
        num = num / 10;
        out = show_digit(dig) + " " + out;
    }

    return out;
}

fn transform(aa: color, bb: color) -> color {
    match (aa, bb) {
        (Red,    Red   ) => { Red    }
        (Red,    Yellow) => { Blue   }
        (Red,    Blue  ) => { Yellow }
        (Yellow, Red   ) => { Blue   }
        (Yellow, Yellow) => { Yellow }
        (Yellow, Blue  ) => { Red    }
        (Blue,   Red   ) => { Yellow }
        (Blue,   Yellow) => { Red    }
        (Blue,   Blue  ) => { Blue   }
    }
}

fn creature(
    name: uint,
    color: color,
    from_rendezvous: Port<Option<CreatureInfo>>,
    to_rendezvous: SharedChan<CreatureInfo>,
    to_rendezvous_log: SharedChan<~str>
) {
    let mut color = color;
    let mut creatures_met = 0;
    let mut evil_clones_met = 0;

    loop {
        // ask for a pairing
        to_rendezvous.send(CreatureInfo {name: name, color: color});
        let resp = from_rendezvous.recv();

        // log and change, or print and quit
        match resp {
            option::Some(other_creature) => {
                color = transform(color, other_creature.color);

                // track some statistics
                creatures_met += 1;
                if other_creature.name == name {
                   evil_clones_met += 1;
                }
            }
            option::None => {
                // log creatures met and evil clones of self
                let report = fmt!("%u %s",
                                  creatures_met, show_number(evil_clones_met));
                to_rendezvous_log.send(report);
                break;
            }
        }
    }
}

fn rendezvous(nn: uint, set: ~[color]) {

    // these ports will allow us to hear from the creatures
    let (from_creatures, to_rendezvous) = stream::<CreatureInfo>();
    let to_rendezvous = SharedChan::new(to_rendezvous);
    let (from_creatures_log, to_rendezvous_log) = stream::<~str>();
    let to_rendezvous_log = SharedChan::new(to_rendezvous_log);

    // these channels will be passed to the creatures so they can talk to us

    // these channels will allow us to talk to each creature by 'name'/index
    let to_creature: ~[Chan<Option<CreatureInfo>>] =
        vec::mapi(set, |ii, col| {
            // create each creature as a listener with a port, and
            // give us a channel to talk to each
            let ii = ii;
            let col = *col;
            let to_rendezvous = to_rendezvous.clone();
            let to_rendezvous_log = to_rendezvous_log.clone();
            let (from_rendezvous, to_creature) = stream();
            let from_rendezvous = Cell::new(from_rendezvous);
            do task::spawn || {
                creature(ii, col, from_rendezvous.take(), to_rendezvous.clone(),
                         to_rendezvous_log.clone());
            }
            to_creature
        });

    let mut creatures_met = 0;

    // set up meetings...
    for nn.times {
        let fst_creature: CreatureInfo = from_creatures.recv();
        let snd_creature: CreatureInfo = from_creatures.recv();

        creatures_met += 2;

        to_creature[fst_creature.name].send(Some(snd_creature));
        to_creature[snd_creature.name].send(Some(fst_creature));
    }

    // tell each creature to stop
    for to_creature.iter().advance |to_one| {
        to_one.send(None);
    }

    // save each creature's meeting stats
    let mut report = ~[];
    for vec::each(to_creature) |_to_one| {
        report.push(from_creatures_log.recv());
    }

    // print each color in the set
    io::println(show_color_list(set));

    // print each creature's stats
    for vec::each(report) |rep| {
        io::println(*rep);
    }

    // print the total number of creatures met
    io::println(show_number(creatures_met));
}

fn main() {
    let args = os::args();
    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"200000"]
    } else if args.len() <= 1u {
        ~[~"", ~"600"]
    } else {
        args
    };

    let nn = uint::from_str(args[1]).get();

    print_complements();
    io::println(~"");

    rendezvous(nn, ~[Blue, Red, Yellow]);
    io::println(~"");

    rendezvous(nn,
        ~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
}
<commit_msg>Changed shootout-chameneos-redux output to conform to the 'official' output format.<commit_after>// Copyright 2012 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.

// chameneos

extern mod extra;

use extra::sort;
use std::cell::Cell;
use std::comm::*;
use std::io;
use std::option;
use std::os;
use std::task;
use std::uint;
use std::vec;

fn print_complements() {
    let all = [Blue, Red, Yellow];
    for all.iter().advance |aa| {
        for all.iter().advance |bb| {
            println(show_color(*aa) + " + " + show_color(*bb) +
                    " -> " + show_color(transform(*aa, *bb)));
        }
    }
}

enum color { Red, Yellow, Blue }

struct CreatureInfo {
    name: uint,
    color: color
}

fn show_color(cc: color) -> ~str {
    match (cc) {
        Red    => {~"red"}
        Yellow => {~"yellow"}
        Blue   => {~"blue"}
    }
}

fn show_color_list(set: ~[color]) -> ~str {
    let mut out = ~"";
    for set.iter().advance |col| {
        out += " ";
        out += show_color(*col);
    }
    return out;
}

fn show_digit(nn: uint) -> ~str {
    match (nn) {
        0 => {~"zero"}
        1 => {~"one"}
        2 => {~"two"}
        3 => {~"three"}
        4 => {~"four"}
        5 => {~"five"}
        6 => {~"six"}
        7 => {~"seven"}
        8 => {~"eight"}
        9 => {~"nine"}
        _ => {fail!("expected digits from 0 to 9...")}
    }
}

fn show_number(nn: uint) -> ~str {
    let mut out = ~"";
    let mut num = nn;
    let mut dig;

    if num == 0 { out = show_digit(0) };

    while num != 0 {
        dig = num % 10;
        num = num / 10;
        out = show_digit(dig) + " " + out;
    }

    return ~" " + out;
}

fn transform(aa: color, bb: color) -> color {
    match (aa, bb) {
        (Red,    Red   ) => { Red    }
        (Red,    Yellow) => { Blue   }
        (Red,    Blue  ) => { Yellow }
        (Yellow, Red   ) => { Blue   }
        (Yellow, Yellow) => { Yellow }
        (Yellow, Blue  ) => { Red    }
        (Blue,   Red   ) => { Yellow }
        (Blue,   Yellow) => { Red    }
        (Blue,   Blue  ) => { Blue   }
    }
}

fn creature(
    name: uint,
    color: color,
    from_rendezvous: Port<Option<CreatureInfo>>,
    to_rendezvous: SharedChan<CreatureInfo>,
    to_rendezvous_log: SharedChan<~str>
) {
    let mut color = color;
    let mut creatures_met = 0;
    let mut evil_clones_met = 0;

    loop {
        // ask for a pairing
        to_rendezvous.send(CreatureInfo {name: name, color: color});
        let resp = from_rendezvous.recv();

        // log and change, or print and quit
        match resp {
            option::Some(other_creature) => {
                color = transform(color, other_creature.color);

                // track some statistics
                creatures_met += 1;
                if other_creature.name == name {
                   evil_clones_met += 1;
                }
            }
            option::None => {
                // log creatures met and evil clones of self
                let report = fmt!("%u %s",
                                  creatures_met, show_number(evil_clones_met));
                to_rendezvous_log.send(report);
                break;
            }
        }
    }
}

fn rendezvous(nn: uint, set: ~[color]) {

    // these ports will allow us to hear from the creatures
    let (from_creatures, to_rendezvous) = stream::<CreatureInfo>();
    let to_rendezvous = SharedChan::new(to_rendezvous);
    let (from_creatures_log, to_rendezvous_log) = stream::<~str>();
    let to_rendezvous_log = SharedChan::new(to_rendezvous_log);

    // these channels will be passed to the creatures so they can talk to us

    // these channels will allow us to talk to each creature by 'name'/index
    let to_creature: ~[Chan<Option<CreatureInfo>>] =
        vec::mapi(set, |ii, col| {
            // create each creature as a listener with a port, and
            // give us a channel to talk to each
            let ii = ii;
            let col = *col;
            let to_rendezvous = to_rendezvous.clone();
            let to_rendezvous_log = to_rendezvous_log.clone();
            let (from_rendezvous, to_creature) = stream();
            let from_rendezvous = Cell::new(from_rendezvous);
            do task::spawn || {
                creature(ii, col, from_rendezvous.take(), to_rendezvous.clone(),
                         to_rendezvous_log.clone());
            }
            to_creature
        });

    let mut creatures_met = 0;

    // set up meetings...
    for nn.times {
        let fst_creature: CreatureInfo = from_creatures.recv();
        let snd_creature: CreatureInfo = from_creatures.recv();

        creatures_met += 2;

        to_creature[fst_creature.name].send(Some(snd_creature));
        to_creature[snd_creature.name].send(Some(fst_creature));
    }

    // tell each creature to stop
    for to_creature.iter().advance |to_one| {
        to_one.send(None);
    }

    // save each creature's meeting stats
    let mut report = ~[];
    for vec::each(to_creature) |_to_one| {
        report.push(from_creatures_log.recv());
    }

    // print each color in the set
    io::println(show_color_list(set));

    // print each creature's stats
    for vec::each(report) |rep| {
        io::println(*rep);
    }

    // print the total number of creatures met
    io::println(show_number(creatures_met));
}

fn main() {
    let args = os::args();
    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"200000"]
    } else if args.len() <= 1u {
        ~[~"", ~"600"]
    } else {
        args
    };

    let nn = uint::from_str(args[1]).get();

    print_complements();
    io::println(~"");

    rendezvous(nn, ~[Blue, Red, Yellow]);
    io::println(~"");

    rendezvous(nn,
        ~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
}
<|endoftext|>


<commit_before>// xfail-pretty

// Copyright 2012 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.

/**
 * Test performance of killing many tasks in a taskgroup.
 * Along the way, tests various edge cases of ancestor group management.
 * In particular, this tries to get each grandchild task to hit the
 * "nobe_is_dead" case in each_ancestor only during task exit, but not during
 * task spawn. This makes sure that defunct ancestor groups are handled correctly
 * w.r.t. possibly leaving stale *rust_tasks lying around.
 */

// Creates in the background 'num_tasks' tasks, all blocked forever.
// Doesn't return until all such tasks are ready, but doesn't block forever itself.

use std::comm::*;
use std::os;
use std::result;
use std::task;
use std::uint;

fn grandchild_group(num_tasks: uint) {
    let (po, ch) = stream();
    let ch = SharedChan::new(ch);

    for _ in range(0, num_tasks) {
        let ch = ch.clone();
        do task::spawn { // linked
            ch.send(());
            let (p, _c) = stream::<()>();
            p.recv(); // block forever
        }
    }
    error!("Grandchild group getting started");
    for _ in range(0, num_tasks) {
        // Make sure all above children are fully spawned; i.e., enlisted in
        // their ancestor groups.
        po.recv();
    }
    error!("Grandchild group ready to go.");
    // Master grandchild task exits early.
}

fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
    let mut res = None;
    let mut builder = task::task();
    builder.future_result(|r| res = Some(r));
    builder.supervised();
    builder.spawn(f);
    error!("%s group waiting", myname);
    let x = res.unwrap().recv();
    assert_eq!(x, task::Success);
}

fn main() {
    let args = os::args();
    let args = if os::getenv("RUST_BENCH").is_some() {
        ~[~"", ~"100000"]
    } else if args.len() <= 1u {
        ~[~"", ~"100"]
    } else {
        args.clone()
    };

    let num_tasks = uint::from_str(args[1]).unwrap();

    // Main group #0 waits for unsupervised group #1.
    // Grandparent group #1 waits for middle group #2, then fails, killing #3.
    // Middle group #2 creates grandchild_group #3, waits for it to be ready, exits.
    let x: result::Result<(),()> = do task::try { // unlinked
        do spawn_supervised_blocking("grandparent") {
            do spawn_supervised_blocking("middle") {
                grandchild_group(num_tasks);
            }
            // When grandchild group is ready to go, make the middle group exit.
            error!("Middle group wakes up and exits");
        }
        // Grandparent group waits for middle group to be gone, then fails
        error!("Grandparent group wakes up and fails");
        fail!();
    };
    assert!(x.is_err());
}
<commit_msg>test: Fix deadlock in task-perf-linked-failure<commit_after>// xfail-pretty

// Copyright 2012 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.

/**
 * Test performance of killing many tasks in a taskgroup.
 * Along the way, tests various edge cases of ancestor group management.
 * In particular, this tries to get each grandchild task to hit the
 * "nobe_is_dead" case in each_ancestor only during task exit, but not during
 * task spawn. This makes sure that defunct ancestor groups are handled correctly
 * w.r.t. possibly leaving stale *rust_tasks lying around.
 */

// Creates in the background 'num_tasks' tasks, all blocked forever.
// Doesn't return until all such tasks are ready, but doesn't block forever itself.

use std::comm::*;
use std::os;
use std::result;
use std::task;
use std::uint;

fn grandchild_group(num_tasks: uint) {
    let (po, ch) = stream();
    let ch = SharedChan::new(ch);

    for _ in range(0, num_tasks) {
        let ch = ch.clone();
        let mut t = task::task();
        t.linked();
        t.unwatched();
        do t.spawn { // linked
            ch.send(());
            let (p, _c) = stream::<()>();
            p.recv(); // block forever
        }
    }
    error!("Grandchild group getting started");
    for _ in range(0, num_tasks) {
        // Make sure all above children are fully spawned; i.e., enlisted in
        // their ancestor groups.
        po.recv();
    }
    error!("Grandchild group ready to go.");
    // Master grandchild task exits early.
}

fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
    let mut res = None;
    let mut builder = task::task();
    builder.future_result(|r| res = Some(r));
    builder.supervised();
    builder.spawn(f);
    error!("%s group waiting", myname);
    let x = res.unwrap().recv();
    assert_eq!(x, task::Success);
}

fn main() {
    let args = os::args();
    let args = if os::getenv("RUST_BENCH").is_some() {
        ~[~"", ~"100000"]
    } else if args.len() <= 1u {
        ~[~"", ~"100"]
    } else {
        args.clone()
    };

    let num_tasks = uint::from_str(args[1]).unwrap();

    // Main group #0 waits for unsupervised group #1.
    // Grandparent group #1 waits for middle group #2, then fails, killing #3.
    // Middle group #2 creates grandchild_group #3, waits for it to be ready, exits.
    let x: result::Result<(),()> = do task::try { // unlinked
        do spawn_supervised_blocking("grandparent") {
            do spawn_supervised_blocking("middle") {
                grandchild_group(num_tasks);
            }
            // When grandchild group is ready to go, make the middle group exit.
            error!("Middle group wakes up and exits");
        }
        // Grandparent group waits for middle group to be gone, then fails
        error!("Grandparent group wakes up and fails");
        fail!();
    };
    assert!(x.is_err());
}
<|endoftext|>


<commit_before>use BitField;

#[test]
fn test_integer_bit_lengths() {
    assert_eq!(u8::bit_length(), 8);
    assert_eq!(u16::bit_length(), 16);
    assert_eq!(u32::bit_length(), 32);
    assert_eq!(u64::bit_length(), 64);

    assert_eq!(i8::bit_length(), 8);
    assert_eq!(i16::bit_length(), 16);
    assert_eq!(i32::bit_length(), 32);
    assert_eq!(i64::bit_length(), 64);
}

#[test]
fn test_set_reset_u8() {
    let mut field = 0b11110010u8;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..8 {
        bit_i(i);
    }
}

#[test]
fn test_set_reset_u16() {
    let mut field = 0b1111001010010110u16;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..16 {
        bit_i(i);
    }
}

#[test]
fn test_read_u32() {
    let field = 0b1111111111010110u32;
    assert_eq!(field.get_bit(0), false);
    assert_eq!(field.get_bit(1), true);
    assert_eq!(field.get_bit(2), true);
    assert_eq!(field.get_bit(3), false);
    assert_eq!(field.get_bit(4), true);
    assert_eq!(field.get_bit(5), false);
    for i in 6..16 {
        assert_eq!(field.get_bit(i), true);
    }
    for i in 16..32 {
        assert_eq!(field.get_bit(i), false);
    }

    assert_eq!(field.get_bits(16..32), 0);
    assert_eq!(field.get_bits(6..16), 0b1111111111);
    assert_eq!(field.get_bits(0..6), 0b010110);
    assert_eq!(field.get_bits(0..10), 0b1111010110);
    assert_eq!(field.get_bits(5..12), 0b1111110);
}

#[test]
fn test_set_reset_u32() {
    let mut field = 0b1111111111010110u32;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..32 {
        bit_i(i);
    }
}

#[test]
fn test_set_range_u32() {
    let mut field = 0b1111111111010110u32;
    field.set_bits(10..15, 0b00000);
    assert_eq!(field.get_bits(10..15), 0b00000);
    field.set_bits(10..15, 0b10101);
    assert_eq!(field.get_bits(10..15), 0b10101);
    field.set_bits(10..15, 0b01010);
    assert_eq!(field.get_bits(10..15), 0b01010);
    field.set_bits(10..15, 0b11111);
    assert_eq!(field.get_bits(10..15), 0b11111);

    field.set_bits(0..16, 0xdead);
    field.set_bits(14..32, 0xbeaf);
    assert_eq!(field.get_bits(0..16), 0xdead);
    assert_eq!(field.get_bits(14..32), 0xbeaf);
}

#[test]
fn test_read_u64() {
    let field = 0b1111111111010110u64 << 32;
    for i in 0..32 {
        assert_eq!(field.get_bit(i), false);
    }
    assert_eq!(field.get_bit(32), false);
    assert_eq!(field.get_bit(33), true);
    assert_eq!(field.get_bit(34), true);
    assert_eq!(field.get_bit(35), false);
    assert_eq!(field.get_bit(36), true);
    assert_eq!(field.get_bit(37), false);
    for i in 38..48 {
        assert_eq!(field.get_bit(i), true);
    }
    for i in 48..64 {
        assert_eq!(field.get_bit(i), false);
    }

    assert_eq!(field.get_bits(0..32), 0);
    assert_eq!(field.get_bits(48..64), 0);
    assert_eq!(field.get_bits(38..48), 0b1111111111);
    assert_eq!(field.get_bits(32..38), 0b010110);
    assert_eq!(field.get_bits(32..42), 0b1111010110);
    assert_eq!(field.get_bits(37..44), 0b1111110);
}

#[test]
fn test_set_reset_u64() {
    let mut field = 0b1111111111010110u64 << 32;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..64 {
        bit_i(i);
    }
}

#[test]
fn test_set_range_u64() {
    let mut field = 0b1111111111010110u64 << 32;
    field.set_bits(42..47, 0b00000);
    assert_eq!(field.get_bits(42..47), 0b00000);
    field.set_bits(10..15, 0b10101);
    assert_eq!(field.get_bits(10..15), 0b10101);
    field.set_bits(40..45, 0b01010);
    assert_eq!(field.get_bits(40..45), 0b01010);
    field.set_bits(40..45, 0b11111);
    assert_eq!(field.get_bits(40..45), 0b11111);

    field.set_bits(0..16, 0xdead);
    field.set_bits(14..32, 0xbeaf);
    field.set_bits(32..64, 0xcafebabe);
    assert_eq!(field.get_bits(0..16), 0xdead);
    assert_eq!(field.get_bits(14..32), 0xbeaf);
    assert_eq!(field.get_bits(32..64), 0xcafebabe);
}
<commit_msg>Added some tests to get things going<commit_after>use BitField;
use BitArray;

#[test]
fn test_integer_bit_lengths() {
    assert_eq!(u8::bit_length(), 8);
    assert_eq!(u16::bit_length(), 16);
    assert_eq!(u32::bit_length(), 32);
    assert_eq!(u64::bit_length(), 64);

    assert_eq!(i8::bit_length(), 8);
    assert_eq!(i16::bit_length(), 16);
    assert_eq!(i32::bit_length(), 32);
    assert_eq!(i64::bit_length(), 64);
}

#[test]
fn test_set_reset_u8() {
    let mut field = 0b11110010u8;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..8 {
        bit_i(i);
    }
}

#[test]
fn test_set_reset_u16() {
    let mut field = 0b1111001010010110u16;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..16 {
        bit_i(i);
    }
}

#[test]
fn test_read_u32() {
    let field = 0b1111111111010110u32;
    assert_eq!(field.get_bit(0), false);
    assert_eq!(field.get_bit(1), true);
    assert_eq!(field.get_bit(2), true);
    assert_eq!(field.get_bit(3), false);
    assert_eq!(field.get_bit(4), true);
    assert_eq!(field.get_bit(5), false);
    for i in 6..16 {
        assert_eq!(field.get_bit(i), true);
    }
    for i in 16..32 {
        assert_eq!(field.get_bit(i), false);
    }

    assert_eq!(field.get_bits(16..32), 0);
    assert_eq!(field.get_bits(6..16), 0b1111111111);
    assert_eq!(field.get_bits(0..6), 0b010110);
    assert_eq!(field.get_bits(0..10), 0b1111010110);
    assert_eq!(field.get_bits(5..12), 0b1111110);
}

#[test]
fn test_set_reset_u32() {
    let mut field = 0b1111111111010110u32;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..32 {
        bit_i(i);
    }
}

#[test]
fn test_set_range_u32() {
    let mut field = 0b1111111111010110u32;
    field.set_bits(10..15, 0b00000);
    assert_eq!(field.get_bits(10..15), 0b00000);
    field.set_bits(10..15, 0b10101);
    assert_eq!(field.get_bits(10..15), 0b10101);
    field.set_bits(10..15, 0b01010);
    assert_eq!(field.get_bits(10..15), 0b01010);
    field.set_bits(10..15, 0b11111);
    assert_eq!(field.get_bits(10..15), 0b11111);

    field.set_bits(0..16, 0xdead);
    field.set_bits(14..32, 0xbeaf);
    assert_eq!(field.get_bits(0..16), 0xdead);
    assert_eq!(field.get_bits(14..32), 0xbeaf);
}

#[test]
fn test_read_u64() {
    let field = 0b1111111111010110u64 << 32;
    for i in 0..32 {
        assert_eq!(field.get_bit(i), false);
    }
    assert_eq!(field.get_bit(32), false);
    assert_eq!(field.get_bit(33), true);
    assert_eq!(field.get_bit(34), true);
    assert_eq!(field.get_bit(35), false);
    assert_eq!(field.get_bit(36), true);
    assert_eq!(field.get_bit(37), false);
    for i in 38..48 {
        assert_eq!(field.get_bit(i), true);
    }
    for i in 48..64 {
        assert_eq!(field.get_bit(i), false);
    }

    assert_eq!(field.get_bits(0..32), 0);
    assert_eq!(field.get_bits(48..64), 0);
    assert_eq!(field.get_bits(38..48), 0b1111111111);
    assert_eq!(field.get_bits(32..38), 0b010110);
    assert_eq!(field.get_bits(32..42), 0b1111010110);
    assert_eq!(field.get_bits(37..44), 0b1111110);
}

#[test]
fn test_set_reset_u64() {
    let mut field = 0b1111111111010110u64 << 32;
    let mut bit_i = |i| {
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
        field.set_bit(i, false);
        assert_eq!(field.get_bit(i), false);
        field.set_bit(i, true);
        assert_eq!(field.get_bit(i), true);
    };
    for i in 0..64 {
        bit_i(i);
    }
}

#[test]
fn test_set_range_u64() {
    let mut field = 0b1111111111010110u64 << 32;
    field.set_bits(42..47, 0b00000);
    assert_eq!(field.get_bits(42..47), 0b00000);
    field.set_bits(10..15, 0b10101);
    assert_eq!(field.get_bits(10..15), 0b10101);
    field.set_bits(40..45, 0b01010);
    assert_eq!(field.get_bits(40..45), 0b01010);
    field.set_bits(40..45, 0b11111);
    assert_eq!(field.get_bits(40..45), 0b11111);

    field.set_bits(0..16, 0xdead);
    field.set_bits(14..32, 0xbeaf);
    field.set_bits(32..64, 0xcafebabe);
    assert_eq!(field.get_bits(0..16), 0xdead);
    assert_eq!(field.get_bits(14..32), 0xbeaf);
    assert_eq!(field.get_bits(32..64), 0xcafebabe);
}

#[test]
fn test_array_length() {
    assert_eq!((&[2u8, 3u8, 4u8]).bit_length(), 24);
    assert_eq!((&[2i8, 3i8, 4i8, 5i8]).bit_length(), 32);

    assert_eq!((&[2u16, 3u16, 4u16]).bit_length(), 48);
    assert_eq!((&[2i16, 3i16, 4i16, 5i16]).bit_length(), 64);

    assert_eq!((&[2u32, 3u32, 4u32]).bit_length(), 96);
    assert_eq!((&[2i32, 3i32, 4i32, 5i32]).bit_length(), 128);

    assert_eq!((&[2u64, 3u64, 4u64]).bit_length(), 192);
    assert_eq!((&[2i64, 3i64, 4i64, 5i64]).bit_length(), 256);
}

#[test]
fn test_get_array() {
    let mut test_val = [0xffu8];
    &test_val.set_bit(0,false);
    assert_eq!(test_val, [0xfeu8]);
    &test_val.set_bit(4,false);
    assert_eq!(test_val, [0xeeu8]);

    let mut test_array = [0xffu8, 0x00u8, 0xffu8];
    &test_array.set_bit(7, false);
    &test_array.set_bit(8, true);
    &test_array.set_bit(16, false);

    assert_eq!(test_array, [0x7fu8, 0x01u8, 0xfeu8]);
}
<|endoftext|>