<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.

// These `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
// microcontrollers. Namely, all these processors:
//
// - Cortex-M0
// - Cortex-M0+
// - Cortex-M1
// - Cortex-M3
// - Cortex-M4(F)
// - Cortex-M7(F)
// - Cortex-M23
//
// We have opted for these targets instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
// And if differences exist between two processors under the same target, rustc flags can be used to
// optimize for one processor or the other.
//
// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
// differentiate one processor from the other.
//
// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
// triples use thumb instead of arm. We follow suit because having thumb in the name let us
// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags.

use std::default::Default;
use spec::{PanicStrategy, TargetOptions};

pub fn opts() -> TargetOptions {
    // See rust-lang/rfcs#1645 for a discussion about these defaults
    TargetOptions {
        executables: true,
        // In most cases, LLD is good enough
        linker: Some("rust-lld".to_string()),
        // Because these devices have very little resources having an unwinder is too onerous so we
        // default to "abort" because the "unwind" strategy is very rare.
        panic_strategy: PanicStrategy::Abort,
        // Similarly, one almost always never wants to use relocatable code because of the extra
        // costs it involves.
        relocation_model: "static".to_string(),
        abi_blacklist: super::arm_base::abi_blacklist(),
        // When this section is added a volatile load to its start address is also generated. This
        // volatile load is a footgun as it can end up loading an invalid memory address, depending
        // on how the user set up their linker scripts. This section adds pretty printer for stuff
        // like std::Vec, which is not that used in no-std context, so it's best to left it out
        // until we figure a way to add the pretty printers without requiring a volatile load cf.
        // rust-lang/rust#44993.
        emit_debug_gdb_scripts: false,
        .. Default::default()
    }
}
<commit_msg>fix tidy<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.

// These `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
// microcontrollers. Namely, all these processors:
//
// - Cortex-M0
// - Cortex-M0+
// - Cortex-M1
// - Cortex-M3
// - Cortex-M4(F)
// - Cortex-M7(F)
// - Cortex-M23
//
// We have opted for these instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
// And if differences exist between two processors under the same target, rustc flags can be used to
// optimize for one processor or the other.
//
// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
// differentiate one processor from the other.
//
// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
// triples use thumb instead of arm. We follow suit because having thumb in the name let us
// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags.

use std::default::Default;
use spec::{PanicStrategy, TargetOptions};

pub fn opts() -> TargetOptions {
    // See rust-lang/rfcs#1645 for a discussion about these defaults
    TargetOptions {
        executables: true,
        // In most cases, LLD is good enough
        linker: Some("rust-lld".to_string()),
        // Because these devices have very little resources having an unwinder is too onerous so we
        // default to "abort" because the "unwind" strategy is very rare.
        panic_strategy: PanicStrategy::Abort,
        // Similarly, one almost always never wants to use relocatable code because of the extra
        // costs it involves.
        relocation_model: "static".to_string(),
        abi_blacklist: super::arm_base::abi_blacklist(),
        // When this section is added a volatile load to its start address is also generated. This
        // volatile load is a footgun as it can end up loading an invalid memory address, depending
        // on how the user set up their linker scripts. This section adds pretty printer for stuff
        // like std::Vec, which is not that used in no-std context, so it's best to left it out
        // until we figure a way to add the pretty printers without requiring a volatile load cf.
        // rust-lang/rust#44993.
        emit_debug_gdb_scripts: false,
        .. Default::default()
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix for macro changes<commit_after><|endoftext|>


<commit_before><commit_msg>feat: add `xml_stack_loader` function<commit_after><|endoftext|>


<commit_before><commit_msg>remove unnecesary parens<commit_after><|endoftext|>


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

#[link(name = "rustdoc",
       vers = "0.8",
       uuid = "8c6e4598-1596-4aa5-a24c-b811914bbbc6",
       url = "https://github.com/mozilla/rust/tree/master/src/librustdoc")];

#[desc = "rustdoc, the Rust documentation extractor"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];

extern mod syntax;
extern mod rustc;
extern mod extra;

use extra::serialize::Encodable;
use extra::time;
use extra::getopts::groups;
use std::cell::Cell;
use std::rt::io;
use std::rt::io::Writer;
use std::rt::io::file::FileInfo;

pub mod clean;
pub mod core;
pub mod doctree;
pub mod fold;
pub mod html {
    pub mod render;
    pub mod layout;
    pub mod markdown;
    pub mod format;
}
pub mod passes;
pub mod plugins;
pub mod visit_ast;

pub static SCHEMA_VERSION: &'static str = "0.8.0";

type Pass = (&'static str,                                      // name
             extern fn(clean::Crate) -> plugins::PluginResult,  // fn
             &'static str);                                     // description

static PASSES: &'static [Pass] = &[
    ("strip-hidden", passes::strip_hidden,
     "strips all doc(hidden) items from the output"),
    ("unindent-comments", passes::unindent_comments,
     "removes excess indentation on comments in order for markdown to like it"),
    ("collapse-docs", passes::collapse_docs,
     "concatenates all document attributes into one document attribute"),
    ("strip-private", passes::strip_private,
     "strips all private items from a crate which cannot be seen externally"),
];

static DEFAULT_PASSES: &'static [&'static str] = &[
    "strip-hidden",
    "strip-private",
    "collapse-docs",
    "unindent-comments",
];

local_data_key!(pub ctxtkey: @core::DocContext)

enum OutputFormat {
    HTML, JSON
}

pub fn main() {
    std::os::set_exit_status(main_args(std::os::args()));
}

pub fn opts() -> ~[groups::OptGroup] {
    use extra::getopts::groups::*;
    ~[
        optmulti("L", "library-path", "directory to add to crate search path",
                 "DIR"),
        optmulti("", "plugin-path", "directory to load plugins from", "DIR"),
        optmulti("", "passes", "space separated list of passes to also run, a \
                                value of `list` will print available passes",
                 "PASSES"),
        optmulti("", "plugins", "space separated list of plugins to also load",
                 "PLUGINS"),
        optflag("h", "help", "show this help message"),
        optflag("", "nodefaults", "don't run the default passes"),
        optopt("o", "output", "where to place the output", "PATH"),
    ]
}

pub fn usage(argv0: &str) {
    println(groups::usage(format!("{} [options] [html|json] <crate>",
                                  argv0), opts()));
}

pub fn main_args(args: &[~str]) -> int {
    //use extra::getopts::groups::*;

    let matches = groups::getopts(args.tail(), opts()).unwrap();

    if matches.opt_present("h") || matches.opt_present("help") {
        usage(args[0]);
        return 0;
    }

    let mut default_passes = !matches.opt_present("nodefaults");
    let mut passes = matches.opt_strs("passes");
    let mut plugins = matches.opt_strs("plugins");

    if passes == ~[~"list"] {
        println("Available passes for running rustdoc:");
        for &(name, _, description) in PASSES.iter() {
            println!("{:>20s} - {}", name, description);
        }
        println("\nDefault passes for rustdoc:");
        for &name in DEFAULT_PASSES.iter() {
            println!("{:>20s}", name);
        }
        return;
    }

    let (format, cratefile) = match matches.free.clone() {
        [~"json", crate] => (JSON, crate),
        [~"html", crate] => (HTML, crate),
        [s, _] => {
            println!("Unknown output format: `{}`", s);
            usage(args[0]);
            return 1;
        }
        [_, .._] => {
            println!("Expected exactly one crate to process");
            usage(args[0]);
            return 1;
        }
        _ => {
            println!("Expected an output format and then one crate");
            usage(args[0]);
            return 1;
        }
    };

    // First, parse the crate and extract all relevant information.
    let libs = Cell::new(matches.opt_strs("L").map(|s| Path(*s)));
    let cr = Cell::new(Path(cratefile));
    info2!("starting to run rustc");
    let crate = do std::task::try {
        let cr = cr.take();
        core::run_core(libs.take(), &cr)
    }.unwrap();
    info2!("finished with rustc");

    // Process all of the crate attributes, extracting plugin metadata along
    // with the passes which we are supposed to run.
    match crate.module.get_ref().doc_list() {
        Some(nested) => {
            for inner in nested.iter() {
                match *inner {
                    clean::Word(~"no_default_passes") => {
                        default_passes = false;
                    }
                    clean::NameValue(~"passes", ref value) => {
                        for pass in value.word_iter() {
                            passes.push(pass.to_owned());
                        }
                    }
                    clean::NameValue(~"plugins", ref value) => {
                        for p in value.word_iter() {
                            plugins.push(p.to_owned());
                        }
                    }
                    _ => {}
                }
            }
        }
        None => {}
    }
    if default_passes {
        for name in DEFAULT_PASSES.rev_iter() {
            passes.unshift(name.to_owned());
        }
    }

    // Load all plugins/passes into a PluginManager
    let mut pm = plugins::PluginManager::new(Path("/tmp/rustdoc_ng/plugins"));
    for pass in passes.iter() {
        let plugin = match PASSES.iter().position(|&(p, _, _)| p == *pass) {
            Some(i) => PASSES[i].n1(),
            None => {
                error2!("unknown pass {}, skipping", *pass);
                loop
            },
        };
        pm.add_plugin(plugin);
    }
    info2!("loading plugins...");
    for pname in plugins.move_iter() {
        pm.load_plugin(pname);
    }

    // Run everything!
    info2!("Executing passes/plugins");
    let (crate, res) = pm.run_plugins(crate);

    info2!("going to format");
    let started = time::precise_time_ns();
    let output = matches.opt_str("o").map(|s| Path(*s));
    match format {
        HTML => { html::render::run(crate, output.unwrap_or(Path("doc"))) }
        JSON => { jsonify(crate, res, output.unwrap_or(Path("doc.json"))) }
    }
    let ended = time::precise_time_ns();
    info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);

    return 0;
}

fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
    // {
    //   "schema": version,
    //   "crate": { parsed crate ... },
    //   "plugins": { output of plugins ... }
    // }
    let mut json = ~extra::treemap::TreeMap::new();
    json.insert(~"schema", extra::json::String(SCHEMA_VERSION.to_owned()));
    let plugins_json = ~res.move_iter().filter_map(|opt| opt).collect();

    // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
    // straight to the Rust JSON representation.
    let crate_json_str = do std::io::with_str_writer |w| {
        crate.encode(&mut extra::json::Encoder(w));
    };
    let crate_json = match extra::json::from_str(crate_json_str) {
        Ok(j) => j,
        Err(_) => fail!("Rust generated JSON is invalid??")
    };

    json.insert(~"crate", crate_json);
    json.insert(~"plugins", extra::json::Object(plugins_json));

    let mut file = dst.open_writer(io::Create).unwrap();
    let output = extra::json::Object(json).to_str();
    file.write(output.as_bytes());
}
<commit_msg>rustdoc: Fix merge fallout<commit_after>// Copyright 2012-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.

#[link(name = "rustdoc",
       vers = "0.8",
       uuid = "8c6e4598-1596-4aa5-a24c-b811914bbbc6",
       url = "https://github.com/mozilla/rust/tree/master/src/librustdoc")];

#[desc = "rustdoc, the Rust documentation extractor"];
#[license = "MIT/ASL2"];
#[crate_type = "lib"];

extern mod syntax;
extern mod rustc;
extern mod extra;

use extra::serialize::Encodable;
use extra::time;
use extra::getopts::groups;
use std::cell::Cell;
use std::rt::io;
use std::rt::io::Writer;
use std::rt::io::file::FileInfo;

pub mod clean;
pub mod core;
pub mod doctree;
pub mod fold;
pub mod html {
    pub mod render;
    pub mod layout;
    pub mod markdown;
    pub mod format;
}
pub mod passes;
pub mod plugins;
pub mod visit_ast;

pub static SCHEMA_VERSION: &'static str = "0.8.0";

type Pass = (&'static str,                                      // name
             extern fn(clean::Crate) -> plugins::PluginResult,  // fn
             &'static str);                                     // description

static PASSES: &'static [Pass] = &[
    ("strip-hidden", passes::strip_hidden,
     "strips all doc(hidden) items from the output"),
    ("unindent-comments", passes::unindent_comments,
     "removes excess indentation on comments in order for markdown to like it"),
    ("collapse-docs", passes::collapse_docs,
     "concatenates all document attributes into one document attribute"),
    ("strip-private", passes::strip_private,
     "strips all private items from a crate which cannot be seen externally"),
];

static DEFAULT_PASSES: &'static [&'static str] = &[
    "strip-hidden",
    "strip-private",
    "collapse-docs",
    "unindent-comments",
];

local_data_key!(pub ctxtkey: @core::DocContext)

enum OutputFormat {
    HTML, JSON
}

pub fn main() {
    std::os::set_exit_status(main_args(std::os::args()));
}

pub fn opts() -> ~[groups::OptGroup] {
    use extra::getopts::groups::*;
    ~[
        optmulti("L", "library-path", "directory to add to crate search path",
                 "DIR"),
        optmulti("", "plugin-path", "directory to load plugins from", "DIR"),
        optmulti("", "passes", "space separated list of passes to also run, a \
                                value of `list` will print available passes",
                 "PASSES"),
        optmulti("", "plugins", "space separated list of plugins to also load",
                 "PLUGINS"),
        optflag("h", "help", "show this help message"),
        optflag("", "nodefaults", "don't run the default passes"),
        optopt("o", "output", "where to place the output", "PATH"),
    ]
}

pub fn usage(argv0: &str) {
    println(groups::usage(format!("{} [options] [html|json] <crate>",
                                  argv0), opts()));
}

pub fn main_args(args: &[~str]) -> int {
    //use extra::getopts::groups::*;

    let matches = groups::getopts(args.tail(), opts()).unwrap();

    if matches.opt_present("h") || matches.opt_present("help") {
        usage(args[0]);
        return 0;
    }

    let mut default_passes = !matches.opt_present("nodefaults");
    let mut passes = matches.opt_strs("passes");
    let mut plugins = matches.opt_strs("plugins");

    if passes == ~[~"list"] {
        println("Available passes for running rustdoc:");
        for &(name, _, description) in PASSES.iter() {
            println!("{:>20s} - {}", name, description);
        }
        println("\nDefault passes for rustdoc:");
        for &name in DEFAULT_PASSES.iter() {
            println!("{:>20s}", name);
        }
        return 0;
    }

    let (format, cratefile) = match matches.free.clone() {
        [~"json", crate] => (JSON, crate),
        [~"html", crate] => (HTML, crate),
        [s, _] => {
            println!("Unknown output format: `{}`", s);
            usage(args[0]);
            return 1;
        }
        [_, .._] => {
            println!("Expected exactly one crate to process");
            usage(args[0]);
            return 1;
        }
        _ => {
            println!("Expected an output format and then one crate");
            usage(args[0]);
            return 1;
        }
    };

    // First, parse the crate and extract all relevant information.
    let libs = Cell::new(matches.opt_strs("L").map(|s| Path(*s)));
    let cr = Cell::new(Path(cratefile));
    info2!("starting to run rustc");
    let crate = do std::task::try {
        let cr = cr.take();
        core::run_core(libs.take(), &cr)
    }.unwrap();
    info2!("finished with rustc");

    // Process all of the crate attributes, extracting plugin metadata along
    // with the passes which we are supposed to run.
    match crate.module.get_ref().doc_list() {
        Some(nested) => {
            for inner in nested.iter() {
                match *inner {
                    clean::Word(~"no_default_passes") => {
                        default_passes = false;
                    }
                    clean::NameValue(~"passes", ref value) => {
                        for pass in value.word_iter() {
                            passes.push(pass.to_owned());
                        }
                    }
                    clean::NameValue(~"plugins", ref value) => {
                        for p in value.word_iter() {
                            plugins.push(p.to_owned());
                        }
                    }
                    _ => {}
                }
            }
        }
        None => {}
    }
    if default_passes {
        for name in DEFAULT_PASSES.rev_iter() {
            passes.unshift(name.to_owned());
        }
    }

    // Load all plugins/passes into a PluginManager
    let mut pm = plugins::PluginManager::new(Path("/tmp/rustdoc_ng/plugins"));
    for pass in passes.iter() {
        let plugin = match PASSES.iter().position(|&(p, _, _)| p == *pass) {
            Some(i) => PASSES[i].n1(),
            None => {
                error2!("unknown pass {}, skipping", *pass);
                loop
            },
        };
        pm.add_plugin(plugin);
    }
    info2!("loading plugins...");
    for pname in plugins.move_iter() {
        pm.load_plugin(pname);
    }

    // Run everything!
    info2!("Executing passes/plugins");
    let (crate, res) = pm.run_plugins(crate);

    info2!("going to format");
    let started = time::precise_time_ns();
    let output = matches.opt_str("o").map(|s| Path(*s));
    match format {
        HTML => { html::render::run(crate, output.unwrap_or(Path("doc"))) }
        JSON => { jsonify(crate, res, output.unwrap_or(Path("doc.json"))) }
    }
    let ended = time::precise_time_ns();
    info2!("Took {:.03f}s", (ended as f64 - started as f64) / 1000000000f64);

    return 0;
}

fn jsonify(crate: clean::Crate, res: ~[plugins::PluginJson], dst: Path) {
    // {
    //   "schema": version,
    //   "crate": { parsed crate ... },
    //   "plugins": { output of plugins ... }
    // }
    let mut json = ~extra::treemap::TreeMap::new();
    json.insert(~"schema", extra::json::String(SCHEMA_VERSION.to_owned()));
    let plugins_json = ~res.move_iter().filter_map(|opt| opt).collect();

    // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
    // straight to the Rust JSON representation.
    let crate_json_str = do std::io::with_str_writer |w| {
        crate.encode(&mut extra::json::Encoder(w));
    };
    let crate_json = match extra::json::from_str(crate_json_str) {
        Ok(j) => j,
        Err(_) => fail!("Rust generated JSON is invalid??")
    };

    json.insert(~"crate", crate_json);
    json.insert(~"plugins", extra::json::Object(plugins_json));

    let mut file = dst.open_writer(io::Create).unwrap();
    let output = extra::json::Object(json).to_str();
    file.write(output.as_bytes());
}
<|endoftext|>


<commit_before><commit_msg>integration_tests: Add virtio-blk test<commit_after>// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

//! Testing virtio-block.

pub mod fixture;

use std::process::Command;

use fixture::Config;
use fixture::TestVm;
use tempfile::NamedTempFile;

fn prepare_disk_img() -> NamedTempFile {
    let mut disk = NamedTempFile::new().unwrap();
    disk.as_file_mut().set_len(1024 * 1024).unwrap();

    // TODO(b/243127910): Use `mkfs.ext4 -d` to include test data.
    Command::new("mkfs.ext4")
        .arg(disk.path().to_str().unwrap())
        .output()
        .expect("failed to execute process");
    disk
}

// TODO(b/243127498): Add tests for write and sync operations.
#[test]
fn mount_block() {
    let disk = prepare_disk_img();
    let disk_path = disk.path().to_str().unwrap().to_string();
    println!("disk={disk_path}");

    let config = Config::new().extra_args(vec!["--rwdisk".to_string(), disk_path]);
    let mut vm = TestVm::new(config).unwrap();
    assert_eq!(
        vm.exec_in_guest("mount -t ext4 /dev/vdb /mnt && echo 42")
            .unwrap()
            .trim(),
        "42"
    );
}
<|endoftext|>


<commit_before><commit_msg>(refactor) simplified content_type retrieval<commit_after><|endoftext|>


<commit_before><commit_msg>Update the description of TreeRouter to match the new variable terminology<commit_after><|endoftext|>


<commit_before><commit_msg>chore: panick<commit_after><|endoftext|>


<commit_before><commit_msg>Adapt for new interface of gen_vars() function<commit_after><|endoftext|>


<commit_before><commit_msg>Added different resolutions<commit_after><|endoftext|>


<commit_before>use std::path::PathBuf;
use std::path::Path;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;

use libimagerror::trace::trace_error;
use libimagstore::hook::Hook;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::result::HookResult;
use libimagstore::storeid::StoreId;
use libimagutil::debug_result::*;

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::runtime::Runtime as GRuntime;

