<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 enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean,
    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
    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.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 == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(0);
            }
        };

        // 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");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            _ => { },
        };

        // 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.");
            }
            "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 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 {
            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 }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-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 takes no arguments\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }
                Subcommand::Clean
            }
            "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 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);

        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"),
        }
    }
}

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 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>Fail ./x.py on invalid command<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 enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean,
    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
    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.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 == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(1);
            }
        };

        // 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");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            _ => { },
        };

        // 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.");
            }
            "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 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 {
            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 }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-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 takes no arguments\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }
                Subcommand::Clean
            }
            "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 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);

        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"),
        }
    }
}

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 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>unbreak collections::Vec::{ grow, relinquish }<commit_after><|endoftext|>


<commit_before>use libimagerror::trace::trace_error;

use store::FileLockEntry;
use storeid::StoreId;
use hook::Hook;
use hook::result::HookResult;
use hook::accessor::{StoreIdAccessor, MutableHookDataAccessor, NonMutableHookDataAccessor};
use hook::accessor::HookDataAccessor as HDA;

use hook::error::HookError as HE;
use hook::error::HookErrorKind as HEK;
use configuration::AspectConfig;

#[derive(Debug)]
pub struct Aspect {
    cfg: Option<AspectConfig>,
    name: String,
    hooks: Vec<Box<Hook>>,
}

impl Aspect {

    pub fn new(name: String, cfg: Option<AspectConfig>) -> Aspect {
        Aspect {
            cfg: cfg,
            name: name,
            hooks: vec![],
        }
    }

    pub fn name(&self) -> &String {
        &self.name
    }

    pub fn register_hook(&mut self, h: Box<Hook>) {
        self.hooks.push(h);
    }

}

impl StoreIdAccessor for Aspect {
    fn access(&self, id: &StoreId) -> HookResult<()> {
        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
        if !accessors.iter().all(|a| is_match!(*a, HDA::StoreIdAccess(_))) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        accessors
            .iter()
            .fold(Ok(()), |acc, accessor| {
                acc.and_then(|_| {
                    let res = match accessor {
                        &HDA::StoreIdAccess(accessor) => accessor.access(id),
                        _ => unreachable!(),
                    };

                    match res {
                        Ok(res) => Ok(res),
                        Err(e) => {
                            if !e.is_aborting() {
                                trace_error(&e);
                                // ignore error if it is not aborting, as we printed it already
                                Ok(())
                            } else {
                                Err(e)
                            }
                        }
                    }
                })
            })
    }
}

impl MutableHookDataAccessor for Aspect {
    fn access_mut(&self, fle: &mut FileLockEntry) -> HookResult<()> {
        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();

        fn is_file_accessor(a: &HDA) -> bool {
            is_match!(*a, HDA::MutableAccess(_) | HDA::NonMutableAccess(_))
        }

        if !accessors.iter().all(|a| is_file_accessor(a)) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        // TODO: Naiive implementation.
        // More sophisticated version would check whether there are _chunks_ of
        // NonMutableAccess accessors and execute these chunks in parallel. We do not have
        // performance concerns yet, so this is okay.
        accessors.iter().fold(Ok(()), |acc, accessor| {
            acc.and_then(|_| {
                let res = match accessor {
                    &HDA::MutableAccess(ref accessor)    => accessor.access_mut(fle),
                    &HDA::NonMutableAccess(ref accessor) => accessor.access(fle),
                    _ => unreachable!(),
                };

                match res {
                    Ok(res) => Ok(res),
                    Err(e) => {
                        if !e.is_aborting() {
                            trace_error(&e);
                            // ignore error if it is not aborting, as we printed it already
                            Ok(())
                        } else {
                            Err(e)
                        }
                    }
                }
            })
        })
    }
}

impl NonMutableHookDataAccessor for Aspect {
    fn access(&self, fle: &FileLockEntry) -> HookResult<()> {
        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
        if !accessors.iter().all(|a| is_match!(*a, HDA::NonMutableAccess(_))) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        accessors
            .iter()
            .fold(Ok(()), |acc, accessor| {
                acc.and_then(|_| {
                    let res = match accessor {
                        &HDA::NonMutableAccess(accessor) => accessor.access(fle),
                        _ => unreachable!(),
                    };

                    match res {
                        Ok(res) => Ok(res),
                        Err(e) => {
                            if !e.is_aborting() {
                                trace_error(&e);
                                // ignore error if it is not aborting, as we printed it already
                                Ok(())
                            } else {
                                Err(e)
                            }
                        }
                    }
                })
            })
    }
}

<commit_msg>Deny mutable access for hooks if the config says so<commit_after>use libimagerror::trace::trace_error;

use store::FileLockEntry;
use storeid::StoreId;
use hook::Hook;
use hook::result::HookResult;
use hook::accessor::{StoreIdAccessor, MutableHookDataAccessor, NonMutableHookDataAccessor};
use hook::accessor::HookDataAccessor as HDA;

use hook::error::HookError as HE;
use hook::error::HookErrorKind as HEK;
use configuration::AspectConfig;

#[derive(Debug)]
pub struct Aspect {
    cfg: Option<AspectConfig>,
    name: String,
    hooks: Vec<Box<Hook>>,
}

impl Aspect {

    pub fn new(name: String, cfg: Option<AspectConfig>) -> Aspect {
        Aspect {
            cfg: cfg,
            name: name,
            hooks: vec![],
        }
    }

    pub fn name(&self) -> &String {
        &self.name
    }

    pub fn register_hook(&mut self, h: Box<Hook>) {
        self.hooks.push(h);
    }

}

impl StoreIdAccessor for Aspect {
    fn access(&self, id: &StoreId) -> HookResult<()> {
        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
        if !accessors.iter().all(|a| is_match!(*a, HDA::StoreIdAccess(_))) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        accessors
            .iter()
            .fold(Ok(()), |acc, accessor| {
                acc.and_then(|_| {
                    let res = match accessor {
                        &HDA::StoreIdAccess(accessor) => accessor.access(id),
                        _ => unreachable!(),
                    };

                    match res {
                        Ok(res) => Ok(res),
                        Err(e) => {
                            if !e.is_aborting() {
                                trace_error(&e);
                                // ignore error if it is not aborting, as we printed it already
                                Ok(())
                            } else {
                                Err(e)
                            }
                        }
                    }
                })
            })
    }
}

impl MutableHookDataAccessor for Aspect {
    fn access_mut(&self, fle: &mut FileLockEntry) -> HookResult<()> {
        if !self.cfg.as_ref().map(|c| c.allow_mutable_hooks()).unwrap_or(false) {
            return Err(HE::new(HEK::MutableHooksNotAllowed, None));
        }

        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();

        fn is_file_accessor(a: &HDA) -> bool {
            is_match!(*a, HDA::MutableAccess(_) | HDA::NonMutableAccess(_))
        }

        if !accessors.iter().all(|a| is_file_accessor(a)) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        // TODO: Naiive implementation.
        // More sophisticated version would check whether there are _chunks_ of
        // NonMutableAccess accessors and execute these chunks in parallel. We do not have
        // performance concerns yet, so this is okay.
        accessors.iter().fold(Ok(()), |acc, accessor| {
            acc.and_then(|_| {
                let res = match accessor {
                    &HDA::MutableAccess(ref accessor)    => accessor.access_mut(fle),
                    &HDA::NonMutableAccess(ref accessor) => accessor.access(fle),
                    _ => unreachable!(),
                };

                match res {
                    Ok(res) => Ok(res),
                    Err(e) => {
                        if !e.is_aborting() {
                            trace_error(&e);
                            // ignore error if it is not aborting, as we printed it already
                            Ok(())
                        } else {
                            Err(e)
                        }
                    }
                }
            })
        })
    }
}

impl NonMutableHookDataAccessor for Aspect {
    fn access(&self, fle: &FileLockEntry) -> HookResult<()> {
        let accessors : Vec<HDA> = self.hooks.iter().map(|h| h.accessor()).collect();
        if !accessors.iter().all(|a| is_match!(*a, HDA::NonMutableAccess(_))) {
            return Err(HE::new(HEK::AccessTypeViolation, None));
        }

        accessors
            .iter()
            .fold(Ok(()), |acc, accessor| {
                acc.and_then(|_| {
                    let res = match accessor {
                        &HDA::NonMutableAccess(accessor) => accessor.access(fle),
                        _ => unreachable!(),
                    };

                    match res {
                        Ok(res) => Ok(res),
                        Err(e) => {
                            if !e.is_aborting() {
                                trace_error(&e);
                                // ignore error if it is not aborting, as we printed it already
                                Ok(())
                            } else {
                                Err(e)
                            }
                        }
                    }
                })
            })
    }
}

