<commit_before>
use ir;
use lang;
use util;
use ir::Value;
use std::fmt;

// TODO: pass the module to all functions so we can lookup globals et al

impl fmt::Display for ir::Module
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self::module(self, fmt)
    }
}

pub fn module(module: &ir::Module, fmt: &mut fmt::Formatter) -> fmt::Result {

    let mut global_accum = 0;
    for global in module.globals() {
        try!(self::global(global, module, fmt, &mut global_accum));
    }

    try!(write!(fmt, "\n"));

    for func in module.functions() {
         try!(self::function(func, module, fmt));
    }

    Ok(())
}

pub fn global(global: &ir::Global,
              module: &ir::Module,
              fmt: &mut fmt::Formatter,
              accum: &mut u64) -> fmt::Result {
    write!(fmt, "%{} = ", global.name());
    self::root_value(global.value(), module, fmt, accum)
}

pub fn function(func: &ir::Function,
                module: &ir::Module,
                fmt: &mut fmt::Formatter) -> fmt::Result {

    let mut accum = 1;

    try!(write!(fmt, "define {} @{}({}) {{\n",
                     util::comma_separated_values(func.signature.returns()),
                     func.name(),
                     util::comma_separated_values(func.signature.parameters())));

    for block in func.blocks() {
        try!(self::block(block, module, fmt, &mut accum));
    }

    write!(fmt, "}}")
}

pub fn block(block: &ir::Block,
             module: &ir::Module,
             fmt: &mut fmt::Formatter,
             accum: &mut u64) -> fmt::Result {

    try!(write!(fmt, "{}:\n", block.name()));

    for value in block.subvalues() {
        try!(self::root_value(&value, module, fmt, accum));
    }

    Ok(())
}

pub fn root_value(value: &ir::Value,
                  module: &ir::Module,
                  fmt: &mut fmt::Formatter,
                  accum: &mut u64) -> fmt::Result {
    try!(write!(fmt, "\t"));
    try!(self::value::plain_value(value, module, fmt, accum));
    write!(fmt, "\n")
}

pub fn name(name: &lang::Name,
            fmt: &mut fmt::Formatter,
            accum: &mut u64) -> fmt::Result {
    unimplemented!();
}

pub mod value
{
    use ir::{Module,Value,Instruction,value};
    use std::fmt;
    use util;
    use lang;

    pub fn value(value: &Value,
                 module: &Module,
                 fmt: &mut fmt::Formatter,
                 accum: &mut u64) -> fmt::Result {
        use lang::Value;

        // simple values are not parenthesised.
        if !value.is_simple() {
            try!(write!(fmt, "("));
        }

        try!(self::plain_value(value, module, fmt, accum));

        if !value.is_simple() {
            try!(write!(fmt, ")"));
        }

        Ok(())
    }

    pub fn plain_value(value: &Value,
                       module: &Module,
                       fmt: &mut fmt::Formatter,
                       accum: &mut u64) -> fmt::Result {

        match value {
            &Value::Literal(ref val) => self::literal(val, fmt),
            &Value::Pointer(ref val) => self::pointer(val, module, fmt, accum),
            &Value::Register(ref val) => self::register(val, module, fmt, accum),
            &Value::Instruction(ref val) => self::instruction::instruction(val, module, fmt, accum),
            &Value::GlobalRef(ref val) => self::global_ref(val, module, fmt, accum),
            &Value::BlockRef(ref val) => self::block_ref(val, module, fmt, accum),
            &Value::FunctionRef(ref val) => self::function_ref(val, module, fmt, accum),
            &Value::RegisterRef(ref val) => self::register_ref(val, module, fmt, accum),
        }
    }

    pub fn literal(value: &value::Literal,
                   fmt: &mut fmt::Formatter) -> fmt::Result {
        match value {
            &value::Literal::Integer(ref val) => self::literal_integer(val, fmt),
            _ => unimplemented!(),
        }
    }

    pub fn literal_integer(value: &value::literal::Integer,
                           fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{} {}", value.ty(), value.value())
    }

    pub fn literal_struct(value: &value::literal::Struct,
                          module: &Module,
                          fmt: &mut fmt::Formatter,
                          accum: &mut u64) -> fmt::Result {
        unimplemented!();
        //write!(fmt, "{{ {} }}", util::comma_separated_values(value.fields()))
    }

    pub fn pointer(value: &value::Pointer,
                   module: &Module,
                   fmt: &mut fmt::Formatter,
                   accum: &mut u64) -> fmt::Result {
        try!(self::value(value.underlying(), module, fmt, accum));
        write!(fmt, "*")
    }

    pub fn register(value: &value::Register,
                    module: &Module,
                    fmt: &mut fmt::Formatter,
                    accum: &mut u64) -> fmt::Result {

        try!(write!(fmt, "%{} = ", value.name()));
        self::value(value.subvalue(), module, fmt, accum)
    }

    pub fn global_ref(value: &value::GlobalRef,
                      module: &Module,
                      fmt: &mut fmt::Formatter,
                      accum: &mut u64) -> fmt::Result {

        let global = module.get_global(value.global_id());
        write!(fmt, "%{}", global.name())
    }

    pub fn block_ref(value: &value::BlockRef,
                     module: &Module,
                     fmt: &mut fmt::Formatter,
                     accum: &mut u64) -> fmt::Result {
        unimplemented!();
    }

    pub fn function_ref(value: &value::FunctionRef,
                        module: &Module,
                        fmt: &mut fmt::Formatter,
                        accum: &mut u64) -> fmt::Result {
        unimplemented!();
    }

    pub fn register_ref(value: &value::RegisterRef,
                        module: &Module,
                        fmt: &mut fmt::Formatter,
                        accum: &mut u64) -> fmt::Result {
        write!(fmt, "%<reg>")
    }

    pub mod instruction
    {
        use ir::{Module,Value,Instruction};
        use ir::instruction::{self,Binary};
        use std::fmt;
        use util;

        pub fn instruction(inst: &Instruction,
                           module: &Module,
                           fmt: &mut fmt::Formatter,
                           accum: &mut u64) -> fmt::Result {
            match inst {
                &Instruction::Add(ref i) => arithmetic_binop("add", i, module, fmt, accum),
                &Instruction::Sub(ref i) => arithmetic_binop("sub", i, module, fmt, accum),
                &Instruction::Mul(ref i) => arithmetic_binop("mul", i, module, fmt, accum),
                &Instruction::Div(ref i) => arithmetic_binop("div", i, module, fmt, accum),
                &Instruction::Shl(ref i) => arithmetic_binop("shl", i, module, fmt, accum),
                &Instruction::Shr(ref i) => arithmetic_binop("shr", i, module, fmt, accum),

                &Instruction::Call(ref i) => call(i, module, fmt, accum),
                &Instruction::Break(ref i) => br(i, module, fmt, accum),
                &Instruction::Return(ref i) => ret(i, module, fmt, accum),
            }
        }

        pub fn arithmetic_binop<I>(mnemonic: &'static str,
                                   inst: &I,
                                   module: &Module,
                                   fmt: &mut fmt::Formatter,
                                   accum: &mut u64) -> fmt::Result
            where I: Binary {

            let (lhs,rhs) = inst.operands();

            try!(write!(fmt, "{} ", mnemonic));
            try!(super::value(lhs, module, fmt, accum));
            try!(write!(fmt, ", "));
            try!(super::value(rhs, module, fmt, accum));
            Ok(())
        }

        pub fn call(inst: &instruction::Call,
                    module: &Module,
                    fmt: &mut fmt::Formatter,
                    accum: &mut u64) -> fmt::Result {
            let func = if let &Value::FunctionRef(ref f) = inst.target() {
                f
            } else {
                unreachable!(); // target must be function
            };
            write!(fmt, "call {} {}",
                   util::comma_separated_values(func.signature().returns()),
                   func.name())

        }

        pub fn br(inst: &instruction::Break,
                  module: &Module,
                  fmt: &mut fmt::Formatter,
                  accum: &mut u64) -> fmt::Result {
            unimplemented!();
        }

        pub fn ret(inst: &instruction::Return,
                   module: &Module,
                   fmt: &mut fmt::Formatter,
                   accum: &mut u64) -> fmt::Result {
            try!(write!(fmt, "ret "));

            match inst.subvalue() {
                Some(i) => super::value(i, module, fmt, accum),
                None => write!(fmt, "void"),
            }
        }
    }
}
<commit_msg>[IR] Use 'Printer' type rather than 'accum'<commit_after>
use ir;
use lang;
use util;
use ir::Value;
use std::fmt;

impl fmt::Display for ir::Module
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        self::module(self, fmt)
    }
}

pub struct Printer<'a>
{
    module: &'a ir::Module,
    accum: u64,
}

pub fn module(module: &ir::Module, fmt: &mut fmt::Formatter) -> fmt::Result {

    let mut printer = Printer {
        module: module,
        accum: 0,
    };

    for global in module.globals() {
        try!(self::global(global, &mut printer, fmt));
    }

    try!(write!(fmt, "\n"));

    for func in module.functions() {
         try!(self::function(func, &mut printer, fmt));
    }

    Ok(())
}

