<commit_before>use std::io::net::ip::{Port, IpAddr};

use http::method;

use router::Router;
use middleware::{ MiddlewareStack, Middleware };
use server::Server;
use request::Request;
use response::Response;

//pre defined middleware
use static_files_handler::StaticFilesHandler;
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;

///Nickel is the application object. It's the surface that
///holds all public APIs.

#[deriving(Clone)]
pub struct Nickel{
    router: Router,
    middleware_stack: MiddlewareStack,
    server: Option<Server>
}
impl Nickel {

    /// In order to use Nickels API one first has to create an instance.
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// ```
    pub fn new() -> Nickel {
        let router = Router::new();
        let middleware_stack = MiddlewareStack::new();
        Nickel {
            router: router,
            middleware_stack: middleware_stack,
            server: None,
        }
    }

    /// Registers a handler to be used for a specific GET request.
    /// Handlers are assigned to paths and paths are allowed to contain
    /// variables and wildcards.
    ///
    /// # Example without variables and wildcards
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user");
    /// };
    /// server.get("/user", handler);
    /// ```
    /// # Example with variables
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
    ///     response.send(text.as_slice());
    /// };
    /// server.get("/user/:userid", handler);
    /// ```
    /// # Example with simple wildcard
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 but not /user/extended/list/4711");
    /// };
    /// server.get("/user/*/:userid", handler);
    /// ```
    /// # Example with double wildcard
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 and also /user/extended/list/4711");
    /// };
    /// server.get("/user/**/:userid", handler);
    /// ```
    pub fn get(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Get, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific POST request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/post/request");
    /// };
    /// server.post("/a/post/request", handler);
    /// ```
    /// Take a look at `get()` for a more detailed description.
    pub fn post(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Post, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific PUT request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/put/request");
    /// };
    /// server.put("/a/put/request", handler);
    /// ```
    /// Take a look at `get(..)` for a more detailed description.
    pub fn put(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Put, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific DELETE request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a DELETE request to /a/delete/request");
    /// };
    /// server.delete("/a/delete/request", handler);
    /// ```
    /// Take a look at `get(...)` for a more detailed description.
    pub fn delete(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Put, String::from_str(uri), handler);
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a return value of boolean. That is to indicate whether
    /// other middleware handler (if any) further down the stack should continue or if the
    /// middleware invocation should be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn logger (req: &Request, res: &mut Response) -> Action{
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Continue
    /// }
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add(handler);
    }

    /// Create a new middleware to serve files from within a given root directory.
    /// The file to serve will be determined by combining the requested Url with
    /// the provided root directory.
    ///
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::static_files("/path/to/serve/"));
    /// ```
    pub fn static_files(root_path: &str) -> StaticFilesHandler {
        StaticFilesHandler::new(root_path)
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```rust
    ///
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     firstname: String,
    ///     lastname:  String,
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::json_body_parser();
    ///
    /// fn post_handler (request: &Request, response: &mut Response) {
    ///
    ///     let person = request.json_as::<Person>().unwrap();
    ///     let text = format!("Hello {} {}", person.firstname, person.lastname);
    ///     response.send(text.as_slice());
    /// };
    ///
    /// server.post("/a/post/request", post_handler);
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```rust
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::query_string();
    ///
    /// fn get_handler (request: &Request, response: &mut Response) {
    ///     let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///     response.send(foo.as_slice());
    /// };
    ///
    /// server.get("/a/get/request", get_handler);
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        self.server = Some(Server::new(self.router, self.middleware_stack, ip, port));
        self.server.unwrap().serve();
    }
}
<commit_msg>=BG= fn delete should use http::method::Delete<commit_after>use std::io::net::ip::{Port, IpAddr};

use http::method;

use router::Router;
use middleware::{ MiddlewareStack, Middleware };
use server::Server;
use request::Request;
use response::Response;

//pre defined middleware
use static_files_handler::StaticFilesHandler;
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;

///Nickel is the application object. It's the surface that
///holds all public APIs.

#[deriving(Clone)]
pub struct Nickel{
    router: Router,
    middleware_stack: MiddlewareStack,
    server: Option<Server>
}
impl Nickel {

    /// In order to use Nickels API one first has to create an instance.
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// ```
    pub fn new() -> Nickel {
        let router = Router::new();
        let middleware_stack = MiddlewareStack::new();
        Nickel {
            router: router,
            middleware_stack: middleware_stack,
            server: None,
        }
    }

