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

extern mod std;
extern mod extra;

use extra::test::{TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use extra::getopts::{getopts, reqopt, opt_str, fail_str};
use std::{os, run, io, str};
use std::cell::Cell;
use std::os::list_dir_path;

#[deriving(Clone)]
struct Config {
    source_dir: ~str,
    filter: Option<~str>
}

fn main() {
    let args = os::args();
    let config = parse_config(args);
    let opts = test_options(config.clone());
    let tests = find_tests(config);
    run_tests_console(&opts, tests);
}

fn parse_config(args: ~[~str]) -> Config {
    let args = args.tail();
    let opts = ~[reqopt("source-dir")];
    let matches = match getopts(args, opts) {
      Ok(m) => m,
      Err(f) => fail!(fail_str(f))
    };

    Config {
        source_dir: opt_str(&matches, "source-dir"),
        filter: if matches.free.is_empty() {
            None
        } else {
            Some((*matches.free.head()).clone())
        }
    }
}

fn test_options(config: Config) -> TestOpts {
    TestOpts {
        filter: config.filter,
        run_ignored: false,
        run_tests: true,
        run_benchmarks: false,
        save_results: None,
        compare_results: None,
        logfile: None
    }
}

fn find_tests(config: Config) -> ~[TestDescAndFn] {
    let mut files = list_dir_path(&Path(config.source_dir));
    files.retain( |file| file.to_str().ends_with(".html") );
    return files.map(|file| make_test((*file).to_str()) );
}

fn make_test(file: ~str) -> TestDescAndFn {
    let f = Cell::new(file.clone());
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(file),
            ignore: false,
            should_fail: false
        },
        testfn: DynTestFn(|| { run_test(f.take()) })
    }
}

fn run_test(file: ~str) {
    let infile = ~"file://" + os::make_absolute(&Path(file)).to_str();
    let res = run::process_output("./servo", [infile]);
    let out = str::from_bytes(res.output);
    io::print(out);
    let lines: ~[&str] = out.split_iter('\n').collect();
    for lines.iter().advance |&line| {
        if line.contains("TEST-UNEXPECTED-FAIL") {
            fail!(line);
        }
    }
}
<commit_msg>Fix contenttest harness build errors.<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod std;
extern mod extra;

use extra::test::{TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use extra::getopts::{getopts, reqopt, opt_str, fail_str};
use std::{os, run, io, str};
use std::cell::Cell;
use std::os::list_dir_path;

#[deriving(Clone)]
struct Config {
    source_dir: ~str,
    filter: Option<~str>
}

fn main() {
    let args = os::args();
    let config = parse_config(args);
    let opts = test_options(config.clone());
    let tests = find_tests(config);
    run_tests_console(&opts, tests);
}

fn parse_config(args: ~[~str]) -> Config {
    let args = args.tail();
    let opts = ~[reqopt("source-dir")];
    let matches = match getopts(args, opts) {
      Ok(m) => m,
      Err(f) => fail!(fail_str(f))
    };

    Config {
        source_dir: opt_str(&matches, "source-dir"),
        filter: if matches.free.is_empty() {
            None
        } else {
            Some((*matches.free.head()).clone())
        }
    }
}

fn test_options(config: Config) -> TestOpts {
    TestOpts {
        filter: config.filter,
        run_ignored: false,
        run_tests: true,
        run_benchmarks: false,
        ratchet_metrics: None,
        ratchet_noise_percent: None,
        save_metrics: None,
        logfile: None
    }
}

fn find_tests(config: Config) -> ~[TestDescAndFn] {
    let mut files = list_dir_path(&Path(config.source_dir));
    files.retain( |file| file.to_str().ends_with(".html") );
    return files.map(|file| make_test((*file).to_str()) );
}

fn make_test(file: ~str) -> TestDescAndFn {
    let f = Cell::new(file.clone());
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(file),
            ignore: false,
            should_fail: false
        },
        testfn: DynTestFn(|| { run_test(f.take()) })
    }
}