/// The `UpdateHook` type
///
/// Represents a hook which is executed whenever a entry in the store is updated (written to disk).
///
/// # Time of execution
///
/// This hook is executed _after_ the store operation succeeded, so _after_ the file is written to
/// disk.
pub struct UpdateHook {
    storepath: PathBuf,

    runtime: GRuntime,

    position: HookPosition,
}

impl UpdateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> UpdateHook {
        UpdateHook {
            runtime: GRuntime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for UpdateHook {
    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "UpdateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?})",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for UpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_update"
    }

    /// Set the configuration of the hook. See
    /// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`.
    ///
    /// This function traces the error (using `trace_error()`) that
    /// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`
    /// returns, if any.
    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for UpdateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for UpdateHook {

    /// The implementation of the UpdateHook
    ///
    /// # Scope
    ///
    /// This hook takes the git index and commits it either interactively or with a default message,
    /// if there is no configuration for an interactive commit.
    ///
    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;
        use vcs::git::error::MapIntoHookError;
        use vcs::git::util::fetch_index;
        use git2::{ADD_DEFAULT, STATUS_WT_NEW, STATUS_WT_MODIFIED, IndexMatchedPath};

        debug!("[GIT UPDATE HOOK]: {:?}", id);

        let action    = StoreAction::Update;
        let cfg       = try!(self.runtime.config_value_or_err(&action));
        let repo      = try!(self.runtime.repository(&action));
        let mut index = try!(fetch_index(repo, &action));

        let signature = try!(
            repo.signature()
                .map_err_into(GHEK::MkSignature)
                .map_dbg_err_str("Failed to fetch signature")
                .map_into_hook_error()
        );

        let head = try!(
            repo.head()
                .map_err_into(GHEK::HeadFetchError)
                .map_dbg_err_str("Failed to fetch HEAD")
                .map_into_hook_error()
        );

        let file_status = try!(
            repo
                .status_file(id.local())
                .map_dbg_err_str("Failed to fetch file status")
                .map_dbg_err(|e| format!("\t->  {:?}", e))
                .map_err_into(GHEK::RepositoryFileStatusError)
                .map_into_hook_error()
        );

        let cb = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
            if file_status.contains(STATUS_WT_NEW) || file_status.contains(STATUS_WT_MODIFIED) {
                debug!("[GIT CREATE HOOK]: File is modified/new: {}", path.display());
                0
            } else {
                debug!("[GIT CREATE HOOK]: Ignoring file: {}", path.display());
                1
            }
        };

        try!(
            index.add_all(&[id.local()], ADD_DEFAULT, Some(cb as &mut IndexMatchedPath))
                .map_err_into(GHEK::RepositoryPathAddingError)
                .map_dbg_err_str("Failed to add to index")
                .map_into_hook_error()
        );

        let tree_id = try!(
            index.write_tree()
                .map_err_into(GHEK::RepositoryIndexWritingError)
                .map_dbg_err_str("Failed to write tree")
                .map_into_hook_error()
        );

        let mut parents = Vec::new();
        {
            let commit = try!(
                repo.find_commit(head.target().unwrap())
                    .map_err_into(GHEK::RepositoryParentFetchingError)
                    .map_dbg_err_str("Failed to find commit HEAD")
                    .map_into_hook_error()
            );
            parents.push(commit);
        }

        // for converting from Vec<Commit> to Vec<&Commit>
        let parents = parents.iter().collect::<Vec<_>>();

        let tree = try!(
            repo.find_tree(tree_id)
                .map_err_into(GHEK::RepositoryParentFetchingError)
                .map_dbg_err_str("Failed to find tree")
                .map_into_hook_error()
        );

        let message = try!(commit_message(&repo, cfg, StoreAction::Update)
                .map_dbg_err_str("Failed to get commit message"));

        try!(repo.commit(Some("HEAD"), &signature, &signature, &message, &tree, &parents)
            .map_dbg_str("Committed")
            .map_dbg_err_str("Failed to commit")
            .map_err_into(GHEK::RepositoryCommittingError)
            .map_into_hook_error()
        );

        index.write()
            .map_err_into(GHEK::RepositoryIndexWritingError)
            .map_dbg_err_str("Failed to write tree")
            .map_into_hook_error()
            .map(|_| ())
    }

}

<commit_msg>Abort the execution of the UpdateHook if repo isnt dirty<commit_after>use std::path::PathBuf;
use std::path::Path;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;

use toml::Value;

use libimagerror::trace::trace_error;
use libimagstore::hook::Hook;
use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::result::HookResult;
use libimagstore::storeid::StoreId;
use libimagutil::debug_result::*;

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::runtime::Runtime as GRuntime;

/// The `UpdateHook` type
///
/// Represents a hook which is executed whenever a entry in the store is updated (written to disk).
///
/// # Time of execution
///
/// This hook is executed _after_ the store operation succeeded, so _after_ the file is written to
/// disk.
pub struct UpdateHook {
    storepath: PathBuf,

    runtime: GRuntime,

    position: HookPosition,
}

impl UpdateHook {

    pub fn new(storepath: PathBuf, p: HookPosition) -> UpdateHook {
        UpdateHook {
            runtime: GRuntime::new(&storepath),
            storepath: storepath,
            position: p,
        }
    }

}

impl Debug for UpdateHook {
    fn fmt(&self, fmt: &mut Formatter) -> RResult<(), FmtError> {
        write!(fmt, "UpdateHook(storepath={:?}, repository={}, pos={:?}, cfg={:?})",
               self.storepath,
               (if self.runtime.has_repository() { "Some(_)" } else { "None" }),
               self.position,
               self.runtime.has_config())
    }
}

impl Hook for UpdateHook {

    fn name(&self) -> &'static str {
        "stdhook_git_update"
    }

    /// Set the configuration of the hook. See
    /// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`.
    ///
    /// This function traces the error (using `trace_error()`) that
    /// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`
    /// returns, if any.
    fn set_config(&mut self, config: &Value) {
        if let Err(e) = self.runtime.set_config(config) {
            trace_error(&e);
        }
    }

}

impl HookDataAccessorProvider for UpdateHook {

    fn accessor(&self) -> HookDataAccessor {
        HookDataAccessor::StoreIdAccess(self)
    }
}

impl StoreIdAccessor for UpdateHook {

    /// The implementation of the UpdateHook
    ///
    /// # Scope
    ///
    /// This hook takes the git index and commits it either interactively or with a default message,
    /// if there is no configuration for an interactive commit.
    ///
    fn access(&self, id: &StoreId) -> HookResult<()> {
        use vcs::git::action::StoreAction;
        use vcs::git::config::commit_message;
        use vcs::git::error::MapIntoHookError;
        use vcs::git::util::fetch_index;
        use git2::{ADD_DEFAULT, STATUS_WT_NEW, STATUS_WT_MODIFIED, IndexMatchedPath};

        debug!("[GIT UPDATE HOOK]: {:?}", id);

        let action    = StoreAction::Update;
        let cfg       = try!(self.runtime.config_value_or_err(&action));
        let repo      = try!(self.runtime.repository(&action));
        let mut index = try!(fetch_index(repo, &action));

        if !self.runtime.repo_is_dirty(&index) {
            debug!("[GIT UPDATE HOOK]: Repository seems to be clean. I'm done.");
            return Ok(())
        } else {
            debug!("[GIT UPDATE HOOK]: Repository seems to be dirty. Continuing.");
        }

        let signature = try!(
            repo.signature()
                .map_err_into(GHEK::MkSignature)
                .map_dbg_err_str("Failed to fetch signature")
                .map_into_hook_error()
        );

        let head = try!(
            repo.head()
                .map_err_into(GHEK::HeadFetchError)
                .map_dbg_err_str("Failed to fetch HEAD")
                .map_into_hook_error()
        );

        let file_status = try!(
            repo
                .status_file(id.local())
                .map_dbg_err_str("Failed to fetch file status")
                .map_dbg_err(|e| format!("\t->  {:?}", e))
                .map_err_into(GHEK::RepositoryFileStatusError)
                .map_into_hook_error()
        );

        let cb = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
            if file_status.contains(STATUS_WT_NEW) || file_status.contains(STATUS_WT_MODIFIED) {
                debug!("[GIT CREATE HOOK]: File is modified/new: {}", path.display());
                0
            } else {
                debug!("[GIT CREATE HOOK]: Ignoring file: {}", path.display());
                1
            }
        };

        try!(
            index.add_all(&[id.local()], ADD_DEFAULT, Some(cb as &mut IndexMatchedPath))
                .map_err_into(GHEK::RepositoryPathAddingError)
                .map_dbg_err_str("Failed to add to index")
                .map_into_hook_error()
        );

        let tree_id = try!(
            index.write_tree()
                .map_err_into(GHEK::RepositoryIndexWritingError)
                .map_dbg_err_str("Failed to write tree")
                .map_into_hook_error()
        );

        let mut parents = Vec::new();
        {
            let commit = try!(
                repo.find_commit(head.target().unwrap())
                    .map_err_into(GHEK::RepositoryParentFetchingError)
                    .map_dbg_err_str("Failed to find commit HEAD")
                    .map_into_hook_error()
            );
            parents.push(commit);
        }

        // for converting from Vec<Commit> to Vec<&Commit>
        let parents = parents.iter().collect::<Vec<_>>();

        let tree = try!(
            repo.find_tree(tree_id)
                .map_err_into(GHEK::RepositoryParentFetchingError)
                .map_dbg_err_str("Failed to find tree")
                .map_into_hook_error()
        );

        let message = try!(commit_message(&repo, cfg, StoreAction::Update)
                .map_dbg_err_str("Failed to get commit message"));

        try!(repo.commit(Some("HEAD"), &signature, &signature, &message, &tree, &parents)
            .map_dbg_str("Committed")
            .map_dbg_err_str("Failed to commit")
            .map_err_into(GHEK::RepositoryCommittingError)
            .map_into_hook_error()
        );

        index.write()
            .map_err_into(GHEK::RepositoryIndexWritingError)
            .map_dbg_err_str("Failed to write tree")
            .map_into_hook_error()
            .map(|_| ())
    }

}