<|endoftext|>


<commit_before><commit_msg>Add MergeRange.<commit_after>
#![feature(core)]
use std::num::{Int, NumCast, ToPrimitive};
use std::cmp::{min, max};

use self::MergeResult::*;

#[derive(Copy,Debug,Eq,PartialEq)]
struct MergeRange {
    start: u64,
    end: u64,
}

#[derive(Copy,Debug,Eq,PartialEq)]
enum MergeResult {
    Separate,
    Adjacent(MergeRange),
    Overlap(MergeRange, MergeRange),
}

fn encode_as_u64<T: Int>(x: T) -> u64 {
    if <T as Int>::min_value() >= <T as Int>::zero() {
        // The unsigned case is easy.
        x.to_u64().unwrap()
    } else {
        // For the signed case, we convert to i64, then convert that to u64 with
        // a shift upward to keep the domain continuous.
        let x_i64 = x.to_i64().unwrap();
        if x_i64 >= 0 {
            x_i64.to_u64().unwrap() + (1u64 << 63)
        } else {
            (x_i64 - <i64 as Int>::min_value()).to_u64().unwrap()
        }
    }
}

fn decode_from_u64<T: Int>(x: u64) -> T {
    if <T as Int>::min_value() >= <T as Int>::zero() {
        <T as NumCast>::from(x).unwrap()
    } else {
        let x_i64 = if x >= (1u64 << 63) {
            (x - (1u64 << 63)).to_i64().unwrap()
        } else {
            x.to_i64().unwrap() + <i64 as Int>::min_value()
        };
        <T as NumCast>::from(x_i64).unwrap()
    }
}

impl MergeRange {
    fn from_range<T: Int>(start: T, end: T) -> MergeRange {
        assert!(start <= end);
        MergeRange {
            start: encode_as_u64(start),
            end: encode_as_u64(end),
        }
    }
    fn to_range<T: Int>(self) -> (T, T) {
        (decode_from_u64(self.start), decode_from_u64(self.end))
    }
    fn from_range_to<T: Int>(end: T) -> MergeRange {
        MergeRange::from_range(<T as Int>::min_value(), end)
    }
    fn from_range_from<T: Int>(start: T) -> MergeRange {
        MergeRange::from_range(start, <T as Int>::max_value())
    }
    fn range_full<T: Int>() -> MergeRange {
        MergeRange::from_range(<T as Int>::min_value(), <T as Int>::max_value())
    }
    fn concatenate(self, other: MergeRange) -> Option<MergeRange> {
        if self.end < (<u64 as Int>::max_value()) &&
            self.end + 1 == other.start {
                Some(MergeRange{start: self.start, end: other.end})
            } else {
                None
            }
    }
    fn merge(self, other: MergeRange) -> MergeResult {
        // Check for adjacent ranges that can be concatenated.
        match self.concatenate(other) {
            Some(concat) => return Adjacent(concat),
            _ => match other.concatenate(self) {
                Some(concat) => return Adjacent(concat),
                _ => (),
            }
        }
        // Check for overlap in the ranges.
        if self.start <= other.end && other.start <= self.end {
            Overlap(MergeRange{start: min(self.start, other.start),
                               end: max(self.end, other.end)},
                    MergeRange{start: max(self.start, other.start),
                               end: min(self.end, other.end)})
        } else {
            Separate
        }
    }
}

#[cfg(test)]
mod tests {
    use std::num::Int;
    use super::MergeRange;
    use super::MergeResult::*;
    #[test]
    fn unsigned_range_merge_range_conversion() {
        assert_eq!(MergeRange::from_range(0u32, 20u32).to_range(),
                   (0u32, 20u32));
    }
    #[test]
    fn signed_range_merge_range_conversion() {
        assert_eq!(MergeRange::from_range(-5i64, 5i64).to_range(),
                   (-5i64, 5i64));
        assert_eq!(MergeRange::from_range(0i32, 0i32).to_range(),
                   (0i32, 0i32));
    }
    #[test]
    fn range_to_merge_range_conversion() {
        assert_eq!(MergeRange::from_range_to(2i8).to_range(),
                   (<i8 as Int>::min_value(), 2i8));
    }
    #[test]
    fn range_from_merge_range_conversion() {
        assert_eq!(MergeRange::from_range_from(2u8).to_range(),
                   (2u8, <u8 as Int>::max_value()));
    }
    #[test]
    fn range_full_merge_range_conversion() {
        assert_eq!(MergeRange::range_full::<i32>().to_range(),
                   (<i32 as Int>::min_value(), <i32 as Int>::max_value()));
    }
    #[test]
    fn merge_separate_ranges() {
        let x = MergeRange::from_range(1i32, 2);
        let y = MergeRange::from_range(4i32, 5);
        assert_eq!(x.merge(y), Separate);
    }
    #[test]
    fn merge_adjacent_ranges() {
        let x = MergeRange::from_range(1i32, 2);
        let y = MergeRange::from_range(3i32, 5);
        assert_eq!(x.merge(y), Adjacent(MergeRange::from_range(1i32, 5)));
        assert_eq!(y.merge(x), x.merge(y));
    }
    #[test]
    fn merge_edge_adjacent_ranges() {
        let x = MergeRange::from_range_to(1u64);
        let y = MergeRange::from_range_from(2u64);
        assert_eq!(x.merge(y), Adjacent(MergeRange::range_full::<u64>()));
        assert_eq!(y.merge(x), x.merge(y));
    }
    #[test]
    fn merge_overlapping_ranges() {
        let x = MergeRange::from_range(-1i8, 2);
        let y = MergeRange::from_range(0i8, 5);
        assert_eq!(x.merge(y), Overlap(MergeRange::from_range(-1i8, 5),
                                       MergeRange::from_range(0i8, 2)));
        assert_eq!(y.merge(x), x.merge(y));
    }
    #[test]
    fn merge_contained_range() {
        let x = MergeRange::from_range(-1i8, 5);
        let y = MergeRange::from_range(0i8, 2);
        assert_eq!(x.merge(y), Overlap(MergeRange::from_range(-1i8, 5),
                                       MergeRange::from_range(0i8, 2)));
        assert_eq!(y.merge(x), x.merge(y));
    }
}
<|endoftext|>


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

//! The `Default` trait for types which may have meaningful default values.
//!
//! Sometimes, you want to fall back to some kind of default value, and
//! don't particularly care what it is. This comes up often with `struct`s
//! that define a set of options:
//!
//! ```
//! # #[allow(dead_code)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//! ```
//!
//! How can we define some default values? You can use `Default`:
//!
//! ```
//! # #[allow(dead_code)]
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! Now, you get all of the default values. Rust implements `Default` for various primitives types.
//! If you have your own type, you need to implement `Default` yourself:
//!
//! ```
//! # #![allow(dead_code)]
//! enum Kind {
//!     A,
//!     B,
//!     C,
//! }
//!
//! impl Default for Kind {
//!     fn default() -> Kind { Kind::A }
//! }
//!
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//!     baz: Kind,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! If you want to override a particular option, but still retain the other defaults:
//!
//! ```
//! # #[allow(dead_code)]
//! # #[derive(Default)]
//! # struct SomeOptions {
//! #     foo: i32,
//! #     bar: f32,
//! # }
//! fn main() {
//!     let options = SomeOptions { foo: 42, ..Default::default() };
//! }
//! ```

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

use marker::Sized;

/// A trait for giving a type a useful default value.
///
/// A struct can derive default implementations of `Default` for basic types using
/// `#[derive(Default)]`.
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), () }
default_impl! { bool, false }
default_impl! { char, '\x00' }

default_impl! { usize, 0 }
default_impl! { u8, 0 }
default_impl! { u16, 0 }
default_impl! { u32, 0 }
default_impl! { u64, 0 }

default_impl! { isize, 0 }
default_impl! { i8, 0 }
default_impl! { i16, 0 }
default_impl! { i32, 0 }
default_impl! { i64, 0 }

