<commit_before>extern crate gutenberg;
extern crate tera;

use std::path::Path;

use gutenberg::{FrontMatter, split_content};
use tera::to_value;

#[test]
fn test_can_parse_a_valid_front_matter() {
    let content = r#"
title = "Hello"
description = "hey there""#;
    let res = FrontMatter::parse(content);
    println!("{:?}", res);
    assert!(res.is_ok());
    let res = res.unwrap();
    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.description, "hey there".to_string());
}

#[test]
fn test_can_parse_tags() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"
tags = ["rust", "html"]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();

    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.slug.unwrap(), "hello-world".to_string());
    assert_eq!(res.tags.unwrap(), ["rust".to_string(), "html".to_string()]);
}

#[test]
fn test_can_parse_extra_attributes_in_frontmatter() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"

[extra]
language = "en"
authors = ["Bob", "Alice"]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();

    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.slug.unwrap(), "hello-world".to_string());
    let extra = res.extra.unwrap();
    assert_eq!(extra.get("language").unwrap(), &to_value("en").unwrap());
    assert_eq!(
    extra.get("authors").unwrap(),
    &to_value(["Bob".to_string(), "Alice".to_string()]).unwrap()
    );
}

#[test]
fn test_is_ok_with_url_instead_of_slug() {
    let content = r#"
title = "Hello"
description = "hey there"
url = "hello-world""#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();
    assert!(res.slug.is_none());
    assert_eq!(res.url.unwrap(), "hello-world".to_string());
}

#[test]
fn test_errors_with_empty_front_matter() {
    let content = r#"  "#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_with_invalid_front_matter() {
    let content = r#"title = 1\n"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_with_missing_required_value_front_matter() {
    let content = r#"title = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_non_string_tag() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"
tags = ["rust", 1]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_present_but_empty_slug() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_present_but_empty_url() {
    let content = r#"
title = "Hello"
description = "hey there"
url = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_parse_date_yyyy_mm_dd() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2016-10-10""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_some());
}

#[test]
fn test_parse_date_rfc3339() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2002-10-02T15:00:00Z""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_some());
}

#[test]
fn test_cant_parse_random_date_format() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2002/10/12""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_none());
}

#[test]
fn test_can_split_content_valid() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
+++
Hello
"#;
    let (front_matter, content) = split_content(Path::new(""), content).unwrap();
    assert_eq!(content, "Hello\n");
    assert_eq!(front_matter.title, "Title");
}

#[test]
fn test_can_split_content_with_only_frontmatter_valid() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
+++"#;
    let (front_matter, content) = split_content(Path::new(""), content).unwrap();
    assert_eq!(content, "");
    assert_eq!(front_matter.title, "Title");
}

#[test]
fn test_error_if_cannot_locate_frontmatter() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
"#;
    let res = split_content(Path::new(""), content);
    assert!(res.is_err());
}
<commit_msg>Add regression test for lazy front-matter matching<commit_after>extern crate gutenberg;
extern crate tera;

use std::path::Path;

use gutenberg::{FrontMatter, split_content};
use tera::to_value;

#[test]
fn test_can_parse_a_valid_front_matter() {
    let content = r#"
title = "Hello"
description = "hey there""#;
    let res = FrontMatter::parse(content);
    println!("{:?}", res);
    assert!(res.is_ok());
    let res = res.unwrap();
    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.description, "hey there".to_string());
}

#[test]
fn test_can_parse_tags() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"
tags = ["rust", "html"]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();

    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.slug.unwrap(), "hello-world".to_string());
    assert_eq!(res.tags.unwrap(), ["rust".to_string(), "html".to_string()]);
}

#[test]
fn test_can_parse_extra_attributes_in_frontmatter() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"

[extra]
language = "en"
authors = ["Bob", "Alice"]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();

    assert_eq!(res.title, "Hello".to_string());
    assert_eq!(res.slug.unwrap(), "hello-world".to_string());
    let extra = res.extra.unwrap();
    assert_eq!(extra.get("language").unwrap(), &to_value("en").unwrap());
    assert_eq!(
    extra.get("authors").unwrap(),
    &to_value(["Bob".to_string(), "Alice".to_string()]).unwrap()
    );
}

#[test]
fn test_is_ok_with_url_instead_of_slug() {
    let content = r#"
title = "Hello"
description = "hey there"
url = "hello-world""#;
    let res = FrontMatter::parse(content);
    assert!(res.is_ok());
    let res = res.unwrap();
    assert!(res.slug.is_none());
    assert_eq!(res.url.unwrap(), "hello-world".to_string());
}

