<commit_before>#![feature(box_syntax)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

use std::collections::{BTreeMap, HashMap, VecDeque};
use std::fs::File;
use std::io::{stdout, Read, Write};
use std::env;
use std::process;

use self::to_num::ToNum;
use self::directory_stack::DirectoryStack;
use self::input_editor::readln;
use self::peg::parse;
use self::expansion::Expand;

pub mod builtin;
pub mod directory_stack;
pub mod to_num;
pub mod input_editor;
pub mod peg;
pub mod expansion;

pub struct Mode {
    value: bool,
}

/// This struct will contain all of the data structures related to this
/// instance of the shell.
pub struct Shell {
    variables: BTreeMap<String, String>,
    modes: Vec<Mode>,
    directory_stack: DirectoryStack,
    history: VecDeque<String>,
}

impl Shell {
    /// Panics if DirectoryStack construction fails
    pub fn new() -> Self {
        Shell {
            variables: BTreeMap::new(),
            modes: vec![],
            directory_stack: DirectoryStack::new().expect(""),
            history: VecDeque::new(),
        }
    }

    pub fn print_prompt(&self) {
        let prompt_prefix = self.modes.iter().rev().fold(String::new(), |acc, mode| {
            acc +
            if mode.value {
                "+ "
            } else {
                "- "
            }
        });
        print!("{}", prompt_prefix);

        let cwd = env::current_dir().ok().map_or("?".to_string(),
                                                 |ref p| p.to_str().unwrap_or("?").to_string());

        print!("ion:{}# ", cwd);
        if let Err(message) = stdout().flush() {
            println!("{}: failed to flush prompt to stdout", message);
        }
    }

    fn on_command(&mut self, command_string: &str, commands: &HashMap<&str, Command>) {
        let max_history: usize = 1000; // TODO temporary, make this configurable
        if self.history.len() > max_history {
            self.history.pop_front();
        }
        self.history.push_back(command_string.to_string());

        // Show variables
        if command_string == "$" {
            for (key, value) in self.variables.iter() {
                println!("{}={}", key, value);
            }
            return;
        }

        let mut jobs = parse(command_string);
        self.expand_variables(&mut jobs);

        // Execute commands
        for job in jobs.iter() {
            if job.command == "if" {
                let mut value = false;

                if let Some(left) = job.args.get(0) {
                    if let Some(cmp) = job.args.get(1) {
                        if let Some(right) = job.args.get(2) {
                            if cmp == "==" {
                                value = *left == *right;
                            } else if cmp == "!=" {
                                value = *left != *right;
                            } else if cmp == ">" {
                                value = left.to_num_signed() > right.to_num_signed();
                            } else if cmp == ">=" {
                                value = left.to_num_signed() >= right.to_num_signed();
                            } else if cmp == "<" {
                                value = left.to_num_signed() < right.to_num_signed();
                            } else if cmp == "<=" {
                                value = left.to_num_signed() <= right.to_num_signed();
                            } else {
                                println!("Unknown comparison: {}", cmp);
                            }
                        } else {
                            println!("No right hand side");
                        }
                    } else {
                        println!("No comparison operator");
                    }
                } else {
                    println!("No left hand side");
                }

                self.modes.insert(0, Mode { value: value });
                continue;
            }

            if job.command == "else" {
                if let Some(mode) = self.modes.get_mut(0) {
                    mode.value = !mode.value;
                } else {
                    println!("Syntax error: else found with no previous if");
                }
                continue;
            }

            if job.command == "fi" {
                if !self.modes.is_empty() {
                    self.modes.remove(0);
                } else {
                    println!("Syntax error: fi found with no previous if");
                }
                continue;
            }

            let mut skipped: bool = false;
            for mode in self.modes.iter() {
                if !mode.value {
                    skipped = true;
                    break;
                }
            }
            if skipped {
                continue;
            }

            // Set variables
            if let Some(i) = job.command.find('=') {
                let name = job.command[0..i].trim();
                let mut value = job.command[i + 1..job.command.len()].trim().to_string();

                for i in 0..job.args.len() {
                    if let Some(arg) = job.args.get(i) {
                        value = value + " " + &arg;
                    }
                }

                self.set_var(name, &value);
                continue;
            }

            // Commands
            let mut args = job.args.clone();
            args.insert(0, job.command.clone());
            if let Some(command) = commands.get(&job.command.as_str()) {
                (*command.main)(&args, self);
            } else {
                self.run_external_commmand(args);
            }
        }
    }

    fn run_external_commmand(&mut self, args: Vec<String>) {
        if let Some(path) = args.get(0) {
            let mut command = process::Command::new(path);
            for i in 1..args.len() {
                if let Some(arg) = args.get(i) {
                    command.arg(arg);
                }
            }
            match command.spawn() {
                Ok(mut child) => {
                    match child.wait() {
                        Ok(status) => {
                            if let Some(code) = status.code() {
                                self.set_var("?", &code.to_string());
                            } else {
                                println!("{}: No child exit code", path);
                            }
                        }
                        Err(err) => println!("{}: Failed to wait: {}", path, err),
                    }
                }
                Err(err) => println!("{}: Failed to execute: {}", path, err),
            }
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str) {
        if name.is_empty() {
            return;
        }

        if value.is_empty() {
            self.variables.remove(&name.to_string());
        } else {
            self.variables.insert(name.to_string(), value.to_string());
        }
    }
}

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the
/// functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     help: "Describe what my_command does followed by a newline showing usage",
///     main: box|args: &[String], &mut Shell| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command {
    pub name: &'static str,
    pub help: &'static str,
    pub main: Box<Fn(&[String], &mut Shell)>,
}

impl Command {
    /// Return the map from command names to commands
    pub fn map() -> HashMap<&'static str, Self> {
        let mut commands: HashMap<&str, Self> = HashMap::new();

        commands.insert("cd",
                        Command {
                            name: "cd",
                            help: "To change the current directory\n    cd <your_destination>",
                            main: box |args: &[String], _: &mut Shell| {
                                builtin::cd(args);
                            },
                        });

        commands.insert("dirs",
                        Command {
                            name: "dirs",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.dirs(args);
                            },
                        });

        commands.insert("exit",
                        Command {
                            name: "exit",
                            help: "To exit the curent session",
                            main: box |_: &[String], _: &mut Shell| {},
                        });

        commands.insert("read",
                        Command {
                            name: "read",
                            help: "To read some variables\n    read <my_variable>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::read(args, shell);
                            },
                        });

        commands.insert("run",
                        Command {
                            name: "run",
                            help: "Run a script\n    run <script>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::run(args, shell);
                            },
                        });

        commands.insert("pushd",
                        Command {
                            name: "pushd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.pushd(args);
                            },
                        });

        commands.insert("popd",
                        Command {
                            name: "popd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.popd(args);
                            },
                        });

        commands.insert("history",
                        Command {
                            name: "history",
                            help: "Display all commands previously executed",
                            main: box |args: &[String], shell: &mut Shell| {
                                for command in shell.history.clone() {
                                    println!("{}", command);
                                }
                            },
                        });

        let command_helper: HashMap<String, String> = commands.iter()
                                                              .map(|(k, v)| {
                                                                  (k.to_string(),
                                                                   v.help.to_string())
                                                              })
                                                              .collect();

        commands.insert("help",
                        Command {
                            name: "help",
                            help: "Display a little helper for a given command\n    help ls",
                            main: box move |args: &[String], _: &mut Shell| {
                                if let Some(command) = args.get(1) {
                                    if command_helper.contains_key(command) {
                                        match command_helper.get(command) {
                                            Some(help) => println!("{}", help),
                                            None => {
                                                println!("Command helper not found [run 'help']...")
                                            }
                                        }
                                    } else {
                                        println!("Command helper not found [run 'help']...");
                                    }
                                } else {
                                    for (command, _help) in command_helper.iter() {
                                        println!("{}", command);
                                    }
                                }
                            },
                        });

        commands
    }
}

fn main() {
    let commands = Command::map();
    let mut shell = Shell::new();

    for arg in env::args().skip(1) {
        let mut command_list = String::new();
        if let Ok(mut file) = File::open(&arg) {
            if let Err(message) = file.read_to_string(&mut command_list) {
                println!("{}: Failed to read {}", message, arg);
            }
        }
        shell.on_command(&command_list, &commands);
        return;
    }

    loop {

        shell.print_prompt();

        if let Some(command_original) = readln() {
            let command = command_original.trim();
            if command == "exit" {
                break;
            } else if !command.is_empty() {
                shell.on_command(&command, &commands);
            }
        } else {
            break;
        }
    }
}
<commit_msg>Finish most of ticki's requests<commit_after>#![feature(box_syntax)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

use std::collections::{BTreeMap, HashMap, VecDeque};
use std::fs::File;
use std::io::{stdout, Read, Write};
use std::env;
use std::process;