pub fn global(global: &ir::Global,
              printer: &mut Printer,
              fmt: &mut fmt::Formatter) -> fmt::Result {
    write!(fmt, "%{} = ", global.name());
    self::root_value(global.value(), printer, fmt)
}

pub fn function(func: &ir::Function,
                printer: &mut Printer,
                fmt: &mut fmt::Formatter) -> fmt::Result {

    let mut accum = 1;

    try!(write!(fmt, "define {} @{}({}) {{\n",
                     util::comma_separated_values(func.signature.returns()),
                     func.name(),
                     util::comma_separated_values(func.signature.parameters())));

    for block in func.blocks() {
        try!(self::block(block, printer, fmt));
    }

    write!(fmt, "}}")
}

pub fn block(block: &ir::Block,
             printer: &mut Printer,
             fmt: &mut fmt::Formatter) -> fmt::Result {

    try!(write!(fmt, "{}:\n", block.name()));

    for value in block.subvalues() {
        try!(self::root_value(&value, printer, fmt));
    }

    Ok(())
}

pub fn root_value(value: &ir::Value,
                  printer: &mut Printer,
                  fmt: &mut fmt::Formatter) -> fmt::Result {
    try!(write!(fmt, "\t"));
    try!(self::value::plain_value(value, printer, fmt));
    write!(fmt, "\n")
}

pub fn name(name: &lang::Name,
            printer: &mut Printer,
            fmt: &mut fmt::Formatter) -> fmt::Result {
    unimplemented!();
}

pub mod value
{
    use ir::{Module,Value,Instruction,value};
    use std::fmt;
    use util;
    use lang;
    use super::Printer;

    pub fn value(value: &Value,
                 printer: &mut Printer,
                 fmt: &mut fmt::Formatter) -> fmt::Result {
        use lang::Value;

        // simple values are not parenthesised.
        if !value.is_simple() {
            try!(write!(fmt, "("));
        }

        try!(self::plain_value(value, printer, fmt));

        if !value.is_simple() {
            try!(write!(fmt, ")"));
        }

        Ok(())
    }

    pub fn plain_value(value: &Value,
                       printer: &mut Printer,
                       fmt: &mut fmt::Formatter) -> fmt::Result {

        match value {
            &Value::Literal(ref val) => self::literal(val, fmt),
            &Value::Pointer(ref val) => self::pointer(val, printer, fmt),
            &Value::Register(ref val) => self::register(val, printer, fmt),
            &Value::Instruction(ref val) => self::instruction::instruction(val, printer, fmt),
            &Value::GlobalRef(ref val) => self::global_ref(val, printer, fmt),
            &Value::BlockRef(ref val) => self::block_ref(val, printer, fmt),
            &Value::FunctionRef(ref val) => self::function_ref(val, printer, fmt),
            &Value::RegisterRef(ref val) => self::register_ref(val, printer, fmt),
        }
    }

    pub fn literal(value: &value::Literal,
                   fmt: &mut fmt::Formatter) -> fmt::Result {
        match value {
            &value::Literal::Integer(ref val) => self::literal_integer(val, fmt),
            _ => unimplemented!(),
        }
    }

    pub fn literal_integer(value: &value::literal::Integer,
                           fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{} {}", value.ty(), value.value())
    }

    pub fn literal_struct(value: &value::literal::Struct,
                          printer: &mut Printer,
                          fmt: &mut fmt::Formatter) -> fmt::Result {
        unimplemented!();
        //write!(fmt, "{{ {} }}", util::comma_separated_values(value.fields()))
    }

    pub fn pointer(value: &value::Pointer,
                   printer: &mut Printer,
                   fmt: &mut fmt::Formatter) -> fmt::Result {
        try!(self::value(value.underlying(), printer, fmt));
        write!(fmt, "*")
    }

    pub fn register(value: &value::Register,
                    printer: &mut Printer,
                    fmt: &mut fmt::Formatter) -> fmt::Result {

        try!(write!(fmt, "%{} = ", value.name()));
        self::value(value.subvalue(), printer, fmt)
    }

    pub fn global_ref(value: &value::GlobalRef,
                      printer: &mut Printer,
                      fmt: &mut fmt::Formatter) -> fmt::Result {

        let global = printer.module.get_global(value.global_id());
        write!(fmt, "%{}", global.name())
    }

    pub fn block_ref(value: &value::BlockRef,
                     printer: &mut Printer,
                     fmt: &mut fmt::Formatter) -> fmt::Result {
        unimplemented!();
    }

    pub fn function_ref(value: &value::FunctionRef,
                        printer: &mut Printer,
                        fmt: &mut fmt::Formatter) -> fmt::Result {
        unimplemented!();
    }

    pub fn register_ref(value: &value::RegisterRef,
                        printer: &mut Printer,
                        fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "%<reg>")
    }

    pub mod instruction
    {
        use ir::{Module,Value,Instruction};
        use ir::instruction::{self,Binary};
        use std::fmt;
        use util;
        use super::super::Printer;

        pub fn instruction(inst: &Instruction,
                           printer: &mut Printer,
                           fmt: &mut fmt::Formatter) -> fmt::Result {
            match inst {
                &Instruction::Add(ref i) => arithmetic_binop("add", i, printer, fmt),
                &Instruction::Sub(ref i) => arithmetic_binop("sub", i, printer, fmt),
                &Instruction::Mul(ref i) => arithmetic_binop("mul", i, printer, fmt),
                &Instruction::Div(ref i) => arithmetic_binop("div", i, printer, fmt),
                &Instruction::Shl(ref i) => arithmetic_binop("shl", i, printer, fmt),
                &Instruction::Shr(ref i) => arithmetic_binop("shr", i, printer, fmt),

                &Instruction::Call(ref i) => call(i, printer, fmt),
                &Instruction::Break(ref i) => br(i, printer, fmt),
                &Instruction::Return(ref i) => ret(i, printer, fmt),
            }
        }

        pub fn arithmetic_binop<I>(mnemonic: &'static str,
                                   inst: &I,
                                   printer: &mut Printer,
                                   fmt: &mut fmt::Formatter) -> fmt::Result
            where I: Binary {

            let (lhs,rhs) = inst.operands();

            try!(write!(fmt, "{} ", mnemonic));
            try!(super::value(lhs, printer, fmt));
            try!(write!(fmt, ", "));
            try!(super::value(rhs, printer, fmt));
            Ok(())
        }

        pub fn call(inst: &instruction::Call,
                    printer: &mut Printer,
                    fmt: &mut fmt::Formatter) -> fmt::Result {
            let func = if let &Value::FunctionRef(ref f) = inst.target() {
                f
            } else {
                unreachable!(); // target must be function
            };
            write!(fmt, "call {} {}",
                   util::comma_separated_values(func.signature().returns()),
                   func.name())

        }

        pub fn br(inst: &instruction::Break,
                  printer: &mut Printer,
                  fmt: &mut fmt::Formatter) -> fmt::Result {
            unimplemented!();
        }

        pub fn ret(inst: &instruction::Return,
                   printer: &mut Printer,
                   fmt: &mut fmt::Formatter) -> fmt::Result {
            try!(write!(fmt, "ret "));

            match inst.subvalue() {
                Some(i) => super::value(i, printer, fmt),
                None => write!(fmt, "void"),
            }
        }
    }
}
<|endoftext|>


<commit_before>#![feature(allocator_api)]
#![feature(const_fn)]
#![feature(alloc)]
#![feature(unique)]

#![no_std]

extern crate spin;
extern crate alloc;

mod block;
mod allocator;
mod locked_allocator;

pub use allocator::Allocator;
pub use locked_allocator::LockedAllocator;

#[cfg(test)]
mod test;
<commit_msg>Added ptr_internals feature gate to alloc_opsys lib<commit_after>#![feature(allocator_api)]
#![feature(const_fn)]
#![feature(alloc)]
#![feature(unique)]
#![feature(ptr_internals)]
#![no_std]

extern crate spin;
extern crate alloc;

mod block;
mod allocator;
mod locked_allocator;

pub use allocator::Allocator;
pub use locked_allocator::LockedAllocator;

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>// Copyright (c) 2015, The Radare Project. All rights reserved.
// See the COPYING file at the top-level directory of this distribution.
// Licensed under the BSD 3-Clause License:
// <http://opensource.org/licenses/BSD-3-Clause>
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implements the `GraphDot` trait for `SSAStorage`

use petgraph::graph;
use petgraph::visit::{IntoEdgeReferences, EdgeRef};
use petgraph::graph::NodeIndex;

use middle::ir::MOpcode;
use middle::dot::{DotAttrBlock, GraphDot};
use super::ssastorage::{EdgeData, NodeData, SSAStorage};
use super::ssa_traits::{SSA, SSAExtra};
use middle::ssa::cfg_traits::CFG;

///////////////////////////////////////////////////////////////////////////////
//// Implementation of GraphDot to emit Dot for SSAStorage.
///////////////////////////////////////////////////////////////////////////////