    /// Registers a handler to be used for a specific GET request.
    /// Handlers are assigned to paths and paths are allowed to contain
    /// variables and wildcards.
    ///
    /// # Example without variables and wildcards
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user");
    /// };
    /// server.get("/user", handler);
    /// ```
    /// # Example with variables
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
    ///     response.send(text.as_slice());
    /// };
    /// server.get("/user/:userid", handler);
    /// ```
    /// # Example with simple wildcard
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 but not /user/extended/list/4711");
    /// };
    /// server.get("/user/*/:userid", handler);
    /// ```
    /// # Example with double wildcard
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 and also /user/extended/list/4711");
    /// };
    /// server.get("/user/**/:userid", handler);
    /// ```
    pub fn get(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Get, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific POST request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/post/request");
    /// };
    /// server.post("/a/post/request", handler);
    /// ```
    /// Take a look at `get()` for a more detailed description.
    pub fn post(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Post, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific PUT request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/put/request");
    /// };
    /// server.put("/a/put/request", handler);
    /// ```
    /// Take a look at `get(..)` for a more detailed description.
    pub fn put(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Put, String::from_str(uri), handler);
    }

    /// Registers a handler to be used for a specific DELETE request.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a DELETE request to /a/delete/request");
    /// };
    /// server.delete("/a/delete/request", handler);
    /// ```
    /// Take a look at `get(...)` for a more detailed description.
    pub fn delete(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.router.add_route(method::Delete, String::from_str(uri), handler);
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a return value of boolean. That is to indicate whether
    /// other middleware handler (if any) further down the stack should continue or if the
    /// middleware invocation should be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```rust
    /// fn logger (req: &Request, res: &mut Response) -> Action{
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Continue
    /// }
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add(handler);
    }

    /// Create a new middleware to serve files from within a given root directory.
    /// The file to serve will be determined by combining the requested Url with
    /// the provided root directory.
    ///
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::static_files("/path/to/serve/"));
    /// ```
    pub fn static_files(root_path: &str) -> StaticFilesHandler {
        StaticFilesHandler::new(root_path)
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```rust
    ///
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     firstname: String,
    ///     lastname:  String,
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::json_body_parser();
    ///
    /// fn post_handler (request: &Request, response: &mut Response) {
    ///
    ///     let person = request.json_as::<Person>().unwrap();
    ///     let text = format!("Hello {} {}", person.firstname, person.lastname);
    ///     response.send(text.as_slice());
    /// };
    ///
    /// server.post("/a/post/request", post_handler);
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```rust
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::query_string();
    ///
    /// fn get_handler (request: &Request, response: &mut Response) {
    ///     let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///     response.send(foo.as_slice());
    /// };
    ///
    /// server.get("/a/get/request", get_handler);
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```rust
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        self.server = Some(Server::new(self.router, self.middleware_stack, ip, port));
        self.server.unwrap().serve();
    }
}
<|endoftext|>


<commit_before><commit_msg>Add function to get flags<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/. */

use db::{ Db, FindFilter, Record };
use iron::headers::ContentType;
use iron::prelude::*;
use iron::status::Status;
use params::{ Map, Params, Value };
use router::Router;
use std::error::Error;
use std::fmt::{self, Debug};
use std::time::{ SystemTime, UNIX_EPOCH };

#[derive(Debug)]
struct StringError(String);

impl fmt::Display for StringError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

impl Error for StringError {
    fn description(&self) -> &str { &*self.0 }
}

fn seconds_from_epoch() -> i64 {
    let now = SystemTime::now();
    now.duration_from_earlier(UNIX_EPOCH).unwrap().as_secs() as i64
}

pub fn create() -> Router {
    let mut router = Router::new();
    router.get("register", move |req: &mut Request| -> IronResult<Response> {
        // Get the local ip from the query, and the public one from the socket.
        let public_ip = format!("{}", req.remote_addr.ip());

        let map: &Map = req.get_ref::<Params>().unwrap();
        let ip_param = match map.find(&["ip"]) {
            Some(&Value::String(ref name)) => Some(name),
            _ => None
        };

        if ip_param == None {
            return Err(IronError::new(StringError("Error".to_string()), Status::BadRequest));
        }
        let local_ip = ip_param.unwrap().to_string();

        // Get the current number of seconds since epoch.
        let now = seconds_from_epoch();

        info!("GET /register public_ip={} local_ip={} time is {}",
              public_ip, local_ip, now);

        // Save this registration in the database.
        // If we already have the same (local, public) tuple, update it, if not
        // create a new tuple.
        let db = Db::new();
        match db.find(FindFilter::PublicAndLocalIp(public_ip.clone(), local_ip.clone())) {
            Ok(rvect) => {
                // If the vector is empty, create a new record, if not update
                // the existing one with the new timestamp.
                let record = Record {
                    public_ip: public_ip,
                    local_ip: local_ip,
                    timestamp: now,
                };

                if rvect.is_empty() {
                    db.add(record).unwrap();
                } else {
                    db.update(record).unwrap();
                }
            },
            Err(_) => {
                let record = Record {
                    public_ip: public_ip,
                    local_ip: local_ip,
                    timestamp: now,
                };
                db.add(record).unwrap();
            }
        }

        let mut response = Response::with("{\"status\" : \"registered\"}");
        response.status = Some(Status::Ok);
        response.headers.set(ContentType::json());

        Ok(response)
    });

    router.get("ping", move |req: &mut Request| -> IronResult<Response> {
        info!("GET /ping");
        let public_ip = format!("{}", req.remote_addr.ip());

        let mut serialized = String::from("[");

        let db = Db::new();
        match db.find(FindFilter::PublicIp(public_ip)) {
            Ok(rvect) => {
                // Serialize the vector.
                for record in rvect {
                    serialized.push_str(&record.to_json());
                }
            },
            Err(_) => { }
        }

        serialized.push_str("]");
        let mut response = Response::with(serialized);
        //let mut response = Response::with("ok");
        response.status = Some(Status::Ok);
        response.headers.set(ContentType::json());

        Ok(response)
    });

    router
}<commit_msg>Set CORS header<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 db::{ Db, FindFilter, Record };
use iron::headers::{ AccessControlAllowOrigin, ContentType };
use iron::prelude::*;
use iron::status::Status;
use params::{ Map, Params, Value };
use router::Router;
use std::error::Error;
use std::fmt::{self, Debug};
use std::time::{ SystemTime, UNIX_EPOCH };

#[derive(Debug)]
struct StringError(String);

impl fmt::Display for StringError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(self, f)
    }
}

impl Error for StringError {
    fn description(&self) -> &str { &*self.0 }
}

fn seconds_from_epoch() -> i64 {
    let now = SystemTime::now();
    now.duration_from_earlier(UNIX_EPOCH).unwrap().as_secs() as i64
}

pub fn create() -> Router {
    let mut router = Router::new();
    router.get("register", move |req: &mut Request| -> IronResult<Response> {
        // Get the local ip from the query, and the public one from the socket.
        let public_ip = format!("{}", req.remote_addr.ip());

        let map: &Map = req.get_ref::<Params>().unwrap();
        let ip_param = match map.find(&["ip"]) {
            Some(&Value::String(ref name)) => Some(name),
            _ => None
        };

        if ip_param == None {
            return Err(IronError::new(StringError("Error".to_string()), Status::BadRequest));
        }
        let local_ip = ip_param.unwrap().to_string();

        // Get the current number of seconds since epoch.
        let now = seconds_from_epoch();

        info!("GET /register public_ip={} local_ip={} time is {}",
              public_ip, local_ip, now);

        // Save this registration in the database.
        // If we already have the same (local, public) tuple, update it, if not
        // create a new tuple.
        let db = Db::new();
        match db.find(FindFilter::PublicAndLocalIp(public_ip.clone(), local_ip.clone())) {
            Ok(rvect) => {
                // If the vector is empty, create a new record, if not update
                // the existing one with the new timestamp.
                let record = Record {
                    public_ip: public_ip,
                    local_ip: local_ip,
                    timestamp: now,
                };

                if rvect.is_empty() {
                    db.add(record).unwrap();
                } else {
                    db.update(record).unwrap();
                }
            },
            Err(_) => {
                let record = Record {
                    public_ip: public_ip,
                    local_ip: local_ip,
                    timestamp: now,
                };
                db.add(record).unwrap();
            }
        }

        let mut response = Response::with("{\"status\" : \"registered\"}");
        response.status = Some(Status::Ok);
        response.headers.set(AccessControlAllowOrigin::Any);
        response.headers.set(ContentType::json());

        Ok(response)
    });

    router.get("ping", move |req: &mut Request| -> IronResult<Response> {
        info!("GET /ping");
        let public_ip = format!("{}", req.remote_addr.ip());

        let mut serialized = String::from("[");

        let db = Db::new();
        match db.find(FindFilter::PublicIp(public_ip)) {
            Ok(rvect) => {
                // Serialize the vector.
                for record in rvect {
                    serialized.push_str(&record.to_json());
                }
            },
            Err(_) => { }
        }

        serialized.push_str("]");
        let mut response = Response::with(serialized);
        //let mut response = Response::with("ok");
        response.status = Some(Status::Ok);
        response.headers.set(AccessControlAllowOrigin::Any);
        response.headers.set(ContentType::json());

        Ok(response)
    });

    router
}<|endoftext|>


<commit_before><commit_msg>fix: check vector length<commit_after><|endoftext|>


<commit_before><commit_msg>docs: document associated types<commit_after><|endoftext|>


<commit_before><commit_msg>Derive standard traits for nat enums<commit_after><|endoftext|>


<commit_before><commit_msg>color and mutable values in hashtables<commit_after><|endoftext|>


<commit_before><commit_msg>Fix becnhmarks<commit_after><|endoftext|>


<commit_before><commit_msg>new test which features conflicting variance requirements<commit_after>fn main() {

    // Note: here we do not have any type annotations
    // but we do express conflicting requirements:

    let v = [mut [0]];
    let w = [mut [mut 0]];
    let x = [mut [mut 0]];

    fn f(&&v: [mut [int]]) {
        v[0] = [3]
    }

    fn g(&&v: [const [const int]]) {
    }

    fn h(&&v: [mut [mut int]]) {
        v[0] = [mut 3]
    }

    fn i(&&v: [mut [const int]]) {
        v[0] = [mut 3]
    }

    fn j(&&v: [[const int]]) {
    }

    f(v);
    g(v);
    h(v); //! ERROR (values differ in mutability)
    i(v); //! ERROR (values differ in mutability)
    j(v); //! ERROR (values differ in mutability)

    f(w); //! ERROR (values differ in mutability)
    g(w);
    h(w);
    i(w); //! ERROR (values differ in mutability)
    j(w); //! ERROR (values differ in mutability)

    // Note that without adding f() or h() to the mix, it is valid for
    // x to have the type [mut [const int]], and thus we can safely
    // call g() and i() but not j():
    g(x);
    i(x);
    j(x); //! ERROR (values differ in mutability)
}
<|endoftext|>


<commit_before>#![warn(rust_2018_idioms)] // while we're getting used to 2018
#![allow(clippy::all)]

use cargo::util::toml::StringOrVec;
use cargo::util::CliError;
use cargo::util::{self, closest_msg, command_prelude, CargoResult, CliResult, Config};
use cargo_util::{ProcessBuilder, ProcessError};
use std::collections::BTreeMap;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};

mod cli;
mod commands;

use crate::command_prelude::*;

fn main() {
    #[cfg(feature = "pretty-env-logger")]
    pretty_env_logger::init_custom_env("CARGO_LOG");
    #[cfg(not(feature = "pretty-env-logger"))]
    env_logger::init_from_env("CARGO_LOG");

    let mut config = cli::LazyConfig::new();

    let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
        cargo::ops::fix_exec_rustc(config.get(), &lock_addr).map_err(|e| CliError::from(e))
    } else {
        let _token = cargo::util::job::setup();
        cli::main(&mut config)
    };

    match result {
        Err(e) => cargo::exit_with_error(e, &mut config.get_mut().shell()),
        Ok(()) => {}
    }
}

/// Table for defining the aliases which come builtin in `Cargo`.
/// The contents are structured as: `(alias, aliased_command, description)`.
const BUILTIN_ALIASES: [(&str, &str, &str); 5] = [
    ("b", "build", "alias: build"),
    ("c", "check", "alias: check"),
    ("d", "doc", "alias: doc"),
    ("r", "run", "alias: run"),
    ("t", "test", "alias: test"),
];

/// Function which contains the list of all of the builtin aliases and it's
/// corresponding execs represented as &str.
fn builtin_aliases_execs(cmd: &str) -> Option<&(&str, &str, &str)> {
    BUILTIN_ALIASES.iter().find(|alias| alias.0 == cmd)
}

fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
    let alias_name = format!("alias.{}", command);
    let user_alias = match config.get_string(&alias_name) {
        Ok(Some(record)) => Some(
            record
                .val
                .split_whitespace()
                .map(|s| s.to_string())
                .collect(),
        ),
        Ok(None) => None,
        Err(_) => config.get::<Option<Vec<String>>>(&alias_name)?,
    };

    let result = user_alias.or_else(|| {
        builtin_aliases_execs(command).map(|command_str| vec![command_str.1.to_string()])
    });
    Ok(result)
}

/// List all runnable commands
fn list_commands(config: &Config) -> BTreeMap<String, CommandInfo> {
    let prefix = "cargo-";
    let suffix = env::consts::EXE_SUFFIX;
    let mut commands = BTreeMap::new();
    for dir in search_directories(config) {
        let entries = match fs::read_dir(dir) {
            Ok(entries) => entries,
            _ => continue,
        };
        for entry in entries.filter_map(|e| e.ok()) {
            let path = entry.path();
            let filename = match path.file_name().and_then(|s| s.to_str()) {
                Some(filename) => filename,
                _ => continue,
            };
            if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
                continue;
            }
            if is_executable(entry.path()) {
                let end = filename.len() - suffix.len();
                commands.insert(
                    filename[prefix.len()..end].to_string(),
                    CommandInfo::External { path: path.clone() },
                );
            }
        }
    }

    for cmd in commands::builtin() {
        commands.insert(
            cmd.get_name().to_string(),
            CommandInfo::BuiltIn {
                about: cmd.get_about().map(|s| s.to_string()),
            },
        );
    }

    // Add the builtin_aliases and them descriptions to the
    // `commands` `BTreeMap`.
    for command in &BUILTIN_ALIASES {
        commands.insert(
            command.0.to_string(),
            CommandInfo::BuiltIn {
                about: Some(command.2.to_string()),
            },
        );
    }

    // Add the user-defined aliases
    if let Ok(aliases) = config.get::<BTreeMap<String, StringOrVec>>("alias") {
        for (name, target) in aliases.iter() {
            commands.insert(
                name.to_string(),
                CommandInfo::Alias {
                    target: target.clone(),
                },
            );
        }
    }

    // `help` is special, so it needs to be inserted separately.
    commands.insert(
        "help".to_string(),
        CommandInfo::BuiltIn {
            about: Some("Displays help for a cargo subcommand".to_string()),
        },
    );

    commands
}

fn find_external_subcommand(config: &Config, cmd: &str) -> Option<PathBuf> {
    let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
    search_directories(config)
        .iter()
        .map(|dir| dir.join(&command_exe))
        .find(|file| is_executable(file))
}

fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&OsStr]) -> CliResult {
    let path = find_external_subcommand(config, cmd);
    let command = match path {
        Some(command) => command,
        None => {
            let err = if cmd.starts_with('+') {
                anyhow::format_err!(
                    "no such subcommand: `{}`\n\n\t\
                    Cargo does not handle `+toolchain` directives.\n\t\
                    Did you mean to invoke `cargo` through `rustup` instead?",
                    cmd
                )
            } else {
                let suggestions = list_commands(config);
                let did_you_mean = closest_msg(cmd, suggestions.keys(), |c| c);

                anyhow::format_err!(
                    "no such subcommand: `{}`{}\n\n\t\
                    View all installed commands with `cargo --list`",
                    cmd,
                    did_you_mean
                )
            };

            return Err(CliError::new(err, 101));
        }
    };

    let cargo_exe = config.cargo_exe()?;
    let mut cmd = ProcessBuilder::new(&command);
    cmd.env(cargo::CARGO_ENV, cargo_exe).args(args);
    if let Some(client) = config.jobserver_from_env() {
        cmd.inherit_jobserver(client);
    }
    let err = match cmd.exec_replace() {
        Ok(()) => return Ok(()),
        Err(e) => e,
    };

    if let Some(perr) = err.downcast_ref::<ProcessError>() {
        if let Some(code) = perr.code {
            return Err(CliError::code(code));
        }
    }
    Err(CliError::new(err, 101))
}

#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path)
        .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
        .unwrap_or(false)
}
#[cfg(windows)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    path.as_ref().is_file()
}

fn search_directories(config: &Config) -> Vec<PathBuf> {
    let mut path_dirs = if let Some(val) = env::var_os("PATH") {
        env::split_paths(&val).collect()
    } else {
        vec![]
    };

    let home_bin = config.home().clone().into_path_unlocked().join("bin");

    // If any of that PATH elements contains `home_bin`, do not
    // add it again. This is so that the users can control priority
    // of it using PATH, while preserving the historical
    // behavior of preferring it over system global directories even
    // when not in PATH at all.
    // See https://github.com/rust-lang/cargo/issues/11020 for details.
    //
    // Note: `p == home_bin` will ignore trailing slash, but we don't
    // `canonicalize` the paths.
    if !path_dirs.iter().any(|p| p == &home_bin) {
        path_dirs.insert(0, home_bin);
    };

    path_dirs
}

fn init_git_transports(config: &Config) {
    // Only use a custom transport if any HTTP options are specified,
    // such as proxies or custom certificate authorities. The custom
    // transport, however, is not as well battle-tested.

    match cargo::ops::needs_custom_http_transport(config) {
        Ok(true) => {}
        _ => return,
    }

    let handle = match cargo::ops::http_handle(config) {
        Ok(handle) => handle,
        Err(..) => return,
    };

    // The unsafety of the registration function derives from two aspects:
    //
    // 1. This call must be synchronized with all other registration calls as
    //    well as construction of new transports.
    // 2. The argument is leaked.
    //
    // We're clear on point (1) because this is only called at the start of this
    // binary (we know what the state of the world looks like) and we're mostly
    // clear on point (2) because we'd only free it after everything is done
    // anyway
    unsafe {
        git2_curl::register(handle);
    }

    // Disabling the owner validation in git can, in theory, lead to code execution
    // vulnerabilities. However, libgit2 does not launch executables, which is the foundation of
    // the original security issue. Meanwhile, issues with refusing to load git repos in
    // `CARGO_HOME` for example will likely be very frustrating for users. So, we disable the
    // validation.
    //
    // For further discussion of Cargo's current interactions with git, see
    //
    //   https://github.com/rust-lang/rfcs/pull/3279
    //
    // and in particular the subsection on "Git support".
    //
    // Note that we only disable this when Cargo is run as a binary. If Cargo is used as a library,
    // this code won't be invoked. Instead, developers will need to explicitly disable the
    // validation in their code. This is inconvenient, but won't accidentally open consuming
    // applications up to security issues if they use git2 to open repositories elsewhere in their
    // code.
    unsafe {
        if git2::opts::set_verify_owner_validation(false).is_err() {
            return;
        }
    }
}
<commit_msg>doc: rustdoc for `aliased_command`<commit_after>#![warn(rust_2018_idioms)] // while we're getting used to 2018
#![allow(clippy::all)]

use cargo::util::toml::StringOrVec;
use cargo::util::CliError;
use cargo::util::{self, closest_msg, command_prelude, CargoResult, CliResult, Config};
use cargo_util::{ProcessBuilder, ProcessError};
use std::collections::BTreeMap;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};

mod cli;
mod commands;

use crate::command_prelude::*;

fn main() {
    #[cfg(feature = "pretty-env-logger")]
    pretty_env_logger::init_custom_env("CARGO_LOG");
    #[cfg(not(feature = "pretty-env-logger"))]
    env_logger::init_from_env("CARGO_LOG");

    let mut config = cli::LazyConfig::new();

    let result = if let Some(lock_addr) = cargo::ops::fix_get_proxy_lock_addr() {
        cargo::ops::fix_exec_rustc(config.get(), &lock_addr).map_err(|e| CliError::from(e))
    } else {
        let _token = cargo::util::job::setup();
        cli::main(&mut config)
    };

    match result {
        Err(e) => cargo::exit_with_error(e, &mut config.get_mut().shell()),
        Ok(()) => {}
    }
}

/// Table for defining the aliases which come builtin in `Cargo`.
/// The contents are structured as: `(alias, aliased_command, description)`.
const BUILTIN_ALIASES: [(&str, &str, &str); 5] = [
    ("b", "build", "alias: build"),
    ("c", "check", "alias: check"),
    ("d", "doc", "alias: doc"),
    ("r", "run", "alias: run"),
    ("t", "test", "alias: test"),
];

/// Function which contains the list of all of the builtin aliases and it's
/// corresponding execs represented as &str.
fn builtin_aliases_execs(cmd: &str) -> Option<&(&str, &str, &str)> {
    BUILTIN_ALIASES.iter().find(|alias| alias.0 == cmd)
}

/// Resolve the aliased command from the [`Config`] with a given command string.
///
/// The search fallback chain is:
///
/// 1. Get the aliased command as a string.
/// 2. If an `Err` occurs (missing key, type mismatch, or any possible error),
///    try to get it as an array again.
/// 3. If still cannot find any, finds one insides [`BUILTIN_ALIASES`].
fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
    let alias_name = format!("alias.{}", command);
    let user_alias = match config.get_string(&alias_name) {
        Ok(Some(record)) => Some(
            record
                .val
                .split_whitespace()
                .map(|s| s.to_string())
                .collect(),
        ),
        Ok(None) => None,
        Err(_) => config.get::<Option<Vec<String>>>(&alias_name)?,
    };

    let result = user_alias.or_else(|| {
        builtin_aliases_execs(command).map(|command_str| vec![command_str.1.to_string()])
    });
    Ok(result)
}

/// List all runnable commands
fn list_commands(config: &Config) -> BTreeMap<String, CommandInfo> {
    let prefix = "cargo-";
    let suffix = env::consts::EXE_SUFFIX;
    let mut commands = BTreeMap::new();
    for dir in search_directories(config) {
        let entries = match fs::read_dir(dir) {
            Ok(entries) => entries,
            _ => continue,
        };
        for entry in entries.filter_map(|e| e.ok()) {
            let path = entry.path();
            let filename = match path.file_name().and_then(|s| s.to_str()) {
                Some(filename) => filename,
                _ => continue,
            };
            if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
                continue;
            }
            if is_executable(entry.path()) {
                let end = filename.len() - suffix.len();
                commands.insert(
                    filename[prefix.len()..end].to_string(),
                    CommandInfo::External { path: path.clone() },
                );
            }
        }
    }

    for cmd in commands::builtin() {
        commands.insert(
            cmd.get_name().to_string(),
            CommandInfo::BuiltIn {
                about: cmd.get_about().map(|s| s.to_string()),
            },
        );
    }

    // Add the builtin_aliases and them descriptions to the
    // `commands` `BTreeMap`.
    for command in &BUILTIN_ALIASES {
        commands.insert(
            command.0.to_string(),
            CommandInfo::BuiltIn {
                about: Some(command.2.to_string()),
            },
        );
    }

    // Add the user-defined aliases
    if let Ok(aliases) = config.get::<BTreeMap<String, StringOrVec>>("alias") {
        for (name, target) in aliases.iter() {
            commands.insert(
                name.to_string(),
                CommandInfo::Alias {
                    target: target.clone(),
                },
            );
        }
    }

    // `help` is special, so it needs to be inserted separately.
    commands.insert(
        "help".to_string(),
        CommandInfo::BuiltIn {
            about: Some("Displays help for a cargo subcommand".to_string()),
        },
    );

    commands
}

fn find_external_subcommand(config: &Config, cmd: &str) -> Option<PathBuf> {
    let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
    search_directories(config)
        .iter()
        .map(|dir| dir.join(&command_exe))
        .find(|file| is_executable(file))
}

fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&OsStr]) -> CliResult {
    let path = find_external_subcommand(config, cmd);
    let command = match path {
        Some(command) => command,
        None => {
            let err = if cmd.starts_with('+') {
                anyhow::format_err!(
                    "no such subcommand: `{}`\n\n\t\
                    Cargo does not handle `+toolchain` directives.\n\t\
                    Did you mean to invoke `cargo` through `rustup` instead?",
                    cmd
                )
            } else {
                let suggestions = list_commands(config);
                let did_you_mean = closest_msg(cmd, suggestions.keys(), |c| c);

                anyhow::format_err!(
                    "no such subcommand: `{}`{}\n\n\t\
                    View all installed commands with `cargo --list`",
                    cmd,
                    did_you_mean
                )
            };

            return Err(CliError::new(err, 101));
        }
    };

    let cargo_exe = config.cargo_exe()?;
    let mut cmd = ProcessBuilder::new(&command);
    cmd.env(cargo::CARGO_ENV, cargo_exe).args(args);
    if let Some(client) = config.jobserver_from_env() {
        cmd.inherit_jobserver(client);
    }
    let err = match cmd.exec_replace() {
        Ok(()) => return Ok(()),
        Err(e) => e,
    };

    if let Some(perr) = err.downcast_ref::<ProcessError>() {
        if let Some(code) = perr.code {
            return Err(CliError::code(code));
        }
    }
    Err(CliError::new(err, 101))
}

#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path)
        .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
        .unwrap_or(false)
}
#[cfg(windows)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
    path.as_ref().is_file()
}

fn search_directories(config: &Config) -> Vec<PathBuf> {
    let mut path_dirs = if let Some(val) = env::var_os("PATH") {
        env::split_paths(&val).collect()
    } else {
        vec![]
    };

    let home_bin = config.home().clone().into_path_unlocked().join("bin");

    // If any of that PATH elements contains `home_bin`, do not
    // add it again. This is so that the users can control priority
    // of it using PATH, while preserving the historical
    // behavior of preferring it over system global directories even
    // when not in PATH at all.
    // See https://github.com/rust-lang/cargo/issues/11020 for details.
    //
    // Note: `p == home_bin` will ignore trailing slash, but we don't
    // `canonicalize` the paths.
    if !path_dirs.iter().any(|p| p == &home_bin) {
        path_dirs.insert(0, home_bin);
    };

    path_dirs
}

fn init_git_transports(config: &Config) {
    // Only use a custom transport if any HTTP options are specified,
    // such as proxies or custom certificate authorities. The custom
    // transport, however, is not as well battle-tested.

    match cargo::ops::needs_custom_http_transport(config) {
        Ok(true) => {}
        _ => return,
    }

    let handle = match cargo::ops::http_handle(config) {
        Ok(handle) => handle,
        Err(..) => return,
    };

    // The unsafety of the registration function derives from two aspects:
    //
    // 1. This call must be synchronized with all other registration calls as
    //    well as construction of new transports.
    // 2. The argument is leaked.
    //
    // We're clear on point (1) because this is only called at the start of this
    // binary (we know what the state of the world looks like) and we're mostly
    // clear on point (2) because we'd only free it after everything is done
    // anyway
    unsafe {
        git2_curl::register(handle);
    }

    // Disabling the owner validation in git can, in theory, lead to code execution
    // vulnerabilities. However, libgit2 does not launch executables, which is the foundation of
    // the original security issue. Meanwhile, issues with refusing to load git repos in
    // `CARGO_HOME` for example will likely be very frustrating for users. So, we disable the
    // validation.
    //
    // For further discussion of Cargo's current interactions with git, see
    //
    //   https://github.com/rust-lang/rfcs/pull/3279
    //
    // and in particular the subsection on "Git support".
    //
    // Note that we only disable this when Cargo is run as a binary. If Cargo is used as a library,
    // this code won't be invoked. Instead, developers will need to explicitly disable the
    // validation in their code. This is inconvenient, but won't accidentally open consuming
    // applications up to security issues if they use git2 to open repositories elsewhere in their
    // code.
    unsafe {
        if git2::opts::set_verify_owner_validation(false).is_err() {
            return;
        }
    }
}
<|endoftext|>


<commit_before>use common::memory;

use core::mem::size_of;
use core::u32;

use drivers::mmio::Mmio;

use super::fis::{FIS_TYPE_REG_H2D, FisRegH2D};

const ATA_CMD_READ_DMA_EXT: u8 = 0x25;
const ATA_DEV_BUSY: u8 = 0x80;
const ATA_DEV_DRQ: u8 = 0x08;

const HBA_PxCMD_CR: u32 = 1 << 15;
const HBA_PxCMD_FR: u32 = 1 << 14;
const HBA_PxCMD_FRE: u32 = 1 << 4;
const HBA_PxCMD_ST: u32 = 1;
const HBA_PxIS_TFES: u32 = 1 << 30;
const HBA_SSTS_PRESENT: u32 = 0x13;
const HBA_SIG_ATA: u32 = 0x00000101;
const HBA_SIG_ATAPI: u32 = 0xEB140101;
const HBA_SIG_PM: u32 = 0x96690101;
const HBA_SIG_SEMB: u32 = 0xC33C0101;

#[derive(Debug)]
pub enum HbaPortType {
    None,
    Unknown(u32),
    SATA,
    SATAPI,
    PM,
    SEMB,
}

#[repr(packed)]
pub struct HbaPort {
    pub clb: Mmio<u64>,   // 0x00, command list base address, 1K-byte aligned
    pub fb: Mmio<u64>,    // 0x08, FIS base address, 256-byte aligned
    pub is: Mmio<u32>,    // 0x10, interrupt status
    pub ie: Mmio<u32>,    // 0x14, interrupt enable
    pub cmd: Mmio<u32>,   // 0x18, command and status
    pub rsv0: Mmio<u32>,  // 0x1C, Reserved
    pub tfd: Mmio<u32>,   // 0x20, task file data
    pub sig: Mmio<u32>,   // 0x24, signature
    pub ssts: Mmio<u32>,  // 0x28, SATA status (SCR0:SStatus)
    pub sctl: Mmio<u32>,  // 0x2C, SATA control (SCR2:SControl)
    pub serr: Mmio<u32>,  // 0x30, SATA error (SCR1:SError)
    pub sact: Mmio<u32>,  // 0x34, SATA active (SCR3:SActive)
    pub ci: Mmio<u32>,    // 0x38, command issue
    pub sntf: Mmio<u32>,  // 0x3C, SATA notification (SCR4:SNotification)
    pub fbs: Mmio<u32>,   // 0x40, FIS-based switch control
    pub rsv1: [Mmio<u32>; 11],    // 0x44 ~ 0x6F, Reserved
    pub vendor: [Mmio<u32>; 4]    // 0x70 ~ 0x7F, vendor specific
}

impl HbaPort {
    pub fn probe(&self) -> HbaPortType {
        if self.ssts.readf(HBA_SSTS_PRESENT) {
            let sig = self.sig.read();
            match sig {
                HBA_SIG_ATA => HbaPortType::SATA,
                HBA_SIG_ATAPI => HbaPortType::SATAPI,
                HBA_SIG_PM => HbaPortType::PM,
                HBA_SIG_SEMB => HbaPortType::SEMB,
                _ => HbaPortType::Unknown(sig)
            }
        } else {
            HbaPortType::None
        }
    }

    pub fn init(&mut self) {
        self.stop();

        debugln!("Port Command List");
        let clb = unsafe { memory::alloc_aligned(size_of::<HbaCmdHeader>(), 1024) };
        self.clb.write(clb as u64);

        debugln!("Port FIS");
        let fb = unsafe { memory::alloc_aligned(256, 256) };
        self.fb.write(fb as u64);

        for i in 0..32 {
            debugln!("Port Command Table {}", i);
            let cmdheader = unsafe { &mut * (clb as *mut HbaCmdHeader).offset(i) };
            let ctba = unsafe { memory::alloc_aligned(256, 256) };
            cmdheader.ctba.write(ctba as u64);
            cmdheader.prdtl.write(8);
        }

        self.start();
    }

    pub fn start(&mut self) {
        debugln!("Starting port");

        while self.cmd.readf(HBA_PxCMD_CR) {}

        self.cmd.writef(HBA_PxCMD_FRE, true);
        self.cmd.writef(HBA_PxCMD_ST, true);
    }

    pub fn stop(&mut self) {
        debugln!("Stopping port");

    	self.cmd.writef(HBA_PxCMD_ST, false);

    	while self.cmd.readf(HBA_PxCMD_FR | HBA_PxCMD_CR) {}

    	self.cmd.writef(HBA_PxCMD_FRE, false);
    }

    pub fn slot(&self) -> Option<u32> {
        let slots = self.sact.read() | self.ci.read();
        for i in 0..32 {
            if slots & 1 << i == 0 {
                return Some(i);
            }
        }
        None
    }

    pub fn read(&mut self, lba: u64, buf: usize, len: usize) -> bool {
        let sectors = len/512;
        let entries = 1;

        debugln!("LBA: {:X} BUF: {:X}, SECTORS: {}", lba, buf, sectors);

        self.is.write(u32::MAX);

        if let Some(slot) = self.slot() {
            debugln!("Slot {}", slot);

            let clb = self.clb.read() as usize;
            let cmdheader = unsafe { &mut * (clb as *mut HbaCmdHeader).offset(slot as isize) };

            cmdheader.cfl.write(((size_of::<FisRegH2D>()/size_of::<u32>()) as u8) << 3);
            cmdheader.prdtl.write(entries);

            let ctba = cmdheader.ctba.read() as usize;
            unsafe { ::memset(ctba as *mut u8, 0, size_of::<HbaCmdTable>()) };
            let cmdtbl = unsafe { &mut * (ctba as *mut HbaCmdTable) };

            let prdt_entry = &mut cmdtbl.prdt_entry[0];
            prdt_entry.dba.write(buf as u64);
            prdt_entry.dbc.write(((sectors * 512) as u32) << 10 | 1);

            let cmdfis = unsafe { &mut * (cmdtbl.cfis.as_ptr() as *mut FisRegH2D) };

            cmdfis.fis_type.write(FIS_TYPE_REG_H2D);
            cmdfis.pm.writef(1, true);
            cmdfis.command.write(ATA_CMD_READ_DMA_EXT);

            cmdfis.lba0.write(lba as u8);
            cmdfis.lba1.write((lba >> 8) as u8);
            cmdfis.lba2.write((lba >> 16) as u8);

            cmdfis.device.write(1 << 6);

            cmdfis.lba3.write((lba >> 24) as u8);
            cmdfis.lba4.write((lba >> 32) as u8);
            cmdfis.lba5.write((lba >> 40) as u8);

            cmdfis.countl.write(sectors as u8);
            cmdfis.counth.write((sectors >> 8) as u8);

            debugln!("Busy Wait");
            while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {}

            self.ci.write(1 << slot);

            debugln!("Completion Wait");
            while self.ci.readf(1 << slot) {
                if self.is.readf(HBA_PxIS_TFES) {
        			debugln!("Read disk error");
        			return false;
        		}
            }

            debugln!("Return");

            if self.is.readf(HBA_PxIS_TFES) {
    			debugln!("Read disk error");
    			return false;
    		}

            return true;
        }

        false
    }
}

#[repr(packed)]
pub struct HbaMem {
    pub cap: Mmio<u32>,       // 0x00, Host capability
    pub ghc: Mmio<u32>,       // 0x04, Global host control
    pub is: Mmio<u32>,        // 0x08, Interrupt status
    pub pi: Mmio<u32>,        // 0x0C, Port implemented
    pub vs: Mmio<u32>,        // 0x10, Version
    pub ccc_ctl: Mmio<u32>,   // 0x14, Command completion coalescing control
    pub ccc_pts: Mmio<u32>,   // 0x18, Command completion coalescing ports
    pub em_loc: Mmio<u32>,    // 0x1C, Enclosure management location
    pub em_ctl: Mmio<u32>,    // 0x20, Enclosure management control
    pub cap2: Mmio<u32>,      // 0x24, Host capabilities extended
    pub bohc: Mmio<u32>,      // 0x28, BIOS/OS handoff control and status
    pub rsv: [Mmio<u8>; 116],         // 0x2C - 0x9F, Reserved
    pub vendor: [Mmio<u8>; 96],       // 0xA0 - 0xFF, Vendor specific registers
    pub ports: [HbaPort; 32]    // 0x100 - 0x10FF, Port control registers
}

#[repr(packed)]
struct HbaPrdtEntry {
   dba: Mmio<u64>,		// Data base address
   rsv0: Mmio<u32>,		// Reserved
   dbc: Mmio<u32>,		// Byte count, 4M max, interrupt = 1
}

#[repr(packed)]
struct HbaCmdTable {
	// 0x00
	cfis: [Mmio<u8>; 64],	// Command FIS

	// 0x40
	acmd: [Mmio<u8>; 16],	// ATAPI command, 12 or 16 bytes

	// 0x50
	rsv: [Mmio<u8>; 48],	// Reserved

	// 0x80
	prdt_entry: [HbaPrdtEntry; 65536],	// Physical region descriptor table entries, 0 ~ 65535
}

#[repr(packed)]
struct HbaCmdHeader {
	// DW0
	cfl: Mmio<u8>,		    // Command FIS length in DWORDS, 2 ~ 16, atapi: 4, write - host to device: 2, prefetchable: 1
	pm: Mmio<u8>,		    // Reset - 0x80, bist: 0x40, clear busy on ok: 0x20, port multiplier

	prdtl: Mmio<u16>,		// Physical region descriptor table length in entries

	// DW1
	prdbc: Mmio<u32>,		// Physical region descriptor byte count transferred

	// DW2, 3
	ctba: Mmio<u64>,		// Command table descriptor base address

	// DW4 - 7
	rsv1: [Mmio<u32>; 4],	// Reserved
}
<commit_msg>Hooray data!<commit_after>use common::memory;

use core::mem::size_of;
use core::u32;

use drivers::mmio::Mmio;

use super::fis::{FIS_TYPE_REG_H2D, FisRegH2D};

const ATA_CMD_READ_DMA_EXT: u8 = 0x25;
const ATA_DEV_BUSY: u8 = 0x80;
const ATA_DEV_DRQ: u8 = 0x08;

const HBA_PxCMD_CR: u32 = 1 << 15;
const HBA_PxCMD_FR: u32 = 1 << 14;
const HBA_PxCMD_FRE: u32 = 1 << 4;
const HBA_PxCMD_ST: u32 = 1;
const HBA_PxIS_TFES: u32 = 1 << 30;
const HBA_SSTS_PRESENT: u32 = 0x13;
const HBA_SIG_ATA: u32 = 0x00000101;
const HBA_SIG_ATAPI: u32 = 0xEB140101;
const HBA_SIG_PM: u32 = 0x96690101;
const HBA_SIG_SEMB: u32 = 0xC33C0101;

#[derive(Debug)]
pub enum HbaPortType {
    None,
    Unknown(u32),
    SATA,
    SATAPI,
    PM,
    SEMB,
}

#[repr(packed)]
pub struct HbaPort {
    pub clb: Mmio<u64>,   // 0x00, command list base address, 1K-byte aligned
    pub fb: Mmio<u64>,    // 0x08, FIS base address, 256-byte aligned
    pub is: Mmio<u32>,    // 0x10, interrupt status
    pub ie: Mmio<u32>,    // 0x14, interrupt enable
    pub cmd: Mmio<u32>,   // 0x18, command and status
    pub rsv0: Mmio<u32>,  // 0x1C, Reserved
    pub tfd: Mmio<u32>,   // 0x20, task file data
    pub sig: Mmio<u32>,   // 0x24, signature
    pub ssts: Mmio<u32>,  // 0x28, SATA status (SCR0:SStatus)
    pub sctl: Mmio<u32>,  // 0x2C, SATA control (SCR2:SControl)
    pub serr: Mmio<u32>,  // 0x30, SATA error (SCR1:SError)
    pub sact: Mmio<u32>,  // 0x34, SATA active (SCR3:SActive)
    pub ci: Mmio<u32>,    // 0x38, command issue
    pub sntf: Mmio<u32>,  // 0x3C, SATA notification (SCR4:SNotification)
    pub fbs: Mmio<u32>,   // 0x40, FIS-based switch control
    pub rsv1: [Mmio<u32>; 11],    // 0x44 ~ 0x6F, Reserved
    pub vendor: [Mmio<u32>; 4]    // 0x70 ~ 0x7F, vendor specific
}

impl HbaPort {
    pub fn probe(&self) -> HbaPortType {
        if self.ssts.readf(HBA_SSTS_PRESENT) {
            let sig = self.sig.read();
            match sig {
                HBA_SIG_ATA => HbaPortType::SATA,
                HBA_SIG_ATAPI => HbaPortType::SATAPI,
                HBA_SIG_PM => HbaPortType::PM,
                HBA_SIG_SEMB => HbaPortType::SEMB,
                _ => HbaPortType::Unknown(sig)
            }
        } else {
            HbaPortType::None
        }
    }

    pub fn init(&mut self) {
        self.stop();

        debugln!("Port Command List");
        let clb = unsafe { memory::alloc_aligned(size_of::<HbaCmdHeader>(), 1024) };
        self.clb.write(clb as u64);

        debugln!("Port FIS");
        let fb = unsafe { memory::alloc_aligned(256, 256) };
        self.fb.write(fb as u64);

        for i in 0..32 {
            debugln!("Port Command Table {}", i);
            let cmdheader = unsafe { &mut * (clb as *mut HbaCmdHeader).offset(i) };
            let ctba = unsafe { memory::alloc_aligned(256, 256) };
            cmdheader.ctba.write(ctba as u64);
            cmdheader.prdtl.write(8);
        }

        self.start();
    }

    pub fn start(&mut self) {
        debugln!("Starting port");

        while self.cmd.readf(HBA_PxCMD_CR) {}

        self.cmd.writef(HBA_PxCMD_FRE, true);
        self.cmd.writef(HBA_PxCMD_ST, true);
    }

    pub fn stop(&mut self) {
        debugln!("Stopping port");

    	self.cmd.writef(HBA_PxCMD_ST, false);

    	while self.cmd.readf(HBA_PxCMD_FR | HBA_PxCMD_CR) {}

    	self.cmd.writef(HBA_PxCMD_FRE, false);
    }

    pub fn slot(&self) -> Option<u32> {
        let slots = self.sact.read() | self.ci.read();
        for i in 0..32 {
            if slots & 1 << i == 0 {
                return Some(i);
            }
        }
        None
    }

    pub fn read(&mut self, lba: u64, buf: usize, len: usize) -> bool {
        let sectors = len/512;
        let entries = 1;

        debugln!("LBA: {:X} BUF: {:X} SECTORS: {}", lba, buf, sectors);

        self.is.write(u32::MAX);

        if let Some(slot) = self.slot() {
            debugln!("Slot {}", slot);

            let clb = self.clb.read() as usize;
            let cmdheader = unsafe { &mut * (clb as *mut HbaCmdHeader).offset(slot as isize) };

            cmdheader.cfl.write(((size_of::<FisRegH2D>()/size_of::<u32>()) as u8));
            cmdheader.prdtl.write(entries);

            let ctba = cmdheader.ctba.read() as usize;
            unsafe { ::memset(ctba as *mut u8, 0, size_of::<HbaCmdTable>()) };
            let cmdtbl = unsafe { &mut * (ctba as *mut HbaCmdTable) };

            let prdt_entry = &mut cmdtbl.prdt_entry[0];
            prdt_entry.dba.write(buf as u64);
            prdt_entry.dbc.write(((sectors * 512) as u32) | 1);

            let cmdfis = unsafe { &mut * (cmdtbl.cfis.as_ptr() as *mut FisRegH2D) };

            cmdfis.fis_type.write(FIS_TYPE_REG_H2D);
            cmdfis.pm.write(1 << 7);
            cmdfis.command.write(ATA_CMD_READ_DMA_EXT);

            cmdfis.lba0.write(lba as u8);
            cmdfis.lba1.write((lba >> 8) as u8);
            cmdfis.lba2.write((lba >> 16) as u8);

            cmdfis.device.write(1 << 6);

            cmdfis.lba3.write((lba >> 24) as u8);
            cmdfis.lba4.write((lba >> 32) as u8);
            cmdfis.lba5.write((lba >> 40) as u8);

            cmdfis.countl.write(sectors as u8);
            cmdfis.counth.write((sectors >> 8) as u8);

            debugln!("Busy Wait");
            while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {}

            self.ci.write(1 << slot);

            debugln!("Completion Wait");
            while self.ci.readf(1 << slot) {
                if self.is.readf(HBA_PxIS_TFES) {
        			debugln!("Read disk error");
        			return false;
        		}
            }

            debugln!("Return");

            if self.is.readf(HBA_PxIS_TFES) {
    			debugln!("Read disk error");
    			return false;
    		}

            return true;
        }

        false
    }
}

#[repr(packed)]
pub struct HbaMem {
    pub cap: Mmio<u32>,       // 0x00, Host capability
    pub ghc: Mmio<u32>,       // 0x04, Global host control
    pub is: Mmio<u32>,        // 0x08, Interrupt status
    pub pi: Mmio<u32>,        // 0x0C, Port implemented
    pub vs: Mmio<u32>,        // 0x10, Version
    pub ccc_ctl: Mmio<u32>,   // 0x14, Command completion coalescing control
    pub ccc_pts: Mmio<u32>,   // 0x18, Command completion coalescing ports
    pub em_loc: Mmio<u32>,    // 0x1C, Enclosure management location
    pub em_ctl: Mmio<u32>,    // 0x20, Enclosure management control
    pub cap2: Mmio<u32>,      // 0x24, Host capabilities extended
    pub bohc: Mmio<u32>,      // 0x28, BIOS/OS handoff control and status
    pub rsv: [Mmio<u8>; 116],         // 0x2C - 0x9F, Reserved
    pub vendor: [Mmio<u8>; 96],       // 0xA0 - 0xFF, Vendor specific registers
    pub ports: [HbaPort; 32]    // 0x100 - 0x10FF, Port control registers
}

#[repr(packed)]
struct HbaPrdtEntry {
   dba: Mmio<u64>,		// Data base address
   rsv0: Mmio<u32>,		// Reserved
   dbc: Mmio<u32>,		// Byte count, 4M max, interrupt = 1
}

#[repr(packed)]
struct HbaCmdTable {
	// 0x00
	cfis: [Mmio<u8>; 64],	// Command FIS

	// 0x40
	acmd: [Mmio<u8>; 16],	// ATAPI command, 12 or 16 bytes

	// 0x50
	rsv: [Mmio<u8>; 48],	// Reserved

	// 0x80
	prdt_entry: [HbaPrdtEntry; 65536],	// Physical region descriptor table entries, 0 ~ 65535
}

#[repr(packed)]
struct HbaCmdHeader {
	// DW0
	cfl: Mmio<u8>,		    // Command FIS length in DWORDS, 2 ~ 16, atapi: 4, write - host to device: 2, prefetchable: 1
	pm: Mmio<u8>,		    // Reset - 0x80, bist: 0x40, clear busy on ok: 0x20, port multiplier

	prdtl: Mmio<u16>,		// Physical region descriptor table length in entries

	// DW1
	prdbc: Mmio<u32>,		// Physical region descriptor byte count transferred

	// DW2, 3
	ctba: Mmio<u64>,		// Command table descriptor base address

	// DW4 - 7
	rsv1: [Mmio<u32>; 4],	// Reserved
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::io::BufRead;
use std::result::Result as RResult;

use toml::Value;
use uuid::Uuid;

use task_hookrs::task::Task as TTask;
use task_hookrs::import::{import_task, import_tasks};

use libimagstore::store::{FileLockEntry, Store};
use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId};
use module_path::ModuleEntryPath;

use error::{TodoError, TodoErrorKind, MapErrInto};
use result::Result;

/// Task struct containing a `FileLockEntry`
#[derive(Debug)]
pub struct Task<'a>(FileLockEntry<'a>);

impl<'a> Task<'a> {

    /// Concstructs a new `Task` with a `FileLockEntry`
    pub fn new(fle: FileLockEntry<'a>) -> Task<'a> {
        Task(fle)
    }

    pub fn import<R: BufRead>(store: &'a Store, mut r: R) -> Result<(Task<'a>, Uuid)> {
        let mut line = String::new();
        r.read_line(&mut line);
        import_task(&line.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .and_then(|t| {
                let uuid = t.uuid().clone();
                t.into_task(store).map(|t| (t, uuid))
            })
    }

    /// Get a task from an import string. That is: read the imported string, get the UUID from it
    /// and try to load this UUID from store.
    ///
    /// Possible return values are:
    ///
    /// * Ok(Ok(Task))
    /// * Ok(Err(String)) - where the String is the String read from the `r` parameter
    /// * Err(_)          - where the error is an error that happened during evaluation
    ///
    pub fn get_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<RResult<Task<'a>, String>>
    {
        unimplemented!()
    }

    /// Get a task from a String. The String is expected to contain the JSON-representation of the
    /// Task to get from the store (only the UUID really matters in this case)
    ///
    /// For an explanation on the return values see `Task::get_from_import()`.
    pub fn get_from_string(store: &'a Store, s: String) -> Result<RResult<Task<'a>, String>> {
        unimplemented!()
    }

    /// Get a task from an UUID.
    ///
    /// If there is no task with this UUID, this returns `Ok(None)`.
    pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result<Option<Task<'a>>> {
        unimplemented!()
    }

    /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to
    /// implicitely create the task if it does not exist.
    pub fn retrieve_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<Task<'a>> {
        unimplemented!()
    }

    /// Retrieve a task from a String. The String is expected to contain the JSON-representation of
    /// the Task to retrieve from the store (only the UUID really matters in this case)
    pub fn retrieve_from_string(store: &'a Store, s: String) -> Result<Task<'a>> {
        unimplemented!()
    }

    pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> {
        store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid())
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all_as_ids(store: &Store) -> Result<StoreIdIterator> {
        store.retrieve_for_module("todo/taskwarrior")
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all(store: &Store) -> Result<TaskIterator> {
        Task::all_as_ids(store)
            .map(|iter| TaskIterator::new(store, iter))
    }

}

impl<'a> Deref for Task<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Task<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

/// A trait to get a `libimagtodo::task::Task` out of the implementing object.
/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name
/// `into_filelockentry`.
pub trait IntoTask<'a> {

    /// # Usage
    /// ```ignore
    /// use std::io::stdin;
    ///
    /// use task_hookrs::task::Task;
    /// use task_hookrs::import::import;
    /// use libimagstore::store::{Store, FileLockEntry};
    ///
    /// if let Ok(task_hookrs_task) = import(stdin()) {
    ///     // Store is given at runtime
    ///     let task = task_hookrs_task.into_filelockentry(store);
    ///     println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
    /// }
    /// ```
    fn into_task(self, store : &'a Store) -> Result<Task<'a>>;

}

impl<'a> IntoTask<'a> for TTask {

    fn into_task(self, store : &'a Store) -> Result<Task<'a>> {
        let uuid     = self.uuid();
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        match store.retrieve(store_id) {
            Err(e) => return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(mut fle) => {
                {
                    let mut header = fle.get_header_mut();
                    match header.read("todo") {
                        Ok(None) => {
                            if let Err(e) = header.set("todo", Value::Table(BTreeMap::new())) {
                                return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                            }
                        }
                        Ok(Some(_)) => { }
                        Err(e) => {
                            return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                        }
                    }

                    if let Err(e) = header.set("todo.uuid", Value::String(format!("{}",uuid))) {
                        return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                    }
                }

                // If none of the errors above have returned the function, everything is fine
                Ok(Task::new(fle))
            }
        }
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Task<'a>>;
}

impl<'a> FromStoreId for Task<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Task<'b>> {
        match store.retrieve(id) {
            Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(c)  => Ok(Task::new( c )),
        }
    }
}

pub struct TaskIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> TaskIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> {
        TaskIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for TaskIterator<'a> {
    type Item = Result<Task<'a>>;

    fn next(&mut self) -> Option<Result<Task<'a>>> {
        self.iditer.next().map(|id| Task::from_storeid(self.store, id))
    }
}

<commit_msg>Impl Task::get_from_import()<commit_after>use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::io::BufRead;
use std::result::Result as RResult;

use toml::Value;
use uuid::Uuid;

use task_hookrs::task::Task as TTask;
use task_hookrs::import::{import_task, import_tasks};

use libimagstore::store::{FileLockEntry, Store};
use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId};
use module_path::ModuleEntryPath;

use error::{TodoError, TodoErrorKind, MapErrInto};
use result::Result;

/// Task struct containing a `FileLockEntry`
#[derive(Debug)]
pub struct Task<'a>(FileLockEntry<'a>);

impl<'a> Task<'a> {

