<commit_before>use regex::Regex;
use http::{Method, Options, Get, Post, Put, Delete, Patch};
use iron::{Ingot, Request, Response, Alloy};
use iron::ingot::{Status, Continue, Unwind};

pub type Handler = |&mut Rq, &mut Rs, &mut A| -> ()

#[deriving(Clone)]
pub struct Router {
    options: Vec<Method>,
    routes: Vec<Route>
}

#[deriving(Clone)]
struct Route {
    method: Method,
    matches: Regex,
    handler: |&mut Rq, &mut Rs, &mut A| -> ()
}

impl Router {
    fn new() -> Router { Router { options: Vec::new(), routes: Vec::new() } }
    fn addRoute(&mut self, route: Route) {
        if !self.options.contains(route.method) {
            self.options.push(route.method)
        }
        self.routes.push(route);
    }
}

<commit_msg>(feat) Added routing methods.<commit_after>use regex::Regex;
use http::{Method, Options, Get, Post, Put, Delete, Patch};
use iron::{Ingot, Request, Response, Alloy};
use iron::ingot::{Status, Continue, Unwind};

pub type Handler = |&mut Rq, &mut Rs, &mut A| -> ()

#[deriving(Clone)]
pub struct Router {
    options: Vec<Method>,
    routes: Vec<Route>
}

#[deriving(Clone)]
struct Route {
    method: Method,
    matches: Regex,
    handler: |&mut Rq, &mut Rs, &mut A| -> ()
}

impl Router {
    fn new() -> Router { Router { options: Vec::new(), routes: Vec::new() } }
    fn addRoute(&mut self, route: Route) {
        if !self.options.contains(route.method) {
            self.options.push(route.method)
        }
        self.routes.push(route);
    }
    method!(get, Get)
    method!(post, Post)
    method!(put, Put)
    method!(patch, Patch)
    method!(delete, Delete)
}

macro_rules! method {
    ($name:ident, $method:ident) => {
        fn $name(&mut self, matches: Regex, handler: Handler) {
            self.addRoute(Route {
                method: $method
                matches: matches,
                handler: handler
            });
        }
    }
}

impl<Rq: Request, Rs: Response> Ingot<Rq, Rs> for Router {
    fn enter(&mut self, req: &mut Rq, res: &mut Rs, alloy: &mut Alloy) -> Status {
        if *req.method() == Options {
            res.write(self.options.iter().map(|p| p.show()).collect().join(" "));
            return Unwind;
        }
        for route in self.routes.iter() {
            if route.matches.is_match(req.reques_uri()) {
                route.handler(req, res, alloy);
                return Unwind;
            }
        }
        Continue
    }
}

<|endoftext|>


<commit_before>use command::{Command, Query};
use command::Command::DatabaseUnmap;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;
use request_timeoutable::RequestTimeoutable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DatabaseUnmapCommand {
    command: Command,
    arguments: HashMap<String, String>,
}

impl Default for DatabaseUnmapCommand {
    fn default() -> DatabaseUnmapCommand {
        DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: HashMap::new(),
        }
    }
}

impl DatabaseUnmapCommand {
    pub fn new() -> DatabaseUnmapCommand {
        Default::default()
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![];
       for (key, value) in &self.arguments {
            query.push((key.to_owned(), value.to_owned()));
        }
        (DatabaseUnmap, query)
    }
}

impl Queryable for DatabaseUnmapCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for DatabaseUnmapCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(DatabaseUnmapCommand);
request_cancellable!(DatabaseUnmapCommand);
request_timeoutable!(DatabaseUnmapCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::DatabaseUnmap;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let database_unmap = DatabaseUnmapCommand::new();
        let expected = DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: HashMap::new(),
        };
        assert_eq!(expected, database_unmap);
    }

    #[test]
    fn test_build() {
        let actual = DatabaseUnmapCommand::new().build();
        let expected_query: Query = vec![];
        let expected = (DatabaseUnmap, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = DatabaseUnmapCommand::new().to_query();
        let url_encoded = "/d/database_unmap?";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = DatabaseUnmapCommand::new().to_command();
        let cli_encoded = "database_unmap";
        assert_eq!(cli_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: arg.to_owned(),
        };
        let query = DatabaseUnmapCommand::new();
        unsafe {
            let extended = query.set_arguments(arg.to_owned());
            assert_eq!(expected, extended);
        }
    }
}
<commit_msg>rustfmt<commit_after>use command::{Command, Query};
use command::Command::DatabaseUnmap;
use std::collections::HashMap;
use command_query::CommandQuery;
use queryable::Queryable;
use command_line::CommandLine;
use commandable::Commandable;
use extendable::Extendable;
use request_cancellable::RequestCancellable;
use request_timeoutable::RequestTimeoutable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DatabaseUnmapCommand {
    command: Command,
    arguments: HashMap<String, String>,
}

impl Default for DatabaseUnmapCommand {
    fn default() -> DatabaseUnmapCommand {
        DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: HashMap::new(),
        }
    }
}

impl DatabaseUnmapCommand {
    pub fn new() -> DatabaseUnmapCommand {
        Default::default()
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![];
        for (key, value) in &self.arguments {
            query.push((key.to_owned(), value.to_owned()));
        }
        (DatabaseUnmap, query)
    }
}

impl Queryable for DatabaseUnmapCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for DatabaseUnmapCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

extendable!(DatabaseUnmapCommand);
request_cancellable!(DatabaseUnmapCommand);
request_timeoutable!(DatabaseUnmapCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::DatabaseUnmap;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let database_unmap = DatabaseUnmapCommand::new();
        let expected = DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: HashMap::new(),
        };
        assert_eq!(expected, database_unmap);
    }

    #[test]
    fn test_build() {
        let actual = DatabaseUnmapCommand::new().build();
        let expected_query: Query = vec![];
        let expected = (DatabaseUnmap, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = DatabaseUnmapCommand::new().to_query();
        let url_encoded = "/d/database_unmap?";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = DatabaseUnmapCommand::new().to_command();
        let cli_encoded = "database_unmap";
        assert_eq!(cli_encoded.to_string(), query);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = DatabaseUnmapCommand {
            command: DatabaseUnmap,
            arguments: arg.to_owned(),
        };
        let query = DatabaseUnmapCommand::new();
        unsafe {
            let extended = query.set_arguments(arg.to_owned());
            assert_eq!(expected, extended);
        }
    }
}
<|endoftext|>


<commit_before>use std;
use std::cmp;
use std::io::stdout;
use std::io::Write;
use std::thread;
use std::time;

use termion;
use termion::clear;
use termion::color;
use termion::cursor;
use termion::input::MouseTerminal;
use termion::raw::IntoRawMode;
use termion::raw::RawTerminal;

use core::Core;
use update::Update;

pub struct Screen {
    pub stdout: MouseTerminal<RawTerminal<std::io::Stdout>>,
    pub size: (u16, u16),
}

impl Screen {
    pub fn new() -> Screen {
        let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
        write!(stdout, "{}", clear::All).unwrap();
        stdout.flush().unwrap();
        Screen {
            size: termion::terminal_size().unwrap(),
            stdout: stdout,
        }
    }

    // TODO: handle lines that are longer than terminal width.
    // Should we wrap them or truncate them?
    pub fn redraw(&mut self, update: &Update) {
        write!(self.stdout, "{}", termion::clear::All).unwrap();
        write!(self.stdout, "{}", cursor::Up(self.size.1)).unwrap();

        let nb_lines = cmp::min(update.lines.len(), self.size.1 as usize);
        if nb_lines > 0 {
            for line in update.lines.iter().take(nb_lines - 1) {
                write!(self.stdout, "{}", cursor::Left(self.size.0)).unwrap();

                if let Some(selection) = line.selection {
                    let start = selection.0 as usize;
                    let end = selection.1 as usize;
                    let mut str_before = String::new();
                    for c in line.text.chars().take(start) {
                        str_before.push(c);
                    }
                    let mut str_selection = String::new();
                    for c in line.text.chars().skip(start).take(end) {
                        str_selection.push(c);
                    }
                    let mut str_after = String::new();
                    for c in line.text.chars().skip(end) {
                        str_after.push(c);
                    }
                    write!(self.stdout, "{}{}{}{}{}{}",
                           termion::style::Reset,
                           str_before,
                           termion::color::Bg(color::Red),
                           str_selection,
                           termion::style::Reset,
                           str_after).unwrap();
                } else {
                    self.stdout.write_all(line.text.as_bytes()).unwrap();
                }
            }

            // If the last line has a trailing \n, we need to remove it
            let mut last_line = update.lines[nb_lines - 1].text.clone();
            match last_line.pop() {
                Some('\n') | None => {
                },
                Some(c) => {
                    last_line.push(c);
                }
            }
            write!(self.stdout, "{}", cursor::Left(self.size.0)).unwrap();
            self.stdout.write_all(last_line.as_bytes()).unwrap();
        }

        let cursor_line_idx = update.scroll_to.0 - update.first_line;
        let cursor_line = update.lines[cursor_line_idx as usize].text.clone();
        let mut cols =  0;
        for c in cursor_line.chars().take(update.scroll_to.1 as usize) {
            if c == '\t' {
                cols += 4;
            } else {
                cols += 1;
            }
        }
        self.scroll(cols + 1, cursor_line_idx + 1);
    }

    pub fn scroll(&mut self, col: u64, line: u64) {
        write!(self.stdout, "{}", cursor::Goto(col as u16, line as u16)).unwrap();
        self.stdout.flush().unwrap();
    }

    pub fn init(&mut self) {
        write!(self.stdout, "{}", termion::clear::All).unwrap();
        write!(self.stdout, "{}", cursor::Up(self.size.1)).unwrap();
        self.stdout.flush().unwrap();
    }