impl GraphDot for SSAStorage {
    type NodeIndex = graph::NodeIndex;
    type EdgeIndex = graph::EdgeIndex;

    fn configure(&self) -> String {
        "digraph cfg {\nsplines=\"ortho\"\nranksep=1\nnodesep=1;\ngraph [fontsize=12 fontname=\"Verdana\" compound=true \
         rankdir=TB;]\n"
            .to_owned()
    }

    fn nodes(&self) -> Vec<Self::NodeIndex> {
        self.g.node_indices().collect()
    }

    fn edges(&self) -> Vec<Self::EdgeIndex> {
        self.g.edge_references().map(|x| x.id()).collect()
    }

    fn node_count(&self) -> usize {
        self.g.node_count()
    }

    fn edge_count(&self) -> usize {
        self.g.edge_count()
    }

    fn node_index_new(i: usize) -> Self::NodeIndex {
        graph::NodeIndex::new(i)
    }

    fn edge_index_new(i: usize) -> Self::EdgeIndex {
        graph::EdgeIndex::new(i)
    }

    fn node_cluster(&self, i: &Self::NodeIndex) -> Option<usize> {
        let invalid_block = self.invalid_action().expect("Invalid Action is not defined");
        match self.g.node_weight(*i) {
            Some(&NodeData::BasicBlock(_, _)) | Some(&NodeData::DynamicAction) => Some(i.index()),
            _ => Some(self.block_for(*i).unwrap_or(invalid_block).index()),
        }
    }

    fn edge_source(&self, i: &Self::EdgeIndex) -> Self::NodeIndex {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return NodeIndex::end();
        };
        let edge = edge_opt.unwrap();
        match *edge.weight() {
            EdgeData::Data(_) => edge.target(),
            _ => edge.source(),
        }
    }

    fn edge_target(&self, i: &Self::EdgeIndex) -> Self::NodeIndex {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return NodeIndex::end();
        };
        let edge = edge_opt.unwrap();
         match *edge.weight() {
            EdgeData::Data(_) => edge.source(),
            _ => edge.target(),
        }
    }

    fn edge_skip(&self, i: &Self::EdgeIndex) -> bool {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return false;
        };
        let edge = edge_opt.unwrap();
        match *edge.weight() {
            EdgeData::ContainedInBB(_) | EdgeData::RegisterState => true,
            _ => false,
        }
    }

    // TODO: Ordering of clusters for ssa is kind of hacky and may not run top to
    // bottom in some
    // cases.
    fn edge_attrs(&self, i: &Self::EdgeIndex) -> DotAttrBlock {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return DotAttrBlock::Raw(String::new());
        };
        let edge = edge_opt.unwrap();
        let mut prefix = String::new();
        let src = edge.source();
        let target = edge.target();

        prefix.push_str(&format!("n{} -> n{}",
                                 src.index(),
                                 target.index()));
        let target_is_bb = if let NodeData::BasicBlock(_, _) = self.g[edge.target()] {
            true
        } else {
            false
        };
        let attr = match *edge.weight() {
            EdgeData::Control(_) if !target_is_bb => {
                vec![("color".to_string(), "red".to_string())]
            }
            EdgeData::Control(i) => {
                // Determine the source and destination clusters.
                let source_cluster = edge.source().index();
                let dst_cluster = edge.target().index();
                let (color, label) = match i {
                    0 => ("red", "F"),
                    1 => ("green", "T"),
                    2 => ("blue", "U"),
                    _ => unreachable!(),
                };
                vec![("color".to_string(), color.to_string()),
                     ("xlabel".to_string(), label.to_string()),
                     ("ltail".to_string(), format!("cluster_{}", source_cluster)),
                     ("lhead".to_string(), format!("cluster_{}", dst_cluster)),
                     ("minlen".to_string(), "9".to_owned())]
            }
            EdgeData::Data(i) => {
                vec![("dir".to_string(), "back".to_string()),
                     ("xlabel".to_string(), format!("{}", i))]
            }
            EdgeData::ContainedInBB(_) => {
                vec![("color".to_string(), "gray".to_string())]
            }
            EdgeData::Selector => {
                vec![("color".to_string(), "purple".to_string())]
            }
            EdgeData::ReplacedBy => {
                vec![("color".to_string(), "brown".to_string())]
            }
            EdgeData::RegisterInfo => {
                vec![("color".to_string(), "yellow".to_string())]
            }
            EdgeData::RegisterState => unreachable!(),
        };

        DotAttrBlock::Hybrid(prefix, attr)
    }

    fn node_attrs(&self, i: &Self::NodeIndex) -> DotAttrBlock {
        let node = &self.g[*i];
        let mut prefix = String::new();
        prefix.push_str(&format!("n{}", i.index()));

        let attr = match *node {
            NodeData::Op(ref opc, vi) => {
                let w = vi.width().get_width().unwrap_or(64);
                let mut attrs = Vec::new();
                let mut r = String::new();
                let addr = self.addr(i);
                if addr.is_some() {
                    r.push_str(&format!("<{}: ",
                                        addr.as_ref().unwrap()))
                }
                r.push_str(&format!("\"[i{}] {:?}\"", w, opc));
                if addr.is_some() {
                    r.push_str(">");
                }

                if let MOpcode::OpConst(_) = *opc {
                    attrs.push(("style".to_owned(), "filled".to_owned()));
                    attrs.push(("color".to_owned(), "black".to_owned()));
                    attrs.push(("fillcolor".to_owned(), "yellow".to_owned()));
                }
                if self.is_marked(i) {
                    attrs.push(("label".to_string(), r));
                    attrs.push(("style".to_owned(), "filled".to_owned()));
                    attrs.push(("color".to_owned(), "black".to_owned()));
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "white".to_owned()));
                }
                attrs
            }
            NodeData::BasicBlock(addr, _) => {
                let label_str = format!("<Basic Block \
                                         Information
Start Address: {}>",
                                        addr);
                let mut attrs = Vec::new();
                if let Some(e) = self.entry_node() {
                    if *i == e {
                        attrs.push(("rank".to_string(), "min".to_string()));
                    }
                };

                attrs.extend([("style".to_string(), "filled".to_string()),
                              ("fillcolor".to_string(), "white".to_string()),
                              ("label".to_string(), label_str),
                              ("shape".to_string(), "box".to_string()),
                              ("color".to_string(), "\"grey\"".to_string()),]
                                 .iter()
                                 .cloned());
                attrs
            }
            NodeData::Comment(_, ref msg) => {
                vec![("label".to_string(),
                      format!("\"{}\"", msg.replace("\"", "\\\""))),
                     ("shape".to_owned(), "box".to_owned()),
                     ("style".to_owned(), "filled".to_owned()),
                     ("color".to_owned(), "black".to_owned()),
                     ("fillcolor".to_owned(), "greenyellow".to_owned())]
            }
            NodeData::Phi(_, _) => {
                let mut attrs = Vec::new();
                let mut label = format!("{:?}", node);
                label = label.replace("\"", "\\\"");
                label = format!("\"{}\"", label);
                if let Some(addr) = self.addr(i) {
                    label = format!("<{}:  {}>", addr, label);
                }
                attrs.push(("label".to_string(), label));
                attrs.push(("style".to_owned(), "filled".to_owned()));
                attrs.push(("color".to_owned(), "black".to_owned()));
                if self.is_marked(i) {
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "orange".to_owned()));
                }
                attrs
            }
            _ => {
                let mut attrs = Vec::new();
                let mut label = format!("{:?}", node);
                label = label.replace("\"", "\\\"");
                label = format!("\"{}\"", label);
                if let Some(addr) = self.addr(i) {
                    label = format!("<{}:  {}>", addr, label);
                }
                attrs.push(("label".to_string(), label));
                attrs.push(("style".to_owned(), "filled".to_owned()));
                attrs.push(("color".to_owned(), "black".to_owned()));
                if self.is_marked(i) {
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "grey90".to_owned()));
                }
                attrs
            }
        };
        DotAttrBlock::Hybrid(prefix, attr)
    }
}
<commit_msg>Skip egdes from registers to registerstates<commit_after>// Copyright (c) 2015, The Radare Project. All rights reserved.
// See the COPYING file at the top-level directory of this distribution.
// Licensed under the BSD 3-Clause License:
// <http://opensource.org/licenses/BSD-3-Clause>
// This file may not be copied, modified, or distributed
// except according to those terms.

//! Implements the `GraphDot` trait for `SSAStorage`

use petgraph::graph;
use petgraph::visit::{IntoEdgeReferences, EdgeRef};
use petgraph::graph::NodeIndex;

use middle::ir::MOpcode;
use middle::dot::{DotAttrBlock, GraphDot};
use super::ssastorage::{EdgeData, NodeData, SSAStorage};
use super::ssa_traits::{SSA, SSAExtra};
use middle::ssa::cfg_traits::CFG;

///////////////////////////////////////////////////////////////////////////////
//// Implementation of GraphDot to emit Dot for SSAStorage.
///////////////////////////////////////////////////////////////////////////////