<|endoftext|>


<commit_before><commit_msg>Add 'packet headers' example<commit_after><|endoftext|>


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

use std::error::Error;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::process::Command;

use devicemapper::DM;
use devicemapper::Bytes;
use devicemapper::{ThinDev, ThinStatus};
use devicemapper::ThinPoolDev;

use super::super::consts::IEC;
use super::super::engine::{Filesystem, HasName, HasUuid};
use super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::types::{FilesystemUuid, PoolUuid};

use super::dmdevice::{ThinRole, format_thin_name};
use super::serde_structs::{FilesystemSave, Recordable};

#[derive(Debug)]
pub struct StratFilesystem {
    fs_id: FilesystemUuid,
    name: String,
    thin_dev: ThinDev,
}

pub enum FilesystemStatus {
    Good,
    Failed,
}

impl StratFilesystem {
    pub fn initialize(pool_id: &PoolUuid,
                      fs_id: FilesystemUuid,
                      name: &str,
                      dm: &DM,
                      thin_pool: &ThinPoolDev)
                      -> EngineResult<StratFilesystem> {
        // TODO should replace with proper id generation. DM takes a 24 bit
        // number for the thin_id.  Generate a u16 to avoid the possibility of
        // "too big". Should this be moved into the DM binding (or lower)?
        // How can a client be expected to avoid collisions?
        let thin_id = rand::random::<u16>();
        let device_name = format_thin_name(pool_id, ThinRole::Filesystem(fs_id));
        // TODO We don't require a size to be provided for create_filesystems -
        // but devicemapper requires an initial size for a thin provisioned
        // device - currently hard coded to 1GB.
        let new_thin_dev = try!(ThinDev::new(&device_name,
                                             dm,
                                             thin_pool,
                                             thin_id as u32,
                                             Bytes(IEC::Ti).sectors()));
        try!(create_fs(try!(new_thin_dev.devnode()).as_path()));
        Ok(StratFilesystem {
               fs_id: fs_id,
               name: name.to_owned(),
               thin_dev: new_thin_dev,
           })
    }

    pub fn check(&self, dm: &DM) -> EngineResult<FilesystemStatus> {
        match try!(self.thin_dev.status(dm)) {
            ThinStatus::Good((_mapped, _highest)) => {
                // TODO: check if filesystem is getting full and might need to
                // be extended (hint: use statfs(2))
                // TODO: periodically kick off fstrim?
            }
            ThinStatus::Fail => return Ok(FilesystemStatus::Failed),
        }
        Ok(FilesystemStatus::Good)
    }
}

impl HasName for StratFilesystem {
    fn name(&self) -> &str {
        &self.name
    }
}

impl HasUuid for StratFilesystem {
    fn uuid(&self) -> &FilesystemUuid {
        &self.fs_id
    }
}

impl Filesystem for StratFilesystem {
    fn rename(&mut self, name: &str) {
        self.name = name.to_owned();
    }

    fn destroy(self) -> EngineResult<()> {
        let dm = try!(DM::new());
        match self.thin_dev.teardown(&dm) {
            Ok(_) => Ok(()),
            Err(e) => Err(EngineError::Engine(ErrorEnum::Error, e.description().into())),
        }
    }

    fn devnode(&self) -> EngineResult<PathBuf> {
        Ok(try!(self.thin_dev.devnode()))
    }
}

impl Recordable<FilesystemSave> for StratFilesystem {
    fn record(&self) -> EngineResult<FilesystemSave> {
        Ok(FilesystemSave {
               name: self.name.clone(),
               uuid: self.fs_id,
               thin_id: self.thin_dev.id(),
               size: self.thin_dev.size(),
           })
    }
}