    pub fn update(&mut self, core: &mut Core) {
        // TODO: check if terminal size changed. If so, send a `render_line` command to the backend,
        // and a `scroll` command for future updates.
        if let Ok(msg) = core.update_rx.try_recv() {
            let update = Update::from_value(msg.as_object().unwrap().get("update").unwrap());
            self.redraw(&update);
        } else {
            thread::sleep(time::Duration::from_millis(10));
        }
    }
}
<commit_msg>Adds support for all current backend requests in the update() method<commit_after>use std;
use std::cmp;
use std::io::stdout;
use std::io::Write;
use std::thread;
use std::time;

use termion;
use termion::clear;
use termion::color;
use termion::cursor;
use termion::input::MouseTerminal;
use termion::raw::IntoRawMode;
use termion::raw::RawTerminal;

use core::Core;
use update::Update;

pub struct Screen {
    pub stdout: MouseTerminal<RawTerminal<std::io::Stdout>>,
    pub size: (u16, u16),
}

impl Screen {
    pub fn new() -> Screen {
        let mut stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
        write!(stdout, "{}", clear::All).unwrap();
        stdout.flush().unwrap();
        Screen {
            size: termion::terminal_size().unwrap(),
            stdout: stdout,
        }
    }

    // TODO: handle lines that are longer than terminal width.
    // Should we wrap them or truncate them?
    pub fn redraw(&mut self, update: &Update) {
        write!(self.stdout, "{}", termion::clear::All).unwrap();
        write!(self.stdout, "{}", cursor::Up(self.size.1)).unwrap();

        let nb_lines = cmp::min(update.lines.len(), self.size.1 as usize);
        if nb_lines > 0 {
            for line in update.lines.iter().take(nb_lines - 1) {
                write!(self.stdout, "{}", cursor::Left(self.size.0)).unwrap();

                if let Some(selection) = line.selection {
                    let start = selection.0 as usize;
                    let end = selection.1 as usize;
                    let mut str_before = String::new();
                    for c in line.text.chars().take(start) {
                        str_before.push(c);
                    }
                    let mut str_selection = String::new();
                    for c in line.text.chars().skip(start).take(end) {
                        str_selection.push(c);
                    }
                    let mut str_after = String::new();
                    for c in line.text.chars().skip(end) {
                        str_after.push(c);
                    }
                    write!(self.stdout, "{}{}{}{}{}{}",
                           termion::style::Reset,
                           str_before,
                           termion::color::Bg(color::Red),
                           str_selection,
                           termion::style::Reset,
                           str_after).unwrap();
                } else {
                    self.stdout.write_all(line.text.as_bytes()).unwrap();
                }
            }

            // If the last line has a trailing \n, we need to remove it
            let mut last_line = update.lines[nb_lines - 1].text.clone();
            match last_line.pop() {
                Some('\n') | None => {
                },
                Some(c) => {
                    last_line.push(c);
                }
            }
            write!(self.stdout, "{}", cursor::Left(self.size.0)).unwrap();
            self.stdout.write_all(last_line.as_bytes()).unwrap();
        }

        let cursor_line_idx = update.scroll_to.0 - update.first_line;
        let cursor_line = update.lines[cursor_line_idx as usize].text.clone();
        let mut cols =  0;
        for c in cursor_line.chars().take(update.scroll_to.1 as usize) {
            if c == '\t' {
                cols += 4;
            } else {
                cols += 1;
            }
        }
        self.scroll(cols + 1, cursor_line_idx + 1);
    }

    pub fn scroll(&mut self, col: u64, line: u64) {
        write!(self.stdout, "{}", cursor::Goto(col as u16, line as u16)).unwrap();
        self.stdout.flush().unwrap();
    }

    pub fn init(&mut self) {
        write!(self.stdout, "{}", termion::clear::All).unwrap();
        write!(self.stdout, "{}", cursor::Up(self.size.1)).unwrap();
        self.stdout.flush().unwrap();
    }

    pub fn update(&mut self, core: &mut Core) {
        // TODO: check if terminal size changed. If so, send a `render_line` command to the backend,
        // and a `scroll` command for future updates.
        if let Ok(msg) = core.update_rx.try_recv() {
            let msg_list = msg.as_array().unwrap();
            let (method, params) = (msg_list[0].as_str().unwrap(), msg_list[1].as_object().unwrap());
            if method == "update" {
                let update = Update::from_value(params.get("update").unwrap());
                self.redraw(&update);
            } else if method == "scroll_to" {
                let (col, line) = (params.get("col").unwrap().as_u64().unwrap(), params.get("line").unwrap().as_u64().unwrap());
                self.scroll(col, line);
            } else if method == "set_style" {
                // TODO: ???
            } else {
                info!("Unknown request from backend {:?}", method);
            }
        } else {
            thread::sleep(time::Duration::from_millis(10));
        }
    }
}
<|endoftext|>


<commit_before>extern crate inkwell;

use self::inkwell::OptimizationLevel::Aggressive;
use self::inkwell::context::Context;
use self::inkwell::passes::{PassManagerBuilder, PassManager, PassRegistry};

#[test]
fn test_init_all_passes_for_module() {
    let context = Context::create();
    let module = context.create_module("my_module");
    let pass_manager = PassManager::create(());

    pass_manager.add_argument_promotion_pass();
    pass_manager.add_constant_merge_pass();
    pass_manager.add_dead_arg_elimination_pass();
    pass_manager.add_function_attrs_pass();
    pass_manager.add_function_inlining_pass();
    pass_manager.add_always_inliner_pass();
    pass_manager.add_global_dce_pass();
    pass_manager.add_global_optimizer_pass();
    pass_manager.add_ip_constant_propagation_pass();
    pass_manager.add_prune_eh_pass();
    pass_manager.add_ipsccp_pass();
    pass_manager.add_internalize_pass(true);
    pass_manager.add_strip_dead_prototypes_pass();
    pass_manager.add_strip_symbol_pass();
    #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0"))]
    pass_manager.add_bb_vectorize_pass();
    pass_manager.add_loop_vectorize_pass();
    pass_manager.add_slp_vectorize_pass();
    pass_manager.add_aggressive_dce_pass();
    #[cfg(not(feature = "llvm3-6"))]
    pass_manager.add_bit_tracking_dce_pass();
    pass_manager.add_alignment_from_assumptions_pass();
    pass_manager.add_cfg_simplification_pass();
    pass_manager.add_dead_store_elimination_pass();
    pass_manager.add_scalarizer_pass();
    pass_manager.add_merged_load_store_motion_pass();
    pass_manager.add_gvn_pass();
    pass_manager.add_ind_var_simplify_pass();
    pass_manager.add_instruction_combining_pass();
    pass_manager.add_jump_threading_pass();
    pass_manager.add_licm_pass();
    pass_manager.add_loop_deletion_pass();
    pass_manager.add_loop_idiom_pass();
    pass_manager.add_loop_rotate_pass();
    pass_manager.add_loop_reroll_pass();
    pass_manager.add_loop_unroll_pass();
    pass_manager.add_loop_unswitch_pass();
    pass_manager.add_memcpy_optimize_pass();
    pass_manager.add_partially_inline_lib_calls_pass();
    pass_manager.add_lower_switch_pass();
    pass_manager.add_promote_memory_to_register_pass();
    pass_manager.add_reassociate_pass();
    pass_manager.add_sccp_pass();
    pass_manager.add_scalar_repl_aggregates_pass();
    pass_manager.add_scalar_repl_aggregates_pass_ssa();
    pass_manager.add_scalar_repl_aggregates_pass_with_threshold(1);
    pass_manager.add_simplify_lib_calls_pass();
    pass_manager.add_tail_call_elimination_pass();
    pass_manager.add_constant_propagation_pass();
    pass_manager.add_demote_memory_to_register_pass();
    pass_manager.add_verifier_pass();
    pass_manager.add_correlated_value_propagation_pass();
    pass_manager.add_early_cse_pass();
    pass_manager.add_lower_expect_intrinsic_pass();
    pass_manager.add_type_based_alias_analysis_pass();
    pass_manager.add_scoped_no_alias_aa_pass();
    pass_manager.add_basic_alias_analysis_pass();

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))]
    {
        pass_manager.add_early_cse_mem_ssa_pass();
        pass_manager.add_new_gvn_pass();
    }

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
    {
        pass_manager.add_aggressive_inst_combiner_pass();
        pass_manager.add_loop_unroll_and_jam_pass();
    }

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0", feature = "llvm7-0")))]
    {
        pass_manager.add_coroutine_early_pass();
        pass_manager.add_coroutine_split_pass();
        pass_manager.add_coroutine_elide_pass();
        pass_manager.add_coroutine_cleanup_pass();
    }

    pass_manager.run_on(&module);
}

#[test]
fn test_pass_manager_builder() {
    let pass_manager_builder = PassManagerBuilder::create();

    pass_manager_builder.set_optimization_level(Aggressive);
    pass_manager_builder.set_size_level(2);
    pass_manager_builder.set_inliner_with_threshold(42);
    pass_manager_builder.set_disable_unit_at_a_time(true);
    pass_manager_builder.set_disable_unroll_loops(true);
    pass_manager_builder.set_disable_simplify_lib_calls(true);

    let context = Context::create();
    let module = context.create_module("my_module");

    let fn_pass_manager = PassManager::create(&module);

    pass_manager_builder.populate_function_pass_manager(&fn_pass_manager);

    let void_type = context.void_type();
    let fn_type = void_type.fn_type(&[], false);
    let fn_value = module.add_function("my_fn", fn_type, None);
    let builder = context.create_builder();
    let entry = context.append_basic_block(fn_value, "entry");

    builder.position_at_end(entry);
    builder.build_return(None);

    #[cfg(not(feature = "llvm3-7"))]
    assert!(!fn_pass_manager.initialize());
    #[cfg(feature = "llvm3-7")]
    fn_pass_manager.initialize();

    // TODO: Test with actual changes? Would be true in that case
    // REVIEW: Segfaults in 4.0
    #[cfg(not(feature = "llvm4-0"))]
    assert!(!fn_pass_manager.run_on(&fn_value));

    assert!(!fn_pass_manager.finalize());

    let module_pass_manager = PassManager::create(());

    pass_manager_builder.populate_module_pass_manager(&module_pass_manager);

    let module2 = module.clone();

    // TODOC: In 3.6, 3.8, & 3.9 it returns false. Seems like a LLVM bug?
    #[cfg(not(any(feature = "llvm3-7", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0", feature = "llvm9-0", feature = "llvm10-0", feature = "llvm11-0")))]
    assert!(!module_pass_manager.run_on(&module));
    #[cfg(any(feature = "llvm3-7", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0", feature = "llvm9-0", feature = "llvm10-0", feature = "llvm11-0"))]
    assert!(module_pass_manager.run_on(&module));

    let lto_pass_manager = PassManager::create(());

    pass_manager_builder.populate_lto_pass_manager(&lto_pass_manager, false, false);

    assert!(lto_pass_manager.run_on(&module2));
}

