<commit_before>#![feature(test)] // compiletest_rs requires this attribute

use compiletest_rs as compiletest;
use compiletest_rs::common::Mode as TestMode;

use std::env::{self, set_var};
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

mod cargo;

fn host_lib() -> PathBuf {
    if let Some(path) = option_env!("HOST_LIBS") {
        PathBuf::from(path)
    } else {
        cargo::CARGO_TARGET_DIR.join(env!("PROFILE"))
    }
}

fn clippy_driver_path() -> PathBuf {
    if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") {
        PathBuf::from(path)
    } else {
        cargo::TARGET_LIB.join("clippy-driver")
    }
}

// When we'll want to use `extern crate ..` for a dependency that is used
// both by the crate and the compiler itself, we can't simply pass -L flags
// as we'll get a duplicate matching versions. Instead, disambiguate with
// `--extern dep=path`.
// See https://github.com/rust-lang/rust-clippy/issues/4015.
//
// FIXME: We cannot use `cargo build --message-format=json` to resolve to dependency files.
//        Because it would force-rebuild if the options passed to `build` command is not the same
//        as what we manually pass to `cargo` invocation
fn third_party_crates() -> String {
    use std::collections::HashMap;
    static CRATES: &[&str] = &["serde", "serde_derive", "regex", "clippy_lints", "syn", "quote"];
    let dep_dir = cargo::TARGET_LIB.join("deps");
    let mut crates: HashMap<&str, PathBuf> = HashMap::with_capacity(CRATES.len());
    for entry in fs::read_dir(dep_dir).unwrap() {
        let path = match entry {
            Ok(entry) => entry.path(),
            Err(_) => continue,
        };
        if let Some(name) = path.file_name().and_then(OsStr::to_str) {
            for dep in CRATES {
                if name.starts_with(&format!("lib{}-", dep)) && name.ends_with(".rlib") {
                    crates.entry(dep).or_insert(path);
                    break;
                }
            }
        }
    }

    let v: Vec<_> = crates
        .into_iter()
        .map(|(dep, path)| format!("--extern {}={}", dep, path.display()))
        .collect();
    v.join(" ")
}

fn default_config() -> compiletest::Config {
    let mut config = compiletest::Config::default();

    if let Ok(name) = env::var("TESTNAME") {
        config.filter = Some(name);
    }

    if let Some(path) = option_env!("RUSTC_LIB_PATH") {
        let path = PathBuf::from(path);
        config.run_lib_path = path.clone();
        config.compile_lib_path = path;
    }

    config.target_rustcflags = Some(format!(
        "-L {0} -L {1} -Dwarnings -Zui-testing {2}",
        host_lib().join("deps").display(),
        cargo::TARGET_LIB.join("deps").display(),
        third_party_crates(),
    ));

    config.build_base = if cargo::is_rustc_test_suite() {
        // This make the stderr files go to clippy OUT_DIR on rustc repo build dir
        let mut path = PathBuf::from(env!("OUT_DIR"));
        path.push("test_build_base");
        path
    } else {
        host_lib().join("test_build_base")
    };
    config.rustc_path = clippy_driver_path();
    config
}

fn run_mode(cfg: &mut compiletest::Config) {
    cfg.mode = TestMode::Ui;
    cfg.src_base = Path::new("tests").join("ui");
    compiletest::run_tests(&cfg);
}

fn run_ui_toml(config: &mut compiletest::Config) {
    fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
        let mut result = true;
        let opts = compiletest::test_opts(config);
        for dir in fs::read_dir(&config.src_base)? {
            let dir = dir?;
            if !dir.file_type()?.is_dir() {
                continue;
            }
            let dir_path = dir.path();
            set_var("CARGO_MANIFEST_DIR", &dir_path);
            for file in fs::read_dir(&dir_path)? {
                let file = file?;
                let file_path = file.path();
                if file.file_type()?.is_dir() {
                    continue;
                }
                if file_path.extension() != Some(OsStr::new("rs")) {
                    continue;
                }
                let paths = compiletest::common::TestPaths {
                    file: file_path,
                    base: config.src_base.clone(),
                    relative_dir: dir_path.file_name().unwrap().into(),
                };
                let test_name = compiletest::make_test_name(&config, &paths);
                let index = tests
                    .iter()
                    .position(|test| test.desc.name == test_name)
                    .expect("The test should be in there");
                result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
            }
        }
        Ok(result)
    }

    config.mode = TestMode::Ui;
    config.src_base = Path::new("tests").join("ui-toml").canonicalize().unwrap();

    let tests = compiletest::make_tests(&config);

    let res = run_tests(&config, tests);
    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            panic!("I/O failure during tests: {:?}", e);
        },
    }
}

fn run_ui_cargo(config: &mut compiletest::Config) {
    fn run_tests(
        config: &compiletest::Config,
        filter: &Option<String>,
        mut tests: Vec<tester::TestDescAndFn>,
    ) -> Result<bool, io::Error> {
        let mut result = true;
        let opts = compiletest::test_opts(config);

        for dir in fs::read_dir(&config.src_base)? {
            let dir = dir?;
            if !dir.file_type()?.is_dir() {
                continue;
            }

            // Use the filter if provided
            let dir_path = dir.path();
            match &filter {
                Some(name) if !dir_path.ends_with(name) => continue,
                _ => {},
            }

            for case in fs::read_dir(&dir_path)? {
                let case = case?;
                if !case.file_type()?.is_dir() {
                    continue;
                }

                let src_path = case.path().join("src");
                env::set_current_dir(&src_path)?;

                for file in fs::read_dir(&src_path)? {
                    let file = file?;
                    if file.file_type()?.is_dir() {
                        continue;
                    }

                    // Search for the main file to avoid running a test for each file in the project
                    let file_path = file.path();
                    match file_path.file_name().and_then(OsStr::to_str) {
                        Some("main.rs") => {},
                        _ => continue,
                    }

                    let paths = compiletest::common::TestPaths {
                        file: file_path,
                        base: config.src_base.clone(),
                        relative_dir: src_path.strip_prefix(&config.src_base).unwrap().into(),
                    };
                    let test_name = compiletest::make_test_name(&config, &paths);
                    let index = tests
                        .iter()
                        .position(|test| test.desc.name == test_name)
                        .expect("The test should be in there");
                    result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
                }
            }
        }
        Ok(result)
    }

    if cargo::is_rustc_test_suite() {
        return;
    }

    config.mode = TestMode::Ui;
    config.src_base = Path::new("tests").join("ui-cargo").canonicalize().unwrap();

    let tests = compiletest::make_tests(&config);

    let current_dir = env::current_dir().unwrap();
    let filter = env::var("TESTNAME").ok();
    let res = run_tests(&config, &filter, tests);
    env::set_current_dir(current_dir).unwrap();

    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            panic!("I/O failure during tests: {:?}", e);
        },
    }
}

fn prepare_env() {
    set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
    set_var("CLIPPY_TESTS", "true");
    //set_var("RUST_BACKTRACE", "0");
}

#[test]
fn compile_test() {
    prepare_env();
    let mut config = default_config();
    run_mode(&mut config);
    run_ui_toml(&mut config);
    run_ui_cargo(&mut config);
}
<commit_msg>cargo-ui tests: check that <dir>/src exists before processing test<commit_after>#![feature(test)] // compiletest_rs requires this attribute

use compiletest_rs as compiletest;
use compiletest_rs::common::Mode as TestMode;

use std::env::{self, set_var};
use std::ffi::OsStr;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};

mod cargo;

fn host_lib() -> PathBuf {
    if let Some(path) = option_env!("HOST_LIBS") {
        PathBuf::from(path)
    } else {
        cargo::CARGO_TARGET_DIR.join(env!("PROFILE"))
    }
}

fn clippy_driver_path() -> PathBuf {
    if let Some(path) = option_env!("CLIPPY_DRIVER_PATH") {
        PathBuf::from(path)
    } else {
        cargo::TARGET_LIB.join("clippy-driver")
    }
}

// When we'll want to use `extern crate ..` for a dependency that is used
// both by the crate and the compiler itself, we can't simply pass -L flags
// as we'll get a duplicate matching versions. Instead, disambiguate with
// `--extern dep=path`.
// See https://github.com/rust-lang/rust-clippy/issues/4015.
//
// FIXME: We cannot use `cargo build --message-format=json` to resolve to dependency files.
//        Because it would force-rebuild if the options passed to `build` command is not the same
//        as what we manually pass to `cargo` invocation
fn third_party_crates() -> String {
    use std::collections::HashMap;
    static CRATES: &[&str] = &["serde", "serde_derive", "regex", "clippy_lints", "syn", "quote"];
    let dep_dir = cargo::TARGET_LIB.join("deps");
    let mut crates: HashMap<&str, PathBuf> = HashMap::with_capacity(CRATES.len());
    for entry in fs::read_dir(dep_dir).unwrap() {
        let path = match entry {
            Ok(entry) => entry.path(),
            Err(_) => continue,
        };
        if let Some(name) = path.file_name().and_then(OsStr::to_str) {
            for dep in CRATES {
                if name.starts_with(&format!("lib{}-", dep)) && name.ends_with(".rlib") {
                    crates.entry(dep).or_insert(path);
                    break;
                }
            }
        }
    }

    let v: Vec<_> = crates
        .into_iter()
        .map(|(dep, path)| format!("--extern {}={}", dep, path.display()))
        .collect();
    v.join(" ")
}