pub fn create_fs(dev_path: &Path) -> EngineResult<()> {

    debug!("Create filesystem for : {:?}", dev_path);
    let output = try!(Command::new("mkfs.xfs")
                          .arg("-f")
                          .arg(&dev_path)
                          .output());

    if output.status.success() {
        debug!("Created xfs filesystem on {:?}", dev_path)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}

pub fn mount_fs(dev_path: &Path, mount_point: &Path) -> EngineResult<()> {

    debug!("Mount filesystem {:?} on : {:?}", dev_path, mount_point);
    let output = try!(Command::new("mount")
                          .arg(&dev_path)
                          .arg(mount_point)
                          .output());

    if output.status.success() {
        debug!("Mounted filesystem on {:?}", mount_point)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}

pub fn unmount_fs<I, S>(mount_point: &Path, flags: I) -> EngineResult<()>
    where I: IntoIterator<Item = S>,
          S: AsRef<OsStr>
{
    debug!("Unmount filesystem {:?}", mount_point);

    let mut command = Command::new("umount");
    let output = try!(command.arg(mount_point).args(flags).output());

    if output.status.success() {
        debug!("Unmounted filesystem {:?}", mount_point)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}
<commit_msg>Get rid of a stray 'extern' directive<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::error::Error;
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::process::Command;

use rand;

use devicemapper::DM;
use devicemapper::Bytes;
use devicemapper::{ThinDev, ThinStatus};
use devicemapper::ThinPoolDev;

use super::super::consts::IEC;
use super::super::engine::{Filesystem, HasName, HasUuid};
use super::super::errors::{EngineError, EngineResult, ErrorEnum};
use super::super::types::{FilesystemUuid, PoolUuid};

use super::dmdevice::{ThinRole, format_thin_name};
use super::serde_structs::{FilesystemSave, Recordable};

#[derive(Debug)]
pub struct StratFilesystem {
    fs_id: FilesystemUuid,
    name: String,
    thin_dev: ThinDev,
}

pub enum FilesystemStatus {
    Good,
    Failed,
}

impl StratFilesystem {
    pub fn initialize(pool_id: &PoolUuid,
                      fs_id: FilesystemUuid,
                      name: &str,
                      dm: &DM,
                      thin_pool: &ThinPoolDev)
                      -> EngineResult<StratFilesystem> {
        // TODO should replace with proper id generation. DM takes a 24 bit
        // number for the thin_id.  Generate a u16 to avoid the possibility of
        // "too big". Should this be moved into the DM binding (or lower)?
        // How can a client be expected to avoid collisions?
        let thin_id = rand::random::<u16>();
        let device_name = format_thin_name(pool_id, ThinRole::Filesystem(fs_id));
        // TODO We don't require a size to be provided for create_filesystems -
        // but devicemapper requires an initial size for a thin provisioned
        // device - currently hard coded to 1GB.
        let new_thin_dev = try!(ThinDev::new(&device_name,
                                             dm,
                                             thin_pool,
                                             thin_id as u32,
                                             Bytes(IEC::Ti).sectors()));
        try!(create_fs(try!(new_thin_dev.devnode()).as_path()));
        Ok(StratFilesystem {
               fs_id: fs_id,
               name: name.to_owned(),
               thin_dev: new_thin_dev,
           })
    }

    pub fn check(&self, dm: &DM) -> EngineResult<FilesystemStatus> {
        match try!(self.thin_dev.status(dm)) {
            ThinStatus::Good((_mapped, _highest)) => {
                // TODO: check if filesystem is getting full and might need to
                // be extended (hint: use statfs(2))
                // TODO: periodically kick off fstrim?
            }
            ThinStatus::Fail => return Ok(FilesystemStatus::Failed),
        }
        Ok(FilesystemStatus::Good)
    }
}

impl HasName for StratFilesystem {
    fn name(&self) -> &str {
        &self.name
    }
}

impl HasUuid for StratFilesystem {
    fn uuid(&self) -> &FilesystemUuid {
        &self.fs_id
    }
}

impl Filesystem for StratFilesystem {
    fn rename(&mut self, name: &str) {
        self.name = name.to_owned();
    }

    fn destroy(self) -> EngineResult<()> {
        let dm = try!(DM::new());
        match self.thin_dev.teardown(&dm) {
            Ok(_) => Ok(()),
            Err(e) => Err(EngineError::Engine(ErrorEnum::Error, e.description().into())),
        }
    }

    fn devnode(&self) -> EngineResult<PathBuf> {
        Ok(try!(self.thin_dev.devnode()))
    }
}

impl Recordable<FilesystemSave> for StratFilesystem {
    fn record(&self) -> EngineResult<FilesystemSave> {
        Ok(FilesystemSave {
               name: self.name.clone(),
               uuid: self.fs_id,
               thin_id: self.thin_dev.id(),
               size: self.thin_dev.size(),
           })
    }
}

pub fn create_fs(dev_path: &Path) -> EngineResult<()> {

    debug!("Create filesystem for : {:?}", dev_path);
    let output = try!(Command::new("mkfs.xfs")
                          .arg("-f")
                          .arg(&dev_path)
                          .output());

    if output.status.success() {
        debug!("Created xfs filesystem on {:?}", dev_path)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}

pub fn mount_fs(dev_path: &Path, mount_point: &Path) -> EngineResult<()> {

    debug!("Mount filesystem {:?} on : {:?}", dev_path, mount_point);
    let output = try!(Command::new("mount")
                          .arg(&dev_path)
                          .arg(mount_point)
                          .output());

    if output.status.success() {
        debug!("Mounted filesystem on {:?}", mount_point)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}

pub fn unmount_fs<I, S>(mount_point: &Path, flags: I) -> EngineResult<()>
    where I: IntoIterator<Item = S>,
          S: AsRef<OsStr>
{
    debug!("Unmount filesystem {:?}", mount_point);

    let mut command = Command::new("umount");
    let output = try!(command.arg(mount_point).args(flags).output());

    if output.status.success() {
        debug!("Unmounted filesystem {:?}", mount_point)
    } else {
        let message = String::from_utf8_lossy(&output.stderr);
        debug!("stderr: {}", message);
        return Err(EngineError::Engine(ErrorEnum::Error, message.into()));
    }
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>add test case<commit_after>#![feature(pin, arbitrary_self_types, futures_api)]

extern crate futures;
use futures::executor::block_on;
use futures::io::AsyncReadExt;

#[test]
fn read_exact() {
    let mut reader: &[u8] = &vec![1,2,3,4,5u8];
    let mut out = [0u8; 3];

    let res = block_on(reader.read_exact(&mut out)); // read 3 bytes out
    assert!(res.is_ok());
    assert_eq!(out, [1,2,3]);
    assert_eq!(reader.len(), 2);

    let res = block_on(reader.read_exact(&mut out)); // read another 3 bytes, but only 2 bytes left
    assert!(res.is_err());
    assert_eq!(reader.len(), 0);
}
<|endoftext|>


<commit_before><commit_msg>Fix duplicate errors<commit_after><|endoftext|>


<commit_before><commit_msg>more useful links<commit_after><|endoftext|>


<commit_before><commit_msg>missing file<commit_after>use std::fmt;
use std::marker;

/// A trait that all HTTP/2 frame header flags need to implement.
pub trait Flag : fmt::Debug + Copy + Clone + Sized {
    /// Returns a bit mask that represents the flag.
    fn bitmask(&self) -> u8;

    fn flags() -> &'static [Self];

    fn to_flags(&self) -> Flags<Self> {
        Flags::new(self.bitmask())
    }
}

/// A helper struct that can be used by all frames that do not define any flags.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct NoFlag;
impl Flag for NoFlag {
    fn bitmask(&self) -> u8 {
        0
    }

    fn flags() -> &'static [Self] {
        static FLAGS: &'static [NoFlag] = &[NoFlag];
        FLAGS
    }
}

#[derive(PartialEq, Eq, Copy, Clone)]
pub struct Flags<F : Flag + 'static>(pub u8, marker::PhantomData<F>);

impl<F : Flag> Flags<F> {
    pub fn new(value: u8) -> Flags<F> {
        Flags(value, marker::PhantomData)
    }

    pub fn is_set(&self, flag: &F) -> bool {
        (self.0 & flag.bitmask()) != 0
    }

    pub fn set(&mut self, flag: &F) {
        self.0 |= flag.bitmask()
    }

    pub fn clear(&mut self, flag: &F) {
        self.0 &= !flag.bitmask();
    }
}

impl<F : Flag> Default for Flags<F> {
    fn default() -> Self {
        Flags::new(0)
    }
}

impl<F : Flag> fmt::Debug for Flags<F> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.0 == 0 {
            return write!(f, "0");
        }

        let mut copy: Flags<F> = (*self).clone();

        let mut first = true;
        for flag in F::flags() {
            if copy.is_set(flag) {
                if !first {
                    write!(f, "|")?;
                }
                first = false;

                write!(f, "{:?}", flag)?;
                copy.clear(flag);
            }
        }

        // unknown flags
        if copy.0 != 0 {
            if !first {
                write!(f, "|")?;
            }
            write!(f, "0x{:x}", copy.0)?;
        }

        Ok(())
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq, Eq)]
    enum FakeFlag {
        Foo = 0x1,
        Bar = 0x80,
    }

    impl Flag for FakeFlag {
        fn bitmask(&self) -> u8 {
            *self as u8
        }

        fn flags() -> &'static [Self] {
            static FLAGS: &'static [FakeFlag] = &[FakeFlag::Foo, FakeFlag::Bar];
            FLAGS
        }
    }

    #[test]
    fn fmt_flags() {
        assert_eq!("0", format!("{:?}", Flags::<FakeFlag>::new(0)));
        assert_eq!("Foo", format!("{:?}", Flags::<FakeFlag>::new(0x1)));
        assert_eq!("0x62", format!("{:?}", Flags::<FakeFlag>::new(0x62)));
        assert_eq!("Foo|Bar", format!("{:?}", Flags::<FakeFlag>::new(0x81)));
        assert_eq!("Foo|Bar|0x62", format!("{:?}", Flags::<FakeFlag>::new(0x81 | 0x62)));
    }
}
<|endoftext|>


<commit_before><commit_msg>concept<commit_after><|endoftext|>


<commit_before><commit_msg>Add service lane<commit_after>use std::io;

fn read_line() -> String {
    let mut reader = io::stdin();
    let mut input = String::new();
    reader.read_line(&mut input).ok().expect("error reading line");
    input
}

fn main () {
    let num_tests = read_line().trim().split(" ")
        .map(|x| x.parse::<i32>().unwrap())
        .nth(1).unwrap();
    let widths = read_line().trim().split(" ")
        .map(|x| x.parse::<i32>().unwrap())
        .collect::<Vec<i32>>();
    for _ in 0..num_tests {
        let line = read_line().trim().split(" ")
            .map(|x| x.parse::<i32>().unwrap())
            .collect::<Vec<i32>>();
        let ioline = &line;
        let wline = &widths;
        let start = ioline[0] as usize;
        let end = ioline[1] as usize;
        let min_width = &wline[start..end + 1]
            .iter()
            .fold(std::i32::MAX, |acc, &x| {
            if x < acc {
                x
            } else {
                acc
            }
        });
        println!("{}", min_width);
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement Entry type (path and index pairing).<commit_after>use matching;
use std::path::PathBuf;
use std::collections::hash_map::HashMap;

pub struct Entry {
    pub path: PathBuf,
    pub index: HashMap<char, Vec<usize>>,
}

pub fn new(path: String) -> Entry {
    Entry{
        // Build the index before we transfer ownership of path.
        index: matching::index_subject(&path),
        path: PathBuf::from(path),
    }
}
<|endoftext|>


<commit_before><commit_msg>Add more errors.<commit_after><|endoftext|>


<commit_before>#![allow(unknown_lints)]
#![allow(float_cmp)]

use std::mem::transmute;
use rustc::ty::layout::TargetDataLayout;

use error::{EvalError, EvalResult};
use memory::{Memory, MemoryPointer};

pub(super) fn bytes_to_f32(bytes: u128) -> f32 {
    unsafe { transmute::<u32, f32>(bytes as u32) }
}

pub(super) fn bytes_to_f64(bytes: u128) -> f64 {
    unsafe { transmute::<u64, f64>(bytes as u64) }
}

pub(super) fn f32_to_bytes(f: f32) -> u128 {
    unsafe { transmute::<f32, u32>(f) as u128 }
}

pub(super) fn f64_to_bytes(f: f64) -> u128 {
    unsafe { transmute::<f64, u64>(f) as u128 }
}

/// A `Value` represents a single self-contained Rust value.
///
/// A `Value` can either refer to a block of memory inside an allocation (`ByRef`) or to a primitve
/// value held directly, outside of any allocation (`ByVal`).
///
/// For optimization of a few very common cases, there is also a representation for a pair of
/// primitive values (`ByValPair`). It allows Miri to avoid making allocations for checked binary
/// operations and fat pointers. This idea was taken from rustc's trans.
#[derive(Clone, Copy, Debug)]
pub enum Value {
    ByRef(Pointer),
    ByVal(PrimVal),
    ByValPair(PrimVal, PrimVal),
}

/// A wrapper type around `PrimVal` that cannot be turned back into a `PrimVal` accidentally.
/// This type clears up a few APIs where having a `PrimVal` argument for something that is
/// potentially an integer pointer or a pointer to an allocation was unclear.
#[derive(Clone, Copy, Debug)]
pub struct Pointer {
    primval: PrimVal,
}

impl<'tcx> Pointer {
    pub fn null() -> Self {
        PrimVal::Bytes(0).into()
    }
    pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
        self.primval.to_ptr()
    }
    pub fn into_inner_primval(self) -> PrimVal {
        self.primval
    }

    pub(crate) fn signed_offset(self, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(signed_offset(b as u64, i, layout)? as u128)))
            },
            PrimVal::Ptr(ptr) => ptr.signed_offset(i, layout).map(Pointer::from),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub(crate) fn offset(self, i: u64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(offset(b as u64, i, layout)? as u128)))
            },
            PrimVal::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub(crate) fn wrapping_signed_offset(self, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(wrapping_signed_offset(b as u64, i, layout) as u128)))
            },
            PrimVal::Ptr(ptr) => Ok(Pointer::from(ptr.wrapping_signed_offset(i, layout))),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn is_null(self) -> EvalResult<'tcx, bool> {
        match self.primval {
            PrimVal::Bytes(b) => Ok(b == 0),
            PrimVal::Ptr(_) => Ok(false),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn to_value_with_len(self, len: u64) -> Value {
        Value::ByValPair(self.primval, PrimVal::from_u128(len as u128))
    }

    pub fn to_value_with_vtable(self, vtable: MemoryPointer) -> Value {
        Value::ByValPair(self.primval, PrimVal::Ptr(vtable))
    }

    pub fn to_value(self) -> Value {
        Value::ByVal(self.primval)
    }
}

impl ::std::convert::From<PrimVal> for Pointer {
    fn from(primval: PrimVal) -> Self {
        Pointer { primval }
    }
}

impl ::std::convert::From<MemoryPointer> for Pointer {
    fn from(ptr: MemoryPointer) -> Self {
        PrimVal::Ptr(ptr).into()
    }
}

/// A `PrimVal` represents an immediate, primitive value existing outside of a
/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
/// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
/// of a simple value, a pointer into another `Allocation`, or be undefined.
#[derive(Clone, Copy, Debug)]
pub enum PrimVal {
    /// The raw bytes of a simple value.
    Bytes(u128),

    /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
    /// relocations, but a `PrimVal` is only large enough to contain one, so we just represent the
    /// relocation and its associated offset together as a `MemoryPointer` here.
    Ptr(MemoryPointer),

    /// An undefined `PrimVal`, for representing values that aren't safe to examine, but are safe
    /// to copy around, just like undefined bytes in an `Allocation`.
    Undef,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PrimValKind {
    I8, I16, I32, I64, I128,
    U8, U16, U32, U64, U128,
    F32, F64,
    Bool,
    Char,
    Ptr,
    FnPtr,
}

impl<'a, 'tcx: 'a> Value {
    pub(super) fn read_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointer> {
        use self::Value::*;
        match *self {
            ByRef(ptr) => mem.read_ptr(ptr.to_ptr()?),
            ByVal(ptr) | ByValPair(ptr, _) => Ok(ptr.into()),
        }
    }