    /// Concstructs a new `Task` with a `FileLockEntry`
    pub fn new(fle: FileLockEntry<'a>) -> Task<'a> {
        Task(fle)
    }

    pub fn import<R: BufRead>(store: &'a Store, mut r: R) -> Result<(Task<'a>, Uuid)> {
        let mut line = String::new();
        r.read_line(&mut line);
        import_task(&line.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .and_then(|t| {
                let uuid = t.uuid().clone();
                t.into_task(store).map(|t| (t, uuid))
            })
    }

    /// Get a task from an import string. That is: read the imported string, get the UUID from it
    /// and try to load this UUID from store.
    ///
    /// Possible return values are:
    ///
    /// * Ok(Ok(Task))
    /// * Ok(Err(String)) - where the String is the String read from the `r` parameter
    /// * Err(_)          - where the error is an error that happened during evaluation
    ///
    pub fn get_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<RResult<Task<'a>, String>>
    {
        let mut line = String::new();
        r.read_line(&mut line);
        Task::get_from_string(store, line)
    }

    /// Get a task from a String. The String is expected to contain the JSON-representation of the
    /// Task to get from the store (only the UUID really matters in this case)
    ///
    /// For an explanation on the return values see `Task::get_from_import()`.
    pub fn get_from_string(store: &'a Store, s: String) -> Result<RResult<Task<'a>, String>> {
        unimplemented!()
    }

    /// Get a task from an UUID.
    ///
    /// If there is no task with this UUID, this returns `Ok(None)`.
    pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result<Option<Task<'a>>> {
        unimplemented!()
    }

    /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to
    /// implicitely create the task if it does not exist.
    pub fn retrieve_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<Task<'a>> {
        unimplemented!()
    }

    /// Retrieve a task from a String. The String is expected to contain the JSON-representation of
    /// the Task to retrieve from the store (only the UUID really matters in this case)
    pub fn retrieve_from_string(store: &'a Store, s: String) -> Result<Task<'a>> {
        unimplemented!()
    }

    pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> {
        store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid())
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all_as_ids(store: &Store) -> Result<StoreIdIterator> {
        store.retrieve_for_module("todo/taskwarrior")
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all(store: &Store) -> Result<TaskIterator> {
        Task::all_as_ids(store)
            .map(|iter| TaskIterator::new(store, iter))
    }

}

impl<'a> Deref for Task<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Task<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

/// A trait to get a `libimagtodo::task::Task` out of the implementing object.
/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name
/// `into_filelockentry`.
pub trait IntoTask<'a> {

    /// # Usage
    /// ```ignore
    /// use std::io::stdin;
    ///
    /// use task_hookrs::task::Task;
    /// use task_hookrs::import::import;
    /// use libimagstore::store::{Store, FileLockEntry};
    ///
    /// if let Ok(task_hookrs_task) = import(stdin()) {
    ///     // Store is given at runtime
    ///     let task = task_hookrs_task.into_filelockentry(store);
    ///     println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
    /// }
    /// ```
    fn into_task(self, store : &'a Store) -> Result<Task<'a>>;

}

impl<'a> IntoTask<'a> for TTask {

    fn into_task(self, store : &'a Store) -> Result<Task<'a>> {
        let uuid     = self.uuid();
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        match store.retrieve(store_id) {
            Err(e) => return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(mut fle) => {
                {
                    let mut header = fle.get_header_mut();
                    match header.read("todo") {
                        Ok(None) => {
                            if let Err(e) = header.set("todo", Value::Table(BTreeMap::new())) {
                                return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                            }
                        }
                        Ok(Some(_)) => { }
                        Err(e) => {
                            return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                        }
                    }

                    if let Err(e) = header.set("todo.uuid", Value::String(format!("{}",uuid))) {
                        return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                    }
                }

                // If none of the errors above have returned the function, everything is fine
                Ok(Task::new(fle))
            }
        }
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Task<'a>>;
}

impl<'a> FromStoreId for Task<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Task<'b>> {
        match store.retrieve(id) {
            Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(c)  => Ok(Task::new( c )),
        }
    }
}

pub struct TaskIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> TaskIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> {
        TaskIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for TaskIterator<'a> {
    type Item = Result<Task<'a>>;

    fn next(&mut self) -> Option<Result<Task<'a>>> {
        self.iditer.next().map(|id| Task::from_storeid(self.store, id))
    }
}

<|endoftext|>


<commit_before><commit_msg>Create calc.rs<commit_after>enum OpType{
    Add,             // +
    Sub,             // -
    Mul,             // *
    Div,             // /
    Modulus,         // %
    Pow,             // ^
}

enum Element{
    Operator(OpType),
    Value(f32),
    Variable(String)
}

use stack::List;
use calc::OpType::*;
use calc::Element::*;
use std::str;

fn get_op_prioroty(op_ch: &char) -> i32{
    match *op_ch{
        '('              => 0,
        ')'              => 1,
        '+' | '-'        => 2,
        '*' | '/' | '%'  => 3,
        '^'              => 4,
        _                => -1
    }
}

fn read_char(option: Option<char>) -> char{
    match option{
        Some(x) => x,
        None => panic!("Ohh, we got end of stack!")
    }
}

fn get_polen_notation(expression: &String) -> Result<String, String>{
    let mut result = String::new();
    let mut stack = String::new();

    let mut operand = false;
    let mut prev_space = false;

    'process: for c in expression.chars(){

        if prev_space && c != ' ' {
            result.push(' ');
            prev_space = false;
        }

        match c{
            '0'...'9' | '.' =>{
                result.push(c);
                operand = true;
            },
            '(' => {
                stack.push(c);},
            ')' => {
                loop{
                    if(stack.is_empty()){
                        return Err("Can't find closing parenthesis or unexpected delimiter.".to_string());
                    }

                    let stack_char = read_char(stack.pop());

                    if(stack_char != '('){
                        result.push(stack_char);
                    }else{
                        break;
                    }
                }
            },
            ' ' => {
                prev_space = true;
            },
            _ => {

                if !operand && c == '-' {
                    operand = true;
                    result.push(c);

                    continue 'process;
                }

                let prior = get_op_prioroty(&c);
                if(prior != -1){
                    operand = false;
                    loop{
                        if !stack.is_empty() {
                            //get last operator priority
                            let stack_operator = &(stack.as_bytes()[stack.len() - 1] as char);
                            if prior <= get_op_prioroty(stack_operator) {
                                stack.pop();
                                result.push(*stack_operator);
                            }else{break;}
                        }else{ //return Err("Stack is empty".to_string());
                            break;
                        }
                    }
                    stack.push(c);
                    prev_space = true;
                }else{
                    return Err(format!("Unexpected char: <{}>, expected operator", c));
                }
            }
        }
    }

    while !stack.is_empty(){
        result.push(read_char(stack.pop()));
    }

    return Ok(result);
}

fn read_f32(option: Option<f32>) -> f32{
    match option{
        Some(x) => x,
        None => panic!("Ohh, we got end of stack!")
    }
}

fn calc_expression(expr_stack: List<Element>) -> f32{
    let mut val_stack: List<f32> = List::new();

    for x in expr_stack.iter(){
        match x{
            &Operator(ref op) => {
                let val2 = read_f32(val_stack.pop());
                let val1 = read_f32(val_stack.pop());

                val_stack.push( match *op {
                    Add => val1 + val2,
                    Sub => val1 - val2,
                    Mul => val1 * val2,
                    Div => val1 / val2,
                    Modulus => val1 % val2,
                    Pow => val1.powf(val2)
                });
            },

            &Value(ref val) => {
                val_stack.push(*val);
            },

            &Variable(ref var) => {
                unimplemented!()
            }
        }
    }

    return read_f32(val_stack.pop());
}

fn get_f32_from_string(val: &String) -> f32{
    match val.parse::<f32>(){
        Ok(x)  => x,
        Err(_) => 0.0
    }
}

fn get_element_by_string(token: &String) -> Element{
    match (token.as_bytes()[0] as char){
        '+' => Operator(Add),
        '-' => if token.len() > 1 {
            Value(get_f32_from_string(token))
        } else {
            Operator(Sub)
        },
        '*' => Operator(Mul),
        '/' => Operator(Div),
        '%' => Operator(Modulus),
        '^' => Operator(Pow),
         _ => {
             Value(get_f32_from_string(token))
        }
    }
}

fn print_stack(stack: &List<Element>){
    for x in stack.iter(){
        print!("{} ",
        match *x{
             Operator(Add) => "+".to_string(),
            Operator(Sub) => "-".to_string(),
            Operator(Mul) => "*".to_string(),
            Operator(Div) => "/".to_string(),
            Operator(Modulus) => "%".to_string(),
            Operator(Pow) => "^".to_string(),
            Value(val) => val.to_string(),
            Variable(_) => "ITS VAR".to_string()
        });
    }
    print!("/n");
}

fn string_to_list(str_expr: &String) -> List<Element>{
    let mut tmp: List<Element> = List::new();
    let mut token: String = String::new();

    let mut operand = false;

    'tokenize: for ch in str_expr.chars(){
        match ch{
            '0'...'9' | '.' => {
                token.push(ch);
                operand = true;
            },
            '+'|'-'|'*'|'/'|'%'|'^' => {

                if !operand && ch == '-'{
                    token.push(ch);
                    operand = true;

                    continue 'tokenize;
                }

                if !token.is_empty(){
                    tmp.push(get_element_by_string( &(token) ));
                    token.clear();
                }

                token.push(ch);

                tmp.push(get_element_by_string( &(token) ));
                token.clear();

                operand = false;
            },
            ' ' => if !token.is_empty(){
                operand = false;
                tmp.push(get_element_by_string( &(token) ));
                token.clear();
            },
            _ => {println!("unexpected situation")}
        }
    }

    print_stack(&tmp);

    let mut stack: List<Element> = List::new();

    while let Some(el) = tmp.pop(){
        stack.push(el);
    }

    return stack;
}

pub fn calc(infix_str: &String) -> Result<f32, String>{
    let stack2;
    match get_polen_notation(infix_str) {
        Ok(x) => {
            stack2 = string_to_list(&x);
            Ok(calc_expression(stack2))
        },
        Err(x) => Err(x)
    }
}

#[cfg(test)]
mod calc_test {
    use super::calc;