fn run_test(file: ~str) {
    let infile = ~"file://" + os::make_absolute(&Path(file)).to_str();
    let res = run::process_output("./servo", [infile]);
    let out = str::from_bytes(res.output);
    io::print(out);
    let lines: ~[&str] = out.split_iter('\n').collect();
    for &line in lines.iter() {
        if line.contains("TEST-UNEXPECTED-FAIL") {
            fail!(line);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test for issue-64848<commit_after>// build-pass

trait AssociatedConstant {
    const DATA: ();
}

impl<F, T> AssociatedConstant for F
where
    F: FnOnce() -> T,
    T: AssociatedConstant,
{
    const DATA: () = T::DATA;
}

impl AssociatedConstant for () {
    const DATA: () = ();
}

fn foo() -> impl AssociatedConstant {
    ()
}

fn get_data<T: AssociatedConstant>(_: T) -> &'static () {
    &T::DATA
}

fn main() {
    get_data(foo);
}
<|endoftext|>


<commit_before><commit_msg>Start setting timer metrics in map<commit_after><|endoftext|>


<commit_before><commit_msg>Changing Vec to Box<[T]><commit_after><|endoftext|>


<commit_before><commit_msg>This was bugging me.<commit_after><|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.

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

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

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
    pub exclude: Vec<PathBuf>,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Check {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        rustc_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean {
        all: bool,
    },
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    check       Compile either the compiler or libraries, using cargo check
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optmulti("", "exclude", "build paths to exclude", "PATH");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "check")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No or an invalid subcommand -- show the general usage and subcommand help
                // An exit code will be 0 when no subcommand is given, and 1 in case of an invalid
                // subcommand.
                println!("{}\n", subcommand_help);
                let exit_code = if args.is_empty() { 0 } else { 1 };
                process::exit(exit_code);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
                opts.optmulti(
                    "",
                    "rustc-args",
                    "extra options to pass the compiler when running tests",
                    "ARGS",
                );
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            "clean" => { opts.optflag("", "all", "clean all build artifacts"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "check" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py check src/libcore
        ./x.py check src/libcore src/libproc_macro

    If no arguments are passed then the complete artifacts are compiled: std, test, and rustc. Note
    also that since we use `cargo check`, by default this will automatically enable incremental
    compilation, so there's no need to pass it separately, though it won't hurt. We also completely
    ignore the stage passed, as there's no way to compile in non-stage 0 without actually building
    the compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands except `clean` can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else if subcommand.as_str() != "clean" {
            extra_help.push_str(format!(
                "Run `./x.py {} -h -v` to see a list of available paths.",
                subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "check" => {
                Subcommand::Check { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    rustc_args: matches.opt_strs("rustc-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean does not take a path argument\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }

                Subcommand::Clean {
                    all: matches.opt_present("all"),
                }
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd.clone());

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            src,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
            exclude: split(matches.opt_strs("exclude"))
                .into_iter().map(|p| cwd.join(p)).collect::<Vec<_>>(),
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn rustc_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref rustc_args, .. } => {
                rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<commit_msg>Make exclude and paths relative to root of checkout<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.

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

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

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
    pub exclude: Vec<PathBuf>,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Check {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        rustc_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean {
        all: bool,
    },
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    check       Compile either the compiler or libraries, using cargo check
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optmulti("", "exclude", "build paths to exclude", "PATH");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "check")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No or an invalid subcommand -- show the general usage and subcommand help
                // An exit code will be 0 when no subcommand is given, and 1 in case of an invalid
                // subcommand.
                println!("{}\n", subcommand_help);
                let exit_code = if args.is_empty() { 0 } else { 1 };
                process::exit(exit_code);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
                opts.optmulti(
                    "",
                    "rustc-args",
                    "extra options to pass the compiler when running tests",
                    "ARGS",
                );
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            "clean" => { opts.optflag("", "all", "clean all build artifacts"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "check" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py check src/libcore
        ./x.py check src/libcore src/libproc_macro

    If no arguments are passed then the complete artifacts are compiled: std, test, and rustc. Note
    also that since we use `cargo check`, by default this will automatically enable incremental
    compilation, so there's no need to pass it separately, though it won't hurt. We also completely
    ignore the stage passed, as there's no way to compile in non-stage 0 without actually building
    the compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd.clone());
        let paths = matches.free[1..].iter().map(|p| {
            cwd.join(p).strip_prefix(&src).expect("paths passed to be inside checkout").into()
        }).collect::<Vec<PathBuf>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands except `clean` can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else if subcommand.as_str() != "clean" {
            extra_help.push_str(format!(
                "Run `./x.py {} -h -v` to see a list of available paths.",
                subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "check" => {
                Subcommand::Check { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    rustc_args: matches.opt_strs("rustc-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean does not take a path argument\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }

                Subcommand::Clean {
                    all: matches.opt_present("all"),
                }
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
            exclude: split(matches.opt_strs("exclude"))
                .into_iter().map(|p| {
                    cwd.join(p).strip_prefix(&src).expect("paths to be inside checkout").into()
                }).collect::<Vec<_>>(),
            src,
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn rustc_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref rustc_args, .. } => {
                rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<|endoftext|>


<commit_before><commit_msg>add collections::vec::tests::split_off_and_append<commit_after><|endoftext|>


<commit_before><commit_msg>add uniform filler<commit_after>use std::rc::Rc;
use shader::Shader;
use std::collections::HashMap;
use glium::uniforms::{UniformValue, Uniforms};

pub trait Filler {
    fn prefix<'a>(&'a self) -> String;
    fn uniform_value<'a>(&'a self, name: &str) -> Option<UniformValue>;
}

pub struct UniformFiller<'a> {
    fillers: HashMap<String, &'a Filler>,
    shader: Option<Rc<Shader>>,
}

impl<'a> UniformFiller<'a> {
    pub fn new() -> UniformFiller<'a> {
        UniformFiller {
            fillers: HashMap::<String, &'a Filler>::new(),
            shader: None
        }
    }

    pub fn add<T>(&mut self, filler: &'a T) where T: Filler {
        let _ = self.fillers.entry(filler.prefix()).or_insert(filler);
    }

    pub fn set_shader(&mut self, shader: Rc<Shader>) {
        self.shader = Some(shader);
    }
}

impl<'a> Uniforms for UniformFiller<'a>  {
    fn visit_values<'c, F: FnMut(&str, UniformValue<'c>)>(&'c self, mut f: F) {
        let uniform_keys: &Vec<String> = &match self.shader {
            Some(ref s) => s,
            None => panic!("Not set shader for Uniformfiller"),
        }.uniform_keys;

        for name in uniform_keys {
            let prefix = match name.find("_") {
                Some(ind) => &name[0..ind],
                None => panic!(format!("Not found '_' in uniform name {} ", name))
            };
            f(&name, match self.fillers[prefix].uniform_value(&name) {
                Some(v) => v,
                None => panic!(format!("Not found uniform name {} in filler", name))
            });
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a run-pass-valgrind test for vecdeque issue<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.

#![feature(global_allocator, alloc_system, allocator_api)]
extern crate alloc_system;

use std::collections::VecDeque;
use alloc_system::System;

#[global_allocator]
static ALLOCATOR: System = System;

fn main() {
    let mut deque = VecDeque::with_capacity(32);
    deque.push_front(0);
    deque.reserve(31);
    deque.push_back(0);
}
<|endoftext|>


<commit_before>// Vectors are allocated in the Rust kernel's memory region, use of
// which requires some amount of synchronization. This test exercises
// that synchronization by spawning a number of tasks and then
// allocating and freeing vectors.

fn f(&&n: uint) {
    for uint::range(0u, n) {|i|
        let mut v: [u8] = [];
        vec::reserve(v, 1000u);
    }
}

fn main(args: [str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        ["", "50000"]
    } else if args.len() <= 1u {
        ["", "100"]
    } else {
        args
    };
    let n = uint::from_str(args[1]).get();
    for uint::range(0u, 100u) {|i| task::spawn {|| f(n); };}
}
<commit_msg>bench: Remove task-perf-vector-party. No longer relevant<commit_after><|endoftext|>


<commit_before><commit_msg>Add regression test for #19791<commit_after><|endoftext|>


<commit_before><commit_msg>Fix comment in UTXOset for stxo cache ordering<commit_after><|endoftext|>


<commit_before><commit_msg>Impl From<Table> for EntryHeader<commit_after><|endoftext|>


<commit_before><commit_msg>Remove protocols and protocol versions we don't support<commit_after><|endoftext|>


<commit_before><commit_msg>Added line-splitting function to String<commit_after><|endoftext|>


<commit_before><commit_msg>Add Result type for libimagentryselect<commit_after>use std::result::Result as RResult;

use error::EntrySelectError;

pub type Result<T> = RResult<T, EntrySelectError>;

<|endoftext|>


<commit_before><commit_msg>Only use forward routes when calculating the distances.<commit_after><|endoftext|>


<commit_before><commit_msg>Switch Marks from HashMap to an array<commit_after><|endoftext|>


<commit_before><commit_msg>Added AVX support.<commit_after><|endoftext|>


<commit_before><commit_msg>Update main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Eliminate some warnings about test-only code.<commit_after><|endoftext|>


<commit_before><commit_msg>error: add more discernable errors<commit_after><|endoftext|>


<commit_before><commit_msg>Add a frame data example<commit_after>use std::env;

use getopts::Options;
use pdb::FallibleIterator;

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} input.pdb", program);
    print!("{}", opts.usage(&brief));
}

fn dump_framedata(filename: &str) -> pdb::Result<()> {
    let file = std::fs::File::open(filename)?;
    let mut pdb = pdb::PDB::open(file)?;

    let string_table = pdb.string_table()?;
    println!("Frame data:");

    println!(
        "Address    Blk Size   Locals   Params   StackMax Prolog    SavedRegs   SEH C++EH Start BP"
    );
    println!("           Program/Type");
    println!();

    let frame_table = pdb.frame_table()?;
    let mut frames = frame_table.iter();
    while let Some(data) = frames.next()? {
        println!(
            "{} {:8x} {:8x} {:8x} {:8x} {:8x} {:8x}        {}   {}      {}     {}",
            data.code_rva,
            data.code_size,
            data.locals_size,
            data.params_size,
            data.max_stack_size.unwrap_or(0),
            data.prolog_size,
            data.saved_regs_size,
            if data.has_structured_eh { 'Y' } else { 'N' },
            if data.has_cpp_eh { 'Y' } else { 'N' },
            if data.is_function_start { 'Y' } else { 'N' },
            if data.uses_base_pointer { 'Y' } else { 'N' },
        );

        match data.info {
            pdb::FrameInfo::Program(prog_ref) => {
                let program_string = prog_ref.to_string_lossy(&string_table)?;
                println!("           {}", program_string);
            }
            pdb::FrameInfo::Type(ty) => println!("          {}", ty),
        }
    }

    Ok(())
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

    let filename = if matches.free.len() == 1 {
        &matches.free[0]
    } else {
        print_usage(&program, opts);
        return;
    };

    match dump_framedata(&filename) {
        Ok(_) => (),
        Err(e) => eprintln!("error dumping PDB: {}", e),
    }
}
<|endoftext|>


<commit_before><commit_msg>Support line_height better in layout 2020<commit_after><|endoftext|>


<commit_before><commit_msg>Remove palette generator<commit_after><|endoftext|>


<commit_before>#![crate_name = "http"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate url = "url_";
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<commit_msg>Upgrade to rust-url with renamed crate.<commit_after>#![crate_name = "http"]

#![comment = "Rust HTTP server"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![doc(html_root_url = "http://www.rust-ci.org/chris-morgan/rust-http/doc/")]

#![deny(non_camel_case_types)]
//#[deny(missing_doc)];

#![feature(default_type_params)]
#![feature(macro_rules)]
#![feature(phase)]

#[phase(plugin, link)] extern crate log;
extern crate url;
extern crate time;
extern crate collections;
extern crate debug;

pub mod buffer;
pub mod client;
pub mod common;
pub mod connecter;
pub mod server;
pub mod method;
pub mod headers;
pub mod rfc2616;
#[path = "generated/status.rs"]
pub mod status;  // Getting an error? It's generated; use ``make`` or see the ``Makefile``

/// TODO: submit upstream
#[cfg(test)]
pub mod memstream;
<|endoftext|>


<commit_before><commit_msg>looping added<commit_after><|endoftext|>


<commit_before><commit_msg>close stream<commit_after><|endoftext|>


<commit_before>use clap::{Arg, App, ArgGroup, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
	app
        .subcommand(SubCommand::with_name("tw-hook")
                    .about("For use in a taskwarrior hook")
                    .version("0.1")

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-add hook"))

                    .arg(Arg::with_name("delete")
                         .long("delete")
                         .short("d")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-delete hook"))

                    .group(ArgGroup::with_name("taskwarrior hooks")
                           .args(&[ "add",
                                    "delete",
                                ])
                           .required(true))
                    )

        .subcommand(SubCommand::with_name("exec")
                    .about("Send a command to taskwarrior")
                    .version("0.1")

                    .arg(Arg::with_name("command")
                         .long("command")
                         .short("c")
                         .takes_value(true)
			 .multiple(true)
                         .required(true)
                         .help("Args written in the string will be send directly to taskwarrior"))

                    )

        .subcommand(SubCommand::with_name("add")
                    .about("create a task")
                    .version("0.1")

                    .arg(Arg::with_name("description")
                        .long("description")
                        .short("d")
                        .takes_value(true)
                        .required(true)
                        .help("Name/Description of the new task")
                    )

                    .arg(Arg::with_name("priority")
                        .long("priority")
                        .short("p")
                        .takes_value(true)
                        .required(false)
                        .help("One of l, m, h for low, medium and high priority")
                    )

                    .arg(Arg::with_name("project")
                        .long("project")
                        .takes_value(true)
                        .required(false)
                        .help("Name of the project the task is related to")
                    )

                    .arg(Arg::with_name("due")
                        .long("due")
                        .takes_value(true)
                        .required(false)
                        .help("Due date of the new task")
                    )

                    .arg(Arg::with_name("frequency")
                        .long("frequency")
                        .short("f")
                        .takes_value(true)
                        .required(false)
                        .help("Frequency of the recurrence of a task")
                    )

}
<commit_msg>fix syntax error<commit_after>use clap::{Arg, App, ArgGroup, SubCommand};

pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
	app
        .subcommand(SubCommand::with_name("tw-hook")
                    .about("For use in a taskwarrior hook")
                    .version("0.1")

                    .arg(Arg::with_name("add")
                         .long("add")
                         .short("a")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-add hook"))

                    .arg(Arg::with_name("delete")
                         .long("delete")
                         .short("d")
                         .takes_value(false)
                         .required(false)
                         .help("For use in an on-delete hook"))

                    .group(ArgGroup::with_name("taskwarrior hooks")
                           .args(&[ "add",
                                    "delete",
                                ])
                           .required(true))
                    )

        .subcommand(SubCommand::with_name("exec")
                    .about("Send a command to taskwarrior")
                    .version("0.1")

                    .arg(Arg::with_name("command")
                         .long("command")
                         .short("c")
                         .takes_value(true)
			 .multiple(true)
                         .required(true)
                         .help("Args written in the string will be send directly to taskwarrior"))

                    )

        .subcommand(SubCommand::with_name("add")
                    .about("create a task")
                    .version("0.1")

                    .arg(Arg::with_name("description")
                        .long("description")
                        .short("d")
                        .takes_value(true)
                        .required(true)
                        .help("Name/Description of the new task")
                    )

                    .arg(Arg::with_name("priority")
                        .long("priority")
                        .short("p")
                        .takes_value(true)
                        .required(false)
                        .help("One of l, m, h for low, medium and high priority")
                    )

                    .arg(Arg::with_name("project")
                        .long("project")
                        .takes_value(true)
                        .required(false)
                        .help("Name of the project the task is related to")
                    )

                    .arg(Arg::with_name("due")
                        .long("due")
                        .takes_value(true)
                        .required(false)
                        .help("Due date of the new task")
                    )

                    .arg(Arg::with_name("frequency")
                        .long("frequency")
                        .short("f")
                        .takes_value(true)
                        .required(false)
                        .help("Frequency of the recurrence of a task")
                    )
        )
}
<|endoftext|>


<commit_before><commit_msg>Increase frequency of physics engine<commit_after><|endoftext|>


<commit_before><commit_msg>#1 Added finite state machine example<commit_after>fn main() {
    let mut the_factory = Factory::new();
    the_factory.bottle_filling_machine = the_factory.bottle_filling_machine.step();
}

// This is our state machine.
struct BottleFillingMachine<S> {
    shared_value: usize,
    state: S,
}

// The following states can be the 'S' in StateMachine<S>
struct Waiting {
    waiting_time: std::time::Duration,
}

struct Filling {
    rate: usize,
}

struct Done;

// Our Machine starts in the 'Waiting' state.
impl BottleFillingMachine<Waiting> {
    fn new(shared_value: usize) -> Self {
        BottleFillingMachine {
            shared_value: shared_value,
            state: Waiting { waiting_time: std::time::Duration::new(0, 0) },
        }
    }
}

// The following are the defined transitions between states.
impl From<BottleFillingMachine<Waiting>> for BottleFillingMachine<Filling> {
    fn from(val: BottleFillingMachine<Waiting>) -> BottleFillingMachine<Filling> {
        BottleFillingMachine {
            shared_value: val.shared_value,
            state: Filling { rate: 1 },
        }
    }
}

impl From<BottleFillingMachine<Filling>> for BottleFillingMachine<Done> {
    fn from(val: BottleFillingMachine<Filling>) -> BottleFillingMachine<Done> {
        BottleFillingMachine {
            shared_value: val.shared_value,
            state: Done,
        }
    }
}

impl From<BottleFillingMachine<Done>> for BottleFillingMachine<Waiting> {
    fn from(val: BottleFillingMachine<Done>) -> BottleFillingMachine<Waiting> {
        BottleFillingMachine {
            shared_value: val.shared_value,
            state: Waiting { waiting_time: std::time::Duration::new(0, 0) },
        }
    }
}

// Here is we're building an enum so we can contain this state machine in a parent.
enum BottleFillingMachineWrapper {
    Waiting(BottleFillingMachine<Waiting>),
    Filling(BottleFillingMachine<Filling>),
    Done(BottleFillingMachine<Done>),
}

// Defining a function which shifts the state along.
impl BottleFillingMachineWrapper {
    fn step(mut self) -> Self {
        self = match self {
            BottleFillingMachineWrapper::Waiting(val) => {
                BottleFillingMachineWrapper::Filling(val.into())
            }
            BottleFillingMachineWrapper::Filling(val) => {
                BottleFillingMachineWrapper::Done(val.into())
            }
            BottleFillingMachineWrapper::Done(val) => {
                BottleFillingMachineWrapper::Waiting(val.into())
            }
        };
        self
    }
}

// The structure with a parent.
struct Factory {
    bottle_filling_machine: BottleFillingMachineWrapper,
}

impl Factory {
    fn new() -> Self {
        Factory {
            bottle_filling_machine:
            BottleFillingMachineWrapper::Waiting(BottleFillingMachine::new(0)),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix bug: don't recognize loop with label as expression.<commit_after><|endoftext|>


<commit_before><commit_msg>genet-kernel: fix a filter iteration issue<commit_after><|endoftext|>


<commit_before><commit_msg>Code cleanup.<commit_after><|endoftext|>


<commit_before><commit_msg>Forgot to add replay.rs<commit_after>/* This module refines a game::State object with a history.*/

use game;
use std::rc::Rc;

pub struct History {
    actions: Vec<game::Action>,
    playback_count: Option<usize>,
    pub state: game::State,
}

impl History {
    pub fn new(structure: Rc<game::Structure>) -> Self {
        History {
            actions: vec![],
            playback_count: None,
            state: game::State::new(structure),
        }
    }
    pub fn add(&mut self, action: game::Action) {
        self.actions.push(action);
        if self.playback_count.is_none() {
            self.state.execute(action);
        }
    }
    pub fn back(&mut self) -> Result<(), ()> {
        let current_count = self.playback_count.unwrap_or(self.actions.len());
        if current_count == 0 {
            return Err(());
        }
        let new_count = current_count - 1;
        self.playback_count = Some(new_count);

        self.state = game::State::new(self.state.structure.clone());
        for i in 0..new_count {
            self.state.execute(self.actions[i]);
        }
        Ok(())
    }
    pub fn forward(&mut self) -> Result<(), ()> {
        // You can only go forward if you are currently in the history replay mode.
        let current_count = self.playback_count.ok_or(())?;
        if current_count >= self.actions.len() {
            // You can't go forward if you are already at the latest position.
            return Err(());
        }
        let new_count = current_count + 1;
        self.playback_count = Some(new_count);
        self.state.execute(self.actions[current_count]);
        Ok(())
    }
    pub fn resume(&mut self) {
        if let Some(current_count) = self.playback_count {
            for i in current_count..self.actions.len() {
                self.state.execute(self.actions[i]);
            }
        } else {
            // We aren't in history playback mode so resuming doesn't do anything.
            return;
        }
    }
}
<|endoftext|>


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

#![feature(test)]

extern crate test;
extern crate xi_rope;

use test::Bencher;
use xi_rope::rope::Rope;

fn build_triangle(n: usize) -> String {
    let mut s = String::new();
    let mut line = String::new();
    for _ in 0 .. n {
        s += &line;
        s += "\n";
        line += "a";
    }
    s
}

fn build_short_lines(n: usize) -> String {
    let line = "match s.as_bytes()[minsplit - 1..splitpoint].iter().rposition(|&c| c == b'\n') {";
    let mut s = String::new();
    for _ in 0..n {
        s += line;
    }
    s
}

fn build_few_big_lines(size: usize) -> String {
    let mut s = String::with_capacity(size * 10 + 20);
    for _ in 0 .. 10 {
        for _ in 0..size {
            s += "a";
        }
        s += "\n";
    }
    s
}

#[bench]
fn benchmark_file_load_short_lines(b: &mut Bencher) {
    let text = build_short_lines(50_000);
    b.iter(|| { Rope::from(&text); });
}

#[bench]
fn benchmark_file_load_few_big_lines(b: &mut Bencher) {
    let text = build_few_big_lines(1_000_000);
    b.iter(|| { Rope::from(&text); });
}

#[bench]
fn benchmark_char_insertion_one_line_edit_str(b: &mut Bencher) {
    let mut text = Rope::from("b".repeat(100));
    let mut length = 100;
    b.iter(|| {
        text.edit_str(length, length, "a");
        length += 1;
    });
}

#[bench]
fn benchmark_paste_into_line(b: &mut Bencher) {
    let mut text = Rope::from(build_short_lines(50_000));
    let insertion = "a".repeat(50);
    let mut insertion_point = 100;
    b.iter(|| {
        text.edit_str(insertion_point, insertion_point, &insertion);
        insertion_point += 150;
    });
}

#[bench]
fn benchmark_insert_newline(b: &mut Bencher) {
    let mut text = Rope::from(build_few_big_lines(1_000_000));
    let mut pos = 1000;
    b.iter(|| {
        text.edit_str(pos, pos, "\n");
        pos += 1001;
    });
}

#[bench]
fn benchmark_overwrite_into_line(b: &mut Bencher) {
    let mut text = Rope::from(build_short_lines(50_000));
    let mut insertion_point = 100;
    let insertion = "a".repeat(50);
    b.iter(|| {
        // TODO: if the method runs too quickly, this may generate a fault
        // since there's an upper limit to how many times this can run.
        text.edit_str(insertion_point, insertion_point + 20, &insertion);
        insertion_point += 30;
    });
}

#[bench]
fn benchmark_triangle_concat_inplace(b: &mut Bencher) {
    let mut text = Rope::from("");
    let insertion = build_triangle(10_000);
    let insertion_len = insertion.len();
    let mut pos = 0;
    b.iter(|| {
        text.edit_str(pos, pos, &insertion);
        pos += insertion_len;
    });
}
<|endoftext|>


<commit_before><commit_msg>The Big Test Suite Overhaul<commit_after>

// -*- rust -*-
use std;
import std::rand;

#[test]
fn test() {
    let rand::rng r1 = rand::mk_rng();
    log r1.next();
    log r1.next();
    {
        auto r2 = rand::mk_rng();
        log r1.next();
        log r2.next();
        log r1.next();
        log r1.next();
        log r2.next();
        log r2.next();
        log r1.next();
        log r1.next();
        log r1.next();
        log r2.next();
        log r2.next();
        log r2.next();
    }
    log r1.next();
    log r1.next();
}<|endoftext|>


<commit_before><commit_msg>Add quadtree implementation<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/. */

// Implements a Quadtree data structure to keep track of which tiles have
// been rasterized and which have not.

use geom::point::Point2D;
use geom::size::Size2D;
use geom::rect::Rect;

priv enum Quadtype {
    Empty,
    Base,
    Branch,
}

priv enum Quadrant {
    TL = 0,
    TR = 1,
    BL = 2,
    BR = 3,
}

pub struct Quadtree {
    quadtype: Quadtype,
    rect: Rect<uint>,
    quadrants: [Option<~Quadtree>, ..4],
}

impl Quadtree {
    pub fn new(x: uint, y: uint, width: uint, height: uint) -> Quadtree {
        Quadtree {
            quadtype: Empty,
            rect: Rect {
                origin: Point2D(x, y),
                size: Size2D(width, height),
            },

            quadrants: [None, None, None, None],
        }
    }

    /// Determine which child contains a given point
    priv fn get_quadrant(&self, x: uint, y: uint) -> Quadrant {
        let self_width = self.rect.size.width;
        let self_height = self.rect.size.height;
        let self_x = self.rect.origin.x;
        let self_y = self.rect.origin.y;
        match (self_width, self_height) {
            (1, _) => {
                if y < self_y + self_height / 2 {
                    TL
                } else {
                    BR
                }
            }
            (_, 1) => {
                if x < self_x + self_width / 2 {
                    TL
                } else {
                    BR
                }
            }
            _ => {
                if x < self_x + self_width / 2 {
                    if y < self_y + self_height / 2 {
                        TL
                    } else {
                        BL
                    }
                } else if y < self_y + self_height / 2 {
                    TR
                } else {
                    BR
                }
            }
        }
    }

    /// Change a point from Empty to Base
    pub fn add_region(&mut self, x: uint, y: uint) {
        let self_x = self.rect.origin.x;
        let self_y = self.rect.origin.y;
        let self_width = self.rect.size.width;
        let self_height = self.rect.size.height;

        debug!("Quadtree: adding: (%?, %?) w:%?, h:%?", self_x, self_y, self_width, self_height);

        if x >= self_x + self_width || x < self_x
            || y >= self_y + self_height || y < self_y {
            return; // Out of bounds
        }
        match self.quadtype {
            Base => return,
            Empty => {
                if self_width == 1 && self_height == 1 {
                    self.quadtype = Base;
                    return;
                }
                self.quadtype = Branch;

                // Initialize children
                self.quadrants[TL as int] = Some(~Quadtree::new(self_x,
                                                                self_y,
                                                                (self_width / 2).max(&1),
                                                                (self_height / 2).max(&1)));
                if self_width > 1 && self_height > 1 {
                    self.quadrants[TR as int] = Some(~Quadtree::new(self_x + self_width / 2,
                                                                    self_y,
                                                                    self_width - self_width / 2,
                                                                    self_height / 2));
                    self.quadrants[BL as int] = Some(~Quadtree::new(self_x,
                                                                    self_y + self_height / 2,
                                                                    self_width / 2,
                                                                    self_height - self_height / 2));
                }
                self.quadrants[BR as int] = Some(~Quadtree::new(self_x + self_width / 2,
                                                                self_y + self_height / 2,
                                                                self_width - self_width / 2,
                                                                self_height - self_height / 2));
            }
            Branch => {} // Fall through
        }

        // If we've made it this far, we know we are a branch and therefore have children
        let index = self.get_quadrant(x, y) as int;

        match self.quadrants[index] {
            None => fail!("Quadtree: child query failure"),
            Some(ref mut region) => {
                // Recurse if necessary
                match region.quadtype {
                    Empty | Branch => {
                        region.add_region(x, y);
                    }
                    Base => {} // nothing to do
                }
            }
        }

        // FIXME: ideally we could make the assignments in the match,
        // but borrowed pointers prevent that. So here's a flag instead.
        let mut base_flag = 0;

        // If all children are Bases, convert self to Base
        match (&self.quadrants, self_width, self_height) {
            (&[Some(ref tl_q), _, _, Some(ref br_q)], 1, _) |
            (&[Some(ref tl_q), _, _, Some(ref br_q)], _, 1) => {
                match(tl_q.quadtype, br_q.quadtype) {
                    (Base, Base) => {
                        base_flag = 1;
                    }
                    _ => {} // nothing to do
                }
            }
            (&[Some(ref tl_q), Some(ref tr_q), Some(ref bl_q), Some(ref br_q)], _, _) => {
                    match (tl_q.quadtype, tr_q.quadtype, bl_q.quadtype, br_q.quadtype) {
                        (Base, Base, Base, Base) => {
                            base_flag = 2;
                        }
                        _ => {} // nothing to do
                    }
            }
            _ => {} // nothing to do
        }

        match base_flag {
            0 => {}
            1 => {
                self.quadtype = Base;
                self.quadrants[TL as int] = None;
                self.quadrants[BR as int] = None;
            }
            2 => {
                self.quadtype = Base;
                self.quadrants[TL as int] = None;
                self.quadrants[TR as int] = None;
                self.quadrants[BL as int] = None;
                self.quadrants[BR as int] = None;
            }
            _ => fail!("Quadtree: Unknown flag type"),
        }
    }

    /// Check if a point is a Base or Empty.
    pub fn check_region(&self, x: uint, y: uint) -> bool {
        let self_x = self.rect.origin.x;
        let self_y = self.rect.origin.y;
        let self_width = self.rect.size.width;
        let self_height = self.rect.size.height;

        if x >= self_x + self_width || x < self_x
            || y >= self_y + self_height || y < self_y {
            return false; // out of bounds
        }

        match self.quadtype {
            Empty => false,
            Base => true,
            Branch => {
                let index = self.get_quadrant(x,y) as int;
                match self.quadrants[index] {
                    None => fail!("Quadtree: child query failed"),
                    Some(ref region) => region.check_region(x, y)
                }
            }
        }
    }

}

#[test]
fn test_add_region() {
    let mut t = Quadtree::new(50, 50, 3, 4);
    assert!(!t.check_region(50, 50));
    t.add_region(50, 50);
    assert!(t.check_region(50, 50));
    assert!(!t.check_region(51, 50));
    assert!(!t.check_region(50, 51));
    t.add_region(53, 50);
    assert!(!t.check_region(53, 50));

}<|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::InheritTypes::{ElementCast};
use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::node::{Node, NodeHelpers};
use dom::window::Window;
use servo_util::namespace::Namespace;
use servo_util::str::DOMString;

use serialize::{Encoder, Encodable};

pub trait CollectionFilter {
    fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool;
}

impl<S: Encoder> Encodable<S> for ~CollectionFilter {
    fn encode(&self, _s: &mut S) {}
}

#[deriving(Encodable)]
pub enum CollectionTypeId {
    Static(~[JS<Element>]),
    Live(JS<Node>, ~CollectionFilter)
}

#[deriving(Encodable)]
pub struct HTMLCollection {
    collection: CollectionTypeId,
    reflector_: Reflector,
    window: JS<Window>,
}

impl HTMLCollection {
    pub fn new_inherited(window: JS<Window>, collection: CollectionTypeId) -> HTMLCollection {
        HTMLCollection {
            collection: collection,
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> {
        reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection),
                           window, HTMLCollectionBinding::Wrap)
    }
}

impl HTMLCollection {
    pub fn create(window: &JS<Window>, root: &JS<Node>, predicate: |elem: &JS<Element>| -> bool) -> JS<HTMLCollection> {
        let mut elements = ~[];
        for child in root.traverse_preorder() {
            if child.is_element() {
                let elem: JS<Element> = ElementCast::to(&child).unwrap();
                if predicate(&elem) {
                    elements.push(elem);
                }
            }
        }
        HTMLCollection::new(window, Static(elements))
    }

    pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString) -> JS<HTMLCollection> {
        HTMLCollection::create(window, root, |elem| elem.get().tag_name == tag_name)
    }

    pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag_name: DOMString, namespace: Namespace) -> JS<HTMLCollection> {
        HTMLCollection::create(window, root, |elem| elem.get().namespace == namespace && elem.get().tag_name == tag_name)
    }

    pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString) -> JS<HTMLCollection> {
        // FIXME: https://github.com/mozilla/servo/issues/1840
        let classes: ~[&str] = classes.split(' ').collect();
        HTMLCollection::create(window, root, |elem| classes.iter().all(|class| elem.has_class(*class)))
    }
}

impl HTMLCollection {
    // http://dom.spec.whatwg.org/#dom-htmlcollection-length
    pub fn Length(&self) -> u32 {
        match self.collection {
            Static(ref elems) => elems.len() as u32,
            Live(ref root, ref filter) => root.traverse_preorder()
                .count(|child| {
                    let elem: Option<JS<Element>> = ElementCast::to(&child);
                    elem.map_or(false, |elem| filter.filter(&elem, root))
                }) as u32
        }
    }

    // http://dom.spec.whatwg.org/#dom-htmlcollection-item
    pub fn Item(&self, index: u32) -> Option<JS<Element>> {
        match self.collection {
            Static(ref elems) => elems
                .get(index as uint)
                .map(|elem| elem.clone()),
            Live(ref root, ref filter) => root.traverse_preorder()
                .filter_map(|node| ElementCast::to(&node))
                .filter(|elem| filter.filter(elem, root))
                .nth(index as uint).clone()
        }
    }

    // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
    pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> {
        // Step 1.
        if key.is_empty() {
            return None;
        }

        // Step 2.
        match self.collection {
            Static(ref elems) => elems.iter()
                .find(|elem| {
                    elem.get_string_attribute("name") == key ||
                    elem.get_string_attribute("id") == key })
                .map(|maybe_elem| maybe_elem.clone()),
            Live(ref root, ref filter) => root.traverse_preorder()
                .filter_map(|node| ElementCast::to(&node))
                .filter(|elem| filter.filter(elem, root))
                .find(|elem| {
                    elem.get_string_attribute("name") == key ||
                    elem.get_string_attribute("id") == key })
                .map(|maybe_elem| maybe_elem.clone())
        }
    }
}

impl HTMLCollection {
    pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> {
        let maybe_elem = self.Item(index);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> {
        match maybe_name {
            Some(name) => {
                let maybe_elem = self.NamedItem(name);
                *found = maybe_elem.is_some();
                maybe_elem
            },
            None => {
                *found = false;
                None
            }
        }
    }
}

impl Reflectable for HTMLCollection {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}
<commit_msg>Implemented HTMLCollection::create_live<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::InheritTypes::{ElementCast};
use dom::bindings::codegen::HTMLCollectionBinding;
use dom::bindings::js::JS;
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::element::{Element, AttributeHandlers};
use dom::node::{Node, NodeHelpers};
use dom::window::Window;
use servo_util::namespace::Namespace;
use servo_util::str::DOMString;

use serialize::{Encoder, Encodable};

pub trait CollectionFilter {
    fn filter(&self, elem: &JS<Element>, root: &JS<Node>) -> bool;
}

impl<S: Encoder> Encodable<S> for ~CollectionFilter {
    fn encode(&self, _s: &mut S) {}
}

#[deriving(Encodable)]
pub enum CollectionTypeId {
    Static(~[JS<Element>]),
    Live(JS<Node>, ~CollectionFilter)
}

#[deriving(Encodable)]
pub struct HTMLCollection {
    collection: CollectionTypeId,
    reflector_: Reflector,
    window: JS<Window>,
}

impl HTMLCollection {
    pub fn new_inherited(window: JS<Window>, collection: CollectionTypeId) -> HTMLCollection {
        HTMLCollection {
            collection: collection,
            reflector_: Reflector::new(),
            window: window,
        }
    }

    pub fn new(window: &JS<Window>, collection: CollectionTypeId) -> JS<HTMLCollection> {
        reflect_dom_object(~HTMLCollection::new_inherited(window.clone(), collection),
                           window, HTMLCollectionBinding::Wrap)
    }
}

impl HTMLCollection {
    pub fn create_live(window: &JS<Window>, root: &JS<Node>, filter: ~CollectionFilter) -> JS<HTMLCollection> {
        HTMLCollection::new(window, Live(root.clone(), filter))
    }

    pub fn create(window: &JS<Window>, root: &JS<Node>, predicate: |elem: &JS<Element>| -> bool) -> JS<HTMLCollection> {
        let mut elements = ~[];
        for child in root.traverse_preorder() {
            if child.is_element() {
                let elem: JS<Element> = ElementCast::to(&child).unwrap();
                if predicate(&elem) {
                    elements.push(elem);
                }
            }
        }
        HTMLCollection::new(window, Static(elements))
    }

    pub fn by_tag_name(window: &JS<Window>, root: &JS<Node>, tag: DOMString)
                       -> JS<HTMLCollection> {
        struct TagNameFilter {
            tag: DOMString
        }
        impl CollectionFilter for TagNameFilter {
            fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
                elem.get().tag_name == self.tag
            }
        }
        let filter = TagNameFilter {
            tag: tag
        };
        HTMLCollection::create_live(window, root, ~filter)
    }

    pub fn by_tag_name_ns(window: &JS<Window>, root: &JS<Node>, tag: DOMString,
                          namespace: Namespace) -> JS<HTMLCollection> {
        struct TagNameNSFilter {
            tag: DOMString,
            namespace: Namespace
        }
        impl CollectionFilter for TagNameNSFilter {
            fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
                elem.get().namespace == self.namespace && elem.get().tag_name == self.tag
            }
        }
        let filter = TagNameNSFilter {
            tag: tag,
            namespace: namespace
        };
        HTMLCollection::create_live(window, root, ~filter)
    }

    pub fn by_class_name(window: &JS<Window>, root: &JS<Node>, classes: DOMString)
                         -> JS<HTMLCollection> {
        struct ClassNameFilter {
            classes: ~[DOMString]
        }
        impl CollectionFilter for ClassNameFilter {
            fn filter(&self, elem: &JS<Element>, _root: &JS<Node>) -> bool {
                self.classes.iter().all(|class| elem.has_class(*class))
            }
        }
        let filter = ClassNameFilter {
            classes: classes.split(' ').map(|class| class.into_owned()).to_owned_vec()
        };
        HTMLCollection::create_live(window, root, ~filter)
    }
}

impl HTMLCollection {
    // http://dom.spec.whatwg.org/#dom-htmlcollection-length
    pub fn Length(&self) -> u32 {
        match self.collection {
            Static(ref elems) => elems.len() as u32,
            Live(ref root, ref filter) => root.traverse_preorder()
                .count(|child| {
                    let elem: Option<JS<Element>> = ElementCast::to(&child);
                    elem.map_or(false, |elem| filter.filter(&elem, root))
                }) as u32
        }
    }

    // http://dom.spec.whatwg.org/#dom-htmlcollection-item
    pub fn Item(&self, index: u32) -> Option<JS<Element>> {
        match self.collection {
            Static(ref elems) => elems
                .get(index as uint)
                .map(|elem| elem.clone()),
            Live(ref root, ref filter) => root.traverse_preorder()
                .filter_map(|node| ElementCast::to(&node))
                .filter(|elem| filter.filter(elem, root))
                .nth(index as uint).clone()
        }
    }

    // http://dom.spec.whatwg.org/#dom-htmlcollection-nameditem
    pub fn NamedItem(&self, key: DOMString) -> Option<JS<Element>> {
        // Step 1.
        if key.is_empty() {
            return None;
        }

        // Step 2.
        match self.collection {
            Static(ref elems) => elems.iter()
                .find(|elem| {
                    elem.get_string_attribute("name") == key ||
                    elem.get_string_attribute("id") == key })
                .map(|maybe_elem| maybe_elem.clone()),
            Live(ref root, ref filter) => root.traverse_preorder()
                .filter_map(|node| ElementCast::to(&node))
                .filter(|elem| filter.filter(elem, root))
                .find(|elem| {
                    elem.get_string_attribute("name") == key ||
                    elem.get_string_attribute("id") == key })
                .map(|maybe_elem| maybe_elem.clone())
        }
    }
}

impl HTMLCollection {
    pub fn IndexedGetter(&self, index: u32, found: &mut bool) -> Option<JS<Element>> {
        let maybe_elem = self.Item(index);
        *found = maybe_elem.is_some();
        maybe_elem
    }

    pub fn NamedGetter(&self, maybe_name: Option<DOMString>, found: &mut bool) -> Option<JS<Element>> {
        match maybe_name {
            Some(name) => {
                let maybe_elem = self.NamedItem(name);
                *found = maybe_elem.is_some();
                maybe_elem
            },
            None => {
                *found = false;
                None
            }
        }
    }
}

impl Reflectable for HTMLCollection {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }

    fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
        &mut self.reflector_
    }
}
<|endoftext|>


<commit_before><commit_msg>feat: Update channel name<commit_after><|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.

//! A type that can represent all platform-native strings, but is cheaply
//! interconvertable with Rust strings.
//!
//! The need for this type arises from the fact that:
//!
//! * On Unix systems, strings are often arbitrary sequences of non-zero
//!   bytes, in many cases interpreted as UTF-8.
//!
//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
//!   values, interpreted as UTF-16 when it is valid to do so.
//!
//! * In Rust, strings are always valid UTF-8, but may contain zeros.
//!
//! The types in this module bridge this gap by simultaneously representing Rust
//! and platform-native string values, and in particular allowing a Rust string
//! to be converted into an "OS" string with no cost.
//!
//! **Note**: At the moment, these types are extremely bare-bones, usable only
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

#![unstable(feature = "os",
            reason = "recently added as part of path/io reform")]

use core::prelude::*;

use core::borrow::{BorrowFrom, ToOwned};
use fmt::{self, Debug};
use mem;
use string::{String, CowString};
use ops;
use cmp;
use hash::{Hash, Hasher, Writer};
use old_path::{Path, GenericPath};

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};
use super::AsOsStr;

/// Owned, mutable OS strings.
#[derive(Clone)]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs an `OsString` at no cost by consuming a `String`.
    pub fn from_string(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }

    /// Constructs an `OsString` by copying from a `&str` slice.
    ///
    /// Equivalent to: `OsString::from_string(String::from_str(s))`.
    pub fn from_str(s: &str) -> OsString {
        OsString { inner: Buf::from_str(s) }
    }

    /// Constructs a new empty `OsString`.
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Convert the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extend the string with the given `&OsStr` slice.
    pub fn push_os_str(&mut self, s: &OsStr) {
        self.inner.push_slice(&s.inner)
    }
}

impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: &ops::RangeFull) -> &OsStr {
        unsafe { mem::transmute(self.inner.as_slice()) }
    }
}

impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[]
    }
}

impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

impl Eq for OsString {}

impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsString {
    #[inline]
    fn hash(&self, state: &mut S) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerce directly from a `&str` slice to a `&OsStr` slice.
    pub fn from_str(s: &str) -> &OsStr {
        unsafe { mem::transmute(Slice::from_str(s)) }
    }

    /// Yield a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Convert an `OsStr` to a `CowString`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    pub fn to_string_lossy(&self) -> CowString {
        self.inner.to_string_lossy()
    }

    /// Copy the slice into an onwed `OsString`.
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Get the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::from_str(other)
    }
}

impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::from_str(self)
    }
}

impl Eq for OsStr {}

impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::from_str(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
    #[inline]
    fn hash(&self, state: &mut S) {
        self.bytes().hash(state)
    }
}

impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

impl BorrowFrom<OsString> for OsStr {
    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
}

impl ToOwned<OsString> for OsStr {
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
    fn as_os_str(&self) -> &OsStr {
        (*self).as_os_str()
    }
}

impl AsOsStr for OsStr {
    fn as_os_str(&self) -> &OsStr {
        self
    }
}

impl AsOsStr for OsString {
    fn as_os_str(&self) -> &OsStr {
        &self[]
    }
}

impl AsOsStr for str {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(self)
    }
}

impl AsOsStr for String {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(&self[])
    }
}

#[cfg(unix)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        unsafe { mem::transmute(self.as_vec()) }
    }
}

#[cfg(windows)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        // currently .as_str() is actually infallible on windows
        OsStr::from_str(self.as_str().unwrap())
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<commit_msg>Correct typo<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.

//! A type that can represent all platform-native strings, but is cheaply
//! interconvertable with Rust strings.
//!
//! The need for this type arises from the fact that:
//!
//! * On Unix systems, strings are often arbitrary sequences of non-zero
//!   bytes, in many cases interpreted as UTF-8.
//!
//! * On Windows, strings are often arbitrary sequences of non-zero 16-bit
//!   values, interpreted as UTF-16 when it is valid to do so.
//!
//! * In Rust, strings are always valid UTF-8, but may contain zeros.
//!
//! The types in this module bridge this gap by simultaneously representing Rust
//! and platform-native string values, and in particular allowing a Rust string
//! to be converted into an "OS" string with no cost.
//!
//! **Note**: At the moment, these types are extremely bare-bones, usable only
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