impl GraphDot for SSAStorage {
    type NodeIndex = graph::NodeIndex;
    type EdgeIndex = graph::EdgeIndex;

    fn configure(&self) -> String {
        "digraph cfg {\nsplines=\"ortho\"\nranksep=1\nnodesep=1;\ngraph [fontsize=12 fontname=\"Verdana\" compound=true \
         rankdir=TB;]\n"
            .to_owned()
    }

    fn nodes(&self) -> Vec<Self::NodeIndex> {
        self.g.node_indices().collect()
    }

    fn edges(&self) -> Vec<Self::EdgeIndex> {
        self.g.edge_references().map(|x| x.id()).collect()
    }

    fn node_count(&self) -> usize {
        self.g.node_count()
    }

    fn edge_count(&self) -> usize {
        self.g.edge_count()
    }

    fn node_index_new(i: usize) -> Self::NodeIndex {
        graph::NodeIndex::new(i)
    }

    fn edge_index_new(i: usize) -> Self::EdgeIndex {
        graph::EdgeIndex::new(i)
    }

    fn node_cluster(&self, i: &Self::NodeIndex) -> Option<usize> {
        let invalid_block = self.invalid_action().expect("Invalid Action is not defined");
        match self.g.node_weight(*i) {
            Some(&NodeData::BasicBlock(_, _)) | Some(&NodeData::DynamicAction) => Some(i.index()),
            _ => Some(self.block_for(*i).unwrap_or(invalid_block).index()),
        }
    }

    fn edge_source(&self, i: &Self::EdgeIndex) -> Self::NodeIndex {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return NodeIndex::end();
        };
        let edge = edge_opt.unwrap();
        match *edge.weight() {
            EdgeData::Data(_) => edge.target(),
            _ => edge.source(),
        }
    }

    fn edge_target(&self, i: &Self::EdgeIndex) -> Self::NodeIndex {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return NodeIndex::end();
        };
        let edge = edge_opt.unwrap();
         match *edge.weight() {
            EdgeData::Data(_) => edge.source(),
            _ => edge.target(),
        }
    }

    fn edge_skip(&self, i: &Self::EdgeIndex) -> bool {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return false;
        };
        let edge = edge_opt.unwrap();
        match *edge.weight() {
            EdgeData::ContainedInBB(_) | EdgeData::RegisterState => true,
            EdgeData::Data(_) => {
                // Skip data edges from registers to registerstates.
                if let NodeData::RegisterState = self.g[edge.source()] {
                    self.comment(edge.target()).is_some()
                } else {
                    false
                }
            },
            _ => false,
        }
    }

    // TODO: Ordering of clusters for ssa is kind of hacky and may not run top to
    // bottom in some
    // cases.
    fn edge_attrs(&self, i: &Self::EdgeIndex) -> DotAttrBlock {
        let edge_opt = &self.g.edge_references().find(|x| x.id() == *i);
        if edge_opt.is_none() {
            radeco_err!("Invalid edge index");
            return DotAttrBlock::Raw(String::new());
        };
        let edge = edge_opt.unwrap();
        let mut prefix = String::new();
        let src = edge.source();
        let target = edge.target();

        prefix.push_str(&format!("n{} -> n{}",
                                 src.index(),
                                 target.index()));
        let target_is_bb = if let NodeData::BasicBlock(_, _) = self.g[edge.target()] {
            true
        } else {
            false
        };
        let attr = match *edge.weight() {
            EdgeData::Control(_) if !target_is_bb => {
                vec![("color".to_string(), "red".to_string())]
            }
            EdgeData::Control(i) => {
                // Determine the source and destination clusters.
                let source_cluster = edge.source().index();
                let dst_cluster = edge.target().index();
                let (color, label) = match i {
                    0 => ("red", "F"),
                    1 => ("green", "T"),
                    2 => ("blue", "U"),
                    _ => unreachable!(),
                };
                vec![("color".to_string(), color.to_string()),
                     ("xlabel".to_string(), label.to_string()),
                     ("ltail".to_string(), format!("cluster_{}", source_cluster)),
                     ("lhead".to_string(), format!("cluster_{}", dst_cluster)),
                     ("minlen".to_string(), "9".to_owned())]
            }
            EdgeData::Data(i) => {
                vec![("dir".to_string(), "back".to_string()),
                     ("xlabel".to_string(), format!("{}", i))]
            }
            EdgeData::ContainedInBB(_) => {
                vec![("color".to_string(), "gray".to_string())]
            }
            EdgeData::Selector => {
                vec![("color".to_string(), "purple".to_string())]
            }
            EdgeData::ReplacedBy => {
                vec![("color".to_string(), "brown".to_string())]
            }
            EdgeData::RegisterInfo => {
                vec![("color".to_string(), "yellow".to_string())]
            }
            EdgeData::RegisterState => unreachable!(),
        };

        DotAttrBlock::Hybrid(prefix, attr)
    }

    fn node_attrs(&self, i: &Self::NodeIndex) -> DotAttrBlock {
        let node = &self.g[*i];
        let mut prefix = String::new();
        prefix.push_str(&format!("n{}", i.index()));

        let attr = match *node {
            NodeData::Op(ref opc, vi) => {
                let w = vi.width().get_width().unwrap_or(64);
                let mut attrs = Vec::new();
                let mut r = String::new();
                let addr = self.addr(i);
                if addr.is_some() {
                    r.push_str(&format!("<{}: ",
                                        addr.as_ref().unwrap()))
                }
                r.push_str(&format!("\"[i{}] {:?}\"", w, opc));
                if addr.is_some() {
                    r.push_str(">");
                }

                if let MOpcode::OpConst(_) = *opc {
                    attrs.push(("style".to_owned(), "filled".to_owned()));
                    attrs.push(("color".to_owned(), "black".to_owned()));
                    attrs.push(("fillcolor".to_owned(), "yellow".to_owned()));
                }
                if self.is_marked(i) {
                    attrs.push(("label".to_string(), r));
                    attrs.push(("style".to_owned(), "filled".to_owned()));
                    attrs.push(("color".to_owned(), "black".to_owned()));
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "white".to_owned()));
                }
                attrs
            }
            NodeData::BasicBlock(addr, _) => {
                let label_str = format!("<Basic Block \
                                         Information
Start Address: {}>",
                                        addr);
                let mut attrs = Vec::new();
                if let Some(e) = self.entry_node() {
                    if *i == e {
                        attrs.push(("rank".to_string(), "min".to_string()));
                    }
                };

                attrs.extend([("style".to_string(), "filled".to_string()),
                              ("fillcolor".to_string(), "white".to_string()),
                              ("label".to_string(), label_str),
                              ("shape".to_string(), "box".to_string()),
                              ("color".to_string(), "\"grey\"".to_string()),]
                                 .iter()
                                 .cloned());
                attrs
            }
            NodeData::Comment(_, ref msg) => {
                vec![("label".to_string(),
                      format!("\"{}\"", msg.replace("\"", "\\\""))),
                     ("shape".to_owned(), "box".to_owned()),
                     ("style".to_owned(), "filled".to_owned()),
                     ("color".to_owned(), "black".to_owned()),
                     ("fillcolor".to_owned(), "greenyellow".to_owned())]
            }
            NodeData::Phi(_, _) => {
                let mut attrs = Vec::new();
                let mut label = format!("{:?}", node);
                label = label.replace("\"", "\\\"");
                label = format!("\"{}\"", label);
                if let Some(addr) = self.addr(i) {
                    label = format!("<{}:  {}>", addr, label);
                }
                attrs.push(("label".to_string(), label));
                attrs.push(("style".to_owned(), "filled".to_owned()));
                attrs.push(("color".to_owned(), "black".to_owned()));
                if self.is_marked(i) {
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "orange".to_owned()));
                }
                attrs
            }
            _ => {
                let mut attrs = Vec::new();
                let mut label = format!("{:?}", node);
                label = label.replace("\"", "\\\"");
                label = format!("\"{}\"", label);
                if let Some(addr) = self.addr(i) {
                    label = format!("<{}:  {}>", addr, label);
                }
                attrs.push(("label".to_string(), label));
                attrs.push(("style".to_owned(), "filled".to_owned()));
                attrs.push(("color".to_owned(), "black".to_owned()));
                if self.is_marked(i) {
                    attrs.push(("fillcolor".to_owned(), "green".to_owned()));
                } else {
                    attrs.push(("fillcolor".to_owned(), "grey90".to_owned()));
                }
                attrs
            }
        };
        DotAttrBlock::Hybrid(prefix, attr)
    }
}
<|endoftext|>


<commit_before>//! Implementation of the custom `Optional` type. See `Optional`
//! docs for more information.

use rustc_serialize::{Decodable, Decoder};

/// An `Optional` can contain either `Value<T>` or `Absent`.
/// It is similar to an `Option`, but `None` will be serialized to `null`
/// while `Absent` means the value will be omitted when serialized.
///
/// An `Optional` implements the `Default` trait, it is `Absent` by default.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Optional<T> {
    Value(T),
    Absent,
}
use Optional::*;