fn default_config() -> compiletest::Config {
    let mut config = compiletest::Config::default();

    if let Ok(name) = env::var("TESTNAME") {
        config.filter = Some(name);
    }

    if let Some(path) = option_env!("RUSTC_LIB_PATH") {
        let path = PathBuf::from(path);
        config.run_lib_path = path.clone();
        config.compile_lib_path = path;
    }

    config.target_rustcflags = Some(format!(
        "-L {0} -L {1} -Dwarnings -Zui-testing {2}",
        host_lib().join("deps").display(),
        cargo::TARGET_LIB.join("deps").display(),
        third_party_crates(),
    ));

    config.build_base = if cargo::is_rustc_test_suite() {
        // This make the stderr files go to clippy OUT_DIR on rustc repo build dir
        let mut path = PathBuf::from(env!("OUT_DIR"));
        path.push("test_build_base");
        path
    } else {
        host_lib().join("test_build_base")
    };
    config.rustc_path = clippy_driver_path();
    config
}

fn run_mode(cfg: &mut compiletest::Config) {
    cfg.mode = TestMode::Ui;
    cfg.src_base = Path::new("tests").join("ui");
    compiletest::run_tests(&cfg);
}

fn run_ui_toml(config: &mut compiletest::Config) {
    fn run_tests(config: &compiletest::Config, mut tests: Vec<tester::TestDescAndFn>) -> Result<bool, io::Error> {
        let mut result = true;
        let opts = compiletest::test_opts(config);
        for dir in fs::read_dir(&config.src_base)? {
            let dir = dir?;
            if !dir.file_type()?.is_dir() {
                continue;
            }
            let dir_path = dir.path();
            set_var("CARGO_MANIFEST_DIR", &dir_path);
            for file in fs::read_dir(&dir_path)? {
                let file = file?;
                let file_path = file.path();
                if file.file_type()?.is_dir() {
                    continue;
                }
                if file_path.extension() != Some(OsStr::new("rs")) {
                    continue;
                }
                let paths = compiletest::common::TestPaths {
                    file: file_path,
                    base: config.src_base.clone(),
                    relative_dir: dir_path.file_name().unwrap().into(),
                };
                let test_name = compiletest::make_test_name(&config, &paths);
                let index = tests
                    .iter()
                    .position(|test| test.desc.name == test_name)
                    .expect("The test should be in there");
                result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
            }
        }
        Ok(result)
    }

    config.mode = TestMode::Ui;
    config.src_base = Path::new("tests").join("ui-toml").canonicalize().unwrap();

    let tests = compiletest::make_tests(&config);

    let res = run_tests(&config, tests);
    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            panic!("I/O failure during tests: {:?}", e);
        },
    }
}

fn run_ui_cargo(config: &mut compiletest::Config) {
    fn run_tests(
        config: &compiletest::Config,
        filter: &Option<String>,
        mut tests: Vec<tester::TestDescAndFn>,
    ) -> Result<bool, io::Error> {
        let mut result = true;
        let opts = compiletest::test_opts(config);

        for dir in fs::read_dir(&config.src_base)? {
            let dir = dir?;
            if !dir.file_type()?.is_dir() {
                continue;
            }

            // Use the filter if provided
            let dir_path = dir.path();
            match &filter {
                Some(name) if !dir_path.ends_with(name) => continue,
                _ => {},
            }

            for case in fs::read_dir(&dir_path)? {
                let case = case?;
                if !case.file_type()?.is_dir() {
                    continue;
                }

                let src_path = case.path().join("src");

                // When switching between branches, if the previous branch had a test
                // that the current branch does not have, the directory is not removed
                // because an ignored Cargo.lock file exists.
                if !src_path.exists() {
                    continue;
                }

                env::set_current_dir(&src_path)?;
                for file in fs::read_dir(&src_path)? {
                    let file = file?;
                    if file.file_type()?.is_dir() {
                        continue;
                    }

                    // Search for the main file to avoid running a test for each file in the project
                    let file_path = file.path();
                    match file_path.file_name().and_then(OsStr::to_str) {
                        Some("main.rs") => {},
                        _ => continue,
                    }

                    let paths = compiletest::common::TestPaths {
                        file: file_path,
                        base: config.src_base.clone(),
                        relative_dir: src_path.strip_prefix(&config.src_base).unwrap().into(),
                    };
                    let test_name = compiletest::make_test_name(&config, &paths);
                    let index = tests
                        .iter()
                        .position(|test| test.desc.name == test_name)
                        .expect("The test should be in there");
                    result &= tester::run_tests_console(&opts, vec![tests.swap_remove(index)])?;
                }
            }
        }
        Ok(result)
    }

    if cargo::is_rustc_test_suite() {
        return;
    }

    config.mode = TestMode::Ui;
    config.src_base = Path::new("tests").join("ui-cargo").canonicalize().unwrap();

    let tests = compiletest::make_tests(&config);

    let current_dir = env::current_dir().unwrap();
    let filter = env::var("TESTNAME").ok();
    let res = run_tests(&config, &filter, tests);
    env::set_current_dir(current_dir).unwrap();

    match res {
        Ok(true) => {},
        Ok(false) => panic!("Some tests failed"),
        Err(e) => {
            panic!("I/O failure during tests: {:?}", e);
        },
    }
}

fn prepare_env() {
    set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
    set_var("CLIPPY_TESTS", "true");
    //set_var("RUST_BACKTRACE", "0");
}

#[test]
fn compile_test() {
    prepare_env();
    let mut config = default_config();
    run_mode(&mut config);
    run_ui_toml(&mut config);
    run_ui_cargo(&mut config);
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "nightly", feature(lang_items, core_intrinsics, panic_implementation))]
#![cfg_attr(feature = "nightly", no_std)]
#![cfg_attr(feature = "nightly", no_main)]

// Pull in the system libc library for what crt0.o likely requires.
extern crate libc;
extern crate raw_cpuid;

#[cfg(feature = "nightly")]
use core::panic::PanicInfo;

#[cfg(feature = "nightly")]
#[no_mangle]
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    let _c = raw_cpuid::CpuId::new();
    0
}

#[cfg(not(feature = "nightly"))]
fn main() {
    let _c = raw_cpuid::CpuId::new();
}

#[cfg(feature = "nightly")]
#[cfg_attr(feature = "nightly", lang = "eh_personality")]
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}

#[cfg(feature = "nightly")]
#[cfg_attr(feature = "nightly", lang = "eh_unwind_resume")]
#[no_mangle]
pub extern "C" fn rust_eh_unwind_resume() {}

#[cfg(feature = "nightly")]
#[cfg_attr(feature = "nightly", panic_implementation)]
fn panic_impl(_info: &PanicInfo) -> ! {
    loop {}
}
<commit_msg>Remove unneeded cfg_attrs.<commit_after>#![cfg_attr(feature = "nightly", feature(lang_items, core_intrinsics, panic_implementation))]
#![cfg_attr(feature = "nightly", no_std)]
#![cfg_attr(feature = "nightly", no_main)]

// Pull in the system libc library for what crt0.o likely requires.
extern crate libc;
extern crate raw_cpuid;

#[cfg(feature = "nightly")]
use core::panic::PanicInfo;

#[cfg(feature = "nightly")]
#[no_mangle]
pub extern "C" fn main(_argc: i32, _argv: *const *const u8) -> i32 {
    let _c = raw_cpuid::CpuId::new();
    0
}

#[cfg(not(feature = "nightly"))]
fn main() {
    let _c = raw_cpuid::CpuId::new();
}

#[cfg(feature = "nightly")]
#[lang = "eh_personality"]
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}

#[cfg(feature = "nightly")]
#[lang = "eh_unwind_resume"]
#[no_mangle]
pub extern "C" fn rust_eh_unwind_resume() {}

#[cfg(feature = "nightly")]
#[panic_implementation]
fn panic_impl(_info: &PanicInfo) -> ! {
    loop {}
}
<|endoftext|>


<commit_before>extern mod extra;

use std::from_str::from_str;
use std::io::net::ip::SocketAddr;
use std::io::net::tcp::TcpListener;
use std::io::{Acceptor,Listener};
use std::run::{Process,ProcessOptions};

use extra::url::Url;