#[test]
fn test_pass_registry() {
    let pass_registry = PassRegistry::get_global();

    pass_registry.initialize_core();
    pass_registry.initialize_transform_utils();
    pass_registry.initialize_scalar_opts();
    pass_registry.initialize_obj_carc_opts();
    pass_registry.initialize_vectorization();
    pass_registry.initialize_inst_combine();
    pass_registry.initialize_ipo();
    pass_registry.initialize_instrumentation();
    pass_registry.initialize_analysis();
    pass_registry.initialize_ipa();
    pass_registry.initialize_codegen();
    pass_registry.initialize_target();
    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
    pass_registry.initialize_aggressive_inst_combiner();
}
<commit_msg>disable test for constant_propagation_pass in llvm12<commit_after>extern crate inkwell;

use self::inkwell::OptimizationLevel::Aggressive;
use self::inkwell::context::Context;
use self::inkwell::passes::{PassManagerBuilder, PassManager, PassRegistry};

#[test]
fn test_init_all_passes_for_module() {
    let context = Context::create();
    let module = context.create_module("my_module");
    let pass_manager = PassManager::create(());

    pass_manager.add_argument_promotion_pass();
    pass_manager.add_constant_merge_pass();
    pass_manager.add_dead_arg_elimination_pass();
    pass_manager.add_function_attrs_pass();
    pass_manager.add_function_inlining_pass();
    pass_manager.add_always_inliner_pass();
    pass_manager.add_global_dce_pass();
    pass_manager.add_global_optimizer_pass();
    pass_manager.add_prune_eh_pass();
    pass_manager.add_ipsccp_pass();
    pass_manager.add_internalize_pass(true);
    pass_manager.add_strip_dead_prototypes_pass();
    pass_manager.add_strip_symbol_pass();
    #[cfg(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9", feature = "llvm4-0"))]
    pass_manager.add_bb_vectorize_pass();
    pass_manager.add_loop_vectorize_pass();
    pass_manager.add_slp_vectorize_pass();
    pass_manager.add_aggressive_dce_pass();
    #[cfg(not(feature = "llvm3-6"))]
    pass_manager.add_bit_tracking_dce_pass();
    pass_manager.add_alignment_from_assumptions_pass();
    pass_manager.add_cfg_simplification_pass();
    pass_manager.add_dead_store_elimination_pass();
    pass_manager.add_scalarizer_pass();
    pass_manager.add_merged_load_store_motion_pass();
    pass_manager.add_gvn_pass();
    pass_manager.add_ind_var_simplify_pass();
    pass_manager.add_instruction_combining_pass();
    pass_manager.add_jump_threading_pass();
    pass_manager.add_licm_pass();
    pass_manager.add_loop_deletion_pass();
    pass_manager.add_loop_idiom_pass();
    pass_manager.add_loop_rotate_pass();
    pass_manager.add_loop_reroll_pass();
    pass_manager.add_loop_unroll_pass();
    pass_manager.add_loop_unswitch_pass();
    pass_manager.add_memcpy_optimize_pass();
    pass_manager.add_partially_inline_lib_calls_pass();
    pass_manager.add_lower_switch_pass();
    pass_manager.add_promote_memory_to_register_pass();
    pass_manager.add_reassociate_pass();
    pass_manager.add_sccp_pass();
    pass_manager.add_scalar_repl_aggregates_pass();
    pass_manager.add_scalar_repl_aggregates_pass_ssa();
    pass_manager.add_scalar_repl_aggregates_pass_with_threshold(1);
    pass_manager.add_simplify_lib_calls_pass();
    pass_manager.add_tail_call_elimination_pass();
    pass_manager.add_demote_memory_to_register_pass();
    pass_manager.add_verifier_pass();
    pass_manager.add_correlated_value_propagation_pass();
    pass_manager.add_early_cse_pass();
    pass_manager.add_lower_expect_intrinsic_pass();
    pass_manager.add_type_based_alias_analysis_pass();
    pass_manager.add_scoped_no_alias_aa_pass();
    pass_manager.add_basic_alias_analysis_pass();

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9")))]
    {
        pass_manager.add_early_cse_mem_ssa_pass();
        pass_manager.add_new_gvn_pass();
    }

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
    {
        pass_manager.add_aggressive_inst_combiner_pass();
        pass_manager.add_loop_unroll_and_jam_pass();
    }

    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0", feature = "llvm7-0")))]
    {
        pass_manager.add_coroutine_early_pass();
        pass_manager.add_coroutine_split_pass();
        pass_manager.add_coroutine_elide_pass();
        pass_manager.add_coroutine_cleanup_pass();
    }

    #[cfg(not(any(feature = "llvm12-0")))]
    {
        pass_manager.add_constant_propagation_pass();
        pass_manager.add_ip_constant_propagation_pass();
    }

    pass_manager.run_on(&module);
}

#[test]
fn test_pass_manager_builder() {
    let pass_manager_builder = PassManagerBuilder::create();

    pass_manager_builder.set_optimization_level(Aggressive);
    pass_manager_builder.set_size_level(2);
    pass_manager_builder.set_inliner_with_threshold(42);
    pass_manager_builder.set_disable_unit_at_a_time(true);
    pass_manager_builder.set_disable_unroll_loops(true);
    pass_manager_builder.set_disable_simplify_lib_calls(true);

    let context = Context::create();
    let module = context.create_module("my_module");

    let fn_pass_manager = PassManager::create(&module);

    pass_manager_builder.populate_function_pass_manager(&fn_pass_manager);

    let void_type = context.void_type();
    let fn_type = void_type.fn_type(&[], false);
    let fn_value = module.add_function("my_fn", fn_type, None);
    let builder = context.create_builder();
    let entry = context.append_basic_block(fn_value, "entry");

    builder.position_at_end(entry);
    builder.build_return(None);

    #[cfg(not(feature = "llvm3-7"))]
    assert!(!fn_pass_manager.initialize());
    #[cfg(feature = "llvm3-7")]
    fn_pass_manager.initialize();

    // TODO: Test with actual changes? Would be true in that case
    // REVIEW: Segfaults in 4.0
    #[cfg(not(feature = "llvm4-0"))]
    assert!(!fn_pass_manager.run_on(&fn_value));

    assert!(!fn_pass_manager.finalize());

    let module_pass_manager = PassManager::create(());

    pass_manager_builder.populate_module_pass_manager(&module_pass_manager);

    let module2 = module.clone();

    // TODOC: In 3.6, 3.8, & 3.9 it returns false. Seems like a LLVM bug?
    #[cfg(not(any(feature = "llvm3-7", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0", feature = "llvm9-0", feature = "llvm10-0", feature = "llvm11-0")))]
    assert!(!module_pass_manager.run_on(&module));
    #[cfg(any(feature = "llvm3-7", feature = "llvm6-0", feature = "llvm7-0", feature = "llvm8-0", feature = "llvm9-0", feature = "llvm10-0", feature = "llvm11-0"))]
    assert!(module_pass_manager.run_on(&module));

    let lto_pass_manager = PassManager::create(());

    pass_manager_builder.populate_lto_pass_manager(&lto_pass_manager, false, false);

    assert!(lto_pass_manager.run_on(&module2));
}

#[test]
fn test_pass_registry() {
    let pass_registry = PassRegistry::get_global();

    pass_registry.initialize_core();
    pass_registry.initialize_transform_utils();
    pass_registry.initialize_scalar_opts();
    pass_registry.initialize_obj_carc_opts();
    pass_registry.initialize_vectorization();
    pass_registry.initialize_inst_combine();
    pass_registry.initialize_ipo();
    pass_registry.initialize_instrumentation();
    pass_registry.initialize_analysis();
    pass_registry.initialize_ipa();
    pass_registry.initialize_codegen();
    pass_registry.initialize_target();
    #[cfg(not(any(feature = "llvm3-6", feature = "llvm3-7", feature = "llvm3-8", feature = "llvm3-9",
                  feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
    pass_registry.initialize_aggressive_inst_combiner();
}
<|endoftext|>


<commit_before>/// Integration tests for the whole project

extern crate zwreec;
use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::Cursor;
use std::vec::Vec;

static TESTFOLDER_PASS: &'static str = "./tests/integration/should-compile/";
static TESTFOLDER_FAIL: &'static str = "./tests/integration/should-fail/";

fn test_compile(input_filename: String) {
    let path = Path::new(&input_filename);
    let mut input = match File::open(path) {
        Err(why) => {
            panic!("Couldn't open {}: {}",
                           path.display(), Error::description(&why))
        },
        Ok(file) => {
            file
        }
    };

    let vec: Vec<u8> = vec![];
    let mut output = Cursor::new(vec);

    let cfg = zwreec::config::Config::default_config();

    zwreec::compile(cfg, &mut input, &mut output);
}

#[test]
fn helloworld_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "HelloWorld.twee");
}

#[test]
fn long_text_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "HelloWorld.twee");
}

#[test]
fn zscii_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "ZSCII.twee");
}

#[test]
fn ascii_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "ASCII.twee");
}

#[test]
fn unicode_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "Unicode.twee");
}