    pub(super) fn expect_ptr_vtable_pair(
        &self,
        mem: &Memory<'a, 'tcx>
    ) -> EvalResult<'tcx, (Pointer, MemoryPointer)> {
        use self::Value::*;
        match *self {
            ByRef(ref_ptr) => {
                let ptr = mem.read_ptr(ref_ptr.to_ptr()?)?;
                let vtable = mem.read_ptr(ref_ptr.offset(mem.pointer_size(), mem.layout)?.to_ptr()?)?;
                Ok((ptr, vtable.to_ptr()?))
            }

            ByValPair(ptr, vtable) => Ok((ptr.into(), vtable.to_ptr()?)),

            _ => bug!("expected ptr and vtable, got {:?}", self),
        }
    }

    pub(super) fn expect_slice(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, (Pointer, u64)> {
        use self::Value::*;
        match *self {
            ByRef(ref_ptr) => {
                let ptr = mem.read_ptr(ref_ptr.to_ptr()?)?;
                let len = mem.read_usize(ref_ptr.offset(mem.pointer_size(), mem.layout)?.to_ptr()?)?;
                Ok((ptr, len))
            },
            ByValPair(ptr, val) => {
                let len = val.to_u128()?;
                assert_eq!(len as u64 as u128, len);
                Ok((ptr.into(), len as u64))
            },
            ByVal(_) => unimplemented!(),
        }
    }
}

impl<'tcx> PrimVal {
    pub fn from_u128(n: u128) -> Self {
        PrimVal::Bytes(n)
    }

    pub fn from_i128(n: i128) -> Self {
        PrimVal::Bytes(n as u128)
    }

    pub fn from_f32(f: f32) -> Self {
        PrimVal::Bytes(f32_to_bytes(f))
    }

    pub fn from_f64(f: f64) -> Self {
        PrimVal::Bytes(f64_to_bytes(f))
    }

    pub fn from_bool(b: bool) -> Self {
        PrimVal::Bytes(b as u128)
    }

    pub fn from_char(c: char) -> Self {
        PrimVal::Bytes(c as u128)
    }

    pub fn to_bytes(self) -> EvalResult<'tcx, u128> {
        match self {
            PrimVal::Bytes(b) => Ok(b),
            PrimVal::Ptr(_) => Err(EvalError::ReadPointerAsBytes),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
        match self {
            PrimVal::Bytes(_) => Err(EvalError::ReadBytesAsPointer),
            PrimVal::Ptr(p) => Ok(p),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn is_bytes(self) -> bool {
        match self {
            PrimVal::Bytes(_) => true,
            _ => false,
        }
    }

    pub fn is_ptr(self) -> bool {
        match self {
            PrimVal::Ptr(_) => true,
            _ => false,
        }
    }

    pub fn is_undef(self) -> bool {
        match self {
            PrimVal::Undef => true,
            _ => false,
        }
    }

    pub fn to_u128(self) -> EvalResult<'tcx, u128> {
        self.to_bytes()
    }

    pub fn to_u64(self) -> EvalResult<'tcx, u64> {
        self.to_bytes().map(|b| {
            assert_eq!(b as u64 as u128, b);
            b as u64
        })
    }

    pub fn to_i32(self) -> EvalResult<'tcx, i32> {
        self.to_bytes().map(|b| {
            assert_eq!(b as i32 as u128, b);
            b as i32
        })
    }

    pub fn to_i128(self) -> EvalResult<'tcx, i128> {
        self.to_bytes().map(|b| b as i128)
    }

    pub fn to_i64(self) -> EvalResult<'tcx, i64> {
        self.to_bytes().map(|b| {
            assert_eq!(b as i64 as u128, b);
            b as i64
        })
    }

    pub fn to_f32(self) -> EvalResult<'tcx, f32> {
        self.to_bytes().map(bytes_to_f32)
    }

    pub fn to_f64(self) -> EvalResult<'tcx, f64> {
        self.to_bytes().map(bytes_to_f64)
    }

    pub fn to_bool(self) -> EvalResult<'tcx, bool> {
        match self.to_bytes()? {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(EvalError::InvalidBool),
        }
    }
}

// Overflow checking only works properly on the range from -u64 to +u64.
pub fn overflowing_signed_offset<'tcx>(val: u64, i: i128, layout: &TargetDataLayout) -> (u64, bool) {
    // FIXME: is it possible to over/underflow here?
    if i < 0 {
        // trickery to ensure that i64::min_value() works fine
        // this formula only works for true negative values, it panics for zero!
        let n = u64::max_value() - (i as u64) + 1;
        val.overflowing_sub(n)
    } else {
        overflowing_offset(val, i as u64, layout)
    }
}

pub fn overflowing_offset<'tcx>(val: u64, i: u64, layout: &TargetDataLayout) -> (u64, bool) {
    let (res, over) = val.overflowing_add(i);
    ((res as u128 % (1u128 << layout.pointer_size.bits())) as u64,
     over || res as u128 >= (1u128 << layout.pointer_size.bits()))
}

pub fn signed_offset<'tcx>(val: u64, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, u64> {
    let (res, over) = overflowing_signed_offset(val, i as i128, layout);
    if over {
        Err(EvalError::OverflowingMath)
    } else {
        Ok(res)
    }
}

pub fn offset<'tcx>(val: u64, i: u64, layout: &TargetDataLayout) -> EvalResult<'tcx, u64> {
    let (res, over) = overflowing_offset(val, i, layout);
    if over {
        Err(EvalError::OverflowingMath)
    } else {
        Ok(res)
    }
}

pub fn wrapping_signed_offset<'tcx>(val: u64, i: i64, layout: &TargetDataLayout) -> u64 {
    overflowing_signed_offset(val, i as i128, layout).0
}

impl PrimValKind {
    pub fn is_int(self) -> bool {
        use self::PrimValKind::*;
        match self {
            I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
            _ => false,
        }
    }

    pub fn is_signed_int(self) -> bool {
        use self::PrimValKind::*;
        match self {
            I8 | I16 | I32 | I64 | I128 => true,
            _ => false,
        }
    }

     pub fn is_float(self) -> bool {
        use self::PrimValKind::*;
        match self {
            F32 | F64 => true,
            _ => false,
        }
    }

    pub fn from_uint_size(size: u64) -> Self {
        match size {
            1 => PrimValKind::U8,
            2 => PrimValKind::U16,
            4 => PrimValKind::U32,
            8 => PrimValKind::U64,
            16 => PrimValKind::U128,
            _ => bug!("can't make uint with size {}", size),
        }
    }

    pub fn from_int_size(size: u64) -> Self {
        match size {
            1 => PrimValKind::I8,
            2 => PrimValKind::I16,
            4 => PrimValKind::I32,
            8 => PrimValKind::I64,
            16 => PrimValKind::I128,
            _ => bug!("can't make int with size {}", size),
        }
    }

    pub fn is_ptr(self) -> bool {
        use self::PrimValKind::*;
        match self {
            Ptr | FnPtr => true,
            _ => false,
        }
    }
}
<commit_msg>Document the reason for `Pointer`'s existence<commit_after>#![allow(unknown_lints)]
#![allow(float_cmp)]

use std::mem::transmute;
use rustc::ty::layout::TargetDataLayout;

use error::{EvalError, EvalResult};
use memory::{Memory, MemoryPointer};

pub(super) fn bytes_to_f32(bytes: u128) -> f32 {
    unsafe { transmute::<u32, f32>(bytes as u32) }
}

pub(super) fn bytes_to_f64(bytes: u128) -> f64 {
    unsafe { transmute::<u64, f64>(bytes as u64) }
}

pub(super) fn f32_to_bytes(f: f32) -> u128 {
    unsafe { transmute::<f32, u32>(f) as u128 }
}

pub(super) fn f64_to_bytes(f: f64) -> u128 {
    unsafe { transmute::<f64, u64>(f) as u128 }
}

/// A `Value` represents a single self-contained Rust value.
///
/// A `Value` can either refer to a block of memory inside an allocation (`ByRef`) or to a primitve
/// value held directly, outside of any allocation (`ByVal`).
///
/// For optimization of a few very common cases, there is also a representation for a pair of
/// primitive values (`ByValPair`). It allows Miri to avoid making allocations for checked binary
/// operations and fat pointers. This idea was taken from rustc's trans.
#[derive(Clone, Copy, Debug)]
pub enum Value {
    ByRef(Pointer),
    ByVal(PrimVal),
    ByValPair(PrimVal, PrimVal),
}

/// A wrapper type around `PrimVal` that cannot be turned back into a `PrimVal` accidentally.
/// This type clears up a few APIs where having a `PrimVal` argument for something that is
/// potentially an integer pointer or a pointer to an allocation was unclear.
///
/// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
/// the representation of pointers. Also all the sites that convert between primvals and pointers
/// are explicit now (and rare!)
#[derive(Clone, Copy, Debug)]
pub struct Pointer {
    primval: PrimVal,
}