fn main() {
        let address = "127.0.0.1:7777";
        let addr: SocketAddr = from_str(address).expect(format!("Invalid address: {}", address));
        let listener = TcpListener::bind(addr).expect(format!("Failed to bind to: {}", address));
        let mut acceptor = listener.listen().expect("Could not listen");
        loop {
                let mut tcpStream = acceptor.accept().expect("Could not accept connection");
                let message = tcpStream.read_to_str();
                for line in message.lines() {
                        // println!("Got message: {}", line);
                        let url: Option<Url> = from_str(line);
                        match url {
                                None     => { println("No Url found") }
                                Some(u)  => {
                                        // println!("Found Url in: {}", line);
                                        if checkUrl(&u) {
                                                spawnProcess(&u, "firefox")
                                        }
                                }
                        }
                }
        }
}

fn checkUrl(u: &Url) -> bool {
        (u.scheme == ~"http" || u.scheme == ~"https" )
                && u.host != ~""
}

fn spawnProcess(u: &Url, command: &'static str) {
        // println!("{} {}", command, u.to_str());
        let pOptions = ProcessOptions::new();
        let mut child = Process::new(command, [u.to_str()], pOptions).expect("Could not fork process");
        child.finish();
}<commit_msg>Add comments and fix minor issues<commit_after>extern mod extra;

use std::from_str::from_str;
use std::io::net::ip::SocketAddr;
use std::io::net::tcp::TcpListener;
use std::io::{Acceptor,Listener};
use std::run::{Process,ProcessOptions};

use extra::url::Url;

// Note: Error handling should be improved
fn main() {
        let browserCommand = "firefox";
        let address = "127.0.0.1:7777";

        // Prepare a socket listening on localhost:7777
        let addr: SocketAddr = from_str(address).expect(format!("Invalid address: {}", address));
        let listener = TcpListener::bind(addr).expect(format!("Failed to bind to: {}", address));
        let mut acceptor = listener.listen().expect("Could not listen");

        // Infinite loop to keep handling new connections.
        loop {
                let mut tcpStream = acceptor.accept().expect("Could not accept connection");
                debug!("Accepted new connection");

                // Note that as soon as read_to_str() returns, everything sent
                // to the socket after this point will be discarded as once
                // we're done working with the content we've just read, the
                // tcpStream will be freed at the end of the current loop
                // iteration.
                let message = tcpStream.read_to_str();

                // Iterate over the lines in the received message
                for line in message.lines() {
                        debug!("Current line is: {}", line);

                        // This tries to convert the line to a Url struct
                        let url: Option<Url> = from_str(line);

                        // If this fails, it returns None, else we got a valid
                        // URL
                        match url {
                                None     => { info!("No Url found") }
                                Some(u)  => {
                                        debug!("Found Url in: {}", line);
                                        if checkUrl(&u) {
                                                spawnProcess(&u, browserCommand)
                                        }
                                }
                        }
                }
        }
}

// Check that the URL is actually usable
fn checkUrl(u: &Url) -> bool {
        (u.scheme == ~"http" || u.scheme == ~"https" )
                && u.host != ~""
}

// Spawn a browser to access the URL
fn spawnProcess(u: &Url, command: &'static str) {
        debug!("Spawning process {} {}", command, u.to_str());
        let pOptions = ProcessOptions::new();
        let mut child = Process::new(command, [u.to_str()], pOptions).expect("Could not fork process");
        child.finish();
}<|endoftext|>


<commit_before>//! # Usage
//!
//! See `examples`.

#[macro_export]
macro_rules! color_spec {
    ($($tt:tt)*) => {
        $crate::_color_spec_inner!(@acc(::termcolor::ColorSpec::new().set_reset(false)), @rest($($tt)*))
    };
}

#[macro_export]
macro_rules! _color_spec_inner {
    (@acc($acc:expr), @rest()) => {
        $acc
    };
    (@acc($acc:expr), @rest(, $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Fg($color:expr) $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_fg(::std::option::Option::Some($color))), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Bg($color:expr) $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_bg(::std::option::Option::Some($color))), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Bold $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_bold(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Italic $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_italic(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Underline $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_underline(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Intense $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_intense(true)), @rest($($rest)*))
    };
}

pub mod judge;
pub mod testsuite;
pub mod web;
<commit_msg>Make `_color_spec_inner!` `#[doc(hidden)]`<commit_after>//! # Usage
//!
//! See `examples`.

#[macro_export]
macro_rules! color_spec {
    ($($tt:tt)*) => {
        $crate::_color_spec_inner!(@acc(::termcolor::ColorSpec::new().set_reset(false)), @rest($($tt)*))
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! _color_spec_inner {
    (@acc($acc:expr), @rest()) => {
        $acc
    };
    (@acc($acc:expr), @rest(, $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Fg($color:expr) $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_fg(::std::option::Option::Some($color))), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Bg($color:expr) $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_bg(::std::option::Option::Some($color))), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Bold $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_bold(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Italic $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_italic(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Underline $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_underline(true)), @rest($($rest)*))
    };
    (@acc($acc:expr), @rest(Intense $($rest:tt)*)) => {
        $crate::_color_spec_inner!(@acc($acc.set_intense(true)), @rest($($rest)*))
    };
}

pub mod judge;
pub mod testsuite;
pub mod web;
<|endoftext|>


<commit_before>#![feature(slice_concat_ext, custom_test_frameworks)]
// Custom test runner, to avoid libtest being wrapped around compiletest which wraps libtest.
#![test_runner(test_runner)]

use std::slice::SliceConcatExt;
use std::path::{PathBuf, Path};
use std::env;

use compiletest_rs as compiletest;
use colored::*;

fn miri_path() -> PathBuf {
    if rustc_test_suite().is_some() {
        PathBuf::from(option_env!("MIRI_PATH").unwrap())
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/miri"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn mk_config(mode: &str) -> compiletest::common::ConfigWithTemp {
    let mut config = compiletest::Config::default().tempdir();
    config.mode = mode.parse().expect("Invalid mode");
    config.rustc_path = miri_path();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    config.filter = env::args().nth(1);
    config.host = get_host();
    config
}

fn compile_fail(path: &str, target: &str, opt: bool) {
    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running compile-fail tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());

    let mut flags = Vec::new();
    flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
    flags.push("--edition 2018".to_owned());
    if opt {
        // Optimizing too aggressivley makes UB detection harder, but test at least
        // the default value.
        // FIXME: Opt level 3 ICEs during stack trace generation.
        flags.push("-Zmir-opt-level=1".to_owned());
    }

    let mut config = mk_config("compile-fail");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, opt: bool) {
    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running run-pass tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());

    let mut flags = Vec::new();
    flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
    flags.push("--edition 2018".to_owned());
    if opt {
        // FIXME: We use opt level 1 because MIR inlining defeats the validation
        // whitelist.
        flags.push("-Zmir-opt-level=1".to_owned());
    }

    let mut config = mk_config("ui");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

/// Make sure the MIRI_SYSROOT env var is set
fn set_sysroot() {
    if std::env::var("MIRI_SYSROOT").is_ok() {
        // Nothing to do
        return;
    }
    let sysroot = std::process::Command::new("rustc")
        .arg("--print")
        .arg("sysroot")
        .output()
        .expect("rustc not found")
        .stdout;
    let sysroot = String::from_utf8(sysroot).expect("sysroot is not utf8");
    std::env::set_var("MIRI_SYSROOT", sysroot.trim());
}

fn get_host() -> String {
    let rustc = rustc_test_suite().unwrap_or(PathBuf::from("rustc"));
    let rustc_version = std::process::Command::new(rustc)
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let rustc_version = std::str::from_utf8(&rustc_version).expect("rustc -vV is not utf8");
    let version_meta = rustc_version::version_meta_for(&rustc_version)
        .expect("failed to parse rustc version info");
    version_meta.host
}

fn get_target() -> String {
    std::env::var("MIRI_TARGET").unwrap_or_else(|_| get_host())
}

fn run_pass_miri(opt: bool) {
    miri_pass("tests/run-pass", &get_target(), opt);
}

fn compile_fail_miri(opt: bool) {
    compile_fail("tests/compile-fail", &get_target(), opt);
}

fn test_runner(_tests: &[&()]) {
    set_sysroot();

    run_pass_miri(false);
    run_pass_miri(true);

    compile_fail_miri(false);
    compile_fail_miri(true);
}
<commit_msg>fix warning<commit_after>#![feature(slice_concat_ext, custom_test_frameworks)]
// Custom test runner, to avoid libtest being wrapped around compiletest which wraps libtest.
#![test_runner(test_runner)]

use std::slice::SliceConcatExt;
use std::path::PathBuf;
use std::env;

use compiletest_rs as compiletest;
use colored::*;

fn miri_path() -> PathBuf {
    if rustc_test_suite().is_some() {
        PathBuf::from(option_env!("MIRI_PATH").unwrap())
    } else {
        PathBuf::from(concat!("target/", env!("PROFILE"), "/miri"))
    }
}

fn rustc_test_suite() -> Option<PathBuf> {
    option_env!("RUSTC_TEST_SUITE").map(PathBuf::from)
}

fn rustc_lib_path() -> PathBuf {
    option_env!("RUSTC_LIB_PATH").unwrap().into()
}

fn mk_config(mode: &str) -> compiletest::common::ConfigWithTemp {
    let mut config = compiletest::Config::default().tempdir();
    config.mode = mode.parse().expect("Invalid mode");
    config.rustc_path = miri_path();
    if rustc_test_suite().is_some() {
        config.run_lib_path = rustc_lib_path();
        config.compile_lib_path = rustc_lib_path();
    }
    config.filter = env::args().nth(1);
    config.host = get_host();
    config
}

fn compile_fail(path: &str, target: &str, opt: bool) {
    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running compile-fail tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());

    let mut flags = Vec::new();
    flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
    flags.push("--edition 2018".to_owned());
    if opt {
        // Optimizing too aggressivley makes UB detection harder, but test at least
        // the default value.
        // FIXME: Opt level 3 ICEs during stack trace generation.
        flags.push("-Zmir-opt-level=1".to_owned());
    }

    let mut config = mk_config("compile-fail");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, opt: bool) {
    let opt_str = if opt { " with optimizations" } else { "" };
    eprintln!("{}", format!(
        "## Running run-pass tests in {} against miri for target {}{}",
        path,
        target,
        opt_str
    ).green().bold());

    let mut flags = Vec::new();
    flags.push("-Dwarnings -Dunused".to_owned()); // overwrite the -Aunused in compiletest-rs
    flags.push("--edition 2018".to_owned());
    if opt {
        // FIXME: We use opt level 1 because MIR inlining defeats the validation
        // whitelist.
        flags.push("-Zmir-opt-level=1".to_owned());
    }

    let mut config = mk_config("ui");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.target_rustcflags = Some(flags.join(" "));
    compiletest::run_tests(&config);
}