#![unstable(feature = "os",
            reason = "recently added as part of path/io reform")]

use core::prelude::*;

use core::borrow::{BorrowFrom, ToOwned};
use fmt::{self, Debug};
use mem;
use string::{String, CowString};
use ops;
use cmp;
use hash::{Hash, Hasher, Writer};
use old_path::{Path, GenericPath};

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};
use super::AsOsStr;

/// Owned, mutable OS strings.
#[derive(Clone)]
pub struct OsString {
    inner: Buf
}

/// Slices into OS strings.
pub struct OsStr {
    inner: Slice
}

impl OsString {
    /// Constructs an `OsString` at no cost by consuming a `String`.
    pub fn from_string(s: String) -> OsString {
        OsString { inner: Buf::from_string(s) }
    }

    /// Constructs an `OsString` by copying from a `&str` slice.
    ///
    /// Equivalent to: `OsString::from_string(String::from_str(s))`.
    pub fn from_str(s: &str) -> OsString {
        OsString { inner: Buf::from_str(s) }
    }

    /// Constructs a new empty `OsString`.
    pub fn new() -> OsString {
        OsString { inner: Buf::from_string(String::new()) }
    }

    /// Convert the `OsString` into a `String` if it contains valid Unicode data.
    ///
    /// On failure, ownership of the original `OsString` is returned.
    pub fn into_string(self) -> Result<String, OsString> {
        self.inner.into_string().map_err(|buf| OsString { inner: buf} )
    }

