<commit_before>use super::ExtractedLexicalGrammar;
use crate::error::{Error, Result};
use crate::grammars::{LexicalGrammar, LexicalVariable};
use crate::nfa::{CharacterSet, Nfa, NfaState};
use crate::rules::Rule;
use regex_syntax::ast::{parse, Ast, Class, ClassPerlKind, ClassSet, ClassSetItem, RepetitionKind};

pub(super) fn expand_tokens(mut grammar: ExtractedLexicalGrammar) -> Result<LexicalGrammar> {
    let mut nfa = Nfa::new();

    let separator_rule = if grammar.separators.len() > 0 {
        grammar.separators.push(Rule::Blank);
        Rule::repeat(Rule::choice(grammar.separators))
    } else {
        Rule::Blank
    };

    let mut variables = Vec::new();
    for (i, variable) in grammar.variables.into_iter().enumerate() {
        let is_immediate_token = match &variable.rule {
            Rule::Metadata { params, .. } => params.is_main_token,
            _ => false,
        };

        nfa.states.push(NfaState::Accept(i));
        let last_state_id = nfa.last_state_id();
        expand_rule(&variable.rule, &mut nfa, last_state_id, false)?;

        if !is_immediate_token {
            let last_state_id = nfa.last_state_id();
            expand_rule(&separator_rule, &mut nfa, last_state_id, true)?;
        }

        variables.push(LexicalVariable {
            name: variable.name,
            kind: variable.kind,
            start_state: nfa.last_state_id(),
        });
    }

    Ok(LexicalGrammar { nfa, variables })
}

fn expand_rule(rule: &Rule, nfa: &mut Nfa, mut next_state_id: u32, is_sep: bool) -> Result<bool> {
    match rule {
        Rule::Pattern(s) => {
            let ast = parse::Parser::new()
                .parse(&s)
                .map_err(|e| Error::GrammarError(e.to_string()))?;
            expand_regex(&ast, nfa, next_state_id, is_sep)
        }
        Rule::String(s) => {
            for c in s.chars().rev() {
                nfa.prepend(|last_state_id| NfaState::Advance {
                    chars: CharacterSet::empty().add_char(c),
                    state_id: last_state_id,
                    is_sep,
                });
            }
            Ok(s.len() > 0)
        }
        Rule::Choice(elements) => {
            let mut alternative_state_ids = Vec::new();
            for element in elements {
                if expand_rule(element, nfa, next_state_id, is_sep)? {
                    alternative_state_ids.push(nfa.last_state_id());
                } else {
                    alternative_state_ids.push(next_state_id);
                }
            }
            alternative_state_ids.retain(|i| *i != nfa.last_state_id());
            for alternative_state_id in alternative_state_ids {
                nfa.prepend(|last_state_id| NfaState::Split(last_state_id, alternative_state_id));
            }
            Ok(true)
        }
        Rule::Seq(elements) => {
            let mut result = false;
            for element in elements.into_iter().rev() {
                if expand_rule(element, nfa, next_state_id, is_sep)? {
                    result = true;
                }
                next_state_id = nfa.last_state_id();
            }
            Ok(result)
        }
        Rule::Repeat(rule) => {
            nfa.states.push(NfaState::Accept(0)); // Placeholder for split
            let split_state_id = nfa.last_state_id();
            if expand_rule(rule, nfa, split_state_id, is_sep)? {
                nfa.states[split_state_id as usize] =
                    NfaState::Split(nfa.last_state_id(), next_state_id);
                Ok(true)
            } else {
                Ok(false)
            }
        }
        Rule::Blank => Ok(false),
        _ => Err(Error::grammar(&format!("Unexpected rule {:?}", rule))),
    }
}

fn expand_regex(ast: &Ast, nfa: &mut Nfa, mut next_state_id: u32, is_sep: bool) -> Result<bool> {
    match ast {
        Ast::Empty(_) => Ok(false),
        Ast::Flags(_) => Err(Error::regex("Flags are not supported")),
        Ast::Literal(literal) => {
            nfa.states.push(NfaState::Advance {
                chars: CharacterSet::Include(vec![literal.c]),
                state_id: next_state_id,
                is_sep,
            });
            Ok(true)
        }
        Ast::Dot(_) => {
            nfa.states.push(NfaState::Advance {
                chars: CharacterSet::Exclude(vec!['\n']),
                state_id: next_state_id,
                is_sep,
            });
            Ok(true)
        }
        Ast::Assertion(_) => Err(Error::regex("Assertions are not supported")),
        Ast::Class(class) => match class {
            Class::Unicode(_) => Err(Error::regex("Unicode character classes are not supported")),
            Class::Perl(class) => {
                nfa.states.push(NfaState::Advance {
                    chars: expand_perl_character_class(&class.kind),
                    state_id: next_state_id,
                    is_sep,
                });
                Ok(true)
            }
            Class::Bracketed(class) => match &class.kind {
                ClassSet::Item(item) => {
                    let character_set = expand_character_class(&item)?;
                    nfa.states.push(NfaState::Advance {
                        chars: character_set,
                        state_id: next_state_id,
                        is_sep,
                    });
                    Ok(true)
                }
                ClassSet::BinaryOp(_) => Err(Error::regex(
                    "Binary operators in character classes aren't supported",
                )),
            },
        },
        Ast::Repetition(repetition) => match repetition.op.kind {
            RepetitionKind::ZeroOrOne => {
                if expand_regex(&repetition.ast, nfa, next_state_id, is_sep)? {
                    nfa.prepend(|last_state_id| NfaState::Split(next_state_id, last_state_id));
                    Ok(true)
                } else {
                    Ok(false)
                }
            }
            RepetitionKind::OneOrMore => {
                nfa.states.push(NfaState::Accept(0)); // Placeholder for split
                let split_state_id = nfa.last_state_id();
                if expand_regex(&repetition.ast, nfa, split_state_id, is_sep)? {
                    nfa.states[split_state_id as usize] =
                        NfaState::Split(nfa.last_state_id(), next_state_id);
                    Ok(true)
                } else {
                    nfa.states.pop();
                    Ok(false)
                }
            }
            RepetitionKind::ZeroOrMore => {
                nfa.states.push(NfaState::Accept(0)); // Placeholder for split
                let split_state_id = nfa.last_state_id();
                if expand_regex(&repetition.ast, nfa, split_state_id, is_sep)? {
                    nfa.states[split_state_id as usize] =
                        NfaState::Split(nfa.last_state_id(), next_state_id);
                    nfa.prepend(|last_state_id| NfaState::Split(last_state_id, next_state_id));
                    Ok(true)
                } else {
                    Ok(false)
                }
            }
            RepetitionKind::Range(_) => unimplemented!(),
        },
        Ast::Group(group) => expand_regex(&group.ast, nfa, nfa.last_state_id(), is_sep),
        Ast::Alternation(alternation) => {
            let mut alternative_state_ids = Vec::new();
            for ast in alternation.asts.iter() {
                if expand_regex(&ast, nfa, next_state_id, is_sep)? {
                    alternative_state_ids.push(nfa.last_state_id());
                } else {
                    alternative_state_ids.push(next_state_id);
                }
            }
            alternative_state_ids.retain(|i| *i != nfa.last_state_id());
            for alternative_state_id in alternative_state_ids {
                nfa.prepend(|last_state_id| NfaState::Split(last_state_id, alternative_state_id));
            }
            Ok(true)
        }
        Ast::Concat(concat) => {
            let mut result = false;
            for ast in concat.asts.iter().rev() {
                if expand_regex(&ast, nfa, next_state_id, is_sep)? {
                    result = true;
                }
                next_state_id = nfa.last_state_id();
            }
            Ok(result)
        }
    }
}

fn expand_character_class(item: &ClassSetItem) -> Result<CharacterSet> {
    match item {
        ClassSetItem::Empty(_) => Ok(CharacterSet::Include(Vec::new())),
        ClassSetItem::Literal(literal) => Ok(CharacterSet::Include(vec![literal.c])),
        ClassSetItem::Range(range) => {
            Ok(CharacterSet::empty().add_range(range.start.c, range.end.c))
        }
        ClassSetItem::Union(union) => {
            let mut result = CharacterSet::empty();
            for item in &union.items {
                result = result.add(expand_character_class(&item)?);
            }
            Ok(result)
        }
        _ => Err(Error::regex("Unsupported character class syntax")),
    }
}