default_impl! { f32, 0.0f32 }
default_impl! { f64, 0.0f64 }
<commit_msg>Make the Default docs more like the other traits<commit_after>// Copyright 2013 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.

//! The `Default` trait for types which may have meaningful default values.
//!
//! Sometimes, you want to fall back to some kind of default value, and
//! don't particularly care what it is. This comes up often with `struct`s
//! that define a set of options:
//!
//! ```
//! # #[allow(dead_code)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//! ```
//!
//! How can we define some default values? You can use `Default`:
//!
//! ```
//! # #[allow(dead_code)]
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! Now, you get all of the default values. Rust implements `Default` for various primitives types.
//! If you have your own type, you need to implement `Default` yourself:
//!
//! ```
//! # #![allow(dead_code)]
//! enum Kind {
//!     A,
//!     B,
//!     C,
//! }
//!
//! impl Default for Kind {
//!     fn default() -> Kind { Kind::A }
//! }
//!
//! #[derive(Default)]
//! struct SomeOptions {
//!     foo: i32,
//!     bar: f32,
//!     baz: Kind,
//! }
//!
//!
//! fn main() {
//!     let options: SomeOptions = Default::default();
//! }
//! ```
//!
//! If you want to override a particular option, but still retain the other defaults:
//!
//! ```
//! # #[allow(dead_code)]
//! # #[derive(Default)]
//! # struct SomeOptions {
//! #     foo: i32,
//! #     bar: f32,
//! # }
//! fn main() {
//!     let options = SomeOptions { foo: 42, ..Default::default() };
//! }
//! ```

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

use marker::Sized;

/// A trait for giving a type a useful default value. For more information, see
/// [the module-level documentation][module].
///
/// [module]: ../../std/default/index.html
///
/// ## Derivable
///
/// This trait can be used with `#[derive]` if all of the type's fields implement
/// `Default`. When `derive`d, it will use the default value for each field's type.
///
/// ## How can I implement `Default`?
///
/// Provide an implementation for the `default()` method that returns the value of
/// your type that should be the default:
///
/// ```
/// # #![allow(dead_code)]
/// enum Kind {
///     A,
///     B,
///     C,
/// }
///
/// impl Default for Kind {
///     fn default() -> Kind { Kind::A }
/// }
/// ```
///
/// # Examples
///
/// ```
/// # #[allow(dead_code)]
/// #[derive(Default)]
/// struct SomeOptions {
///     foo: i32,
///     bar: f32,
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Default: Sized {
    /// Returns the "default value" for a type.
    ///
    /// Default values are often some kind of initial value, identity value, or anything else that
    /// may make sense as a default.
    ///
    /// # Examples
    ///
    /// Using built-in default values:
    ///
    /// ```
    /// let i: i8 = Default::default();
    /// let (x, y): (Option<String>, f64) = Default::default();
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
    /// ```
    ///
    /// Making your own:
    ///
    /// ```
    /// # #[allow(dead_code)]
    /// enum Kind {
    ///     A,
    ///     B,
    ///     C,
    /// }
    ///
    /// impl Default for Kind {
    ///     fn default() -> Kind { Kind::A }
    /// }
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn default() -> Self;
}

macro_rules! default_impl {
    ($t:ty, $v:expr) => {
        #[stable(feature = "rust1", since = "1.0.0")]
        impl Default for $t {
            #[inline]
            fn default() -> $t { $v }
        }
    }
}

default_impl! { (), () }
default_impl! { bool, false }
default_impl! { char, '\x00' }

default_impl! { usize, 0 }
default_impl! { u8, 0 }
default_impl! { u16, 0 }
default_impl! { u32, 0 }
default_impl! { u64, 0 }

default_impl! { isize, 0 }
default_impl! { i8, 0 }
default_impl! { i16, 0 }
default_impl! { i32, 0 }
default_impl! { i64, 0 }

default_impl! { f32, 0.0f32 }
default_impl! { f64, 0.0f64 }
<|endoftext|>


<commit_before><commit_msg>Test case showing that issue 324 is resolved.<commit_after>// xfail-boot
fn main() {

  obj foo(mutable int i) {
      fn inc_by(int incr) -> int {
          i += incr;
          ret i;
      }

      fn inc_by_5() -> int {
          ret self.inc_by(5);
      }

      // A test case showing that issue #324 is resolved.  (It used to
      // be that commenting out this (unused!) function produced a
      // type error.)
      // fn wrapper(int incr) -> int {
      //     ret self.inc_by(incr);
      // }

      fn get() -> int {
          ret i;
      }
  }

  let int res;
  auto o = foo(5);

  res = o.get();
  assert (res == 5);

  res = o.inc_by(3);
  assert (res == 8);

  res = o.get();
  assert (res == 8);

}

<|endoftext|>


<commit_before><commit_msg>Error Handling | https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/error-handling.html * "Standard library traits used for error handling" part<commit_after><|endoftext|>


<commit_before><commit_msg>Add failing use case for CubeMapArray type in shaders.<commit_after>#[macro_use]
extern crate glium;

mod support;

// Tests for support of the cube map array type in programs.
fn program_support_for_cube_map_array(type_prefix: &str) {
    let display = support::build_display();
    let _ = glium::Program::from_source(
        &display,
        "
            #version 400

            attribute vec2 position;

            void main() {
                gl_Position = vec4(position, 0.0, 1.0);
            }
        ",
        &format!(
            "
                #version 400

                uniform {}samplerCubeArray cube_textures;

                void main() {{
                    gl_FragColor = texture(cube_textures, vec4(0, 0, 0, 0));
                }}
            ",
            type_prefix
        ),
        None
    ).unwrap();
}

#[test]
fn program_support_for_cube_map_array_float() {
    program_support_for_cube_map_array("");
}

#[test]
fn program_support_for_cube_map_array_unsigned() {
    program_support_for_cube_map_array("u");
}

#[test]
fn program_support_for_cube_map_array_integral() {
    program_support_for_cube_map_array("i");
}
<|endoftext|>


<commit_before><commit_msg>Note about file level annotations in Rust<commit_after>// This definition works for current file.
// Everywhere.
#![allow(dead_code)]
<|endoftext|>


<commit_before><commit_msg>command refactor<commit_after><|endoftext|>


<commit_before>use std::cmp;
use std::io::{self, Read, BufRead};

pub struct BufReader<R> {
    inner: R,
    buf: Vec<u8>,
    pos: usize,
    cap: usize,
}

const INIT_BUFFER_SIZE: usize = 4096;
const MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

impl<R: Read> BufReader<R> {
    #[inline]
    pub fn new(rdr: R) -> BufReader<R> {
        BufReader::with_capacity(rdr, INIT_BUFFER_SIZE)
    }

    #[inline]
    pub fn with_capacity(rdr: R, cap: usize) -> BufReader<R> {
        BufReader {
            inner: rdr,
            buf: vec![0; cap],
            pos: 0,
            cap: 0,
        }
    }

    #[inline]
    pub fn get_ref(&self) -> &R { &self.inner }

    #[inline]
    pub fn get_mut(&mut self) -> &mut R { &mut self.inner }

    #[inline]
    pub fn get_buf(&self) -> &[u8] {
        if self.pos < self.cap {
            trace!("get_buf [u8; {}][{}..{}]", self.buf.len(), self.pos, self.cap);
            &self.buf[self.pos..self.cap]
        } else {
            trace!("get_buf []");
            &[]
        }
    }

    #[inline]
    pub fn into_inner(self) -> R { self.inner }

    #[inline]
    pub fn read_into_buf(&mut self) -> io::Result<usize> {
        self.maybe_reserve();
        let v = &mut self.buf;
        trace!("read_into_buf buf[{}..{}]", self.cap, v.len());
        if self.cap < v.capacity() {
            let nread = try!(self.inner.read(&mut v[self.cap..]));
            self.cap += nread;
            Ok(nread)
        } else {
            trace!("read_into_buf at full capacity");
            Ok(0)
        }
    }

    #[inline]
    fn maybe_reserve(&mut self) {
        let cap = self.buf.capacity();
        if self.cap == cap && cap < MAX_BUFFER_SIZE {
            self.buf.reserve(cmp::min(cap * 4, MAX_BUFFER_SIZE) - cap);
            let new = self.buf.capacity() - self.buf.len();
            trace!("reserved {}", new);
            unsafe { grow_zerofill(&mut self.buf, new) }
        }
    }
}

