<commit_before>//! Internal library for data-encoding-macro
//!
//! Do **not** use this library. Use [data-encoding-macro] instead.
//!
//! This library is for internal use by data-encoding-macro because procedural
//! macros require a separate crate.
//!
//! [data-encoding-macro]: https://crates.io/crates/data-encoding-macro

#![cfg_attr(not(feature = "stable"), feature(proc_macro))]
#![warn(unused_results)]

extern crate proc_macro;
#[cfg(feature = "stable")]
#[macro_use]
extern crate proc_macro_hack;
extern crate syn;

extern crate data_encoding;

#[cfg(not(feature = "stable"))]
use proc_macro::{Spacing, TokenNode, TokenStream, TokenTree, TokenTreeIter};
use std::collections::HashMap;
#[cfg(feature = "stable")]
use syn::{Lit, Token, TokenTree};
#[cfg(feature = "stable")]
use syn::parse::IResult;

use data_encoding::{BitOrder, Encoding, Specification, Translate, Wrap};

#[cfg(not(feature = "stable"))]
fn parse_op(tokens: &mut TokenTreeIter, op: char, key: &str) {
    match tokens.next() {
        Some(TokenTree { span: _, kind: TokenNode::Op(x, Spacing::Alone) })
            if x == op => (),
        _ => panic!("expected {:?} after {}", op, key),
    }
}
#[cfg(feature = "stable")]
fn parse_op<'a>(input: &'a str, op: Token, key: &str) -> &'a str {
    match syn::parse::tt(input) {
        IResult::Done(rest, TokenTree::Token(ref x)) if x == &op => rest,
        _ => panic!("expected {:?} after {}", op, key),
    }
}

#[cfg(not(feature = "stable"))]
fn parse_map(mut tokens: TokenTreeIter) -> HashMap<String, TokenNode> {
    let mut map = HashMap::new();
    while let Some(key) = tokens.next() {
        let key = match key.kind {
            TokenNode::Term(term) => term.as_str().to_string(),
            _ => panic!("expected key got {}", key),
        };
        parse_op(&mut tokens, ':', &key);
        let value = match tokens.next() {
            None => panic!("expected value for {}", key),
            Some(value) => value.kind,
        };
        parse_op(&mut tokens, ',', &key);
        let _ = map.insert(key, value);
    }
    map
}
#[cfg(feature = "stable")]
fn parse_map(mut input: &str) -> HashMap<String, Token> {
    let mut map = HashMap::new();
    loop {
        let key = match syn::parse::tt(input) {
            IResult::Done(rest, key) => {
                input = rest;
                key
            }
            IResult::Error => break,
        };
        let key = match key {
            TokenTree::Token(Token::Ident(key)) => key,
            _ => panic!("expected key got {:?}", key),
        };
        input = parse_op(input, Token::Colon, key.as_ref());
        let value = match syn::parse::tt(input) {
            IResult::Done(rest, TokenTree::Token(value)) => {
                input = rest;
                value
            }
            _ => panic!("expected value for {}", key),
        };
        input = parse_op(input, Token::Comma, key.as_ref());
        let _ = map.insert(key.as_ref().to_string(), value);
    }
    map
}