fn expand_perl_character_class(item: &ClassPerlKind) -> CharacterSet {
    match item {
        ClassPerlKind::Digit => CharacterSet::empty().add_range('0', '9'),
        ClassPerlKind::Space => CharacterSet::empty()
            .add_char(' ')
            .add_char('\t')
            .add_char('\r')
            .add_char('\n'),
        ClassPerlKind::Word => CharacterSet::empty()
            .add_char('_')
            .add_range('A', 'Z')
            .add_range('a', 'z')
            .add_range('0', '9'),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::grammars::Variable;
    use crate::nfa::NfaCursor;

    fn simulate_nfa<'a>(grammar: &'a LexicalGrammar, s: &'a str) -> Option<(usize, &'a str)> {
        let start_states = grammar.variables.iter().map(|v| v.start_state).collect();
        let mut cursor = NfaCursor::new(&grammar.nfa, start_states);

        let mut result = None;
        let mut start_char = 0;
        let mut end_char = 0;
        for c in s.chars() {
            if let Some(id) = cursor.finished_id() {
                result = Some((id, &s[start_char..end_char]));
            }
            if cursor.advance(c) {
                end_char += 1;
                if cursor.in_separator() {
                    start_char = end_char;
                }
            } else {
                break;
            }
        }

        if let Some(id) = cursor.finished_id() {
            result = Some((id, &s[start_char..end_char]));
        }

        result
    }

    #[test]
    fn test_rule_expansion() {
        struct Row {
            rules: Vec<Rule>,
            separators: Vec<Rule>,
            examples: Vec<(&'static str, Option<(usize, &'static str)>)>,
        }

        let table = [
            // regex with sequences and alternatives
            Row {
                rules: vec![Rule::pattern("(a|b|c)d(e|f|g)h?")],
                separators: vec![],
                examples: vec![
                    ("ade1", Some((0, "ade"))),
                    ("bdf1", Some((0, "bdf"))),
                    ("bdfh1", Some((0, "bdfh"))),
                    ("ad1", None),
                ],
            },
            // regex with repeats
            Row {
                rules: vec![Rule::pattern("a*")],
                separators: vec![],
                examples: vec![("aaa1", Some((0, "aaa"))), ("b", Some((0, "")))],
            },
            // regex with repeats in sequences
            Row {
                rules: vec![Rule::pattern("a((bc)+|(de)*)f")],
                separators: vec![],
                examples: vec![
                    ("af1", Some((0, "af"))),
                    ("adedef1", Some((0, "adedef"))),
                    ("abcbcbcf1", Some((0, "abcbcbcf"))),
                    ("a", None),
                ],
            },
            // regex with character ranges
            Row {
                rules: vec![Rule::pattern("[a-fA-F0-9]+")],
                separators: vec![],
                examples: vec![("A1ff0.", Some((0, "A1ff0")))],
            },
            // regex with perl character classes
            Row {
                rules: vec![Rule::pattern("\\w\\d\\s")],
                separators: vec![],
                examples: vec![("_0  ", Some((0, "_0 ")))],
            },
            // string
            Row {
                rules: vec![Rule::string("abc")],
                separators: vec![],
                examples: vec![("abcd", Some((0, "abc"))), ("ab", None)],
            },
            // complex rule containing strings and regexes
            Row {
                rules: vec![Rule::repeat(Rule::seq(vec![
                    Rule::string("{"),
                    Rule::pattern("[a-f]+"),
                    Rule::string("}"),
                ]))],
                separators: vec![],
                examples: vec![
                    ("{a}{", Some((0, "{a}"))),
                    ("{a}{d", Some((0, "{a}"))),
                    ("ab", None),
                ],
            },
            // longest match rule
            Row {
                rules: vec![
                    Rule::pattern("a|bc"),
                    Rule::pattern("aa"),
                    Rule::pattern("bcd"),
                ],
                separators: vec![],
                examples: vec![
                    ("a.", Some((0, "a"))),
                    ("bc.", Some((0, "bc"))),
                    ("aa.", Some((1, "aa"))),
                    ("bcd?", Some((2, "bcd"))),
                    ("b.", None),
                    ("c.", None),
                ],
            },
            // regex with an alternative including the empty string
            Row {
                rules: vec![Rule::pattern("a(b|)+c")],
                separators: vec![],
                examples: vec![
                    ("ac.", Some((0, "ac"))),
                    ("abc.", Some((0, "abc"))),
                    ("abbc.", Some((0, "abbc"))),
                ],
            },
            // separators
            Row {
                rules: vec![Rule::pattern("[a-f]+")],
                separators: vec![Rule::string("\\\n"), Rule::pattern("\\s")],
                examples: vec![
                    ("  a", Some((0, "a"))),
                    ("  \nb", Some((0, "b"))),
                    ("  \\a", None),
                    ("  \\\na", Some((0, "a"))),
                ],
            },
        ];

        for Row {
            rules,
            separators,
            examples,
        } in &table
        {
            let grammar = expand_tokens(ExtractedLexicalGrammar {
                separators: separators.clone(),
                variables: rules
                    .into_iter()
                    .map(|rule| Variable::named("", rule.clone()))
                    .collect(),
            })
            .unwrap();

            for (haystack, needle) in examples.iter() {
                assert_eq!(simulate_nfa(&grammar, haystack), *needle);
            }
        }
    }
}
<commit_msg>Handle repetition ranges in regexes<commit_after>use super::ExtractedLexicalGrammar;
use crate::error::{Error, Result};
use crate::grammars::{LexicalGrammar, LexicalVariable};
use crate::nfa::{CharacterSet, Nfa, NfaState};
use crate::rules::Rule;
use regex_syntax::ast::{
    parse, Ast, Class, ClassPerlKind, ClassSet, ClassSetItem, RepetitionKind, RepetitionRange,
};

pub(super) fn expand_tokens(mut grammar: ExtractedLexicalGrammar) -> Result<LexicalGrammar> {
    let mut nfa = Nfa::new();

    let separator_rule = if grammar.separators.len() > 0 {
        grammar.separators.push(Rule::Blank);
        Rule::repeat(Rule::choice(grammar.separators))
    } else {
        Rule::Blank
    };

    let mut variables = Vec::new();
    for (i, variable) in grammar.variables.into_iter().enumerate() {
        let is_immediate_token = match &variable.rule {
            Rule::Metadata { params, .. } => params.is_main_token,
            _ => false,
        };

        nfa.states.push(NfaState::Accept(i));
        let last_state_id = nfa.last_state_id();
        expand_rule(&variable.rule, &mut nfa, last_state_id, false).map_err(|e| match e {
            Error::RegexError(msg) => Error::RegexError(format!("Rule {} {}", variable.name, msg)),
            _ => e,
        })?;

        if !is_immediate_token {
            let last_state_id = nfa.last_state_id();
            expand_rule(&separator_rule, &mut nfa, last_state_id, true)?;
        }

        variables.push(LexicalVariable {
            name: variable.name,
            kind: variable.kind,
            start_state: nfa.last_state_id(),
        });
    }

    Ok(LexicalGrammar { nfa, variables })
}

fn expand_rule(rule: &Rule, nfa: &mut Nfa, mut next_state_id: u32, is_sep: bool) -> Result<bool> {
    match rule {
        Rule::Pattern(s) => {
            let ast = parse::Parser::new()
                .parse(&s)
                .map_err(|e| Error::GrammarError(e.to_string()))?;
            expand_regex(&ast, nfa, next_state_id, is_sep)
        }
        Rule::String(s) => {
            for c in s.chars().rev() {
                nfa.prepend(|last_state_id| NfaState::Advance {
                    chars: CharacterSet::empty().add_char(c),
                    state_id: last_state_id,
                    is_sep,
                });
            }
            Ok(s.len() > 0)
        }
        Rule::Choice(elements) => {
            let mut alternative_state_ids = Vec::new();
            for element in elements {
                if expand_rule(element, nfa, next_state_id, is_sep)? {
                    alternative_state_ids.push(nfa.last_state_id());
                } else {
                    alternative_state_ids.push(next_state_id);
                }
            }
            alternative_state_ids.retain(|i| *i != nfa.last_state_id());
            for alternative_state_id in alternative_state_ids {
                nfa.prepend(|last_state_id| NfaState::Split(last_state_id, alternative_state_id));
            }
            Ok(true)
        }
        Rule::Seq(elements) => {
            let mut result = false;
            for element in elements.into_iter().rev() {
                if expand_rule(element, nfa, next_state_id, is_sep)? {
                    result = true;
                }
                next_state_id = nfa.last_state_id();
            }
            Ok(result)
        }
        Rule::Repeat(rule) => {
            nfa.states.push(NfaState::Accept(0)); // Placeholder for split
            let split_state_id = nfa.last_state_id();
            if expand_rule(rule, nfa, split_state_id, is_sep)? {
                nfa.states[split_state_id as usize] =
                    NfaState::Split(nfa.last_state_id(), next_state_id);
                Ok(true)
            } else {
                Ok(false)
            }
        }
        Rule::Metadata { rule, .. } => {
            // TODO - implement precedence
            expand_rule(rule, nfa, next_state_id, is_sep)
        }
        Rule::Blank => Ok(false),
        _ => Err(Error::grammar(&format!("Unexpected rule {:?}", rule))),
    }
}

fn expand_one_or_more(ast: &Ast, nfa: &mut Nfa, next_state_id: u32, is_sep: bool) -> Result<bool> {
    nfa.states.push(NfaState::Accept(0)); // Placeholder for split
    let split_state_id = nfa.last_state_id();
    if expand_regex(&ast, nfa, split_state_id, is_sep)? {
        nfa.states[split_state_id as usize] = NfaState::Split(nfa.last_state_id(), next_state_id);
        Ok(true)
    } else {
        nfa.states.pop();
        Ok(false)
    }
}