#[inline]
unsafe fn grow_zerofill(buf: &mut Vec<u8>, additional: usize) {
    use std::ptr;
    let len = buf.len();
    buf.set_len(len + additional);
    ptr::write_bytes(buf.as_mut_ptr(), 0, buf.len());
}

impl<R: Read> Read for BufReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.cap == self.pos && buf.len() >= self.buf.len() {
            return self.inner.read(buf);
        }
        let nread = {
           let mut rem = try!(self.fill_buf());
           try!(rem.read(buf))
        };
        self.consume(nread);
        Ok(nread)
    }
}

impl<R: Read> BufRead for BufReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.pos == self.cap {
            self.cap = try!(self.inner.read(&mut self.buf));
            self.pos = 0;
        }
        Ok(&self.buf[self.pos..self.cap])
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        self.pos = cmp::min(self.pos + amt, self.cap);
        if self.pos == self.cap {
            self.pos = 0;
            self.cap = 0;
        }
    }
}

#[cfg(test)]
mod tests {

    use std::io::{self, Read, BufRead};
    use super::BufReader;

    struct SlowRead(u8);

    impl Read for SlowRead {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            let state = self.0;
            self.0 += 1;
            (&match state % 3 {
                0 => b"foo",
                1 => b"bar",
                _ => b"baz",
            }[..]).read(buf)
        }
    }

    #[test]
    fn test_consume_and_get_buf() {
        let mut rdr = BufReader::new(SlowRead(0));
        rdr.read_into_buf().unwrap();
        rdr.consume(1);
        assert_eq!(rdr.get_buf(), b"oo");
        rdr.read_into_buf().unwrap();
        rdr.read_into_buf().unwrap();
        assert_eq!(rdr.get_buf(), b"oobarbaz");
        rdr.consume(5);
        assert_eq!(rdr.get_buf(), b"baz");
        rdr.consume(3);
        assert_eq!(rdr.get_buf(), b"");
        assert_eq!(rdr.pos, 0);
        assert_eq!(rdr.cap, 0);
    }
}
<commit_msg>fix(buffer): fix incorrect resizing of BufReader<commit_after>use std::cmp;
use std::io::{self, Read, BufRead};

pub struct BufReader<R> {
    inner: R,
    buf: Vec<u8>,
    pos: usize,
    cap: usize,
}

const INIT_BUFFER_SIZE: usize = 4096;
const MAX_BUFFER_SIZE: usize = 8192 + 4096 * 100;

impl<R: Read> BufReader<R> {
    #[inline]
    pub fn new(rdr: R) -> BufReader<R> {
        BufReader::with_capacity(rdr, INIT_BUFFER_SIZE)
    }

    #[inline]
    pub fn with_capacity(rdr: R, cap: usize) -> BufReader<R> {
        BufReader {
            inner: rdr,
            buf: vec![0; cap],
            pos: 0,
            cap: 0,
        }
    }

    #[inline]
    pub fn get_ref(&self) -> &R { &self.inner }

    #[inline]
    pub fn get_mut(&mut self) -> &mut R { &mut self.inner }

    #[inline]
    pub fn get_buf(&self) -> &[u8] {
        if self.pos < self.cap {
            trace!("get_buf [u8; {}][{}..{}]", self.buf.len(), self.pos, self.cap);
            &self.buf[self.pos..self.cap]
        } else {
            trace!("get_buf []");
            &[]
        }
    }

    #[inline]
    pub fn into_inner(self) -> R { self.inner }

    #[inline]
    pub fn read_into_buf(&mut self) -> io::Result<usize> {
        self.maybe_reserve();
        let v = &mut self.buf;
        trace!("read_into_buf buf[{}..{}]", self.cap, v.len());
        if self.cap < v.capacity() {
            let nread = try!(self.inner.read(&mut v[self.cap..]));
            self.cap += nread;
            Ok(nread)
        } else {
            trace!("read_into_buf at full capacity");
            Ok(0)
        }
    }

    #[inline]
    fn maybe_reserve(&mut self) {
        let cap = self.buf.capacity();
        if self.cap == cap && cap < MAX_BUFFER_SIZE {
            self.buf.reserve(cmp::min(cap * 4, MAX_BUFFER_SIZE) - cap);
            let new = self.buf.capacity() - self.buf.len();
            trace!("reserved {}", new);
            unsafe { grow_zerofill(&mut self.buf, new) }
        }
    }
}

#[inline]
unsafe fn grow_zerofill(buf: &mut Vec<u8>, additional: usize) {
    use std::ptr;
    let len = buf.len();
    buf.set_len(len + additional);
    ptr::write_bytes(buf.as_mut_ptr().offset(len as isize), 0, buf.len());
}

impl<R: Read> Read for BufReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.cap == self.pos && buf.len() >= self.buf.len() {
            return self.inner.read(buf);
        }
        let nread = {
           let mut rem = try!(self.fill_buf());
           try!(rem.read(buf))
        };
        self.consume(nread);
        Ok(nread)
    }
}

impl<R: Read> BufRead for BufReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.pos == self.cap {
            self.cap = try!(self.inner.read(&mut self.buf));
            self.pos = 0;
        }
        Ok(&self.buf[self.pos..self.cap])
    }

    #[inline]
    fn consume(&mut self, amt: usize) {
        self.pos = cmp::min(self.pos + amt, self.cap);
        if self.pos == self.cap {
            self.pos = 0;
            self.cap = 0;
        }
    }
}

#[cfg(test)]
mod tests {

    use std::io::{self, Read, BufRead};
    use super::BufReader;

    struct SlowRead(u8);

    impl Read for SlowRead {
        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
            let state = self.0;
            self.0 += 1;
            (&match state % 3 {
                0 => b"foo",
                1 => b"bar",
                _ => b"baz",
            }[..]).read(buf)
        }
    }

    #[test]
    fn test_consume_and_get_buf() {
        let mut rdr = BufReader::new(SlowRead(0));
        rdr.read_into_buf().unwrap();
        rdr.consume(1);
        assert_eq!(rdr.get_buf(), b"oo");
        rdr.read_into_buf().unwrap();
        rdr.read_into_buf().unwrap();
        assert_eq!(rdr.get_buf(), b"oobarbaz");
        rdr.consume(5);
        assert_eq!(rdr.get_buf(), b"baz");
        rdr.consume(3);
        assert_eq!(rdr.get_buf(), b"");
        assert_eq!(rdr.pos, 0);
        assert_eq!(rdr.cap, 0);
    }

    #[test]
    fn test_resize() {
        let raw = b"hello world";
        let mut rdr = BufReader::with_capacity(&raw[..], 5);
        rdr.read_into_buf().unwrap();
        assert_eq!(rdr.get_buf(), b"hello");
        rdr.read_into_buf().unwrap();
        assert_eq!(rdr.get_buf(), b"hello world");
    }
}
<|endoftext|>


<commit_before>use context::{mod, GlVersion};
use gl;
use libc;
use std::c_vec::CVec;
use std::{fmt, mem, ptr};
use std::sync::Arc;
use GlObject;

/// A buffer in the graphics card's memory.
pub struct Buffer {
    display: Arc<super::DisplayImpl>,
    id: gl::types::GLuint,
    elements_size: uint,
    elements_count: uint,
}

/// Type of a buffer.
pub trait BufferType {
    /// Should return `&mut ctxt.state.something`.
    fn get_storage_point(Option<Self>, &mut context::GLState)
        -> &mut Option<gl::types::GLuint>;
    /// Should return `gl::SOMETHING_BUFFER`.
    fn get_bind_point(Option<Self>) -> gl::types::GLenum;
}

/// Used for vertex buffers.
pub struct ArrayBuffer;

impl BufferType for ArrayBuffer {
    fn get_storage_point(_: Option<ArrayBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.array_buffer_binding
    }

    fn get_bind_point(_: Option<ArrayBuffer>) -> gl::types::GLenum {
        gl::ARRAY_BUFFER
    }
}

/// Used for index buffers.
pub struct ElementArrayBuffer;

impl BufferType for ElementArrayBuffer {
    fn get_storage_point(_: Option<ElementArrayBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.element_array_buffer_binding
    }

    fn get_bind_point(_: Option<ElementArrayBuffer>) -> gl::types::GLenum {
        gl::ELEMENT_ARRAY_BUFFER
    }
}