    /// Extend the string with the given `&OsStr` slice.
    pub fn push_os_str(&mut self, s: &OsStr) {
        self.inner.push_slice(&s.inner)
    }
}

impl ops::Index<ops::RangeFull> for OsString {
    type Output = OsStr;

    #[inline]
    fn index(&self, _index: &ops::RangeFull) -> &OsStr {
        unsafe { mem::transmute(self.inner.as_slice()) }
    }
}

impl ops::Deref for OsString {
    type Target = OsStr;

    #[inline]
    fn deref(&self) -> &OsStr {
        &self[]
    }
}

impl Debug for OsString {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        fmt::Debug::fmt(&**self, formatter)
    }
}

impl PartialEq for OsString {
    fn eq(&self, other: &OsString) -> bool {
        &**self == &**other
    }
}

impl PartialEq<str> for OsString {
    fn eq(&self, other: &str) -> bool {
        &**self == other
    }
}

impl PartialEq<OsString> for str {
    fn eq(&self, other: &OsString) -> bool {
        &**other == self
    }
}

impl Eq for OsString {}

impl PartialOrd for OsString {
    #[inline]
    fn partial_cmp(&self, other: &OsString) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(&**other)
    }
    #[inline]
    fn lt(&self, other: &OsString) -> bool { &**self < &**other }
    #[inline]
    fn le(&self, other: &OsString) -> bool { &**self <= &**other }
    #[inline]
    fn gt(&self, other: &OsString) -> bool { &**self > &**other }
    #[inline]
    fn ge(&self, other: &OsString) -> bool { &**self >= &**other }
}