use self::to_num::ToNum;
use self::directory_stack::DirectoryStack;
use self::input_editor::readln;
use self::peg::parse;
use self::expansion::Expand;

pub mod builtin;
pub mod directory_stack;
pub mod to_num;
pub mod input_editor;
pub mod peg;
pub mod expansion;

pub struct Mode {
    value: bool,
}

/// This struct will contain all of the data structures related to this
/// instance of the shell.
pub struct Shell {
    variables: BTreeMap<String, String>,
    modes: Vec<Mode>,
    directory_stack: DirectoryStack,
    history: VecDeque<String>,
}

impl Shell {
    /// Panics if DirectoryStack construction fails
    pub fn new() -> Self {
        Shell {
            variables: BTreeMap::new(),
            modes: vec![],
            directory_stack: DirectoryStack::new().expect(""),
            history: VecDeque::new(),
        }
    }

    pub fn print_prompt(&self) {
        let prompt_prefix = self.modes.iter().rev().fold(String::new(), |acc, mode| {
            acc +
            if mode.value {
                "+ "
            } else {
                "- "
            }
        });
        print!("{}", prompt_prefix);

        let cwd = env::current_dir().ok().map_or("?".to_string(),
                                                 |ref p| p.to_str().unwrap_or("?").to_string());

        print!("ion:{}# ", cwd);
        if let Err(message) = stdout().flush() {
            println!("{}: failed to flush prompt to stdout", message);
        }
    }

    fn on_command(&mut self, command_string: &str, commands: &HashMap<&str, Command>) {
        let max_history: usize = 1000; // TODO temporary, make this configurable
        if self.history.len() > max_history {
            self.history.pop_front();
        }
        self.history.push_back(command_string.to_string());

        // Show variables
        if command_string == "$" {
            for (key, value) in self.variables.iter() {
                println!("{}={}", key, value);
            }
        } else {
            let mut jobs = parse(command_string);
            self.expand_variables(&mut jobs);

            // Execute commands
            for job in jobs.iter() {
                if job.command == "if" {
                    let mut value = false;

                    if let Some(left) = job.args.get(0) {
                        if let Some(cmp) = job.args.get(1) {
                            if let Some(right) = job.args.get(2) {
                                if cmp == "==" {
                                    value = *left == *right;
                                } else if cmp == "!=" {
                                    value = *left != *right;
                                } else if cmp == ">" {
                                    value = left.to_num_signed() > right.to_num_signed();
                                } else if cmp == ">=" {
                                    value = left.to_num_signed() >= right.to_num_signed();
                                } else if cmp == "<" {
                                    value = left.to_num_signed() < right.to_num_signed();
                                } else if cmp == "<=" {
                                    value = left.to_num_signed() <= right.to_num_signed();
                                } else {
                                    println!("Unknown comparison: {}", cmp);
                                }
                            } else {
                                println!("No right hand side");
                            }
                        } else {
                            println!("No comparison operator");
                        }
                    } else {
                        println!("No left hand side");
                    }

                    self.modes.insert(0, Mode { value: value });
                    continue;
                }

                if job.command == "else" {
                    if let Some(mode) = self.modes.get_mut(0) {
                        mode.value = !mode.value;
                    } else {
                        println!("Syntax error: else found with no previous if");
                    }
                    continue;
                }

                if job.command == "fi" {
                    if !self.modes.is_empty() {
                        self.modes.remove(0);
                    } else {
                        println!("Syntax error: fi found with no previous if");
                    }
                    continue;
                }

                let skipped = self.modes.iter().any(|mode| !mode.value);
                if skipped {
                    continue;
                }

                // Set variables
                if let Some(i) = job.command.find('=') {
                    let name = job.command[..i].trim();
                    let mut value = job.command[i + 1..job.command.len()].trim().to_string();

                    for i in 0..job.args.len() {
                        if let Some(arg) = job.args.get(i) {
                            value = value + " " + &arg;
                        }
                    }

                    self.set_var(name, &value);
                    continue;
                }

                // Commands
                let mut args = job.args.clone();
                args.insert(0, job.command.clone());
                if let Some(command) = commands.get(&job.command.as_str()) {
                    (*command.main)(&args, self);
                } else {
                    self.run_external_commmand(args);
                }
            }
        }
    }

    fn run_external_commmand(&mut self, args: Vec<String>) {
        if let Some(path) = args.get(0) {
            let mut command = process::Command::new(path);
            for i in 1..args.len() {
                if let Some(arg) = args.get(i) {
                    command.arg(arg);
                }
            }
            match command.spawn() {
                Ok(mut child) => {
                    match child.wait() {
                        Ok(status) => {
                            if let Some(code) = status.code() {
                                self.set_var("?", &code.to_string());
                            } else {
                                println!("{}: No child exit code", path);
                            }
                        }
                        Err(err) => println!("{}: Failed to wait: {}", path, err),
                    }
                }
                Err(err) => println!("{}: Failed to execute: {}", path, err),
            }
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str) {
        if !name.is_empty() {
            if value.is_empty() {
                self.variables.remove(&name.to_string());
            } else {
                self.variables.insert(name.to_string(), value.to_string());
            }
        }
    }
}

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the
/// functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     help: "Describe what my_command does followed by a newline showing usage",
///     main: box|args: &[String], &mut Shell| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command {
    pub name: &'static str,
    pub help: &'static str,
    pub main: Box<Fn(&[String], &mut Shell)>,
}

impl Command {
    /// Return the map from command names to commands
    pub fn map() -> HashMap<&'static str, Self> {
        let mut commands: HashMap<&str, Self> = HashMap::new();

        commands.insert("cd",
                        Command {
                            name: "cd",
                            help: "To change the current directory\n    cd <your_destination>",
                            main: box |args: &[String], _: &mut Shell| {
                                builtin::cd(args);
                            },
                        });

        commands.insert("dirs",
                        Command {
                            name: "dirs",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.dirs(args);
                            },
                        });

        commands.insert("exit",
                        Command {
                            name: "exit",
                            help: "To exit the curent session",
                            main: box |_: &[String], _: &mut Shell| {},
                        });

        commands.insert("read",
                        Command {
                            name: "read",
                            help: "To read some variables\n    read <my_variable>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::read(args, shell);
                            },
                        });

        commands.insert("run",
                        Command {
                            name: "run",
                            help: "Run a script\n    run <script>",
                            main: box |args: &[String], shell: &mut Shell| {
                                builtin::run(args, shell);
                            },
                        });

        commands.insert("pushd",
                        Command {
                            name: "pushd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.pushd(args);
                            },
                        });

        commands.insert("popd",
                        Command {
                            name: "popd",
                            help: "Make a sleep in the current session\n    sleep \
                                   <number_of_seconds>",
                            main: box |args: &[String], shell: &mut Shell| {
                                shell.directory_stack.popd(args);
                            },
                        });

        commands.insert("history",
                        Command {
                            name: "history",
                            help: "Display all commands previously executed",
                            main: box |args: &[String], shell: &mut Shell| {
                                for command in shell.history.clone() {
                                    println!("{}", command);
                                }
                            },
                        });

        let command_helper: HashMap<String, String> = commands.iter()
                                                              .map(|(k, v)| {
                                                                  (k.to_string(),
                                                                   v.help.to_string())
                                                              })
                                                              .collect();

        commands.insert("help",
                        Command {
                            name: "help",
                            help: "Display a little helper for a given command\n    help ls",
                            main: box move |args: &[String], _: &mut Shell| {
                                if let Some(command) = args.get(1) {
                                    if command_helper.contains_key(command) {
                                        match command_helper.get(command) {
                                            Some(help) => println!("{}", help),
                                            None => {
                                                println!("Command helper not found [run 'help']...")
                                            }
                                        }
                                    } else {
                                        println!("Command helper not found [run 'help']...");
                                    }
                                } else {
                                    for (command, _help) in command_helper.iter() {
                                        println!("{}", command);
                                    }
                                }
                            },
                        });

        commands
    }
}