/// Used for pixel buffers.
pub struct PixelPackBuffer;

impl BufferType for PixelPackBuffer {
    fn get_storage_point(_: Option<PixelPackBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.pixel_pack_buffer_binding
    }

    fn get_bind_point(_: Option<PixelPackBuffer>) -> gl::types::GLenum {
        gl::PIXEL_PACK_BUFFER
    }
}

/// Used for pixel buffers.
pub struct PixelUnpackBuffer;

impl BufferType for PixelUnpackBuffer {
    fn get_storage_point(_: Option<PixelUnpackBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.pixel_unpack_buffer_binding
    }

    fn get_bind_point(_: Option<PixelUnpackBuffer>) -> gl::types::GLenum {
        gl::PIXEL_UNPACK_BUFFER
    }
}

impl Buffer {
    pub fn new<T, D>(display: &super::Display, data: Vec<D>, usage: gl::types::GLenum)
        -> Buffer where T: BufferType, D: Send + Copy
    {
        use std::mem;

        let elements_size = {
            let d0: *const D = &data[0];
            let d1: *const D = &data[1];
            (d1 as uint) - (d0 as uint)
        };

        let elements_count = data.len();
        let buffer_size = elements_count * elements_size as uint;

        let (tx, rx) = channel();

        display.context.context.exec(proc(ctxt) {
            let data = data;

            unsafe {
                let mut id: gl::types::GLuint = mem::uninitialized();
                ctxt.gl.GenBuffers(1, &mut id);
                tx.send(id);

                if !ctxt.opengl_es && ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.NamedBufferData(id, buffer_size as gl::types::GLsizei,
                        data.as_ptr() as *const libc::c_void, usage);

                } else if ctxt.extensions.gl_ext_direct_state_access {
                    ctxt.gl.NamedBufferDataEXT(id, buffer_size as gl::types::GLsizeiptr,
                        data.as_ptr() as *const libc::c_void, usage);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.BufferData(bind, buffer_size as gl::types::GLsizeiptr,
                        data.as_ptr() as *const libc::c_void, usage);
                }
            }
        });

        Buffer {
            display: display.context.clone(),
            id: rx.recv(),
            elements_size: elements_size,
            elements_count: elements_count,
        }
    }

    pub fn new_empty<T>(display: &super::Display, elements_size: uint, elements_count: uint,
                        usage: gl::types::GLenum) -> Buffer where T: BufferType
    {
        let buffer_size = elements_count * elements_size as uint;

        let (tx, rx) = channel();
        display.context.context.exec(proc(ctxt) {
            unsafe {
                let mut id: gl::types::GLuint = mem::uninitialized();
                ctxt.gl.GenBuffers(1, &mut id);

                if !ctxt.opengl_es && ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.NamedBufferData(id, buffer_size as gl::types::GLsizei, ptr::null(), usage);

                } else if ctxt.extensions.gl_ext_direct_state_access {
                    ctxt.gl.NamedBufferDataEXT(id, buffer_size as gl::types::GLsizeiptr, ptr::null(),
                        usage);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.BufferData(bind, buffer_size as gl::types::GLsizeiptr, ptr::null(), usage);
                }

                tx.send(id);
            }
        });

        Buffer {
            display: display.context.clone(),
            id: rx.recv(),
            elements_size: elements_size,
            elements_count: elements_count,
        }
    }

    pub fn get_display(&self) -> &Arc<super::DisplayImpl> {
        &self.display
    }

    pub fn get_elements_size(&self) -> uint {
        self.elements_size
    }

    pub fn get_elements_count(&self) -> uint {
        self.elements_count
    }

    pub fn get_total_size(&self) -> uint {
        self.elements_count * self.elements_size
    }

    #[cfg(feature = "gl_extensions")]
    pub fn map<'a, T, D>(&'a mut self) -> Mapping<'a, T, D> where T: BufferType, D: Send {
        let (tx, rx) = channel();
        let id = self.id.clone();
        let elements_count = self.elements_count.clone();

        self.display.context.exec(proc(ctxt) {
            if ctxt.opengl_es {
                tx.send(Err("OpenGL ES doesn't support glMapBuffer"));
                return;
            }

            let ptr = unsafe {
                if ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.MapNamedBuffer(id, gl::READ_WRITE)

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.MapBuffer(bind, gl::READ_WRITE)
                }
            };

            if ptr.is_null() {
                tx.send(Err("glMapBuffer returned null"));
            } else {
                tx.send(Ok(ptr as *mut D));
            }
        });

        Mapping {
            buffer: self,
            data: unsafe { CVec::new(rx.recv().unwrap(), elements_count) },
        }
    }

    #[cfg(feature = "gl_extensions")]
    pub fn read<T, D>(&self) -> Vec<D> where T: BufferType, D: Send {
        self.read_slice::<T, D>(0, self.elements_count)
    }

    #[cfg(feature = "gl_extensions")]
    pub fn read_slice<T, D>(&self, offset: uint, size: uint)
                            -> Vec<D> where T: BufferType, D: Send
    {
        assert!(offset + size <= self.elements_count);

        let id = self.id.clone();
        let elements_size = self.elements_size.clone();
        let (tx, rx) = channel();

        self.display.context.exec(proc(ctxt) {
            if ctxt.opengl_es {
                panic!("OpenGL ES doesn't support glGetBufferSubData");
            }

            unsafe {
                let mut data = Vec::with_capacity(size);
                data.set_len(size);

                if !ctxt.opengl_es && ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.GetNamedBufferSubData(id, (offset * elements_size) as gl::types::GLintptr,
                        (size * elements_size) as gl::types::GLsizei,
                        data.as_mut_ptr() as *mut libc::c_void);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.GetBufferSubData(bind, (offset * elements_size) as gl::types::GLintptr,
                        (size * elements_size) as gl::types::GLsizeiptr,
                        data.as_mut_ptr() as *mut libc::c_void);
                }

                tx.send_opt(data).ok();
            }
        });

        rx.recv()
    }
}

impl fmt::Show for Buffer {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        (format!("Buffer #{}", self.id)).fmt(formatter)
    }
}

impl Drop for Buffer {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(ctxt) {
            if ctxt.state.array_buffer_binding == Some(id) {
                ctxt.state.array_buffer_binding = None;
            }

            if ctxt.state.element_array_buffer_binding == Some(id) {
                ctxt.state.element_array_buffer_binding = None;
            }

            if ctxt.state.pixel_pack_buffer_binding == Some(id) {
                ctxt.state.pixel_pack_buffer_binding = None;
            }

            if ctxt.state.pixel_unpack_buffer_binding == Some(id) {
                ctxt.state.pixel_unpack_buffer_binding = None;
            }

            unsafe { ctxt.gl.DeleteBuffers(1, [ id ].as_ptr()); }
        });
    }
}

impl GlObject for Buffer {
    fn get_id(&self) -> gl::types::GLuint {
        self.id
    }
}

/// Describes the attribute of a vertex.
///
/// When you create a vertex buffer, you need to pass some sort of array of data. In order for
/// OpenGL to use this data, we must tell it some informations about each field of each
/// element. This structure describes one such field.
#[deriving(Show, Clone)]
pub struct VertexAttrib {
    /// The offset, in bytes, between the start of each vertex and the attribute.
    pub offset: uint,

    /// Type of the field.
    pub data_type: gl::types::GLenum,

    /// Number of invidual elements in the attribute.
    ///
    /// For example if `data_type` is a f32 and `elements_count` is 2, then you have a `vec2`.
    pub elements_count: u32,
}

/// Describes the layout of each vertex in a vertex buffer.
pub type VertexBindings = Vec<(String, VertexAttrib)>;

/// Trait for structures that represent a vertex.
pub trait VertexFormat: Copy {
    /// Builds the `VertexBindings` representing the layout of this element.
    fn build_bindings(Option<Self>) -> VertexBindings;
}

/// A mapping of a buffer.
#[cfg(feature = "gl_extensions")]
pub struct Mapping<'b, T, D> {
    buffer: &'b mut Buffer,
    data: CVec<D>,
}

#[cfg(feature = "gl_extensions")]
#[unsafe_destructor]
impl<'a, T, D> Drop for Mapping<'a, T, D> where T: BufferType {
    fn drop(&mut self) {
        let id = self.buffer.id.clone();
        self.buffer.display.context.exec(proc(ctxt) {
            unsafe {
                if ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.UnmapNamedBuffer(id);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    if *storage != Some(id) {
                        ctxt.gl.BindBuffer(bind, id);
                        *storage = Some(id);
                    }

                    ctxt.gl.UnmapBuffer(bind);
                }
            }
        });
    }
}