impl<T> Optional<T> {

    /// Moves the value `v` out of the `Optional<T>` if it is `Value(v)`.
    ///
    /// # Panics
    ///
    /// Panics if the self value equals `Absent`.
    ///
    /// # Safety note
    ///
    /// In general, because this function may panic, its use is discouraged.
    /// Instead, prefer to use pattern matching and handle the `Absent`
    /// case explicitly.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x = Value("air");
    /// assert_eq!(x.unwrap(), "air");
    /// ```
    ///
    /// ```{.should_panic}
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<&str> = Absent;
    /// assert_eq!(x.unwrap(), "air"); // fails
    /// ```
    pub fn unwrap(self) -> T {
        match self {
            Optional::Value(val) => val,
            Optional::Absent => panic!("called `Optional::unwrap()` on a `Absent` value"),
        }
    }

    /// Returns the contained value or computes it from a closure.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let k = 10;
    /// assert_eq!(Value(4).unwrap_or_else(|| 2 * k), 4);
    /// assert_eq!(Absent.unwrap_or_else(|| 2 * k), 20);
    /// ```
    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
        match self {
            Optional::Value(x) => x,
            Optional::Absent => f()
        }
    }

    /// Maps an `Optional<T>` to `Optional<U>` by applying a function to a contained value
    ///
    /// # Examples
    ///
    /// Convert an `Optional<String>` into an `Optional<usize>`, consuming the original:
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let num_as_str: Optional<String> = Value("10".to_string());
    /// // `Optional::map` takes self *by value*, consuming `num_as_str`
    /// let num_as_int: Optional<usize> = num_as_str.map(|n| n.len());
    /// ```
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
        match self {
            Optional::Value(x) => Optional::Value(f(x)),
            Optional::Absent => Optional::Absent
        }
    }

    /// Applies a function to the contained value or returns a default.  see
    /// [`std::option::Option<T>::map_or`](http://doc.rust-lang.org/std/option/enum.Option.html#method.map_or)
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Optional::Value(v) => f(v),
            Optional::Absent => def,
        }
    }

    /// Converts from `Optional<T>` to `Optional<&mut T>`
    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Optional::Value(ref mut x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Converts from `Optional<T>` to `Optional<&T>`
    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Optional::Value(ref x) => Optional::Value(x),
            Optional::Absent => Optional::Absent
        }
    }

    /// Returns `Absent` if the optional is `Absent`, otherwise calls `f` with the
    /// wrapped value and returns the result.
    ///
    /// Some languages call this operation flatmap.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// fn sq(x: u32) -> Optional<u32> { Value(x * x) }
    /// fn nope(_: u32) -> Optional<u32> { Absent }
    ///
    /// assert_eq!(Value(2).and_then(sq).and_then(sq), Value(16));
    /// assert_eq!(Value(2).and_then(sq).and_then(nope), Absent);
    /// assert_eq!(Value(2).and_then(nope).and_then(sq), Absent);
    /// assert_eq!(Absent.and_then(sq).and_then(sq), Absent);
    /// ```
    pub fn and_then<U, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
        match self {
            Optional::Value(x) => f(x),
            Optional::Absent => Optional::Absent,
        }
    }

    /// Returns `true` if the optional is a `Absent` value
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(x.is_absent(), false);
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(x.is_absent(), true);
    /// ```
    pub fn is_absent(&self) -> bool {
        match *self {
            Optional::Absent => true,
            _ => false
        }
    }
}

impl<T> Default for Optional<T> {
    /// An optional value is absent by default.
    fn default() -> Optional<T> {
        Absent
    }
}

impl<T> Into<Option<T>> for Optional<T> {
    /// Convert Optional<T> into Option<T>
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(Some(2), x.into());
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(None, x.into());
    /// ```
    fn into(self) -> Option<T> {
        match self {
            Optional::Value(x) => Some(x),
            Optional::Absent => None,
        }
    }
}

impl<T:Decodable> Decodable for Optional<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<Optional<T>, D::Error> {
        d.read_option(|d, b| {
            if b {
                Ok(Value(try!(Decodable::decode(d))))
            } else {
                Ok(Absent)
            }
        })
    }
}

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

    #[test]
    fn test_default() {
        let something: Optional<u8> = Default::default();
        assert_eq!(something, Optional::Absent);
    }

    #[test]
    fn test_default_in_struct() {
        #[derive(Default)]
        struct Foo {
            something: Optional<u8>,
            somenum: u8,
        }

        let foo1: Foo = Default::default();
        assert_eq!(foo1.something, Optional::Absent);
        assert_eq!(foo1.somenum, 0);

        let foo2 = Foo { somenum: 7, ..Default::default() };
        assert_eq!(foo2.something, Optional::Absent);
        assert_eq!(foo2.somenum, 7);
    }

}
<commit_msg>Remove unneeded namespacing<commit_after>//! Implementation of the custom `Optional` type. See `Optional`
//! docs for more information.

use rustc_serialize::{Decodable, Decoder};

/// An `Optional` can contain either `Value<T>` or `Absent`.
/// It is similar to an `Option`, but `None` will be serialized to `null`
/// while `Absent` means the value will be omitted when serialized.
///
/// An `Optional` implements the `Default` trait, it is `Absent` by default.
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
pub enum Optional<T> {
    Value(T),
    Absent,
}
use Optional::*;

impl<T> Optional<T> {

    /// Moves the value `v` out of the `Optional<T>` if it is `Value(v)`.
    ///
    /// # Panics
    ///
    /// Panics if the self value equals `Absent`.
    ///
    /// # Safety note
    ///
    /// In general, because this function may panic, its use is discouraged.
    /// Instead, prefer to use pattern matching and handle the `Absent`
    /// case explicitly.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x = Value("air");
    /// assert_eq!(x.unwrap(), "air");
    /// ```
    ///
    /// ```{.should_panic}
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<&str> = Absent;
    /// assert_eq!(x.unwrap(), "air"); // fails
    /// ```
    pub fn unwrap(self) -> T {
        match self {
            Value(val) => val,
            Absent => panic!("called `Optional::unwrap()` on a `Absent` value"),
        }
    }

    /// Returns the contained value or computes it from a closure.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let k = 10;
    /// assert_eq!(Value(4).unwrap_or_else(|| 2 * k), 4);
    /// assert_eq!(Absent.unwrap_or_else(|| 2 * k), 20);
    /// ```
    pub fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T {
        match self {
            Value(x) => x,
            Absent => f()
        }
    }

    /// Maps an `Optional<T>` to `Optional<U>` by applying a function to a contained value
    ///
    /// # Examples
    ///
    /// Convert an `Optional<String>` into an `Optional<usize>`, consuming the original:
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let num_as_str: Optional<String> = Value("10".to_string());
    /// // `Optional::map` takes self *by value*, consuming `num_as_str`
    /// let num_as_int: Optional<usize> = num_as_str.map(|n| n.len());
    /// ```
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Optional<U> {
        match self {
            Value(x) => Value(f(x)),
            Absent => Absent
        }
    }

    /// Applies a function to the contained value or returns a default.  see
    /// [`std::option::Option<T>::map_or`](http://doc.rust-lang.org/std/option/enum.Option.html#method.map_or)
    pub fn map_or<U, F: FnOnce(T) -> U>(self, def: U, f: F) -> U {
        match self {
            Value(v) => f(v),
            Absent => def,
        }
    }

    /// Converts from `Optional<T>` to `Optional<&mut T>`
    pub fn as_mut<'r>(&'r mut self) -> Optional<&'r mut T> {
        match *self {
            Value(ref mut x) => Value(x),
            Absent => Absent
        }
    }

    /// Converts from `Optional<T>` to `Optional<&T>`
    pub fn as_ref<'r>(&'r self) -> Optional<&'r T> {
        match *self {
            Value(ref x) => Value(x),
            Absent => Absent
        }
    }

    /// Returns `Absent` if the optional is `Absent`, otherwise calls `f` with the
    /// wrapped value and returns the result.
    ///
    /// Some languages call this operation flatmap.
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// fn sq(x: u32) -> Optional<u32> { Value(x * x) }
    /// fn nope(_: u32) -> Optional<u32> { Absent }
    ///
    /// assert_eq!(Value(2).and_then(sq).and_then(sq), Value(16));
    /// assert_eq!(Value(2).and_then(sq).and_then(nope), Absent);
    /// assert_eq!(Value(2).and_then(nope).and_then(sq), Absent);
    /// assert_eq!(Absent.and_then(sq).and_then(sq), Absent);
    /// ```
    pub fn and_then<U, F: FnOnce(T) -> Optional<U>>(self, f: F) -> Optional<U> {
        match self {
            Value(x) => f(x),
            Absent => Absent,
        }
    }

    /// Returns `true` if the optional is a `Absent` value
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(x.is_absent(), false);
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(x.is_absent(), true);
    /// ```
    pub fn is_absent(&self) -> bool {
        match *self {
            Absent => true,
            _ => false
        }
    }
}