fn expand_zero_or_one(ast: &Ast, nfa: &mut Nfa, next_state_id: u32, is_sep: bool) -> Result<bool> {
    if expand_regex(ast, nfa, next_state_id, is_sep)? {
        nfa.prepend(|last_state_id| NfaState::Split(next_state_id, last_state_id));
        Ok(true)
    } else {
        Ok(false)
    }
}

fn expand_zero_or_more(ast: &Ast, nfa: &mut Nfa, next_state_id: u32, is_sep: bool) -> Result<bool> {
    if expand_one_or_more(&ast, nfa, next_state_id, is_sep)? {
        nfa.prepend(|last_state_id| NfaState::Split(last_state_id, next_state_id));
        Ok(true)
    } else {
        Ok(false)
    }
}

fn expand_count(
    ast: &Ast,
    count: u32,
    nfa: &mut Nfa,
    mut next_state_id: u32,
    is_sep: bool,
) -> Result<bool> {
    let mut result = false;
    for _ in 0..count {
        if expand_regex(ast, nfa, next_state_id, is_sep)? {
            result = true;
            next_state_id = nfa.last_state_id();
        }
    }
    Ok(result)
}

fn expand_regex(ast: &Ast, nfa: &mut Nfa, mut next_state_id: u32, is_sep: bool) -> Result<bool> {
    match ast {
        Ast::Empty(_) => Ok(false),
        Ast::Flags(_) => Err(Error::regex("Flags are not supported")),
        Ast::Literal(literal) => {
            nfa.states.push(NfaState::Advance {
                chars: CharacterSet::Include(vec![literal.c]),
                state_id: next_state_id,
                is_sep,
            });
            Ok(true)
        }
        Ast::Dot(_) => {
            nfa.states.push(NfaState::Advance {
                chars: CharacterSet::Exclude(vec!['\n']),
                state_id: next_state_id,
                is_sep,
            });
            Ok(true)
        }
        Ast::Assertion(_) => Err(Error::regex("Assertions are not supported")),
        Ast::Class(class) => match class {
            Class::Unicode(_) => Err(Error::regex("Unicode character classes are not supported")),
            Class::Perl(class) => {
                nfa.states.push(NfaState::Advance {
                    chars: expand_perl_character_class(&class.kind),
                    state_id: next_state_id,
                    is_sep,
                });
                Ok(true)
            }
            Class::Bracketed(class) => match &class.kind {
                ClassSet::Item(item) => {
                    let character_set = expand_character_class(&item)?;
                    nfa.states.push(NfaState::Advance {
                        chars: character_set,
                        state_id: next_state_id,
                        is_sep,
                    });
                    Ok(true)
                }
                ClassSet::BinaryOp(_) => Err(Error::regex(
                    "Binary operators in character classes aren't supported",
                )),
            },
        },
        Ast::Repetition(repetition) => match repetition.op.kind {
            RepetitionKind::ZeroOrOne => {
                expand_zero_or_one(&repetition.ast, nfa, next_state_id, is_sep)
            }
            RepetitionKind::OneOrMore => {
                expand_one_or_more(&repetition.ast, nfa, next_state_id, is_sep)
            }
            RepetitionKind::ZeroOrMore => {
                expand_zero_or_more(&repetition.ast, nfa, next_state_id, is_sep)
            }
            RepetitionKind::Range(RepetitionRange::Exactly(count)) => {
                expand_count(&repetition.ast, count, nfa, next_state_id, is_sep)
            }
            RepetitionKind::Range(RepetitionRange::AtLeast(min)) => {
                if expand_zero_or_more(&repetition.ast, nfa, next_state_id, is_sep)? {
                    expand_count(ast, min, nfa, next_state_id, is_sep)
                } else {
                    Ok(false)
                }
            }
            RepetitionKind::Range(RepetitionRange::Bounded(min, max)) => {
                let mut result = expand_count(&repetition.ast, min, nfa, next_state_id, is_sep)?;
                for _ in min..max {
                    if result {
                        next_state_id = nfa.last_state_id();
                    }
                    if expand_zero_or_one(&repetition.ast, nfa, next_state_id, is_sep)? {
                        result = true;
                    }
                }
                Ok(result)
            }
        },
        Ast::Group(group) => expand_regex(&group.ast, nfa, nfa.last_state_id(), is_sep),
        Ast::Alternation(alternation) => {
            let mut alternative_state_ids = Vec::new();
            for ast in alternation.asts.iter() {
                if expand_regex(&ast, nfa, next_state_id, is_sep)? {
                    alternative_state_ids.push(nfa.last_state_id());
                } else {
                    alternative_state_ids.push(next_state_id);
                }
            }
            alternative_state_ids.retain(|i| *i != nfa.last_state_id());
            for alternative_state_id in alternative_state_ids {
                nfa.prepend(|last_state_id| NfaState::Split(last_state_id, alternative_state_id));
            }
            Ok(true)
        }
        Ast::Concat(concat) => {
            let mut result = false;
            for ast in concat.asts.iter().rev() {
                if expand_regex(&ast, nfa, next_state_id, is_sep)? {
                    result = true;
                    next_state_id = nfa.last_state_id();
                }
            }
            Ok(result)
        }
    }
}

fn expand_character_class(item: &ClassSetItem) -> Result<CharacterSet> {
    match item {
        ClassSetItem::Empty(_) => Ok(CharacterSet::Include(Vec::new())),
        ClassSetItem::Literal(literal) => Ok(CharacterSet::Include(vec![literal.c])),
        ClassSetItem::Range(range) => {
            Ok(CharacterSet::empty().add_range(range.start.c, range.end.c))
        }
        ClassSetItem::Union(union) => {
            let mut result = CharacterSet::empty();
            for item in &union.items {
                result = result.add(expand_character_class(&item)?);
            }
            Ok(result)
        }
        ClassSetItem::Perl(class) => Ok(expand_perl_character_class(&class.kind)),
        _ => Err(Error::regex(&format!(
            "Unsupported character class syntax {:?}",
            item
        ))),
    }
}

fn expand_perl_character_class(item: &ClassPerlKind) -> CharacterSet {
    match item {
        ClassPerlKind::Digit => CharacterSet::empty().add_range('0', '9'),
        ClassPerlKind::Space => CharacterSet::empty()
            .add_char(' ')
            .add_char('\t')
            .add_char('\r')
            .add_char('\n'),
        ClassPerlKind::Word => CharacterSet::empty()
            .add_char('_')
            .add_range('A', 'Z')
            .add_range('a', 'z')
            .add_range('0', '9'),
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::grammars::Variable;
    use crate::nfa::NfaCursor;

    fn simulate_nfa<'a>(grammar: &'a LexicalGrammar, s: &'a str) -> Option<(usize, &'a str)> {
        let start_states = grammar.variables.iter().map(|v| v.start_state).collect();
        let mut cursor = NfaCursor::new(&grammar.nfa, start_states);

        let mut result = None;
        let mut start_char = 0;
        let mut end_char = 0;
        for c in s.chars() {
            if let Some(id) = cursor.finished_id() {
                result = Some((id, &s[start_char..end_char]));
            }
            if cursor.advance(c) {
                end_char += 1;
                if cursor.in_separator() {
                    start_char = end_char;
                }
            } else {
                break;
            }
        }

        if let Some(id) = cursor.finished_id() {
            result = Some((id, &s[start_char..end_char]));
        }

        result
    }

    #[test]
    fn test_rule_expansion() {
        struct Row {
            rules: Vec<Rule>,
            separators: Vec<Rule>,
            examples: Vec<(&'static str, Option<(usize, &'static str)>)>,
        }

        let table = [
            // regex with sequences and alternatives
            Row {
                rules: vec![Rule::pattern("(a|b|c)d(e|f|g)h?")],
                separators: vec![],
                examples: vec![
                    ("ade1", Some((0, "ade"))),
                    ("bdf1", Some((0, "bdf"))),
                    ("bdfh1", Some((0, "bdfh"))),
                    ("ad1", None),
                ],
            },
            // regex with repeats
            Row {
                rules: vec![Rule::pattern("a*")],
                separators: vec![],
                examples: vec![("aaa1", Some((0, "aaa"))), ("b", Some((0, "")))],
            },
            // regex with repeats in sequences
            Row {
                rules: vec![Rule::pattern("a((bc)+|(de)*)f")],
                separators: vec![],
                examples: vec![
                    ("af1", Some((0, "af"))),
                    ("adedef1", Some((0, "adedef"))),
                    ("abcbcbcf1", Some((0, "abcbcbcf"))),
                    ("a", None),
                ],
            },
            // regex with character ranges
            Row {
                rules: vec![Rule::pattern("[a-fA-F0-9]+")],
                separators: vec![],
                examples: vec![("A1ff0.", Some((0, "A1ff0")))],
            },
            // regex with perl character classes
            Row {
                rules: vec![Rule::pattern("\\w\\d\\s")],
                separators: vec![],
                examples: vec![("_0  ", Some((0, "_0 ")))],
            },
            // string
            Row {
                rules: vec![Rule::string("abc")],
                separators: vec![],
                examples: vec![("abcd", Some((0, "abc"))), ("ab", None)],
            },
            // complex rule containing strings and regexes
            Row {
                rules: vec![Rule::repeat(Rule::seq(vec![
                    Rule::string("{"),
                    Rule::pattern("[a-f]+"),
                    Rule::string("}"),
                ]))],
                separators: vec![],
                examples: vec![
                    ("{a}{", Some((0, "{a}"))),
                    ("{a}{d", Some((0, "{a}"))),
                    ("ab", None),
                ],
            },
            // longest match rule
            Row {
                rules: vec![
                    Rule::pattern("a|bc"),
                    Rule::pattern("aa"),
                    Rule::pattern("bcd"),
                ],
                separators: vec![],
                examples: vec![
                    ("a.", Some((0, "a"))),
                    ("bc.", Some((0, "bc"))),
                    ("aa.", Some((1, "aa"))),
                    ("bcd?", Some((2, "bcd"))),
                    ("b.", None),
                    ("c.", None),
                ],
            },
            // regex with an alternative including the empty string
            Row {
                rules: vec![Rule::pattern("a(b|)+c")],
                separators: vec![],
                examples: vec![
                    ("ac.", Some((0, "ac"))),
                    ("abc.", Some((0, "abc"))),
                    ("abbc.", Some((0, "abbc"))),
                ],
            },
            // separators
            Row {
                rules: vec![Rule::pattern("[a-f]+")],
                separators: vec![Rule::string("\\\n"), Rule::pattern("\\s")],
                examples: vec![
                    ("  a", Some((0, "a"))),
                    ("  \nb", Some((0, "b"))),
                    ("  \\a", None),
                    ("  \\\na", Some((0, "a"))),
                ],
            },
        ];

        for Row {
            rules,
            separators,
            examples,
        } in &table
        {
            let grammar = expand_tokens(ExtractedLexicalGrammar {
                separators: separators.clone(),
                variables: rules
                    .into_iter()
                    .map(|rule| Variable::named("", rule.clone()))
                    .collect(),
            })
            .unwrap();

            for (haystack, needle) in examples.iter() {
                assert_eq!(simulate_nfa(&grammar, haystack), *needle);
            }
        }
    }
}
<|endoftext|>