#[test]
fn test_errors_with_empty_front_matter() {
    let content = r#"  "#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_with_invalid_front_matter() {
    let content = r#"title = 1\n"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_with_missing_required_value_front_matter() {
    let content = r#"title = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_non_string_tag() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = "hello-world"
tags = ["rust", 1]"#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_present_but_empty_slug() {
    let content = r#"
title = "Hello"
description = "hey there"
slug = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_errors_on_present_but_empty_url() {
    let content = r#"
title = "Hello"
description = "hey there"
url = """#;
    let res = FrontMatter::parse(content);
    assert!(res.is_err());
}

#[test]
fn test_parse_date_yyyy_mm_dd() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2016-10-10""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_some());
}

#[test]
fn test_parse_date_rfc3339() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2002-10-02T15:00:00Z""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_some());
}

#[test]
fn test_cant_parse_random_date_format() {
    let content = r#"
title = "Hello"
description = "hey there"
date = "2002/10/12""#;
    let res = FrontMatter::parse(content).unwrap();
    assert!(res.parse_date().is_none());
}

#[test]
fn test_can_split_content_valid() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
+++
Hello
"#;
    let (front_matter, content) = split_content(Path::new(""), content).unwrap();
    assert_eq!(content, "Hello\n");
    assert_eq!(front_matter.title, "Title");
}

#[test]
fn test_can_split_content_with_only_frontmatter_valid() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
+++"#;
    let (front_matter, content) = split_content(Path::new(""), content).unwrap();
    assert_eq!(content, "");
    assert_eq!(front_matter.title, "Title");
}

#[test]
fn test_can_split_content_lazily() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002-10-02T15:00:00Z"
+++
+++"#;
    let (front_matter, content) = split_content(Path::new(""), content).unwrap();
    assert_eq!(content, "+++");
    assert_eq!(front_matter.title, "Title");
}

#[test]
fn test_error_if_cannot_locate_frontmatter() {
    let content = r#"
+++
title = "Title"
description = "hey there"
date = "2002/10/12"
"#;
    let res = split_content(Path::new(""), content);
    assert!(res.is_err());
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

impl SpecLinkMethods for SpecLink {
    fn Test(&self) -> f32 {
        0
    }
}
<commit_msg>Remove "python/tidy_self_test/speclink.rs" - it already move to "python/tidy/servo_tidy_tests/speclink.rs"<commit_after><|endoftext|>


<commit_before>extern crate bindgen;
extern crate cc;
extern crate glob;

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

fn link(name: &str, bundled: bool) {
    use std::env::var;
    let target = var("TARGET").unwrap();
    let target: Vec<_> = target.split('-').collect();
    if target.get(2) == Some(&"windows") {
        println!("cargo:rustc-link-lib=dylib={}", name);
        if bundled && target.get(3) == Some(&"gnu") {
            let dir = var("CARGO_MANIFEST_DIR").unwrap();
            println!("cargo:rustc-link-search=native={}/{}", dir, target[0]);
        }
    }
}

fn fail_on_empty_directory(name: &str) {
    if fs::read_dir(name).unwrap().count() == 0 {
        println!(
            "The `{}` directory is empty, did you forget to pull the submodules?",
            name
        );
        println!("Try `git submodule update --init --recursive`");
        panic!();
    }
}

fn bindgen_rocksdb() {
    let bindings = bindgen::Builder::default()
        .header("rocksdb/include/rocksdb/c.h")
        .blacklist_type("max_align_t") // https://github.com/rust-lang-nursery/rust-bindgen/issues/550
        .ctypes_prefix("libc")
        .generate()
        .expect("unable to generate rocksdb bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("unable to write rocksdb bindings");
}

fn build_rocksdb() {
    let mut config = cc::Build::new();
    config.include("rocksdb/include/");
    config.include("rocksdb/");
    config.include("rocksdb/third-party/gtest-1.7.0/fused-src/");

    if cfg!(feature = "snappy") {
        config.define("SNAPPY", Some("1"));
        config.include("snappy/");
    }

    if cfg!(feature = "lz4") {
        config.define("LZ4", Some("1"));
        config.include("lz4/lib/");
    }

    if cfg!(feature = "zstd") {
        config.define("ZSTD", Some("1"));
        config.include("zstd/lib/");
        config.include("zstd/lib/dictBuilder/");
    }

    if cfg!(feature = "zlib") {
        config.define("ZLIB", Some("1"));
        config.include("zlib/");
    }

    if cfg!(feature = "bzip2") {
        config.define("BZIP2", Some("1"));
        config.include("bzip2/");
    }

    config.include(".");
    config.define("NDEBUG", Some("1"));

    let mut lib_sources = include_str!("rocksdb_lib_sources.txt")
        .split(" ")
        .collect::<Vec<&'static str>>();

    // We have a pregenerated a version of build_version.cc in the local directory
    lib_sources = lib_sources
        .iter()
        .cloned()
        .filter(|file| *file != "util/build_version.cc")
        .collect::<Vec<&'static str>>();

    if cfg!(target_os = "macos") {
        config.define("OS_MACOSX", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
    }
    if cfg!(target_os = "linux") {
        config.define("OS_LINUX", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
        // COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp"
    }
    if cfg!(target_os = "freebsd") {
        config.define("OS_FREEBSD", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
    }

    if cfg!(target_os = "windows") {
        link("rpcrt4", false);
        link("shlwapi", false);
        config.define("OS_WIN", Some("1"));

        // Remove POSIX-specific sources
        lib_sources = lib_sources
            .iter()
            .cloned()
            .filter(|file| match *file {
                "port/port_posix.cc" | "env/env_posix.cc" | "env/io_posix.cc" => false,
                _ => true,
            })
            .collect::<Vec<&'static str>>();

        // Add Windows-specific sources
        lib_sources.push("port/win/port_win.cc");
        lib_sources.push("port/win/env_win.cc");
        lib_sources.push("port/win/env_default.cc");
        lib_sources.push("port/win/win_logger.cc");
        lib_sources.push("port/win/io_win.cc");
        lib_sources.push("port/win/win_thread.cc");
    }

    if cfg!(target_env = "msvc") {
        config.flag("-EHsc");
    } else {
        config.flag("-std=c++11");
        // this was breaking the build on travis due to
        // > 4mb of warnings emitted.
        config.flag("-Wno-unused-parameter");
    }

    for file in lib_sources {
        let file = "rocksdb/".to_string() + file;
        config.file(&file);
    }

    config.file("build_version.cc");

    config.cpp(true);
    config.compile("librocksdb.a");
}

fn build_snappy() {
    let mut config = cc::Build::new();
    config.include("snappy/");
    config.include(".");

    config.define("NDEBUG", Some("1"));

    if cfg!(target_env = "msvc") {
        config.flag("-EHsc");
    } else {
        config.flag("-std=c++11");
    }

    config.file("snappy/snappy.cc");
    config.file("snappy/snappy-sinksource.cc");
    config.file("snappy/snappy-c.cc");
    config.cpp(true);
    config.compile("libsnappy.a");
}

fn build_lz4() {
    let mut compiler = cc::Build::new();

    compiler
        .file("lz4/lib/lz4.c")
        .file("lz4/lib/lz4frame.c")
        .file("lz4/lib/lz4hc.c")
        .file("lz4/lib/xxhash.c");

    compiler.opt_level(3);

    match env::var("TARGET").unwrap().as_str() {
        "i686-pc-windows-gnu" => {
            compiler.flag("-fno-tree-vectorize");
        }
        _ => {}
    }

    compiler.compile("liblz4.a");
}

fn build_zstd() {
    let mut compiler = cc::Build::new();

    compiler.include("zstd/lib/");
    compiler.include("zstd/lib/common");
    compiler.include("zstd/lib/legacy");

    let globs = &[
        "zstd/lib/common/*.c",
        "zstd/lib/compress/*.c",
        "zstd/lib/decompress/*.c",
        "zstd/lib/dictBuilder/*.c",
        "zstd/lib/legacy/*.c",
    ];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            compiler.file(path);
        }
    }

    compiler.opt_level(3);

    compiler.define("ZSTD_LIB_DEPRECATED", Some("0"));
    compiler.compile("libzstd.a");
}

fn build_zlib() {
    let mut compiler = cc::Build::new();

    let globs = &["zlib/*.c"];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            compiler.file(path);
        }
    }

    compiler.flag_if_supported("-Wno-implicit-function-declaration");
    compiler.opt_level(3);
    compiler.compile("libz.a");
}

fn build_bzip2() {
    let mut compiler = cc::Build::new();

    compiler
        .file("bzip2/blocksort.c")
        .file("bzip2/bzlib.c")
        .file("bzip2/compress.c")
        .file("bzip2/crctable.c")
        .file("bzip2/decompress.c")
        .file("bzip2/huffman.c")
        .file("bzip2/randtable.c");

    compiler
        .define("_FILE_OFFSET_BITS", Some("64"))
        .define("BZ_NO_STDIO", None);

    compiler.extra_warnings(false);
    compiler.opt_level(3);
    compiler.compile("libbz2.a");
}

fn try_to_find_and_link_lib(lib_name: &str) -> bool {
    if let Ok(lib_dir) = env::var(&format!("{}_LIB_DIR", lib_name)) {
        println!("cargo:rustc-link-search=native={}", lib_dir);
        let mode = match env::var_os(&format!("{}_STATIC", lib_name)) {
            Some(_) => "static",
            None => "dylib",
        };
        println!("cargo:rustc-link-lib={}={}", mode, lib_name.to_lowercase());
        return true;
    }
    false
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=rocksdb/");
    println!("cargo:rerun-if-changed=snappy/");
    println!("cargo:rerun-if-changed=lz4/");
    println!("cargo:rerun-if-changed=zstd/");
    println!("cargo:rerun-if-changed=zlib/");
    println!("cargo:rerun-if-changed=bzip2/");

    fail_on_empty_directory("rocksdb");
    fail_on_empty_directory("snappy");
    fail_on_empty_directory("lz4");
    fail_on_empty_directory("zstd");
    fail_on_empty_directory("zlib");
    fail_on_empty_directory("bzip2");

    bindgen_rocksdb();

    if !try_to_find_and_link_lib("ROCKSDB") {
        build_rocksdb();
    }
    if cfg!(feature = "snappy") && !try_to_find_and_link_lib("SNAPPY") {
        build_snappy();
    }
    if cfg!(feature = "lz4") && !try_to_find_and_link_lib("LZ4") {
        build_lz4();
    }
    if cfg!(feature = "zstd") && !try_to_find_and_link_lib("ZSTD") {
        build_zstd();
    }
    if cfg!(feature = "zlib") && !try_to_find_and_link_lib("ZLIB") {
        build_zlib();
    }
    if cfg!(feature = "bzip2") && !try_to_find_and_link_lib("BZIP2") {
        build_bzip2();
    }
}
<commit_msg>enable sse4.2/pclmul for accelerated crc32c<commit_after>extern crate bindgen;
extern crate cc;
extern crate glob;

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

fn link(name: &str, bundled: bool) {
    use std::env::var;
    let target = var("TARGET").unwrap();
    let target: Vec<_> = target.split('-').collect();
    if target.get(2) == Some(&"windows") {
        println!("cargo:rustc-link-lib=dylib={}", name);
        if bundled && target.get(3) == Some(&"gnu") {
            let dir = var("CARGO_MANIFEST_DIR").unwrap();
            println!("cargo:rustc-link-search=native={}/{}", dir, target[0]);
        }
    }
}

fn fail_on_empty_directory(name: &str) {
    if fs::read_dir(name).unwrap().count() == 0 {
        println!(
            "The `{}` directory is empty, did you forget to pull the submodules?",
            name
        );
        println!("Try `git submodule update --init --recursive`");
        panic!();
    }
}

fn bindgen_rocksdb() {
    let bindings = bindgen::Builder::default()
        .header("rocksdb/include/rocksdb/c.h")
        .blacklist_type("max_align_t") // https://github.com/rust-lang-nursery/rust-bindgen/issues/550
        .ctypes_prefix("libc")
        .generate()
        .expect("unable to generate rocksdb bindings");

    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("unable to write rocksdb bindings");
}

fn build_rocksdb() {
    let mut config = cc::Build::new();
    config.include("rocksdb/include/");
    config.include("rocksdb/");
    config.include("rocksdb/third-party/gtest-1.7.0/fused-src/");

    if cfg!(feature = "snappy") {
        config.define("SNAPPY", Some("1"));
        config.include("snappy/");
    }

    if cfg!(feature = "lz4") {
        config.define("LZ4", Some("1"));
        config.include("lz4/lib/");
    }

    if cfg!(feature = "zstd") {
        config.define("ZSTD", Some("1"));
        config.include("zstd/lib/");
        config.include("zstd/lib/dictBuilder/");
    }

    if cfg!(feature = "zlib") {
        config.define("ZLIB", Some("1"));
        config.include("zlib/");
    }

    if cfg!(feature = "bzip2") {
        config.define("BZIP2", Some("1"));
        config.include("bzip2/");
    }

    config.include(".");
    config.define("NDEBUG", Some("1"));

    let mut lib_sources = include_str!("rocksdb_lib_sources.txt")
        .split(" ")
        .collect::<Vec<&'static str>>();

    // We have a pregenerated a version of build_version.cc in the local directory
    lib_sources = lib_sources
        .iter()
        .cloned()
        .filter(|file| *file != "util/build_version.cc")
        .collect::<Vec<&'static str>>();

    if cfg!(target_arch = "x86_64") {
        // This is needed to enable hardware CRC32C. Technically, SSE 4.2 is
        // only available since Intel Nehalem (about 2010) and AMD Bulldozer
        // (about 2011).
        config.define("HAVE_PCLMUL", Some("1"));
        config.define("HAVE_SSE42", Some("1"));
        config.flag("-msse2");
        config.flag("-msse4.1");
        config.flag("-msse4.2");
        config.flag("-mpclmul");
    }

    if cfg!(target_os = "macos") {
        config.define("OS_MACOSX", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
    }
    if cfg!(target_os = "linux") {
        config.define("OS_LINUX", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
        // COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp"
    }
    if cfg!(target_os = "freebsd") {
        config.define("OS_FREEBSD", Some("1"));
        config.define("ROCKSDB_PLATFORM_POSIX", Some("1"));
        config.define("ROCKSDB_LIB_IO_POSIX", Some("1"));
    }

    if cfg!(target_os = "windows") {
        link("rpcrt4", false);
        link("shlwapi", false);
        config.define("OS_WIN", Some("1"));

        // Remove POSIX-specific sources
        lib_sources = lib_sources
            .iter()
            .cloned()
            .filter(|file| match *file {
                "port/port_posix.cc" | "env/env_posix.cc" | "env/io_posix.cc" => false,
                _ => true,
            })
            .collect::<Vec<&'static str>>();

        // Add Windows-specific sources
        lib_sources.push("port/win/port_win.cc");
        lib_sources.push("port/win/env_win.cc");
        lib_sources.push("port/win/env_default.cc");
        lib_sources.push("port/win/win_logger.cc");
        lib_sources.push("port/win/io_win.cc");
        lib_sources.push("port/win/win_thread.cc");
    }

    if cfg!(target_env = "msvc") {
        config.flag("-EHsc");
    } else {
        config.flag("-std=c++11");
        // this was breaking the build on travis due to
        // > 4mb of warnings emitted.
        config.flag("-Wno-unused-parameter");
    }

    for file in lib_sources {
        let file = "rocksdb/".to_string() + file;
        config.file(&file);
    }

    config.file("build_version.cc");

    config.cpp(true);
    config.compile("librocksdb.a");
}

fn build_snappy() {
    let mut config = cc::Build::new();
    config.include("snappy/");
    config.include(".");

    config.define("NDEBUG", Some("1"));

    if cfg!(target_env = "msvc") {
        config.flag("-EHsc");
    } else {
        config.flag("-std=c++11");
    }

    config.file("snappy/snappy.cc");
    config.file("snappy/snappy-sinksource.cc");
    config.file("snappy/snappy-c.cc");
    config.cpp(true);
    config.compile("libsnappy.a");
}

fn build_lz4() {
    let mut compiler = cc::Build::new();

    compiler
        .file("lz4/lib/lz4.c")
        .file("lz4/lib/lz4frame.c")
        .file("lz4/lib/lz4hc.c")
        .file("lz4/lib/xxhash.c");

    compiler.opt_level(3);

    match env::var("TARGET").unwrap().as_str() {
        "i686-pc-windows-gnu" => {
            compiler.flag("-fno-tree-vectorize");
        }
        _ => {}
    }

    compiler.compile("liblz4.a");
}

fn build_zstd() {
    let mut compiler = cc::Build::new();

    compiler.include("zstd/lib/");
    compiler.include("zstd/lib/common");
    compiler.include("zstd/lib/legacy");

    let globs = &[
        "zstd/lib/common/*.c",
        "zstd/lib/compress/*.c",
        "zstd/lib/decompress/*.c",
        "zstd/lib/dictBuilder/*.c",
        "zstd/lib/legacy/*.c",
    ];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            compiler.file(path);
        }
    }

    compiler.opt_level(3);

    compiler.define("ZSTD_LIB_DEPRECATED", Some("0"));
    compiler.compile("libzstd.a");
}

fn build_zlib() {
    let mut compiler = cc::Build::new();

    let globs = &["zlib/*.c"];

    for pattern in globs {
        for path in glob::glob(pattern).unwrap() {
            let path = path.unwrap();
            compiler.file(path);
        }
    }

    compiler.flag_if_supported("-Wno-implicit-function-declaration");
    compiler.opt_level(3);
    compiler.compile("libz.a");
}

fn build_bzip2() {
    let mut compiler = cc::Build::new();

    compiler
        .file("bzip2/blocksort.c")
        .file("bzip2/bzlib.c")
        .file("bzip2/compress.c")
        .file("bzip2/crctable.c")
        .file("bzip2/decompress.c")
        .file("bzip2/huffman.c")
        .file("bzip2/randtable.c");

    compiler
        .define("_FILE_OFFSET_BITS", Some("64"))
        .define("BZ_NO_STDIO", None);

    compiler.extra_warnings(false);
    compiler.opt_level(3);
    compiler.compile("libbz2.a");
}

fn try_to_find_and_link_lib(lib_name: &str) -> bool {
    if let Ok(lib_dir) = env::var(&format!("{}_LIB_DIR", lib_name)) {
        println!("cargo:rustc-link-search=native={}", lib_dir);
        let mode = match env::var_os(&format!("{}_STATIC", lib_name)) {
            Some(_) => "static",
            None => "dylib",
        };
        println!("cargo:rustc-link-lib={}={}", mode, lib_name.to_lowercase());
        return true;
    }
    false
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=rocksdb/");
    println!("cargo:rerun-if-changed=snappy/");
    println!("cargo:rerun-if-changed=lz4/");
    println!("cargo:rerun-if-changed=zstd/");
    println!("cargo:rerun-if-changed=zlib/");
    println!("cargo:rerun-if-changed=bzip2/");

    fail_on_empty_directory("rocksdb");
    fail_on_empty_directory("snappy");
    fail_on_empty_directory("lz4");
    fail_on_empty_directory("zstd");
    fail_on_empty_directory("zlib");
    fail_on_empty_directory("bzip2");

    bindgen_rocksdb();

    if !try_to_find_and_link_lib("ROCKSDB") {
        build_rocksdb();
    }
    if cfg!(feature = "snappy") && !try_to_find_and_link_lib("SNAPPY") {
        build_snappy();
    }
    if cfg!(feature = "lz4") && !try_to_find_and_link_lib("LZ4") {
        build_lz4();
    }
    if cfg!(feature = "zstd") && !try_to_find_and_link_lib("ZSTD") {
        build_zstd();
    }
    if cfg!(feature = "zlib") && !try_to_find_and_link_lib("ZLIB") {
        build_zlib();
    }
    if cfg!(feature = "bzip2") && !try_to_find_and_link_lib("BZIP2") {
        build_bzip2();
    }
}
<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};
use std::fs;

use super::{git2, GitStatuses, GitError, GitReference, GitBranch, FileStatus};

pub struct GitRepo {
    repo: git2::Repository,
    path: PathBuf,
}

unsafe impl Send for GitRepo {}
unsafe impl Sync for GitRepo {}

impl GitRepo {
    pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, GitError> {
        let path_ref = path.as_ref();
        let repo = git2::Repository::open(path_ref)
            .map_err(|_| GitError::OpenRepo)?;

        Ok(Self {
               repo: repo,
               path: path_ref.to_owned(),
           })
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn statuses(&self) -> Result<GitStatuses, GitError> {
        // self.repo.graph_ahead_behind

        let mut opts = git2::StatusOptions::new();

        opts.include_ignored(false)
            .include_untracked(true)
            .recurse_untracked_dirs(true)
            .include_unreadable_as_untracked(true)
            .disable_pathspec_match(true)
            .exclude_submodules(true);

        let statuses = self.repo
            .statuses(Some(&mut opts))
            .map_err(|_| GitError::Status)?;

        Ok(GitStatuses::new(statuses))
    }

    pub fn reset(&self) -> Result<GitReference, GitError> {
        let head = self.repo.head().map_err(|_| GitError::Reset)?;
        let obj = head.peel(git2::ObjectType::Any)
            .map_err(|_| GitError::Reset)?;

        let mut builder = git2::build::CheckoutBuilder::new();
        let options = builder
            .remove_untracked(true) // this is ignored for a reset :()
            .progress(|path, a, b| {
                          if path == None {
                              return;
                          }

                          println!("{:?} {:?} {:?}", path, a, b)
                      });

        self.repo
            .reset(&obj, git2::ResetType::Hard, Some(options))
            .map_err(|_| GitError::Reset)?;

        Ok(GitReference::new(&head))
    }

    pub fn checkout(&self, branch_name: &str) -> Result<(), GitError> {
        let branch_type = match branch_name.find("origin/") {
            Some(_) => git2::BranchType::Remote,
            None => git2::BranchType::Local,
        };

        let branch = self.repo
            .find_branch(branch_name, branch_type)
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        let obj = branch
            .get()
            .peel(git2::ObjectType::Any)
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        let mut opts = git2::build::CheckoutBuilder::new();

        self.repo
            .checkout_tree(&obj, Some(&mut opts))
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        let branch_str = format!("refs/heads/{}", branch_name);
        println!("- checking out '{}'", &branch_str);
        let branch_ref = match self.repo.find_reference(&branch_str) {
            Ok(r) => r,
            Err(e) => {
                println!("- checkout error: {}", e.message());
                return Err(GitError::Checkout(GitBranch::from(branch_type)));
            }
        };

        self.repo
            .set_head(branch_ref.name().unwrap())
            .expect("Error setting head");

        println!(" {} {}",
                 match branch_type {
                     git2::BranchType::Local => " [Local]",
                     git2::BranchType::Remote => "[Remote]",
                 },
                 branch_name);

        Ok(())
    }

    pub fn remove_untracked(&self) -> Result<(), GitError> {
        let statuses = self.statuses()?;
        let iter = statuses
            .iter()
            .filter(|x| match *x.status() {
                        FileStatus::New => true,
                        _ => false,
                    });

        // TODO: Finish this nonsense
        for entry in iter {
            let p = self.path.join(entry.path());

            // The whole file/directory distinction might be useless.
            // If a untracked file is removed from an untracked directory, should also
            // remove now empty directory?
            if p.is_file() {
                fs::remove_file(p)
                    .map_err(|_| GitError::RemoveUntracked)?;
            } else if p.is_dir() {
                fs::remove_dir_all(p)
                    .map_err(|_| GitError::RemoveUntracked)?;
            }
        }

        Ok(())
    }

    pub fn state(&self) -> RepoState {
        RepoState::from(self.repo.state())
    }
}

#[derive(Debug)]
pub enum RepoState {
    Clean,
    Merge,
    Revert,
    RevertSequence,
    CherryPick,
    CherryPickSequence,
    Bisect,
    Rebase,
    RebaseInteractive,
    RebaseMerge,
    ApplyMailbox,
    ApplyMailboxOrRebase,
}

impl From<git2::RepositoryState> for RepoState {
    fn from(state: git2::RepositoryState) -> Self {
        use git2::RepositoryState;

        match state {
            RepositoryState::Clean => RepoState::Clean,
            RepositoryState::Merge => RepoState::Merge,
            RepositoryState::Revert => RepoState::Revert,
            RepositoryState::RevertSequence => RepoState::RevertSequence,
            RepositoryState::CherryPick => RepoState::CherryPick,
            RepositoryState::CherryPickSequence => RepoState::CherryPickSequence,
            RepositoryState::Bisect => RepoState::Bisect,
            RepositoryState::Rebase => RepoState::Rebase,
            RepositoryState::RebaseInteractive => RepoState::RebaseInteractive,
            RepositoryState::RebaseMerge => RepoState::RebaseMerge,
            RepositoryState::ApplyMailbox => RepoState::ApplyMailbox,
            RepositoryState::ApplyMailboxOrRebase => RepoState::ApplyMailboxOrRebase,
        }
    }
}
<commit_msg>Added temp checkout logging<commit_after>use std::path::{Path, PathBuf};
use std::fs;

use super::{git2, GitStatuses, GitError, GitReference, GitBranch, FileStatus};

pub struct GitRepo {
    repo: git2::Repository,
    path: PathBuf,
}

unsafe impl Send for GitRepo {}
unsafe impl Sync for GitRepo {}

impl GitRepo {
    pub fn new<P: AsRef<Path>>(path: P) -> Result<Self, GitError> {
        let path_ref = path.as_ref();
        let repo = git2::Repository::open(path_ref)
            .map_err(|_| GitError::OpenRepo)?;

        Ok(Self {
               repo: repo,
               path: path_ref.to_owned(),
           })
    }

    pub fn path(&self) -> &Path {
        &self.path
    }

    pub fn statuses(&self) -> Result<GitStatuses, GitError> {
        // self.repo.graph_ahead_behind

        let mut opts = git2::StatusOptions::new();

        opts.include_ignored(false)
            .include_untracked(true)
            .recurse_untracked_dirs(true)
            .include_unreadable_as_untracked(true)
            .disable_pathspec_match(true)
            .exclude_submodules(true);

        let statuses = self.repo
            .statuses(Some(&mut opts))
            .map_err(|_| GitError::Status)?;

        Ok(GitStatuses::new(statuses))
    }

    pub fn reset(&self) -> Result<GitReference, GitError> {
        let head = self.repo.head().map_err(|_| GitError::Reset)?;
        let obj = head.peel(git2::ObjectType::Any)
            .map_err(|_| GitError::Reset)?;

        let mut builder = git2::build::CheckoutBuilder::new();
        let options = builder
            .remove_untracked(true) // this is ignored for a reset :()
            .progress(|path, a, b| {
                          if path == None {
                              return;
                          }

                          println!("{:?} {:?} {:?}", path, a, b)
                      });

        self.repo
            .reset(&obj, git2::ResetType::Hard, Some(options))
            .map_err(|_| GitError::Reset)?;

        Ok(GitReference::new(&head))
    }

    pub fn checkout(&self, branch_name: &str) -> Result<(), GitError> {
        let branch_type = match branch_name.find("origin/") {
            Some(_) => git2::BranchType::Remote,
            None => git2::BranchType::Local,
        };

        let branch = self.repo
            .find_branch(branch_name, branch_type)
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        let obj = branch
            .get()
            .peel(git2::ObjectType::Commit)
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        println!("{:?}", &obj);

        let mut opts = git2::build::CheckoutBuilder::new();

        self.repo
            .checkout_tree(&obj, Some(&mut opts))
            .map_err(|_| GitError::Checkout(GitBranch::from(branch_type)))?;

        let branch_str = format!("refs/heads/{}", branch_name);
        println!("- checking out '{}'", &branch_str);
        let branch_ref = match self.repo.find_reference(&branch_str) {
            Ok(r) => r,
            Err(e) => {
                println!("- checkout error: {}", e.message());
                return Err(GitError::Checkout(GitBranch::from(branch_type)));
            }
        };

        self.repo
            .set_head(branch_ref.name().unwrap())
            .expect("Error setting head");

        println!(" {} {}",
                 match branch_type {
                     git2::BranchType::Local => " [Local]",
                     git2::BranchType::Remote => "[Remote]",
                 },
                 branch_name);

        Ok(())
    }

    pub fn remove_untracked(&self) -> Result<(), GitError> {
        let statuses = self.statuses()?;
        let iter = statuses
            .iter()
            .filter(|x| match *x.status() {
                        FileStatus::New => true,
                        _ => false,
                    });

        // TODO: Finish this nonsense
        for entry in iter {
            let p = self.path.join(entry.path());

            // The whole file/directory distinction might be useless.
            // If a untracked file is removed from an untracked directory, should also
            // remove now empty directory?
            if p.is_file() {
                fs::remove_file(p)
                    .map_err(|_| GitError::RemoveUntracked)?;
            } else if p.is_dir() {
                fs::remove_dir_all(p)
                    .map_err(|_| GitError::RemoveUntracked)?;
            }
        }

        Ok(())
    }

    pub fn state(&self) -> RepoState {
        RepoState::from(self.repo.state())
    }
}

#[derive(Debug)]
pub enum RepoState {
    Clean,
    Merge,
    Revert,
    RevertSequence,
    CherryPick,
    CherryPickSequence,
    Bisect,
    Rebase,
    RebaseInteractive,
    RebaseMerge,
    ApplyMailbox,
    ApplyMailboxOrRebase,
}

impl From<git2::RepositoryState> for RepoState {
    fn from(state: git2::RepositoryState) -> Self {
        use git2::RepositoryState;

        match state {
            RepositoryState::Clean => RepoState::Clean,
            RepositoryState::Merge => RepoState::Merge,
            RepositoryState::Revert => RepoState::Revert,
            RepositoryState::RevertSequence => RepoState::RevertSequence,
            RepositoryState::CherryPick => RepoState::CherryPick,
            RepositoryState::CherryPickSequence => RepoState::CherryPickSequence,
            RepositoryState::Bisect => RepoState::Bisect,
            RepositoryState::Rebase => RepoState::Rebase,
            RepositoryState::RebaseInteractive => RepoState::RebaseInteractive,
            RepositoryState::RebaseMerge => RepoState::RebaseMerge,
            RepositoryState::ApplyMailbox => RepoState::ApplyMailbox,
            RepositoryState::ApplyMailboxOrRebase => RepoState::ApplyMailboxOrRebase,
        }
    }
}
<|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.

//! Parameterized string expansion

use core::prelude::*;
use core::{char, int, vec};

#[deriving(Eq)]
enum States {
    Nothing,
    Percent,
    SetVar,
    GetVar,
    PushParam,
    CharConstant,
    CharClose,
    IntConstant,
    IfCond,
    IfBody
}

/// Types of parameters a capability can use
pub enum Param {
    String(~str),
    Char(char),
    Number(int)
}

/**
  Expand a parameterized capability

  # Arguments
  * `cap`    - string to expand
  * `params` - vector of params for %p1 etc
  * `sta`    - vector of params corresponding to static variables
  * `dyn`    - vector of params corresponding to stativ variables

  To be compatible with ncurses, `sta` and `dyn` should be the same between calls to `expand` for
  multiple capabilities for the same terminal.
  */
pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param])
    -> Result<~[u8], ~str> {
    assert!(cap.len() != 0, "expanding an empty capability makes no sense");
    assert!(params.len() <= 9, "only 9 parameters are supported by capability strings");

    assert!(sta.len() <= 26, "only 26 static vars are able to be used by capability strings");
    assert!(dyn.len() <= 26, "only 26 dynamic vars are able to be used by capability strings");

    let mut state = Nothing;
    let mut i = 0;

    // expanded cap will only rarely be smaller than the cap itself
    let mut output = vec::with_capacity(cap.len());

    let mut cur;

    let mut stack: ~[Param] = ~[];

    let mut intstate = ~[];

    while i < cap.len() {
        cur = cap[i] as char;
        debug!("current char: %c", cur);
        let mut old_state = state;
        match state {
            Nothing => {
                if cur == '%' {
                    state = Percent;
                } else {
                    output.push(cap[i]);
                }
            },
            Percent => {
                match cur {
                    '%' => { output.push(cap[i]); state = Nothing },
                    'c' => match stack.pop() {
                        Char(c) => output.push(c as u8),
                        _       => return Err(~"a non-char was used with %c")
                    },
                    's' => match stack.pop() {
                        String(s) => output.push_all(s.as_bytes()),
                        _         => return Err(~"a non-str was used with %s")
                    },
                    'd' => match stack.pop() {
                        Number(x) => {
                            let s = x.to_str();
                            output.push_all(s.as_bytes())
                        }
                        _         => return Err(~"a non-number was used with %d")
                    },
                    'p' => state = PushParam,
                    'P' => state = SetVar,
                    'g' => state = GetVar,
                    '\'' => state = CharConstant,
                    '{' => state = IntConstant,
                    'l' => match stack.pop() {
                        String(s) => stack.push(Number(s.len() as int)),
                        _         => return Err(~"a non-str was used with %l")
                    },
                    '+' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x + y)),
                        (_, _) => return Err(~"non-numbers on stack with +")
                    },
                    '-' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x - y)),
                        (_, _) => return Err(~"non-numbers on stack with -")
                    },
                    '*' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x * y)),
                        (_, _) => return Err(~"non-numbers on stack with *")
                    },
                    '/' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x / y)),
                        (_, _) => return Err(~"non-numbers on stack with /")
                    },
                    'm' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x % y)),
                        (_, _) => return Err(~"non-numbers on stack with %")
                    },
                    '&' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x & y)),
                        (_, _) => return Err(~"non-numbers on stack with &")
                    },
                    '|' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x | y)),
                        (_, _) => return Err(~"non-numbers on stack with |")
                    },
                    'A' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => {
                            if x == 1 && y == 1 {
                                stack.push(Number(1));
                            } else {
                                stack.push(Number(0));
                            }
                        },
                        (_, _) => return Err(~"non-numbers on stack with logical and")
                    },
                    'O' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => {
                            if x == 1 && y == 1 {
                                stack.push(Number(1));
                            } else {
                                stack.push(Number(0));
                            }
                        },
                        (_, _) => return Err(~"non-numbers on stack with logical or")
                    },
                    '!' => match stack.pop() {
                        Number(x) => {
                            if x == 1 {
                                stack.push(Number(0))
                            } else {
                                stack.push(Number(1))
                            }
                        },
                        _ => return Err(~"non-number on stack with logical not")
                    },
                    '~' => match stack.pop() {
                        Number(x) => stack.push(Number(!x)),
                        _         => return Err(~"non-number on stack with %~")
                    },
                    'i' => match (copy params[0], copy params[1]) {
                        (Number(x), Number(y)) => {
                            params[0] = Number(x + 1);
                            params[1] = Number(y + 1);
                        },
                        (_, _) => return Err(~"first two params not numbers with %i")
                    },
                    '?' => state = return Err(fmt!("if expressions unimplemented (%?)", cap)),
                    _ => return Err(fmt!("unrecognized format option %c", cur))
                }
            },
            PushParam => {
                // params are 1-indexed
                stack.push(copy params[char::to_digit(cur, 10).expect("bad param number") - 1]);
            },
            SetVar => {
                if cur >= 'A' && cur <= 'Z' {
                    let idx = (cur as u8) - ('A' as u8);
                    sta[idx] = stack.pop();
                } else if cur >= 'a' && cur <= 'z' {
                    let idx = (cur as u8) - ('a' as u8);
                    dyn[idx] = stack.pop();
                } else {
                    return Err(~"bad variable name in %P");
                }
            },
            GetVar => {
                if cur >= 'A' && cur <= 'Z' {
                    let idx = (cur as u8) - ('A' as u8);
                    stack.push(copy sta[idx]);
                } else if cur >= 'a' && cur <= 'z' {
                    let idx = (cur as u8) - ('a' as u8);
                    stack.push(copy dyn[idx]);
                } else {
                    return Err(~"bad variable name in %g");
                }
            },
            CharConstant => {
                stack.push(Char(cur));
                state = CharClose;
            },
            CharClose => {
                if cur != '\'' {
                    return Err(~"malformed character constant");
                }
            },
            IntConstant => {
                if cur == '}' {
                    stack.push(Number(int::parse_bytes(intstate, 10).expect("bad int constant")));
                    state = Nothing;
                }
                intstate.push(cur as u8);
                old_state = Nothing;
            }
            _ => return Err(~"unimplemented state")
        }
        if state == old_state {
            state = Nothing;
        }
        i += 1;
    }
    Ok(output)
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_basic_setabf() {
        let s = bytes!("\\E[48;5;%p1%dm");
        assert_eq!(expand(s, [Number(1)], [], []).unwrap(), bytes!("\\E[48;5;1m").to_owned());
    }
}
<commit_msg>Tweak new terminfo logical operator support<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.

//! Parameterized string expansion

use core::prelude::*;
use core::{char, int, vec};

#[deriving(Eq)]
enum States {
    Nothing,
    Percent,
    SetVar,
    GetVar,
    PushParam,
    CharConstant,
    CharClose,
    IntConstant,
    IfCond,
    IfBody
}

/// Types of parameters a capability can use
pub enum Param {
    String(~str),
    Char(char),
    Number(int)
}

/**
  Expand a parameterized capability

  # Arguments
  * `cap`    - string to expand
  * `params` - vector of params for %p1 etc
  * `sta`    - vector of params corresponding to static variables
  * `dyn`    - vector of params corresponding to stativ variables

  To be compatible with ncurses, `sta` and `dyn` should be the same between calls to `expand` for
  multiple capabilities for the same terminal.
  */
pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param])
    -> Result<~[u8], ~str> {
    assert!(cap.len() != 0, "expanding an empty capability makes no sense");
    assert!(params.len() <= 9, "only 9 parameters are supported by capability strings");

    assert!(sta.len() <= 26, "only 26 static vars are able to be used by capability strings");
    assert!(dyn.len() <= 26, "only 26 dynamic vars are able to be used by capability strings");

    let mut state = Nothing;
    let mut i = 0;

    // expanded cap will only rarely be smaller than the cap itself
    let mut output = vec::with_capacity(cap.len());

    let mut cur;

    let mut stack: ~[Param] = ~[];

    let mut intstate = ~[];

    while i < cap.len() {
        cur = cap[i] as char;
        let mut old_state = state;
        match state {
            Nothing => {
                if cur == '%' {
                    state = Percent;
                } else {
                    output.push(cap[i]);
                }
            },
            Percent => {
                match cur {
                    '%' => { output.push(cap[i]); state = Nothing },
                    'c' => match stack.pop() {
                        Char(c) => output.push(c as u8),
                        _       => return Err(~"a non-char was used with %c")
                    },
                    's' => match stack.pop() {
                        String(s) => output.push_all(s.as_bytes()),
                        _         => return Err(~"a non-str was used with %s")
                    },
                    'd' => match stack.pop() {
                        Number(x) => {
                            let s = x.to_str();
                            output.push_all(s.as_bytes())
                        }
                        _         => return Err(~"a non-number was used with %d")
                    },
                    'p' => state = PushParam,
                    'P' => state = SetVar,
                    'g' => state = GetVar,
                    '\'' => state = CharConstant,
                    '{' => state = IntConstant,
                    'l' => match stack.pop() {
                        String(s) => stack.push(Number(s.len() as int)),
                        _         => return Err(~"a non-str was used with %l")
                    },
                    '+' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x + y)),
                        (_, _) => return Err(~"non-numbers on stack with +")
                    },
                    '-' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x - y)),
                        (_, _) => return Err(~"non-numbers on stack with -")
                    },
                    '*' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x * y)),
                        (_, _) => return Err(~"non-numbers on stack with *")
                    },
                    '/' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x / y)),
                        (_, _) => return Err(~"non-numbers on stack with /")
                    },
                    'm' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x % y)),
                        (_, _) => return Err(~"non-numbers on stack with %")
                    },
                    '&' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x & y)),
                        (_, _) => return Err(~"non-numbers on stack with &")
                    },
                    '|' => match (stack.pop(), stack.pop()) {
                        (Number(x), Number(y)) => stack.push(Number(x | y)),
                        (_, _) => return Err(~"non-numbers on stack with |")
                    },
                    'A' => match (stack.pop(), stack.pop()) {
                        (Number(0), Number(_)) => stack.push(Number(0)),
                        (Number(_), Number(0)) => stack.push(Number(0)),
                        (Number(_), Number(_)) => stack.push(Number(1)),
                        _ => return Err(~"non-numbers on stack with logical and")
                    },
                    'O' => match (stack.pop(), stack.pop()) {
                        (Number(0), Number(0)) => stack.push(Number(0)),
                        (Number(_), Number(_)) => stack.push(Number(1)),
                        _ => return Err(~"non-numbers on stack with logical or")
                    },
                    '!' => match stack.pop() {
                        Number(0) => stack.push(Number(1)),
                        Number(_) => stack.push(Number(0)),
                        _ => return Err(~"non-number on stack with logical not")
                    },
                    '~' => match stack.pop() {
                        Number(x) => stack.push(Number(!x)),
                        _         => return Err(~"non-number on stack with %~")
                    },
                    'i' => match (copy params[0], copy params[1]) {
                        (Number(ref mut x), Number(ref mut y)) => {
                            *x += 1;
                            *y += 1;
                        },
                        (_, _) => return Err(~"first two params not numbers with %i")
                    },
                    '?' => state = return Err(fmt!("if expressions unimplemented (%?)", cap)),
                    _ => return Err(fmt!("unrecognized format option %c", cur))
                }
            },
            PushParam => {
                // params are 1-indexed
                stack.push(copy params[char::to_digit(cur, 10).expect("bad param number") - 1]);
            },
            SetVar => {
                if cur >= 'A' && cur <= 'Z' {
                    let idx = (cur as u8) - ('A' as u8);
                    sta[idx] = stack.pop();
                } else if cur >= 'a' && cur <= 'z' {
                    let idx = (cur as u8) - ('a' as u8);
                    dyn[idx] = stack.pop();
                } else {
                    return Err(~"bad variable name in %P");
                }
            },
            GetVar => {
                if cur >= 'A' && cur <= 'Z' {
                    let idx = (cur as u8) - ('A' as u8);
                    stack.push(copy sta[idx]);
                } else if cur >= 'a' && cur <= 'z' {
                    let idx = (cur as u8) - ('a' as u8);
                    stack.push(copy dyn[idx]);
                } else {
                    return Err(~"bad variable name in %g");
                }
            },
            CharConstant => {
                stack.push(Char(cur));
                state = CharClose;
            },
            CharClose => {
                if cur != '\'' {
                    return Err(~"malformed character constant");
                }
            },
            IntConstant => {
                if cur == '}' {
                    stack.push(Number(int::parse_bytes(intstate, 10).expect("bad int constant")));
                    state = Nothing;
                }
                intstate.push(cur as u8);
                old_state = Nothing;
            }
            _ => return Err(~"unimplemented state")
        }
        if state == old_state {
            state = Nothing;
        }
        i += 1;
    }
    Ok(output)
}

#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn test_basic_setabf() {
        let s = bytes!("\\E[48;5;%p1%dm");
        assert_eq!(expand(s, [Number(1)], [], []).unwrap(), bytes!("\\E[48;5;1m").to_owned());
    }
}
<|endoftext|>


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

//! Unix-specific extensions to primitives in the `std::fs` module.

#![stable(feature = "rust1", since = "1.0.0")]

use prelude::v1::*;

use fs::{self, Permissions, OpenOptions};
use io;
use mem;
use os::raw::c_long;
use os::unix::raw;
use path::Path;
use sys::platform;
use sys;
use sys_common::{FromInner, AsInner, AsInnerMut};

#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_READ: raw::mode_t = 0o400;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_WRITE: raw::mode_t = 0o200;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_EXECUTE: raw::mode_t = 0o100;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_RWX: raw::mode_t = 0o700;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_READ: raw::mode_t = 0o040;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_WRITE: raw::mode_t = 0o020;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_EXECUTE: raw::mode_t = 0o010;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_RWX: raw::mode_t = 0o070;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_READ: raw::mode_t = 0o004;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_WRITE: raw::mode_t = 0o002;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_EXECUTE: raw::mode_t = 0o001;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_RWX: raw::mode_t = 0o007;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_READ: raw::mode_t = 0o444;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_WRITE: raw::mode_t = 0o222;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_EXECUTE: raw::mode_t = 0o111;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_RWX: raw::mode_t = 0o777;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const SETUID: raw::mode_t = 0o4000;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const SETGID: raw::mode_t = 0o2000;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const STICKY_BIT: raw::mode_t = 0o1000;

/// Unix-specific extensions to `Permissions`
#[unstable(feature = "fs_ext",
           reason = "may want a more useful mode abstraction")]
pub trait PermissionsExt {
    fn mode(&self) -> raw::mode_t;
    fn set_mode(&mut self, mode: raw::mode_t);
    fn from_mode(mode: raw::mode_t) -> Self;
}

impl PermissionsExt for Permissions {
    fn mode(&self) -> raw::mode_t { self.as_inner().mode() }

    fn set_mode(&mut self, mode: raw::mode_t) {
        *self = FromInner::from_inner(FromInner::from_inner(mode));
    }

    fn from_mode(mode: raw::mode_t) -> Permissions {
        FromInner::from_inner(FromInner::from_inner(mode))
    }
}

/// Unix-specific extensions to `OpenOptions`
#[unstable(feature = "fs_ext",
           reason = "may want a more useful mode abstraction")]
pub trait OpenOptionsExt {
    /// Sets the mode bits that a new file will be created with.
    ///
    /// If a new file is created as part of a `File::open_opts` call then this
    /// specified `mode` will be used as the permission bits for the new file.
    fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
}

impl OpenOptionsExt for OpenOptions {
    fn mode(&mut self, mode: raw::mode_t) -> &mut OpenOptions {
        self.as_inner_mut().mode(mode); self
    }
}

#[unstable(feature = "metadata_ext", reason = "recently added API")]
pub struct Metadata(sys::fs2::FileAttr);

#[unstable(feature = "metadata_ext", reason = "recently added API")]
pub trait MetadataExt {
    fn as_raw(&self) -> &Metadata;
}

impl MetadataExt for fs::Metadata {
    fn as_raw(&self) -> &Metadata {
        let inner: &sys::fs2::FileAttr = self.as_inner();
        unsafe { mem::transmute(inner) }
    }
}

impl AsInner<platform::raw::stat> for Metadata {
    fn as_inner(&self) -> &platform::raw::stat { self.0.as_inner() }
}

// Hm, why are there casts here to the returned type, shouldn't the types always
// be the same? Right you are! Turns out, however, on android at least the types
// in the raw `stat` structure are not the same as the types being returned. Who
// knew!
//
// As a result to make sure this compiles for all platforms we do the manual
// casts and rely on manual lowering to `stat` if the raw type is desired.
#[unstable(feature = "metadata_ext", reason = "recently added API")]
impl Metadata {
    pub fn dev(&self) -> raw::dev_t { self.0.raw().st_dev as raw::dev_t }
    pub fn ino(&self) -> raw::ino_t { self.0.raw().st_ino as raw::ino_t }
    pub fn mode(&self) -> raw::mode_t { self.0.raw().st_mode as raw::mode_t }
    pub fn nlink(&self) -> raw::nlink_t { self.0.raw().st_nlink as raw::nlink_t }
    pub fn uid(&self) -> raw::uid_t { self.0.raw().st_uid as raw::uid_t }
    pub fn gid(&self) -> raw::gid_t { self.0.raw().st_gid as raw::gid_t }
    pub fn rdev(&self) -> raw::dev_t { self.0.raw().st_rdev as raw::dev_t }
    pub fn size(&self) -> raw::off_t { self.0.raw().st_size as raw::off_t }
    pub fn atime(&self) -> raw::time_t { self.0.raw().st_atime }
    pub fn atime_nsec(&self) -> c_long { self.0.raw().st_atime }
    pub fn mtime(&self) -> raw::time_t { self.0.raw().st_mtime }
    pub fn mtime_nsec(&self) -> c_long { self.0.raw().st_mtime }
    pub fn ctime(&self) -> raw::time_t { self.0.raw().st_ctime }
    pub fn ctime_nsec(&self) -> c_long { self.0.raw().st_ctime }

    pub fn blksize(&self) -> raw::blksize_t {
        self.0.raw().st_blksize as raw::blksize_t
    }
    pub fn blocks(&self) -> raw::blkcnt_t {
        self.0.raw().st_blocks as raw::blkcnt_t
    }
}

#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
pub trait DirEntryExt {
    fn ino(&self) -> raw::ino_t;
}

impl DirEntryExt for fs::DirEntry {
    fn ino(&self) -> raw::ino_t { self.as_inner().ino() }
}

/// Creates a new symbolic link on the filesystem.
///
/// The `dst` path will be a symbolic link pointing to the `src` path.
///
/// # Note
///
/// On Windows, you must specify whether a symbolic link points to a file
/// or directory.  Use `os::windows::fs::symlink_file` to create a
/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
/// symbolic link to a directory.  Additionally, the process must have
/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
/// symbolic link.
///
/// # Examples
///
/// ```
/// use std::os::unix::fs;
///
/// # fn foo() -> std::io::Result<()> {
/// try!(fs::symlink("a.txt", "b.txt"));
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
{
    sys::fs2::symlink(src.as_ref(), dst.as_ref())
}

#[unstable(feature = "dir_builder", reason = "recently added API")]
/// An extension trait for `fs::DirBuilder` for unix-specific options.
pub trait DirBuilderExt {
    /// Sets the mode to create new directories with. This option defaults to
    /// 0o777.
    fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
}

impl DirBuilderExt for fs::DirBuilder {
    fn mode(&mut self, mode: raw::mode_t) -> &mut fs::DirBuilder {
        self.as_inner_mut().set_mode(mode);
        self
    }
}

<commit_msg>std: Fix {atime,mtime,ctime}_nsec accessors<commit_after>// Copyright 2015 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.

//! Unix-specific extensions to primitives in the `std::fs` module.

#![stable(feature = "rust1", since = "1.0.0")]

use prelude::v1::*;

use fs::{self, Permissions, OpenOptions};
use io;
use mem;
use os::raw::c_long;
use os::unix::raw;
use path::Path;
use sys::platform;
use sys;
use sys_common::{FromInner, AsInner, AsInnerMut};

#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_READ: raw::mode_t = 0o400;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_WRITE: raw::mode_t = 0o200;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_EXECUTE: raw::mode_t = 0o100;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const USER_RWX: raw::mode_t = 0o700;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_READ: raw::mode_t = 0o040;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_WRITE: raw::mode_t = 0o020;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_EXECUTE: raw::mode_t = 0o010;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const GROUP_RWX: raw::mode_t = 0o070;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_READ: raw::mode_t = 0o004;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_WRITE: raw::mode_t = 0o002;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_EXECUTE: raw::mode_t = 0o001;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const OTHER_RWX: raw::mode_t = 0o007;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_READ: raw::mode_t = 0o444;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_WRITE: raw::mode_t = 0o222;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_EXECUTE: raw::mode_t = 0o111;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const ALL_RWX: raw::mode_t = 0o777;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const SETUID: raw::mode_t = 0o4000;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const SETGID: raw::mode_t = 0o2000;
#[unstable(feature = "fs_mode", reason = "recently added API")]
pub const STICKY_BIT: raw::mode_t = 0o1000;

/// Unix-specific extensions to `Permissions`
#[unstable(feature = "fs_ext",
           reason = "may want a more useful mode abstraction")]
pub trait PermissionsExt {
    fn mode(&self) -> raw::mode_t;
    fn set_mode(&mut self, mode: raw::mode_t);
    fn from_mode(mode: raw::mode_t) -> Self;
}

impl PermissionsExt for Permissions {
    fn mode(&self) -> raw::mode_t { self.as_inner().mode() }

    fn set_mode(&mut self, mode: raw::mode_t) {
        *self = FromInner::from_inner(FromInner::from_inner(mode));
    }

    fn from_mode(mode: raw::mode_t) -> Permissions {
        FromInner::from_inner(FromInner::from_inner(mode))
    }
}

/// Unix-specific extensions to `OpenOptions`
#[unstable(feature = "fs_ext",
           reason = "may want a more useful mode abstraction")]
pub trait OpenOptionsExt {
    /// Sets the mode bits that a new file will be created with.
    ///
    /// If a new file is created as part of a `File::open_opts` call then this
    /// specified `mode` will be used as the permission bits for the new file.
    fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
}

impl OpenOptionsExt for OpenOptions {
    fn mode(&mut self, mode: raw::mode_t) -> &mut OpenOptions {
        self.as_inner_mut().mode(mode); self
    }
}

#[unstable(feature = "metadata_ext", reason = "recently added API")]
pub struct Metadata(sys::fs2::FileAttr);

#[unstable(feature = "metadata_ext", reason = "recently added API")]
pub trait MetadataExt {
    fn as_raw(&self) -> &Metadata;
}

impl MetadataExt for fs::Metadata {
    fn as_raw(&self) -> &Metadata {
        let inner: &sys::fs2::FileAttr = self.as_inner();
        unsafe { mem::transmute(inner) }
    }
}

impl AsInner<platform::raw::stat> for Metadata {
    fn as_inner(&self) -> &platform::raw::stat { self.0.as_inner() }
}

// Hm, why are there casts here to the returned type, shouldn't the types always
// be the same? Right you are! Turns out, however, on android at least the types
// in the raw `stat` structure are not the same as the types being returned. Who
// knew!
//
// As a result to make sure this compiles for all platforms we do the manual
// casts and rely on manual lowering to `stat` if the raw type is desired.
#[unstable(feature = "metadata_ext", reason = "recently added API")]
impl Metadata {
    pub fn dev(&self) -> raw::dev_t { self.0.raw().st_dev as raw::dev_t }
    pub fn ino(&self) -> raw::ino_t { self.0.raw().st_ino as raw::ino_t }
    pub fn mode(&self) -> raw::mode_t { self.0.raw().st_mode as raw::mode_t }
    pub fn nlink(&self) -> raw::nlink_t { self.0.raw().st_nlink as raw::nlink_t }
    pub fn uid(&self) -> raw::uid_t { self.0.raw().st_uid as raw::uid_t }
    pub fn gid(&self) -> raw::gid_t { self.0.raw().st_gid as raw::gid_t }
    pub fn rdev(&self) -> raw::dev_t { self.0.raw().st_rdev as raw::dev_t }
    pub fn size(&self) -> raw::off_t { self.0.raw().st_size as raw::off_t }
    pub fn atime(&self) -> raw::time_t { self.0.raw().st_atime }
    pub fn atime_nsec(&self) -> c_long { self.0.raw().st_atime_nsec as c_long }
    pub fn mtime(&self) -> raw::time_t { self.0.raw().st_mtime }
    pub fn mtime_nsec(&self) -> c_long { self.0.raw().st_mtime_nsec as c_long }
    pub fn ctime(&self) -> raw::time_t { self.0.raw().st_ctime }
    pub fn ctime_nsec(&self) -> c_long { self.0.raw().st_ctime_nsec as c_long }

    pub fn blksize(&self) -> raw::blksize_t {
        self.0.raw().st_blksize as raw::blksize_t
    }
    pub fn blocks(&self) -> raw::blkcnt_t {
        self.0.raw().st_blocks as raw::blkcnt_t
    }
}

#[unstable(feature = "dir_entry_ext", reason = "recently added API")]
pub trait DirEntryExt {
    fn ino(&self) -> raw::ino_t;
}

impl DirEntryExt for fs::DirEntry {
    fn ino(&self) -> raw::ino_t { self.as_inner().ino() }
}

/// Creates a new symbolic link on the filesystem.
///
/// The `dst` path will be a symbolic link pointing to the `src` path.
///
/// # Note
///
/// On Windows, you must specify whether a symbolic link points to a file
/// or directory.  Use `os::windows::fs::symlink_file` to create a
/// symbolic link to a file, or `os::windows::fs::symlink_dir` to create a
/// symbolic link to a directory.  Additionally, the process must have
/// `SeCreateSymbolicLinkPrivilege` in order to be able to create a
/// symbolic link.
///
/// # Examples
///
/// ```
/// use std::os::unix::fs;
///
/// # fn foo() -> std::io::Result<()> {
/// try!(fs::symlink("a.txt", "b.txt"));
/// # Ok(())
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
{
    sys::fs2::symlink(src.as_ref(), dst.as_ref())
}

#[unstable(feature = "dir_builder", reason = "recently added API")]
/// An extension trait for `fs::DirBuilder` for unix-specific options.
pub trait DirBuilderExt {
    /// Sets the mode to create new directories with. This option defaults to
    /// 0o777.
    fn mode(&mut self, mode: raw::mode_t) -> &mut Self;
}

impl DirBuilderExt for fs::DirBuilder {
    fn mode(&mut self, mode: raw::mode_t) -> &mut fs::DirBuilder {
        self.as_inner_mut().set_mode(mode);
        self
    }
}

<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::on_chain_config::OnChainConfig;
use anyhow::Result;
use move_core_types::identifier::Identifier;
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RegisteredCurrencies {
    currency_codes: Vec<Identifier>,
}

impl fmt::Display for RegisteredCurrencies {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[")?;
        for currency_code in self.currency_codes().iter() {
            write!(f, "{} ", currency_code)?;
        }
        write!(f, "]")
    }
}

impl RegisteredCurrencies {
    pub fn new(currency_codes: Vec<Identifier>) -> Self {
        Self { currency_codes }
    }

    pub fn currency_codes(&self) -> &[Identifier] {
        &self.currency_codes
    }

    pub fn empty() -> Self {
        Self::new(Vec::new())
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
        lcs::from_bytes(bytes).map_err(Into::into)
    }
}

impl OnChainConfig for RegisteredCurrencies {
    // registered currencies address
    const IDENTIFIER: &'static str = "RegisteredCurrencies";
}
<commit_msg>Removing empty from types/src/on_chain_config/registered_currencies.rs<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::on_chain_config::OnChainConfig;
use anyhow::Result;
use move_core_types::identifier::Identifier;
use serde::{Deserialize, Serialize};
use std::fmt;

#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RegisteredCurrencies {
    currency_codes: Vec<Identifier>,
}

impl fmt::Display for RegisteredCurrencies {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[")?;
        for currency_code in self.currency_codes().iter() {
            write!(f, "{} ", currency_code)?;
        }
        write!(f, "]")
    }
}

impl RegisteredCurrencies {
    pub fn new(currency_codes: Vec<Identifier>) -> Self {
        Self { currency_codes }
    }

    pub fn currency_codes(&self) -> &[Identifier] {
        &self.currency_codes
    }

    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
        lcs::from_bytes(bytes).map_err(Into::into)
    }
}

impl OnChainConfig for RegisteredCurrencies {
    // registered currencies address
    const IDENTIFIER: &'static str = "RegisteredCurrencies";
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLCanvasElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::{ErrorResult};
use dom::document::Document;
use dom::element::HTMLCanvasElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLCanvasElement {
    pub htmlelement: HTMLElement,
}

impl HTMLCanvasElementDerived for EventTarget {
    fn is_htmlcanvaselement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLCanvasElementTypeId))
    }
}

impl HTMLCanvasElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLCanvasElement {
        HTMLCanvasElement {
            htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLCanvasElement> {
        let element = HTMLCanvasElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
    }
}

pub trait HTMLCanvasElementMethods {
    fn Width(&self) -> u32;
    fn SetWidth(&mut self, _width: u32) -> ErrorResult;
    fn Height(&self) -> u32;
    fn SetHeight(&mut self, _height: u32) -> ErrorResult;
}

impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
    fn Width(&self) -> u32 {
        0
    }

    fn SetWidth(&mut self, _width: u32) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> u32 {
        0
    }

    fn SetHeight(&mut self, _height: u32) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLCanvasElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLCanvasElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::{ErrorResult};
use dom::document::Document;
use dom::element::HTMLCanvasElementTypeId;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, ElementNodeTypeId};
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLCanvasElement {
    pub htmlelement: HTMLElement,
}

impl HTMLCanvasElementDerived for EventTarget {
    fn is_htmlcanvaselement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLCanvasElementTypeId))
    }
}

impl HTMLCanvasElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLCanvasElement {
        HTMLCanvasElement {
            htmlelement: HTMLElement::new_inherited(HTMLCanvasElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLCanvasElement> {
        let element = HTMLCanvasElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap)
    }
}

pub trait HTMLCanvasElementMethods {
    fn Width(&self) -> u32;
    fn SetWidth(&self, _width: u32) -> ErrorResult;
    fn Height(&self) -> u32;
    fn SetHeight(&self, _height: u32) -> ErrorResult;
}

impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> {
    fn Width(&self) -> u32 {
        0
    }

    fn SetWidth(&self, _width: u32) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> u32 {
        0
    }

    fn SetHeight(&self, _height: u32) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>