#[cfg(feature = "gl_extensions")]
impl<'a, T, D> Deref<[D]> for Mapping<'a, T, D> {
    fn deref<'b>(&'b self) -> &'b [D] {
        self.data.as_slice()
    }
}

#[cfg(feature = "gl_extensions")]
impl<'a, T, D> DerefMut<[D]> for Mapping<'a, T, D> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut [D] {
        self.data.as_mut_slice()
    }
}
<commit_msg>panic! if there was a problem during buffer creation<commit_after>use context::{mod, GlVersion};
use gl;
use libc;
use std::c_vec::CVec;
use std::{fmt, mem, ptr};
use std::sync::Arc;
use GlObject;

/// A buffer in the graphics card's memory.
pub struct Buffer {
    display: Arc<super::DisplayImpl>,
    id: gl::types::GLuint,
    elements_size: uint,
    elements_count: uint,
}

/// Type of a buffer.
pub trait BufferType {
    /// Should return `&mut ctxt.state.something`.
    fn get_storage_point(Option<Self>, &mut context::GLState)
        -> &mut Option<gl::types::GLuint>;
    /// Should return `gl::SOMETHING_BUFFER`.
    fn get_bind_point(Option<Self>) -> gl::types::GLenum;
}

/// Used for vertex buffers.
pub struct ArrayBuffer;

impl BufferType for ArrayBuffer {
    fn get_storage_point(_: Option<ArrayBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.array_buffer_binding
    }

    fn get_bind_point(_: Option<ArrayBuffer>) -> gl::types::GLenum {
        gl::ARRAY_BUFFER
    }
}

/// Used for index buffers.
pub struct ElementArrayBuffer;

impl BufferType for ElementArrayBuffer {
    fn get_storage_point(_: Option<ElementArrayBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.element_array_buffer_binding
    }

    fn get_bind_point(_: Option<ElementArrayBuffer>) -> gl::types::GLenum {
        gl::ELEMENT_ARRAY_BUFFER
    }
}

/// Used for pixel buffers.
pub struct PixelPackBuffer;

impl BufferType for PixelPackBuffer {
    fn get_storage_point(_: Option<PixelPackBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.pixel_pack_buffer_binding
    }

    fn get_bind_point(_: Option<PixelPackBuffer>) -> gl::types::GLenum {
        gl::PIXEL_PACK_BUFFER
    }
}

/// Used for pixel buffers.
pub struct PixelUnpackBuffer;

impl BufferType for PixelUnpackBuffer {
    fn get_storage_point(_: Option<PixelUnpackBuffer>, state: &mut context::GLState)
        -> &mut Option<gl::types::GLuint>
    {
        &mut state.pixel_unpack_buffer_binding
    }

    fn get_bind_point(_: Option<PixelUnpackBuffer>) -> gl::types::GLenum {
        gl::PIXEL_UNPACK_BUFFER
    }
}

impl Buffer {
    pub fn new<T, D>(display: &super::Display, data: Vec<D>, usage: gl::types::GLenum)
        -> Buffer where T: BufferType, D: Send + Copy
    {
        use std::mem;

        let elements_size = {
            let d0: *const D = &data[0];
            let d1: *const D = &data[1];
            (d1 as uint) - (d0 as uint)
        };

        let elements_count = data.len();
        let buffer_size = elements_count * elements_size as uint;

        let (tx, rx) = channel();

        display.context.context.exec(proc(ctxt) {
            let data = data;

            unsafe {
                let mut id: gl::types::GLuint = mem::uninitialized();
                ctxt.gl.GenBuffers(1, &mut id);
                tx.send(id);

                let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                let bind = BufferType::get_bind_point(None::<T>);

                ctxt.gl.BindBuffer(bind, id);
                *storage = Some(id);
                ctxt.gl.BufferData(bind, buffer_size as gl::types::GLsizeiptr,
                                   data.as_ptr() as *const libc::c_void, usage);

                let mut obtained_size: gl::types::GLint = mem::uninitialized();
                ctxt.gl.GetBufferParameteriv(bind, gl::BUFFER_SIZE, &mut obtained_size);
                if buffer_size != obtained_size as uint {
                    ctxt.gl.DeleteBuffers(1, [id].as_ptr());
                    panic!("Not enough available memory for buffer");
                }
            }
        });

        Buffer {
            display: display.context.clone(),
            id: rx.recv(),
            elements_size: elements_size,
            elements_count: elements_count,
        }
    }

    pub fn new_empty<T>(display: &super::Display, elements_size: uint, elements_count: uint,
                        usage: gl::types::GLenum) -> Buffer where T: BufferType
    {
        let buffer_size = elements_count * elements_size as uint;

        let (tx, rx) = channel();
        display.context.context.exec(proc(ctxt) {
            unsafe {
                let mut id: gl::types::GLuint = mem::uninitialized();
                ctxt.gl.GenBuffers(1, &mut id);

                let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                let bind = BufferType::get_bind_point(None::<T>);

                ctxt.gl.BindBuffer(bind, id);
                *storage = Some(id);
                ctxt.gl.BufferData(bind, buffer_size as gl::types::GLsizeiptr, ptr::null(), usage);

                let mut obtained_size: gl::types::GLint = mem::uninitialized();
                ctxt.gl.GetBufferParameteriv(bind, gl::BUFFER_SIZE, &mut obtained_size);
                if buffer_size != obtained_size as uint {
                    ctxt.gl.DeleteBuffers(1, [id].as_ptr());
                    panic!("Not enough available memory for buffer");
                }

                tx.send(id);
            }
        });

        Buffer {
            display: display.context.clone(),
            id: rx.recv(),
            elements_size: elements_size,
            elements_count: elements_count,
        }
    }

    pub fn get_display(&self) -> &Arc<super::DisplayImpl> {
        &self.display
    }

    pub fn get_elements_size(&self) -> uint {
        self.elements_size
    }

    pub fn get_elements_count(&self) -> uint {
        self.elements_count
    }

    pub fn get_total_size(&self) -> uint {
        self.elements_count * self.elements_size
    }

    #[cfg(feature = "gl_extensions")]
    pub fn map<'a, T, D>(&'a mut self) -> Mapping<'a, T, D> where T: BufferType, D: Send {
        let (tx, rx) = channel();
        let id = self.id.clone();
        let elements_count = self.elements_count.clone();

        self.display.context.exec(proc(ctxt) {
            if ctxt.opengl_es {
                tx.send(Err("OpenGL ES doesn't support glMapBuffer"));
                return;
            }

            let ptr = unsafe {
                if ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.MapNamedBuffer(id, gl::READ_WRITE)

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.MapBuffer(bind, gl::READ_WRITE)
                }
            };

            if ptr.is_null() {
                tx.send(Err("glMapBuffer returned null"));
            } else {
                tx.send(Ok(ptr as *mut D));
            }
        });

        Mapping {
            buffer: self,
            data: unsafe { CVec::new(rx.recv().unwrap(), elements_count) },
        }
    }

    #[cfg(feature = "gl_extensions")]
    pub fn read<T, D>(&self) -> Vec<D> where T: BufferType, D: Send {
        self.read_slice::<T, D>(0, self.elements_count)
    }

    #[cfg(feature = "gl_extensions")]
    pub fn read_slice<T, D>(&self, offset: uint, size: uint)
                            -> Vec<D> where T: BufferType, D: Send
    {
        assert!(offset + size <= self.elements_count);

        let id = self.id.clone();
        let elements_size = self.elements_size.clone();
        let (tx, rx) = channel();

        self.display.context.exec(proc(ctxt) {
            if ctxt.opengl_es {
                panic!("OpenGL ES doesn't support glGetBufferSubData");
            }

            unsafe {
                let mut data = Vec::with_capacity(size);
                data.set_len(size);

                if !ctxt.opengl_es && ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.GetNamedBufferSubData(id, (offset * elements_size) as gl::types::GLintptr,
                        (size * elements_size) as gl::types::GLsizei,
                        data.as_mut_ptr() as *mut libc::c_void);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    ctxt.gl.BindBuffer(bind, id);
                    *storage = Some(id);
                    ctxt.gl.GetBufferSubData(bind, (offset * elements_size) as gl::types::GLintptr,
                        (size * elements_size) as gl::types::GLsizeiptr,
                        data.as_mut_ptr() as *mut libc::c_void);
                }

                tx.send_opt(data).ok();
            }
        });

        rx.recv()
    }
}