/// Make sure the MIRI_SYSROOT env var is set
fn set_sysroot() {
    if std::env::var("MIRI_SYSROOT").is_ok() {
        // Nothing to do
        return;
    }
    let sysroot = std::process::Command::new("rustc")
        .arg("--print")
        .arg("sysroot")
        .output()
        .expect("rustc not found")
        .stdout;
    let sysroot = String::from_utf8(sysroot).expect("sysroot is not utf8");
    std::env::set_var("MIRI_SYSROOT", sysroot.trim());
}

fn get_host() -> String {
    let rustc = rustc_test_suite().unwrap_or(PathBuf::from("rustc"));
    let rustc_version = std::process::Command::new(rustc)
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let rustc_version = std::str::from_utf8(&rustc_version).expect("rustc -vV is not utf8");
    let version_meta = rustc_version::version_meta_for(&rustc_version)
        .expect("failed to parse rustc version info");
    version_meta.host
}

fn get_target() -> String {
    std::env::var("MIRI_TARGET").unwrap_or_else(|_| get_host())
}

fn run_pass_miri(opt: bool) {
    miri_pass("tests/run-pass", &get_target(), opt);
}

fn compile_fail_miri(opt: bool) {
    compile_fail("tests/compile-fail", &get_target(), opt);
}

fn test_runner(_tests: &[&()]) {
    set_sysroot();

    run_pass_miri(false);
    run_pass_miri(true);

    compile_fail_miri(false);
    compile_fail_miri(true);
}
<|endoftext|>


<commit_before>#[cfg(feature="http-client")] extern crate hyper;
extern crate wikipedia;

#[cfg(feature = "http-client")]
mod tests {
    use wikipedia::Wikipedia;
    use wikipedia::http;
    use std::collections::HashSet;

    fn w() -> Wikipedia<http::hyper::Client> {
        Wikipedia::default()
    }

    #[test]
    fn search() {
        let wikipedia = w();
        let results = wikipedia.search("hello world").unwrap();
        assert!(results.len() > 0);
        assert!(results.contains(&"\"Hello, World!\" program".to_owned()));
    }

    #[test]
    fn geosearch() {
        let wikipedia = w();
        let results = wikipedia.geosearch(-34.603333, -58.381667, 10).unwrap();
        assert!(results.len() > 0);
        assert!(results.contains(&"Buenos Aires".to_owned()));
    }

    #[test]
    fn random() {
        let wikipedia = w();
        wikipedia.random().unwrap().unwrap();
    }

    #[test]
    fn random_count() {
        let wikipedia = w();
        assert_eq!(wikipedia.random_count(3).unwrap().len(), 3);
    }