impl<'tcx> Pointer {
    pub fn null() -> Self {
        PrimVal::Bytes(0).into()
    }
    pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
        self.primval.to_ptr()
    }
    pub fn into_inner_primval(self) -> PrimVal {
        self.primval
    }

    pub(crate) fn signed_offset(self, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(signed_offset(b as u64, i, layout)? as u128)))
            },
            PrimVal::Ptr(ptr) => ptr.signed_offset(i, layout).map(Pointer::from),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub(crate) fn offset(self, i: u64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(offset(b as u64, i, layout)? as u128)))
            },
            PrimVal::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub(crate) fn wrapping_signed_offset(self, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, Self> {
        match self.primval {
            PrimVal::Bytes(b) => {
                assert_eq!(b as u64 as u128, b);
                Ok(Pointer::from(PrimVal::Bytes(wrapping_signed_offset(b as u64, i, layout) as u128)))
            },
            PrimVal::Ptr(ptr) => Ok(Pointer::from(ptr.wrapping_signed_offset(i, layout))),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn is_null(self) -> EvalResult<'tcx, bool> {
        match self.primval {
            PrimVal::Bytes(b) => Ok(b == 0),
            PrimVal::Ptr(_) => Ok(false),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn to_value_with_len(self, len: u64) -> Value {
        Value::ByValPair(self.primval, PrimVal::from_u128(len as u128))
    }

    pub fn to_value_with_vtable(self, vtable: MemoryPointer) -> Value {
        Value::ByValPair(self.primval, PrimVal::Ptr(vtable))
    }

    pub fn to_value(self) -> Value {
        Value::ByVal(self.primval)
    }
}

impl ::std::convert::From<PrimVal> for Pointer {
    fn from(primval: PrimVal) -> Self {
        Pointer { primval }
    }
}

impl ::std::convert::From<MemoryPointer> for Pointer {
    fn from(ptr: MemoryPointer) -> Self {
        PrimVal::Ptr(ptr).into()
    }
}

/// A `PrimVal` represents an immediate, primitive value existing outside of a
/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
/// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
/// of a simple value, a pointer into another `Allocation`, or be undefined.
#[derive(Clone, Copy, Debug)]
pub enum PrimVal {
    /// The raw bytes of a simple value.
    Bytes(u128),

    /// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
    /// relocations, but a `PrimVal` is only large enough to contain one, so we just represent the
    /// relocation and its associated offset together as a `MemoryPointer` here.
    Ptr(MemoryPointer),

    /// An undefined `PrimVal`, for representing values that aren't safe to examine, but are safe
    /// to copy around, just like undefined bytes in an `Allocation`.
    Undef,
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PrimValKind {
    I8, I16, I32, I64, I128,
    U8, U16, U32, U64, U128,
    F32, F64,
    Bool,
    Char,
    Ptr,
    FnPtr,
}

impl<'a, 'tcx: 'a> Value {
    pub(super) fn read_ptr(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, Pointer> {
        use self::Value::*;
        match *self {
            ByRef(ptr) => mem.read_ptr(ptr.to_ptr()?),
            ByVal(ptr) | ByValPair(ptr, _) => Ok(ptr.into()),
        }
    }

    pub(super) fn expect_ptr_vtable_pair(
        &self,
        mem: &Memory<'a, 'tcx>
    ) -> EvalResult<'tcx, (Pointer, MemoryPointer)> {
        use self::Value::*;
        match *self {
            ByRef(ref_ptr) => {
                let ptr = mem.read_ptr(ref_ptr.to_ptr()?)?;
                let vtable = mem.read_ptr(ref_ptr.offset(mem.pointer_size(), mem.layout)?.to_ptr()?)?;
                Ok((ptr, vtable.to_ptr()?))
            }

            ByValPair(ptr, vtable) => Ok((ptr.into(), vtable.to_ptr()?)),

            _ => bug!("expected ptr and vtable, got {:?}", self),
        }
    }

    pub(super) fn expect_slice(&self, mem: &Memory<'a, 'tcx>) -> EvalResult<'tcx, (Pointer, u64)> {
        use self::Value::*;
        match *self {
            ByRef(ref_ptr) => {
                let ptr = mem.read_ptr(ref_ptr.to_ptr()?)?;
                let len = mem.read_usize(ref_ptr.offset(mem.pointer_size(), mem.layout)?.to_ptr()?)?;
                Ok((ptr, len))
            },
            ByValPair(ptr, val) => {
                let len = val.to_u128()?;
                assert_eq!(len as u64 as u128, len);
                Ok((ptr.into(), len as u64))
            },
            ByVal(_) => unimplemented!(),
        }
    }
}

impl<'tcx> PrimVal {
    pub fn from_u128(n: u128) -> Self {
        PrimVal::Bytes(n)
    }

    pub fn from_i128(n: i128) -> Self {
        PrimVal::Bytes(n as u128)
    }

    pub fn from_f32(f: f32) -> Self {
        PrimVal::Bytes(f32_to_bytes(f))
    }

    pub fn from_f64(f: f64) -> Self {
        PrimVal::Bytes(f64_to_bytes(f))
    }

    pub fn from_bool(b: bool) -> Self {
        PrimVal::Bytes(b as u128)
    }

    pub fn from_char(c: char) -> Self {
        PrimVal::Bytes(c as u128)
    }

    pub fn to_bytes(self) -> EvalResult<'tcx, u128> {
        match self {
            PrimVal::Bytes(b) => Ok(b),
            PrimVal::Ptr(_) => Err(EvalError::ReadPointerAsBytes),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
        match self {
            PrimVal::Bytes(_) => Err(EvalError::ReadBytesAsPointer),
            PrimVal::Ptr(p) => Ok(p),
            PrimVal::Undef => Err(EvalError::ReadUndefBytes),
        }
    }

    pub fn is_bytes(self) -> bool {
        match self {
            PrimVal::Bytes(_) => true,
            _ => false,
        }
    }

    pub fn is_ptr(self) -> bool {
        match self {
            PrimVal::Ptr(_) => true,
            _ => false,
        }
    }

    pub fn is_undef(self) -> bool {
        match self {
            PrimVal::Undef => true,
            _ => false,
        }
    }

    pub fn to_u128(self) -> EvalResult<'tcx, u128> {
        self.to_bytes()
    }

    pub fn to_u64(self) -> EvalResult<'tcx, u64> {
        self.to_bytes().map(|b| {
            assert_eq!(b as u64 as u128, b);
            b as u64
        })
    }

    pub fn to_i32(self) -> EvalResult<'tcx, i32> {
        self.to_bytes().map(|b| {
            assert_eq!(b as i32 as u128, b);
            b as i32
        })
    }

    pub fn to_i128(self) -> EvalResult<'tcx, i128> {
        self.to_bytes().map(|b| b as i128)
    }

    pub fn to_i64(self) -> EvalResult<'tcx, i64> {
        self.to_bytes().map(|b| {
            assert_eq!(b as i64 as u128, b);
            b as i64
        })
    }

    pub fn to_f32(self) -> EvalResult<'tcx, f32> {
        self.to_bytes().map(bytes_to_f32)
    }

    pub fn to_f64(self) -> EvalResult<'tcx, f64> {
        self.to_bytes().map(bytes_to_f64)
    }

    pub fn to_bool(self) -> EvalResult<'tcx, bool> {
        match self.to_bytes()? {
            0 => Ok(false),
            1 => Ok(true),
            _ => Err(EvalError::InvalidBool),
        }
    }
}

// Overflow checking only works properly on the range from -u64 to +u64.
pub fn overflowing_signed_offset<'tcx>(val: u64, i: i128, layout: &TargetDataLayout) -> (u64, bool) {
    // FIXME: is it possible to over/underflow here?
    if i < 0 {
        // trickery to ensure that i64::min_value() works fine
        // this formula only works for true negative values, it panics for zero!
        let n = u64::max_value() - (i as u64) + 1;
        val.overflowing_sub(n)
    } else {
        overflowing_offset(val, i as u64, layout)
    }
}

pub fn overflowing_offset<'tcx>(val: u64, i: u64, layout: &TargetDataLayout) -> (u64, bool) {
    let (res, over) = val.overflowing_add(i);
    ((res as u128 % (1u128 << layout.pointer_size.bits())) as u64,
     over || res as u128 >= (1u128 << layout.pointer_size.bits()))
}

pub fn signed_offset<'tcx>(val: u64, i: i64, layout: &TargetDataLayout) -> EvalResult<'tcx, u64> {
    let (res, over) = overflowing_signed_offset(val, i as i128, layout);
    if over {
        Err(EvalError::OverflowingMath)
    } else {
        Ok(res)
    }
}

pub fn offset<'tcx>(val: u64, i: u64, layout: &TargetDataLayout) -> EvalResult<'tcx, u64> {
    let (res, over) = overflowing_offset(val, i, layout);
    if over {
        Err(EvalError::OverflowingMath)
    } else {
        Ok(res)
    }
}

pub fn wrapping_signed_offset<'tcx>(val: u64, i: i64, layout: &TargetDataLayout) -> u64 {
    overflowing_signed_offset(val, i as i128, layout).0
}

impl PrimValKind {
    pub fn is_int(self) -> bool {
        use self::PrimValKind::*;
        match self {
            I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
            _ => false,
        }
    }

    pub fn is_signed_int(self) -> bool {
        use self::PrimValKind::*;
        match self {
            I8 | I16 | I32 | I64 | I128 => true,
            _ => false,
        }
    }

     pub fn is_float(self) -> bool {
        use self::PrimValKind::*;
        match self {
            F32 | F64 => true,
            _ => false,
        }
    }

    pub fn from_uint_size(size: u64) -> Self {
        match size {
            1 => PrimValKind::U8,
            2 => PrimValKind::U16,
            4 => PrimValKind::U32,
            8 => PrimValKind::U64,
            16 => PrimValKind::U128,
            _ => bug!("can't make uint with size {}", size),
        }
    }

    pub fn from_int_size(size: u64) -> Self {
        match size {
            1 => PrimValKind::I8,
            2 => PrimValKind::I16,
            4 => PrimValKind::I32,
            8 => PrimValKind::I64,
            16 => PrimValKind::I128,
            _ => bug!("can't make int with size {}", size),
        }
    }

    pub fn is_ptr(self) -> bool {
        use self::PrimValKind::*;
        match self {
            Ptr | FnPtr => true,
            _ => false,
        }
    }
}
<|endoftext|>


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

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
}
<commit_msg>add playbot jokes to run-pass test<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn you_eight() {
    assert_eq!(8, {
        macro_rules! u8 {
            (u8) => {
                mod u8 {
                    pub fn u8<'u8>(u8: &'u8 u8) -> &'u8 u8 {
                        "u8";
                        u8
                    }
                }
            };
        }

        u8!(u8);
        let &u8: &u8 = u8::u8(&8u8);
        u8
    });
}