<commit_before>use super::imp::{BitMaskWord, BITMASK_MASK, BITMASK_STRIDE};
#[cfg(feature = "nightly")]
use core::intrinsics;

/// A bit mask which contains the result of a `Match` operation on a `Group` and
/// allows iterating through them.
///
/// The bit mask is arranged so that low-order bits represent lower memory
/// addresses for group match results.
///
/// For implementation reasons, the bits in the set may be sparsely packed, so
/// that there is only one bit-per-byte used (the high bit, 7). If this is the
/// case, `BITMASK_STRIDE` will be 8 to indicate a divide-by-8 should be
/// performed on counts/indices to normalize this difference. `BITMASK_MASK` is
/// similarly a mask of all the actually-used bits.
#[derive(Copy, Clone)]
pub struct BitMask(pub BitMaskWord);

#[allow(clippy::use_self)]
impl BitMask {
    /// Returns a new `BitMask` with all bits inverted.
    #[inline]
    #[must_use]
    pub fn invert(self) -> Self {
        BitMask(self.0 ^ BITMASK_MASK)
    }

    /// Returns a new `BitMask` with the lowest bit removed.
    #[inline]
    #[must_use]
    pub fn remove_lowest_bit(self) -> Self {
        BitMask(self.0 & (self.0 - 1))
    }
    /// Returns whether the `BitMask` has at least one set bit.
    #[inline]
    pub fn any_bit_set(self) -> bool {
        self.0 != 0
    }

    /// Returns the first set bit in the `BitMask`, if there is one.
    #[inline]
    pub fn lowest_set_bit(self) -> Option<usize> {
        if self.0 == 0 {
            None
        } else {
            Some(unsafe { self.lowest_set_bit_nonzero() })
        }
    }

    /// Returns the first set bit in the `BitMask`, if there is one. The
    /// bitmask must not be empty.
    #[inline]
    #[cfg(feature = "nightly")]
    pub unsafe fn lowest_set_bit_nonzero(self) -> usize {
        intrinsics::cttz_nonzero(self.0) as usize / BITMASK_STRIDE
    }
    #[cfg(not(feature = "nightly"))]
    pub unsafe fn lowest_set_bit_nonzero(self) -> usize {
        self.trailing_zeros()
    }

    /// Returns the number of trailing zeroes in the `BitMask`.
    #[inline]
    pub fn trailing_zeros(self) -> usize {
        // ARM doesn't have a trailing_zeroes instruction, and instead uses
        // reverse_bits (RBIT) + leading_zeroes (CLZ). However older ARM
        // versions (pre-ARMv7) don't have RBIT and need to emulate it
        // instead. Since we only have 1 bit set in each byte on ARM, we can
        // use swap_bytes (REV) + leading_zeroes instead.
        if cfg!(target_arch = "arm") && BITMASK_STRIDE % 8 == 0 {
            self.0.swap_bytes().leading_zeros() as usize / BITMASK_STRIDE
        } else {
            self.0.trailing_zeros() as usize / BITMASK_STRIDE
        }
    }

    /// Returns the number of leading zeroes in the `BitMask`.
    #[inline]
    pub fn leading_zeros(self) -> usize {
        self.0.leading_zeros() as usize / BITMASK_STRIDE
    }
}

impl IntoIterator for BitMask {
    type Item = usize;
    type IntoIter = BitMaskIter;

    #[inline]
    fn into_iter(self) -> BitMaskIter {
        BitMaskIter(self)
    }
}

/// Iterator over the contents of a `BitMask`, returning the indicies of set
/// bits.
pub struct BitMaskIter(BitMask);

impl Iterator for BitMaskIter {
    type Item = usize;

    #[inline]
    fn next(&mut self) -> Option<usize> {
        let bit = self.0.lowest_set_bit()?;
        self.0 = self.0.remove_lowest_bit();
        Some(bit)
    }
}
<commit_msg>Inline non-nightly lowest_set_bit_nonzero<commit_after>use super::imp::{BitMaskWord, BITMASK_MASK, BITMASK_STRIDE};
#[cfg(feature = "nightly")]
use core::intrinsics;

/// A bit mask which contains the result of a `Match` operation on a `Group` and
/// allows iterating through them.
///
/// The bit mask is arranged so that low-order bits represent lower memory
/// addresses for group match results.
///
/// For implementation reasons, the bits in the set may be sparsely packed, so
/// that there is only one bit-per-byte used (the high bit, 7). If this is the
/// case, `BITMASK_STRIDE` will be 8 to indicate a divide-by-8 should be
/// performed on counts/indices to normalize this difference. `BITMASK_MASK` is
/// similarly a mask of all the actually-used bits.
#[derive(Copy, Clone)]
pub struct BitMask(pub BitMaskWord);

#[allow(clippy::use_self)]
impl BitMask {
    /// Returns a new `BitMask` with all bits inverted.
    #[inline]
    #[must_use]
    pub fn invert(self) -> Self {
        BitMask(self.0 ^ BITMASK_MASK)
    }

    /// Returns a new `BitMask` with the lowest bit removed.
    #[inline]
    #[must_use]
    pub fn remove_lowest_bit(self) -> Self {
        BitMask(self.0 & (self.0 - 1))
    }
    /// Returns whether the `BitMask` has at least one set bit.
    #[inline]
    pub fn any_bit_set(self) -> bool {
        self.0 != 0
    }

    /// Returns the first set bit in the `BitMask`, if there is one.
    #[inline]
    pub fn lowest_set_bit(self) -> Option<usize> {
        if self.0 == 0 {
            None
        } else {
            Some(unsafe { self.lowest_set_bit_nonzero() })
        }
    }

    /// Returns the first set bit in the `BitMask`, if there is one. The
    /// bitmask must not be empty.
    #[inline]
    #[cfg(feature = "nightly")]
    pub unsafe fn lowest_set_bit_nonzero(self) -> usize {
        intrinsics::cttz_nonzero(self.0) as usize / BITMASK_STRIDE
    }
    #[inline]
    #[cfg(not(feature = "nightly"))]
    pub unsafe fn lowest_set_bit_nonzero(self) -> usize {
        self.trailing_zeros()
    }

    /// Returns the number of trailing zeroes in the `BitMask`.
    #[inline]
    pub fn trailing_zeros(self) -> usize {
        // ARM doesn't have a trailing_zeroes instruction, and instead uses
        // reverse_bits (RBIT) + leading_zeroes (CLZ). However older ARM
        // versions (pre-ARMv7) don't have RBIT and need to emulate it
        // instead. Since we only have 1 bit set in each byte on ARM, we can
        // use swap_bytes (REV) + leading_zeroes instead.
        if cfg!(target_arch = "arm") && BITMASK_STRIDE % 8 == 0 {
            self.0.swap_bytes().leading_zeros() as usize / BITMASK_STRIDE
        } else {
            self.0.trailing_zeros() as usize / BITMASK_STRIDE
        }
    }