impl<T> Default for Optional<T> {
    /// An optional value is absent by default.
    fn default() -> Optional<T> {
        Absent
    }
}

impl<T> Into<Option<T>> for Optional<T> {
    /// Convert Optional<T> into Option<T>
    ///
    /// # Examples
    ///
    /// ```
    /// # use spaceapi::optional::Optional;
    /// # use spaceapi::optional::Optional::{Value,Absent};
    /// let x: Optional<u32> = Value(2);
    /// assert_eq!(Some(2), x.into());
    ///
    /// let x: Optional<u32> = Absent;
    /// assert_eq!(None, x.into());
    /// ```
    fn into(self) -> Option<T> {
        match self {
            Value(x) => Some(x),
            Absent => None,
        }
    }
}

impl<T:Decodable> Decodable for Optional<T> {
    fn decode<D: Decoder>(d: &mut D) -> Result<Optional<T>, D::Error> {
        d.read_option(|d, b| {
            if b {
                Ok(Value(try!(Decodable::decode(d))))
            } else {
                Ok(Absent)
            }
        })
    }
}

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

    #[test]
    fn test_default() {
        let something: Optional<u8> = Default::default();
        assert_eq!(something, Optional::Absent);
    }

    #[test]
    fn test_default_in_struct() {
        #[derive(Default)]
        struct Foo {
            something: Optional<u8>,
            somenum: u8,
        }

        let foo1: Foo = Default::default();
        assert_eq!(foo1.something, Optional::Absent);
        assert_eq!(foo1.somenum, 0);

        let foo2 = Foo { somenum: 7, ..Default::default() };
        assert_eq!(foo2.something, Optional::Absent);
        assert_eq!(foo2.somenum, 7);
    }

}
<|endoftext|>


<commit_before>//! Just a dumping ground for cli stuff

use rustup::{self, Cfg, Notification, Toolchain, UpdateStatus};
use rustup::telemetry_analysis::TelemetryAnalysis;
use errors::*;
use rustup_utils::utils;
use rustup_utils::notify::NotificationLevel;
use self_update;
use std::io::{Write, BufRead, BufReader};
use std::process::{Command, Stdio};
use std::path::Path;
use std::{cmp, iter};
use std::sync::Arc;
use std::time::Duration;
use std;
use term2;
use wait_timeout::ChildExt;

pub fn confirm(question: &str, default: bool) -> Result<bool> {
    print!("{} ", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "y" | "Y" => true,
        "n" | "N" => false,
        "" => default,
        _ => false,
    };

    println!("");

    Ok(r)
}

pub enum Confirm {
    Yes, No, Advanced
}

pub fn confirm_advanced() -> Result<Confirm> {
    println!("");
    println!("1) Proceed with installation (default)");
    println!("2) Customize installation");
    println!("3) Cancel installation");

    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "1"|"" => Confirm::Yes,
        "2" => Confirm::Advanced,
        _ => Confirm::No,
    };

    println!("");

    Ok(r)
}