    #[test]
    fn page_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert!(page.get_content().unwrap().contains("bikeshedding"));
    }

    #[test]
    fn title() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert_eq!(page.get_title().unwrap(), "Parkinson's law of triviality".to_owned());
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(page.get_title().unwrap(), "Parkinson's law of triviality".to_owned());
    }

    #[test]
    fn pageid() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
    }

    #[test]
    fn page_html_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        let html = page.get_html_content().unwrap();
        assert!(html.contains("bikeshedding"));
        assert!(html.contains("
")); // it would not be html otherwise
    }

    #[test]
    fn page_summary() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        let summary = page.get_summary().unwrap();
        let content = page.get_content().unwrap();
        assert!(summary.contains("bikeshedding"));
        assert!(summary.len() < content.len());
    }

    #[test]
    fn page_redirect_summary() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        let summary = page.get_summary().unwrap();
        let content = page.get_content().unwrap();
        assert!(summary.contains("bikeshedding"));
        assert!(summary.len() < content.len());
    }

    #[test]
    fn page_images() {
        let mut wikipedia = w();
        wikipedia.images_results = "5".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let images = page.get_images().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for i in images {
            assert!(i.title.len() > 0);
            assert!(i.url.len() > 0);
            assert!(i.description_url.len() > 0);
            c += 1;
            set.insert(i.title);
            if c == 11 {
                break;
            }
        }
        assert_eq!(set.len(), 11);
    }

    #[test]
    fn coordinates() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("San Francisco".to_owned());
        let (lat, lon) = page.get_coordinates().unwrap().unwrap();
        assert!(lat > 0.0);
        assert!(lon < 0.0);
    }

    #[test]
    fn no_coordinates() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert!(page.get_coordinates().unwrap().is_none());
    }

    #[test]
    fn references() {
        let mut wikipedia = w();
        wikipedia.links_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let references = page.get_references().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for r in references {
            assert!(r.url.starts_with("http"));
            c += 1;
            set.insert(r.url);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn links() {
        let mut wikipedia = w();
        wikipedia.links_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let links = page.get_links().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for r in links {
            c += 1;
            set.insert(r.title);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn categories() {
        let mut wikipedia = w();
        wikipedia.categories_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let categories = page.get_links().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for ca in categories {
            c += 1;
            set.insert(ca.title);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn sections() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert_eq!(
                page.get_sections().unwrap(),
                vec![
                "Argument".to_owned(),
                "Examples".to_owned(),
                "Related principles and formulations".to_owned(),
                "See also".to_owned(),
                "References".to_owned(),
                "Further reading".to_owned(),
                "External links".to_owned(),
                ]
                )
    }

    #[test]
    fn sections2() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(
                page.get_sections().unwrap(),
                vec![
                "Argument".to_owned(),
                "Examples".to_owned(),
                "Related principles and formulations".to_owned(),
                "See also".to_owned(),
                "References".to_owned(),
                "Further reading".to_owned(),
                "External links".to_owned(),
                ]
                )
    }

    #[test]
    fn section_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert!(page.get_section_content("Examples").unwrap().unwrap()
                .contains("finance committee meeting"))
    }

    #[test]
    fn languages() {
        let languages = w().get_languages().unwrap();
        assert!(languages.contains(&("en".to_owned(), "English".to_owned())));
        assert!(languages.contains(&("es".to_owned(), "español".to_owned())));
    }
}
<commit_msg>Fix tests<commit_after>#[cfg(feature="http-client")] extern crate hyper;
extern crate wikipedia;

#[cfg(feature = "http-client")]
mod tests {
    use wikipedia::Wikipedia;
    use wikipedia::http;
    use std::collections::HashSet;

    fn w() -> Wikipedia<http::hyper::Client> {
        Wikipedia::default()
    }

    #[test]
    fn search() {
        let wikipedia = w();
        let results = wikipedia.search("hello world").unwrap();
        assert!(results.len() > 0);
        assert!(results.contains(&"\"Hello, World!\" program".to_owned()));
    }

    #[test]
    fn geosearch() {
        let wikipedia = w();
        let results = wikipedia.geosearch(-34.603333, -58.381667, 10).unwrap();
        assert!(results.len() > 0);
        assert!(results.contains(&"Buenos Aires".to_owned()));
    }

    #[test]
    fn random() {
        let wikipedia = w();
        wikipedia.random().unwrap().unwrap();
    }

    #[test]
    fn random_count() {
        let wikipedia = w();
        assert_eq!(wikipedia.random_count(3).unwrap().len(), 3);
    }

    #[test]
    fn page_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert!(page.get_content().unwrap().contains("bike-shedding"));
    }

    #[test]
    fn title() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert_eq!(page.get_title().unwrap(), "Parkinson's law of triviality".to_owned());
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(page.get_title().unwrap(), "Law of triviality".to_owned());
    }

    #[test]
    fn pageid() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(page.get_pageid().unwrap(), "4138548".to_owned());
    }

    #[test]
    fn page_html_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        let html = page.get_html_content().unwrap();
        assert!(html.contains("bike-shedding"));
        assert!(html.contains("
")); // it would not be html otherwise
    }

    #[test]
    fn page_summary() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Parkinson's law of triviality".to_owned());
        let summary = page.get_summary().unwrap();
        let content = page.get_content().unwrap();
        assert!(summary.contains("bike-shedding"));
        assert!(summary.len() < content.len());
    }

    #[test]
    fn page_redirect_summary() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        let summary = page.get_summary().unwrap();
        let content = page.get_content().unwrap();
        assert!(summary.contains("bike-shedding"));
        assert!(summary.len() < content.len());
    }

    #[test]
    fn page_images() {
        let mut wikipedia = w();
        wikipedia.images_results = "5".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let images = page.get_images().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for i in images {
            assert!(i.title.len() > 0);
            assert!(i.url.len() > 0);
            assert!(i.description_url.len() > 0);
            c += 1;
            set.insert(i.title);
            if c == 11 {
                break;
            }
        }
        assert_eq!(set.len(), 11);
    }

    #[test]
    fn coordinates() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("San Francisco".to_owned());
        let (lat, lon) = page.get_coordinates().unwrap().unwrap();
        assert!(lat > 0.0);
        assert!(lon < 0.0);
    }

    #[test]
    fn no_coordinates() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert!(page.get_coordinates().unwrap().is_none());
    }

    #[test]
    fn references() {
        let mut wikipedia = w();
        wikipedia.links_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let references = page.get_references().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for r in references {
            assert!(r.url.starts_with("http"));
            c += 1;
            set.insert(r.url);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn links() {
        let mut wikipedia = w();
        wikipedia.links_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let links = page.get_links().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for r in links {
            c += 1;
            set.insert(r.title);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn categories() {
        let mut wikipedia = w();
        wikipedia.categories_results = "3".to_owned();
        let page = wikipedia.page_from_title("Argentina".to_owned());
        let categories = page.get_links().unwrap();
        let mut c = 0;
        let mut set = HashSet::new();
        for ca in categories {
            c += 1;
            set.insert(ca.title);
            if c == 7 {
                break;
            }
        }
        assert_eq!(set.len(), 7);
    }

    #[test]
    fn sections() {
        let wikipedia = w();
        let page = wikipedia.page_from_title("Bikeshedding".to_owned());
        assert_eq!(
                page.get_sections().unwrap(),
                vec![
                "Argument".to_owned(),
                "Examples".to_owned(),
                "Related principles and formulations".to_owned(),
                "See also".to_owned(),
                "References".to_owned(),
                "Further reading".to_owned(),
                "External links".to_owned(),
                ]
                )
    }

    #[test]
    fn sections2() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert_eq!(
                page.get_sections().unwrap(),
                vec![
                "Argument".to_owned(),
                "Examples".to_owned(),
                "Related principles and formulations".to_owned(),
                "See also".to_owned(),
                "References".to_owned(),
                "Further reading".to_owned(),
                "External links".to_owned(),
                ]
                )
    }

    #[test]
    fn section_content() {
        let wikipedia = w();
        let page = wikipedia.page_from_pageid("4138548".to_owned());
        assert!(page.get_section_content("Examples").unwrap().unwrap()
                .contains("finance committee meeting"))
    }

    #[test]
    fn languages() {
        let languages = w().get_languages().unwrap();
        assert!(languages.contains(&("en".to_owned(), "English".to_owned())));
        assert!(languages.contains(&("es".to_owned(), "español".to_owned())));
    }
}
<|endoftext|>


<commit_before>// https://leetcode.com/problems/number-of-valid-clock-times/
pub fn count_time(time: String) -> i32 {
    todo!()
}

fn main() {
    println!("{}", count_time("?5:00".to_string())); // 2
    println!("{}", count_time("0?:0?".to_string())); // 100
    println!("{}", count_time("??:??".to_string())); // 1440
}<commit_msg>Solve problem 2437<commit_after>// https://leetcode.com/problems/number-of-valid-clock-times/
pub fn count_time(time: String) -> i32 {
    let time = time.as_bytes();
    let first = if time[0] == '?' as u8 && time[1] == '?' as u8 {
        "2".to_string()
    } else if time[0] == '?' as u8 && time[1] - '0' as u8 <= 3 {
        "2".to_string()
    } else if time[0] == '?' as u8 && time[1] - '0' as u8 > 3 {
        "1".to_string()
    } else {
        "".to_string()
    };
    let second = if time[0] == '?' as u8 && time[1] == '?' as u8 {
        "3".to_string()
    } else if time[0] == '2' as u8 && time[1] == '?' as u8 {
        "3".to_string()
    } else if (time[0] == '1' as u8 || time[0] == '0' as u8) && time[1] == '?' as u8 {
        "9".to_string()
    } else {
        "".to_string()
    };
    let third = if time[3] == '?' as u8 {
        "5".to_string()
    } else {
        "".to_string()
    };
    let fourth = if time[4] == '?' as u8 {
        "9".to_string()
    } else {
        "".to_string()
    };
    let hours = format!("{}{}", first, second).parse::<i32>().unwrap_or(0);
    let minutes = format!("{}{}", third, fourth).parse::<i32>().unwrap_or(0);
    (hours + 1) * (minutes + 1)
}

fn main() {
    println!("{}", count_time("?5:00".to_string())); // 2
    println!("{}", count_time("0?:0?".to_string())); // 100
    println!("{}", count_time("??:??".to_string())); // 1440
    println!("{}", count_time("0?:??".to_string())); // 600
    println!("{}", count_time("2?:?6".to_string())); // 24
    println!("{}", count_time("1?:26".to_string())); // 10
    println!("{}", count_time("1?:26".to_string())); // 10
    println!("{}", count_time("?3:26".to_string())); // 3
}
<|endoftext|>


<commit_before>use jpeg;
use png;
use std::cmp;
use std::fs::File;
use std::path::Path;

use super::common;

#[test]
fn reftest() {
    let files = common::test_files(&Path::new("tests").join("reftest").join("images"));

    for path in &files {
        reftest_file(path);
    }
}

#[test]
fn reftest_scaled() {
    let base = &Path::new("tests").join("reftest").join("images");
    reftest_scaled_file(&base.join("rgb.jpg"), 500, 333, &base.join("rgb.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 250, 167, &base.join("rgb_250x167.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 125, 84,  &base.join("rgb_125x84.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 63,  42,  &base.join("rgb_63x42.png"));
}

fn reftest_file(path: &Path) {
    let file = File::open(path).unwrap();
    let decoder = jpeg::Decoder::new(file);
    reftest_decoder(decoder, path, &path.with_extension("png"));
}

fn reftest_scaled_file(path: &Path, width: u16, height: u16, ref_path: &Path) {
    let file = File::open(path).unwrap();
    let mut decoder = jpeg::Decoder::new(file);
    decoder.read_info().unwrap();
    decoder.scale(width, height).unwrap();
    reftest_decoder(decoder, path, &ref_path);
}

fn reftest_decoder<T: std::io::Read>(mut decoder: jpeg::Decoder<T>, path: &Path, ref_path: &Path) {
    let mut data = decoder.decode().expect(&format!("failed to decode file: {:?}", path));
    let info = decoder.info().unwrap();
    let mut pixel_format = info.pixel_format;

    if pixel_format == jpeg::PixelFormat::CMYK32 {
        data = cmyk_to_rgb(&data);
        pixel_format = jpeg::PixelFormat::RGB24;
    }

    let ref_file = File::open(ref_path).unwrap();
    let mut decoder = png::Decoder::new(ref_file);

    if ref_path.ends_with("lossless16bit.png") {
        // disable the default 8bit output of png v0.16.8 (changed in master branch of png)
        decoder.set_transformations(png::Transformations::EXPAND);
    }

    let (ref_info, mut ref_reader) = decoder.read_info().expect("png failed to read info");
    println!("ref_info {:?}", ref_info);

    assert_eq!(ref_info.width, info.width as u32);
    assert_eq!(ref_info.height, info.height as u32);

    let mut ref_data = vec![0; ref_info.buffer_size()];
    ref_reader.next_frame(&mut ref_data).expect("png decode failed");
    let mut ref_pixel_format = ref_info.color_type;

    let mut refdatai : Vec<isize> = ref_data.iter().map(|x| *x as isize).collect();

    if ref_pixel_format == png::ColorType::RGBA {
        refdatai = rgba_to_rgb(&refdatai);
        ref_pixel_format = png::ColorType::RGB;
    }

    match pixel_format {
        jpeg::PixelFormat::L8 => {
            assert_eq!(ref_pixel_format, png::ColorType::Grayscale);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Eight);
        },
        jpeg::PixelFormat::L16 => {
            assert_eq!(ref_pixel_format, png::ColorType::Grayscale);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Sixteen);
            refdatai = ref_data.chunks_exact(2).into_iter().map(|a| u16::from_be_bytes([a[0],a[1]])).map(|x| x as isize).collect();
        },
        jpeg::PixelFormat::RGB24 => {
            assert_eq!(ref_pixel_format, png::ColorType::RGB);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Eight);
        },
        _ => panic!(),
    }

    assert_eq!(data.len(), refdatai.len());
    let mut max_diff = 0;
    let pixels: Vec<u8> = data.iter().zip(refdatai.iter()).map(|(&a, &b)| {
        let diff = (a as isize - b as isize).abs();
        max_diff = cmp::max(diff, max_diff);

        // FIXME: Only a diff of 1 should be allowed?
        if diff <= 2 {
            // White for correct
            0xFF
        } else {
            println!("data: {}, ref: {}", a, b);
            // "1100" in the RGBA channel with an error for an incorrect value
            // This results in some number of C0 and FFs, which is much more
            // readable (and distinguishable) than the previous difference-wise
            // scaling but does not require reconstructing the actual RGBA pixel.
            0xC0
        }
    }).collect();

    if pixels.iter().any(|&a| a < 255) {
        let output_path = path.with_file_name(format!("{}-diff.png", path.file_stem().unwrap().to_str().unwrap()));
        let output = File::create(&output_path).unwrap();
        let mut encoder = png::Encoder::new(output, info.width as u32, info.height as u32);
        encoder.set_depth(png::BitDepth::Eight);
        encoder.set_color(ref_pixel_format);
        encoder.write_header().expect("png failed to write header").write_image_data(&pixels).expect("png failed to write data");

        panic!("decoding difference: {:?}, maximum difference was {}", output_path, max_diff);
    }
}

fn rgba_to_rgb(input: &[isize]) -> Vec<isize> {
    let size = input.len() - input.len() / 4;
    let mut output = Vec::with_capacity(size);

    for pixel in input.chunks(4) {
        assert_eq!(pixel[3], 255);

        output.push(pixel[0]);
        output.push(pixel[1]);
        output.push(pixel[2]);
    }

    output
}

fn cmyk_to_rgb(input: &[isize]) -> Vec<isize> {
    let size = input.len() - input.len() / 4;
    let mut output = Vec::with_capacity(size);

    for pixel in input.chunks(4) {
        let c = pixel[0] as f32 / 255.0;
        let m = pixel[1] as f32 / 255.0;
        let y = pixel[2] as f32 / 255.0;
        let k = pixel[3] as f32 / 255.0;

        // CMYK -> CMY
        let c = c * (1.0 - k) + k;
        let m = m * (1.0 - k) + k;
        let y = y * (1.0 - k) + k;

        // CMY -> RGB
        let r = (1.0 - c) * 255.0;
        let g = (1.0 - m) * 255.0;
        let b = (1.0 - y) * 255.0;

        output.push(r as isize);
        output.push(g as isize);
        output.push(b as isize);
    }

    output
}
<commit_msg>generalize png output in 16bit case<commit_after>use jpeg;
use png;
use std::cmp;
use std::fs::File;
use std::path::Path;

use super::common;

#[test]
fn reftest() {
    let files = common::test_files(&Path::new("tests").join("reftest").join("images"));

    for path in &files {
        reftest_file(path);
    }
}

#[test]
fn reftest_scaled() {
    let base = &Path::new("tests").join("reftest").join("images");
    reftest_scaled_file(&base.join("rgb.jpg"), 500, 333, &base.join("rgb.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 250, 167, &base.join("rgb_250x167.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 125, 84,  &base.join("rgb_125x84.png"));
    reftest_scaled_file(&base.join("rgb.jpg"), 63,  42,  &base.join("rgb_63x42.png"));
}

fn reftest_file(path: &Path) {
    let file = File::open(path).unwrap();
    let decoder = jpeg::Decoder::new(file);
    reftest_decoder(decoder, path, &path.with_extension("png"));
}

fn reftest_scaled_file(path: &Path, width: u16, height: u16, ref_path: &Path) {
    let file = File::open(path).unwrap();
    let mut decoder = jpeg::Decoder::new(file);
    decoder.read_info().unwrap();
    decoder.scale(width, height).unwrap();
    reftest_decoder(decoder, path, &ref_path);
}

fn reftest_decoder<T: std::io::Read>(mut decoder: jpeg::Decoder<T>, path: &Path, ref_path: &Path) {
    let mut data = decoder.decode().expect(&format!("failed to decode file: {:?}", path));
    let info = decoder.info().unwrap();
    let mut pixel_format = info.pixel_format;

    if pixel_format == jpeg::PixelFormat::CMYK32 {
        data = cmyk_to_rgb(&data);
        pixel_format = jpeg::PixelFormat::RGB24;
    }

    let ref_file = File::open(ref_path).unwrap();
    let mut decoder = png::Decoder::new(ref_file);

    if pixel_format == jpeg::PixelFormat::L16 {
        // disable the default 8bit output of png v0.16.8 (fixed in master branch of png)
        decoder.set_transformations(png::Transformations::EXPAND);
    }

    let (ref_info, mut ref_reader) = decoder.read_info().expect("png failed to read info");
    println!("ref_info {:?}", ref_info);

    assert_eq!(ref_info.width, info.width as u32);
    assert_eq!(ref_info.height, info.height as u32);

    let mut ref_data = vec![0; ref_info.buffer_size()];
    ref_reader.next_frame(&mut ref_data).expect("png decode failed");
    let mut ref_pixel_format = ref_info.color_type;

    let mut refdatai : Vec<isize> = ref_data.iter().map(|x| *x as isize).collect();

    if ref_pixel_format == png::ColorType::RGBA {
        refdatai = rgba_to_rgb(&refdatai);
        ref_pixel_format = png::ColorType::RGB;
    }

    match pixel_format {
        jpeg::PixelFormat::L8 => {
            assert_eq!(ref_pixel_format, png::ColorType::Grayscale);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Eight);
        },
        jpeg::PixelFormat::L16 => {
            assert_eq!(ref_pixel_format, png::ColorType::Grayscale);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Sixteen);
            refdatai = ref_data.chunks_exact(2).into_iter().map(|a| u16::from_be_bytes([a[0],a[1]])).map(|x| x as isize).collect();
        },
        jpeg::PixelFormat::RGB24 => {
            assert_eq!(ref_pixel_format, png::ColorType::RGB);
            assert_eq!(ref_info.bit_depth, png::BitDepth::Eight);
        },
        _ => panic!(),
    }

    assert_eq!(data.len(), refdatai.len());
    let mut max_diff = 0;
    let pixels: Vec<u8> = data.iter().zip(refdatai.iter()).map(|(&a, &b)| {
        let diff = (a as isize - b as isize).abs();
        max_diff = cmp::max(diff, max_diff);

        // FIXME: Only a diff of 1 should be allowed?
        if diff <= 2 {
            // White for correct
            0xFF
        } else {
            println!("data: {}, ref: {}", a, b);
            // "1100" in the RGBA channel with an error for an incorrect value
            // This results in some number of C0 and FFs, which is much more
            // readable (and distinguishable) than the previous difference-wise
            // scaling but does not require reconstructing the actual RGBA pixel.
            0xC0
        }
    }).collect();

    if pixels.iter().any(|&a| a < 255) {
        let output_path = path.with_file_name(format!("{}-diff.png", path.file_stem().unwrap().to_str().unwrap()));
        let output = File::create(&output_path).unwrap();
        let mut encoder = png::Encoder::new(output, info.width as u32, info.height as u32);
        encoder.set_depth(png::BitDepth::Eight);
        encoder.set_color(ref_pixel_format);
        encoder.write_header().expect("png failed to write header").write_image_data(&pixels).expect("png failed to write data");

        panic!("decoding difference: {:?}, maximum difference was {}", output_path, max_diff);
    }
}

fn rgba_to_rgb(input: &[isize]) -> Vec<isize> {
    let size = input.len() - input.len() / 4;
    let mut output = Vec::with_capacity(size);

    for pixel in input.chunks(4) {
        assert_eq!(pixel[3], 255);

        output.push(pixel[0]);
        output.push(pixel[1]);
        output.push(pixel[2]);
    }

    output
}

fn cmyk_to_rgb(input: &[isize]) -> Vec<isize> {
    let size = input.len() - input.len() / 4;
    let mut output = Vec::with_capacity(size);

    for pixel in input.chunks(4) {
        let c = pixel[0] as f32 / 255.0;
        let m = pixel[1] as f32 / 255.0;
        let y = pixel[2] as f32 / 255.0;
        let k = pixel[3] as f32 / 255.0;

        // CMYK -> CMY
        let c = c * (1.0 - k) + k;
        let m = m * (1.0 - k) + k;
        let y = y * (1.0 - k) + k;

        // CMY -> RGB
        let r = (1.0 - c) * 255.0;
        let g = (1.0 - m) * 255.0;
        let b = (1.0 - y) * 255.0;

        output.push(r as isize);
        output.push(g as isize);
        output.push(b as isize);
    }

    output
}
<|endoftext|>


<commit_before>use super::*;
use crate::{inner::*, norm::*};
use num_traits::Zero;

/// Iterative orthogonalizer using Householder reflection
#[derive(Debug, Clone)]
pub struct Householder {
    /// Dimension of orthogonalizer
    dim: usize,

    /// Store Householder reflector.
    ///
    /// The coefficient is copied into another array, and this does not contain
    v: Vec<Array1>,
}

impl Householder {
    /// Create a new orthogonalizer
    pub fn new(dim: usize) -> Self {
        Householder { dim, v: Vec::new() }
    }

    /// Take a Reflection `P = I - 2ww^T`
    fn fundamental_reflection<S: DataMut<Elem = A>>(&self, k: usize, a: &mut ArrayBase<S, Ix1>) {
        assert!(k < self.v.len());
        assert_eq!(a.len(), self.dim, "Input array size mismaches to the dimension");

        let w = self.v[k].slice(s![k..]);
        let mut a_slice = a.slice_mut(s![k..]);
        let c = A::from(2.0).unwrap() * w.inner(&a_slice);
        for l in 0..self.dim - k {
            a_slice[l] -= c * w[l];
        }
    }

    /// Take forward reflection `P = P_l ... P_1`
    pub fn forward_reflection<S>(&self, a: &mut ArrayBase<S, Ix1>)
    where
        S: DataMut<Elem = A>,
    {
        assert!(a.len() == self.dim);
        let l = self.v.len();
        for k in 0..l {
            self.fundamental_reflection(k, a);
        }
    }

    /// Take backward reflection `P = P_1 ... P_l`
    pub fn backward_reflection<S>(&self, a: &mut ArrayBase<S, Ix1>)
    where
        S: DataMut<Elem = A>,
    {
        assert!(a.len() == self.dim);
        let l = self.v.len();
        for k in (0..l).rev() {
            self.fundamental_reflection(k, a);
        }
    }

    fn eval_residual<S>(&self, a: &ArrayBase<S, Ix1>) -> A::Real
    where
        S: Data<Elem = A>,
    {
        let l = self.v.len();
        if l == self.dim {
            Zero::zero()
        } else {
            a.slice(s![l..]).norm_l2()
        }
    }
}

impl Orthogonalizer for Householder {
    type Elem = A;

    fn dim(&self) -> usize {
        self.dim
    }

    fn len(&self) -> usize {
        self.v.len()
    }

    fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Array1
    where
        S: Data<Elem = A>,
    {
        let mut a = a.into_owned();
        self.forward_reflection(&mut a);
        let res = self.eval_residual(&a);
        let k = self.len();
        let mut c = Array1::zeros(k + 1);
        azip!(mut c(c.slice_mut(s![..k])), a(a.slice(s![..k])) in { *c = a });
        c[k] = A::from_real(res);
        c
    }

    fn append<S>(&mut self, mut a: ArrayBase<S, Ix1>, rtol: A::Real) -> Result<Array1, Array1>
    where
        S: DataMut<Elem = A>,
    {
        assert_eq!(a.len(), self.dim);
        let k = self.len();
        self.forward_reflection(&mut a);
        let alpha = self.eval_residual(&a);
        let mut coef = Array::zeros(k + 1);
        for i in 0..k {
            coef[i] = a[i];
        }
        if alpha < rtol {
            // linearly dependent
            coef[k] = A::from_real(alpha);
            return Err(coef);
        }

        // Add reflector
        assert!(k < a.len()); // this must hold because `alpha == 0` if k >= a.len()
        let alpha = if a[k].abs() > Zero::zero() {
            a[k].mul_real(alpha / a[k].abs())
        } else {
            A::from_real(alpha)
        };
        coef[k] = alpha;

        a[k] -= alpha;
        let norm = a.slice(s![k..]).norm_l2();
        azip!(mut a (a.slice_mut(s![..k])) in { *a = Zero::zero() }); // this can be omitted
        azip!(mut a (a.slice_mut(s![k..])) in { *a = a.div_real(norm) });
        self.v.push(a.into_owned());
        Ok(coef)
    }

    fn get_q(&self) -> Q {
        assert!(self.len() > 0);
        let mut a = Array::zeros((self.dim(), self.len()));
        for (i, mut col) in a.axis_iter_mut(Axis(1)).enumerate() {
            col[i] = A::one();
            self.backward_reflection(&mut col);
        }
        a
    }
}
<commit_msg>Add householder iterative decomposition<commit_after>use super::*;
use crate::{inner::*, norm::*};
use num_traits::Zero;

/// Iterative orthogonalizer using Householder reflection
#[derive(Debug, Clone)]
pub struct Householder {
    /// Dimension of orthogonalizer
    dim: usize,

    /// Store Householder reflector.
    ///
    /// The coefficient is copied into another array, and this does not contain
    v: Vec<Array1>,
}

impl Householder {
    /// Create a new orthogonalizer
    pub fn new(dim: usize) -> Self {
        Householder { dim, v: Vec::new() }
    }

    /// Take a Reflection `P = I - 2ww^T`
    fn fundamental_reflection<S>(&self, k: usize, a: &mut ArrayBase<S, Ix1>)
    where
        S: DataMut<Elem = A>,
    {
        assert!(k < self.v.len());
        assert_eq!(a.len(), self.dim, "Input array size mismaches to the dimension");

        let w = self.v[k].slice(s![k..]);
        let mut a_slice = a.slice_mut(s![k..]);
        let c = A::from(2.0).unwrap() * w.inner(&a_slice);
        for l in 0..self.dim - k {
            a_slice[l] -= c * w[l];
        }
    }

    /// Take forward reflection `P = P_l ... P_1`
    pub fn forward_reflection<S>(&self, a: &mut ArrayBase<S, Ix1>)
    where
        S: DataMut<Elem = A>,
    {
        assert!(a.len() == self.dim);
        let l = self.v.len();
        for k in 0..l {
            self.fundamental_reflection(k, a);
        }
    }

    /// Take backward reflection `P = P_1 ... P_l`
    pub fn backward_reflection<S>(&self, a: &mut ArrayBase<S, Ix1>)
    where
        S: DataMut<Elem = A>,
    {
        assert!(a.len() == self.dim);
        let l = self.v.len();
        for k in (0..l).rev() {
            self.fundamental_reflection(k, a);
        }
    }

    fn eval_residual<S>(&self, a: &ArrayBase<S, Ix1>) -> A::Real
    where
        S: Data<Elem = A>,
    {
        let l = self.v.len();
        if l == self.dim {
            Zero::zero()
        } else {
            a.slice(s![l..]).norm_l2()
        }
    }
}

impl Orthogonalizer for Householder {
    type Elem = A;

    fn dim(&self) -> usize {
        self.dim
    }

    fn len(&self) -> usize {
        self.v.len()
    }

    fn coeff<S>(&self, a: ArrayBase<S, Ix1>) -> Array1
    where
        S: Data<Elem = A>,
    {
        let mut a = a.into_owned();
        self.forward_reflection(&mut a);
        let res = self.eval_residual(&a);
        let k = self.len();
        let mut c = Array1::zeros(k + 1);
        azip!(mut c(c.slice_mut(s![..k])), a(a.slice(s![..k])) in { *c = a });
        c[k] = A::from_real(res);
        c
    }

    fn append<S>(&mut self, mut a: ArrayBase<S, Ix1>, rtol: A::Real) -> Result<Array1, Array1>
    where
        S: DataMut<Elem = A>,
    {
        assert_eq!(a.len(), self.dim);
        let k = self.len();
        self.forward_reflection(&mut a);
        let alpha = self.eval_residual(&a);
        let mut coef = Array::zeros(k + 1);
        for i in 0..k {
            coef[i] = a[i];
        }
        if alpha < rtol {
            // linearly dependent
            coef[k] = A::from_real(alpha);
            return Err(coef);
        }

        // Add reflector
        assert!(k < a.len()); // this must hold because `alpha == 0` if k >= a.len()
        let alpha = if a[k].abs() > Zero::zero() {
            a[k].mul_real(alpha / a[k].abs())
        } else {
            A::from_real(alpha)
        };
        coef[k] = alpha;

        a[k] -= alpha;
        let norm = a.slice(s![k..]).norm_l2();
        azip!(mut a (a.slice_mut(s![..k])) in { *a = Zero::zero() }); // this can be omitted
        azip!(mut a (a.slice_mut(s![k..])) in { *a = a.div_real(norm) });
        self.v.push(a.into_owned());
        Ok(coef)
    }

    fn get_q(&self) -> Q {
        assert!(self.len() > 0);
        let mut a = Array::zeros((self.dim(), self.len()));
        for (i, mut col) in a.axis_iter_mut(Axis(1)).enumerate() {
            col[i] = A::one();
            self.backward_reflection(&mut col);
        }
        a
    }
}

/// Online QR decomposition of vectors
pub fn householder(
    iter: impl Iterator<Item = ArrayBase<S, Ix1>>,
    dim: usize,
    rtol: A::Real,
    strategy: Strategy,
) -> (Q, R)
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    let h = Householder::new(dim);
    qr(iter, h, rtol, strategy)
}
<|endoftext|>