    /// Returns the number of leading zeroes in the `BitMask`.
    #[inline]
    pub fn leading_zeros(self) -> usize {
        self.0.leading_zeros() as usize / BITMASK_STRIDE
    }
}

impl IntoIterator for BitMask {
    type Item = usize;
    type IntoIter = BitMaskIter;

    #[inline]
    fn into_iter(self) -> BitMaskIter {
        BitMaskIter(self)
    }
}

/// Iterator over the contents of a `BitMask`, returning the indicies of set
/// bits.
pub struct BitMaskIter(BitMask);

impl Iterator for BitMaskIter {
    type Item = usize;

    #[inline]
    fn next(&mut self) -> Option<usize> {
        let bit = self.0.lowest_set_bit()?;
        self.0 = self.0.remove_lowest_bit();
        Some(bit)
    }
}
<|endoftext|>


<commit_before>use std::ptr;

struct TssContext { handle: u32 }
struct TssTpm { handle: u32 }

type TssHContext = u32;
type TssHTPM = u32;
type TssResult = u32;
type TssUnicode = u16;

const TSS_SUCCESS: TssResult = 0;

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Connect(phContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_GetTpmObject(phContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_Context_Close(phContext: TssHContext) -> TssResult;
}

impl TssContext {
    fn new() -> Result<TssContext, TssResult> {
        unsafe {
            let mut handle = 0;
            let result = Tspi_Context_Create(&mut handle);
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(TssContext { handle: handle })
            }
        }
    }

    // TODO: support destination
    fn connect(&self) -> Result<(), TssResult> {
        unsafe {
            let result = Tspi_Context_Connect(self.handle, ptr::null());
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(())
            }
        }
    }

    fn get_tpm_object(&self) -> Result<TssTpm, TssResult> {
        unsafe {
            let mut handle = 0;
            let result = Tspi_Context_GetTpmObject(self.handle, &mut handle);
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(TssTpm { handle: handle })
            }
        }
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_Close(self.handle);
        }
    }
}

fn main() {
    // TODO: Any cleaner way to write this?
    let contextresult = TssContext::new();
    if let Ok(context) = contextresult {
        if let Ok(_) = context.connect() {
            if let Ok(tpm) = context.get_tpm_object() {
                println!("Success! TPM handle: {:?}", tpm.handle);
            } else {
                println!("Failed to get TPM handle :(")
            }
        } else {
            println!("Failed to connect :(");
        }
    } else {
        println!("Failed :(");
    }

    /*
    match blah {
        Ok(context) => println!("Context created! {:?}", context.handle),
        Err(e) => println!("Context failed with err {:?}", e),
    }
    println!("Hello world!");
    */
}
<commit_msg>Implement Tspi_TPM_PcrRead<commit_after>use std::ptr;

struct TssContext { handle: u32 }
struct TssTpm { handle: u32 }

type TssHContext = u32;
type TssHTPM = u32;
type TssResult = u32;
type TssUnicode = u16;

const TSS_SUCCESS: TssResult = 0;

#[link(name = "tspi")]
extern {
    fn Tspi_Context_Create(phContext: *mut TssHContext) -> TssResult;
    fn Tspi_Context_Connect(phContext: TssHContext, wszDestination: *const TssUnicode) -> TssResult;
    fn Tspi_Context_GetTpmObject(phContext: TssHContext, phTPM: *mut TssHTPM) -> TssResult;
    fn Tspi_Context_Close(phContext: TssHContext) -> TssResult;
    fn Tspi_TPM_PcrRead(hTPM: TssHTPM, ulPcrIndex: u32, pulPcrValueLength: *mut u32, prgbPcrValue: *mut *mut u8) -> TssResult;
}

impl TssContext {
    fn new() -> Result<TssContext, TssResult> {
        unsafe {
            let mut handle = 0;
            let result = Tspi_Context_Create(&mut handle);
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(TssContext { handle: handle })
            }
        }
    }

    // TODO: support destination
    fn connect(&self) -> Result<(), TssResult> {
        unsafe {
            let result = Tspi_Context_Connect(self.handle, ptr::null());
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(())
            }
        }
    }

    fn get_tpm_object(&self) -> Result<TssTpm, TssResult> {
        unsafe {
            let mut handle = 0;
            let result = Tspi_Context_GetTpmObject(self.handle, &mut handle);
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                Ok(TssTpm { handle: handle })
            }
        }
    }
}

impl Drop for TssContext {
    fn drop(&mut self) {
        unsafe {
            Tspi_Context_Close(self.handle);
        }
    }
}

impl TssTpm {
    fn pcr_read(&self, pcr_index: u32) -> Result<Vec<u8>, TssResult> {
        unsafe {
            let mut ulPcrValueLength = -1;
            let mut pRgbPcrValue = 0 as *mut u8;
            let result = Tspi_TPM_PcrRead(self.handle, pcr_index, &mut ulPcrValueLength, &mut pRgbPcrValue);
            if result != TSS_SUCCESS {
                Err(result)
            } else {
                let mut vec = Vec::new();
                for i in 0..ulPcrValueLength {
                    vec.push(*pRgbPcrValue.offset(i as isize));
                }
                Ok(vec)
                // Need to free
            }
        }
    }
}

fn main() {
    // TODO: Any cleaner way to write this?
    let contextresult = TssContext::new();
    if let Ok(context) = contextresult {
        if let Ok(_) = context.connect() {
            if let Ok(tpm) = context.get_tpm_object() {
                println!("I'M IN UR TPM READING UR PCRZ (From Rust!)");
                println!("TPM handle: {:?}", tpm.handle);
                for i in 0..24 {
                    if let Ok(vec) = tpm.pcr_read(i) {
                        print!("PCR {:02}", i);
                        for j in 0..19 {
                            print!(" {:02X}", vec[j]);
                        }
                        print!("\n");
                    }
                }
            } else {
                println!("Failed to get TPM handle :(")
            }
        } else {
            println!("Failed to connect :(");
        }
    } else {
        println!("Failed :(");
    }

    /*
    match blah {
        Ok(context) => println!("Context created! {:?}", context.handle),
        Err(e) => println!("Context failed with err {:?}", e),
    }
    println!("Hello world!");
    */
}
<|endoftext|>


<commit_before>#![feature(test)]
#![allow(unused_imports)]

extern crate test;
#[macro_use(s)]
extern crate ndarray;
#[cfg(feature = "rblas")]
extern crate rblas;
#[cfg(feature = "rblas")]
use rblas::matrix::Matrix;

use ndarray::{
    OwnedArray,
    zeros,
};
use ndarray::{arr0, arr1, arr2};

use test::black_box;