impl PartialOrd<str> for OsString {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        (&**self).partial_cmp(other)
    }
}

impl Ord for OsString {
    #[inline]
    fn cmp(&self, other: &OsString) -> cmp::Ordering {
        (&**self).cmp(&**other)
    }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsString {
    #[inline]
    fn hash(&self, state: &mut S) {
        (&**self).hash(state)
    }
}

impl OsStr {
    /// Coerce directly from a `&str` slice to a `&OsStr` slice.
    pub fn from_str(s: &str) -> &OsStr {
        unsafe { mem::transmute(Slice::from_str(s)) }
    }

    /// Yield a `&str` slice if the `OsStr` is valid unicode.
    ///
    /// This conversion may entail doing a check for UTF-8 validity.
    pub fn to_str(&self) -> Option<&str> {
        self.inner.to_str()
    }

    /// Convert an `OsStr` to a `CowString`.
    ///
    /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
    pub fn to_string_lossy(&self) -> CowString {
        self.inner.to_string_lossy()
    }

    /// Copy the slice into an owned `OsString`.
    pub fn to_os_string(&self) -> OsString {
        OsString { inner: self.inner.to_owned() }
    }

    /// Get the underlying byte representation.
    ///
    /// Note: it is *crucial* that this API is private, to avoid
    /// revealing the internal, platform-specific encodings.
    fn bytes(&self) -> &[u8] {
        unsafe { mem::transmute(&self.inner) }
    }
}

impl PartialEq for OsStr {
    fn eq(&self, other: &OsStr) -> bool {
        self.bytes().eq(other.bytes())
    }
}

impl PartialEq<str> for OsStr {
    fn eq(&self, other: &str) -> bool {
        *self == *OsStr::from_str(other)
    }
}

impl PartialEq<OsStr> for str {
    fn eq(&self, other: &OsStr) -> bool {
        *other == *OsStr::from_str(self)
    }
}

impl Eq for OsStr {}

impl PartialOrd for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &OsStr) -> Option<cmp::Ordering> {
        self.bytes().partial_cmp(other.bytes())
    }
    #[inline]
    fn lt(&self, other: &OsStr) -> bool { self.bytes().lt(other.bytes()) }
    #[inline]
    fn le(&self, other: &OsStr) -> bool { self.bytes().le(other.bytes()) }
    #[inline]
    fn gt(&self, other: &OsStr) -> bool { self.bytes().gt(other.bytes()) }
    #[inline]
    fn ge(&self, other: &OsStr) -> bool { self.bytes().ge(other.bytes()) }
}