<commit_before>#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
use std::sync::Arc;
use std::fmt::Debug;

fn rc_refcell() {
    let r = Rc::new(RefCell::new(42));
    let r2 = r.clone();
    *r.borrow_mut() += 10;
    let x = *r2.borrow();
    assert_eq!(x, 52);
}

fn rc_cell() {
    let r = Rc::new(Cell::new(42));
    let r2 = r.clone();
    let x = r.get();
    r2.set(x + x);
    assert_eq!(r.get(), 84);
}

fn rc_refcell2() {
    let r = Rc::new(RefCell::new(42));
    let r2 = r.clone();
    *r.borrow_mut() += 10;
    let x = r2.borrow();
    let r3 = r.clone();
    let y = r3.borrow();
    assert_eq!((*x + *y)/2, 52);
}

fn rc_raw() {
    let r = Rc::new(0);
    let r2 = Rc::into_raw(r.clone());
    let r2 = unsafe { Rc::from_raw(r2) };
    assert!(Rc::ptr_eq(&r, &r2));
    drop(r);
    assert!(Rc::try_unwrap(r2).is_ok());
}

fn arc() {
    fn test() -> Arc<i32> {
        let a = Arc::new(42);
        a
    }
    assert_eq!(*test(), 42);
}

// Make sure this Rc doesn't fall apart when touched
fn check_unique_rc<T: ?Sized>(mut r: Rc<T>) {
    let r2 = r.clone();
    assert!(Rc::get_mut(&mut r).is_none());
    drop(r2);
    assert!(Rc::get_mut(&mut r).is_some());
}