#[bench]
fn bench_std_add_shared(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn bench_std_add_owned(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let mut a = a.to_owned();
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn small_iter_1d(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn small_iter_1d_raw(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.raw_data().iter() { black_box(elt); })
}

#[bench]
fn small_iter_2d(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn add_1d_regular(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_1d_raw(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = OwnedArray::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_2d_regular(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_2d_by_row(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for row in a.outer_iter() {
            for &elt in row {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn add_2d_raw(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_2d_cutout(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_2d_cutout_fold(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        a.fold(0, |acc, elt| acc + *elt)
    });
}

#[bench]
fn add_2d_cutout_by_row(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for row in 0..a.shape()[0] {
            for &elt in a.row_iter(row) {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn add_2d_cutout_outer_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for row in a.outer_iter() {
            for &elt in row {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn add_2d_transpose_regular(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::<i32, _>::zeros((64, 64));
    a.swap_axes(0, 1);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn add_2d_transpose_by_row(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::<i32, _>::zeros((64, 64));
    a.swap_axes(0, 1);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for row in 0..a.shape()[0] {
            for &elt in a.row_iter(row) {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn assign_scalar_2d_transposed(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    a.swap_axes(0, 1);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::zeros((64, 64));
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_cutout(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::zeros((66, 66));
    let mut a = a.slice_mut(s![1..-1, 1..-1]);
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_transposed_large(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::zeros((64, 64));
    a.swap_axes(0, 1);
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_raw_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::zeros((64, 64));
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| for elt in a.raw_data_mut() { *elt = s; });
}

#[bench]
fn bench_iter_diag(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.diag_iter() { black_box(elt); })
}

#[bench]
fn bench_row_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    let it = a.row_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_col_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    let it = a.col_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_mat_mul(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    bench.iter(|| at.mat_mul(&a));
}

#[bench]
fn bench_mat_mul_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((64, 64));
    let b = OwnedArray::<f32, _>::zeros((64, 64));
    let a = black_box(a.view());
    let b = black_box(b.view());
    bench.iter(|| a.mat_mul(&b));
}

#[cfg(feature = "rblas")]
#[bench]
fn bench_mat_mul_rblas_large(bench: &mut test::Bencher)
{
    use rblas::Gemm;
    use rblas::attribute::Transpose;
    use ndarray::blas::AsBlas;

    let mut a = OwnedArray::<f32, _>::zeros((64, 64));
    let mut b = OwnedArray::<f32, _>::zeros((64, 64));
    let mut c = OwnedArray::<f32, _>::zeros((64, 64));
    bench.iter(|| {
        // C ← α AB + β C
        f32::gemm(&1.,
                  Transpose::NoTrans, &a.blas(),
                  Transpose::NoTrans, &b.blas(),
                  &1., &mut c.blas());
    });
}

#[bench]
fn bench_create_iter(bench: &mut test::Bencher)
{
    let a = arr2(&[[1., 2., 2.],
                   [3., 4., 4.],
                   [3., 4., 4.],
                   [3., 4., 4.],
                   [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    let v = black_box(at.view());

    bench.iter(|| {
        let v = black_box(v);
        v.into_iter()
    });
}

#[bench]
fn lst_squares(bench: &mut test::Bencher)
{
    let xs = arr2::<f32, _>(&[[ 2.,  3.],
                           [-2., -1.],
                           [ 1.,  5.],
                           [-1.,  2.]]);
    let b = arr1(&[1., -1., 2., 1.]);
    bench.iter(|| ndarray::linalg::least_squares(&xs, &b));
}

#[bench]
fn bench_to_owned_n(bench: &mut test::Bencher)
{
    let a = zeros::<f32, _>((32, 32));
    bench.iter(|| a.to_owned());
}

#[bench]
fn bench_to_owned_t(bench: &mut test::Bencher)
{
    let mut a = zeros::<f32, _>((32, 32));
    a.swap_axes(0, 1);
    bench.iter(|| a.to_owned());
}
<commit_msg>Rename benchmarks<commit_after>#![feature(test)]
#![allow(unused_imports)]

extern crate test;
#[macro_use(s)]
extern crate ndarray;
#[cfg(feature = "rblas")]
extern crate rblas;
#[cfg(feature = "rblas")]
use rblas::matrix::Matrix;

use ndarray::{
    OwnedArray,
    zeros,
};
use ndarray::{arr0, arr1, arr2};

use test::black_box;

#[bench]
fn bench_std_add_shared(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn bench_std_add_owned(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    let mut a = a.to_owned();
    let b = a.clone();
    bench.iter(|| a.iadd(&b));
}

#[bench]
fn small_iter_1d(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn small_iter_1d_raw(bench: &mut test::Bencher)
{
    let a = arr1::<f32>(&[1., 2., 2.,
                         3., 4., 4.,
                         3., 4., 4.,
                         3., 4., 4.,
                         5., 6., 6.]);
    bench.iter(|| for &elt in a.raw_data().iter() { black_box(elt); })
}

#[bench]
fn small_iter_2d(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    bench.iter(|| for &elt in a.iter() { black_box(elt); })
}

#[bench]
fn sum_1d_regular(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_1d_raw(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = OwnedArray::<i32, _>::zeros(64 * 64);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_2d_regular(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_2d_by_row(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for row in a.outer_iter() {
            for &elt in row {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn sum_2d_raw(bench: &mut test::Bencher)
{
    // this is autovectorized to death (= great performance)
    let a = OwnedArray::<i32, _>::zeros((64, 64));
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.raw_data() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_2d_cutout(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_2d_cutout_fold(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        a.fold(0, |acc, elt| acc + *elt)
    });
}

#[bench]
fn sum_2d_cutout_by_row(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for row in 0..a.shape()[0] {
            for &elt in a.row_iter(row) {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn sum_2d_cutout_outer_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<i32, _>::zeros((66, 66));
    let av = a.view().slice(s![1..-1, 1..-1]);
    let a = black_box(av);
    bench.iter(|| {
        let mut sum = 0;
        for row in a.outer_iter() {
            for &elt in row {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn sum_2d_transpose_regular(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::<i32, _>::zeros((64, 64));
    a.swap_axes(0, 1);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for &elt in a.iter() {
            sum += elt;
        }
        sum
    });
}

#[bench]
fn sum_2d_transpose_by_row(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::<i32, _>::zeros((64, 64));
    a.swap_axes(0, 1);
    let a = black_box(a);
    bench.iter(|| {
        let mut sum = 0;
        for row in 0..a.shape()[0] {
            for &elt in a.row_iter(row) {
                sum += elt;
            }
        }
        sum
    });
}

#[bench]
fn assign_scalar_2d_transposed(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    a.swap_axes(0, 1);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d(bench: &mut test::Bencher)
{
    let mut a = arr2::<f32, _>(&[[1., 2., 2.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [3., 4., 4.],
                              [5., 6., 6.]]);
    bench.iter(|| a.assign_scalar(&3.))
}

#[bench]
fn assign_scalar_2d_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::zeros((64, 64));
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_cutout(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::zeros((66, 66));
    let mut a = a.slice_mut(s![1..-1, 1..-1]);
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_transposed_large(bench: &mut test::Bencher)
{
    let mut a = OwnedArray::zeros((64, 64));
    a.swap_axes(0, 1);
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| a.assign_scalar(&s))
}

#[bench]
fn assign_scalar_2d_raw_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::zeros((64, 64));
    let mut a = black_box(a);
    let s = 3.;
    bench.iter(|| for elt in a.raw_data_mut() { *elt = s; });
}

#[bench]
fn bench_iter_diag(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    bench.iter(|| for elt in a.diag_iter() { black_box(elt); })
}

#[bench]
fn bench_row_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    let it = a.row_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_col_iter(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((1024, 1024));
    let it = a.col_iter(17);
    bench.iter(|| for elt in it.clone() { black_box(elt); })
}

#[bench]
fn bench_mat_mul(bench: &mut test::Bencher)
{
    let a = arr2::<f32, _>(&[[1., 2., 2.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [3., 4., 4.],
                          [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    bench.iter(|| at.mat_mul(&a));
}

#[bench]
fn bench_mat_mul_large(bench: &mut test::Bencher)
{
    let a = OwnedArray::<f32, _>::zeros((64, 64));
    let b = OwnedArray::<f32, _>::zeros((64, 64));
    let a = black_box(a.view());
    let b = black_box(b.view());
    bench.iter(|| a.mat_mul(&b));
}

#[cfg(feature = "rblas")]
#[bench]
fn bench_mat_mul_rblas_large(bench: &mut test::Bencher)
{
    use rblas::Gemm;
    use rblas::attribute::Transpose;
    use ndarray::blas::AsBlas;

    let mut a = OwnedArray::<f32, _>::zeros((64, 64));
    let mut b = OwnedArray::<f32, _>::zeros((64, 64));
    let mut c = OwnedArray::<f32, _>::zeros((64, 64));
    bench.iter(|| {
        // C ← α AB + β C
        f32::gemm(&1.,
                  Transpose::NoTrans, &a.blas(),
                  Transpose::NoTrans, &b.blas(),
                  &1., &mut c.blas());
    });
}

#[bench]
fn bench_create_iter(bench: &mut test::Bencher)
{
    let a = arr2(&[[1., 2., 2.],
                   [3., 4., 4.],
                   [3., 4., 4.],
                   [3., 4., 4.],
                   [5., 6., 6.]]);
    let mut at = a.clone();
    at.swap_axes(0, 1);
    let v = black_box(at.view());

    bench.iter(|| {
        let v = black_box(v);
        v.into_iter()
    });
}

#[bench]
fn lst_squares(bench: &mut test::Bencher)
{
    let xs = arr2::<f32, _>(&[[ 2.,  3.],
                           [-2., -1.],
                           [ 1.,  5.],
                           [-1.,  2.]]);
    let b = arr1(&[1., -1., 2., 1.]);
    bench.iter(|| ndarray::linalg::least_squares(&xs, &b));
}

#[bench]
fn bench_to_owned_n(bench: &mut test::Bencher)
{
    let a = zeros::<f32, _>((32, 32));
    bench.iter(|| a.to_owned());
}

#[bench]
fn bench_to_owned_t(bench: &mut test::Bencher)
{
    let mut a = zeros::<f32, _>((32, 32));
    a.swap_axes(0, 1);
    bench.iter(|| a.to_owned());
}
<|endoftext|>


<commit_before>use errors::crypto::CryptoError;

#[derive(Copy, Clone)]
pub struct PointG1 {}

pub struct PointG2 {}

#[derive(Copy, Clone)]
pub struct GroupOrderElement {}

pub struct Pair {}

impl PointG1 {
    pub fn new() -> Result<PointG1, CryptoError> {
        // generate random point from the group G1
        unimplemented!();
    }

    pub fn new_inf() -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn mul(&self, gr: &GroupOrderElement) -> Result<PointG1, CryptoError> {
        unimplemented!();
    }

    pub fn add(&self, q: &PointG1) -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn sub(&self, q: &PointG1) -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<PointG1, CryptoError> {
        unimplemented!();
    }
}

impl GroupOrderElement {
    pub fn new() -> Result<GroupOrderElement, CryptoError> {
        // returns random element in 0, ..., GroupOrder-1
        unimplemented!();
    }

    pub fn pow_mod(&self, e: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        // need to use powmod where n - group_order
        unimplemented!();
    }

    pub fn add_mod(&self, r: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        //need to use rmod after add
        unimplemented!()
    }

    pub fn mul_mod(&self, r: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        // use modmul where n - group_order
        unimplemented!();
    }

    pub fn inverse(&self) -> Result<GroupOrderElement, CryptoError> {
        unimplemented!();
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<GroupOrderElement, CryptoError> {
        unimplemented!();
    }
}

impl Pair {
    pub fn pair(p: &PointG1, q: &PointG1) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn mul(&self, b: &Pair) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn pow(&self, b: &GroupOrderElement) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn inverse(&self) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<Pair, CryptoError> {
        unimplemented!();
    }
}<commit_msg>added mod_neg<commit_after>use errors::crypto::CryptoError;

#[derive(Copy, Clone)]
pub struct PointG1 {}

pub struct PointG2 {}

#[derive(Copy, Clone)]
pub struct GroupOrderElement {}

pub struct Pair {}

impl PointG1 {
    pub fn new() -> Result<PointG1, CryptoError> {
        // generate random point from the group G1
        unimplemented!();
    }

    pub fn new_inf() -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn mul(&self, gr: &GroupOrderElement) -> Result<PointG1, CryptoError> {
        unimplemented!();
    }

    pub fn add(&self, q: &PointG1) -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn sub(&self, q: &PointG1) -> Result<PointG1, CryptoError> {
        unimplemented!()
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<PointG1, CryptoError> {
        unimplemented!();
    }
}

impl GroupOrderElement {
    pub fn new() -> Result<GroupOrderElement, CryptoError> {
        // returns random element in 0, ..., GroupOrder-1
        unimplemented!();
    }

    pub fn pow_mod(&self, e: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        // need to use powmod where n - group_order
        unimplemented!();
    }

    pub fn add_mod(&self, r: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        //need to use rmod after add
        unimplemented!()
    }

    pub fn mul_mod(&self, r: &GroupOrderElement) -> Result<GroupOrderElement, CryptoError> {
        // use modmul where n - group_order
        unimplemented!();
    }

    pub fn inverse(&self) -> Result<GroupOrderElement, CryptoError> {
        unimplemented!();
    }

    pub fn mod_neg(&self) -> Result<GroupOrderElement, CryptoError> {
        unimplemented!();
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<GroupOrderElement, CryptoError> {
        unimplemented!();
    }
}

impl Pair {
    pub fn pair(p: &PointG1, q: &PointG1) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn mul(&self, b: &Pair) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn pow(&self, b: &GroupOrderElement) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn inverse(&self) -> Result<Pair, CryptoError> {
        unimplemented!();
    }

    pub fn to_string(&self) -> Result<String, CryptoError> {
        unimplemented!();
    }

    pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError> {
        unimplemented!();
    }

    pub fn from_bytes(b: &[u8]) -> Result<Pair, CryptoError> {
        unimplemented!();
    }
}<|endoftext|>


<commit_before>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate clap;
extern crate futures;
extern crate point_viewer_grpc;

use futures::{Future};
use futures::sync::oneshot;
use std::{io, thread};
use std::io::Read;
use std::path::PathBuf;

use point_viewer_grpc::service::{start_grpc_server};

fn main() {
    let matches = clap::App::new("octree_server")
        .args(&[
            clap::Arg::with_name("port")
                .help("Port to listen on for connections. [50051]")
                .long("port")
                .takes_value(true),
            clap::Arg::with_name("octree_directory")
                .help("Input directory of the octree directory to serve.")
                .index(1)
                .required(true),
        ])
        .get_matches();

    let port = value_t!(matches, "port", u16).unwrap_or(50051);
    let octree_directory = PathBuf::from(matches.value_of("octree_directory").unwrap());
    let mut server = start_grpc_server(octree_directory, "0.0.0.0", port);

    for &(ref host, port) in server.bind_addrs() {
        println!("listening on {}:{}", host, port);
    }
    let (tx, rx) = oneshot::channel();
    thread::spawn(move || {
        println!("Press ENTER to exit...");
        let _ = io::stdin().read(&mut [0]).unwrap();
        tx.send(())
    });
    let _ = rx.wait();
    let _ = server.shutdown().wait();
}
<commit_msg>Fix octree server. It was not reacting to requests. (#168)<commit_after>// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[macro_use]
extern crate clap;
extern crate futures;
extern crate point_viewer_grpc;

use futures::{Future};
use futures::sync::oneshot;
use std::{io, thread};
use std::io::Read;
use std::path::PathBuf;

use point_viewer_grpc::service::{start_grpc_server};

fn main() {
    let matches = clap::App::new("octree_server")
        .args(&[
            clap::Arg::with_name("port")
                .help("Port to listen on for connections. [50051]")
                .long("port")
                .takes_value(true),
            clap::Arg::with_name("octree_directory")
                .help("Input directory of the octree directory to serve.")
                .index(1)
                .required(true),
        ])
        .get_matches();

    let port = value_t!(matches, "port", u16).unwrap_or(50051);
    let octree_directory = PathBuf::from(matches.value_of("octree_directory").unwrap());
    let mut server = start_grpc_server(octree_directory, "0.0.0.0", port);
    server.start();

    for &(ref host, port) in server.bind_addrs() {
        println!("listening on {}:{}", host, port);
    }
    let (tx, rx) = oneshot::channel();
    thread::spawn(move || {
        println!("Press ENTER to exit...");
        let _ = io::stdin().read(&mut [0]).unwrap();
        tx.send(())
    });
    let _ = rx.wait();
    let _ = server.shutdown().wait();
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! Main loop

use std::{cell::RefCell, os::unix::io::AsRawFd, rc::Rc};

use nix::sys::signalfd::{signal, SfdFlags, SigSet, SignalFd};

use crate::{
    engine::{Engine, SimEngine, StratEngine},
    stratis::{
        dbus_support::MaybeDbusSupport,
        errors::{StratisError, StratisResult},
        stratis::VERSION,
        udev_monitor::UdevMonitor,
    },
};

// Process any pending signals, return true if SIGINT received.
// Return an error if there was an error reading the signal.
fn process_signal(sfd: &mut SignalFd) -> StratisResult<bool> {
    match sfd.read_signal() {
        // This is an unsafe conversion, but in this context that is
        // mostly harmless. A negative converted value, which is
        // virtually impossible, will not match any of the masked
        // values, and stratisd will panic and exit.
        Ok(Some(sig)) => match sig.ssi_signo as i32 {
            nix::libc::SIGINT => {
                info!("SIGINT received, exiting");
                Ok(true)
            }
            signo => {
                panic!("Caught an impossible signal {:?}", signo);
            }
        },
        // No signals waiting (SFD_NONBLOCK flag is set)
        Ok(None) => Ok(false),

        Err(err) => Err(err.into()),
    }
}

/// Handle blocking the event loop
fn process_poll(poll_timeout: i32, fds: &mut Vec<libc::pollfd>) -> StratisResult<()> {
    let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::c_ulong, poll_timeout) };

    // TODO: refine this behavior.
    // Different behaviors may be indicated, depending on the value of
    // errno when return value is -1.
    if r < 0 {
        return Err(StratisError::Error(format!(
            "poll command failed: number of fds: {}, timeout: {}",
            fds.len(),
            poll_timeout
        )));
    }
    Ok(())
}

/// Set up all sorts of signal and event handling mechanisms.
/// Initialize the engine and keep it running until a signal is received
/// or a fatal error is encountered. Dump log entries on specified signal
/// via buff_log.
/// If sim is true, start the sim engine rather than the real engine.
pub fn run(sim: bool) -> StratisResult<()> {
    let mut dbus_support = MaybeDbusSupport::new();

    // Setup a udev listener before initializing the engine. A device may
    // appear after the engine has processed the udev db, but before it has
    // completed initialization. Unless the udev event has been recorded, the
    // engine will miss the device.
    // This is especially important since stratisd must run during early boot.
    let context = libudev::Context::new()?;
    let mut udev_monitor = UdevMonitor::create(&context)?;

    let engine: Rc<RefCell<dyn Engine>> = {
        info!("stratis daemon version {} started", VERSION);
        if sim {
            info!("Using SimEngine");
            Rc::new(RefCell::new(SimEngine::default()))
        } else {
            info!("Using StratEngine");
            Rc::new(RefCell::new(StratEngine::initialize()?))
        }
    };

    /*
    The file descriptor array indexes are:

    0   == Always udev fd index
    1   == SIGNAL FD index
    2   == engine index if eventable
    2/3 == Start of dbus client file descriptor(s)
            * 2 if engine is not eventable
            * else 3
    */
    const FD_INDEX_UDEV: usize = 0;
    const FD_INDEX_SIGNALFD: usize = 1;
    const FD_INDEX_ENGINE: usize = 2;

    /*
    fds is a Vec of libc::pollfd structs. Ideally, it would be possible
    to use the higher level nix crate to handle polling. If this were possible,
    then the Vec would be one of nix::poll::PollFds and this would be more
    rustic. Unfortunately, the rust D-Bus library requires an explicit file
    descriptor to be passed as an argument to Connection::watch_handle(),
    and the explicit file descriptor can not be extracted from the PollFd
    struct. So, at this time, sticking with libc is less complex than
    converting to using nix, because if using nix, the file descriptor would
    have to be maintained in the Vec as well as the PollFd struct.
    */
    let mut fds = Vec::new();

    fds.push(libc::pollfd {
        fd: udev_monitor.as_raw_fd(),
        revents: 0,
        events: libc::POLLIN,
    });

    // Signals can be queued up on this file descriptor
    let mut sfd = {
        let mut mask = SigSet::empty();
        mask.add(signal::SIGINT);
        mask.add(signal::SIGUSR1);
        mask.thread_block()?;
        SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK)?
    };

    fds.push(libc::pollfd {
        fd: sfd.as_raw_fd(),
        revents: 0,
        events: libc::POLLIN,
    });

    let eventable = engine.borrow().get_eventable();

    if let Some(evt) = eventable {
        fds.push(libc::pollfd {
            fd: evt.get_pollable_fd(),
            revents: 0,
            events: libc::POLLIN,
        });
    };

    let dbus_client_index_start = if eventable.is_some() {
        FD_INDEX_ENGINE + 1
    } else {
        FD_INDEX_ENGINE
    };

    loop {
        if fds[FD_INDEX_UDEV].revents != 0 {
            udev_monitor.handle_events(&mut *engine.borrow_mut(), &mut dbus_support)
        }

        if fds[FD_INDEX_SIGNALFD].revents != 0 {
            match process_signal(&mut sfd) {
                Ok(should_exit) => {
                    if should_exit {
                        return Ok(());
                    }
                }
                Err(e) => return Err(e),
            }
        }

        if let Some(evt) = eventable {
            if fds[FD_INDEX_ENGINE].revents != 0 {
                evt.clear_event()?;
                engine.borrow_mut().evented()?;
            }
        }

        dbus_support.process(&engine, &mut fds, dbus_client_index_start);

        process_poll(dbus_support.poll_timeout(), &mut fds)?;
    }
}
<commit_msg>Remove mask for SIGUSR1<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! Main loop

use std::{cell::RefCell, os::unix::io::AsRawFd, rc::Rc};

use nix::sys::signalfd::{signal, SfdFlags, SigSet, SignalFd};

use crate::{
    engine::{Engine, SimEngine, StratEngine},
    stratis::{
        dbus_support::MaybeDbusSupport,
        errors::{StratisError, StratisResult},
        stratis::VERSION,
        udev_monitor::UdevMonitor,
    },
};

// Process any pending signals, return true if SIGINT received.
// Return an error if there was an error reading the signal.
fn process_signal(sfd: &mut SignalFd) -> StratisResult<bool> {
    match sfd.read_signal() {
        // This is an unsafe conversion, but in this context that is
        // mostly harmless. A negative converted value, which is
        // virtually impossible, will not match any of the masked
        // values, and stratisd will panic and exit.
        Ok(Some(sig)) => match sig.ssi_signo as i32 {
            nix::libc::SIGINT => {
                info!("SIGINT received, exiting");
                Ok(true)
            }
            signo => {
                panic!("Caught an impossible signal {:?}", signo);
            }
        },
        // No signals waiting (SFD_NONBLOCK flag is set)
        Ok(None) => Ok(false),

        Err(err) => Err(err.into()),
    }
}

/// Handle blocking the event loop
fn process_poll(poll_timeout: i32, fds: &mut Vec<libc::pollfd>) -> StratisResult<()> {
    let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::c_ulong, poll_timeout) };

    // TODO: refine this behavior.
    // Different behaviors may be indicated, depending on the value of
    // errno when return value is -1.
    if r < 0 {
        return Err(StratisError::Error(format!(
            "poll command failed: number of fds: {}, timeout: {}",
            fds.len(),
            poll_timeout
        )));
    }
    Ok(())
}

/// Set up all sorts of signal and event handling mechanisms.
/// Initialize the engine and keep it running until a signal is received
/// or a fatal error is encountered. Dump log entries on specified signal
/// via buff_log.
/// If sim is true, start the sim engine rather than the real engine.
pub fn run(sim: bool) -> StratisResult<()> {
    let mut dbus_support = MaybeDbusSupport::new();

    // Setup a udev listener before initializing the engine. A device may
    // appear after the engine has processed the udev db, but before it has
    // completed initialization. Unless the udev event has been recorded, the
    // engine will miss the device.
    // This is especially important since stratisd must run during early boot.
    let context = libudev::Context::new()?;
    let mut udev_monitor = UdevMonitor::create(&context)?;

    let engine: Rc<RefCell<dyn Engine>> = {
        info!("stratis daemon version {} started", VERSION);
        if sim {
            info!("Using SimEngine");
            Rc::new(RefCell::new(SimEngine::default()))
        } else {
            info!("Using StratEngine");
            Rc::new(RefCell::new(StratEngine::initialize()?))
        }
    };

    /*
    The file descriptor array indexes are:

    0   == Always udev fd index
    1   == SIGNAL FD index
    2   == engine index if eventable
    2/3 == Start of dbus client file descriptor(s)
            * 2 if engine is not eventable
            * else 3
    */
    const FD_INDEX_UDEV: usize = 0;
    const FD_INDEX_SIGNALFD: usize = 1;
    const FD_INDEX_ENGINE: usize = 2;

    /*
    fds is a Vec of libc::pollfd structs. Ideally, it would be possible
    to use the higher level nix crate to handle polling. If this were possible,
    then the Vec would be one of nix::poll::PollFds and this would be more
    rustic. Unfortunately, the rust D-Bus library requires an explicit file
    descriptor to be passed as an argument to Connection::watch_handle(),
    and the explicit file descriptor can not be extracted from the PollFd
    struct. So, at this time, sticking with libc is less complex than
    converting to using nix, because if using nix, the file descriptor would
    have to be maintained in the Vec as well as the PollFd struct.
    */
    let mut fds = Vec::new();

    fds.push(libc::pollfd {
        fd: udev_monitor.as_raw_fd(),
        revents: 0,
        events: libc::POLLIN,
    });

    // Signals can be queued up on this file descriptor
    let mut sfd = {
        let mut mask = SigSet::empty();
        mask.add(signal::SIGINT);
        mask.thread_block()?;
        SignalFd::with_flags(&mask, SfdFlags::SFD_NONBLOCK)?
    };

    fds.push(libc::pollfd {
        fd: sfd.as_raw_fd(),
        revents: 0,
        events: libc::POLLIN,
    });

    let eventable = engine.borrow().get_eventable();

    if let Some(evt) = eventable {
        fds.push(libc::pollfd {
            fd: evt.get_pollable_fd(),
            revents: 0,
            events: libc::POLLIN,
        });
    };

    let dbus_client_index_start = if eventable.is_some() {
        FD_INDEX_ENGINE + 1
    } else {
        FD_INDEX_ENGINE
    };

    loop {
        if fds[FD_INDEX_UDEV].revents != 0 {
            udev_monitor.handle_events(&mut *engine.borrow_mut(), &mut dbus_support)
        }

        if fds[FD_INDEX_SIGNALFD].revents != 0 {
            match process_signal(&mut sfd) {
                Ok(should_exit) => {
                    if should_exit {
                        return Ok(());
                    }
                }
                Err(e) => return Err(e),
            }
        }

        if let Some(evt) = eventable {
            if fds[FD_INDEX_ENGINE].revents != 0 {
                evt.clear_event()?;
                engine.borrow_mut().evented()?;
            }
        }

        dbus_support.process(&engine, &mut fds, dbus_client_index_start);

        process_poll(dbus_support.poll_timeout(), &mut fds)?;
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

trait Wrap<'b> {
    fn foo(&'b mut self);
}

struct Wrapper<P>(P);

impl<'b, P> Wrap<'b> for Wrapper<P>
where P: Process<'b>,
      <P as Process<'b>>::Item: Iterator {
    fn foo(&mut self) {}
}

pub trait Process<'a> {
    type Item;
    fn bar(&'a self);
}

fn push_process<P>(process: P) where P: Process<'static> {
    let _: Box<for<'b> Wrap<'b>> = Box::new(Wrapper(process));
    //~^ ERROR the trait `for<'b> Process<'b>` is not implemented for the type `P` [E0277]
    //~| ERROR the trait `for<'b> core::iter::Iterator` is not implemented for the type
    //~| ERROR cannot infer an appropriate lifetime for lifetime parameter `'b` due to conflicting
}

fn main() {}
<commit_msg>Remove incorrect test for #22872<commit_after><|endoftext|>