#[test]
fn passage_links_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "PassageLinks.twee");
}

#[test]
fn random_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "Random.twee");
}

#[test]
fn if_else_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "If-Else.twee");
}

#[test]
fn current_status_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "CurrentStatus.twee");
}

// #[test]
// #[should_panic]
// fn invalid_macro_test() {
//    test_compile(TESTFOLDER_FAIL.to_string() + "InvalidMacro.twee");
// }

#[test]
#[should_panic]
fn no_start_passage_test() {
    test_compile(TESTFOLDER_FAIL.to_string() + "NoStartPassage.twee");
}

#[test]
#[should_panic]
fn duplicate_passage_test() {
    test_compile(TESTFOLDER_FAIL.to_string() + "DuplicatePassage.twee");
}
<commit_msg>Fixes invalid macro integration test<commit_after>/// Integration tests for the whole project

extern crate zwreec;
use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::io::Cursor;
use std::vec::Vec;

static TESTFOLDER_PASS: &'static str = "./tests/integration/should-compile/";
static TESTFOLDER_FAIL: &'static str = "./tests/integration/should-fail/";

fn test_compile(input_filename: String) {
    let path = Path::new(&input_filename);
    let mut input = match File::open(path) {
        Err(why) => {
            panic!("Couldn't open {}: {}",
                           path.display(), Error::description(&why))
        },
        Ok(file) => {
            file
        }
    };

    let vec: Vec<u8> = vec![];
    let mut output = Cursor::new(vec);

    let cfg = zwreec::config::Config::default_config();

    zwreec::compile(cfg, &mut input, &mut output);
}

#[test]
fn helloworld_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "HelloWorld.twee");
}

#[test]
fn long_text_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "HelloWorld.twee");
}

#[test]
fn zscii_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "ZSCII.twee");
}

#[test]
fn ascii_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "ASCII.twee");
}

#[test]
fn unicode_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "Unicode.twee");
}

#[test]
fn passage_links_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "PassageLinks.twee");
}

#[test]
fn random_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "Random.twee");
}

#[test]
fn if_else_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "If-Else.twee");
}

#[test]
fn current_status_test() {
    test_compile(TESTFOLDER_PASS.to_string() + "CurrentStatus.twee");
}

#[test]
#[should_panic]
fn invalid_macro_test() {
   test_compile(TESTFOLDER_FAIL.to_string() + "InvalidMacro.twee");
}

#[test]
#[should_panic]
fn no_start_passage_test() {
    test_compile(TESTFOLDER_FAIL.to_string() + "NoStartPassage.twee");
}

#[test]
#[should_panic]
fn duplicate_passage_test() {
    test_compile(TESTFOLDER_FAIL.to_string() + "DuplicatePassage.twee");
}
<|endoftext|>


<commit_before>use core;
use super::super::alloc;
use super::super::alloc::{SliceWrapper, SliceWrapperMut};
use super::interface;
use super::input_pair::{InputPair, InputReference, InputReferenceMut};
use super::histogram::ContextType;
use super::constants::{kSigned3BitContextLookup, kUTF8ContextLookup};
use super::util::{floatX, FastLog2u16};
use super::find_stride;
use super::weights::{Weights, BLEND_FIXED_POINT_PRECISION};

use super::context_map_entropy::SpeedAndMax;

const NUM_PRIORS_TO_TRY: usize = 2;
const NIBBLE_PRIOR_SIZE: usize = 16;
// the high nibble, followed by the low nibbles
const CONTEXT_MAP_PRIOR_SIZE: usize = 256 * NIBBLE_PRIOR_SIZE * 17;
const STRIDE_PRIOR_SIZE: usize = 256 * 256 * NIBBLE_PRIOR_SIZE * 2;
const PRIOR_SIZES : [usize;2] = [CONTEXT_MAP_PRIOR_SIZE, STRIDE_PRIOR_SIZE];
pub trait Prior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize;
    fn lookup_mut(data:&mut [u8], actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> &mut[u8] {
        data.split_at_mut(
            Self::lookup_lin(actual_context,
                             selected_context,
                             stride_byte,
                             high_nibble) * NIBBLE_PRIOR_SIZE).1.split_at_mut(16).0
    }
    fn lookup(data:&[u8], actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> &[u8] {
        data.split_at(
            Self::lookup_lin(actual_context,
                             selected_context,
                             stride_byte,
                             high_nibble) * NIBBLE_PRIOR_SIZE).1.split_at(16).0
    }
}

pub struct StridePrior {
}
impl Prior for StridePrior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize {
        if let Some(nibble) = high_nibble {
            1 + 2 * (actual_context as usize
                     | ((stride_byte as usize & 0xf) << 8)
                     | ((nibble as usize) << 12))
        } else {
            2 * (actual_context as usize | ((stride_byte as usize) << 8))
        }
    }
}

pub struct CMPrior {
}
impl Prior for CMPrior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize {
        if let Some(nibble) = high_nibble {
            (nibble as usize + 1) + 17 * actual_context as usize
        } else {
            17 * actual_context as usize
        }
    }
}

fn init_cdfs(cdfs: &mut [u16]) {
    assert_eq!(cdfs.len() % 16, 0);
    for (index, item) in cdfs.iter_mut().enumerate() {
        *item = 4 + 4 * (index as u16 & 0xf);
    }
}

pub struct PriorEval<'a,
                     AllocU16:alloc::Allocator<u16>,
                     AllocU32:alloc::Allocator<u32>,
                     AllocF:alloc::Allocator<floatX>,
                     > {
    input: InputPair<'a>,
    context_map: interface::PredictionModeContextMap<InputReferenceMut<'a>>,
    block_type: u8,
    local_byte_offset: usize,
    _nop: AllocU32::AllocatedMemory,
    priors: [AllocU16::AllocatedMemory; NUM_PRIORS_TO_TRY],
    stride_pyramid_leaves: [u8; find_stride::NUM_LEAF_NODES],
    phantom: core::marker::PhantomData<AllocF>,
}

impl<'a,
     AllocU16:alloc::Allocator<u16>,
     AllocU32:alloc::Allocator<u32>,
     AllocF:alloc::Allocator<floatX>,
     > PriorEval<'a, AllocU16, AllocU32, AllocF> {
   pub fn new(m16: &mut AllocU16,
              _m32: &mut AllocU32,
              _mf: &mut AllocF,
              input: InputPair<'a>,
              stride: [u8; find_stride::NUM_LEAF_NODES],
              prediction_mode: interface::PredictionModeContextMap<InputReferenceMut<'a>>) -> Self {
      let mut ret = PriorEval::<AllocU16, AllocU32, AllocF>{
         phantom:core::marker::PhantomData::<AllocF>::default(),
         input: input,
         context_map: prediction_mode,
         block_type: 0,
         local_byte_offset: 0,
         _nop:  AllocU32::AllocatedMemory::default(),
         priors: [m16.alloc_cell(PRIOR_SIZES[0]), m16.alloc_cell(PRIOR_SIZES[1])],
         stride_pyramid_leaves: stride,
      };
      for prior in ret.priors.iter_mut() {
          init_cdfs(prior.slice_mut());
      }
      ret
   }
}
<commit_msg>implement IR interpreter for the new prior eval struct<commit_after>use core;
use super::super::alloc;
use super::super::alloc::{SliceWrapper, SliceWrapperMut};
use super::interface;
use super::input_pair::{InputPair, InputReference, InputReferenceMut};
use super::ir_interpret::{IRInterpreter};
use super::histogram::ContextType;
use super::constants::{kSigned3BitContextLookup, kUTF8ContextLookup};
use super::util::{floatX, FastLog2u16};
use super::find_stride;
use super::weights::{Weights, BLEND_FIXED_POINT_PRECISION};

use super::context_map_entropy::SpeedAndMax;

const NUM_PRIORS_TO_TRY: usize = 2;
const NIBBLE_PRIOR_SIZE: usize = 16;
// the high nibble, followed by the low nibbles
const CONTEXT_MAP_PRIOR_SIZE: usize = 256 * NIBBLE_PRIOR_SIZE * 17;
const STRIDE_PRIOR_SIZE: usize = 256 * 256 * NIBBLE_PRIOR_SIZE * 2;
const PRIOR_SIZES : [usize;2] = [CONTEXT_MAP_PRIOR_SIZE, STRIDE_PRIOR_SIZE];
pub trait Prior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize;
    fn lookup_mut(data:&mut [u8], actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> &mut[u8] {
        data.split_at_mut(
            Self::lookup_lin(actual_context,
                             selected_context,
                             stride_byte,
                             high_nibble) * NIBBLE_PRIOR_SIZE).1.split_at_mut(16).0
    }
    fn lookup(data:&[u8], actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> &[u8] {
        data.split_at(
            Self::lookup_lin(actual_context,
                             selected_context,
                             stride_byte,
                             high_nibble) * NIBBLE_PRIOR_SIZE).1.split_at(16).0
    }
}

pub struct StridePrior {
}
impl Prior for StridePrior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize {
        if let Some(nibble) = high_nibble {
            1 + 2 * (actual_context as usize
                     | ((stride_byte as usize & 0xf) << 8)
                     | ((nibble as usize) << 12))
        } else {
            2 * (actual_context as usize | ((stride_byte as usize) << 8))
        }
    }
}

pub struct CMPrior {
}
impl Prior for CMPrior {
    fn lookup_lin(actual_context:u8, selected_context:u8, stride_byte: u8, high_nibble: Option<u8>) -> usize {
        if let Some(nibble) = high_nibble {
            (nibble as usize + 1) + 17 * actual_context as usize
        } else {
            17 * actual_context as usize
        }
    }
}

fn init_cdfs(cdfs: &mut [u16]) {
    assert_eq!(cdfs.len() % 16, 0);
    for (index, item) in cdfs.iter_mut().enumerate() {
        *item = 4 + 4 * (index as u16 & 0xf);
    }
}