fn rc_from() {
    check_unique_rc::<[_]>(Rc::from(&[1,2,3] as &[_]));
    check_unique_rc::<[_]>(Rc::from(vec![1,2,3]));
    check_unique_rc::<[_]>(Rc::from(Box::new([1,2,3]) as Box<[_]>));
    check_unique_rc::<str>(Rc::from("Hello, World!"));
}

fn rc_fat_ptr_eq() {
    let p = Rc::new(1) as Rc<dyn Debug>;
    let a: *const dyn Debug = &*p;
    let r = Rc::into_raw(p);
    assert!(a == r);
    drop(unsafe { Rc::from_raw(r) });
}

/// Taken from the `Weak::into_raw` doctest.
fn weak_into_raw() {
    let strong = Rc::new(42);
    let weak = Rc::downgrade(&strong);
    let raw = Weak::into_raw(weak);

    assert_eq!(1, Rc::weak_count(&strong));
    assert_eq!(42, unsafe { *raw });

    drop(unsafe { Weak::from_raw(raw) });
    assert_eq!(0, Rc::weak_count(&strong));
}

/// Taken from the `Weak::from_raw` doctest.
fn weak_from_raw() {
    let strong = Rc::new(42);

    let raw_1 = Weak::into_raw(Rc::downgrade(&strong));
    let raw_2 = Weak::into_raw(Rc::downgrade(&strong));

    assert_eq!(2, Rc::weak_count(&strong));

    assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
    assert_eq!(1, Rc::weak_count(&strong));

    drop(strong);

    // Decrement the last weak count.
    assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none());
}