    #[test]
    fn calc_basics() {

        let tests_result_4 = vec![
            "2+2",
            "2 +2",
            "2 + 2",
            " 2 + 2 ",
            "(2+2)",
            "( 2+2)",
            " ( 2 +2)",
            "(2+ 2)",
            "(2+ 2 )",
            "(2+ 2 ) ",
            "(((2+2)))",
            "(((2)) + 2)",
            "4-0",
            "8/2",
            "8*0.5",
            "9.5 - 5.5",
            "9 % 5",
            "-4 + 8",
            "8 + -4",
            "-2 + 6"
        ];

        for test in tests_result_4{
            match calc(&test.to_string()) {
                Ok(x) => assert_eq!(x, 4.0),
                Err(x) => {
                    println!("FAILED TEST: {}, error: {} \n", test, x);
                    assert!(false);
                }
            }
        }

    }

    #[test]
    fn calc_long_expression(){
        let tests_result_2648 = vec![
            "55 * (3552 / 74) + 2^3",
            "55 * (3552 / (37 * 2)) + 2^3",
            "(54 + 1) * (3552 / (37 * 2)) + 2^3",
            "55 * (3552 / (147 % 74 + 1)) + 2^3",
            "55 * (3552 / 74) + 2^(2+1)",
            "55 * (3552 / 74) + 2^(4-1)",
            "55 * (3552 / 74) + 2^(0.5 * 6)",
            "55 * (3552 / 74) + 2^(6 * 0.5)",
            "2^3 + 55 / (1/(3552 * (1/74)))",
        ];

        for test in tests_result_2648{
            match calc(&test.to_string()) {
                Ok(x) => assert_eq!(x, 2648.0),
                Err(x) => {
                    println!("FAILED TEST: {}, error: {} \n", test, x);
                    assert!(false);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix comment for rustc 1.26<commit_after><|endoftext|>


<commit_before><commit_msg>Remove ununsed sourcefile<commit_after><|endoftext|>


<commit_before><commit_msg>Implement state block parsing.<commit_after>enum Error {
    WrongPassword,
    UnknownChecksumAlgorithm,
    UnknownCompressionAlgorithm,
    InvalidChecksum,
    Disk(disk::Error),
}

enum ChecksumAlgorithm {
    Constant,
    SeaHash,
}

enum CompressionAlgorithm {
    Identity,
    Lz4,
}

struct StateBlock {
    checksum_algorithm: ChecksumAlgorithm,
    compression_algorithm: CompressionAlgorithm,
    freelist_head: clusters::Pointer,
    super_page: clusters::Pointer,
}

impl StateBlock {
    fn new(buf: &[u8]) -> Result<(), Error> {
        if &buf[..4] != &[0, 0, 0, 0] {
            return Err(Error::WrongPassword);
        }

        let checksum_algorithm = match LittleEndian::read(buf[16..18]) {
            0 => ChecksumAlgorithm::Constant,
            1 => ChecksumAlgorithm::SeaHash,
            _ => return Err(Error::UnknownChecksumAlgorithm),
        };

        if checksum_algorithm.hash(&buf[..40]) != LittleEndian::read(&buf[40..44]) {
            return Err(Error::InvalidChecksum);
        }

        StateBlock {
            checksum_algorithm: checksum_algorithm,
            compression_algorithm: match LittleEndian::read(buf[18..20]) {
                0 => CompressionAlgorithm::Identity,
                1 => CompressionAlgorithm::Lz4,
                _ => return Err(Error::UnknownCompressionAlgorithm),
            },
            freelist_head: LittleEndian::read(buf[32..40]),
            super_page: LittleEndian::read(buf[40..48]),
        }

    }
}
<|endoftext|>


<commit_before><commit_msg>Fix function types in ast.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused functions<commit_after><|endoftext|>


<commit_before><commit_msg>Handle if command has already config arg<commit_after><|endoftext|>


<commit_before><commit_msg>Added test for name mapping<commit_after>extern crate sourcemap;

use sourcemap::SourceMap;

#[test]
fn test_basic_name_mapping() {
    let input = r#"{"version":3,"file":"test.min.js","sources":["test.js"],"names":["makeAFailure","testingStuff","Error","onSuccess","data","onFailure","invoke","cb","failed","test","value"],"mappings":"AAAA,GAAIA,cAAe,WACjB,QAASC,KACP,GAAIA,GAAe,EACnB,MAAM,IAAIC,OAAMD,GAGlB,QAASE,GAAUC,GACjBH,IAGF,QAASI,GAAUD,GACjB,KAAM,IAAIF,OAAM,WAGlB,QAASI,GAAOF,GACd,GAAIG,GAAK,IACT,IAAIH,EAAKI,OAAQ,CACfD,EAAKF,MACA,CACLE,EAAKJ,EAEPI,EAAGH,GAGL,QAASK,KACP,GAAIL,IAAQI,OAAQ,KAAME,MAAO,GACjCJ,GAAOF,GAGT,MAAOK","sourcesContent":["var makeAFailure = (function() {\n  function testingStuff() {\n    var testingStuff = 42;\n    throw new Error(testingStuff);\n  }\n\n  function onSuccess(data) {\n    testingStuff();\n  }\n\n  function onFailure(data) {\n    throw new Error('failed!');\n  }\n\n  function invoke(data) {\n    var cb = null;\n    if (data.failed) {\n      cb = onFailure;\n    } else {\n      cb = onSuccess;\n    }\n    cb(data);\n  }\n\n  function test() {\n    var data = {failed: true, value: 42};\n    invoke(data);\n  }\n\n  return test;\n})();\n"]}"#.as_bytes();
    let minified_file = r#"var makeAFailure=function(){function n(){var n=42;throw new Error(n)}function r(r){n()}function e(n){throw new Error("failed!")}function i(n){var i=null;if(n.failed){i=e}else{i=r}i(n)}function u(){var n={failed:true,value:42};i(n)}return u}();"#;
    let sm = SourceMap::from_reader(input).unwrap();

    let tok = sm.lookup_token(0, 45).unwrap();
    assert_eq!(tok.get_name(), Some("testingStuff"));
    assert_eq!(tok.get_minified_name(minified_file), Some("n"));

    let tok = sm.lookup_token(0, 66).unwrap();
    assert_eq!(tok.get_name(), Some("testingStuff"));
    assert_eq!(tok.get_minified_name(minified_file), Some("n"));

    let tok = sm.lookup_token(0, 96).unwrap();
    assert_eq!(tok.get_name(), Some("onFailure"));
    assert_eq!(tok.get_minified_name(minified_file), Some("e"));

    let name = sm.map_minified_name(0, 107, "e", minified_file);
    assert_eq!(name, Some("onFailure"));
}
<|endoftext|>


<commit_before><commit_msg>examples: add npm_bar example<commit_after>extern crate pbr;
use pbr::ProgressBar;
use std::thread;
use std::time::Duration;

fn main() {
    let count = 30;
    let mut pb = ProgressBar::new(count * 10);
    pb.tick_format("\\|/-");
    pb.format("|#--|");
    pb.show_tick = true;
    pb.show_speed = false;
    pb.show_percent = false;
    pb.show_counter = false;
    pb.show_time_left = false;
    pb.inc();
    for _ in 0..count {
        for _ in 0..10 {
            pb.message("normalize -> thing ");
            thread::sleep(Duration::from_millis(80));
            pb.tick();
        }
        for _ in 0..10 {
            pb.message("fuzz -> tree       ");
            thread::sleep(Duration::from_millis(80));
            pb.inc();
        }
    }
    pb.finish_println("done!");
}
<|endoftext|>