pub struct PriorEval<'a,
                     AllocU16:alloc::Allocator<u16>,
                     AllocU32:alloc::Allocator<u32>,
                     AllocF:alloc::Allocator<floatX>,
                     > {
    input: InputPair<'a>,
    context_map: interface::PredictionModeContextMap<InputReferenceMut<'a>>,
    block_type: u8,
    local_byte_offset: usize,
    _nop: AllocU32::AllocatedMemory,
    priors: [AllocU16::AllocatedMemory; NUM_PRIORS_TO_TRY],
    stride_pyramid_leaves: [u8; find_stride::NUM_LEAF_NODES],
    phantom: core::marker::PhantomData<AllocF>,
}

impl<'a,
     AllocU16:alloc::Allocator<u16>,
     AllocU32:alloc::Allocator<u32>,
     AllocF:alloc::Allocator<floatX>,
     > PriorEval<'a, AllocU16, AllocU32, AllocF> {
   pub fn new(m16: &mut AllocU16,
              _m32: &mut AllocU32,
              _mf: &mut AllocF,
              input: InputPair<'a>,
              stride: [u8; find_stride::NUM_LEAF_NODES],
              prediction_mode: interface::PredictionModeContextMap<InputReferenceMut<'a>>) -> Self {
      let mut ret = PriorEval::<AllocU16, AllocU32, AllocF>{
         phantom:core::marker::PhantomData::<AllocF>::default(),
         input: input,
         context_map: prediction_mode,
         block_type: 0,
         local_byte_offset: 0,
         _nop:  AllocU32::AllocatedMemory::default(),
         priors: [m16.alloc_cell(PRIOR_SIZES[0]), m16.alloc_cell(PRIOR_SIZES[1])],
         stride_pyramid_leaves: stride,
      };
      for prior in ret.priors.iter_mut() {
          init_cdfs(prior.slice_mut());
      }
      ret
   }
   fn update_cost_base(&mut self, stride_prior: u8, cm_prior: usize, literal: u8) {
   }
}
impl<'a, AllocU16: alloc::Allocator<u16>,
     AllocU32:alloc::Allocator<u32>,
     AllocF: alloc::Allocator<floatX>> IRInterpreter for PriorEval<'a, AllocU16, AllocU32, AllocF> {
    fn inc_local_byte_offset(&mut self, inc: usize) {
        self.local_byte_offset += inc;
    }
    fn get_stride(&self, local_byte_offset: usize) -> u8 {
        self.stride_pyramid_leaves[local_byte_offset * 8 / self.input.len()]
    }
    fn local_byte_offset(&self) -> usize {
        self.local_byte_offset
    }
    fn update_block_type(&mut self, new_type: u8) {
        self.block_type = new_type;
    }
    fn block_type(&self) -> u8 {
        self.block_type
    }
    fn literal_data_at_offset(&self, index:usize) -> u8 {
        self.input[index]
    }
    fn literal_context_map(&self) -> &[u8] {
        self.context_map.literal_context_map.slice()
    }
    fn prediction_mode(&self) -> ::interface::LiteralPredictionModeNibble {
        self.context_map.literal_prediction_mode()
    }
    fn update_cost(&mut self, stride_prior: u8, cm_prior: usize, literal: u8) {
        self.update_cost_base(stride_prior, cm_prior, literal)
    }
}

<|endoftext|>


<commit_before>extern crate winreg;

use winreg::RegKey;
use winreg::enums::*;

use std::path::{Path, PathBuf};
use std::env;
use std::fs::File;
use std::io::Write;
use std::process::Command;