impl PartialOrd<str> for OsStr {
    #[inline]
    fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
        self.partial_cmp(OsStr::from_str(other))
    }
}

// FIXME (#19470): cannot provide PartialOrd<OsStr> for str until we
// have more flexible coherence rules.

impl Ord for OsStr {
    #[inline]
    fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
}

impl<'a, S: Hasher + Writer> Hash<S> for OsStr {
    #[inline]
    fn hash(&self, state: &mut S) {
        self.bytes().hash(state)
    }
}

impl Debug for OsStr {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.inner.fmt(formatter)
    }
}

impl BorrowFrom<OsString> for OsStr {
    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
}

impl ToOwned<OsString> for OsStr {
    fn to_owned(&self) -> OsString { self.to_os_string() }
}

impl<'a, T: AsOsStr + ?Sized> AsOsStr for &'a T {
    fn as_os_str(&self) -> &OsStr {
        (*self).as_os_str()
    }
}

impl AsOsStr for OsStr {
    fn as_os_str(&self) -> &OsStr {
        self
    }
}

impl AsOsStr for OsString {
    fn as_os_str(&self) -> &OsStr {
        &self[]
    }
}

impl AsOsStr for str {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(self)
    }
}

impl AsOsStr for String {
    fn as_os_str(&self) -> &OsStr {
        OsStr::from_str(&self[])
    }
}

#[cfg(unix)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        unsafe { mem::transmute(self.as_vec()) }
    }
}

#[cfg(windows)]
impl AsOsStr for Path {
    fn as_os_str(&self) -> &OsStr {
        // currently .as_str() is actually infallible on windows
        OsStr::from_str(self.as_str().unwrap())
    }
}

impl FromInner<Buf> for OsString {
    fn from_inner(buf: Buf) -> OsString {
        OsString { inner: buf }
    }
}

impl IntoInner<Buf> for OsString {
    fn into_inner(self) -> Buf {
        self.inner
    }
}

impl AsInner<Slice> for OsStr {
    fn as_inner(&self) -> &Slice {
        &self.inner
    }
}
<|endoftext|>