#[cfg(not(feature = "stable"))]
fn get_string(map: &mut HashMap<String, TokenNode>, key: &str) -> String {
    let node = match map.remove(key) {
        None => return String::new(),
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match syn::parse::string(&literal.to_string()) {
        syn::parse::IResult::Done(_, result) => result.value,
        _ => panic!("expected string for {}", key),
    }
}
#[cfg(feature = "stable")]
fn get_string(map: &mut HashMap<String, Token>, key: &str) -> String {
    match map.remove(key) {
        None => return String::new(),
        Some(Token::Literal(Lit::Str(value, _))) => value,
        Some(_) => panic!("expected string literal for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_usize(map: &mut HashMap<String, TokenNode>, key: &str) -> usize {
    let node = match map.remove(key) {
        None => return 0,
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match literal.to_string().parse() {
        Ok(result) => result,
        Err(error) => panic!("expected usize for {}: {}", key, error),
    }
}
#[cfg(feature = "stable")]
fn get_usize(map: &mut HashMap<String, Token>, key: &str) -> usize {
    match map.remove(key) {
        None => return 0,
        Some(Token::Literal(Lit::Int(value, _))) => value as usize,
        Some(_) => panic!("expected usize for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_padding(map: &mut HashMap<String, TokenNode>) -> Option<char> {
    let node = match map.remove("padding") {
        None => return None,
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Term(term) if term.as_str() == "None" => return None,
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for padding"),
    };
    Some(syn::parse::character(&literal.to_string()).expect(
        "expected char for padding",
    ))
}
#[cfg(feature = "stable")]
fn get_padding(map: &mut HashMap<String, Token>) -> Option<char> {
    match map.remove("padding") {
        None => return None,
        Some(Token::Ident(ref ident)) if ident.as_ref() == "None" => None,
        Some(Token::Literal(Lit::Char(value))) => Some(value),
        Some(_) => panic!("expected char for padding"),
    }
}

#[cfg(not(feature = "stable"))]
fn get_bool(map: &mut HashMap<String, TokenNode>, key: &str) -> Option<bool> {
    let node = match map.remove(key) {
        None => return None,
        Some(node) => node,
    };
    let term = match node {
        TokenNode::Term(term) => term,
        _ => panic!("expected literal for padding"),
    };
    Some(syn::parse::boolean(term.as_str()).expect(
        "expected bool for padding",
    ))
}
#[cfg(feature = "stable")]
fn get_bool(map: &mut HashMap<String, Token>, key: &str) -> Option<bool> {
    match map.remove(key) {
        None => return None,
        Some(Token::Literal(Lit::Bool(value))) => Some(value),
        Some(_) => panic!("expected bool for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_bit_order(map: &mut HashMap<String, TokenNode>) -> BitOrder {
    let node = match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(node) => node,
    };
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match node {
        TokenNode::Term(term) if term.as_str() == msb => {
            BitOrder::MostSignificantFirst
        }
        TokenNode::Term(term) if term.as_str() == lsb => {
            BitOrder::LeastSignificantFirst
        }
        _ => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}
#[cfg(feature = "stable")]
fn get_bit_order(map: &mut HashMap<String, Token>) -> BitOrder {
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(Token::Ident(ref ident)) if ident.as_ref() == msb => {
            BitOrder::MostSignificantFirst
        }
        Some(Token::Ident(ref ident)) if ident.as_ref() == lsb => {
            BitOrder::LeastSignificantFirst
        }
        Some(_) => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}

fn check_present<T>(hash_map: &HashMap<String, T>, key: &str) {
    if !hash_map.contains_key(key) {
        panic!("{} is required", key);
    }
}

#[cfg(not(feature = "stable"))]
fn get_encoding(mut hash_map: &mut HashMap<String, TokenNode>) -> Encoding {
    check_present(&hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(&mut hash_map, "symbols"),
        bit_order: get_bit_order(&mut hash_map),
        check_trailing_bits: get_bool(&mut hash_map, "check_trailing_bits")
            .unwrap_or(true),
        padding: get_padding(&mut hash_map),
        ignore: get_string(&mut hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(&mut hash_map, "wrap_width"),
            separator: get_string(&mut hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(&mut hash_map, "translate_from"),
            to: get_string(&mut hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}
#[cfg(feature = "stable")]
fn get_encoding(mut hash_map: &mut HashMap<String, Token>) -> Encoding {
    check_present(&hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(&mut hash_map, "symbols"),
        bit_order: get_bit_order(&mut hash_map),
        check_trailing_bits: get_bool(&mut hash_map, "check_trailing_bits")
            .unwrap_or(true),
        padding: get_padding(&mut hash_map),
        ignore: get_string(&mut hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(&mut hash_map, "wrap_width"),
            separator: get_string(&mut hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(&mut hash_map, "translate_from"),
            to: get_string(&mut hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}

fn check_empty<T>(hash_map: HashMap<String, T>) {
    if !hash_map.is_empty() {
        panic!("Unexpected keys {:?}", hash_map.keys());
    }
}

#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_new_encoding(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_empty(hash_map);
    format!("{:?}", encoding.internal_implementation())
        .parse()
        .unwrap()
}
#[cfg(feature = "stable")]
proc_macro_expr_impl! {
    #[doc(hidden)]
    pub fn internal_new_encoding_impl(input: &str) -> String {
        let mut hash_map = parse_map(input);
        let encoding = get_encoding(&mut hash_map);
        check_empty(hash_map);
        format!("{:?}", encoding.internal_implementation())
    }
}

#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_array(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&mut hash_map, "name");
    let name = get_string(&mut hash_map, "name");
    check_present(&mut hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    let output = encoding.decode(input.as_bytes()).unwrap();
    format!("{}: [u8; {}] = {:?};", name, output.len(), output)
        .parse()
        .unwrap()
}
#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_slice(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&mut hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    format!("{:?}", encoding.decode(input.as_bytes()).unwrap())
        .parse()
        .unwrap()
}
#[cfg(feature = "stable")]
proc_macro_expr_impl! {
    #[doc(hidden)]
    pub fn internal_decode_slice_impl(input: &str) -> String {
        let mut hash_map = parse_map(input);
        let encoding = get_encoding(&mut hash_map);
        check_present(&mut hash_map, "input");
        let input = get_string(&mut hash_map, "input");
        check_empty(hash_map);
        format!("{:?}", encoding.decode(input.as_bytes()).unwrap())
    }
}
<commit_msg>lib/macro/internal: remove consecutive empty lines<commit_after>//! Internal library for data-encoding-macro
//!
//! Do **not** use this library. Use [data-encoding-macro] instead.
//!
//! This library is for internal use by data-encoding-macro because procedural
//! macros require a separate crate.
//!
//! [data-encoding-macro]: https://crates.io/crates/data-encoding-macro

#![cfg_attr(not(feature = "stable"), feature(proc_macro))]
#![warn(unused_results)]

extern crate proc_macro;
#[cfg(feature = "stable")]
#[macro_use]
extern crate proc_macro_hack;
extern crate syn;

extern crate data_encoding;

#[cfg(not(feature = "stable"))]
use proc_macro::{Spacing, TokenNode, TokenStream, TokenTree, TokenTreeIter};
use std::collections::HashMap;
#[cfg(feature = "stable")]
use syn::{Lit, Token, TokenTree};
#[cfg(feature = "stable")]
use syn::parse::IResult;

use data_encoding::{BitOrder, Encoding, Specification, Translate, Wrap};

#[cfg(not(feature = "stable"))]
fn parse_op(tokens: &mut TokenTreeIter, op: char, key: &str) {
    match tokens.next() {
        Some(TokenTree { span: _, kind: TokenNode::Op(x, Spacing::Alone) })
            if x == op => (),
        _ => panic!("expected {:?} after {}", op, key),
    }
}
#[cfg(feature = "stable")]
fn parse_op<'a>(input: &'a str, op: Token, key: &str) -> &'a str {
    match syn::parse::tt(input) {
        IResult::Done(rest, TokenTree::Token(ref x)) if x == &op => rest,
        _ => panic!("expected {:?} after {}", op, key),
    }
}

#[cfg(not(feature = "stable"))]
fn parse_map(mut tokens: TokenTreeIter) -> HashMap<String, TokenNode> {
    let mut map = HashMap::new();
    while let Some(key) = tokens.next() {
        let key = match key.kind {
            TokenNode::Term(term) => term.as_str().to_string(),
            _ => panic!("expected key got {}", key),
        };
        parse_op(&mut tokens, ':', &key);
        let value = match tokens.next() {
            None => panic!("expected value for {}", key),
            Some(value) => value.kind,
        };
        parse_op(&mut tokens, ',', &key);
        let _ = map.insert(key, value);
    }
    map
}
#[cfg(feature = "stable")]
fn parse_map(mut input: &str) -> HashMap<String, Token> {
    let mut map = HashMap::new();
    loop {
        let key = match syn::parse::tt(input) {
            IResult::Done(rest, key) => {
                input = rest;
                key
            }
            IResult::Error => break,
        };
        let key = match key {
            TokenTree::Token(Token::Ident(key)) => key,
            _ => panic!("expected key got {:?}", key),
        };
        input = parse_op(input, Token::Colon, key.as_ref());
        let value = match syn::parse::tt(input) {
            IResult::Done(rest, TokenTree::Token(value)) => {
                input = rest;
                value
            }
            _ => panic!("expected value for {}", key),
        };
        input = parse_op(input, Token::Comma, key.as_ref());
        let _ = map.insert(key.as_ref().to_string(), value);
    }
    map
}

#[cfg(not(feature = "stable"))]
fn get_string(map: &mut HashMap<String, TokenNode>, key: &str) -> String {
    let node = match map.remove(key) {
        None => return String::new(),
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match syn::parse::string(&literal.to_string()) {
        syn::parse::IResult::Done(_, result) => result.value,
        _ => panic!("expected string for {}", key),
    }
}
#[cfg(feature = "stable")]
fn get_string(map: &mut HashMap<String, Token>, key: &str) -> String {
    match map.remove(key) {
        None => return String::new(),
        Some(Token::Literal(Lit::Str(value, _))) => value,
        Some(_) => panic!("expected string literal for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_usize(map: &mut HashMap<String, TokenNode>, key: &str) -> usize {
    let node = match map.remove(key) {
        None => return 0,
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for {}", key),
    };
    match literal.to_string().parse() {
        Ok(result) => result,
        Err(error) => panic!("expected usize for {}: {}", key, error),
    }
}
#[cfg(feature = "stable")]
fn get_usize(map: &mut HashMap<String, Token>, key: &str) -> usize {
    match map.remove(key) {
        None => return 0,
        Some(Token::Literal(Lit::Int(value, _))) => value as usize,
        Some(_) => panic!("expected usize for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_padding(map: &mut HashMap<String, TokenNode>) -> Option<char> {
    let node = match map.remove("padding") {
        None => return None,
        Some(node) => node,
    };
    let literal = match node {
        TokenNode::Term(term) if term.as_str() == "None" => return None,
        TokenNode::Literal(literal) => literal,
        _ => panic!("expected literal for padding"),
    };
    Some(syn::parse::character(&literal.to_string()).expect(
        "expected char for padding",
    ))
}
#[cfg(feature = "stable")]
fn get_padding(map: &mut HashMap<String, Token>) -> Option<char> {
    match map.remove("padding") {
        None => return None,
        Some(Token::Ident(ref ident)) if ident.as_ref() == "None" => None,
        Some(Token::Literal(Lit::Char(value))) => Some(value),
        Some(_) => panic!("expected char for padding"),
    }
}

#[cfg(not(feature = "stable"))]
fn get_bool(map: &mut HashMap<String, TokenNode>, key: &str) -> Option<bool> {
    let node = match map.remove(key) {
        None => return None,
        Some(node) => node,
    };
    let term = match node {
        TokenNode::Term(term) => term,
        _ => panic!("expected literal for padding"),
    };
    Some(syn::parse::boolean(term.as_str()).expect(
        "expected bool for padding",
    ))
}
#[cfg(feature = "stable")]
fn get_bool(map: &mut HashMap<String, Token>, key: &str) -> Option<bool> {
    match map.remove(key) {
        None => return None,
        Some(Token::Literal(Lit::Bool(value))) => Some(value),
        Some(_) => panic!("expected bool for {}", key),
    }
}

#[cfg(not(feature = "stable"))]
fn get_bit_order(map: &mut HashMap<String, TokenNode>) -> BitOrder {
    let node = match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(node) => node,
    };
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match node {
        TokenNode::Term(term) if term.as_str() == msb => {
            BitOrder::MostSignificantFirst
        }
        TokenNode::Term(term) if term.as_str() == lsb => {
            BitOrder::LeastSignificantFirst
        }
        _ => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}
#[cfg(feature = "stable")]
fn get_bit_order(map: &mut HashMap<String, Token>) -> BitOrder {
    let msb = "MostSignificantFirst";
    let lsb = "LeastSignificantFirst";
    match map.remove("bit_order") {
        None => return BitOrder::MostSignificantFirst,
        Some(Token::Ident(ref ident)) if ident.as_ref() == msb => {
            BitOrder::MostSignificantFirst
        }
        Some(Token::Ident(ref ident)) if ident.as_ref() == lsb => {
            BitOrder::LeastSignificantFirst
        }
        Some(_) => panic!("expected {} or {} for bit_order", msb, lsb),
    }
}

fn check_present<T>(hash_map: &HashMap<String, T>, key: &str) {
    if !hash_map.contains_key(key) {
        panic!("{} is required", key);
    }
}

#[cfg(not(feature = "stable"))]
fn get_encoding(mut hash_map: &mut HashMap<String, TokenNode>) -> Encoding {
    check_present(&hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(&mut hash_map, "symbols"),
        bit_order: get_bit_order(&mut hash_map),
        check_trailing_bits: get_bool(&mut hash_map, "check_trailing_bits")
            .unwrap_or(true),
        padding: get_padding(&mut hash_map),
        ignore: get_string(&mut hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(&mut hash_map, "wrap_width"),
            separator: get_string(&mut hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(&mut hash_map, "translate_from"),
            to: get_string(&mut hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}
#[cfg(feature = "stable")]
fn get_encoding(mut hash_map: &mut HashMap<String, Token>) -> Encoding {
    check_present(&hash_map, "symbols");
    let spec = Specification {
        symbols: get_string(&mut hash_map, "symbols"),
        bit_order: get_bit_order(&mut hash_map),
        check_trailing_bits: get_bool(&mut hash_map, "check_trailing_bits")
            .unwrap_or(true),
        padding: get_padding(&mut hash_map),
        ignore: get_string(&mut hash_map, "ignore"),
        wrap: Wrap {
            width: get_usize(&mut hash_map, "wrap_width"),
            separator: get_string(&mut hash_map, "wrap_separator"),
        },
        translate: Translate {
            from: get_string(&mut hash_map, "translate_from"),
            to: get_string(&mut hash_map, "translate_to"),
        },
    };
    spec.encoding().unwrap()
}

fn check_empty<T>(hash_map: HashMap<String, T>) {
    if !hash_map.is_empty() {
        panic!("Unexpected keys {:?}", hash_map.keys());
    }
}

#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_new_encoding(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_empty(hash_map);
    format!("{:?}", encoding.internal_implementation())
        .parse()
        .unwrap()
}
#[cfg(feature = "stable")]
proc_macro_expr_impl! {
    #[doc(hidden)]
    pub fn internal_new_encoding_impl(input: &str) -> String {
        let mut hash_map = parse_map(input);
        let encoding = get_encoding(&mut hash_map);
        check_empty(hash_map);
        format!("{:?}", encoding.internal_implementation())
    }
}

#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_array(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&mut hash_map, "name");
    let name = get_string(&mut hash_map, "name");
    check_present(&mut hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    let output = encoding.decode(input.as_bytes()).unwrap();
    format!("{}: [u8; {}] = {:?};", name, output.len(), output)
        .parse()
        .unwrap()
}
#[cfg(not(feature = "stable"))]
#[proc_macro]
#[doc(hidden)]
pub fn internal_decode_slice(input: TokenStream) -> TokenStream {
    let mut hash_map = parse_map(input.into_iter());
    let encoding = get_encoding(&mut hash_map);
    check_present(&mut hash_map, "input");
    let input = get_string(&mut hash_map, "input");
    check_empty(hash_map);
    format!("{:?}", encoding.decode(input.as_bytes()).unwrap())
        .parse()
        .unwrap()
}
#[cfg(feature = "stable")]
proc_macro_expr_impl! {
    #[doc(hidden)]
    pub fn internal_decode_slice_impl(input: &str) -> String {
        let mut hash_map = parse_map(input);
        let encoding = get_encoding(&mut hash_map);
        check_present(&mut hash_map, "input");
        let input = get_string(&mut hash_map, "input");
        check_empty(hash_map);
        format!("{:?}", encoding.decode(input.as_bytes()).unwrap())
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;
use std::collections::BTreeMap;
use std::io;
use std::ascii::AsciiExt;

fn main() {
    let re = regex!(r"[^a-z']+");
    let mut counts = BTreeMap::new();
    for line in io::stdin().lock().lines() {
        let raw_word = line.unwrap().to_ascii_lower();
        for word in re.split(&*raw_word) {
            if word.len() > 0 {
                let num_items = match counts.get(word) {
                    Some(x) => *x,
                    None    => 0i
                };
                counts.insert(String::from_str(word), num_items + 1);
            }
        }
    }
    for (key, value) in counts.iter() {
        println!("{} {}", key, value);
    }
}
<commit_msg>Update wordcount.rs to work with current Rust version<commit_after>use std::collections::BTreeMap;
use std::io;
use std::io::BufRead;

fn main() {
    let mut counts: BTreeMap<String, isize> = BTreeMap::new();
    let stdin = io::stdin();
    for line_result in stdin.lock().lines() {
        if let Ok(line) = line_result {
            let lowercase_line = line.to_lowercase();
            let words = lowercase_line.split(|c: char| {
                 !(c.is_alphabetic() || c == '\'')
             });
             for word in words {
                 if word.len() > 0 {
                     *counts.entry(word.to_string()).or_insert(0) += 1;
                 }
             }
        } else {
            panic!("Error parsing stdin");
        }
    }
    for (key, value) in counts.iter() {
        println!("{} {}", key, value);
    }
}
<|endoftext|>


<commit_before><commit_msg>Improve parser to recognize struct expression.<commit_after><|endoftext|>


<commit_before>mod Worksheet;
// Basic excel

struct Basic_Excel {
    pub file_: Compound_File,                  // Compound file handler.
    pub workbook_: Workbook,                   // Raw Workbook.
    pub worksheets_: Vec<Worksheet::Worksheet>,// Raw Worksheets.
    pub yesheets_: Vec<Basic_Excel_Worksheet>, // Parsed Worksheets.
}

impl Basic_Excel {

    pub fn new() -> Basic_Excel {
        return Basic_Excel{file_: Compound_File, workbook_: Workbook, worksheets_: vec![Worksheet::Worksheet], yesheets_: vec![Basic_Excel_Worksheet::new()]};
    }

    // File functions
    pub fn new_with_sheets(sheets: i32) {
        unimplemented!();
    }

    pub fn load<T>(filename: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn save() -> bool {
        let mut result = false;

        return result;
    }

    pub fn save_as<T>(filename: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn close() {
        unimplemented!();
    }

    // Worksheet functions
    pub fn get_total_worksheets() -> i32 {
        let mut result = 0;

        return result;
    }

    pub fn get_worksheet<T>(sheet_index: T) -> Basic_Excel_Worksheet {
        let mut result = Basic_Excel_Worksheet::new();

        return result;
    }

    pub fn add_worksheet<T>(sheet_index: T) -> Basic_Excel_Worksheet {
        let mut result = Basic_Excel_Worksheet::new();

        return result;
    }

    pub fn delete_worksheet<T>(sheet_index: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn get_ansi_sheet_name(sheet_index: i32) {
        panic!("Rust operates completely in UTF-8 Unicode strings and as such there's no reason return an ANSI version.");
    }

    pub fn get_unicode_sheet_name(sheet_index: i32) -> String {
        let mut result = String::new();

        return result;
    }

    pub fn get_sheet_name(sheet_index: i32) -> (bool, String) {
        let mut result = false;
        let mut name = String::new();

        return (result, name);
    }

    pub fn rename_worksheet_from_index(sheet_index: i32, to: &str) -> bool {
        let mut result = false;

        return result;
    }

    pub fn rename_worksheet_from_str(from: &str, to: &str) -> bool {
        let mut result = false;

        return result;
    }

}

struct Basic_Excel_Worksheet {
    pub excel_: Basic_Excel,
    pub sheet_index_: i32,
    pub max_rows_: i32,
    pub max_cols_: i32,
    pub cells_: Vec<Basic_Excel_Cell>,
    pub col_infos_: Worksheet::Col_Infos,
}

impl Basic_Excel_Worksheet {
    // Worksheet functions
    pub fn new() -> Basic_Excel_Worksheet {
        return Basic_Excel_Worksheet{excel_: Basic_Excel::new(), sheet_index_: 0, max_rows_: 0, max_cols_: 0, cells_: vec![Basic_Excel_Cell], col_infos_: Worksheet::Col_Infos};
    }

    pub fn get_sheet_name() -> (bool, String) {
        unimplemented!();
    }

    pub fn rename(to: &str) -> bool {
        unimplemented!();
    }

    pub fn print() {
        unimplemented!();
    }

    // Cell functions
    pub fn get_total_rows() -> i32 {
        unimplemented!();
    }

    pub fn get_total_cols() -> i32 {
        unimplemented!();
    }

    pub fn cell(row: i32, col: i32) -> *mut Basic_Excel_Cell {
        unimplemented!();
    }

    pub fn erase_cell(row: i32, col: i32) -> bool {
        unimplemented!();
    }

    pub fn set_col_width(col_index: i32, col_width: u16) {
        unimplemented!();
    }

    pub fn get_col_width(col_index: i32) -> u16 {
        unimplemented!();
    }

    pub fn merge_cells(row: i32, col: i32, row_range: u16, col_range: u16) {
        unimplemented!();
    }

    // Private
    fn update_cells() {
        unimplemented!();
    }
}

struct Compound_File;

struct Workbook;

struct Basic_Excel_Cell;

<commit_msg>Skeleton for Basic_Excel_Cell<commit_after>mod Worksheet;
// Basic excel

struct Basic_Excel {
    pub file_: Compound_File,                  // Compound file handler.
    pub workbook_: Workbook,                   // Raw Workbook.
    pub worksheets_: Vec<Worksheet::Worksheet>,// Raw Worksheets.
    pub yesheets_: Vec<Basic_Excel_Worksheet>, // Parsed Worksheets.
}

impl Basic_Excel {

    pub fn new() -> Basic_Excel {
        return Basic_Excel{file_: Compound_File, workbook_: Workbook, worksheets_: vec![Worksheet::Worksheet], yesheets_: vec![Basic_Excel_Worksheet::new()]};
    }

    // File functions
    pub fn new_with_sheets(sheets: i32) {
        unimplemented!();
    }

    pub fn load<T>(filename: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn save() -> bool {
        let mut result = false;

        return result;
    }

    pub fn save_as<T>(filename: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn close() {
        unimplemented!();
    }

    // Worksheet functions
    pub fn get_total_worksheets() -> i32 {
        let mut result = 0;

        return result;
    }

    pub fn get_worksheet<T>(sheet_index: T) -> Basic_Excel_Worksheet {
        let mut result = Basic_Excel_Worksheet::new();

        return result;
    }

    pub fn add_worksheet<T>(sheet_index: T) -> Basic_Excel_Worksheet {
        let mut result = Basic_Excel_Worksheet::new();

        return result;
    }

    pub fn delete_worksheet<T>(sheet_index: T) -> bool {
        let mut result = false;

        return result;
    }

    pub fn get_ansi_sheet_name(sheet_index: i32) {
        panic!("Rust operates completely in UTF-8 Unicode strings and as such there's no reason return an ANSI version.");
    }

    pub fn get_unicode_sheet_name(sheet_index: i32) -> String {
        let mut result = String::new();

        return result;
    }

    pub fn get_sheet_name(sheet_index: i32) -> (bool, String) {
        let mut result = false;
        let mut name = String::new();

        return (result, name);
    }

    pub fn rename_worksheet_from_index(sheet_index: i32, to: &str) -> bool {
        let mut result = false;

        return result;
    }

    pub fn rename_worksheet_from_str(from: &str, to: &str) -> bool {
        let mut result = false;

        return result;
    }

}

struct Basic_Excel_Worksheet {
    excel_: Basic_Excel,
    sheet_index_: i32,
    max_rows_: i32,
    max_cols_: i32,
    cells_: Vec<Basic_Excel_Cell>,
    col_infos_: Worksheet::Col_Infos,
}

impl Basic_Excel_Worksheet {
    // Worksheet functions
    pub fn new() -> Basic_Excel_Worksheet {
        return Basic_Excel_Worksheet{excel_: Basic_Excel::new(), sheet_index_: 0, max_rows_: 0, max_cols_: 0, cells_: vec![Basic_Excel_Cell::new()], col_infos_: Worksheet::Col_Infos};
    }

    pub fn get_sheet_name() -> (bool, String) {
        unimplemented!();
    }

    pub fn rename(to: &str) -> bool {
        unimplemented!();
    }

    pub fn print() {
        unimplemented!();
    }

    // Cell functions
    pub fn get_total_rows() -> i32 {
        unimplemented!();
    }

    pub fn get_total_cols() -> i32 {
        unimplemented!();
    }

    pub fn cell(row: i32, col: i32) -> *mut Basic_Excel_Cell {
        unimplemented!();
    }

    pub fn erase_cell(row: i32, col: i32) -> bool {
        unimplemented!();
    }

    pub fn set_col_width(col_index: i32, col_width: u16) {
        unimplemented!();
    }

    pub fn get_col_width(col_index: i32) -> u16 {
        unimplemented!();
    }

    pub fn merge_cells(row: i32, col: i32, row_range: u16, col_range: u16) {
        unimplemented!();
    }

    // Private
    fn update_cells() {
        unimplemented!();
    }
}

struct Compound_File;

struct Workbook;

struct Basic_Excel_Cell {
    type_: i32,
    ival_: i32,
    fval_: f32,
    str_: String,

    merged_rows_: u16,
    merged_cols_: u16,

    _xf_idx: i32,
}

impl Basic_Excel_Cell {
    pub fn new() -> Basic_Excel_Cell {
        return Basic_Excel_Cell{type_: 0, ival_: 0, fval_: 0 as f32, str_: "".to_string(), merged_rows_: 0, merged_cols_: 0, _xf_idx: 0};
    }

    pub fn get_type() -> i32 {
        unimplemented!();
    }

    pub fn get() -> (bool, f32) { // We don't need a separate return for ints in rust, since you can easily type-cast it (E.G. let (x, z as i32) = get())
        unimplemented!();
    }

    pub fn get_string_length() -> usize { // Length of string contents
        unimplemented!();
    }

    pub fn get_integer() -> i32 {
        unimplemented!();
    }

    pub fn get_float() -> f32 {
        unimplemented!();
    }

    pub fn get_string() -> String {
        unimplemented!();
    }

    pub fn set<T>(val: T) {
        unimplemented!();
    }

    pub fn set_formula() {
        unimplemented!();
    }

    pub fn get_xformat_index(&self) -> i32 {
        return self._xf_idx;
    }

    pub fn set_xformat_index(&mut self, xf_idx: i32) {
        self._xf_idx = xf_idx;
    }

    pub fn set_format() {
        unimplemented!();
    }

    pub fn EraseContents() {
        unimplemented!();
    }

    pub fn get_merged_rows(&self) -> u16 {
        return self.merged_rows_;
    }

    pub fn get_merged_cols(&self) -> u16 {
        return self.merged_cols_;
    }

    pub fn set_merged_rows(&mut self, merged_rows: u16) {
        self.merged_rows_ = merged_rows;
    }

    pub fn set_merged_cols(&mut self, merged_cols: u16) {
        self.merged_cols_ = merged_cols;
    }
}
<|endoftext|>


<commit_before>//! Project changelog

/// Release 0.4.2 (2017-09-24)
///
/// * Improved error and race-condition handling on Windows;
/// * Improved documentation about thread-safety of Library;
/// * Added Symbol::<Option<T>::lift_option() -> Option<Symbol<T>> convenience method.
pub mod r0_4_1 {}

/// Release 0.4.1 (2017-08-29)
///
/// * Solaris support
pub mod r0_4_1 {}

/// Release 0.4.0 (2017-05-01)
///
/// * Remove build-time dependency on target_build_utils (and by extension serde/phf);
/// * Require at least version 1.14.0 of rustc to build;
///   * Actually, it is cargo which has to be more recent here. The one shipped with rustc 1.14.0
///     is what’s being required from now on.
pub mod r0_4_0 {}

/// Release 0.3.4 (2017-03-25)
///
/// * Remove rogue println!
pub mod r0_3_4 {}

/// Release 0.3.3 (2017-03-25)
///
/// * Panics when `Library::get` is called for incompatibly sized type such as named function
///   types (which are zero-sized).
pub mod r0_3_3 {}

/// Release 0.3.2 (2017-02-10)
///
/// * Minimum version required is now rustc 1.12.0;
/// * Updated dependency versions (most notably target_build_utils to 0.3.0)
pub mod r0_3_2 {}

/// Release 0.3.1 (2016-10-01)
///
/// * `Symbol<T>` and `os::*::Symbol<T>` now implement `Send` where `T: Send`;
/// * `Symbol<T>` and `os::*::Symbol<T>` now implement `Sync` where `T: Sync`;
/// * `Library` and `os::*::Library` now implement `Sync` (they were `Send` in 0.3.0 already).
pub mod r0_3_1 {}

/// Release 0.3.0 (2016-07-27)
///
/// * Greatly improved documentation, especially around platform-specific behaviours;
/// * Improved test suite by building our own library to test against;
/// * All `Library`-ies now implement `Send`.
/// * Added `impl From<os::platform::Library> for Library` and `impl From<Library> for
/// os::platform::Library` allowing wrapping and extracting the platform-specific library handle;
/// * Added methods to wrap (`Symbol::from_raw`) and unwrap (`Symbol::into_raw`) the safe `Symbol`
/// wrapper into unsafe `os::platform::Symbol`.
///
/// The last two additions focus on not restricting potential usecases of this library, allowing
/// users of the library to circumvent safety checks if need be.
///
/// ## Beaking Changes
///
/// `Library::new` defaults to `RTLD_NOW` instead of `RTLD_LAZY` on UNIX for more consistent
/// cross-platform behaviour. If a library loaded with `Library::new` had any linking errors, but
/// unresolved references weren’t forced to be resolved, the library would’ve “just worked”,
/// whereas now the call to `Library::new` will return an error signifying presence of such error.
///
/// ## os::platform
/// * Added `os::unix::Library::open` which allows specifying arbitrary flags (e.g. `RTLD_LAZY`);
/// * Added `os::windows::Library::get_ordinal` which allows finding a function or variable by its
/// ordinal number;
pub mod r0_3_0 {}
<commit_msg>Fix stupid mistake in changelog<commit_after>//! Project changelog

/// Release 0.4.2 (2017-09-24)
///
/// * Improved error and race-condition handling on Windows;
/// * Improved documentation about thread-safety of Library;
/// * Added Symbol::<Option<T>::lift_option() -> Option<Symbol<T>> convenience method.
pub mod r0_4_2 {}

/// Release 0.4.1 (2017-08-29)
///
/// * Solaris support
pub mod r0_4_1 {}

/// Release 0.4.0 (2017-05-01)
///
/// * Remove build-time dependency on target_build_utils (and by extension serde/phf);
/// * Require at least version 1.14.0 of rustc to build;
///   * Actually, it is cargo which has to be more recent here. The one shipped with rustc 1.14.0
///     is what’s being required from now on.
pub mod r0_4_0 {}

/// Release 0.3.4 (2017-03-25)
///
/// * Remove rogue println!
pub mod r0_3_4 {}

/// Release 0.3.3 (2017-03-25)
///
/// * Panics when `Library::get` is called for incompatibly sized type such as named function
///   types (which are zero-sized).
pub mod r0_3_3 {}

/// Release 0.3.2 (2017-02-10)
///
/// * Minimum version required is now rustc 1.12.0;
/// * Updated dependency versions (most notably target_build_utils to 0.3.0)
pub mod r0_3_2 {}

/// Release 0.3.1 (2016-10-01)
///
/// * `Symbol<T>` and `os::*::Symbol<T>` now implement `Send` where `T: Send`;
/// * `Symbol<T>` and `os::*::Symbol<T>` now implement `Sync` where `T: Sync`;
/// * `Library` and `os::*::Library` now implement `Sync` (they were `Send` in 0.3.0 already).
pub mod r0_3_1 {}

/// Release 0.3.0 (2016-07-27)
///
/// * Greatly improved documentation, especially around platform-specific behaviours;
/// * Improved test suite by building our own library to test against;
/// * All `Library`-ies now implement `Send`.
/// * Added `impl From<os::platform::Library> for Library` and `impl From<Library> for
/// os::platform::Library` allowing wrapping and extracting the platform-specific library handle;
/// * Added methods to wrap (`Symbol::from_raw`) and unwrap (`Symbol::into_raw`) the safe `Symbol`
/// wrapper into unsafe `os::platform::Symbol`.
///
/// The last two additions focus on not restricting potential usecases of this library, allowing
/// users of the library to circumvent safety checks if need be.
///
/// ## Beaking Changes
///
/// `Library::new` defaults to `RTLD_NOW` instead of `RTLD_LAZY` on UNIX for more consistent
/// cross-platform behaviour. If a library loaded with `Library::new` had any linking errors, but
/// unresolved references weren’t forced to be resolved, the library would’ve “just worked”,
/// whereas now the call to `Library::new` will return an error signifying presence of such error.
///
/// ## os::platform
/// * Added `os::unix::Library::open` which allows specifying arbitrary flags (e.g. `RTLD_LAZY`);
/// * Added `os::windows::Library::get_ordinal` which allows finding a function or variable by its
/// ordinal number;
pub mod r0_3_0 {}
<|endoftext|>


<commit_before>generate_error_module!(
    generate_error_types!(LinkError, LinkErrorKind,
        EntryHeaderReadError    => "Error while reading an entry header",
        EntryHeaderWriteError   => "Error while writing an entry header",
        ExistingLinkTypeWrong   => "Existing link entry has wrong type",
        LinkTargetDoesNotExist  => "Link target does not exist in the store",
        InternalConversionError => "Error while converting values internally",
        InvalidUri              => "URI is not valid",
        StoreReadError          => "Store read error",
        StoreWriteError         => "Store write error"
    );
);

pub use self::error::LinkError;
pub use self::error::LinkErrorKind;

<commit_msg>Export MapErrInto trait<commit_after>generate_error_module!(
    generate_error_types!(LinkError, LinkErrorKind,
        EntryHeaderReadError    => "Error while reading an entry header",
        EntryHeaderWriteError   => "Error while writing an entry header",
        ExistingLinkTypeWrong   => "Existing link entry has wrong type",
        LinkTargetDoesNotExist  => "Link target does not exist in the store",
        InternalConversionError => "Error while converting values internally",
        InvalidUri              => "URI is not valid",
        StoreReadError          => "Store read error",
        StoreWriteError         => "Store write error"
    );
);

pub use self::error::LinkError;
pub use self::error::LinkErrorKind;
pub use self::error::MapErrInto;

<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#[macro_export]
macro_rules! generate_error_imports {
    () => {
        use std::error::Error;
        use std::fmt::Error as FmtError;
        use std::fmt::{Display, Formatter};

        use $crate::into::IntoError;
    }
}

#[macro_export]
macro_rules! generate_error_module {
    ( $exprs:item ) => {
        pub mod error {
            generate_error_imports!();
            $exprs
        }
    }
}

#[macro_export]
macro_rules! generate_custom_error_types {
    {
        $name: ident,
        $kindname: ident,
        $customMemberTypeName: ident,
        $($kind:ident => $string:expr),*
    } => {
        #[derive(Clone, Copy, Debug, PartialEq)]
        pub enum $kindname {
            $( $kind ),*
        }

        impl Display for $kindname {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                let s = match *self {
                    $( $kindname::$kind => $string ),*
                };
                try!(write!(fmt, "{}", s));
                Ok(())
            }

        }

        impl IntoError for $kindname {
            type Target = $name;

            fn into_error(self) -> Self::Target {
                $name::new(self, None)
            }

            fn into_error_with_cause(self, cause: Box<Error>) -> Self::Target {
                $name::new(self, Some(cause))
            }

        }

        #[derive(Debug)]
        pub struct $name {
            err_type: $kindname,
            cause: Option<Box<Error>>,
            custom_data: Option<$customMemberTypeName>,
        }

        impl $name {

            pub fn new(errtype: $kindname, cause: Option<Box<Error>>) -> $name {
                $name {
                    err_type: errtype,
                    cause: cause,
                    custom_data: None,
                }
            }

            #[allow(dead_code)]
            pub fn err_type(&self) -> $kindname {
                self.err_type
            }

            #[allow(dead_code)]
            pub fn with_custom_data(mut self, custom: $customMemberTypeName) -> $name {
                self.custom_data = Some(custom);
                self
            }

        }

        impl Into<$name> for $kindname {

            fn into(self) -> $name {
                $name::new(self, None)
            }

        }

        impl Display for $name {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                try!(write!(fmt, "[{}]", self.err_type));
                Ok(())
            }

        }

        impl Error for $name {

            fn description(&self) -> &str {
                match self.err_type {
                    $( $kindname::$kind => $string ),*
                }
            }

            fn cause(&self) -> Option<&Error> {
                self.cause.as_ref().map(|e| &**e)
            }

        }

    }
}

#[macro_export]
macro_rules! generate_result_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.map_err(Box::new).map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(e))
        /// // or:
        /// foo.map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(Box::new(e)))
        /// ```
        ///
        /// with much nicer
        ///
        /// ```ignore
        /// foo.map_err_into(SomeType::SomeErrorKind)
        /// ```
        ///
        pub trait MapErrInto<T> {
            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name>;
        }

        impl<T, E: Error + 'static> MapErrInto<T> for Result<T, E> {

            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name> {
                self.map_err(Box::new)
                    .map_err(|e| error_kind.into_error_with_cause(e))
            }

        }
    }
}

#[macro_export]
macro_rules! generate_option_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.ok_or(SomeType::SomeErrorKind.into_error())
        /// ```
        ///
        /// with
        ///
        /// ```ignore
        /// foo.ok_or_errkind(SomeType::SomeErrorKind)
        /// ```
        pub trait OkOrErr<T> {
            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name>;
        }

        impl<T> OkOrErr<T> for Option<T> {

            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name> {
                self.ok_or(kind.into_error())
            }

        }
    }
}

#[macro_export]
macro_rules! generate_error_types {
    (
        $name: ident,
        $kindname: ident,
        $($kind:ident => $string:expr),*
    ) => {
        #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
        pub struct SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {}
        generate_custom_error_types!($name, $kindname,
                                     SomeNotExistingTypeWithATypeNameNoOneWillEverChoose,
                                     $($kind => $string),*);

        generate_result_helper!($name, $kindname);
        generate_option_helper!($name, $kindname);
    }
}

#[cfg(test)]
mod test {

    generate_error_module!(
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    );

    #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
    pub struct CustomData {
        pub test: i32,
        pub othr: i64,
    }

    generate_error_imports!();

    #[allow(dead_code)]
    generate_custom_error_types!(CustomTestError, CustomTestErrorKind,
        CustomData,
        CustomErrorKindA => "customerrorkind a",
        CustomErrorKindB => "customerrorkind B");

    // Allow dead code here.
    // We wrote this to show that custom test types can be implemented.
    #[allow(dead_code)]
    impl CustomTestError {
        pub fn test(&self) -> i32 {
            match self.custom_data {
                Some(t) => t.test,
                None => 0,
            }
        }

        pub fn bar(&self) -> i64 {
            match self.custom_data {
                Some(t) => t.othr,
                None => 0,
            }
        }
    }

    #[test]
    fn test_a() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_b() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_ab() {
        use std::error::Error;
        use self::error::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    pub mod anothererrormod {
        generate_error_imports!();
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    }

    #[test]
    fn test_other_a() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_other_b() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_other_ab() {
        use std::error::Error;
        use self::anothererrormod::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    #[test]
    fn test_error_kind_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA);

        assert!(err.is_err());
        let err = err.unwrap_err();

        match err.err_type() {
            TestErrorKind::TestErrorKindA => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn test_error_kind_double_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA)
                                     .map_err_into(TestErrorKind::TestErrorKindB);

        assert!(err.is_err());
        let err = err.unwrap_err();
        match err.err_type() {
            TestErrorKind::TestErrorKindB => assert!(true),
            _ => assert!(false),
        }

        // not sure how to test that the inner error is of TestErrorKindA, actually...
        match err.cause() {
            Some(_) => assert!(true),
            None    => assert!(false),
        }

    }

    #[test]
    fn test_error_option_good() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something = Some(1);
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(1) => assert!(true),
            _     => assert!(false),
        }
    }

    #[test]
    fn test_error_option_bad() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something : Option<i32> = None;
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(_)  => assert!(false),
            Err(e) => assert!(true),
        }
    }

}
<commit_msg>Remove unused variable<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

#[macro_export]
macro_rules! generate_error_imports {
    () => {
        use std::error::Error;
        use std::fmt::Error as FmtError;
        use std::fmt::{Display, Formatter};

        use $crate::into::IntoError;
    }
}

#[macro_export]
macro_rules! generate_error_module {
    ( $exprs:item ) => {
        pub mod error {
            generate_error_imports!();
            $exprs
        }
    }
}

#[macro_export]
macro_rules! generate_custom_error_types {
    {
        $name: ident,
        $kindname: ident,
        $customMemberTypeName: ident,
        $($kind:ident => $string:expr),*
    } => {
        #[derive(Clone, Copy, Debug, PartialEq)]
        pub enum $kindname {
            $( $kind ),*
        }

        impl Display for $kindname {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                let s = match *self {
                    $( $kindname::$kind => $string ),*
                };
                try!(write!(fmt, "{}", s));
                Ok(())
            }

        }

        impl IntoError for $kindname {
            type Target = $name;

            fn into_error(self) -> Self::Target {
                $name::new(self, None)
            }

            fn into_error_with_cause(self, cause: Box<Error>) -> Self::Target {
                $name::new(self, Some(cause))
            }

        }

        #[derive(Debug)]
        pub struct $name {
            err_type: $kindname,
            cause: Option<Box<Error>>,
            custom_data: Option<$customMemberTypeName>,
        }

        impl $name {

            pub fn new(errtype: $kindname, cause: Option<Box<Error>>) -> $name {
                $name {
                    err_type: errtype,
                    cause: cause,
                    custom_data: None,
                }
            }

            #[allow(dead_code)]
            pub fn err_type(&self) -> $kindname {
                self.err_type
            }

            #[allow(dead_code)]
            pub fn with_custom_data(mut self, custom: $customMemberTypeName) -> $name {
                self.custom_data = Some(custom);
                self
            }

        }

        impl Into<$name> for $kindname {

            fn into(self) -> $name {
                $name::new(self, None)
            }

        }

        impl Display for $name {

            fn fmt(&self, fmt: &mut Formatter) -> Result<(), FmtError> {
                try!(write!(fmt, "[{}]", self.err_type));
                Ok(())
            }

        }

        impl Error for $name {

            fn description(&self) -> &str {
                match self.err_type {
                    $( $kindname::$kind => $string ),*
                }
            }

            fn cause(&self) -> Option<&Error> {
                self.cause.as_ref().map(|e| &**e)
            }

        }

    }
}

#[macro_export]
macro_rules! generate_result_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.map_err(Box::new).map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(e))
        /// // or:
        /// foo.map_err(|e| SomeType::SomeErrorKind.into_error_with_cause(Box::new(e)))
        /// ```
        ///
        /// with much nicer
        ///
        /// ```ignore
        /// foo.map_err_into(SomeType::SomeErrorKind)
        /// ```
        ///
        pub trait MapErrInto<T> {
            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name>;
        }

        impl<T, E: Error + 'static> MapErrInto<T> for Result<T, E> {

            fn map_err_into(self, error_kind: $kindname) -> Result<T, $name> {
                self.map_err(Box::new)
                    .map_err(|e| error_kind.into_error_with_cause(e))
            }

        }
    }
}

#[macro_export]
macro_rules! generate_option_helper {
    (
        $name: ident,
        $kindname: ident
    ) => {
        /// Trait to replace
        ///
        /// ```ignore
        /// foo.ok_or(SomeType::SomeErrorKind.into_error())
        /// ```
        ///
        /// with
        ///
        /// ```ignore
        /// foo.ok_or_errkind(SomeType::SomeErrorKind)
        /// ```
        pub trait OkOrErr<T> {
            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name>;
        }

        impl<T> OkOrErr<T> for Option<T> {

            fn ok_or_errkind(self, kind: $kindname) -> Result<T, $name> {
                self.ok_or(kind.into_error())
            }

        }
    }
}

#[macro_export]
macro_rules! generate_error_types {
    (
        $name: ident,
        $kindname: ident,
        $($kind:ident => $string:expr),*
    ) => {
        #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
        pub struct SomeNotExistingTypeWithATypeNameNoOneWillEverChoose {}
        generate_custom_error_types!($name, $kindname,
                                     SomeNotExistingTypeWithATypeNameNoOneWillEverChoose,
                                     $($kind => $string),*);

        generate_result_helper!($name, $kindname);
        generate_option_helper!($name, $kindname);
    }
}

#[cfg(test)]
mod test {

    generate_error_module!(
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    );

    #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Copy)]
    pub struct CustomData {
        pub test: i32,
        pub othr: i64,
    }

    generate_error_imports!();

    #[allow(dead_code)]
    generate_custom_error_types!(CustomTestError, CustomTestErrorKind,
        CustomData,
        CustomErrorKindA => "customerrorkind a",
        CustomErrorKindB => "customerrorkind B");

    // Allow dead code here.
    // We wrote this to show that custom test types can be implemented.
    #[allow(dead_code)]
    impl CustomTestError {
        pub fn test(&self) -> i32 {
            match self.custom_data {
                Some(t) => t.test,
                None => 0,
            }
        }

        pub fn bar(&self) -> i64 {
            match self.custom_data {
                Some(t) => t.othr,
                None => 0,
            }
        }
    }

    #[test]
    fn test_a() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_b() {
        use self::error::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_ab() {
        use std::error::Error;
        use self::error::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    pub mod anothererrormod {
        generate_error_imports!();
        generate_error_types!(TestError, TestErrorKind,
            TestErrorKindA => "testerrorkind a",
            TestErrorKindB => "testerrorkind B");
    }

    #[test]
    fn test_other_a() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindA;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
    }

    #[test]
    fn test_other_b() {
        use self::anothererrormod::{TestError, TestErrorKind};

        let kind = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind B"), format!("{}", kind));

        let e = TestError::new(kind, None);
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e));

    }

    #[test]
    fn test_other_ab() {
        use std::error::Error;
        use self::anothererrormod::{TestError, TestErrorKind};

        let kinda = TestErrorKind::TestErrorKindA;
        let kindb = TestErrorKind::TestErrorKindB;
        assert_eq!(String::from("testerrorkind a"), format!("{}", kinda));
        assert_eq!(String::from("testerrorkind B"), format!("{}", kindb));

        let e = TestError::new(kinda, Some(Box::new(TestError::new(kindb, None))));
        assert_eq!(String::from("[testerrorkind a]"), format!("{}", e));
        assert_eq!(TestErrorKind::TestErrorKindA, e.err_type());
        assert_eq!(String::from("[testerrorkind B]"), format!("{}", e.cause().unwrap()));
    }

    #[test]
    fn test_error_kind_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA);

        assert!(err.is_err());
        let err = err.unwrap_err();

        match err.err_type() {
            TestErrorKind::TestErrorKindA => assert!(true),
            _ => assert!(false),
        }
    }

    #[test]
    fn test_error_kind_double_mapping() {
        use std::io::{Error, ErrorKind};
        use self::error::MapErrInto;
        use self::error::TestErrorKind;

        let err : Result<(), _> = Err(Error::new(ErrorKind::Other, ""));
        let err : Result<(), _> = err.map_err_into(TestErrorKind::TestErrorKindA)
                                     .map_err_into(TestErrorKind::TestErrorKindB);

        assert!(err.is_err());
        let err = err.unwrap_err();
        match err.err_type() {
            TestErrorKind::TestErrorKindB => assert!(true),
            _ => assert!(false),
        }

        // not sure how to test that the inner error is of TestErrorKindA, actually...
        match err.cause() {
            Some(_) => assert!(true),
            None    => assert!(false),
        }

    }

    #[test]
    fn test_error_option_good() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something = Some(1);
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(1) => assert!(true),
            _     => assert!(false),
        }
    }

    #[test]
    fn test_error_option_bad() {
        use self::error::OkOrErr;
        use self::error::TestErrorKind;

        let something : Option<i32> = None;
        match something.ok_or_errkind(TestErrorKind::TestErrorKindA) {
            Ok(_)  => assert!(false),
            Err(_) => assert!(true),
        }
    }

}
<|endoftext|>


<commit_before>#![feature(box_syntax)]
extern crate e2d2;
extern crate fnv;
extern crate time;
extern crate simd;
extern crate getopts;
extern crate rand;
use e2d2::interface::*;
use e2d2::interface::dpdk::*;
use e2d2::operators::*;
use e2d2::scheduler::*;
use getopts::Options;
use std::collections::HashMap;
use std::env;
use std::time::Duration;
use std::thread;
use std::sync::Arc;
use self::nf::*;
mod nf;

const CONVERSION_FACTOR: f64 = 1000000000.;

fn recv_thread(ports: Vec<PortQueue>, core: i32) {
    init_thread(core, core);
    println!("Receiving started");
    for port in &ports {
        println!("Receiving port {} rxq {} txq {} on core {}",
                 port.port.mac_address(),
                 port.rxq(),
                 port.txq(),
                 core);
    }

    let pipelines: Vec<_> = ports.iter()
                                 .map(|port| tcp_nf(ReceiveBatch::new(port.clone())).send(port.clone()))
                                 .collect();
    println!("Running {} pipelines", pipelines.len());
    let mut sched = Scheduler::new();
    for pipeline in pipelines {
        sched.add_task(pipeline);
    }
    sched.execute_one();
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("", "secondary", "run as a secondary process");
    opts.optopt("n", "name", "name to use for the current process", "name");
    opts.optmulti("p", "port", "Port to use", "[type:]id");
    opts.optmulti("c", "core", "Core to use", "core");
    opts.optopt("m", "master", "Master core", "master");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    if matches.opt_present("h") {
        print!("{}", opts.usage(&format!("Usage: {} [options]", program)));
    }

    let cores_str = matches.opt_strs("c");
    let master_core = matches.opt_str("m")
                             .unwrap_or_else(|| String::from("0"))
                             .parse()
                             .expect("Could not parse master core spec");
    println!("Using master core {}", master_core);
    let name = matches.opt_str("n").unwrap_or_else(|| String::from("recv"));

    let cores: Vec<i32> = cores_str.iter()
                                   .map(|n: &String| n.parse().ok().expect(&format!("Core cannot be parsed {}", n)))
                                   .collect();

    fn extract_cores_for_port(ports: &[String], cores: &[i32]) -> HashMap<String, Vec<i32>> {
        let mut cores_for_port = HashMap::<String, Vec<i32>>::new();
        for (port, core) in ports.iter().zip(cores.iter()) {
            cores_for_port.entry(port.clone()).or_insert(vec![]).push(*core)
        }
        cores_for_port
    }

    let primary = !matches.opt_present("secondary");

    let cores_for_port = extract_cores_for_port(&matches.opt_strs("p"), &cores);

    if primary {
        init_system_wl(&name, master_core, &[]);
    } else {
        init_system_secondary(&name, master_core);
    }

    let ports_to_activate: Vec<_> = cores_for_port.keys().collect();

    let mut queues_by_core = HashMap::<i32, Vec<_>>::with_capacity(cores.len());
    let mut ports = Vec::<Arc<PmdPort>>::with_capacity(ports_to_activate.len());
    for port in &ports_to_activate {
        let cores = cores_for_port.get(*port).unwrap();
        let queues = cores.len() as i32;
        let pmd_port = PmdPort::new_with_queues(*port, queues, queues, cores, cores)
                           .expect("Could not initialize port");
        for (idx, core) in cores.iter().enumerate() {
            let queue = idx as i32;
            queues_by_core.entry(*core)
                          .or_insert(vec![])
                          .push(PmdPort::new_queue_pair(&pmd_port, queue, queue).unwrap());
        }
        ports.push(pmd_port);
    }

    const _BATCH: usize = 1 << 10;
    const _CHANNEL_SIZE: usize = 256;
    let mut threads: Vec<_> = queues_by_core.iter()
                                        .map(|(core, ports)| {
                                            let c = core.clone();
                                            let p: Vec<_> = ports.iter().map(|p| p.clone()).collect();
                                            std::thread::spawn(move || recv_thread(p, c))
                                        })
                                        .collect();
    while !threads.is_empty() {
        let thr = threads.pop().unwrap();
        let _ = thr.join().unwrap();
    }
    //let mut pkts_so_far = (0, 0);
    //let mut last_printed = 0.;
    //const MAX_PRINT_INTERVAL: f64 = 1.0;
    //const PRINT_DELAY: f64 = 0.5;
    //let sleep_delay = (PRINT_DELAY / 2.) as u64;
    //let mut start = time::precise_time_ns() as f64 / CONVERSION_FACTOR;
    //let sleep_time = Duration::from_millis(sleep_delay);
    //println!("0 OVERALL RX 0.00 TX 0.00 CYCLE_PER_DELAY 0 0 0");
    //loop {
        //thread::sleep(sleep_time); // Sleep for a bit
        //let now = time::precise_time_ns() as f64 / CONVERSION_FACTOR;
        //if now - start > PRINT_DELAY {
            //let mut rx = 0;
            //let mut tx = 0;
            //for port in &ports {
                //for q in 0..port.rxqs() {
                    //let (rp, tp) = port.stats(q);
                    //rx += rp;
                    //tx += tp;
                //}
            //}
            //let pkts = (rx, tx);
            //let rx_pkts = pkts.0 - pkts_so_far.0;
            //if rx_pkts > 0 || now - last_printed > MAX_PRINT_INTERVAL {
                //println!("{:.2} OVERALL RX {:.2} TX {:.2}",
                         //now - start,
                         //rx_pkts as f64 / (now - start),
                         //(pkts.1 - pkts_so_far.1) as f64 / (now - start));
                //last_printed = now;
                //start = now;
                //pkts_so_far = pkts;
            //}
        //}
    //}
}
<commit_msg>Remove TCP check warnings<commit_after>#![feature(box_syntax)]
extern crate e2d2;
extern crate fnv;
extern crate time;
extern crate simd;
extern crate getopts;
extern crate rand;
use e2d2::interface::*;
use e2d2::interface::dpdk::*;
use e2d2::operators::*;
use e2d2::scheduler::*;
use getopts::Options;
use std::collections::HashMap;
use std::env;
use std::sync::Arc;
use self::nf::*;
mod nf;

fn recv_thread(ports: Vec<PortQueue>, core: i32) {
    init_thread(core, core);
    println!("Receiving started");
    for port in &ports {
        println!("Receiving port {} rxq {} txq {} on core {}",
                 port.port.mac_address(),
                 port.rxq(),
                 port.txq(),
                 core);
    }

    let pipelines: Vec<_> = ports.iter()
                                 .map(|port| tcp_nf(ReceiveBatch::new(port.clone())).send(port.clone()))
                                 .collect();
    println!("Running {} pipelines", pipelines.len());
    let mut sched = Scheduler::new();
    for pipeline in pipelines {
        sched.add_task(pipeline);
    }
    sched.execute_one();
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    opts.optflag("", "secondary", "run as a secondary process");
    opts.optopt("n", "name", "name to use for the current process", "name");
    opts.optmulti("p", "port", "Port to use", "[type:]id");
    opts.optmulti("c", "core", "Core to use", "core");
    opts.optopt("m", "master", "Master core", "master");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    if matches.opt_present("h") {
        print!("{}", opts.usage(&format!("Usage: {} [options]", program)));
    }

    let cores_str = matches.opt_strs("c");
    let master_core = matches.opt_str("m")
                             .unwrap_or_else(|| String::from("0"))
                             .parse()
                             .expect("Could not parse master core spec");
    println!("Using master core {}", master_core);
    let name = matches.opt_str("n").unwrap_or_else(|| String::from("recv"));

    let cores: Vec<i32> = cores_str.iter()
                                   .map(|n: &String| n.parse().ok().expect(&format!("Core cannot be parsed {}", n)))
                                   .collect();

    fn extract_cores_for_port(ports: &[String], cores: &[i32]) -> HashMap<String, Vec<i32>> {
        let mut cores_for_port = HashMap::<String, Vec<i32>>::new();
        for (port, core) in ports.iter().zip(cores.iter()) {
            cores_for_port.entry(port.clone()).or_insert(vec![]).push(*core)
        }
        cores_for_port
    }

    let primary = !matches.opt_present("secondary");

    let cores_for_port = extract_cores_for_port(&matches.opt_strs("p"), &cores);

    if primary {
        init_system_wl(&name, master_core, &[]);
    } else {
        init_system_secondary(&name, master_core);
    }

    let ports_to_activate: Vec<_> = cores_for_port.keys().collect();

    let mut queues_by_core = HashMap::<i32, Vec<_>>::with_capacity(cores.len());
    let mut ports = Vec::<Arc<PmdPort>>::with_capacity(ports_to_activate.len());
    for port in &ports_to_activate {
        let cores = cores_for_port.get(*port).unwrap();
        let queues = cores.len() as i32;
        let pmd_port = PmdPort::new_with_queues(*port, queues, queues, cores, cores)
                           .expect("Could not initialize port");
        for (idx, core) in cores.iter().enumerate() {
            let queue = idx as i32;
            queues_by_core.entry(*core)
                          .or_insert(vec![])
                          .push(PmdPort::new_queue_pair(&pmd_port, queue, queue).unwrap());
        }
        ports.push(pmd_port);
    }

    const _BATCH: usize = 1 << 10;
    const _CHANNEL_SIZE: usize = 256;
    let mut threads: Vec<_> = queues_by_core.iter()
                                        .map(|(core, ports)| {
                                            let c = core.clone();
                                            let p: Vec<_> = ports.iter().map(|p| p.clone()).collect();
                                            std::thread::spawn(move || recv_thread(p, c))
                                        })
                                        .collect();
    while !threads.is_empty() {
        let thr = threads.pop().unwrap();
        let _ = thr.join().unwrap();
    }
    //let mut pkts_so_far = (0, 0);
    //let mut last_printed = 0.;
    //const MAX_PRINT_INTERVAL: f64 = 1.0;
    //const PRINT_DELAY: f64 = 0.5;
    //let sleep_delay = (PRINT_DELAY / 2.) as u64;
    //let mut start = time::precise_time_ns() as f64 / CONVERSION_FACTOR;
    //let sleep_time = Duration::from_millis(sleep_delay);
    //println!("0 OVERALL RX 0.00 TX 0.00 CYCLE_PER_DELAY 0 0 0");
    //loop {
        //thread::sleep(sleep_time); // Sleep for a bit
        //let now = time::precise_time_ns() as f64 / CONVERSION_FACTOR;
        //if now - start > PRINT_DELAY {
            //let mut rx = 0;
            //let mut tx = 0;
            //for port in &ports {
                //for q in 0..port.rxqs() {
                    //let (rp, tp) = port.stats(q);
                    //rx += rp;
                    //tx += tp;
                //}
            //}
            //let pkts = (rx, tx);
            //let rx_pkts = pkts.0 - pkts_so_far.0;
            //if rx_pkts > 0 || now - last_printed > MAX_PRINT_INTERVAL {
                //println!("{:.2} OVERALL RX {:.2} TX {:.2}",
                         //now - start,
                         //rx_pkts as f64 / (now - start),
                         //(pkts.1 - pkts_so_far.1) as f64 / (now - start));
                //last_printed = now;
                //start = now;
                //pkts_so_far = pkts;
            //}
        //}
    //}
}
<|endoftext|>


<commit_before>// Copyright (c) Aptos
// SPDX-License-Identifier: Apache-2.0

use aptos_aggregator::{
    aggregator_extension::{AggregatorData, AggregatorID, AggregatorState},
    delta_change_set::{DeltaOp, DeltaUpdate},
};
use aptos_types::vm_status::VMStatus;
use better_any::{Tid, TidAble};
use move_deps::{move_binary_format::errors::Location, move_table_extension::TableResolver};
use std::{
    cell::RefCell,
    collections::{btree_map, BTreeMap},
};

/// Represents a single aggregator change.
#[derive(Copy, Clone, Debug)]
pub enum AggregatorChange {
    // A value should be written to storage.
    Write(u128),
    // A delta should be merged with the value from storage.
    Merge(DeltaOp),
    // A value should be deleted from the storage.
    Delete,
}

/// Represents changes made by all aggregators during this context. This change
/// set can be converted into appropriate `WriteSet` and `DeltaChangeSet` by the
/// user, e.g. VM session.
pub struct AggregatorChangeSet {
    pub changes: BTreeMap<AggregatorID, AggregatorChange>,
}

/// Native context that can be attached to VM `NativeContextExtensions`.
///
/// Note: table resolver is reused for fine-grained storage access.
#[derive(Tid)]
pub struct NativeAggregatorContext<'a> {
    txn_hash: [u8; 32],
    pub(crate) resolver: &'a dyn TableResolver,
    pub(crate) aggregator_data: RefCell<AggregatorData>,
}

impl<'a> NativeAggregatorContext<'a> {
    /// Creates a new instance of a native aggregator context. This must be
    /// passed into VM session.
    pub fn new(txn_hash: [u8; 32], resolver: &'a dyn TableResolver) -> Self {
        Self {
            txn_hash,
            resolver,
            aggregator_data: Default::default(),
        }
    }

    /// Returns the hash of transaction associated with this context.
    pub fn txn_hash(&self) -> [u8; 32] {
        self.txn_hash
    }

    /// Returns all changes made within this context (i.e. by a single
    /// transaction).
    pub fn into_change_set(self) -> AggregatorChangeSet {
        let NativeAggregatorContext {
            aggregator_data, ..
        } = self;
        let (_, destroyed_aggregators, aggregators) = aggregator_data.into_inner().into();

        let mut changes = BTreeMap::new();

        // First, process all writes and deltas.
        for (id, aggregator) in aggregators {
            let (value, state, limit, history) = aggregator.into();

            let change = match state {
                AggregatorState::Data => AggregatorChange::Write(value),
                AggregatorState::PositiveDelta => {
                    let history = history.unwrap();
                    let plus = DeltaUpdate::Plus(value);
                    let delta_op =
                        DeltaOp::new(plus, limit, history.max_positive, history.min_negative);
                    AggregatorChange::Merge(delta_op)
                }
                AggregatorState::NegativeDelta => {
                    let history = history.unwrap();
                    let minus = DeltaUpdate::Minus(value);
                    let delta_op =
                        DeltaOp::new(minus, limit, history.max_positive, history.min_negative);
                    AggregatorChange::Merge(delta_op)
                }
            };
            changes.insert(id, change);
        }

        // Additionally, do not forget to delete destroyed values from storage.
        for id in destroyed_aggregators {
            changes.insert(id, AggregatorChange::Delete);
        }

        AggregatorChangeSet { changes }
    }
}

impl AggregatorChangeSet {
    pub fn squash(&mut self, other: Self) -> Result<(), VMStatus> {
        for (other_id, other_change) in other.changes {
            match self.changes.entry(other_id) {
                // If something was changed only in `other` session, add it.
                btree_map::Entry::Vacant(entry) => {
                    entry.insert(other_change);
                }
                // Otherwise, we might need to aggregate deltas.
                btree_map::Entry::Occupied(mut entry) => {
                    use AggregatorChange::*;

                    let entry_mut = entry.get_mut();
                    match (*entry_mut, other_change) {
                        (Write(_) | Merge(_), Write(data)) => *entry_mut = Write(data),
                        (Write(_) | Merge(_), Delete) => *entry_mut = Delete,
                        (Write(data), Merge(delta)) => {
                            let new_data = delta
                                .apply_to(data)
                                .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
                            *entry_mut = Write(new_data);
                        }
                        (Merge(delta1), Merge(mut delta2)) => {
                            // `delta1` occurred before `delta12`, therefore we must ensure we merge the latter
                            // one to the initial delta.
                            delta2
                                .merge_onto(delta1)
                                .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
                            *entry_mut = Merge(delta2)
                        }
                        // Hashing properties guarantee that aggregator keys should
                        // not collide, making this case impossible.
                        (Delete, _) => unreachable!("resource cannot be accessed after deletion"),
                    }
                }
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use aptos_aggregator::aggregator_extension::AggregatorHandle;
    use aptos_types::account_address::AccountAddress;
    use claims::assert_matches;
    use move_deps::move_table_extension::TableHandle;

    struct EmptyStorage;

    impl TableResolver for EmptyStorage {
        fn resolve_table_entry(
            &self,
            _handle: &TableHandle,
            _key: &[u8],
        ) -> Result<Option<Vec<u8>>, anyhow::Error> {
            Ok(None)
        }
    }

    fn test_id(key: u128) -> AggregatorID {
        let bytes: Vec<u8> = [key.to_le_bytes(), key.to_le_bytes()]
            .iter()
            .flat_map(|b| b.to_vec())
            .collect();
        let key = AggregatorHandle(AccountAddress::from_bytes(&bytes).unwrap());
        AggregatorID::new(TableHandle(AccountAddress::ZERO), key)
    }

    // All aggregators are initialized deterministically based on their ID,
    // with the follwing spec.
    //
    //     +-------+---------------+----------+-----+---------+
    //     |  key  | storage value |  create  | get | remove  |
    //     +-------+---------------+----------+-----+---------+
    //     |  100  |               |   yes    | yes |   yes   |
    //     |  200  |               |   yes    | yes |         |
    //     |  300  |               |   yes    |     |   yes   |
    //     |  400  |               |   yes    |     |         |
    //     |  500  |               |          | yes |   yes   |
    //     |  600  |      300      |          | yes |         |
    //     |  700  |               |          | yes |         |
    //     |  800  |               |          |     |   yes   |
    //     +-------+---------------+----------+-----+---------+
    fn test_set_up(context: &NativeAggregatorContext) {
        let mut aggregator_data = context.aggregator_data.borrow_mut();

        aggregator_data.create_new_aggregator(test_id(100), 100);
        aggregator_data.create_new_aggregator(test_id(200), 200);
        aggregator_data.create_new_aggregator(test_id(300), 300);
        aggregator_data.create_new_aggregator(test_id(400), 400);

        aggregator_data.get_aggregator(test_id(100), 100);
        aggregator_data.get_aggregator(test_id(200), 200);
        aggregator_data.get_aggregator(test_id(500), 500);
        aggregator_data.get_aggregator(test_id(600), 600);
        aggregator_data.get_aggregator(test_id(700), 700);

        aggregator_data.remove_aggregator(test_id(100));
        aggregator_data.remove_aggregator(test_id(300));
        aggregator_data.remove_aggregator(test_id(500));
        aggregator_data.remove_aggregator(test_id(800));
    }

    #[test]
    fn test_into_change_set() {
        let context = NativeAggregatorContext::new([0; 32], &EmptyStorage);
        use AggregatorChange::*;

        test_set_up(&context);
        let AggregatorChangeSet { changes } = context.into_change_set();

        assert!(!changes.contains_key(&test_id(100)));
        assert_matches!(changes.get(&test_id(200)).unwrap(), Write(0));
        assert!(!changes.contains_key(&test_id(300)));
        assert_matches!(changes.get(&test_id(400)).unwrap(), Write(0));
        assert_matches!(changes.get(&test_id(500)).unwrap(), Delete);
        assert!(changes.contains_key(&test_id(600)));
        assert!(changes.contains_key(&test_id(700)));
        assert_matches!(changes.get(&test_id(800)).unwrap(), Delete);
    }
}
<commit_msg>fixed a typo<commit_after>// Copyright (c) Aptos
// SPDX-License-Identifier: Apache-2.0

use aptos_aggregator::{
    aggregator_extension::{AggregatorData, AggregatorID, AggregatorState},
    delta_change_set::{DeltaOp, DeltaUpdate},
};
use aptos_types::vm_status::VMStatus;
use better_any::{Tid, TidAble};
use move_deps::{move_binary_format::errors::Location, move_table_extension::TableResolver};
use std::{
    cell::RefCell,
    collections::{btree_map, BTreeMap},
};

/// Represents a single aggregator change.
#[derive(Copy, Clone, Debug)]
pub enum AggregatorChange {
    // A value should be written to storage.
    Write(u128),
    // A delta should be merged with the value from storage.
    Merge(DeltaOp),
    // A value should be deleted from the storage.
    Delete,
}

/// Represents changes made by all aggregators during this context. This change
/// set can be converted into appropriate `WriteSet` and `DeltaChangeSet` by the
/// user, e.g. VM session.
pub struct AggregatorChangeSet {
    pub changes: BTreeMap<AggregatorID, AggregatorChange>,
}

/// Native context that can be attached to VM `NativeContextExtensions`.
///
/// Note: table resolver is reused for fine-grained storage access.
#[derive(Tid)]
pub struct NativeAggregatorContext<'a> {
    txn_hash: [u8; 32],
    pub(crate) resolver: &'a dyn TableResolver,
    pub(crate) aggregator_data: RefCell<AggregatorData>,
}

impl<'a> NativeAggregatorContext<'a> {
    /// Creates a new instance of a native aggregator context. This must be
    /// passed into VM session.
    pub fn new(txn_hash: [u8; 32], resolver: &'a dyn TableResolver) -> Self {
        Self {
            txn_hash,
            resolver,
            aggregator_data: Default::default(),
        }
    }

    /// Returns the hash of transaction associated with this context.
    pub fn txn_hash(&self) -> [u8; 32] {
        self.txn_hash
    }

    /// Returns all changes made within this context (i.e. by a single
    /// transaction).
    pub fn into_change_set(self) -> AggregatorChangeSet {
        let NativeAggregatorContext {
            aggregator_data, ..
        } = self;
        let (_, destroyed_aggregators, aggregators) = aggregator_data.into_inner().into();

        let mut changes = BTreeMap::new();

        // First, process all writes and deltas.
        for (id, aggregator) in aggregators {
            let (value, state, limit, history) = aggregator.into();

            let change = match state {
                AggregatorState::Data => AggregatorChange::Write(value),
                AggregatorState::PositiveDelta => {
                    let history = history.unwrap();
                    let plus = DeltaUpdate::Plus(value);
                    let delta_op =
                        DeltaOp::new(plus, limit, history.max_positive, history.min_negative);
                    AggregatorChange::Merge(delta_op)
                }
                AggregatorState::NegativeDelta => {
                    let history = history.unwrap();
                    let minus = DeltaUpdate::Minus(value);
                    let delta_op =
                        DeltaOp::new(minus, limit, history.max_positive, history.min_negative);
                    AggregatorChange::Merge(delta_op)
                }
            };
            changes.insert(id, change);
        }

        // Additionally, do not forget to delete destroyed values from storage.
        for id in destroyed_aggregators {
            changes.insert(id, AggregatorChange::Delete);
        }

        AggregatorChangeSet { changes }
    }
}

impl AggregatorChangeSet {
    pub fn squash(&mut self, other: Self) -> Result<(), VMStatus> {
        for (other_id, other_change) in other.changes {
            match self.changes.entry(other_id) {
                // If something was changed only in `other` session, add it.
                btree_map::Entry::Vacant(entry) => {
                    entry.insert(other_change);
                }
                // Otherwise, we might need to aggregate deltas.
                btree_map::Entry::Occupied(mut entry) => {
                    use AggregatorChange::*;

                    let entry_mut = entry.get_mut();
                    match (*entry_mut, other_change) {
                        (Write(_) | Merge(_), Write(data)) => *entry_mut = Write(data),
                        (Write(_) | Merge(_), Delete) => *entry_mut = Delete,
                        (Write(data), Merge(delta)) => {
                            let new_data = delta
                                .apply_to(data)
                                .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
                            *entry_mut = Write(new_data);
                        }
                        (Merge(delta1), Merge(mut delta2)) => {
                            // `delta1` occurred before `delta2`, therefore we must ensure we merge the latter
                            // one to the initial delta.
                            delta2
                                .merge_onto(delta1)
                                .map_err(|e| e.finish(Location::Undefined).into_vm_status())?;
                            *entry_mut = Merge(delta2)
                        }
                        // Hashing properties guarantee that aggregator keys should
                        // not collide, making this case impossible.
                        (Delete, _) => unreachable!("resource cannot be accessed after deletion"),
                    }
                }
            }
        }
        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use aptos_aggregator::aggregator_extension::AggregatorHandle;
    use aptos_types::account_address::AccountAddress;
    use claims::assert_matches;
    use move_deps::move_table_extension::TableHandle;

    struct EmptyStorage;

    impl TableResolver for EmptyStorage {
        fn resolve_table_entry(
            &self,
            _handle: &TableHandle,
            _key: &[u8],
        ) -> Result<Option<Vec<u8>>, anyhow::Error> {
            Ok(None)
        }
    }

    fn test_id(key: u128) -> AggregatorID {
        let bytes: Vec<u8> = [key.to_le_bytes(), key.to_le_bytes()]
            .iter()
            .flat_map(|b| b.to_vec())
            .collect();
        let key = AggregatorHandle(AccountAddress::from_bytes(&bytes).unwrap());
        AggregatorID::new(TableHandle(AccountAddress::ZERO), key)
    }

    // All aggregators are initialized deterministically based on their ID,
    // with the follwing spec.
    //
    //     +-------+---------------+----------+-----+---------+
    //     |  key  | storage value |  create  | get | remove  |
    //     +-------+---------------+----------+-----+---------+
    //     |  100  |               |   yes    | yes |   yes   |
    //     |  200  |               |   yes    | yes |         |
    //     |  300  |               |   yes    |     |   yes   |
    //     |  400  |               |   yes    |     |         |
    //     |  500  |               |          | yes |   yes   |
    //     |  600  |      300      |          | yes |         |
    //     |  700  |               |          | yes |         |
    //     |  800  |               |          |     |   yes   |
    //     +-------+---------------+----------+-----+---------+
    fn test_set_up(context: &NativeAggregatorContext) {
        let mut aggregator_data = context.aggregator_data.borrow_mut();

        aggregator_data.create_new_aggregator(test_id(100), 100);
        aggregator_data.create_new_aggregator(test_id(200), 200);
        aggregator_data.create_new_aggregator(test_id(300), 300);
        aggregator_data.create_new_aggregator(test_id(400), 400);

        aggregator_data.get_aggregator(test_id(100), 100);
        aggregator_data.get_aggregator(test_id(200), 200);
        aggregator_data.get_aggregator(test_id(500), 500);
        aggregator_data.get_aggregator(test_id(600), 600);
        aggregator_data.get_aggregator(test_id(700), 700);

        aggregator_data.remove_aggregator(test_id(100));
        aggregator_data.remove_aggregator(test_id(300));
        aggregator_data.remove_aggregator(test_id(500));
        aggregator_data.remove_aggregator(test_id(800));
    }

    #[test]
    fn test_into_change_set() {
        let context = NativeAggregatorContext::new([0; 32], &EmptyStorage);
        use AggregatorChange::*;

        test_set_up(&context);
        let AggregatorChangeSet { changes } = context.into_change_set();

        assert!(!changes.contains_key(&test_id(100)));
        assert_matches!(changes.get(&test_id(200)).unwrap(), Write(0));
        assert!(!changes.contains_key(&test_id(300)));
        assert_matches!(changes.get(&test_id(400)).unwrap(), Write(0));
        assert_matches!(changes.get(&test_id(500)).unwrap(), Delete);
        assert!(changes.contains_key(&test_id(600)));
        assert!(changes.contains_key(&test_id(700)));
        assert_matches!(changes.get(&test_id(800)).unwrap(), Delete);
    }
}
<|endoftext|>