fn fishy() {
    assert_eq!(String::from("><>"), String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    you_eight();
    fishy();
}
<|endoftext|>


<commit_before><commit_msg>Removing the giveaway from the guessing game<commit_after><|endoftext|>


<commit_before><commit_msg>Add angular acceleration to component<commit_after><|endoftext|>


<commit_before><commit_msg>[No-auto] lib/entry/filter: Fix Clippy warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Flags is packed (it shouldn't change anything because it only has one member but IDK why not)<commit_after><|endoftext|>


<commit_before>

// FIXME: Most of these should be uints.
const int rc_base_field_refcnt = 0;

// FIXME: import from std::dbg when imported consts work.
const uint const_refcount = 0x7bad_face_u;

const int task_field_refcnt = 0;

const int task_field_stk = 2;

const int task_field_runtime_sp = 3;

const int task_field_rust_sp = 4;

const int task_field_gc_alloc_chain = 5;

const int task_field_dom = 6;

const int n_visible_task_fields = 7;

const int dom_field_interrupt_flag = 1;

const int frame_glue_fns_field_mark = 0;

const int frame_glue_fns_field_drop = 1;

const int frame_glue_fns_field_reloc = 2;

const int box_rc_field_refcnt = 0;

const int box_rc_field_body = 1;

const int general_code_alignment = 16;

const int vec_elt_rc = 0;

const int vec_elt_alloc = 1;

const int vec_elt_fill = 2;

const int vec_elt_pad = 3;

const int vec_elt_data = 4;

const int tydesc_field_first_param = 0;

const int tydesc_field_size = 1;

const int tydesc_field_align = 2;

const int tydesc_field_copy_glue = 3;

const int tydesc_field_drop_glue = 4;

const int tydesc_field_free_glue = 5;

const int tydesc_field_sever_glue = 6;

const int tydesc_field_mark_glue = 7;

// FIXME no longer used in rustc, drop when rustboot is gone
const int tydesc_field_obj_drop_glue = 8;

const int tydesc_field_is_stateful = 9;

const int tydesc_field_cmp_glue = 10;

const int n_tydesc_fields = 11;

const uint cmp_glue_op_eq = 0u;

const uint cmp_glue_op_lt = 1u;

const uint cmp_glue_op_le = 2u;

const int obj_field_vtbl = 0;

const int obj_field_box = 1;

const int obj_body_elt_tydesc = 0;

const int obj_body_elt_typarams = 1;

const int obj_body_elt_fields = 2;

const int obj_body_elt_with_obj = 3;

/* The base object to which an anonymous
 * object is attached */
const int fn_field_code = 0;

const int fn_field_box = 1;

const int closure_elt_tydesc = 0;

const int closure_elt_target = 1;

const int closure_elt_bindings = 2;

const int closure_elt_ty_params = 3;

const uint ivec_default_length = 4u;

const uint ivec_elt_len = 0u;

const uint ivec_elt_alen = 1u;

const uint ivec_elt_elems = 2u;

const uint ivec_heap_stub_elt_zero = 0u;

const uint ivec_heap_stub_elt_alen = 1u;

const uint ivec_heap_stub_elt_ptr = 2u;

const uint ivec_heap_elt_len = 0u;

const uint ivec_heap_elt_elems = 1u;

const int worst_case_glue_call_args = 7;

fn memcpy_glue_name() -> str { ret "rust_memcpy_glue"; }

fn bzero_glue_name() -> str { ret "rust_bzero_glue"; }

fn yield_glue_name() -> str { ret "rust_yield_glue"; }

fn no_op_type_glue_name() -> str { ret "rust_no_op_type_glue"; }
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Comments and cleanup.<commit_after>

// FIXME: Most of these should be uints.
const int rc_base_field_refcnt = 0;

// FIXME: import from std::dbg when imported consts work.
const uint const_refcount = 0x7bad_face_u;

const int task_field_refcnt = 0;

const int task_field_stk = 2;

const int task_field_runtime_sp = 3;

const int task_field_rust_sp = 4;

const int task_field_gc_alloc_chain = 5;

const int task_field_dom = 6;

const int n_visible_task_fields = 7;

const int dom_field_interrupt_flag = 1;

const int frame_glue_fns_field_mark = 0;

const int frame_glue_fns_field_drop = 1;

const int frame_glue_fns_field_reloc = 2;

const int box_rc_field_refcnt = 0;

const int box_rc_field_body = 1;

const int general_code_alignment = 16;

const int vec_elt_rc = 0;

const int vec_elt_alloc = 1;

const int vec_elt_fill = 2;

const int vec_elt_pad = 3;

const int vec_elt_data = 4;

const int tydesc_field_first_param = 0;

const int tydesc_field_size = 1;

const int tydesc_field_align = 2;

const int tydesc_field_copy_glue = 3;

const int tydesc_field_drop_glue = 4;

const int tydesc_field_free_glue = 5;

const int tydesc_field_sever_glue = 6;

const int tydesc_field_mark_glue = 7;

// FIXME no longer used in rustc, drop when rustboot is gone
const int tydesc_field_obj_drop_glue = 8;

const int tydesc_field_is_stateful = 9;

const int tydesc_field_cmp_glue = 10;

const int n_tydesc_fields = 11;

const uint cmp_glue_op_eq = 0u;

const uint cmp_glue_op_lt = 1u;

const uint cmp_glue_op_le = 2u;

const int obj_field_vtbl = 0;

const int obj_field_box = 1;

const int obj_body_elt_tydesc = 0;

const int obj_body_elt_typarams = 1;

const int obj_body_elt_fields = 2;

// The base object to which an anonymous object is attached.
const int obj_body_elt_with_obj = 3;

// The two halves of a closure: code and environment.
const int fn_field_code = 0;
const int fn_field_box = 1;

const int closure_elt_tydesc = 0;

const int closure_elt_target = 1;

const int closure_elt_bindings = 2;

const int closure_elt_ty_params = 3;

const uint ivec_default_length = 4u;

const uint ivec_elt_len = 0u;

const uint ivec_elt_alen = 1u;

const uint ivec_elt_elems = 2u;

const uint ivec_heap_stub_elt_zero = 0u;

const uint ivec_heap_stub_elt_alen = 1u;

const uint ivec_heap_stub_elt_ptr = 2u;

const uint ivec_heap_elt_len = 0u;

const uint ivec_heap_elt_elems = 1u;

const int worst_case_glue_call_args = 7;

fn memcpy_glue_name() -> str { ret "rust_memcpy_glue"; }

fn bzero_glue_name() -> str { ret "rust_bzero_glue"; }

fn yield_glue_name() -> str { ret "rust_yield_glue"; }

fn no_op_type_glue_name() -> str { ret "rust_no_op_type_glue"; }
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric};
use nom::IResult::*;

use std::str;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn not_rsb(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}
o!(category<&[u8], &[u8]> lsb ~ not_rsb ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn not_line_ending_or_semicolon(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

opt!(opt_line_ending<&[u8],&[u8]> line_ending);
o!(value<&[u8],&[u8]> space equal space ~ not_line_ending_or_semicolon ~ space opt_comment  opt_line_ending);
chain!(key_value<&[u8],(&[u8],&[u8])>, ||{(key, val)},  key: alphanumeric, val: value,);

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), str::from_utf8(o)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category".as_bytes()));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}
<commit_msg>rename parsers<commit_after>#![feature(globs,macro_rules,phase)]

#[phase(plugin,link)]
extern crate nom;

use nom::{IResult,Producer,FileProducer,ProducerState,Mapper,Mapper2,line_ending,not_line_ending, space, alphanumeric, is_alphanumeric};
use nom::IResult::*;

use std::str;
use std::fmt::Show;

fn empty_result(i:&[u8]) -> IResult<&[u8], ()> { Done(i,()) }
tag!(semicolon ";".as_bytes());
o!(comment_body<&[u8],&[u8]> semicolon ~ not_line_ending ~ );
o!(comment<&[u8], ()> comment_body line_ending ~ empty_result ~);
opt!(opt_comment<&[u8],&[u8]> comment_body);

tag!(lsb "[".as_bytes());
tag!(rsb "]".as_bytes());
fn category_name(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == ']' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}
o!(category<&[u8], &[u8]> lsb ~ category_name ~ rsb line_ending);

tag!(equal "=".as_bytes());
fn not_equal(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '=' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

fn value_parser(input:&[u8]) -> IResult<&[u8], &[u8]> {
  for idx in range(0, input.len()) {
    if input[idx] == '\n' as u8 || input[idx] == ';' as u8 {
      return Done(input.slice_from(idx), input.slice(0, idx))
    }
  }
  Done("".as_bytes(), input)
}

opt!(opt_line_ending<&[u8],&[u8]> line_ending);
o!(value<&[u8],&[u8]> space equal space ~ value_parser ~ space opt_comment opt_line_ending);
chain!(key_value<&[u8],(&[u8],&[u8])>, ||{(key, val)},  key: alphanumeric, val: value,);

#[test]
fn parse_comment_test() {
  let ini_file = ";comment
[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let ini_without_comment = "[category]
parameter=value
key = value2

[other]
number = 1234
str = a b cc dd ; comment";

  let res = Done((), ini_file.as_bytes()).flat_map(comment);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_comment.as_bytes(), ()));
}

#[test]
fn parse_category_test() {
  let ini_file = "[category]
parameter=value
key = value2";

  let ini_without_category = "parameter=value
key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(category);
  println!("{}", res);
  match res {
    IResult::Done(i, o) => println!("i: {} | o: {}", str::from_utf8(i), str::from_utf8(o)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category.as_bytes(), "category".as_bytes()));
}

#[test]
fn parse_key_value_test() {
  let ini_file = "parameter=value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = "parameter = value
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = "parameter=value;abc
key = value2";

  let ini_without_key_value = "key = value2";

  let res = Done((), ini_file.as_bytes()).flat_map(key_value);
  println!("{}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {} | o: ({},{})", str::from_utf8(i), str::from_utf8(o1), str::from_utf8(o2)),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value.as_bytes(), ("parameter".as_bytes(), "value".as_bytes())));
}
<|endoftext|>


<commit_before><commit_msg>get query build simplify<commit_after><|endoftext|>


<commit_before><commit_msg>Rustfmt<commit_after><|endoftext|>


<commit_before><commit_msg>Add EventEmitter.process_all()<commit_after><|endoftext|>


<commit_before><commit_msg>equip/inspect items is working<commit_after><|endoftext|>


<commit_before><commit_msg>Introduced an error message if the result of collect_one() is empty<commit_after><|endoftext|>


<commit_before><commit_msg>adds comments to state methods<commit_after><|endoftext|>