// Find LogitechLcd.dll in windows registry using its CLSID
fn dll_path_clsid(machine: &str) -> Option<String> {
    let hkcl = RegKey::predef(HKEY_CLASSES_ROOT);
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);

    let mut dll_path = None;

    if machine == "x64" {
        match hkcl.open_subkey_with_flags("CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Classes\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }
    } else {
        match hkcl.open_subkey_with_flags("Wow6432Node\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Classes\\Wow6432Node\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Classes\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }
    }

    dll_path.map(|p| {
        let lib_dir_path = Path::new(&p[..]).parent().unwrap();
        String::from(lib_dir_path.to_str().unwrap())
    })
}

// Find visual studio install
fn vs_path() -> Option<String> {
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    match hkcu.open_subkey_with_flags("SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    match hklm.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    match hkcu.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    None
}

fn main() {
    assert!(cfg!(windows), "Unsupported target platform");

    let target_str = env::var("TARGET").unwrap();
    let out_dir_str = env::var("OUT_DIR").unwrap();

    let machine = if target_str.starts_with("x86_64") {
        "x64"
    } else if target_str.starts_with("i686") {
        "x86"
    } else {
        panic!("Unknown msvc target: {}", target_str);
    };

    // Get location of library from env var or try get path form winreg
    let lib_dir_str = match env::var("LOGITECH_LCD_LIB_DIR") {
        Ok(val) => val,
        Err(_)  => dll_path_clsid(machine).unwrap(),
    };

    let dll_path = Path::new(&lib_dir_str[..]).join("LogitechLcd.dll");

    // MSVC requires both a .dll file and a .lib import library
    if target_str.contains("msvc") {
        let lib_path = Path::new(&lib_dir_str[..]).join("LogitechLcd.lib");

        // We are missing the a .lib import library
        if !lib_path.exists() || true {

            // Get visual studio install path
            let vs_path_str = vs_path().unwrap();
            let lib_tool_path = Path::new(&vs_path_str[..]).join("VC\\bin\\lib.exe");
            assert!(lib_tool_path.is_file());

            // Create .def file which contains a list symbols in our .dll file
            let def_file_path = Path::new(&out_dir_str[..]).join("LogitechLcd.def");
            let def_str = include_str!("LogitechLcd.def");
            let mut def_file = File::create(def_file_path).unwrap();
            def_file.write_all(def_str.as_bytes()).unwrap();

            // Use the VS lib tool to create a .lib import library for our .dll file
            Command::new(lib_tool_path)
                .arg("/def:LogitechLcd.def")
                .arg("/out:LogitechLcd.lib")
                .arg(format!("/machine:{}", machine))
                .current_dir(&out_dir_str)
                .spawn()
                .unwrap();

            // Link to the .lib file we created
            println!("cargo:rustc-link-search=native={}", out_dir_str);
        } else {
            // We found a .lib file, use that
            println!("cargo:rustc-link-search=native={}", lib_dir_str);
        }

    } else {
        // The gnu Compiler can link directly to our .dll file
        assert!(dll_path.is_file());
        assert_eq!(dll_path.file_name().unwrap(), "LogitechLcd.dll");

        // link to the .dll file
        println!("cargo:rustc-link-search=native={}", lib_dir_str);
    }

    if env::var("LOGITECH_LCD_COPY_OUT").is_ok() {
        assert!(dll_path.is_file());
        assert_eq!(dll_path.file_name().unwrap(), "LogitechLcd.dll");

        // Start with build out folder
        // Example: logi-lcd\target\debug\build\logi-lcd-sys-cb228bca7013f026\out
        let mut target_path = PathBuf::from(&out_dir_str);

        // Pop down to our traget dir: logi-lcd\target\debug
        assert!(target_path.pop());
        assert!(target_path.pop());
        assert!(target_path.pop());

        // Copy dll if doesn't exist
        target_path.push(dll_path.file_name().unwrap());
        if !target_path.exists() {
            std::fs::copy(dll_path, target_path).unwrap();
        }
    }

    println!("cargo:rustc-link-lib=LogitechLcd");
}<commit_msg>Add error messages in build script<commit_after>extern crate winreg;

use winreg::RegKey;
use winreg::enums::*;

use std::path::{Path, PathBuf};
use std::env;
use std::fs::File;
use std::io::Write;
use std::process::Command;

// Find LogitechLcd.dll in windows registry using its CLSID
fn dll_path_clsid(machine: &str) -> Option<String> {
    let hkcl = RegKey::predef(HKEY_CLASSES_ROOT);
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);

    let mut dll_path = None;

    if machine == "x64" {
        match hkcl.open_subkey_with_flags("CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Classes\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }
    } else {
        match hkcl.open_subkey_with_flags("Wow6432Node\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Classes\\Wow6432Node\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }

        match hklm.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Classes\\CLSID\\{d0e790a5-01a7-49ae-ae0b-e986bdd0c21b}\\ServerBinary", KEY_READ) {
            Ok(key) => dll_path = key.get_value::<String, &str>("").ok(),
            Err(_) => {},
        }
    }

    dll_path.map(|p| {
        let lib_dir_path = Path::new(&p[..]).parent().unwrap();
        String::from(lib_dir_path.to_str().unwrap())
    })
}

// Find visual studio install
fn vs_path() -> Option<String> {
    let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);

    match hkcu.open_subkey_with_flags("SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    match hklm.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    match hkcu.open_subkey_with_flags("SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VS7", KEY_READ) {
        Ok(key) => {
            match key.get_value::<String, &str>("14.0") {
                Ok(s) => return Some(s),
                Err(_) => {},
            }
        },
        Err(_) => {},
    }

    None
}

fn main() {
    assert!(cfg!(windows), "Unsupported target platform");

    let target_str = env::var("TARGET").unwrap();
    let out_dir_str = env::var("OUT_DIR").unwrap();

    let machine = if target_str.starts_with("x86_64") {
        "x64"
    } else if target_str.starts_with("i686") {
        "x86"
    } else {
        panic!("Unknown msvc target: {}", target_str);
    };

    // Get location of library from env var or try get path form winreg
    let lib_dir_str = match env::var("LOGITECH_LCD_LIB_DIR") {
        Ok(val) => val,
        Err(_)  => dll_path_clsid(machine).expect("Couldn't find the logitech lcd sdk. \
            Please make sure \"Logitech Gaming Software\" is installed or \
            manually specify a library path with the \"LOGITECH_LCD_LIB_DIR\" \
            environment variable"),
    };

    let dll_path = Path::new(&lib_dir_str[..]).join("LogitechLcd.dll");

    // MSVC requires both a .dll file and a .lib import library
    if target_str.contains("msvc") {
        let lib_path = Path::new(&lib_dir_str[..]).join("LogitechLcd.lib");

        // We are missing the a .lib import library
        if !lib_path.exists() {

            // Get visual studio install path
            let vs_path_str = vs_path().expect("Couldn't find visual studio install");

            let lib_tool_path = Path::new(&vs_path_str[..]).join("VC\\bin\\lib.exe");
            if !lib_tool_path.is_file() {
                panic!("Couldn't find lib.exe at \"{}\"", lib_tool_path.to_str().unwrap());
            }

            // Create .def file which contains a list symbols in our .dll file
            let def_file_path = Path::new(&out_dir_str[..]).join("LogitechLcd.def");
            let def_str = include_str!("LogitechLcd.def");
            let mut def_file = File::create(def_file_path).unwrap();
            def_file.write_all(def_str.as_bytes()).unwrap();

            // Use the VS lib tool to create a .lib import library for our .dll file
            Command::new(lib_tool_path)
                .arg("/def:LogitechLcd.def")
                .arg("/out:LogitechLcd.lib")
                .arg(format!("/machine:{}", machine))
                .current_dir(&out_dir_str)
                .spawn()
                .expect("Failed to create .lib import library using lib.exe");

            // Link to the .lib file we created
            println!("cargo:rustc-link-search=native={}", out_dir_str);
        } else {
            if !lib_path.is_file() {
                panic!("Couldn't find LogitechLcd.lib at \"{}\"", lib_path.to_str().unwrap());
            }

            // We found a .lib file, use that
            println!("cargo:rustc-link-search=native={}", lib_dir_str);
        }

    } else {
        // The gnu Compiler can link directly to our .dll file
        if !dll_path.is_file() {
            panic!("Couldn't find LogitechLcd.dll at \"{}\"", dll_path.to_str().unwrap());
        }

        // link to the .dll file
        println!("cargo:rustc-link-search=native={}", lib_dir_str);
    }

    if env::var("LOGITECH_LCD_COPY_OUT").is_ok() {
        if !dll_path.is_file() {
            panic!("Couldn't find LogitechLcd.dll at \"{}\"", dll_path.to_str().unwrap());
        }

        // Start with build out folder
        // Example: logi-lcd\target\debug\build\logi-lcd-sys-cb228bca7013f026\out
        let mut target_path = PathBuf::from(&out_dir_str);

        // Pop down to our traget dir: logi-lcd\target\debug
        assert!(target_path.pop());
        assert!(target_path.pop());
        assert!(target_path.pop());

        // Copy dll if doesn't exist
        target_path.push(dll_path.file_name().unwrap());
        if !target_path.exists() {
            std::fs::copy(dll_path, target_path).unwrap();
        }
    }

    println!("cargo:rustc-link-lib=LogitechLcd");
}<|endoftext|>


<commit_before>use rustc::lint::{Context, LintPass, LintArray};
use std::cmp::Ordering;
use syntax::ast::{Item, Item_, Lit_, MetaItem_, Mod, PathListItem_, ViewPath_, Visibility};
use syntax::codemap::Span;
use syntax::print::pprust::path_to_string;

declare_lint!(UNSORTED_DECLARATIONS, Warn,
              "Warn when the declarations of crates or modules are not in alphabetical order");

pub struct Sorter;

impl LintPass for Sorter {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNSORTED_DECLARATIONS)
    }

    fn check_mod(&mut self, cx: &Context, module: &Mod, _span: Span, _id: u32) {
        let session_codemap = cx.tcx.sess.codemap();
        let mut extern_crates = Vec::new();
        let mut uses = Vec::new();
        let mut mods = Vec::new();
        for item in &module.items {
            let item_name = format!("{}", item.ident.name.as_str());
            let item_span = item.span;
            match item.node.clone() {
                Item_::ItemExternCrate(_) if item_name != "std" => {
                    let item_attrs = get_item_attrs(&item, false);
                    extern_crates.push((item_name, item_attrs, item_span, false));
                },
                Item_::ItemMod(module) => {
                    let mod_invoked_file = session_codemap.span_to_filename(item.span);
                    let mod_declared_file = session_codemap.span_to_filename(module.inner);
                    if mod_declared_file != mod_invoked_file {      // ignores inline modules
                        let item_attrs = get_item_attrs(&item, true);
                        mods.push((item_name, item_attrs, item_span, false));
                    }
                },
                Item_::ItemUse(spanned) => {
                    let item_attrs = get_item_attrs(&item, true);
                    match spanned.node {
                        ViewPath_::ViewPathSimple(ref ident, ref path) => {
                            let path_str = path_to_string(&path);
                            let name = ident.name.as_str();
                            let renamed = match path_str.ends_with(&*name) {
                                true => path_str,   // for checking `use foo as bar`
                                false => format!("{} as {}", &path_str, &name),
                            };
                            uses.push((renamed, item_attrs, item_span, false));
                        },
                        ViewPath_::ViewPathList(ref path, ref list) => {
                            let old_list = list
                                           .iter()
                                           .map(|&list_item| {
                                                match list_item.node {
                                                    PathListItem_::PathListMod { .. } =>
                                                        "self".to_owned(),      // this must be `self`
                                                    PathListItem_::PathListIdent { name, .. } => {
                                                        // we don't have any renames inside brackets in servo
                                                        let interned = name.name.as_str();
                                                        let string = &*interned;
                                                        string.to_owned()
                                                    },
                                                }
                                            }).collect::<Vec<String>>();
                            let mut new_list = old_list.clone();
                            new_list.sort_by(|a, b| {
                                match (&**a, &**b) {    // `self` should be first in an use list
                                    ("self", _) => Ordering::Less,
                                    (_, "self") => Ordering::Greater,
                                    _ => a.cmp(b),
                                }
                            });
                            let mut warn = false;
                            for i in 0..old_list.len() {
                                if old_list[i] != new_list[i] {
                                    warn = true;
                                    break;
                                }
                            }
                            let use_list = format!("{}::{{{}}}", path_to_string(&path), new_list.connect(", "));
                            uses.push((use_list, item_attrs, path.span, warn));
                        },
                        ViewPath_::ViewPathGlob(ref path) => {
                            let path_str = path_to_string(&path) + "::*";
                            // we don't have any use statements like `use std::prelude::*`
                            // since it's done only by rustc, we can safely neglect those here
                            if !path_str.starts_with("std::") {
                                uses.push((path_str, item_attrs, item_span, false));
                            }
                        },
                    }
                },
                _ => (),
            }
        }

        check_sort(&extern_crates, cx, "crate declarations", "extern crate");
        check_sort(&mods, cx, "module declarations (other than inline modules)", "mod");
        check_sort(&uses, cx, "use statements", "use");

        // for collecting, formatting & filtering the attributes (and checking the visibility)
        fn get_item_attrs(item: &Item, pub_check: bool) -> String {
            let mut attr_vec = item.attrs
                               .iter()
                               .filter_map(|attr| {
                                   let meta_item = attr.node.value.node.clone();
                                   let meta_string = get_meta_as_string(&meta_item);
                                   match meta_string.starts_with("doc = ") {
                                       true => None,
                                       false => Some(format!("#[{}]", meta_string)),
                                   }
                               }).collect::<Vec<String>>();
            attr_vec.sort_by(|a, b| {
                match (&**a, &**b) {    // put `macro_use` first for later checking
                    ("#[macro_use]", _) => Ordering::Less,
                    (_, "#[macro_use]") => Ordering::Greater,
                    _ => a.cmp(b),
                }
            });
            let attr_string = attr_vec.connect("\n");
            match item.vis {
                Visibility::Public if pub_check => {
                    match attr_string.is_empty() {
                        true => "pub ".to_owned(),
                        false => attr_string + "\npub ",    // `pub` for mods and uses
                    }
                },
                _ => {
                    match attr_string.is_empty() {
                        true => attr_string,
                        false => attr_string + "\n",
                    }
                },
            }
        }

        // collect the information from meta items into Strings
        fn get_meta_as_string(meta_item: &MetaItem_) -> String {
            match *meta_item {
                MetaItem_::MetaWord(ref string) => format!("{}", string),
                MetaItem_::MetaList(ref string, ref meta_items) => {
                    let stuff = meta_items
                                .iter()
                                .map(|meta_item| {
                                    get_meta_as_string(&meta_item.node)
                                }).collect::<Vec<String>>();
                    format!("{}({})", string, stuff.connect(", "))
                },
                MetaItem_::MetaNameValue(ref string, ref literal) => {
                    let value = match literal.node {
                        Lit_::LitStr(ref inner_str, _style) => inner_str,
                        _ => panic!("unexpected literal found for meta item!"),
                    }; format!("{} = \"{}\"", string, value)
                },
            }
        }

        // checks the sorting of all the declarations and raises warnings whenever necessary
        // takes a slice of tuples with name, related attributes, spans and whether to warn for unordered use lists
        fn check_sort(old_list: &[(String, String, Span, bool)], cx: &Context, kind: &str, syntax: &str) {
            let length = old_list.len();
            let mut new_list = old_list
                                .iter()
                                .map(|&(ref name, ref attrs, _span, warn)| (name.clone(), attrs.clone(), warn))
                                .collect::<Vec<(String, String, bool)>>();
            new_list.sort_by(|&(ref str_a, ref attr_a, _), &(ref str_b, ref attr_b, _)| {
                // move the `pub` statements below (with `~` since it's on the farther side of ASCII)
                let mut new_str_a = str_for_biased_sort(&str_a, attr_a.ends_with("pub "), "~");
                let mut new_str_b = str_for_biased_sort(&str_b, attr_b.ends_with("pub "), "~");
                // move the #[macro_use] stuff above (with `!` since it's on the lower extreme of ASCII)
                new_str_a = str_for_biased_sort(&new_str_a, attr_a.starts_with("#[macro_use]"), "!");
                new_str_b = str_for_biased_sort(&new_str_b, attr_b.starts_with("#[macro_use]"), "!");
                new_str_a.cmp(&new_str_b)
            });

            let mut index = 0;
            let mut span: Option<Span> = None;
            for i in 0..length {
                if (old_list[i].0 != new_list[i].0) || new_list[i].2 {
                    span = Some(old_list[i].2);
                    index = i;      // only to find the index of the first unsorted declaration
                    break;          // because, we'll be printing everything following the first unsorted one
                }
            }

            match span {
                Some(span_start) => {   // print all the declarations proceeding the first unsorted one
                    let suggestion_list = (index..length)
                                          .map(|i| {
                                              if i == length - 1 {  // increase the span to include more lines
                                                  let mut sp = span_start;
                                                  sp.hi = old_list[i].2.hi;
                                                  span = Some(sp);
                                              } format!("{}{} {};", new_list[i].1, syntax, new_list[i].0)
                                          }).collect::<Vec<String>>();
                    let suggestion = format!("{} should be in alphabetical order!\nTry this...\n\n{}\n\n",
                                            kind, suggestion_list.connect("\n"));
                    // unwrapping the value here, because it's quite certain that there's something in `span`
                    cx.span_lint(UNSORTED_DECLARATIONS, span.unwrap(), &suggestion);
                },
                None => (),
            }

            // prepend given characters to names for biased sorting
            fn str_for_biased_sort(string: &String, choice: bool, prepend_char: &str) -> String {
                match choice {
                    true => prepend_char.to_owned() + &**string,
                    false => string.clone()
                }
            }
        }
    }
}
<commit_msg>detect renamed declarations!<commit_after>use rustc::lint::{Context, LintPass, LintArray};
use std::cmp::Ordering;
use syntax::ast::{Item, Item_, Lit_, MetaItem_, Mod, PathListItem_, ViewPath_, Visibility};
use syntax::codemap::Span;
use syntax::print::pprust::path_to_string;