impl fmt::Show for Buffer {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        (format!("Buffer #{}", self.id)).fmt(formatter)
    }
}

impl Drop for Buffer {
    fn drop(&mut self) {
        let id = self.id.clone();
        self.display.context.exec(proc(ctxt) {
            if ctxt.state.array_buffer_binding == Some(id) {
                ctxt.state.array_buffer_binding = None;
            }

            if ctxt.state.element_array_buffer_binding == Some(id) {
                ctxt.state.element_array_buffer_binding = None;
            }

            if ctxt.state.pixel_pack_buffer_binding == Some(id) {
                ctxt.state.pixel_pack_buffer_binding = None;
            }

            if ctxt.state.pixel_unpack_buffer_binding == Some(id) {
                ctxt.state.pixel_unpack_buffer_binding = None;
            }

            unsafe { ctxt.gl.DeleteBuffers(1, [ id ].as_ptr()); }
        });
    }
}

impl GlObject for Buffer {
    fn get_id(&self) -> gl::types::GLuint {
        self.id
    }
}

/// Describes the attribute of a vertex.
///
/// When you create a vertex buffer, you need to pass some sort of array of data. In order for
/// OpenGL to use this data, we must tell it some informations about each field of each
/// element. This structure describes one such field.
#[deriving(Show, Clone)]
pub struct VertexAttrib {
    /// The offset, in bytes, between the start of each vertex and the attribute.
    pub offset: uint,

    /// Type of the field.
    pub data_type: gl::types::GLenum,

    /// Number of invidual elements in the attribute.
    ///
    /// For example if `data_type` is a f32 and `elements_count` is 2, then you have a `vec2`.
    pub elements_count: u32,
}

/// Describes the layout of each vertex in a vertex buffer.
pub type VertexBindings = Vec<(String, VertexAttrib)>;

/// Trait for structures that represent a vertex.
pub trait VertexFormat: Copy {
    /// Builds the `VertexBindings` representing the layout of this element.
    fn build_bindings(Option<Self>) -> VertexBindings;
}

/// A mapping of a buffer.
#[cfg(feature = "gl_extensions")]
pub struct Mapping<'b, T, D> {
    buffer: &'b mut Buffer,
    data: CVec<D>,
}

#[cfg(feature = "gl_extensions")]
#[unsafe_destructor]
impl<'a, T, D> Drop for Mapping<'a, T, D> where T: BufferType {
    fn drop(&mut self) {
        let id = self.buffer.id.clone();
        self.buffer.display.context.exec(proc(ctxt) {
            unsafe {
                if ctxt.version >= &GlVersion(4, 5) {
                    ctxt.gl.UnmapNamedBuffer(id);

                } else {
                    let storage = BufferType::get_storage_point(None::<T>, ctxt.state);
                    let bind = BufferType::get_bind_point(None::<T>);

                    if *storage != Some(id) {
                        ctxt.gl.BindBuffer(bind, id);
                        *storage = Some(id);
                    }

                    ctxt.gl.UnmapBuffer(bind);
                }
            }
        });
    }
}

#[cfg(feature = "gl_extensions")]
impl<'a, T, D> Deref<[D]> for Mapping<'a, T, D> {
    fn deref<'b>(&'b self) -> &'b [D] {
        self.data.as_slice()
    }
}

#[cfg(feature = "gl_extensions")]
impl<'a, T, D> DerefMut<[D]> for Mapping<'a, T, D> {
    fn deref_mut<'b>(&'b mut self) -> &'b mut [D] {
        self.data.as_mut_slice()
    }
}
<|endoftext|>


<commit_before><commit_msg>implementing multiple trait bounds using where clause<commit_after><|endoftext|>


<commit_before><commit_msg>trait HasArea added for struct Circle<commit_after><|endoftext|>


<commit_before><commit_msg>change return to continue<commit_after><|endoftext|>


<commit_before><commit_msg>Minor cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>add figure 3.5<commit_after>/// Figure 3.5: Copy standard input to standard output

extern crate libc;
#[macro_use(as_void)]
extern crate apue;
extern crate errno;

use libc::{STDIN_FILENO, STDOUT_FILENO, read, write};
use apue::LibcResult;
use errno::errno;

const BUFFSIZE:usize = 4096;