pub fn question_str(question: &str, default: &str) -> Result<String> {
    println!("{}", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    println!("");

    if input.is_empty() {
        Ok(default.to_string())
    } else {
        Ok(input)
    }
}

pub fn question_bool(question: &str, default: bool) -> Result<bool> {
    println!("{}", question);

    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    println!("");

    if input.is_empty() {
        Ok(default)
    } else {
        match &*input {
            "y" | "Y" | "yes" => Ok(true),
            "n" | "N" | "no" => Ok(false),
            _ => Ok(default)
        }
    }

}

pub fn read_line() -> Result<String> {
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    lines.next().and_then(|l| l.ok()).ok_or(
        "unable to read from stdin for confirmation".into())
}

pub fn set_globals(verbose: bool) -> Result<Cfg> {
    use download_tracker::DownloadTracker;
    use std::cell::RefCell;

    let download_tracker = RefCell::new(DownloadTracker::new());

    Ok(try!(Cfg::from_env(Arc::new(move |n: Notification| {
       if download_tracker.borrow_mut().handle_notification(&n) {
            return;
        }

        match n.level() {
            NotificationLevel::Verbose => {
                if verbose {
                    verbose!("{}", n);
                }
            }
            NotificationLevel::Info => {
                info!("{}", n);
            }
            NotificationLevel::Warn => {
                warn!("{}", n);
            }
            NotificationLevel::Error => {
                err!("{}", n);
            }
        }
    }))))

}

pub fn show_channel_update(cfg: &Cfg, name: &str,
                           updated: rustup::Result<UpdateStatus>) -> Result<()> {
    show_channel_updates(cfg, vec![(name.to_string(), updated)])
}

fn show_channel_updates(cfg: &Cfg, toolchains: Vec<(String, rustup::Result<UpdateStatus>)>) -> Result<()> {
    let data = toolchains.into_iter().map(|(name, result)| {
        let ref toolchain = cfg.get_toolchain(&name, false).expect("");
        let version = rustc_version(toolchain);

        let banner;
        let color;
        match result {
            Ok(UpdateStatus::Installed) => {
                banner = "installed";
                color = Some(term2::color::BRIGHT_GREEN);
            }
            Ok(UpdateStatus::Updated) => {
                banner = "updated";
                color = Some(term2::color::BRIGHT_GREEN);
            }
            Ok(UpdateStatus::Unchanged) => {
                banner = "unchanged";
                color = None;
            }
            Err(_) => {
                banner = "update failed";
                color = Some(term2::color::BRIGHT_RED);
            }
        }

        let width = name.len() + 1 + banner.len();

        (name, banner, width, color, version)
    });

    let mut t = term2::stdout();

    let data: Vec<_> = data.collect();
    let max_width = data.iter().fold(0, |a, &(_, _, width, _, _)| cmp::max(a, width));

    for (name, banner, width, color, version) in data {
        let padding = max_width - width;
        let padding: String = iter::repeat(' ').take(padding).collect();
        let _ = write!(t, "  {}", padding);
        let _ = t.attr(term2::Attr::Bold);
        if let Some(color) = color {
            let _ = t.fg(color);
        }
        let _ = write!(t, "{} ", name);
        let _ = write!(t, "{}", banner);
        let _ = t.reset();
        let _ = writeln!(t, " - {}", version);
    }
    let _ = writeln!(t, "");

    Ok(())
}

pub fn update_all_channels(cfg: &Cfg, self_update: bool) -> Result<()> {

    let toolchains = try!(cfg.update_all_channels());

    if toolchains.is_empty() {
        info!("no updatable toolchains installed");
    }

    let setup_path = if self_update {
        try!(self_update::prepare_update())
    } else {
        None
    };

    if !toolchains.is_empty() {
        println!("");

        try!(show_channel_updates(cfg, toolchains));
    }

    if let Some(ref setup_path) = setup_path {
        try!(self_update::run_update(setup_path));

        unreachable!(); // update exits on success
    }

    Ok(())
}

pub fn rustc_version(toolchain: &Toolchain) -> String {
    if toolchain.exists() {
        let rustc_path = toolchain.binary_file("rustc");
        if utils::is_file(&rustc_path) {
            let mut cmd = Command::new(&rustc_path);
            cmd.arg("--version");
            cmd.stdin(Stdio::null());
            cmd.stdout(Stdio::piped());
            cmd.stderr(Stdio::piped());
            toolchain.set_ldpath(&mut cmd);

            // some toolchains are faulty with some combinations of platforms and
            // may fail to launch but also to timely terminate.
            // (known cases include Rust 1.3.0 through 1.10.0 in recent macOS Sierra.)
            // we guard against such cases by enforcing a reasonable timeout to read.
            let mut line1 = None;
            if let Ok(mut child) = cmd.spawn() {
                let timeout = Duration::new(3, 0);
                match child.wait_timeout(timeout) {
                    Ok(Some(status)) if status.success() => {
                        let out = child.stdout.expect("Child::stdout requested but not present");
                        let mut line = String::new();
                        if BufReader::new(out).read_line(&mut line).is_ok() {
                            let lineend = line.trim_right_matches(&['\r', '\n'][..]).len();
                            line.truncate(lineend);
                            line1 = Some(line);
                        }
                    }
                    Ok(None) => {
                        let _ = child.kill();
                        return String::from("(timeout reading rustc version)")
                    }
                    Ok(Some(_)) | Err(_) => {}
                }
            }

            if let Some(line1) = line1 {
                line1.to_owned()
            } else {
                String::from("(error reading rustc version)")
            }
        } else {
            String::from("(rustc does not exist)")
        }
    } else {
        String::from("(toolchain not installed)")
    }
}

pub fn list_targets(toolchain: &Toolchain) -> Result<()> {
    let mut t = term2::stdout();
    for component in try!(toolchain.list_components()) {
        if component.component.pkg == "rust-std" {
            let target = component.component.target.as_ref().expect("rust-std should have a target");
            if component.required {
                let _ = t.attr(term2::Attr::Bold);
                let _ = writeln!(t, "{} (default)", target);
                let _ = t.reset();
            } else if component.installed {
                let _ = t.attr(term2::Attr::Bold);
                let _ = writeln!(t, "{} (installed)", target);
                let _ = t.reset();
            } else if component.available {
                let _ = writeln!(t, "{}", target);
            }
        }
    }

    Ok(())
}

pub fn list_components(toolchain: &Toolchain) -> Result<()> {
    let mut t = term2::stdout();
    for component in try!(toolchain.list_components()) {
        let name = component.component.name();
        if component.required {
            let _ = t.attr(term2::Attr::Bold);
            let _ = writeln!(t, "{} (default)", name);
            let _ = t.reset();
        } else if component.installed {
            let _ = t.attr(term2::Attr::Bold);
            let _ = writeln!(t, "{} (installed)", name);
            let _ = t.reset();
        } else if component.available {
            let _ = writeln!(t, "{}", name);
        }
    }

    Ok(())
}

pub fn list_toolchains(cfg: &Cfg) -> Result<()> {
    let toolchains = try!(cfg.list_toolchains());

    if toolchains.is_empty() {
        println!("no installed toolchains");
    } else {
        if let Ok(Some(def_toolchain)) = cfg.find_default() {
            for toolchain in toolchains {
                let if_default = if def_toolchain.name() == &*toolchain {
                    " (default)"
                } else {
                    ""
                };
                println!("{}{}", &toolchain, if_default);
            }

        } else {
            for toolchain in toolchains {
                println!("{}", &toolchain);
            }
        }
    }
    Ok(())
}

pub fn list_overrides(cfg: &Cfg) -> Result<()> {
    let overrides = try!(cfg.settings_file.with(|s| Ok(s.overrides.clone())));

    if overrides.is_empty() {
        println!("no overrides");
    } else {
        let mut any_not_exist = false;
        for (k, v) in overrides {
            let dir_exists = Path::new(&k).is_dir();
            if !dir_exists {
                any_not_exist = true;
            }
            println!("{:<40}\t{:<20}",
                     utils::format_path_for_display(&k) +
                     if dir_exists {
                         ""
                     } else {
                         " (not a directory)"
                     },
                     v)
        }
        if any_not_exist {
            println!("");
            info!("you may remove overrides for non-existent directories with
`rustup override unset --nonexistent`");
        }
    }
    Ok(())
}

pub fn version() -> &'static str {
    concat!(env!("CARGO_PKG_VERSION"), include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")))
}

pub fn report_error(e: &Error) {
    err!("{}", e);

    for e in e.iter().skip(1) {
        info!("caused by: {}", e);
    }

    if show_backtrace() {
        if let Some(backtrace) = e.backtrace() {
            info!("backtrace:");
            println!("");
            println!("{:?}", backtrace);
        }
    } else {
    }

    fn show_backtrace() -> bool {
        use std::env;
        use std::ops::Deref;

        if env::var("RUST_BACKTRACE").as_ref().map(Deref::deref) == Ok("1") {
            return true;
        }

        for arg in env::args() {
            if arg == "-v" || arg == "--verbose" {
                return true;
            }
        }

        false
    }
}

pub fn show_telemetry(analysis: TelemetryAnalysis) -> Result<()> {
    println!("Telemetry Analysis");

    println!("{}", analysis);

    Ok(())
}
<commit_msg>increase the timeout for running `rustc --version`<commit_after>//! Just a dumping ground for cli stuff

use rustup::{self, Cfg, Notification, Toolchain, UpdateStatus};
use rustup::telemetry_analysis::TelemetryAnalysis;
use errors::*;
use rustup_utils::utils;
use rustup_utils::notify::NotificationLevel;
use self_update;
use std::io::{Write, BufRead, BufReader};
use std::process::{Command, Stdio};
use std::path::Path;
use std::{cmp, iter};
use std::sync::Arc;
use std::time::Duration;
use std;
use term2;
use wait_timeout::ChildExt;

pub fn confirm(question: &str, default: bool) -> Result<bool> {
    print!("{} ", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "y" | "Y" => true,
        "n" | "N" => false,
        "" => default,
        _ => false,
    };

    println!("");

    Ok(r)
}

pub enum Confirm {
    Yes, No, Advanced
}

pub fn confirm_advanced() -> Result<Confirm> {
    println!("");
    println!("1) Proceed with installation (default)");
    println!("2) Customize installation");
    println!("3) Cancel installation");

    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    let r = match &*input {
        "1"|"" => Confirm::Yes,
        "2" => Confirm::Advanced,
        _ => Confirm::No,
    };

    println!("");

    Ok(r)
}

pub fn question_str(question: &str, default: &str) -> Result<String> {
    println!("{}", question);
    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    println!("");

    if input.is_empty() {
        Ok(default.to_string())
    } else {
        Ok(input)
    }
}

pub fn question_bool(question: &str, default: bool) -> Result<bool> {
    println!("{}", question);

    let _ = std::io::stdout().flush();
    let input = try!(read_line());

    println!("");

    if input.is_empty() {
        Ok(default)
    } else {
        match &*input {
            "y" | "Y" | "yes" => Ok(true),
            "n" | "N" | "no" => Ok(false),
            _ => Ok(default)
        }
    }

}

pub fn read_line() -> Result<String> {
    let stdin = std::io::stdin();
    let stdin = stdin.lock();
    let mut lines = stdin.lines();
    lines.next().and_then(|l| l.ok()).ok_or(
        "unable to read from stdin for confirmation".into())
}

pub fn set_globals(verbose: bool) -> Result<Cfg> {
    use download_tracker::DownloadTracker;
    use std::cell::RefCell;

    let download_tracker = RefCell::new(DownloadTracker::new());

    Ok(try!(Cfg::from_env(Arc::new(move |n: Notification| {
       if download_tracker.borrow_mut().handle_notification(&n) {
            return;
        }

        match n.level() {
            NotificationLevel::Verbose => {
                if verbose {
                    verbose!("{}", n);
                }
            }
            NotificationLevel::Info => {
                info!("{}", n);
            }
            NotificationLevel::Warn => {
                warn!("{}", n);
            }
            NotificationLevel::Error => {
                err!("{}", n);
            }
        }
    }))))

}

pub fn show_channel_update(cfg: &Cfg, name: &str,
                           updated: rustup::Result<UpdateStatus>) -> Result<()> {
    show_channel_updates(cfg, vec![(name.to_string(), updated)])
}

fn show_channel_updates(cfg: &Cfg, toolchains: Vec<(String, rustup::Result<UpdateStatus>)>) -> Result<()> {
    let data = toolchains.into_iter().map(|(name, result)| {
        let ref toolchain = cfg.get_toolchain(&name, false).expect("");
        let version = rustc_version(toolchain);

        let banner;
        let color;
        match result {
            Ok(UpdateStatus::Installed) => {
                banner = "installed";
                color = Some(term2::color::BRIGHT_GREEN);
            }
            Ok(UpdateStatus::Updated) => {
                banner = "updated";
                color = Some(term2::color::BRIGHT_GREEN);
            }
            Ok(UpdateStatus::Unchanged) => {
                banner = "unchanged";
                color = None;
            }
            Err(_) => {
                banner = "update failed";
                color = Some(term2::color::BRIGHT_RED);
            }
        }

        let width = name.len() + 1 + banner.len();

        (name, banner, width, color, version)
    });

    let mut t = term2::stdout();

    let data: Vec<_> = data.collect();
    let max_width = data.iter().fold(0, |a, &(_, _, width, _, _)| cmp::max(a, width));

    for (name, banner, width, color, version) in data {
        let padding = max_width - width;
        let padding: String = iter::repeat(' ').take(padding).collect();
        let _ = write!(t, "  {}", padding);
        let _ = t.attr(term2::Attr::Bold);
        if let Some(color) = color {
            let _ = t.fg(color);
        }
        let _ = write!(t, "{} ", name);
        let _ = write!(t, "{}", banner);
        let _ = t.reset();
        let _ = writeln!(t, " - {}", version);
    }
    let _ = writeln!(t, "");

    Ok(())
}

pub fn update_all_channels(cfg: &Cfg, self_update: bool) -> Result<()> {

    let toolchains = try!(cfg.update_all_channels());

    if toolchains.is_empty() {
        info!("no updatable toolchains installed");
    }

    let setup_path = if self_update {
        try!(self_update::prepare_update())
    } else {
        None
    };

    if !toolchains.is_empty() {
        println!("");

        try!(show_channel_updates(cfg, toolchains));
    }

    if let Some(ref setup_path) = setup_path {
        try!(self_update::run_update(setup_path));

        unreachable!(); // update exits on success
    }

    Ok(())
}

pub fn rustc_version(toolchain: &Toolchain) -> String {
    if toolchain.exists() {
        let rustc_path = toolchain.binary_file("rustc");
        if utils::is_file(&rustc_path) {
            let mut cmd = Command::new(&rustc_path);
            cmd.arg("--version");
            cmd.stdin(Stdio::null());
            cmd.stdout(Stdio::piped());
            cmd.stderr(Stdio::piped());
            toolchain.set_ldpath(&mut cmd);

            // some toolchains are faulty with some combinations of platforms and
            // may fail to launch but also to timely terminate.
            // (known cases include Rust 1.3.0 through 1.10.0 in recent macOS Sierra.)
            // we guard against such cases by enforcing a reasonable timeout to read.
            let mut line1 = None;
            if let Ok(mut child) = cmd.spawn() {
                let timeout = Duration::new(10, 0);
                match child.wait_timeout(timeout) {
                    Ok(Some(status)) if status.success() => {
                        let out = child.stdout.expect("Child::stdout requested but not present");
                        let mut line = String::new();
                        if BufReader::new(out).read_line(&mut line).is_ok() {
                            let lineend = line.trim_right_matches(&['\r', '\n'][..]).len();
                            line.truncate(lineend);
                            line1 = Some(line);
                        }
                    }
                    Ok(None) => {
                        let _ = child.kill();
                        return String::from("(timeout reading rustc version)")
                    }
                    Ok(Some(_)) | Err(_) => {}
                }
            }

            if let Some(line1) = line1 {
                line1.to_owned()
            } else {
                String::from("(error reading rustc version)")
            }
        } else {
            String::from("(rustc does not exist)")
        }
    } else {
        String::from("(toolchain not installed)")
    }
}

pub fn list_targets(toolchain: &Toolchain) -> Result<()> {
    let mut t = term2::stdout();
    for component in try!(toolchain.list_components()) {
        if component.component.pkg == "rust-std" {
            let target = component.component.target.as_ref().expect("rust-std should have a target");
            if component.required {
                let _ = t.attr(term2::Attr::Bold);
                let _ = writeln!(t, "{} (default)", target);
                let _ = t.reset();
            } else if component.installed {
                let _ = t.attr(term2::Attr::Bold);
                let _ = writeln!(t, "{} (installed)", target);
                let _ = t.reset();
            } else if component.available {
                let _ = writeln!(t, "{}", target);
            }
        }
    }

    Ok(())
}

pub fn list_components(toolchain: &Toolchain) -> Result<()> {
    let mut t = term2::stdout();
    for component in try!(toolchain.list_components()) {
        let name = component.component.name();
        if component.required {
            let _ = t.attr(term2::Attr::Bold);
            let _ = writeln!(t, "{} (default)", name);
            let _ = t.reset();
        } else if component.installed {
            let _ = t.attr(term2::Attr::Bold);
            let _ = writeln!(t, "{} (installed)", name);
            let _ = t.reset();
        } else if component.available {
            let _ = writeln!(t, "{}", name);
        }
    }

    Ok(())
}

pub fn list_toolchains(cfg: &Cfg) -> Result<()> {
    let toolchains = try!(cfg.list_toolchains());

    if toolchains.is_empty() {
        println!("no installed toolchains");
    } else {
        if let Ok(Some(def_toolchain)) = cfg.find_default() {
            for toolchain in toolchains {
                let if_default = if def_toolchain.name() == &*toolchain {
                    " (default)"
                } else {
                    ""
                };
                println!("{}{}", &toolchain, if_default);
            }

        } else {
            for toolchain in toolchains {
                println!("{}", &toolchain);
            }
        }
    }
    Ok(())
}

pub fn list_overrides(cfg: &Cfg) -> Result<()> {
    let overrides = try!(cfg.settings_file.with(|s| Ok(s.overrides.clone())));

    if overrides.is_empty() {
        println!("no overrides");
    } else {
        let mut any_not_exist = false;
        for (k, v) in overrides {
            let dir_exists = Path::new(&k).is_dir();
            if !dir_exists {
                any_not_exist = true;
            }
            println!("{:<40}\t{:<20}",
                     utils::format_path_for_display(&k) +
                     if dir_exists {
                         ""
                     } else {
                         " (not a directory)"
                     },
                     v)
        }
        if any_not_exist {
            println!("");
            info!("you may remove overrides for non-existent directories with
`rustup override unset --nonexistent`");
        }
    }
    Ok(())
}

pub fn version() -> &'static str {
    concat!(env!("CARGO_PKG_VERSION"), include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")))
}

pub fn report_error(e: &Error) {
    err!("{}", e);

    for e in e.iter().skip(1) {
        info!("caused by: {}", e);
    }

    if show_backtrace() {
        if let Some(backtrace) = e.backtrace() {
            info!("backtrace:");
            println!("");
            println!("{:?}", backtrace);
        }
    } else {
    }

    fn show_backtrace() -> bool {
        use std::env;
        use std::ops::Deref;

        if env::var("RUST_BACKTRACE").as_ref().map(Deref::deref) == Ok("1") {
            return true;
        }

        for arg in env::args() {
            if arg == "-v" || arg == "--verbose" {
                return true;
            }
        }

        false
    }
}

pub fn show_telemetry(analysis: TelemetryAnalysis) -> Result<()> {
    println!("Telemetry Analysis");

    println!("{}", analysis);

    Ok(())
}
<|endoftext|>


<commit_before>
use handshake::{Token, HandshakePattern};
use handshake::Token::*;
use crypto_stuff::{copy_memory};

fn copy_tokens(input: &[Token], out: &mut [Token]) {
    for count in 0..input.len() {out[count] = input[count];}
}

pub struct NoiseN;
pub struct NoiseK;
pub struct NoiseX;

pub struct NoiseNN;
pub struct NoiseNK;
pub struct NoiseNE;
pub struct NoiseNX;

pub struct NoiseXN;
pub struct NoiseXK;
pub struct NoiseXE;
pub struct NoiseXX;

pub struct NoiseKN;
pub struct NoiseKK;
pub struct NoiseKE;
pub struct NoiseKX;

pub struct NoiseIN;
pub struct NoiseIK;
pub struct NoiseIE;
pub struct NoiseIX;

impl HandshakePattern for NoiseN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_N".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_K".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[S], premsg_pattern_i);

        copy_tokens(&[E, Dhes, Dhss], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_K".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhes, S, Dhss], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseNN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S, E], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, S, Dhse], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseXN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XE".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S, E], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, S, Dhse], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseKN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[S], premsg_pattern_i);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[S], premsg_pattern_i);

        copy_tokens(&[E, Dhes, Dhss], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("noise_ke".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S, E], premsg_pattern_r);
        copy_tokens(&[S], premsg_pattern_i);

        copy_tokens(&[E, Dhee, Dhes, Dhse], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[S], premsg_pattern_i);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[S, E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhes, S, Dhss], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IE".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S, E], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_r);
        copy_tokens(&[], premsg_pattern_i);

        copy_tokens(&[S, E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[1]);
    }
}
<commit_msg>Cleanup patterns.<commit_after>
use handshake::{Token, HandshakePattern};
use handshake::Token::*;
use crypto_stuff::{copy_memory};