declare_lint!(UNSORTED_DECLARATIONS, Warn,
              "Warn when the declarations of crates or modules are not in alphabetical order");

pub struct Sorter;

impl LintPass for Sorter {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNSORTED_DECLARATIONS)
    }

    fn check_mod(&mut self, cx: &Context, module: &Mod, _span: Span, _id: u32) {
        let session_codemap = cx.tcx.sess.codemap();    // required only for checking inline mods
        let mut extern_crates = Vec::new();
        let mut uses = Vec::new();
        let mut mods = Vec::new();

        for item in &module.items {
            let item_name = format!("{}", item.ident.name.as_str());
            let item_span = item.span;
            match item.node.clone() {
                Item_::ItemExternCrate(optional_name) if item_name != "std" => {
                    // We've put the declaration here because, we have to sort crate declarations
                    // with respect to the renamed version (instead of the old one).
                    // Since we also don't have `pub` (indicated by the `false` below),
                    // we could just append the declaration to the attributes.
                    let mut item_attrs = get_item_attrs(&item, false);
                    item_attrs = match optional_name {    // for `extern crate foo as bar`
                        Some(old_name) => format!("{}extern crate {} as", item_attrs, old_name),
                        None => format!("{}extern crate", item_attrs),
                    };
                    extern_crates.push((item_name, item_attrs, item_span, false));
                },
                Item_::ItemMod(module) => {
                    let mod_invoked_file = session_codemap.span_to_filename(item.span);
                    let mod_declared_file = session_codemap.span_to_filename(module.inner);
                    if mod_declared_file != mod_invoked_file {      // ignores inline modules
                        let item_attrs = get_item_attrs(&item, true);
                        mods.push((item_name, item_attrs, item_span, false));
                    }
                },
                Item_::ItemUse(spanned) => {
                    let item_attrs = get_item_attrs(&item, true);
                    match spanned.node {
                        ViewPath_::ViewPathSimple(ref ident, ref path) => {
                            let path_str = path_to_string(&path);
                            let name = ident.name.as_str();
                            let renamed = {     // for checking `use foo as bar`
                                let split = path_str.split(":").collect::<Vec<&str>>();
                                match split[split.len() - 1] == &*name {
                                    true => path_str.clone(),
                                    false => format!("{} as {}", &path_str, &name),
                                }
                            };
                            uses.push((renamed, item_attrs, item_span, false));
                        },
                        ViewPath_::ViewPathList(ref path, ref list) => {
                            let old_list = list
                                           .iter()
                                           .map(|&list_item| {
                                                match list_item.node {
                                                    PathListItem_::PathListMod { .. } =>
                                                        "self".to_owned(),      // this must be `self`
                                                    PathListItem_::PathListIdent { name, .. } => {
                                                        // we don't have any renames inside brackets in servo
                                                        let interned = name.name.as_str();
                                                        let string = &*interned;
                                                        string.to_owned()
                                                    },
                                                }
                                            }).collect::<Vec<String>>();
                            let mut new_list = old_list.clone();
                            new_list.sort_by(|a, b| {
                                match (&**a, &**b) {    // `self` should be first in an use list
                                    ("self", _) => Ordering::Less,
                                    (_, "self") => Ordering::Greater,
                                    _ => a.cmp(b),
                                }
                            });
                            let mut warn = false;
                            for i in 0..old_list.len() {
                                if old_list[i] != new_list[i] {
                                    warn = true;    // check whether the use list is sorted
                                    break;
                                }
                            }
                            let use_list = format!("{}::{{{}}}", path_to_string(&path), new_list.connect(", "));
                            uses.push((use_list, item_attrs, path.span, warn));
                        },
                        ViewPath_::ViewPathGlob(ref path) => {
                            let path_str = path_to_string(&path) + "::*";
                            // we don't have any use statements like `use std::prelude::*`
                            // since it's done only by rustc, we can safely neglect those here
                            if !path_str.starts_with("std::") {
                                uses.push((path_str, item_attrs, item_span, false));
                            }
                        },
                    }
                },
                _ => (),
            }
        }

        // we don't include the declaration here, because we've already appended it with the attributes
        check_sort(&extern_crates, cx, "crate declarations", "");
        check_sort(&mods, cx, "module declarations (other than inline modules)", "mod");
        check_sort(&uses, cx, "use statements", "use");

        // for collecting, formatting & filtering the attributes (and checking the visibility)
        fn get_item_attrs(item: &Item, pub_check: bool) -> String {
            let mut attr_vec = item.attrs
                               .iter()
                               .filter_map(|attr| {
                                   let meta_item = attr.node.value.node.clone();
                                   let meta_string = get_meta_as_string(&meta_item);
                                   match meta_string.starts_with("doc = ") {
                                       true => None,
                                       false => Some(format!("#[{}]", meta_string)),
                                   }
                               }).collect::<Vec<String>>();
            attr_vec.sort_by(|a, b| {
                match (&**a, &**b) {    // put `macro_use` first for later checking
                    ("#[macro_use]", _) => Ordering::Less,
                    (_, "#[macro_use]") => Ordering::Greater,
                    _ => a.cmp(b),
                }
            });
            let attr_string = attr_vec.connect("\n");
            match item.vis {
                Visibility::Public if pub_check => {
                    match attr_string.is_empty() {
                        true => "pub ".to_owned(),
                        false => attr_string + "\npub ",    // `pub` for mods and uses
                    }
                },
                _ => {
                    match attr_string.is_empty() {
                        true => attr_string,
                        false => attr_string + "\n",
                    }
                },
            }
        }

        // collect the information from meta items into Strings
        fn get_meta_as_string(meta_item: &MetaItem_) -> String {
            match *meta_item {
                MetaItem_::MetaWord(ref string) => format!("{}", string),
                MetaItem_::MetaList(ref string, ref meta_items) => {
                    let stuff = meta_items
                                .iter()
                                .map(|meta_item| {
                                    get_meta_as_string(&meta_item.node)
                                }).collect::<Vec<String>>();
                    format!("{}({})", string, stuff.connect(", "))
                },
                MetaItem_::MetaNameValue(ref string, ref literal) => {
                    let value = match literal.node {
                        Lit_::LitStr(ref inner_str, _style) => inner_str,
                        _ => panic!("unexpected literal found for meta item!"),
                    }; format!("{} = \"{}\"", string, value)
                },
            }
        }

        // checks the sorting of all the declarations and raises warnings whenever necessary
        // takes a slice of tuples with name, related attributes, spans and whether to warn for unordered use lists
        fn check_sort(old_list: &[(String, String, Span, bool)], cx: &Context, kind: &str, syntax: &str) {
            let length = old_list.len();
            let mut new_list = old_list
                                .iter()
                                .map(|&(ref name, ref attrs, _span, warn)| (name.clone(), attrs.clone(), warn))
                                .collect::<Vec<(String, String, bool)>>();
            new_list.sort_by(|&(ref str_a, ref attr_a, _), &(ref str_b, ref attr_b, _)| {
                // move the `pub` statements below (with `~` since it's on the farther side of ASCII)
                let mut new_str_a = str_for_biased_sort(&str_a, attr_a.ends_with("pub "), "~");
                let mut new_str_b = str_for_biased_sort(&str_b, attr_b.ends_with("pub "), "~");
                // move the #[macro_use] stuff above (with `!` since it's on the lower extreme of ASCII)
                new_str_a = str_for_biased_sort(&new_str_a, attr_a.starts_with("#[macro_use]"), "!");
                new_str_b = str_for_biased_sort(&new_str_b, attr_b.starts_with("#[macro_use]"), "!");
                new_str_a.cmp(&new_str_b)
            });

            let mut index = 0;
            let mut span: Option<Span> = None;
            for i in 0..length {
                if (old_list[i].0 != new_list[i].0) || new_list[i].2 {
                    span = Some(old_list[i].2);
                    index = i;      // only to find the index of the first unsorted declaration
                    break;          // because, we'll be printing everything following the first unsorted one
                }
            }

            match span {
                Some(span_start) => {   // print all the declarations proceeding the first unsorted one
                    let suggestion_list = (index..length)
                                          .map(|i| {
                                              if i == length - 1 {  // increase the span to include more lines
                                                  let mut sp = span_start;
                                                  sp.hi = old_list[i].2.hi;
                                                  span = Some(sp);
                                              } format!("{}{} {};", new_list[i].1, syntax, new_list[i].0)
                                          }).collect::<Vec<String>>();
                    let suggestion = format!("{} should be in alphabetical order!\nTry this...\n\n{}\n\n",
                                            kind, suggestion_list.connect("\n"));
                    // unwrapping the value here, because it's quite certain that there's something in `span`
                    cx.span_lint(UNSORTED_DECLARATIONS, span.unwrap(), &suggestion);
                },
                None => (),
            }

            // prepend given characters to names for biased sorting
            fn str_for_biased_sort(string: &String, choice: bool, prepend_char: &str) -> String {
                match choice {
                    true => prepend_char.to_owned() + &**string,
                    false => string.clone()
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::str::FromStr;
use std::convert::From;
use time::Duration;

use error::{Error, ProtoError, ParseError};

#[derive(Debug, PartialEq, Clone)]
pub struct Status {
    pub volume: i8,
    pub repeat: bool,
    pub random: bool,
    pub single: bool,
    pub consume: bool,
    pub queue_version: usize,
    pub queue_len: usize,
    pub state: State,
    //song: Option<MpdQueuePlace>,
    //nextsong: Option<MpdQueuePlace>,
    //play_time: Option<Duration>,
    //total_time: Option<Duration>,
    //elapsed: Option<Duration>,
    //duration: Option<Duration>,
    pub bitrate: Option<usize>,
    pub crossfade: Option<u64>,
    pub mixrampdb: f32,
    pub mixrampdelay: Option<Duration>,
    pub audio: Option<AudioFormat>,
    pub updating_db: Option<usize>,
    pub error: Option<String>
}

impl Status {
    pub fn from_map(map: BTreeMap<String, String>) -> Result<Status, Error> {
        Ok(Status {
            volume: get_field!(map, "volume"),

            repeat: get_field!(map, bool "repeat"),
            random: get_field!(map, bool "random"),
            single: get_field!(map, bool "single"),
            consume: get_field!(map, bool "consume"),

            queue_version: get_field!(map, "playlist"),
            queue_len: get_field!(map, "playlistlength"),
            state: get_field!(map, "state"),
            //song: Option<MpdQueuePlace>,
            //nextsong: Option<MpdQueuePlace>,
            //play_time: Option<Duration>,
            //total_time: Option<Duration>,
            //elapsed: Option<Duration>,
            //duration: Option<Duration>,
            bitrate: get_field!(map, opt "bitrate"),
            crossfade: get_field!(map, opt "xfade"),
            mixrampdb: 0.0, //get_field!(map, "mixrampdb"),
            mixrampdelay: None, //get_field!(map, opt "mixrampdelay").map(|v: f64| Duration::milliseconds((v * 1000.0) as i64)),
            audio: get_field!(map, opt "audio"),
            updating_db: get_field!(map, opt "updating_db"),
            error: map.get("error").map(|v| v.to_owned()),
        })
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct AudioFormat {
    pub rate: u16,
    pub bits: u8,
    pub chans: u8
}

impl FromStr for AudioFormat {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<AudioFormat, ParseError> {
        let mut it = s.split(':');
        Ok(AudioFormat {
            rate: try!(it.next().ok_or(ParseError::NoRate).and_then(|v| v.parse().map_err(ParseError::BadRate))),
            bits: try!(it.next().ok_or(ParseError::NoBits).and_then(|v| v.parse().map_err(ParseError::BadBits))),
            chans: try!(it.next().ok_or(ParseError::NoChans).and_then(|v| v.parse().map_err(ParseError::BadChans))),
        })
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum State {
    Stop,
    Play,
    Pause
}

impl FromStr for State {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<State, ParseError> {
        match s {
            "stop" => Ok(State::Stop),
            "play" => Ok(State::Play),
            "pause" => Ok(State::Pause),
            _ => Err(ParseError::BadState(s.to_owned())),
        }
    }
}
<commit_msg>fix bits parsing<commit_after>use std::collections::BTreeMap;
use std::str::FromStr;
use std::convert::From;
use time::Duration;

use error::{Error, ProtoError, ParseError};

#[derive(Debug, PartialEq, Clone)]
pub struct Status {
    pub volume: i8,
    pub repeat: bool,
    pub random: bool,
    pub single: bool,
    pub consume: bool,
    pub queue_version: usize,
    pub queue_len: usize,
    pub state: State,
    //song: Option<MpdQueuePlace>,
    //nextsong: Option<MpdQueuePlace>,
    //play_time: Option<Duration>,
    //total_time: Option<Duration>,
    //elapsed: Option<Duration>,
    //duration: Option<Duration>,
    pub bitrate: Option<usize>,
    pub crossfade: Option<u64>,
    pub mixrampdb: f32,
    pub mixrampdelay: Option<Duration>,
    pub audio: Option<AudioFormat>,
    pub updating_db: Option<usize>,
    pub error: Option<String>
}

impl Status {
    pub fn from_map(map: BTreeMap<String, String>) -> Result<Status, Error> {
        Ok(Status {
            volume: get_field!(map, "volume"),

            repeat: get_field!(map, bool "repeat"),
            random: get_field!(map, bool "random"),
            single: get_field!(map, bool "single"),
            consume: get_field!(map, bool "consume"),

            queue_version: get_field!(map, "playlist"),
            queue_len: get_field!(map, "playlistlength"),
            state: get_field!(map, "state"),
            //song: Option<MpdQueuePlace>,
            //nextsong: Option<MpdQueuePlace>,
            //play_time: Option<Duration>,
            //total_time: Option<Duration>,
            //elapsed: Option<Duration>,
            //duration: Option<Duration>,
            bitrate: get_field!(map, opt "bitrate"),
            crossfade: get_field!(map, opt "xfade"),
            mixrampdb: 0.0, //get_field!(map, "mixrampdb"),
            mixrampdelay: None, //get_field!(map, opt "mixrampdelay").map(|v: f64| Duration::milliseconds((v * 1000.0) as i64)),
            audio: get_field!(map, opt "audio"),
            updating_db: get_field!(map, opt "updating_db"),
            error: map.get("error").map(|v| v.to_owned()),
        })
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub struct AudioFormat {
    pub rate: u16,
    pub bits: u8,
    pub chans: u8
}

impl FromStr for AudioFormat {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<AudioFormat, ParseError> {
        let mut it = s.split(':');
        Ok(AudioFormat {
            rate: try!(it.next().ok_or(ParseError::NoRate).and_then(|v| v.parse().map_err(ParseError::BadRate))),
            bits: try!(it.next().ok_or(ParseError::NoBits).and_then(|v| if &*v == "f" { Ok(0) } else { v.parse().map_err(ParseError::BadBits) })),
            chans: try!(it.next().ok_or(ParseError::NoChans).and_then(|v| v.parse().map_err(ParseError::BadChans))),
        })
    }
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum State {
    Stop,
    Play,
    Pause
}

impl FromStr for State {
    type Err = ParseError;
    fn from_str(s: &str) -> Result<State, ParseError> {
        match s {
            "stop" => Ok(State::Stop),
            "play" => Ok(State::Play),
            "pause" => Ok(State::Pause),
            _ => Err(ParseError::BadState(s.to_owned())),
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub struct GameBoard {
    field: [[State, ..3], ..3]
}

impl GameBoard {
    pub fn new() -> GameBoard {
        GameBoard {
            field: [[State::Empty, ..3], ..3]
        }
    }

    pub fn set_at(& mut self, who: State, at: (uint, uint)) {
        self.field[at.0][at.1] = who;
    }

    pub fn get_at(&self, at: (uint, uint)) -> State {
        self.field[at.0][at.1]
    }
}

pub enum State {
    Empty, X, O
}

impl State {
    pub fn negate(self) -> State {
        match self {
            State::O => State::X,
            State::X => State::O,
            _ => State::Empty
        }
    }
}

impl PartialEq for State {
    fn eq(&self, other: &State) -> bool {
        match *other {
            State::Empty => {
                match *self {
                    State::Empty => true,
                    _ => false
                }
            },
            State::X => {
                match *self {
                    State::X => true,
                    _ => false
                }
            },
            State::O => {
                match *self {
                    State::O => true,
                    _ => false
                }
            }
        }
    }
}

impl fmt::Show for State {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let out = match *self {
            State::Empty => "_",
            State::X => "X",
            State::O => "O"
        };
        fmt.pad(out)
    }
}

impl Copy for State {

}<commit_msg>New array syntax<commit_after>use std::fmt;

pub struct GameBoard {
    field: [[State;3];3]
}

impl GameBoard {
    pub fn new() -> GameBoard {
        GameBoard {
            field: [[State::Empty;3];3]
        }
    }

    pub fn set_at(& mut self, who: State, at: (uint, uint)) {
        self.field[at.0][at.1] = who;
    }

    pub fn get_at(&self, at: (uint, uint)) -> State {
        self.field[at.0][at.1]
    }
}

pub enum State {
    Empty, X, O
}

impl State {
    pub fn negate(self) -> State {
        match self {
            State::O => State::X,
            State::X => State::O,
            _ => State::Empty
        }
    }
}

impl PartialEq for State {
    fn eq(&self, other: &State) -> bool {
        match *other {
            State::Empty => {
                match *self {
                    State::Empty => true,
                    _ => false
                }
            },
            State::X => {
                match *self {
                    State::X => true,
                    _ => false
                }
            },
            State::O => {
                match *self {
                    State::O => true,
                    _ => false
                }
            }
        }
    }
}

impl fmt::Show for State {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let out = match *self {
            State::Empty => "_",
            State::X => "X",
            State::O => "O"
        };
        fmt.pad(out)
    }
}

impl Copy for State {

}<|endoftext|>