fn main() {
    let commands = Command::map();
    let mut shell = Shell::new();

    for arg in env::args().skip(1) {
        let mut command_list = String::new();
        if let Ok(mut file) = File::open(&arg) {
            if let Err(message) = file.read_to_string(&mut command_list) {
                println!("{}: Failed to read {}", message, arg);
            }
        }
        shell.on_command(&command_list, &commands);
        return;
    }

    loop {

        shell.print_prompt();

        if let Some(command_original) = readln() {
            let command = command_original.trim();
            if command == "exit" {
                break;
            } else if !command.is_empty() {
                shell.on_command(&command, &commands);
            }
        } else {
            break;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Abuse piped stdout from geth Removed<commit_after><|endoftext|>


<commit_before><commit_msg>Sort imports<commit_after><|endoftext|>


<commit_before><commit_msg>[matcher] limit the number of criterion to below 4.<commit_after><|endoftext|>


<commit_before><commit_msg>(doc) Documented Request wrapper.<commit_after><|endoftext|>


<commit_before><commit_msg>Added image example<commit_after>extern crate kiss3d;
extern crate nalgebra as na;

use std::path::Path;

use na::Vec3;
use kiss3d::window::Window;
use kiss3d::light::Light;

// Based on cube example.
fn main() {
    let mut window = Window::new("Kiss3d: cube");
    let mut c      = window.add_cube(0.2, 0.2, 0.2);

    c.set_color(1.0, 0.0, 0.0);
    c.prepend_to_local_rotation(&Vec3::new(0.0f32, 0.785, 0.0));
    c.prepend_to_local_rotation(&Vec3::new(-0.6f32, 0.0, 0.0));

    window.set_light(Light::StickToCamera);

    while window.render() {
        let img = window.snap_image();
        let img_path = Path::new("cube.png");
        img.save(img_path).unwrap();
        break;
    }
}
<|endoftext|>


<commit_before><commit_msg>Added a line example<commit_after>extern crate sdl2;
extern crate sdl2_sys;
extern crate libc;

extern crate sdl3d;

use sdl3d::vid::*;
use sdl3d::start;

fn main() {
    let mut rend_contx = start::bootstrap(1280, 720, "Hello world!");
    let (mut renderer, mut pump) = rend_contx;

    unsafe {sdl2_sys::mouse::SDL_SetRelativeMouseMode(1);}

    // Variables, some of them should be static afaik.
    let screen_w = 1280/2;
    let screen_h = 720/2;

    let mut camera_x = 0.0;
    let mut camera_y = 0.0;
    let mut camera_z = 3.0;

    let mut camera_x_z = 0.0;
    let mut camera_y_z = 0.0;
    let mut camera_x_y = 0.0;

    //A vector of arrays of points. Each array is a line from first to second point.
    let mut lines = Lines::new(vec![
                                [DepthPoint::new(-0.5, -0.5, 0.6), DepthPoint::new(-0.5, 0.5, 0.6)],
                                [DepthPoint::new(-0.5, -0.5, 0.6), DepthPoint::new(0.0, -0.5, 0.6)],
                                [DepthPoint::new(-0.5, 0.0, 0.6), DepthPoint::new(0.0, 0.0, 0.6)],
                                [DepthPoint::new(0.0, 0.0, 0.6), DepthPoint::new(0.0, -0.5, 0.6)],
                               ]);

    'game_loop: loop {
        use sdl2::pixels::Color::RGB;

        std::thread::sleep(std::time::Duration::from_millis(33));

        for event in pump.poll_iter() {
            use sdl2::event::Event::*;
            use sdl2::keyboard::Keycode::*;

            match event {
                Quit {..} => {break 'game_loop;},
                KeyDown {keycode, ..} => {
                    match keycode {
                        Some(Up) => {
                            let z = camera_z;
                            camera_z = z - 0.05;
                        },
                        Some(Down) => {
                            let z = camera_z;
                            camera_z = z + 0.05;
                        },
                        Some(Left) => {
                            let x = camera_x;
                            camera_x = x + 0.05;
                        },
                        Some(Right) => {
                            let x = camera_x;
                            camera_x = x - 0.05;
                        },
                        Some(RCtrl) => {
                            let y = camera_y;
                            camera_y = y + 0.05;
                        },
                        Some(RShift) => {
                            let y = camera_y;
                            camera_y = y - 0.05;
                        },
                        Some(Q) => {
                            camera_x_y += 0.1;
                        },
                        Some(E) => {
                            camera_x_y -= 0.1;
                        },
                        Some(Escape) => {
                            break 'game_loop;
                        }
                        _ => {println!("{:?}", keycode);}
                    }
                },
                MouseMotion {xrel, yrel, ..} => {
                    camera_x_z = (xrel as f64)/30.0;
                    //camera_y_z = (yrel as f64)/30.0;
                }
                _ => {}
            }
        }

        renderer.set_draw_color(RGB(20, 40, 60));
        renderer.clear();
        renderer.set_draw_color(RGB(200, 200, 200));

        lines.flat(screen_w, screen_h, &mut renderer,
                   camera_x, camera_y, camera_z,
                  camera_x_y, camera_x_z, camera_y_z);

        // Reset relative mouse move back to 0 as everything was already moved
        camera_x_z = 0.0;
        camera_y_z = 0.0;
        camera_x_y = 0.0;

        renderer.present();
    }
}<|endoftext|>


<commit_before>use core::cmp::PartialEq;
use core::ops::{BitAnd, BitOr, Not};
use core::marker::PhantomData;

pub trait ReadWrite<T>
{
    fn read(&self) -> T;
    fn write(&self, value: T);
}

/// Generic PIO
#[derive(Copy, Clone)]
pub struct Pio<T> {
    port: u16,
    value: PhantomData<T>,
}

/// Read/Write for byte PIO
impl ReadWrite<u8> for Pio<u8> {
    /// Read
    fn read(&self) -> u8 {
        let value: u8;
        unsafe {
            asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u8) {
        unsafe {
            asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

/// Read/Write for word PIO
impl ReadWrite<u16> for Pio<u16> {
    /// Read
    fn read(&self) -> u16 {
        let value: u16;
        unsafe {
            asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u16) {
        unsafe {
            asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

/// Read/Write for doubleword PIO
impl ReadWrite<u32> for Pio<u32> {
    /// Read
    fn read(&self) -> u32 {
        let value: u32;
        unsafe {
            asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u32) {
        unsafe {
            asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

impl<T> Pio<T>
    where Pio<T>: ReadWrite<T>,
          T: BitAnd<Output = T> + BitOr<Output = T> + PartialEq<T> + Not<Output = T> + Copy
{
    /// Create a PIO from a given port
    pub fn new(port: u16) -> Self {
        return Pio::<T> {
            port: port,
            value: PhantomData,
        };
    }

    pub fn readf(&self, flags: T) -> bool {
        (self.read() & flags) as T == flags
    }

    pub fn writef(&mut self, flags: T, value: bool) {
        let tmp: T = match value {
            true => self.read() | flags,
            false => self.read() & !flags,
        };
        self.write(tmp);
    }
}

/// PIO8
#[derive(Copy, Clone)]
pub struct Pio8 {
    port: u16,
}

impl Pio8 {
    /// Create a PIO8 from a given port
    pub fn new(port: u16) -> Self {
        return Pio8 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u8 {
        let value: u8;
        asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u8) {
        asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u8) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u8, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn inb(port: u16) -> u8 {
    return Pio8::new(port).read();
}

// TODO: Remove
pub unsafe fn outb(port: u16, value: u8) {
    Pio8::new(port).write(value);
}

/// PIO16
#[derive(Copy, Clone)]
pub struct Pio16 {
    port: u16,
}

impl Pio16 {
    /// Create a new PIO16 from a given port
    pub fn new(port: u16) -> Self {
        return Pio16 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u16 {
        let value: u16;
        asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u16) {
        asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u16) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u16, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn inw(port: u16) -> u16 {
    return Pio16::new(port).read();
}

// TODO: Remove
pub unsafe fn outw(port: u16, value: u16) {
    Pio16::new(port).write(value);
}

/// PIO32
#[derive(Copy, Clone)]
pub struct Pio32 {
    port: u16,
}

impl Pio32 {
    /// Create a new PIO32 from a port
    pub fn new(port: u16) -> Self {
        return Pio32 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u32 {
        let value: u32;
        asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u32) {
        asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u32) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u32, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn ind(port: u16) -> u32 {
    return Pio32::new(port).read();
}

// TODO: Remove
pub unsafe fn outd(port: u16, value: u32) {
    Pio32::new(port).write(value);
}
<commit_msg>Convert in[bwd] and out[bwd] function to Pio<T><commit_after>use core::cmp::PartialEq;
use core::ops::{BitAnd, BitOr, Not};
use core::marker::PhantomData;

pub trait ReadWrite<T>
{
    fn read(&self) -> T;
    fn write(&self, value: T);
}

/// Generic PIO
#[derive(Copy, Clone)]
pub struct Pio<T> {
    port: u16,
    value: PhantomData<T>,
}

/// Read/Write for byte PIO
impl ReadWrite<u8> for Pio<u8> {
    /// Read
    fn read(&self) -> u8 {
        let value: u8;
        unsafe {
            asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u8) {
        unsafe {
            asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

/// Read/Write for word PIO
impl ReadWrite<u16> for Pio<u16> {
    /// Read
    fn read(&self) -> u16 {
        let value: u16;
        unsafe {
            asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u16) {
        unsafe {
            asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

/// Read/Write for doubleword PIO
impl ReadWrite<u32> for Pio<u32> {
    /// Read
    fn read(&self) -> u32 {
        let value: u32;
        unsafe {
            asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
        return value;
    }

    /// Write
    fn write(&self, value: u32) {
        unsafe {
            asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
        }
    }
}

impl<T> Pio<T>
    where Pio<T>: ReadWrite<T>,
          T: BitAnd<Output = T> + BitOr<Output = T> + PartialEq<T> + Not<Output = T> + Copy
{
    /// Create a PIO from a given port
    pub fn new(port: u16) -> Self {
        return Pio::<T> {
            port: port,
            value: PhantomData,
        };
    }

    pub fn readf(&self, flags: T) -> bool {
        (self.read() & flags) as T == flags
    }

    pub fn writef(&mut self, flags: T, value: bool) {
        let tmp: T = match value {
            true => self.read() | flags,
            false => self.read() & !flags,
        };
        self.write(tmp);
    }
}

/// PIO8
#[derive(Copy, Clone)]
pub struct Pio8 {
    port: u16,
}

impl Pio8 {
    /// Create a PIO8 from a given port
    pub fn new(port: u16) -> Self {
        return Pio8 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u8 {
        let value: u8;
        asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u8) {
        asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u8) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u8, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn inb(port: u16) -> u8 {
    Pio::<u8>::new(port).read()
}

// TODO: Remove
pub unsafe fn outb(port: u16, value: u8) {
    Pio::<u8>::new(port).write(value);
}

/// PIO16
#[derive(Copy, Clone)]
pub struct Pio16 {
    port: u16,
}

impl Pio16 {
    /// Create a new PIO16 from a given port
    pub fn new(port: u16) -> Self {
        return Pio16 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u16 {
        let value: u16;
        asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u16) {
        asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u16) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u16, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn inw(port: u16) -> u16 {
    Pio::<u16>::new(port).read()
}

// TODO: Remove
pub unsafe fn outw(port: u16, value: u16) {
    Pio::<u16>::new(port).write(value);
}

/// PIO32
#[derive(Copy, Clone)]
pub struct Pio32 {
    port: u16,
}

impl Pio32 {
    /// Create a new PIO32 from a port
    pub fn new(port: u16) -> Self {
        return Pio32 { port: port };
    }

    /// Read
    pub unsafe fn read(&self) -> u32 {
        let value: u32;
        asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
        return value;
    }

    /// Write
    pub unsafe fn write(&mut self, value: u32) {
        asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
    }

    pub unsafe fn readf(&self, flags: u32) -> bool {
        self.read() & flags == flags
    }

    pub unsafe fn writef(&mut self, flags: u32, value: bool) {
        if value {
            let value = self.read() | flags;
            self.write(value);
        } else {
            let value = self.read() & !flags;
            self.write(value);
        }
    }
}

// TODO: Remove
pub unsafe fn ind(port: u16) -> u32 {
    Pio::<u32>::new(port).read()
}

// TODO: Remove
pub unsafe fn outd(port: u16, value: u32) {
    Pio::<u32>::new(port).write(value);
}
<|endoftext|>


<commit_before>// Copyright 2012-2014 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 llvm::ValueRef;
use rustc::middle::ty::{self, Ty, HasTypeFlags};
use rustc::mir::repr as mir;
use rustc::mir::tcx::LvalueTy;
use trans::adt;
use trans::base;
use trans::build;
use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::machine;

use std::ptr;

use super::{MirContext, TempRef};

#[derive(Copy, Clone)]
pub struct LvalueRef<'tcx> {
    /// Pointer to the contents of the lvalue
    pub llval: ValueRef,

    /// This lvalue's extra data if it is unsized, or null
    pub llextra: ValueRef,

    /// Monomorphized type of this lvalue, including variant information
    pub ty: LvalueTy<'tcx>,
}

impl<'tcx> LvalueRef<'tcx> {
    pub fn new_sized(llval: ValueRef, lvalue_ty: LvalueTy<'tcx>) -> LvalueRef<'tcx> {
        LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
    }

    pub fn alloca<'bcx>(bcx: Block<'bcx, 'tcx>,
                        ty: Ty<'tcx>,
                        name: &str)
                        -> LvalueRef<'tcx>
    {
        assert!(!ty.has_erasable_regions());
        let lltemp = base::alloc_ty(bcx, ty, name);
        LvalueRef::new_sized(lltemp, LvalueTy::from_ty(ty))
    }
}

impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
    pub fn lvalue_len(&mut self,
                      bcx: Block<'bcx, 'tcx>,
                      lvalue: LvalueRef<'tcx>)
                      -> ValueRef {
        match lvalue.ty.to_ty(bcx.tcx()).sty {
            ty::TyArray(_, n) => common::C_uint(bcx.ccx(), n),
            ty::TySlice(_) | ty::TyStr => {
                assert!(lvalue.llextra != ptr::null_mut());
                lvalue.llextra
            }
            _ => bcx.sess().bug("unexpected type in get_base_and_len"),
        }
    }

    pub fn trans_lvalue(&mut self,
                        bcx: Block<'bcx, 'tcx>,
                        lvalue: &mir::Lvalue<'tcx>)
                        -> LvalueRef<'tcx> {
        debug!("trans_lvalue(lvalue={:?})", lvalue);

        let fcx = bcx.fcx;
        let ccx = fcx.ccx;
        let tcx = bcx.tcx();
        match *lvalue {
            mir::Lvalue::Var(index) => self.vars[index as usize],
            mir::Lvalue::Temp(index) => match self.temps[index as usize] {
                TempRef::Lvalue(lvalue) =>
                    lvalue,
                TempRef::Operand(..) =>
                    tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)),
            },
            mir::Lvalue::Arg(index) => self.args[index as usize],
            mir::Lvalue::Static(def_id) => {
                let const_ty = self.mir.lvalue_ty(tcx, lvalue);
                LvalueRef::new_sized(
                    common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)),
                    const_ty)
            },
            mir::Lvalue::ReturnPointer => {
                let return_ty = bcx.monomorphize(&self.mir.return_ty);
                let llval = fcx.get_ret_slot(bcx, return_ty, "return");
                LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap()))
            }
            mir::Lvalue::Projection(ref projection) => {
                let tr_base = self.trans_lvalue(bcx, &projection.base);
                let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
                let (llprojected, llextra) = match projection.elem {
                    mir::ProjectionElem::Deref => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
                            (base::load_ty(bcx, tr_base.llval, base_ty),
                             ptr::null_mut())
                        } else {
                            base::load_fat_ptr(bcx, tr_base.llval, base_ty)
                        }
                    }
                    mir::ProjectionElem::Field(ref field) => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        let base_repr = adt::represent_type(ccx, base_ty);
                        let discr = match tr_base.ty {
                            LvalueTy::Ty { .. } => 0,
                            LvalueTy::Downcast { adt_def: _, substs: _, variant_index: v } => v,
                        };
                        let discr = discr as u64;
                        let is_sized = common::type_is_sized(tcx, projected_ty.to_ty(tcx));
                        let base = if is_sized {
                            adt::MaybeSizedValue::sized(tr_base.llval)
                        } else {
                            adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
                        };
                        (adt::trans_field_ptr(bcx, &base_repr, base, discr, field.index()),
                         if is_sized {
                             ptr::null_mut()
                         } else {
                             tr_base.llextra
                         })
                    }
                    mir::ProjectionElem::Index(ref index) => {
                        let index = self.trans_operand(bcx, index);
                        let llindex = self.prepare_index(bcx, index.immediate());
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: false,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let llindex = self.prepare_index(bcx, lloffset);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: true,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let lllen = self.lvalue_len(bcx, tr_base);
                        let llindex = build::Sub(bcx, lllen, lloffset, DebugLoc::None);
                        let llindex = self.prepare_index(bcx, llindex);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::Downcast(..) => {
                        (tr_base.llval, tr_base.llextra)
                    }
                };
                LvalueRef {
                    llval: llprojected,
                    llextra: llextra,
                    ty: projected_ty,
                }
            }
        }
    }

    /// Adjust the bitwidth of an index since LLVM is less forgiving
    /// than we are.
    ///
    /// nmatsakis: is this still necessary? Not sure.
    fn prepare_index(&mut self,
                     bcx: Block<'bcx, 'tcx>,
                     llindex: ValueRef)
                     -> ValueRef
    {
        let ccx = bcx.ccx();
        let index_size = machine::llbitsize_of_real(bcx.ccx(), common::val_ty(llindex));
        let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type());
        if index_size < int_size {
            build::ZExt(bcx, llindex, ccx.int_type())
        } else if index_size > int_size {
            build::Trunc(bcx, llindex, ccx.int_type())
        } else {
            llindex
        }
    }
}
<commit_msg>Auto merge of #30486 - nagisa:mir-fix-geps, r=luqmana<commit_after>// Copyright 2012-2014 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 llvm::ValueRef;
use rustc::middle::ty::{self, Ty, HasTypeFlags};
use rustc::mir::repr as mir;
use rustc::mir::tcx::LvalueTy;
use trans::adt;
use trans::base;
use trans::build;
use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::machine;

use std::ptr;

use super::{MirContext, TempRef};

#[derive(Copy, Clone)]
pub struct LvalueRef<'tcx> {
    /// Pointer to the contents of the lvalue
    pub llval: ValueRef,

    /// This lvalue's extra data if it is unsized, or null
    pub llextra: ValueRef,

    /// Monomorphized type of this lvalue, including variant information
    pub ty: LvalueTy<'tcx>,
}

impl<'tcx> LvalueRef<'tcx> {
    pub fn new_sized(llval: ValueRef, lvalue_ty: LvalueTy<'tcx>) -> LvalueRef<'tcx> {
        LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
    }

    pub fn alloca<'bcx>(bcx: Block<'bcx, 'tcx>,
                        ty: Ty<'tcx>,
                        name: &str)
                        -> LvalueRef<'tcx>
    {
        assert!(!ty.has_erasable_regions());
        let lltemp = base::alloc_ty(bcx, ty, name);
        LvalueRef::new_sized(lltemp, LvalueTy::from_ty(ty))
    }
}

impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
    pub fn lvalue_len(&mut self,
                      bcx: Block<'bcx, 'tcx>,
                      lvalue: LvalueRef<'tcx>)
                      -> ValueRef {
        match lvalue.ty.to_ty(bcx.tcx()).sty {
            ty::TyArray(_, n) => common::C_uint(bcx.ccx(), n),
            ty::TySlice(_) | ty::TyStr => {
                assert!(lvalue.llextra != ptr::null_mut());
                lvalue.llextra
            }
            _ => bcx.sess().bug("unexpected type in get_base_and_len"),
        }
    }

    pub fn trans_lvalue(&mut self,
                        bcx: Block<'bcx, 'tcx>,
                        lvalue: &mir::Lvalue<'tcx>)
                        -> LvalueRef<'tcx> {
        debug!("trans_lvalue(lvalue={:?})", lvalue);

        let fcx = bcx.fcx;
        let ccx = fcx.ccx;
        let tcx = bcx.tcx();
        match *lvalue {
            mir::Lvalue::Var(index) => self.vars[index as usize],
            mir::Lvalue::Temp(index) => match self.temps[index as usize] {
                TempRef::Lvalue(lvalue) =>
                    lvalue,
                TempRef::Operand(..) =>
                    tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)),
            },
            mir::Lvalue::Arg(index) => self.args[index as usize],
            mir::Lvalue::Static(def_id) => {
                let const_ty = self.mir.lvalue_ty(tcx, lvalue);
                LvalueRef::new_sized(
                    common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)),
                    const_ty)
            },
            mir::Lvalue::ReturnPointer => {
                let return_ty = bcx.monomorphize(&self.mir.return_ty);
                let llval = fcx.get_ret_slot(bcx, return_ty, "return");
                LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap()))
            }
            mir::Lvalue::Projection(ref projection) => {
                let tr_base = self.trans_lvalue(bcx, &projection.base);
                let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
                let (llprojected, llextra) = match projection.elem {
                    mir::ProjectionElem::Deref => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
                            (base::load_ty(bcx, tr_base.llval, base_ty),
                             ptr::null_mut())
                        } else {
                            base::load_fat_ptr(bcx, tr_base.llval, base_ty)
                        }
                    }
                    mir::ProjectionElem::Field(ref field) => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        let base_repr = adt::represent_type(ccx, base_ty);
                        let discr = match tr_base.ty {
                            LvalueTy::Ty { .. } => 0,
                            LvalueTy::Downcast { adt_def: _, substs: _, variant_index: v } => v,
                        };
                        let discr = discr as u64;
                        let is_sized = common::type_is_sized(tcx, projected_ty.to_ty(tcx));
                        let base = if is_sized {
                            adt::MaybeSizedValue::sized(tr_base.llval)
                        } else {
                            adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
                        };
                        (adt::trans_field_ptr(bcx, &base_repr, base, discr, field.index()),
                         if is_sized {
                             ptr::null_mut()
                         } else {
                             tr_base.llextra
                         })
                    }
                    mir::ProjectionElem::Index(ref index) => {
                        let index = self.trans_operand(bcx, index);
                        let llindex = self.prepare_index(bcx, index.immediate());
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: false,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let llindex = self.prepare_index(bcx, lloffset);
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: true,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let lllen = self.lvalue_len(bcx, tr_base);
                        let llindex = build::Sub(bcx, lllen, lloffset, DebugLoc::None);
                        let llindex = self.prepare_index(bcx, llindex);
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::Downcast(..) => {
                        (tr_base.llval, tr_base.llextra)
                    }
                };
                LvalueRef {
                    llval: llprojected,
                    llextra: llextra,
                    ty: projected_ty,
                }
            }
        }
    }

    /// Adjust the bitwidth of an index since LLVM is less forgiving
    /// than we are.
    ///
    /// nmatsakis: is this still necessary? Not sure.
    fn prepare_index(&mut self,
                     bcx: Block<'bcx, 'tcx>,
                     llindex: ValueRef)
                     -> ValueRef
    {
        let ccx = bcx.ccx();
        let index_size = machine::llbitsize_of_real(bcx.ccx(), common::val_ty(llindex));
        let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type());
        if index_size < int_size {
            build::ZExt(bcx, llindex, ccx.int_type())
        } else if index_size > int_size {
            build::Trunc(bcx, llindex, ccx.int_type())
        } else {
            llindex
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove unit-let-binding<commit_after><|endoftext|>


<commit_before>extern crate compiletest_rs as compiletest;

use std::path::{PathBuf, Path};
use std::io::Write;

fn compile_fail(sysroot: &Path) {
    let flags = format!("--sysroot {} -Dwarnings", sysroot.to_str().expect("non utf8 path"));
    for_all_targets(&sysroot, |target| {
        let mut config = compiletest::default_config();
        config.host_rustcflags = Some(flags.clone());
        config.mode = "compile-fail".parse().expect("Invalid mode");
        config.run_lib_path = Path::new(sysroot).join("lib").join("rustlib").join(&target).join("lib");
        config.rustc_path = "target/debug/miri".into();
        config.src_base = PathBuf::from("tests/compile-fail".to_string());
        config.target = target.to_owned();
        config.target_rustcflags = Some(flags.clone());
        compiletest::run_tests(&config);
    });
}

fn run_pass() {
    let mut config = compiletest::default_config();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from("tests/run-pass".to_string());
    config.target_rustcflags = Some("-Dwarnings".to_string());
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, host: &str) {
    let mut config = compiletest::default_config();
    config.mode = "mir-opt".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = PathBuf::from("target/debug/miri");
    // don't actually execute the final binary, it might be for other targets and we only care
    // about running miri, not the binary.
    config.runtool = Some("echo \"\" || ".to_owned());
    if target == host {
        std::env::set_var("MIRI_HOST_TARGET", "yes");
    }
    compiletest::run_tests(&config);
    std::env::set_var("MIRI_HOST_TARGET", "");
}

fn is_target_dir<P: Into<PathBuf>>(path: P) -> bool {
    let mut path = path.into();
    path.push("lib");
    path.metadata().map(|m| m.is_dir()).unwrap_or(false)
}

fn for_all_targets<F: FnMut(String)>(sysroot: &Path, mut f: F) {
    let target_dir = sysroot.join("lib").join("rustlib");
    println!("target dir: {}", target_dir.to_str().unwrap());
    for entry in std::fs::read_dir(target_dir).expect("invalid sysroot") {
        let entry = entry.unwrap();
        if !is_target_dir(entry.path()) { continue; }
        let target = entry.file_name().into_string().unwrap();
        let stderr = std::io::stderr();
        writeln!(stderr.lock(), "running tests for target {}", target).unwrap();
        f(target);
    }
}

#[test]
fn compile_test() {
    let sysroot = std::process::Command::new("rustc")
        .arg("--print")
        .arg("sysroot")
        .output()
        .expect("rustc not found")
        .stdout;
    let sysroot = std::str::from_utf8(&sysroot).expect("sysroot is not utf8").trim();
    let sysroot = &Path::new(&sysroot);
    let host = std::process::Command::new("rustc")
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let host = std::str::from_utf8(&host).expect("sysroot is not utf8");
    let host = host.split("\nhost: ").skip(1).next().expect("no host: part in rustc -vV");
    let host = host.split("\n").next().expect("no \n after host");
    run_pass();
    for_all_targets(&sysroot, |target| {
        miri_pass("tests/run-pass", &target, host);
        if let Ok(path) = std::env::var("MIRI_RUSTC_TEST") {
            miri_pass(&path, &target, host);
        }
    });
    compile_fail(&sysroot);
}
<commit_msg>reenable rustc run pass tests<commit_after>extern crate compiletest_rs as compiletest;

use std::path::{PathBuf, Path};
use std::io::Write;

fn compile_fail(sysroot: &Path) {
    let flags = format!("--sysroot {} -Dwarnings", sysroot.to_str().expect("non utf8 path"));
    for_all_targets(&sysroot, |target| {
        let mut config = compiletest::default_config();
        config.host_rustcflags = Some(flags.clone());
        config.mode = "compile-fail".parse().expect("Invalid mode");
        config.run_lib_path = Path::new(sysroot).join("lib").join("rustlib").join(&target).join("lib");
        config.rustc_path = "target/debug/miri".into();
        config.src_base = PathBuf::from("tests/compile-fail".to_string());
        config.target = target.to_owned();
        config.target_rustcflags = Some(flags.clone());
        compiletest::run_tests(&config);
    });
}

fn run_pass() {
    let mut config = compiletest::default_config();
    config.mode = "run-pass".parse().expect("Invalid mode");
    config.src_base = PathBuf::from("tests/run-pass".to_string());
    config.target_rustcflags = Some("-Dwarnings".to_string());
    config.host_rustcflags = Some("-Dwarnings".to_string());
    compiletest::run_tests(&config);
}

fn miri_pass(path: &str, target: &str, host: &str) {
    let mut config = compiletest::default_config();
    config.mode = "mir-opt".parse().expect("Invalid mode");
    config.src_base = PathBuf::from(path);
    config.target = target.to_owned();
    config.host = host.to_owned();
    config.rustc_path = PathBuf::from("target/debug/miri");
    // don't actually execute the final binary, it might be for other targets and we only care
    // about running miri, not the binary.
    config.runtool = Some("echo \"\" || ".to_owned());
    if target == host {
        std::env::set_var("MIRI_HOST_TARGET", "yes");
    }
    compiletest::run_tests(&config);
    std::env::set_var("MIRI_HOST_TARGET", "");
}

fn is_target_dir<P: Into<PathBuf>>(path: P) -> bool {
    let mut path = path.into();
    path.push("lib");
    path.metadata().map(|m| m.is_dir()).unwrap_or(false)
}

fn for_all_targets<F: FnMut(String)>(sysroot: &Path, mut f: F) {
    let target_dir = sysroot.join("lib").join("rustlib");
    println!("target dir: {}", target_dir.to_str().unwrap());
    for entry in std::fs::read_dir(target_dir).expect("invalid sysroot") {
        let entry = entry.unwrap();
        if !is_target_dir(entry.path()) { continue; }
        let target = entry.file_name().into_string().unwrap();
        let stderr = std::io::stderr();
        writeln!(stderr.lock(), "running tests for target {}", target).unwrap();
        f(target);
    }
}

#[test]
fn compile_test() {
    let sysroot = std::process::Command::new("rustc")
        .arg("--print")
        .arg("sysroot")
        .output()
        .expect("rustc not found")
        .stdout;
    let sysroot = std::str::from_utf8(&sysroot).expect("sysroot is not utf8").trim();
    let sysroot = &Path::new(&sysroot);
    let host = std::process::Command::new("rustc")
        .arg("-vV")
        .output()
        .expect("rustc not found for -vV")
        .stdout;
    let host = std::str::from_utf8(&host).expect("sysroot is not utf8");
    let host = host.split("\nhost: ").skip(1).next().expect("no host: part in rustc -vV");
    let host = host.split("\n").next().expect("no \n after host");

    if let Ok(path) = std::env::var("MIRI_RUSTC_TEST") {
        let mut mir_not_found = 0;
        let mut crate_not_found = 0;
        let mut success = 0;
        let mut failed = 0;
        for file in std::fs::read_dir(path).unwrap() {
            let file = file.unwrap();
            let path = file.path();
            if !file.metadata().unwrap().is_file() || !path.to_str().unwrap().ends_with(".rs") {
                continue;
            }
            let stderr = std::io::stderr();
            write!(stderr.lock(), "test [miri-pass] {} ... ", path.display()).unwrap();
            let mut cmd = std::process::Command::new("target/debug/miri");
            cmd.arg(path);
            let libs = Path::new(&sysroot).join("lib");
            let sysroot = libs.join("rustlib").join(&host).join("lib");
            let paths = std::env::join_paths(&[libs, sysroot]).unwrap();
            cmd.env(compiletest::procsrv::dylib_env_var(), paths);

            match cmd.output() {
                Ok(ref output) if output.status.success() => {
                    success += 1;
                    writeln!(stderr.lock(), "ok").unwrap()
                },
                Ok(output) => {
                    let output_err = std::str::from_utf8(&output.stderr).unwrap();
                    if let Some(text) = output_err.splitn(2, "no mir for `").nth(1) {
                        mir_not_found += 1;
                        let end = text.find('`').unwrap();
                        writeln!(stderr.lock(), "NO MIR FOR `{}`", &text[..end]).unwrap();
                    } else if let Some(text) = output_err.splitn(2, "can't find crate for `").nth(1) {
                        crate_not_found += 1;
                        let end = text.find('`').unwrap();
                        writeln!(stderr.lock(), "CAN'T FIND CRATE FOR `{}`", &text[..end]).unwrap();
                    } else {
                        failed += 1;
                        writeln!(stderr.lock(), "FAILED with exit code {:?}", output.status.code()).unwrap();
                        writeln!(stderr.lock(), "stdout: \n {}", std::str::from_utf8(&output.stdout).unwrap()).unwrap();
                        writeln!(stderr.lock(), "stderr: \n {}", output_err).unwrap();
                    }
                }
                Err(e) => {
                    writeln!(stderr.lock(), "FAILED: {}", e).unwrap();
                    panic!("failed to execute miri");
                },
            }
        }
        let stderr = std::io::stderr();
        writeln!(stderr.lock(), "{} success, {} mir not found, {} crate not found, {} failed", success, mir_not_found, crate_not_found, failed).unwrap();
        assert_eq!(failed, 0, "some tests failed");
    } else {
        run_pass();
        for_all_targets(&sysroot, |target| {
            miri_pass("tests/run-pass", &target, host);
        });
        compile_fail(&sysroot);
    }
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #60572 - tmandry:issue-59972, r=RalfJung,oli-obk<commit_after>// compile-flags: --edition=2018

#![feature(async_await, await_macro)]

pub enum Uninhabited { }

fn uninhabited_async() -> Uninhabited {
    unreachable!()
}

async fn noop() { }

#[allow(unused)]
async fn contains_never() {
    let error = uninhabited_async();
    await!(noop());
    let error2 = error;
}

#[allow(unused_must_use)]
fn main() {
    contains_never();
}
<|endoftext|>


<commit_before><commit_msg>make sure opening a file fails with isolation enabled<commit_after>// ignore-windows: File handling is not implemented yet
// error-pattern: `open` not available when isolation is enabled

fn main() {
    let _file = std::fs::File::open("file.txt").unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #34262 - dsprenkels:enum_pattern_resolve_ice, r=eddyb<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.

fn main() {
    match 0 {
        aaa::bbb(_) => ()
        //~^ ERROR failed to resolve. Use of undeclared type or module `aaa`
    };
}
<|endoftext|>


<commit_before><commit_msg>FizzBuzz using pattern matching<commit_after>use std::iter;

fn main() {
    for i in iter::range_inclusive(1, 100) {
        match (i % 3, i % 5) {
            (0, 0) => println!("{}: FizzBuzz", i),
            (0, _) => println!("{}: Fizz", i),
            (_, 0) => println!("{}: Buzz", i),
            (_, _) => {}
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>base v1 complete<commit_after>
extern crate sdl;

use sdl::video::{SurfaceFlag, VideoFlag, Color};
use sdl::event::{Event, Key, Mouse};

fn init(screen_width: isize, screen_height: isize) -> sdl::video::Surface {
    sdl::init(&[sdl::InitFlag::Video]);
    sdl::wm::set_caption("mines", "mines");

    let screen = match sdl::video::set_video_mode(screen_width, screen_height, 32,
                                                  &[SurfaceFlag::HWSurface],
                                                  &[VideoFlag::DoubleBuf]) {
        Ok(screen) => screen,
        Err(err) => panic!("failed to set video mode: {}", err)
    };
    screen
}

fn draw_field(ref field: &Vec<Vec<bool>>, length: i16, screen: &sdl::video::Surface) {
    let mut n = 0;
    for ref i in field.iter() {
        let mut m = 0;
        for ref j in i.iter() {
            screen.fill_rect(Some(
                sdl::Rect {x: m as i16*length as i16, y: n as i16*length as i16, w: length as u16, h: length as u16}
            ), if **j {Color::RGB(0, 0, 0)} else {Color::RGB(255, 255, 255)});
            m += 1;
        }
        n += 1;
    }
}

fn flip_field(ref mut field: &mut Vec<Vec<bool>>, x: i16, y: i16, size: i16) {
    let i = (x/size) as usize;
    let j = (y/size) as usize;
    field[i][j] = !(field[i][j]);
}

fn main() {
    const WIDTH: usize = 40;
    const HEIGHT: usize = 30;
    const SIZE: usize = 25;

    let field = &mut vec![vec![false; WIDTH]; HEIGHT];

    let screen = init((SIZE*WIDTH) as isize, (SIZE*HEIGHT) as isize);
    loop {
        match sdl::event::poll_event() {
            Event::Quit => break,
            Event::MouseButton(_, down, mx, my) => {
                if down {
                    flip_field(field, my as i16, mx as i16, SIZE as i16);
                    for ref i in field.iter(){
                        println!("{:?}", i);
                    }
                    println!("");
                }
            },
            Event::Key(k, _, _, _)
                if k == Key::Escape
                    => break,
            _ => {}
        }
        draw_field(&field, SIZE as i16, &screen);
        screen.flip();
    }

    sdl::quit();
}
<|endoftext|>


<commit_before><commit_msg>Supply content-length with HEAD requests<commit_after><|endoftext|>


<commit_before><commit_msg>Add 2021 test.<commit_after>// rustfmt-edition: 2021

use ::happy::new::year;
<|endoftext|>


<commit_before>pub use crate::bundle::keys::{Error as KeyValueError, KeyValue};
use crate::{bundle::keys, models::IsoKey};
use serde::{
    de::{self, Deserializer},
    ser::{SerializeMap, Serializer},
    Deserialize, Serialize,
};
use snafu::{ResultExt, Snafu};
use std::{collections::BTreeMap, fmt, str::FromStr};

/// Map of keys on a desktop keyboard
///
/// A full keymap has 48 items. It has two forms of representation, a
/// string-based one with 12 items per line; the other representation is a
/// regular YAML map. Some keys might be omitted, which is represented as
/// `\u{0}` (the unicode escape for a `NULL` byte) in the string representation
/// or `None` in the map.
///
/// We will try to serialize everything that is more than half of a full map as
/// string-based key map; other sizes will be regular maps in YAML.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DesktopKeyMap(pub(crate) BTreeMap<IsoKey, keys::KeyValue>);

impl<'de> Deserialize<'de> for DesktopKeyMap {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Debug, Clone, PartialEq, Eq)]
        #[derive(Serialize, Deserialize)]
        #[serde(untagged)]
        enum Wat {
            String(String),
            Map(BTreeMap<IsoKey, keys::KeyValue>),
        }

        match Wat::deserialize(deserializer)? {
            Wat::String(s) => Ok(s.parse().map_err(de::Error::custom)?),
            Wat::Map(m) => Ok(DesktopKeyMap(m)),
        }
    }
}

impl Serialize for DesktopKeyMap {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        const KEYMAP_FULL_SIZE: usize = 48;
        if self.0.len() < KEYMAP_FULL_SIZE / 2 {
            let mut map = serializer.serialize_map(Some(self.0.len()))?;
            for (k, v) in &self.0 {
                map.serialize_entry(k, v)?;
            }
            map.end()
        } else {
            serializer.serialize_str(&self.to_string())
        }
    }
}

impl FromStr for DesktopKeyMap {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use strum::IntoEnumIterator;

        let map: Result<_, Error> = s
            .lines()
            .flat_map(|l| l.split_whitespace())
            .zip(IsoKey::iter())
            .map(|(val, key)| Ok((key, keys::KeyValue(keys::deserialize(val)))))
            .collect();

        Ok(DesktopKeyMap(map?))
    }
}

impl fmt::Display for DesktopKeyMap {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let keys: Vec<String> = self.0.values().map(|v| keys::serialize(&v.0)).collect();
        let width = keys
            .iter()
            .map(|x| unic_segment::Graphemes::new(x).count())
            .max()
            .unwrap_or(1);
        let lines: Vec<&[String]> = [
            &keys.get(0..13),
            &keys.get(13..25),
            &keys.get(25..37),
            &keys.get(37..48),
            &keys.get(48..),
        ]
        .iter()
        .filter_map(|x| x.filter(|x| !x.is_empty()))
        .collect();

        for (idx, line) in lines.into_iter().enumerate() {
            use std::fmt::Write;
            let mut l = String::new();

            if idx == 1 || idx == 2 {
                write!(&mut l, "{key:width$} ", key = " ", width = width)?;
            }
            for key in line {
                write!(&mut l, "{key:width$} ", key = key, width = width)?;
            }

            writeln!(f, "{}", l.trim_end())?;
        }

        Ok(())
    }
}

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("{}", description))]
    ParseError {
        description: String,
        backtrace: snafu::Backtrace,
    },
    #[snafu(display("failed process key `{}`: {}", input, source))]
    KeyError {
        input: String,
        source: KeyValueError,
        backtrace: snafu::Backtrace,
    },
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(transparent)]
pub struct MobileKeyMap(pub(crate) Vec<Vec<String>>);

impl<'de> Deserialize<'de> for MobileKeyMap {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(MobileKeyMap(
            s.lines()
                .map(|l| l.split_whitespace().map(String::from).collect())
                .collect(),
        ))
    }
}
<commit_msg>Serialize MobileKeyMap in its proper glory<commit_after>pub use crate::bundle::keys::{Error as KeyValueError, KeyValue};
use crate::{bundle::keys, models::IsoKey};
use serde::{
    de::{self, Deserializer},
    ser::{SerializeMap, Serializer},
    Deserialize, Serialize,
};
use snafu::{ResultExt, Snafu};
use std::{collections::BTreeMap, fmt, str::FromStr};

/// Map of keys on a desktop keyboard
///
/// A full keymap has 48 items. It has two forms of representation, a
/// string-based one with 12 items per line; the other representation is a
/// regular YAML map. Some keys might be omitted, which is represented as
/// `\u{0}` (the unicode escape for a `NULL` byte) in the string representation
/// or `None` in the map.
///
/// We will try to serialize everything that is more than half of a full map as
/// string-based key map; other sizes will be regular maps in YAML.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DesktopKeyMap(pub(crate) BTreeMap<IsoKey, keys::KeyValue>);

impl<'de> Deserialize<'de> for DesktopKeyMap {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Debug, Clone, PartialEq, Eq)]
        #[derive(Serialize, Deserialize)]
        #[serde(untagged)]
        enum Wat {
            String(String),
            Map(BTreeMap<IsoKey, keys::KeyValue>),
        }

        match Wat::deserialize(deserializer)? {
            Wat::String(s) => Ok(s.parse().map_err(de::Error::custom)?),
            Wat::Map(m) => Ok(DesktopKeyMap(m)),
        }
    }
}

impl Serialize for DesktopKeyMap {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        const KEYMAP_FULL_SIZE: usize = 48;
        if self.0.len() < KEYMAP_FULL_SIZE / 2 {
            let mut map = serializer.serialize_map(Some(self.0.len()))?;
            for (k, v) in &self.0 {
                map.serialize_entry(k, v)?;
            }
            map.end()
        } else {
            serializer.serialize_str(&self.to_string())
        }
    }
}

impl FromStr for DesktopKeyMap {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        use strum::IntoEnumIterator;

        let map: Result<_, Error> = s
            .lines()
            .flat_map(|l| l.split_whitespace())
            .zip(IsoKey::iter())
            .map(|(val, key)| Ok((key, keys::KeyValue(keys::deserialize(val)))))
            .collect();

        Ok(DesktopKeyMap(map?))
    }
}

impl fmt::Display for DesktopKeyMap {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let keys: Vec<String> = self.0.values().map(|v| keys::serialize(&v.0)).collect();
        let width = keys
            .iter()
            .map(|x| unic_segment::Graphemes::new(x).count())
            .max()
            .unwrap_or(1);
        let lines: Vec<&[String]> = [
            &keys.get(0..13),
            &keys.get(13..25),
            &keys.get(25..37),
            &keys.get(37..48),
            &keys.get(48..),
        ]
        .iter()
        .filter_map(|x| x.filter(|x| !x.is_empty()))
        .collect();

        for (idx, line) in lines.into_iter().enumerate() {
            use std::fmt::Write;
            let mut l = String::new();

            if idx == 1 || idx == 2 {
                write!(&mut l, "{key:width$} ", key = " ", width = width)?;
            }
            for key in line {
                write!(&mut l, "{key:width$} ", key = key, width = width)?;
            }

            writeln!(f, "{}", l.trim_end())?;
        }

        Ok(())
    }
}

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("{}", description))]
    ParseError {
        description: String,
        backtrace: snafu::Backtrace,
    },
    #[snafu(display("failed process key `{}`: {}", input, source))]
    KeyError {
        input: String,
        source: KeyValueError,
        backtrace: snafu::Backtrace,
    },
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MobileKeyMap(pub(crate) Vec<Vec<String>>);

impl<'de> Deserialize<'de> for MobileKeyMap {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        Ok(MobileKeyMap(
            s.lines()
                .map(|l| l.split_whitespace().map(String::from).collect())
                .collect(),
        ))
    }
}

impl Serialize for MobileKeyMap {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let lines: Vec<String> = self.0.iter().map(|line| line.join(" ")).collect();
        let max_len = lines.iter().map(|x| x.trim().len()).max().unwrap_or(0);

        let mut res = String::new();
        for line in &lines {
            res.push_str(&format!("{line:^width$}", line = line, width = max_len));
            res.push_str("\n");
        }

        serializer.serialize_str(&res)
    }
}
<|endoftext|>


<commit_before><commit_msg>Move definition of the collected metrics<commit_after><|endoftext|>


<commit_before>use core::usize;

use io::{Read, Write, Seek, SeekFrom};
use str;
use string::{String, ToString};
use vec::Vec;

use syscall::{sys_open, sys_dup, sys_close, sys_execve, sys_fpath, sys_ftruncate, sys_read, sys_write, sys_lseek, sys_fsync, sys_chdir, sys_mkdir};
use syscall::common::{O_RDWR, O_CREAT, O_TRUNC, SEEK_SET, SEEK_CUR, SEEK_END};

/// A Unix-style file
pub struct File {
    /// The id for the file
    fd: usize,
}

impl File {
    pub fn exec(path: &str, args: &[&str]) -> bool {
        let path_c = path.to_string() + "\0";

        let mut args_vec: Vec<String> = Vec::new();
        for arg in args.iter() {
            args_vec.push(arg.to_string() + "\0");
        }

        let mut args_c: Vec<*const u8> = Vec::new();
        for arg_vec in args_vec.iter() {
            args_c.push(arg_vec.as_ptr());
        }
        args_c.push(0 as *const u8);

        unsafe {
            sys_execve(path_c.as_ptr(), args_c.as_ptr()) == 0
        }
    }

    /// Open a new file using a path
    pub fn open(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_RDWR, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Create a new file using a path
    pub fn create(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_CREAT | O_RDWR | O_TRUNC, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Duplicate the file
    pub fn dup(&self) -> Option<File> {
        unsafe{
            let new_fd = sys_dup(self.fd);
            if new_fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: new_fd
                })
            }
        }
    }

    /// Get the canonical path of the file
    pub fn path(&self) -> Option<String> {
        unsafe {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = sys_fpath(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(String::from_utf8_unchecked(Vec::from(&buf[0..count])))
            }
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }

    pub fn set_len(&mut self, size: usize) -> bool {
        unsafe { sys_ftruncate(self.fd, size) == 0 }
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Seek for File {
    /// Seek a given position
    fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let (whence, offset) = match pos {
            SeekFrom::Start(offset) => (SEEK_SET, offset as isize),
            SeekFrom::Current(offset) => (SEEK_CUR, offset),
            SeekFrom::End(offset) => (SEEK_END, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == usize::MAX {
            None
        } else {
            Some(position)
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}

pub struct DirEntry {
    path: String
}

impl DirEntry {
    pub fn path(&self) -> &str {
        &self.path
    }
}

pub struct ReadDir {
    file: File
}

impl Iterator for ReadDir {
    type Item = DirEntry;
    fn next(&mut self) -> Option<DirEntry> {
        let mut path = String::new();
        let mut buf: [u8; 1] = [0; 1];
        loop {
            match self.file.read(&mut buf) {
                Some(0) => break,
                Some(count) => {
                    if buf[0] == 10 {
                        break;
                    } else {
                        path.push_str(unsafe { str::from_utf8_unchecked(&buf[.. count]) });
                    }
                },
                None => break
            }
        }
        if path.is_empty() {
            None
        }else {
            Some(DirEntry {
                path: path
            })
        }
    }
}

pub fn read_dir(path: &str) -> Option<ReadDir> {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        Some(ReadDir{
            file: file
        })
    } else {
        None
    }
}

pub fn change_cwd(path: &str) -> bool {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        if let Some(file_path) = file.path() {
            if unsafe { sys_chdir((file_path + "\0").as_ptr()) } == 0 {
                return true;
            }
        }
    }

    false
}
<commit_msg>Method added to create a directory, with a given path<commit_after>use core::usize;

use io::{Read, Write, Seek, SeekFrom};
use str;
use string::{String, ToString};
use vec::Vec;

use syscall::{sys_open, sys_dup, sys_close, sys_execve, sys_fpath, sys_ftruncate, sys_read, sys_write, sys_lseek, sys_fsync, sys_chdir, sys_mkdir};
use syscall::common::{O_RDWR, O_CREAT, O_TRUNC, SEEK_SET, SEEK_CUR, SEEK_END};

/// A Unix-style file
pub struct File {
    /// The id for the file
    fd: usize,
}

impl File {
    pub fn exec(path: &str, args: &[&str]) -> bool {
        let path_c = path.to_string() + "\0";

        let mut args_vec: Vec<String> = Vec::new();
        for arg in args.iter() {
            args_vec.push(arg.to_string() + "\0");
        }

        let mut args_c: Vec<*const u8> = Vec::new();
        for arg_vec in args_vec.iter() {
            args_c.push(arg_vec.as_ptr());
        }
        args_c.push(0 as *const u8);

        unsafe {
            sys_execve(path_c.as_ptr(), args_c.as_ptr()) == 0
        }
    }

    /// Open a new file using a path
    pub fn open(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_RDWR, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Create a new file using a path
    pub fn create(path: &str) -> Option<File> {
        unsafe {
            let fd = sys_open((path.to_string() + "\0").as_ptr(), O_CREAT | O_RDWR | O_TRUNC, 0);
            if fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: fd
                })
            }
        }
    }

    /// Duplicate the file
    pub fn dup(&self) -> Option<File> {
        unsafe{
            let new_fd = sys_dup(self.fd);
            if new_fd == usize::MAX {
                None
            } else {
                Some(File {
                    fd: new_fd
                })
            }
        }
    }

    /// Get the canonical path of the file
    pub fn path(&self) -> Option<String> {
        unsafe {
            let mut buf: [u8; 4096] = [0; 4096];
            let count = sys_fpath(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(String::from_utf8_unchecked(Vec::from(&buf[0..count])))
            }
        }
    }

    /// Flush the io
    pub fn sync(&mut self) -> bool {
        unsafe { sys_fsync(self.fd) == 0 }
    }

    pub fn set_len(&mut self, size: usize) -> bool {
        unsafe { sys_ftruncate(self.fd, size) == 0 }
    }
}

impl Read for File {
    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        unsafe {
            let count = sys_read(self.fd, buf.as_mut_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Write for File {
    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        unsafe {
            let count = sys_write(self.fd, buf.as_ptr(), buf.len());
            if count == usize::MAX {
                None
            } else {
                Some(count)
            }
        }
    }
}

impl Seek for File {
    /// Seek a given position
    fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        let (whence, offset) = match pos {
            SeekFrom::Start(offset) => (SEEK_SET, offset as isize),
            SeekFrom::Current(offset) => (SEEK_CUR, offset),
            SeekFrom::End(offset) => (SEEK_END, offset),
        };

        let position = unsafe { sys_lseek(self.fd, offset, whence) };
        if position == usize::MAX {
            None
        } else {
            Some(position)
        }
    }
}

impl Drop for File {
    fn drop(&mut self) {
        unsafe {
            sys_close(self.fd);
        }
    }
}

pub struct DirEntry {
    path: String
}

impl DirEntry {
    pub fn path(&self) -> &str {
        &self.path
    }

    /// Create a new directory, using a path
    /// The default mode of the directory is 744
    pub fn create(path: &str) -> Option<DirEntry> {
        unsafe {
            let dir = sys_mkdir((path.to_string() + "\0").as_ptr(), 744);
            if dir == usize::MAX {
                None
            } else {
                Some(DirEntry {
                    path: path.to_string()
                })
            }
        }
    }

}

pub struct ReadDir {
    file: File
}

impl Iterator for ReadDir {
    type Item = DirEntry;
    fn next(&mut self) -> Option<DirEntry> {
        let mut path = String::new();
        let mut buf: [u8; 1] = [0; 1];
        loop {
            match self.file.read(&mut buf) {
                Some(0) => break,
                Some(count) => {
                    if buf[0] == 10 {
                        break;
                    } else {
                        path.push_str(unsafe { str::from_utf8_unchecked(&buf[.. count]) });
                    }
                },
                None => break
            }
        }
        if path.is_empty() {
            None
        }else {
            Some(DirEntry {
                path: path
            })
        }
    }
}

pub fn read_dir(path: &str) -> Option<ReadDir> {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        Some(ReadDir{
            file: file
        })
    } else {
        None
    }
}

pub fn change_cwd(path: &str) -> bool {
    let file_option = if path.is_empty() || path.ends_with('/') {
        File::open(path)
    } else {
        File::open(&(path.to_string() + "/"))
    };

    if let Some(file) = file_option {
        if let Some(file_path) = file.path() {
            if unsafe { sys_chdir((file_path + "\0").as_ptr()) } == 0 {
                return true;
            }
        }
    }

    false
}
<|endoftext|>


<commit_before><commit_msg>Distinguish between network/decode errors in network message decode<commit_after><|endoftext|>


<commit_before><commit_msg>Add subcommand "help"<commit_after><|endoftext|>