fn copy_tokens(input: &[Token], out: &mut [Token]) {
    for count in 0..input.len() {out[count] = input[count];}
}

pub struct NoiseN;
pub struct NoiseK;
pub struct NoiseX;

pub struct NoiseNN;
pub struct NoiseNK;
pub struct NoiseNE;
pub struct NoiseNX;

pub struct NoiseXN;
pub struct NoiseXK;
pub struct NoiseXE;
pub struct NoiseXX;

pub struct NoiseKN;
pub struct NoiseKK;
pub struct NoiseKE;
pub struct NoiseKX;

pub struct NoiseIN;
pub struct NoiseIK;
pub struct NoiseIE;
pub struct NoiseIX;

impl HandshakePattern for NoiseN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_N".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_K".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes, Dhss], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_K".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes, S, Dhss], &mut msg_patterns[0]);
    }
}

impl HandshakePattern for NoiseNN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S, E], premsg_pattern_r);

        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseNX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_NX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, S, Dhse], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseXN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XE".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S, E], premsg_pattern_r);

        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseXX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_XX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, S, Dhse], &mut msg_patterns[1]);
        copy_tokens(&[S, Dhse], &mut msg_patterns[2]);
    }
}

impl HandshakePattern for NoiseKN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes, Dhss], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("noise_ke".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_i);
        copy_tokens(&[S, E], premsg_pattern_r);

        copy_tokens(&[E, Dhee, Dhes, Dhse], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseKX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_KX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[S], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIN {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IN".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[S, E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIK {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IK".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S], premsg_pattern_r);

        copy_tokens(&[E, Dhes, S, Dhss], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIE {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IE".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[S, E], premsg_pattern_r);

        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes], &mut msg_patterns[1]);
    }
}

impl HandshakePattern for NoiseIX {
    fn name(out : &mut [u8]) -> usize {
        copy_memory("Noise_IX".as_bytes(), out)
    }

    fn get(premsg_pattern_i: &mut [Token],
           premsg_pattern_r: &mut [Token],
           msg_patterns: &mut [[Token; 8]; 5]) {
        copy_tokens(&[], premsg_pattern_i);
        copy_tokens(&[], premsg_pattern_r);

        copy_tokens(&[S, E], &mut msg_patterns[0]);
        copy_tokens(&[E, Dhee, Dhes, S, Dhse], &mut msg_patterns[1]);
    }
}
<|endoftext|>