fn main() {
    unsafe {
        let buf:[u8;BUFFSIZE] = std::mem::uninitialized();
        println!("enter some words, to stop just hit return on empty line");
        while let Some(n) = read(STDIN_FILENO, as_void!(buf), BUFFSIZE).to_option() {
            if n == 1 && buf[0] == '\n' as _ {
                break
            }
            assert!(write(STDOUT_FILENO, as_void!(buf), n as _) == n, "write error");
        }
        if errno().0 > 0 {
            panic!("read error");
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Added the beginnings of some doc strings<commit_after><|endoftext|>


<commit_before><commit_msg>Add simple vertex buffer tests<commit_after>#![feature(phase)]

#[phase(plugin)]
extern crate glium_macros;

extern crate glutin;
extern crate glium;

use glium::DisplayBuild;

#[test]
fn vertex_buffer_creation() {
    #[vertex_format]
    #[allow(dead_code)]
    struct Vertex {
        field1: [f32, ..3],
        field2: [f32, ..3],
    }

    let display = glutin::HeadlessRendererBuilder::new(1024, 768)
        .build_glium().unwrap();

    glium::VertexBuffer::new(&display,
        vec![
            Vertex { field1: [-0.5, -0.5, 0.0], field2: [0.0, 1.0, 0.0] },
            Vertex { field1: [ 0.0,  0.5, 1.0], field2: [0.0, 0.0, 1.0] },
            Vertex { field1: [ 0.5, -0.5, 0.0], field2: [1.0, 0.0, 0.0] },
        ]
    );
}

#[test]
fn vertex_buffer_mapping_read() {
    #[vertex_format]
    struct Vertex {
        field1: [u8, ..2],
        field2: [u8, ..2],
    }

    let display = glutin::HeadlessRendererBuilder::new(1024, 768)
        .build_glium().unwrap();

    let mut vb = glium::VertexBuffer::new(&display,
        vec![
            Vertex { field1: [ 2,  3], field2: [ 5,  7] },
            Vertex { field1: [12, 13], field2: [15, 17] },
        ]
    );

    let mapping = vb.map();
    assert_eq!(mapping[0].field1.as_slice(), [2, 3].as_slice());
    assert_eq!(mapping[1].field2.as_slice(), [15, 17].as_slice());
}

#[test]
fn vertex_buffer_mapping_write() {
    #[vertex_format]
    struct Vertex {
        field1: [u8, ..2],
        field2: [u8, ..2],
    }

    let display = glutin::HeadlessRendererBuilder::new(1024, 768)
        .build_glium().unwrap();

    let mut vb = glium::VertexBuffer::new(&display,
        vec![
            Vertex { field1: [ 2,  3], field2: [ 5,  7] },
            Vertex { field1: [12, 13], field2: [15, 17] },
        ]
    );

    {
        let mut mapping = vb.map();
        mapping[0].field1 = [0, 1];
    }

    let mapping = vb.map();
    assert_eq!(mapping[0].field1.as_slice(), [0, 1].as_slice());
    assert_eq!(mapping[1].field2.as_slice(), [15, 17].as_slice());
}
<|endoftext|>


<commit_before><commit_msg>add benchmark<commit_after>#![no_std]
#![feature(test)]
#[macro_use]
extern crate digest;
extern crate jh_x86_64;

bench!(jh_x86_64::Jh256);
<|endoftext|>


<commit_before><commit_msg>Add archive exploder tool.<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #28863 - nagisa:test-16403, r=alexcrichton<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.
//
// error-pattern:already defined

#![allow(warnings)]

fn main() {
    {
        extern fn fail() {}
    }
    {
        extern fn fail() {}
    }
}
<|endoftext|>


<commit_before><commit_msg>Test for issue #6338.<commit_after>// Copyright 2013 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.

// xfail-test

fn test1() {
    // from issue 6338
    match ((1, ~"a"), (2, ~"b")) {
        ((1, a), (2, b)) | ((2, b), (1, a)) => {
                assert_eq!(a, ~"a");
                assert_eq!(b, ~"b");
            },
            _ => fail!(),
    }
}

fn test2() {
    match (1, 2, 3) {
        (1, a, b) | (2, b, a) => {
            assert_eq!(a, 2);
            assert_eq!(b, 3);
        },
        _ => fail!(),
    }
}

fn test3() {
    match (1, 2, 3) {
        (1, ref a, ref b) | (2, ref b, ref a) => {
            assert_eq!(*a, 2);
            assert_eq!(*b, 3);
        },
        _ => fail!(),
    }
}

fn test4() {
    match (1, 2, 3) {
        (1, a, b) | (2, b, a) if a == 2 => {
            assert_eq!(a, 2);
            assert_eq!(b, 3);
        },
        _ => fail!(),
    }
}

fn test5() {
    match (1, 2, 3) {
        (1, ref a, ref b) | (2, ref b, ref a) if *a == 2 => {
            assert_eq!(*a, 2);
            assert_eq!(*b, 3);
        },
        _ => fail!(),
    }
}

fn main() {
    test1();
    test2();
    test3();
    test4();
    test5();
}
<|endoftext|>


<commit_before><commit_msg>Example file<commit_after>extern crate core;
use core::num::ToPrimitive;

fn isPrime(x: i32, y: f64) -> bool {
    match x.to_f64() {
        Some(num) => num > y,
        None => false
    }
}

fn main() {
    let x = 5;
    let y = 7.0;
    isPrime(x,y);
}
<|endoftext|>


<commit_before><commit_msg>Add syntactic test for rest patterns.<commit_after>// Here we test that `..` is allowed in all pattern locations *syntactically*.
// The semantic test is in `rest-pat-semantic-disallowed.rs`.

// check-pass

fn main() {}

macro_rules! accept_pat {
    ($p:pat) => {}
}

accept_pat!(..);

#[cfg(FALSE)]
fn rest_patterns() {
    // Top level:
    fn foo(..: u8) {}
    let ..;

    // Box patterns:
    let box ..;

    // In or-patterns:
    match x {
        .. | .. => {}
    }

    // Ref patterns:
    let &..;
    let &mut ..;

    // Ident patterns:
    let x @ ..;
    let ref x @ ..;
    let ref mut x @ ..;

    // Tuple:
    let (..); // This is interpreted as a tuple pattern, not a parenthesis one.
    let (..,); // Allowing trailing comma.
    let (.., .., ..); // Duplicates also.
    let (.., P, ..); // Including with things in between.

    // Tuple struct (same idea as for tuple patterns):
    let A(..);
    let A(..,);
    let A(.., .., ..);
    let A(.., P, ..);

    // Array/Slice (like with tuple patterns):
    let [..];
    let [..,];
    let [.., .., ..];
    let [.., P, ..];

    // Random walk to guard against special casing:
    match x {
        .. |
        [
            (
                box ..,
                &(..),
                &mut ..,
                x @ ..
            ),
            ref x @ ..,
        ] |
        ref mut x @ ..
        => {}
    }
}
<|endoftext|>


<commit_before><commit_msg>Add codegen test to make sure that closures are 'internalized' properly.<commit_after>// Copyright 2016 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.

// compile-flags: -C no-prepopulate-passes

pub fn main() {

    // We want to make sure that closures get 'internal' linkage instead of
    // 'weak_odr' when they are not shared between codegen units
    // CHECK: define internal {{.*}}_ZN20internalize_closures4main{{.*}}$u7b$$u7b$closure$u7d$$u7d$
    let c = |x:i32| { x + 1 };
    let _ = c(1);
}
<|endoftext|>


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

// aux-build:two_macros.rs

#![feature(rustc_attrs)]
#![allow(unused)]

fn f() {
    let _ = macro_one!();
}
#[macro_use(macro_one)] // Check that this macro is usable in the above function
extern crate two_macros;

macro_rules! m { () => {
    fn g() {
        macro_two!();
    }
    #[macro_use(macro_two)] // Check that this macro is usable in the above function
    extern crate two_macros as _two_macros;
} }
m!();

#[rustc_error]
fn main() {} //~ ERROR compilation successful
<commit_msg>Add test.<commit_after>// Copyright 2016 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.

// aux-build:two_macros.rs

#![feature(rustc_attrs)]
#![allow(unused)]

fn f() {
    let _ = macro_one!();
}
#[macro_use(macro_one)] // Check that this macro is usable in the above function
extern crate two_macros;

fn g() {
    macro_two!();
}
macro_rules! m { () => {
    #[macro_use(macro_two)] // Check that this macro is usable in the above function
    extern crate two_macros as _two_macros;
} }
m!();

#[rustc_error]
fn main() {} //~ ERROR compilation successful
<|endoftext|>


<commit_before><commit_msg>continued demacrofication<commit_after><|endoftext|>


<commit_before><commit_msg>Add initial Scheme compiler integration targets<commit_after>#![feature(box_syntax,box_patterns)]
#![feature(compile)]
#![feature(scheme)]

/// Scheme compiler integration tests
///
/// These are based on the sample programs in Zach Allaun's Clojure SECD
/// [implementation](https://github.com/zachallaun/secd).

#[macro_use]
extern crate seax_svm as svm;
extern crate seax_scheme as scheme;

use svm::slist::List::{Cons,Nil};
use svm::cell::Atom::*;
use svm::cell::SVMCell::*;
use svm::Inst::*;

/// Test for simple list construction through CONS.
///
/// ```lisp
/// (cons 10 (cons 20 nil))
/// ```
#[test]
fn compile_list_creation() {
    assert_eq!(
        scheme::compile("(cons 10 (cons 20 nil))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (car (cons 10 (cons 20 nil)))
/// ```
#[test]
fn  compile_list_car() {
    assert_eq!(
        scheme::compile("(car (cons 10 (cons 20 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CAR)
        ))
    );
}

/// Test for simple list construction and destructuring
///
/// ```lisp
/// (cdr (cons 10 (cons 20 nil)))
/// ```
#[test]
fn compile_list_cdr() {
    assert_eq!(
        scheme::compile("(cdr (cons 10 (cons 20 nil)))"),
        Ok(list!(
            InstCell(NIL),
            InstCell(LDC), AtomCell(SInt(10)), InstCell(CONS),
            InstCell(LDC), AtomCell(SInt(20)), InstCell(CONS),
            InstCell(CDR)
        ))
    );
}

/// Test for simple mathematics application
///
/// ```lisp
/// (+ 10 10)
/// ```
#[test]
fn compile_simple_add(){
    assert_eq!(
        scheme::compile("(+ 10 10)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

/// Test for nested arithmetic
///
/// ```lisp
/// (- 20 (+ 5 5))
/// ```
#[test]
fn compile_nested_arith() {
     assert_eq!(
        scheme::compile("(- 20 (+ 5 5))"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(LDC), AtomCell(SInt(5)),
            InstCell(ADD),
            InstCell(LDC), AtomCell(SInt(20)),
            InstCell(SUB)
        ))
    );
}

/// Tests for basic branching
///
/// ```lisp
/// ((if (= 0 (- 1 1)) #t #f)
/// ```
///
/// ```lisp
/// (+ 10 (if (nil? nil) 10 20))
/// ```
#[test]
fn test_basic_branching() {
    assert_eq!(
        scheme::compile("((if (= 0 (- 1 1)) #t #f)"),
        Ok(list!(
            InstCell(LDC), AtomCell(SInt(1)), InstCell(LDC), AtomCell(SInt(1)),
            InstCell(SUB),
            InstCell(LDC), AtomCell(SInt(0)),
            InstCell(EQ),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(1)), InstCell(JOIN))),
                ListCell(box list!(InstCell(NIL), InstCell(JOIN))
            )
        ))
    );
    assert_eq!(
        scheme::compile("(+ 10 (if (nil? nil) 10 20))"),
        Ok(list!(
            InstCell(NIL), InstCell(NULL),
            InstCell(SEL),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(10)), InstCell(JOIN))),
                ListCell(box list!(InstCell(LDC), AtomCell(SInt(20)), InstCell(JOIN))),
            InstCell(LDC), AtomCell(SInt(10)),
            InstCell(ADD)
        ))
    );
}

<|endoftext|>