fn rc_uninit() {
    let mut five = Rc::<Box<u32>>::new_uninit();
    let five = unsafe {
        // Deferred initialization:
        Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(Box::new(5));
        five.assume_init()
    };
    assert_eq!(**five, 5)
}

fn rc_uninit_slice() {
    let mut values = Rc::<[Box<usize>]>::new_uninit_slice(3);

    let values = unsafe {
        // Deferred initialization:
        Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(Box::new(0));
        Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(Box::new(1));
        Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(Box::new(2));

        values.assume_init()
    };

    for (idx, i) in values.iter().enumerate() {
        assert_eq!(idx, **i);
    }
}

fn main() {
    rc_fat_ptr_eq();
    rc_refcell();
    rc_refcell2();
    rc_cell();
    rc_raw();
    rc_from();
    weak_into_raw();
    weak_from_raw();
    rc_uninit();
    rc_uninit_slice();

    arc();
}
<commit_msg>test Rc with raw pointer tracking<commit_after>// compile-flags: -Zmiri-track-raw-pointers
// ignore-windows (FIXME: tracking raw pointers does not work on Windows)
#![feature(new_uninit)]
#![feature(get_mut_unchecked)]

use std::cell::{Cell, RefCell};
use std::rc::{Rc, Weak};
use std::sync::Arc;
use std::fmt::Debug;

fn rc_refcell() {
    let r = Rc::new(RefCell::new(42));
    let r2 = r.clone();
    *r.borrow_mut() += 10;
    let x = *r2.borrow();
    assert_eq!(x, 52);
}

fn rc_cell() {
    let r = Rc::new(Cell::new(42));
    let r2 = r.clone();
    let x = r.get();
    r2.set(x + x);
    assert_eq!(r.get(), 84);
}

fn rc_refcell2() {
    let r = Rc::new(RefCell::new(42));
    let r2 = r.clone();
    *r.borrow_mut() += 10;
    let x = r2.borrow();
    let r3 = r.clone();
    let y = r3.borrow();
    assert_eq!((*x + *y)/2, 52);
}

fn rc_raw() {
    let r = Rc::new(0);
    let r2 = Rc::into_raw(r.clone());
    let r2 = unsafe { Rc::from_raw(r2) };
    assert!(Rc::ptr_eq(&r, &r2));
    drop(r);
    assert!(Rc::try_unwrap(r2).is_ok());
}

fn arc() {
    fn test() -> Arc<i32> {
        let a = Arc::new(42);
        a
    }
    assert_eq!(*test(), 42);
}

// Make sure this Rc doesn't fall apart when touched
fn check_unique_rc<T: ?Sized>(mut r: Rc<T>) {
    let r2 = r.clone();
    assert!(Rc::get_mut(&mut r).is_none());
    drop(r2);
    assert!(Rc::get_mut(&mut r).is_some());
}

fn rc_from() {
    check_unique_rc::<[_]>(Rc::from(&[1,2,3] as &[_]));
    check_unique_rc::<[_]>(Rc::from(vec![1,2,3]));
    check_unique_rc::<[_]>(Rc::from(Box::new([1,2,3]) as Box<[_]>));
    check_unique_rc::<str>(Rc::from("Hello, World!"));
}

fn rc_fat_ptr_eq() {
    let p = Rc::new(1) as Rc<dyn Debug>;
    let a: *const dyn Debug = &*p;
    let r = Rc::into_raw(p);
    assert!(a == r);
    drop(unsafe { Rc::from_raw(r) });
}

/// Taken from the `Weak::into_raw` doctest.
fn weak_into_raw() {
    let strong = Rc::new(42);
    let weak = Rc::downgrade(&strong);
    let raw = Weak::into_raw(weak);

    assert_eq!(1, Rc::weak_count(&strong));
    assert_eq!(42, unsafe { *raw });

    drop(unsafe { Weak::from_raw(raw) });
    assert_eq!(0, Rc::weak_count(&strong));
}

/// Taken from the `Weak::from_raw` doctest.
fn weak_from_raw() {
    let strong = Rc::new(42);

    let raw_1 = Weak::into_raw(Rc::downgrade(&strong));
    let raw_2 = Weak::into_raw(Rc::downgrade(&strong));

    assert_eq!(2, Rc::weak_count(&strong));

    assert_eq!(42, *Weak::upgrade(&unsafe { Weak::from_raw(raw_1) }).unwrap());
    assert_eq!(1, Rc::weak_count(&strong));

    drop(strong);

    // Decrement the last weak count.
    assert!(Weak::upgrade(&unsafe { Weak::from_raw(raw_2) }).is_none());
}

fn rc_uninit() {
    let mut five = Rc::<Box<u32>>::new_uninit();
    let five = unsafe {
        // Deferred initialization:
        Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(Box::new(5));
        five.assume_init()
    };
    assert_eq!(**five, 5)
}

fn rc_uninit_slice() {
    let mut values = Rc::<[Box<usize>]>::new_uninit_slice(3);

    let values = unsafe {
        // Deferred initialization:
        Rc::get_mut_unchecked(&mut values)[0].as_mut_ptr().write(Box::new(0));
        Rc::get_mut_unchecked(&mut values)[1].as_mut_ptr().write(Box::new(1));
        Rc::get_mut_unchecked(&mut values)[2].as_mut_ptr().write(Box::new(2));

        values.assume_init()
    };

    for (idx, i) in values.iter().enumerate() {
        assert_eq!(idx, **i);
    }
}

fn main() {
    rc_fat_ptr_eq();
    rc_refcell();
    rc_refcell2();
    rc_cell();
    rc_raw();
    rc_from();
    weak_into_raw();
    weak_from_raw();
    rc_uninit();
    rc_uninit_slice();

    arc();
}
<|endoftext|>