<commit_before>//! Intermediate representation for C/C++ functions and methods.

use super::context::BindgenContext;
use super::item::{Item, ItemId};
use super::ty::TypeKind;
use super::type_collector::{ItemSet, TypeCollector};
use syntax::abi;
use clang;
use clangll::Enum_CXCallingConv;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};

/// A function declaration, with a signature, arguments, and argument names.
///
/// The argument names vector must be the same length as the ones in the
/// signature.
#[derive(Debug)]
pub struct Function {
    /// The name of this function.
    name: String,

    /// The mangled name, that is, the symbol.
    mangled_name: Option<String>,

    /// The id pointing to the current function signature.
    signature: ItemId,

    /// The doc comment on the function, if any.
    comment: Option<String>,
}

impl Function {
    /// Construct a new function.
    pub fn new(name: String,
               mangled_name: Option<String>,
               sig: ItemId,
               comment: Option<String>) -> Self {
        Function {
            name: name,
            mangled_name: mangled_name,
            signature: sig,
            comment: comment,
        }
    }

    /// Get this function's name.
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Get this function's name.
    pub fn mangled_name(&self) -> Option<&str> {
        self.mangled_name.as_ref().map(|n| &**n)
    }

    /// Get this function's signature.
    pub fn signature(&self) -> ItemId {
        self.signature
    }
}

/// A function signature.
#[derive(Debug)]
pub struct FunctionSig {
    /// The return type of the function.
    return_type: ItemId,

    /// The type of the arguments, optionally with the name of the argument when
    /// declared.
    argument_types: Vec<(Option<String>, ItemId)>,

    /// Whether this function is variadic.
    is_variadic: bool,

    /// The ABI of this function.
    abi: abi::Abi,
}

fn get_abi(cc: Enum_CXCallingConv) -> abi::Abi {
    use clangll::*;
    match cc {
        CXCallingConv_Default => abi::Abi::C,
        CXCallingConv_C => abi::Abi::C,
        CXCallingConv_X86StdCall => abi::Abi::Stdcall,
        CXCallingConv_X86FastCall => abi::Abi::Fastcall,
        CXCallingConv_AAPCS => abi::Abi::Aapcs,
        CXCallingConv_X86_64Win64 => abi::Abi::Win64,
        other => panic!("unsupported calling convention: {}", other),
    }
}

/// Get the mangled name for the cursor's referent.
pub fn cursor_mangling(cursor: &clang::Cursor) -> Option<String> {
    // We early return here because libclang may crash in some case
    // if we pass in a variable inside a partial specialized template.
    // See servo/rust-bindgen#67.
    if cursor.is_in_non_fully_specialized_template() {
        return None;
    }

    let mut mangling = cursor.mangling();

    // Try to undo backend linkage munging (prepended _, generally)
    if cfg!(target_os = "macos") {
        mangling.remove(0);
    }

    if mangling.is_empty() { None } else { Some(mangling) }
}

impl FunctionSig {
    /// Construct a new function signature.
    pub fn new(return_type: ItemId,
               arguments: Vec<(Option<String>, ItemId)>,
               is_variadic: bool,
               abi: abi::Abi) -> Self {
        FunctionSig {
            return_type: return_type,
            argument_types: arguments,
            is_variadic: is_variadic,
            abi: abi,
        }
    }

    /// Construct a new function signature from the given Clang type.
    pub fn from_ty(ty: &clang::Type,
                   cursor: &clang::Cursor,
                   ctx: &mut BindgenContext) -> Result<Self, ParseError> {
        use clangll::*;
        debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor);

        // Don't parse operatorxx functions in C++
        let spelling = cursor.spelling();
        if spelling.starts_with("operator") {
            return Err(ParseError::Continue);
        }

        let cursor = if cursor.is_valid() {
            *cursor
        } else {
            ty.declaration()
        };
        let mut args: Vec<_> = match cursor.kind() {
            CXCursor_FunctionDecl |
            CXCursor_CXXMethod => {
                // For CXCursor_FunctionDecl, cursor.args() is the reliable way
                // to get parameter names and types.
                cursor.args().iter().map(|arg| {
                    let arg_ty = arg.cur_type();
                    let name = arg.spelling();
                    let name = if name.is_empty() { None } else { Some(name) };
                    let ty = Item::from_ty(&arg_ty, Some(*arg), None, ctx)
                                    .expect("Argument?");
                    (name, ty)
                }).collect()
            }
            _ => {
                // For non-CXCursor_FunctionDecl, visiting the cursor's children
                // is the only reliable way to get parameter names.
                let mut args = vec![];
                cursor.visit(|c, _| {
                    if c.kind() == CXCursor_ParmDecl {
                        let ty = Item::from_ty(&c.cur_type(), Some(*c), None, ctx)
                                    .expect("ParmDecl?");
                        let name = c.spelling();
                        let name = if name.is_empty() { None } else { Some(name) };
                        args.push((name, ty));
                    }
                    CXChildVisit_Continue
                });
                args
            }
        };

        if cursor.kind() == CXCursor_CXXMethod {
            let is_const = cursor.method_is_const();
            let is_virtual = cursor.method_is_virtual();
            let is_static = cursor.method_is_static();
            if !is_static && !is_virtual {
                let class = Item::parse(cursor.semantic_parent(), None, ctx)
                                .expect("Expected to parse the class");
                let ptr = Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
                args.insert(0, (Some("this".into()), ptr));
            } else if is_virtual {
                let void = Item::builtin_type(TypeKind::Void, false, ctx);
                let ptr = Item::builtin_type(TypeKind::Pointer(void), false, ctx);
                args.insert(0, (Some("this".into()), ptr));
            }
        }

        let ty_ret_type = try!(ty.ret_type().ok_or(ParseError::Continue));
        let ret = try!(Item::from_ty(&ty_ret_type, None, None, ctx));
        let abi = get_abi(ty.call_conv());

        Ok(Self::new(ret, args, ty.is_variadic(), abi))
    }

    /// Get this function signature's return type.
    pub fn return_type(&self) -> ItemId {
        self.return_type
    }

    /// Get this function signature's argument (name, type) pairs.
    pub fn argument_types(&self) -> &[(Option<String>, ItemId)] {
        &self.argument_types
    }

    /// Get this function signature's ABI.
    pub fn abi(&self) -> abi::Abi {
        self.abi
    }

    /// Is this function signature variadic?
    pub fn is_variadic(&self) -> bool {
        // Clang reports some functions as variadic when they *might* be
        // variadic. We do the argument check because rust doesn't codegen well
        // variadic functions without an initial argument.
        self.is_variadic && !self.argument_types.is_empty()
    }
}

impl ClangSubItemParser for Function {
    fn parse(cursor: clang::Cursor,
             context: &mut BindgenContext) -> Result<ParseResult<Self>, ParseError> {
        use clangll::*;
        match cursor.kind() {
            CXCursor_FunctionDecl |
            CXCursor_CXXMethod => {},
            _ => return Err(ParseError::Continue),
        };

        debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type());

        // Grab the signature using Item::from_ty.
        let sig = try!(Item::from_ty(&cursor.cur_type(), Some(cursor), None, context));

        let name = cursor.spelling();
        assert!(!name.is_empty(), "Empty function name?");

        let mut mangled_name = cursor_mangling(&cursor);
        if mangled_name.as_ref() == Some(&name) {
            mangled_name = None;
        }

        let comment = cursor.raw_comment();

        let function = Self::new(name, mangled_name, sig, comment);
        Ok(ParseResult::New(function, Some(cursor)))
    }
}

impl TypeCollector for FunctionSig {
    type Extra = Item;

    fn collect_types(&self,
                     context: &BindgenContext,
                     types: &mut ItemSet,
                     _item: &Item) {
        self.return_type().collect_types(context, types, &());

        for &(_, ty) in self.argument_types() {
            ty.collect_types(context, types, &());
        }
    }
}
<commit_msg>Fix empty mangling handling on OSX<commit_after>//! Intermediate representation for C/C++ functions and methods.

use super::context::BindgenContext;
use super::item::{Item, ItemId};
use super::ty::TypeKind;
use super::type_collector::{ItemSet, TypeCollector};
use syntax::abi;
use clang;
use clangll::Enum_CXCallingConv;
use parse::{ClangItemParser, ClangSubItemParser, ParseError, ParseResult};

/// A function declaration, with a signature, arguments, and argument names.
///
/// The argument names vector must be the same length as the ones in the
/// signature.
#[derive(Debug)]
pub struct Function {
    /// The name of this function.
    name: String,

    /// The mangled name, that is, the symbol.
    mangled_name: Option<String>,

    /// The id pointing to the current function signature.
    signature: ItemId,

    /// The doc comment on the function, if any.
    comment: Option<String>,
}

impl Function {
    /// Construct a new function.
    pub fn new(name: String,
               mangled_name: Option<String>,
               sig: ItemId,
               comment: Option<String>) -> Self {
        Function {
            name: name,
            mangled_name: mangled_name,
            signature: sig,
            comment: comment,
        }
    }

    /// Get this function's name.
    pub fn name(&self) -> &str {
        &self.name
    }

    /// Get this function's name.
    pub fn mangled_name(&self) -> Option<&str> {
        self.mangled_name.as_ref().map(|n| &**n)
    }

    /// Get this function's signature.
    pub fn signature(&self) -> ItemId {
        self.signature
    }
}

/// A function signature.
#[derive(Debug)]
pub struct FunctionSig {
    /// The return type of the function.
    return_type: ItemId,

    /// The type of the arguments, optionally with the name of the argument when
    /// declared.
    argument_types: Vec<(Option<String>, ItemId)>,

    /// Whether this function is variadic.
    is_variadic: bool,

    /// The ABI of this function.
    abi: abi::Abi,
}

fn get_abi(cc: Enum_CXCallingConv) -> abi::Abi {
    use clangll::*;
    match cc {
        CXCallingConv_Default => abi::Abi::C,
        CXCallingConv_C => abi::Abi::C,
        CXCallingConv_X86StdCall => abi::Abi::Stdcall,
        CXCallingConv_X86FastCall => abi::Abi::Fastcall,
        CXCallingConv_AAPCS => abi::Abi::Aapcs,
        CXCallingConv_X86_64Win64 => abi::Abi::Win64,
        other => panic!("unsupported calling convention: {}", other),
    }
}

/// Get the mangled name for the cursor's referent.
pub fn cursor_mangling(cursor: &clang::Cursor) -> Option<String> {
    // We early return here because libclang may crash in some case
    // if we pass in a variable inside a partial specialized template.
    // See servo/rust-bindgen#67.
    if cursor.is_in_non_fully_specialized_template() {
        return None;
    }

    let mut mangling = cursor.mangling();
    if mangling.is_empty() {
        return None;
    }

    // Try to undo backend linkage munging (prepended _, generally)
    if cfg!(target_os = "macos") {
        mangling.remove(0);
    }

    Some(mangling)
}

impl FunctionSig {
    /// Construct a new function signature.
    pub fn new(return_type: ItemId,
               arguments: Vec<(Option<String>, ItemId)>,
               is_variadic: bool,
               abi: abi::Abi) -> Self {
        FunctionSig {
            return_type: return_type,
            argument_types: arguments,
            is_variadic: is_variadic,
            abi: abi,
        }
    }

    /// Construct a new function signature from the given Clang type.
    pub fn from_ty(ty: &clang::Type,
                   cursor: &clang::Cursor,
                   ctx: &mut BindgenContext) -> Result<Self, ParseError> {
        use clangll::*;
        debug!("FunctionSig::from_ty {:?} {:?}", ty, cursor);

        // Don't parse operatorxx functions in C++
        let spelling = cursor.spelling();
        if spelling.starts_with("operator") {
            return Err(ParseError::Continue);
        }

        let cursor = if cursor.is_valid() {
            *cursor
        } else {
            ty.declaration()
        };
        let mut args: Vec<_> = match cursor.kind() {
            CXCursor_FunctionDecl |
            CXCursor_CXXMethod => {
                // For CXCursor_FunctionDecl, cursor.args() is the reliable way
                // to get parameter names and types.
                cursor.args().iter().map(|arg| {
                    let arg_ty = arg.cur_type();
                    let name = arg.spelling();
                    let name = if name.is_empty() { None } else { Some(name) };
                    let ty = Item::from_ty(&arg_ty, Some(*arg), None, ctx)
                                    .expect("Argument?");
                    (name, ty)
                }).collect()
            }
            _ => {
                // For non-CXCursor_FunctionDecl, visiting the cursor's children
                // is the only reliable way to get parameter names.
                let mut args = vec![];
                cursor.visit(|c, _| {
                    if c.kind() == CXCursor_ParmDecl {
                        let ty = Item::from_ty(&c.cur_type(), Some(*c), None, ctx)
                                    .expect("ParmDecl?");
                        let name = c.spelling();
                        let name = if name.is_empty() { None } else { Some(name) };
                        args.push((name, ty));
                    }
                    CXChildVisit_Continue
                });
                args
            }
        };

        if cursor.kind() == CXCursor_CXXMethod {
            let is_const = cursor.method_is_const();
            let is_virtual = cursor.method_is_virtual();
            let is_static = cursor.method_is_static();
            if !is_static && !is_virtual {
                let class = Item::parse(cursor.semantic_parent(), None, ctx)
                                .expect("Expected to parse the class");
                let ptr = Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
                args.insert(0, (Some("this".into()), ptr));
            } else if is_virtual {
                let void = Item::builtin_type(TypeKind::Void, false, ctx);
                let ptr = Item::builtin_type(TypeKind::Pointer(void), false, ctx);
                args.insert(0, (Some("this".into()), ptr));
            }
        }

        let ty_ret_type = try!(ty.ret_type().ok_or(ParseError::Continue));
        let ret = try!(Item::from_ty(&ty_ret_type, None, None, ctx));
        let abi = get_abi(ty.call_conv());

        Ok(Self::new(ret, args, ty.is_variadic(), abi))
    }

    /// Get this function signature's return type.
    pub fn return_type(&self) -> ItemId {
        self.return_type
    }

    /// Get this function signature's argument (name, type) pairs.
    pub fn argument_types(&self) -> &[(Option<String>, ItemId)] {
        &self.argument_types
    }

    /// Get this function signature's ABI.
    pub fn abi(&self) -> abi::Abi {
        self.abi
    }

    /// Is this function signature variadic?
    pub fn is_variadic(&self) -> bool {
        // Clang reports some functions as variadic when they *might* be
        // variadic. We do the argument check because rust doesn't codegen well
        // variadic functions without an initial argument.
        self.is_variadic && !self.argument_types.is_empty()
    }
}

impl ClangSubItemParser for Function {
    fn parse(cursor: clang::Cursor,
             context: &mut BindgenContext) -> Result<ParseResult<Self>, ParseError> {
        use clangll::*;
        match cursor.kind() {
            CXCursor_FunctionDecl |
            CXCursor_CXXMethod => {},
            _ => return Err(ParseError::Continue),
        };

        debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type());

        // Grab the signature using Item::from_ty.
        let sig = try!(Item::from_ty(&cursor.cur_type(), Some(cursor), None, context));

        let name = cursor.spelling();
        assert!(!name.is_empty(), "Empty function name?");

        let mut mangled_name = cursor_mangling(&cursor);
        if mangled_name.as_ref() == Some(&name) {
            mangled_name = None;
        }

        let comment = cursor.raw_comment();

        let function = Self::new(name, mangled_name, sig, comment);
        Ok(ParseResult::New(function, Some(cursor)))
    }
}

impl TypeCollector for FunctionSig {
    type Extra = Item;

    fn collect_types(&self,
                     context: &BindgenContext,
                     types: &mut ItemSet,
                     _item: &Item) {
        self.return_type().collect_types(context, types, &());

        for &(_, ty) in self.argument_types() {
            ty.collect_types(context, types, &());
        }
    }
}
<|endoftext|>


<commit_before>extern crate classfile;

mod hello_world;
mod point;
mod constants;
<commit_msg>Remove tests/lib.rs<commit_after><|endoftext|>


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

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene star (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    let mut result = Vec::new();
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }
            _ => result.push(tree),
        }
    }
    result
}

fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    match tree {
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }
            None => TokenTree::Token(span, token::Dollar),
        },
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _pattern_ itself, rather than trying to match some
/// stream of tokens against the pattern.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<commit_msg>Add a bunch of doc comments<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// thatthat the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    /// Return the opening delimiter (possibly `NoDelim`).
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    /// Return the closing delimiter (possibly `NoDelim`).
    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the opening delimiter.
    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the closing delimiter.
    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene star (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    /// Return the number of tokens in the tree.
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    /// Returns true if the given token tree contains no other tokens. This is vacuously true for
    /// single tokens or metavar/decls, but may be false for delimited trees or sequences.
    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    /// Get the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
/// collection of `TokenTree` for use in parsing a macro.
///
/// # Parameters
///
/// - `input`: a token stream to read from, the contents of which we are parsing.
/// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
///   macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
///   their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
///   `ident` are "matchers". They are not present in the body of a macro rule -- just in the
///   pattern, so we pass a parameter to indicate whether to expect them or not.
/// - `sess`: the parsing session. Any errors will be emitted to this session.
///
/// # Returns
///
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    // Will contain the final collection of `self::TokenTree`
    let mut result = Vec::new();

    // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
    // additional trees if need be.
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);

        // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }

            // Not a metavar or no matchers allowed, so just return the tree
            _ => result.push(tree),
        }
    }
    result
}

/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
/// for use in parsing a macro.
///
/// Converting the given tree may involve reading more tokens.
///
/// # Parameters
///
/// - `tree`: the tree wish to convert.
/// - `trees`: an iterator over trees. We may need to read more tokens from it in order to finish
///   converting `tree`
/// - `expect_matchers`: same as for `parse` (see above).
/// - `sess`: the parsing session. Any errors will be emitted to this session.
fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    // Depending on what `tree` is, we could be parsing different parts of a macro
    match tree {
        // `tree` is a `$` token. Look at the next token in `trees`
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            // `tree` is followed by a delimited set of token trees. This indicates the beginning
            // of a repetition sequence in the macro (e.g. `$(pat)*`).
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                // Must have `(` not `{` or `[`
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                // Parse the contents of the sequence itself
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                // Get the Kleen operator and optional separator
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                // Count the number of captured "names" (i.e. named metavars)
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }

            // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
            // metavariable that names the crate of the invokation.
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }

            // `tree` is followed by a random token. This is an error.
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }

            // There are no more tokens. Just return the `$` we already have.
            None => TokenTree::Token(span, token::Dollar),
        },

        // `tree` is an arbitrary token. Keep it.
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),

        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
        // descend into the delimited set and further parse it.
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _macro_ itself, rather than trying to match some
/// stream of tokens in an invokation of a macro.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<|endoftext|>


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

//! The Rust core library
//!
//! This library is meant to represent the core functionality of rust that is
//! maximally portable to other platforms. To that extent, this library has no
//! knowledge of things like allocation, threads, I/O, etc. This library is
//! built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by `librlibc` which is distributed with the standard rust
//!   distribution.
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `&fmt::Arguments`, a `&str`, and a `uint. These three arguments dictate
//!   the failure message, the file at which failure was invoked, and the line.
//!   It is up to consumers of this core library to define this failure
//!   function; it is only required to never return.
//!
//! Currently, it is *not* recommended to use the core library. The stable
//! functionality of libcore is exported directly into the
//! [standard library](../std/index.html). The composition of this library is
//! subject to change over time, only the interface exposed through libstd is
//! intended to be stable.

#![crate_id = "core#0.11.0-pre"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![no_std]
#![feature(globs, macro_rules, managed_boxes, phase)]
#![deny(missing_doc)]

#[cfg(test)] extern crate realcore = "core";
#[cfg(test)] extern crate libc;
#[cfg(test)] extern crate native;
#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate realstd = "std";

#[cfg(test)] pub use cmp = realcore::cmp;
#[cfg(test)] pub use kinds = realcore::kinds;
#[cfg(test)] pub use ops = realcore::ops;
#[cfg(test)] pub use ty = realcore::ty;

mod macros;

#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;

/* Core language traits */

#[cfg(not(test))] pub mod kinds;
#[cfg(not(test))] pub mod ops;
#[cfg(not(test))] pub mod ty;
#[cfg(not(test))] pub mod cmp;
pub mod clone;
pub mod default;
pub mod container;

/* Core types and methods on primitives */

mod unicode;
pub mod any;
pub mod atomics;
pub mod bool;
pub mod cell;
pub mod char;
pub mod failure;
pub mod finally;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod slice;
pub mod str;
pub mod tuple;
pub mod fmt;

// FIXME: this module should not exist. Once owned allocations are no longer a
//        language type, this module can move outside to the owned allocation
//        crate.
mod should_not_exist;

mod core {
    pub use failure;
}

mod std {
    pub use clone;
    pub use cmp;
    pub use kinds;
    pub use option;
    pub use fmt;

    #[cfg(test)] pub use realstd::rt;     // needed for fail!()
    // #[cfg(test)] pub use realstd::option; // needed for fail!()
    // #[cfg(test)] pub use realstd::fmt;    // needed for fail!()
    #[cfg(test)] pub use realstd::os;     // needed for tests
    #[cfg(test)] pub use realstd::slice;  // needed for tests
    #[cfg(test)] pub use realstd::vec;    // needed for vec![]
}
<commit_msg>core: Spruce up the crate description<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! The Rust Core Library
//!
//! The Rust Core Library is the dependency-free foundation of [The
//! Rust Standard Library](../std/index.html). It is the portable glue
//! between the language and its libraries, defining the intrinsic and
//! primitive building blocks of all Rust code. It links to no
//! upstream libraries, no system libraries, no libc.
//!
//! The core library is *minimal*: it isn't even aware of heap allocation,
//! nor does it provide concurrency or I/O. These things require
//! platform integration, and this library is platform-oblivious.
//!
//! *It is not recommended to use the core library*. The stable
//! functionality of libcore is reexported from the
//! [standard library](../std/index.html). The composition of this library is
//! subject to change over time; only the interface exposed through libstd is
//! intended to be stable.
//!
//! # How to use the core library
//!
// TODO: Fill me in with more detail when the interface settles
//! This library is built on the assumption of a few existing symbols:
//!
//! * `memcpy`, `memcmp`, `memset` - These are core memory routines which are
//!   often generated by LLVM. Additionally, this library can make explicit
//!   calls to these functions. Their signatures are the same as found in C.
//!   These functions are often provided by the system libc, but can also be
//!   provided by `librlibc` which is distributed with the standard rust
//!   distribution.
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
//!   `&fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
//!   the failure message, the file at which failure was invoked, and the line.
//!   It is up to consumers of this core library to define this failure
//!   function; it is only required to never return.
//!

#![crate_id = "core#0.11.0-pre"]
#![license = "MIT/ASL2"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://static.rust-lang.org/doc/master")]

#![no_std]
#![feature(globs, macro_rules, managed_boxes, phase)]
#![deny(missing_doc)]

#[cfg(test)] extern crate realcore = "core";
#[cfg(test)] extern crate libc;
#[cfg(test)] extern crate native;
#[cfg(test)] extern crate rand;
#[cfg(test)] extern crate realstd = "std";

#[cfg(test)] pub use cmp = realcore::cmp;
#[cfg(test)] pub use kinds = realcore::kinds;
#[cfg(test)] pub use ops = realcore::ops;
#[cfg(test)] pub use ty = realcore::ty;

mod macros;

#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod num;

/* The libcore prelude, not as all-encompassing as the libstd prelude */

pub mod prelude;

/* Core modules for ownership management */

pub mod intrinsics;
pub mod mem;
pub mod ptr;

/* Core language traits */

#[cfg(not(test))] pub mod kinds;
#[cfg(not(test))] pub mod ops;
#[cfg(not(test))] pub mod ty;
#[cfg(not(test))] pub mod cmp;
pub mod clone;
pub mod default;
pub mod container;

/* Core types and methods on primitives */

mod unicode;
pub mod any;
pub mod atomics;
pub mod bool;
pub mod cell;
pub mod char;
pub mod failure;
pub mod finally;
pub mod iter;
pub mod option;
pub mod raw;
pub mod result;
pub mod slice;
pub mod str;
pub mod tuple;
pub mod fmt;

// FIXME: this module should not exist. Once owned allocations are no longer a
//        language type, this module can move outside to the owned allocation
//        crate.
mod should_not_exist;

mod core {
    pub use failure;
}

mod std {
    pub use clone;
    pub use cmp;
    pub use kinds;
    pub use option;
    pub use fmt;

    #[cfg(test)] pub use realstd::rt;     // needed for fail!()
    // #[cfg(test)] pub use realstd::option; // needed for fail!()
    // #[cfg(test)] pub use realstd::fmt;    // needed for fail!()
    #[cfg(test)] pub use realstd::os;     // needed for tests
    #[cfg(test)] pub use realstd::slice;  // needed for tests
    #[cfg(test)] pub use realstd::vec;    // needed for vec![]
}
<|endoftext|>


<commit_before>use std::fmt;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum State {
    Alive,
    Dead,
}

impl PartialEq for State {
    fn eq(&self, p: &State) -> bool {
        match *self {
            State::Alive => match *p { State::Alive => true, _ => false },
            State::Dead  => match *p { State::Dead  => true, _ => false },
        }
    }
}

impl State {
    fn to_string(&self) -> String {
        match *self {
            State::Alive => "alive",
            State::Dead  => "dead",
        }.to_string()
    }
    pub fn new(str: String) -> State {
        match str.as_ref() {
            "alive" => State::Alive,
            "dead"  => State::Dead,
            _       => State::Dead,
        }
    }
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}
<commit_msg>Serialize lower case for State<commit_after>use std::fmt;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum State {
    #[serde(rename = "alive")]
    Alive,
    #[serde(rename = "dead")]
    Dead,
}

impl PartialEq for State {
    fn eq(&self, p: &State) -> bool {
        match *self {
            State::Alive => match *p { State::Alive => true, _ => false },
            State::Dead  => match *p { State::Dead  => true, _ => false },
        }
    }
}

impl State {
    fn to_string(&self) -> String {
        match *self {
            State::Alive => "alive",
            State::Dead  => "dead",
        }.to_string()
    }
    pub fn new(str: String) -> State {
        match str.as_ref() {
            "alive" => State::Alive,
            "dead"  => State::Dead,
            _       => State::Dead,
        }
    }
}

impl fmt::Display for State {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.to_string())
    }
}
<|endoftext|>


<commit_before>use node::{ Expr };
use parser::{ Parse, Context };
use { Token };
use Result;
use Error;
use error::ErrorMessage;

impl<'a, 'code> Parse<'code> for Expr<'a> {
    type Output = Expr<'code>;

    fn parse<'r, I>(parser: &mut Context<'r, I>)
        -> Result<Expr<'code>>
    where
        I: Iterator<Item=Result<Token<'code>>>
    {
        println!("parse");
        parse_with_precedence_0(parser)
    }
}

fn parse_with_precedence_0<'r, 'c, I>(parser: &mut Context<'r, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_with_precedence_0");
    parse_primary(parser)
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_primary<'r, 'c, I>(parser: &mut Context<'r, I>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    let token = match parser.tokens.next() {
        Some(Ok(t)) => t,
        None => return Err(Error::new(ErrorMessage::UnexpectedEndOfTemplate)),
        Some(Err(e)) => return Err(e),
    };

    println!("parse_primary");
    Ok(Expr::Constant { value: "", line: 1 })
}
<commit_msg>Always pass first token to parser functions.<commit_after>use node::{ Expr };
use parser::{ Parse, Context };
use { Token, TokenValue };
use token::{ OperatorKind };
use Result;
use Error;
use error::ErrorMessage;

impl<'a, 'code> Parse<'code> for Expr<'a> {
    type Output = Expr<'code>;

    fn parse<'r, I>(parser: &mut Context<'r, I>)
        -> Result<Expr<'code>>
    where
        I: Iterator<Item=Result<Token<'code>>>
    {
        let token = match parser.tokens.next() {
            Some(Ok(t)) => t,
            None => return Err(Error::new(ErrorMessage::UnexpectedEndOfTemplate)),
            Some(Err(e)) => return Err(e),
        };

        parse_with_precedence_0(parser, token)
    }
}

fn parse_with_precedence_0<'r, 'c, I>(parser: &mut Context<'r, I>, token: Token<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_with_precedence_0");
    parse_primary(parser, token)
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_primary<'r, 'c, I>(parser: &mut Context<'r, I>, token: Token<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    match token.value {
        TokenValue::Operator { kind: OperatorKind::Unary, .. } => {
            unimplemented!()
        },
        TokenValue::Punctuation('(') => {
            unimplemented!()
        },
        _ => parse_primary_expression(parser, token),
    }
}

/// Parses expression and returns handle to one that should be executed first.
fn parse_primary_expression<'r, 'c, I>(parser: &mut Context<'r, I>, token: Token<'c>)
    -> Result<Expr<'c>>
    where
        I: Iterator<Item=Result<Token<'c>>>
{
    println!("parse_primary");
    Ok(Expr::Constant { value: "", line: 1 })
}
<|endoftext|>


<commit_before>use super::*;
use std::collections::{BTreeMap, VecDeque};

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct TermId {
    address: Vec<usize>,
    compos_var_pos: usize,
}

impl From<(Vec<usize>, usize)> for TermId {
    fn from((address, compos_var_pos): (Vec<usize>, usize)) -> TermId {
        TermId { address, compos_var_pos }
    }
}

pub fn identify_terminals<A>(tree_map: &GornTree<Composition<A>>)
        -> (GornTree<Composition<TermId>>, BTreeMap<TermId, A>)
    where A: Clone,
{
    let mut identified_tree_map = GornTree::new();
    let mut terminal_map = BTreeMap::new();

    for (address, composition) in tree_map {
        let vec_compos = &composition.composition;
        let mut identified_compos = Vec::new();
        let mut compos_var_pos = 0;

        for component in vec_compos {
            let mut identified_compon = Vec::new();

            for variable in component {
                match variable {
                    &VarT::Var(x, y) => {
                        identified_compon.push(VarT::Var(x, y));
                    },
                    &VarT::T(ref terminal) => {
                        let terminal_id = TermId { address: address.clone(), compos_var_pos };
                        identified_compon.push(VarT::T(terminal_id.clone()));
                        terminal_map.insert(terminal_id, terminal.clone());
                    },
                };

                compos_var_pos += 1;
            }

            identified_compos.push(identified_compon);
        }

        identified_tree_map.insert(address.clone(), Composition::from(identified_compos));
    }

    (identified_tree_map, terminal_map)
}

pub fn to_negra<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>, sentence_id: usize)
        -> String
    where H: Clone + ToString,
          T: Clone + ToString,
{
    if !meets_negra_criteria(&tree_map) {
        panic!("The given tree does not meet the negra criteria! All rules must either consist \
                only of nonterminals or of exactly one terminal symbol.");
    }

    let negra_vector = to_negra_vector(&tree_map);
    let mut output = format!("#BOS {}\n", sentence_id);

    for (word, tag, parent) in negra_vector {
        output.push_str(&format!("{}\t{}\t--\t--\t{}\n", word, tag, parent));
    }

    output.push_str(&format!("#EOS {}", sentence_id));
    output
}

pub fn meets_negra_criteria<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>)
        -> bool
{
    for (_address, rule) in tree_map {
        let &PMCFGRule { head: _, tail: _, ref composition, weight: _ } = rule;
        let mut contains_nonterminal = false;
        let mut contains_terminal = false;

        for component in &composition.composition {
            for variable in component {
                match variable {
                    &VarT::Var(_, _) => {
                        if contains_terminal {
                            return false;
                        }

                        contains_nonterminal = true;
                    },
                    &VarT::T(_) => {
                        if contains_nonterminal || contains_terminal {
                            return false;
                        }

                        contains_terminal = true;
                    },
                }
            }
        }
    }

    true
}

pub fn to_negra_vector<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>)
        -> Vec<(String, String, usize)>
    where H: Clone + ToString,
          T: Clone + ToString,
{
    let (term_map, nonterminal_map) = to_term(&tree_map);
    let (identified_tree_map, terminal_map) = identify_terminals(&term_map);
    let evaluated_compos = evaluate(&identified_tree_map);

    let mut negra_vector = Vec::new();
    let mut rule_queue = VecDeque::new();
    let mut rule_number_map = GornTree::new();
    let mut rule_counter = 1;

    for component in evaluated_compos.composition {
        for variable in component {
            match variable {
                VarT::Var(_, _) => {
                    panic!("Nonterminals must not appear in a fully evaluated configuration!");
                },
                VarT::T(terminal_id) => {
                    let terminal_symbol = terminal_map.get(&terminal_id).unwrap();
                    let address = terminal_id.address;
                    let rule_label = nonterminal_map.get(&address).unwrap();

                    let mut parent_address = address;
                    let parent_number = if let None = parent_address.pop() {
                        panic!("Terminals must have a nonterminal-only rule as their parent!");
                    } else {
                        get_rule_number(&parent_address, &mut rule_queue, &mut rule_number_map,
                                        &mut rule_counter)
                    };
                    negra_vector.push((terminal_symbol.to_string(), rule_label.to_string(), parent_number));
                }
            }
        }
    }

    while let Some((address, rule_number)) = rule_queue.pop_front() {
        let mut parent_address = address.clone();

        let parent_number = if let None = parent_address.pop() {
            0
        } else {
            get_rule_number(&parent_address, &mut rule_queue, &mut rule_number_map, &mut rule_counter)
        };

        let rule_label = nonterminal_map.get(&address).unwrap();
        negra_vector.push((format!("#{}", rule_number), rule_label.to_string(), parent_number));
    }

    negra_vector
}

fn get_rule_number(address: &Vec<usize>, rule_queue: &mut VecDeque<(Vec<usize>, usize)>, rule_number_map: &mut GornTree<usize>, rule_counter: &mut usize)
        -> usize
{
    if let Some(rule_number) = rule_number_map.get(address) {
        return *rule_number
    }

    let rule_number = *rule_counter;
    *rule_counter = *rule_counter + 1;

    rule_number_map.insert(address.clone(), rule_number.clone());
    rule_queue.push_back((address.clone(), rule_number));
    rule_number
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::tests::*;
    use self::VarT::{Var, T};

    #[test]
    fn test_identify_terminals() {
        let mut tree_map = GornTree::new();
        tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T("a"), Var(0, 1), T("b")]
        ]));
        tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T("c")]
        ]));
        tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T("d")]
        ]));

        let mut identified_tree_map = GornTree::new();
        identified_tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T(TermId::from((vec![], 1))), Var(0, 1), T(TermId::from((vec![], 3)))]
        ]));
        identified_tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T(TermId::from((vec![0], 1)))]
        ]));
        identified_tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T(TermId::from((vec![0, 1], 0)))]
        ]));

        let mut terminal_map = BTreeMap::new();
        terminal_map.insert(TermId::from((vec![], 1)), "a");
        terminal_map.insert(TermId::from((vec![], 3)), "b");
        terminal_map.insert(TermId::from((vec![0], 1)), "c");
        terminal_map.insert(TermId::from((vec![0, 1], 0)), "d");

        assert_eq!((identified_tree_map, terminal_map), identify_terminals(&tree_map));
    }

    #[test]
    fn test_to_negra_vector() {
        let tree_map = example_tree_map();
        let negra_vector = vec![
            (String::from("a"), String::from("a"), 1),
            (String::from("a"), String::from("a"), 2),
            (String::from("b"), String::from("b"), 3),
            (String::from("c"), String::from("c"), 1),
            (String::from("c"), String::from("c"), 2),
            (String::from("d"), String::from("d"), 3),
            (String::from("#1"), String::from("A"), 4),
            (String::from("#2"), String::from("A"), 1),
            (String::from("#3"), String::from("B"), 4),
            (String::from("#4"), String::from("S"), 0)
        ];

        assert_eq!(negra_vector, to_negra_vector(&tree_map));
    }
}
<commit_msg>src/pmcfg/negra.rs: made `address` owned in get_rule_number()<commit_after>use super::*;
use std::collections::{BTreeMap, VecDeque};

#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct TermId {
    address: Vec<usize>,
    compos_var_pos: usize,
}

impl From<(Vec<usize>, usize)> for TermId {
    fn from((address, compos_var_pos): (Vec<usize>, usize)) -> TermId {
        TermId { address, compos_var_pos }
    }
}

pub fn identify_terminals<A>(tree_map: &GornTree<Composition<A>>)
        -> (GornTree<Composition<TermId>>, BTreeMap<TermId, A>)
    where A: Clone,
{
    let mut identified_tree_map = GornTree::new();
    let mut terminal_map = BTreeMap::new();

    for (address, composition) in tree_map {
        let vec_compos = &composition.composition;
        let mut identified_compos = Vec::new();
        let mut compos_var_pos = 0;

        for component in vec_compos {
            let mut identified_compon = Vec::new();

            for variable in component {
                match variable {
                    &VarT::Var(x, y) => {
                        identified_compon.push(VarT::Var(x, y));
                    },
                    &VarT::T(ref terminal) => {
                        let terminal_id = TermId { address: address.clone(), compos_var_pos };
                        identified_compon.push(VarT::T(terminal_id.clone()));
                        terminal_map.insert(terminal_id, terminal.clone());
                    },
                };

                compos_var_pos += 1;
            }

            identified_compos.push(identified_compon);
        }

        identified_tree_map.insert(address.clone(), Composition::from(identified_compos));
    }

    (identified_tree_map, terminal_map)
}

pub fn to_negra<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>, sentence_id: usize)
        -> String
    where H: Clone + ToString,
          T: Clone + ToString,
{
    if !meets_negra_criteria(&tree_map) {
        panic!("The given tree does not meet the negra criteria! All rules must either consist \
                only of nonterminals or of exactly one terminal symbol.");
    }

    let negra_vector = to_negra_vector(&tree_map);
    let mut output = format!("#BOS {}\n", sentence_id);

    for (word, tag, parent) in negra_vector {
        output.push_str(&format!("{}\t{}\t--\t--\t{}\n", word, tag, parent));
    }

    output.push_str(&format!("#EOS {}", sentence_id));
    output
}

pub fn meets_negra_criteria<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>)
        -> bool
{
    for (_address, rule) in tree_map {
        let &PMCFGRule { head: _, tail: _, ref composition, weight: _ } = rule;
        let mut contains_nonterminal = false;
        let mut contains_terminal = false;

        for component in &composition.composition {
            for variable in component {
                match variable {
                    &VarT::Var(_, _) => {
                        if contains_terminal {
                            return false;
                        }

                        contains_nonterminal = true;
                    },
                    &VarT::T(_) => {
                        if contains_nonterminal || contains_terminal {
                            return false;
                        }

                        contains_terminal = true;
                    },
                }
            }
        }
    }

    true
}

pub fn to_negra_vector<H, T, W>(tree_map: &GornTree<PMCFGRule<H, T, W>>)
        -> Vec<(String, String, usize)>
    where H: Clone + ToString,
          T: Clone + ToString,
{
    let (term_map, nonterminal_map) = to_term(&tree_map);
    let (identified_tree_map, terminal_map) = identify_terminals(&term_map);
    let evaluated_compos = evaluate(&identified_tree_map);

    let mut negra_vector = Vec::new();
    let mut rule_queue = VecDeque::new();
    let mut rule_number_map = GornTree::new();
    let mut rule_counter = 1;

    for component in evaluated_compos.composition {
        for variable in component {
            match variable {
                VarT::Var(_, _) => {
                    panic!("Nonterminals must not appear in a fully evaluated configuration!");
                },
                VarT::T(terminal_id) => {
                    let terminal_symbol = terminal_map.get(&terminal_id).unwrap();
                    let address = terminal_id.address;
                    let rule_label = nonterminal_map.get(&address).unwrap();

                    let mut parent_address = address;
                    let parent_number = if let None = parent_address.pop() {
                        panic!("Terminals must have a nonterminal-only rule as their parent!");
                    } else {
                        get_rule_number(parent_address, &mut rule_queue, &mut rule_number_map,
                                        &mut rule_counter)
                    };
                    negra_vector.push((terminal_symbol.to_string(), rule_label.to_string(), parent_number));
                },
            }
        }
    }

    while let Some((address, rule_number)) = rule_queue.pop_front() {
        let mut parent_address = address.clone();

        let parent_number = if let None = parent_address.pop() {
            0
        } else {
            get_rule_number(parent_address, &mut rule_queue, &mut rule_number_map, &mut rule_counter)
        };

        let rule_label = nonterminal_map.get(&address).unwrap();
        negra_vector.push((format!("#{}", rule_number), rule_label.to_string(), parent_number));
    }

    negra_vector
}

fn get_rule_number(address: Vec<usize>, rule_queue: &mut VecDeque<(Vec<usize>, usize)>, rule_number_map: &mut GornTree<usize>, rule_counter: &mut usize)
        -> usize
{
    if let Some(rule_number) = rule_number_map.get(&address) {
        return *rule_number
    }

    let rule_number = *rule_counter;
    *rule_counter = *rule_counter + 1;

    rule_number_map.insert(address.clone(), rule_number.clone());
    rule_queue.push_back((address, rule_number));
    rule_number
}

#[cfg(test)]
mod tests {
    use super::*;
    use super::super::tests::*;
    use self::VarT::{Var, T};

    #[test]
    fn test_identify_terminals() {
        let mut tree_map = GornTree::new();
        tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T("a"), Var(0, 1), T("b")]
        ]));
        tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T("c")]
        ]));
        tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T("d")]
        ]));

        let mut identified_tree_map = GornTree::new();
        identified_tree_map.insert(vec![], Composition::from(vec![
            vec![Var(0, 0), T(TermId::from((vec![], 1))), Var(0, 1), T(TermId::from((vec![], 3)))]
        ]));
        identified_tree_map.insert(vec![0], Composition::from(vec![
            vec![Var(1, 0)],
            vec![T(TermId::from((vec![0], 1)))]
        ]));
        identified_tree_map.insert(vec![0, 1], Composition::from(vec![
            vec![T(TermId::from((vec![0, 1], 0)))]
        ]));

        let mut terminal_map = BTreeMap::new();
        terminal_map.insert(TermId::from((vec![], 1)), "a");
        terminal_map.insert(TermId::from((vec![], 3)), "b");
        terminal_map.insert(TermId::from((vec![0], 1)), "c");
        terminal_map.insert(TermId::from((vec![0, 1], 0)), "d");

        assert_eq!((identified_tree_map, terminal_map), identify_terminals(&tree_map));
    }

    #[test]
    fn test_to_negra_vector() {
        let tree_map = example_tree_map();
        let negra_vector = vec![
            (String::from("a"), String::from("a"), 1),
            (String::from("a"), String::from("a"), 2),
            (String::from("b"), String::from("b"), 3),
            (String::from("c"), String::from("c"), 1),
            (String::from("c"), String::from("c"), 2),
            (String::from("d"), String::from("d"), 3),
            (String::from("#1"), String::from("A"), 4),
            (String::from("#2"), String::from("A"), 1),
            (String::from("#3"), String::from("B"), 4),
            (String::from("#4"), String::from("S"), 0)
        ];

        assert_eq!(negra_vector, to_negra_vector(&tree_map));
    }
}
<|endoftext|>


<commit_before>use libc::pid_t;
use nix::sys::ptrace::*;
use nix::sys::ptrace::ptrace::*;
use std::ptr;
use libc::c_void;
use std::ops::{Add, Sub};

#[derive(Copy, Clone)]
pub struct InferiorPointer(pub u64);
impl Add<i64> for InferiorPointer {
    type Output = InferiorPointer;
    fn add(self, rhs: i64) -> InferiorPointer {
        let InferiorPointer(u) = self;
        if rhs >= 0 {
            InferiorPointer(u + rhs as u64)
        } else {
            InferiorPointer(u - rhs as u64)
        }
    }
}
impl Sub<i64> for InferiorPointer {
    type Output = InferiorPointer;
    fn sub(self, rhs: i64) -> InferiorPointer {
        let InferiorPointer(u) = self;
        if rhs >= 0 {
            InferiorPointer(u - rhs as u64)
        } else {
            InferiorPointer(u + rhs as u64)
        }
    }
}

pub mod user {
    pub mod regs {
        // pub const R15: i64 = 0 * 8;
        // pub const R14: i64 = 1 * 8;
        // pub const R13: i64 = 2 * 8;
        // pub const R12: i64 = 3 * 8;
        // pub const RBP: i64 = 4 * 8;
        // pub const RBX: i64 = 5 * 8;
        // pub const R11: i64 = 6 * 8;
        // pub const R10: i64 = 7 * 8;
        // pub const R9:  i64 = 8 * 8;
        // pub const R8:  i64 = 9 * 8;
        // pub const RAX: i64 = 10 * 8;
        // pub const RCX: i64 = 11 * 8;
        // pub const RDX: i64 = 12 * 8;
        // pub const RSI: i64 = 13 * 8;
        // pub const RDI: i64 = 14 * 8;
        // pub const ORIG_RAX: i64 = 15 * 8;
        pub const RIP: i64 = 16 * 8;
        // pub const CS:  i64 = 17 * 8;
        // pub const EFLAGS: i64 = 18 * 8;
        // pub const RSP: i64 = 19 * 8;
        // pub const SS:  i64 = 20 * 8;
        // pub const FS_BASE: i64 = 21 * 8;
        // pub const GS_BASE: i64 = 22 * 8;
        // pub const DS:  i64 = 23 * 8;
        // pub const ES:  i64 = 24 * 8;
        // pub const FS:  i64 = 25 * 8;
        // pub const GS:  i64 = 26 * 8;
    }
}

pub fn trace_me() -> () {
    ptrace(PTRACE_TRACEME, 0, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_TRACEME");
}

pub fn get_instruction_pointer(pid: pid_t) -> InferiorPointer {
    let raw = ptrace(PTRACE_PEEKUSER, pid, user::regs::RIP as * mut c_void, ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKUSER");
    InferiorPointer(raw as u64)
}

pub fn set_instruction_pointer(pid: pid_t, ip: InferiorPointer) -> () {
    let InferiorPointer(raw_address) = ip;

    ptrace(PTRACE_POKEUSER, pid, user::regs::RIP as * mut c_void, raw_address as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKEUSER");
}

pub fn cont(pid: pid_t) -> () {
    ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_CONTINUE");
}

pub fn peek_text(pid: pid_t, address: InferiorPointer) -> i64 {
    let InferiorPointer(raw_address) = address;

    ptrace(PTRACE_PEEKTEXT, pid, raw_address as * mut c_void, ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKTEXT")
}

pub fn poke_text(pid: pid_t, address: InferiorPointer, value: i64) -> () {
    let InferiorPointer(raw_address) = address;

    ptrace(PTRACE_POKETEXT, pid, raw_address as * mut c_void, value as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKETEXT");
}
<commit_msg>Extract as_voidptr from common cast operation.<commit_after>use libc::pid_t;
use nix::sys::ptrace::*;
use nix::sys::ptrace::ptrace::*;
use std::ptr;
use libc::c_void;
use std::ops::{Add, Sub};

#[derive(Copy, Clone)]
pub struct InferiorPointer(pub u64);
impl InferiorPointer {
    fn as_voidptr(&self) -> * mut c_void {
        let &InferiorPointer(u) = self;
        u as * mut c_void
    }
}
impl Add<i64> for InferiorPointer {
    type Output = InferiorPointer;
    fn add(self, rhs: i64) -> InferiorPointer {
        let InferiorPointer(u) = self;
        if rhs >= 0 {
            InferiorPointer(u + rhs as u64)
        } else {
            InferiorPointer(u - rhs as u64)
        }
    }
}
impl Sub<i64> for InferiorPointer {
    type Output = InferiorPointer;
    fn sub(self, rhs: i64) -> InferiorPointer {
        let InferiorPointer(u) = self;
        if rhs >= 0 {
            InferiorPointer(u - rhs as u64)
        } else {
            InferiorPointer(u + rhs as u64)
        }
    }
}

pub mod user {
    pub mod regs {
        // pub const R15: i64 = 0 * 8;
        // pub const R14: i64 = 1 * 8;
        // pub const R13: i64 = 2 * 8;
        // pub const R12: i64 = 3 * 8;
        // pub const RBP: i64 = 4 * 8;
        // pub const RBX: i64 = 5 * 8;
        // pub const R11: i64 = 6 * 8;
        // pub const R10: i64 = 7 * 8;
        // pub const R9:  i64 = 8 * 8;
        // pub const R8:  i64 = 9 * 8;
        // pub const RAX: i64 = 10 * 8;
        // pub const RCX: i64 = 11 * 8;
        // pub const RDX: i64 = 12 * 8;
        // pub const RSI: i64 = 13 * 8;
        // pub const RDI: i64 = 14 * 8;
        // pub const ORIG_RAX: i64 = 15 * 8;
        pub const RIP: i64 = 16 * 8;
        // pub const CS:  i64 = 17 * 8;
        // pub const EFLAGS: i64 = 18 * 8;
        // pub const RSP: i64 = 19 * 8;
        // pub const SS:  i64 = 20 * 8;
        // pub const FS_BASE: i64 = 21 * 8;
        // pub const GS_BASE: i64 = 22 * 8;
        // pub const DS:  i64 = 23 * 8;
        // pub const ES:  i64 = 24 * 8;
        // pub const FS:  i64 = 25 * 8;
        // pub const GS:  i64 = 26 * 8;
    }
}

pub fn trace_me() -> () {
    ptrace(PTRACE_TRACEME, 0, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_TRACEME");
}

pub fn get_instruction_pointer(pid: pid_t) -> InferiorPointer {
    let raw = ptrace(PTRACE_PEEKUSER, pid, user::regs::RIP as * mut c_void, ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKUSER");
    InferiorPointer(raw as u64)
}

pub fn set_instruction_pointer(pid: pid_t, ip: InferiorPointer) -> () {
    ptrace(PTRACE_POKEUSER, pid, user::regs::RIP as * mut c_void, ip.as_voidptr())
        .ok()
        .expect("Failed PTRACE_POKEUSER");
}

pub fn cont(pid: pid_t) -> () {
    ptrace(PTRACE_CONT, pid, ptr::null_mut(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_CONTINUE");
}

pub fn peek_text(pid: pid_t, address: InferiorPointer) -> i64 {
    ptrace(PTRACE_PEEKTEXT, pid, address.as_voidptr(), ptr::null_mut())
        .ok()
        .expect("Failed PTRACE_PEEKTEXT")
}

pub fn poke_text(pid: pid_t, address: InferiorPointer, value: i64) -> () {
    ptrace(PTRACE_POKETEXT, pid, address.as_voidptr(), value as * mut c_void)
        .ok()
        .expect("Failed PTRACE_POKETEXT");
}
<|endoftext|>


<commit_before>#![feature(hash)]
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]

use std::str::StrExt;
use std::hash::{Hasher, Hash, SipHasher};

#[inline]
pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 {
    d2 + f1 * d1 + f2
}

#[inline]
fn split(hash: u64) -> (u32, u32, u32) {
    const BITS: u32 = 21;
    const MASK: u64 = (1 << BITS) - 1;

    ((hash & MASK) as u32,
     ((hash >> BITS) & MASK) as u32,
     ((hash >> (2 * BITS)) & MASK) as u32)
}

/// A trait implemented by types which can be used in PHF data structures
pub trait PhfHash {
    /// Hashes the value of `self`, factoring in a seed
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32);
}

impl<'a> PhfHash for &'a str {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        self.as_bytes().phf_hash(seed)
    }
}

impl<'a> PhfHash for &'a [u8] {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        (*self).phf_hash(seed)
    }
}

impl PhfHash for str {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        self.as_bytes().phf_hash(seed)
    }
}

impl PhfHash for [u8] {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        let mut state = SipHasher::new_with_keys(seed, 0);
        Hasher::write(&mut state, self);
        split(state.finish())
    }
}

macro_rules! sip_impl(
    ($t:ty) => (
        impl PhfHash for $t {
            #[inline]
            fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
                let mut hasher = SipHasher::new_with_keys(seed, 0);
                self.hash(&mut hasher);
                split(hasher.finish())
            }
        }
    )
);

sip_impl!(u8);
sip_impl!(i8);
sip_impl!(u16);
sip_impl!(i16);
sip_impl!(u32);
sip_impl!(i32);
sip_impl!(u64);
sip_impl!(i64);
sip_impl!(char);
sip_impl!(bool);

macro_rules! array_impl(
    ($t:ty, $n:expr) => (
        impl PhfHash for [$t; $n] {
            #[inline]
            fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
                let mut hasher = SipHasher::new_with_keys(seed, 0);
                Hasher::write(&mut hasher, self);
                split(hasher.finish())
            }
        }
    )
);

array_impl!(u8, 1);
array_impl!(u8, 2);
array_impl!(u8, 3);
array_impl!(u8, 4);
array_impl!(u8, 5);
array_impl!(u8, 6);
array_impl!(u8, 7);
array_impl!(u8, 8);
array_impl!(u8, 9);
array_impl!(u8, 10);
array_impl!(u8, 11);
array_impl!(u8, 12);
array_impl!(u8, 13);
array_impl!(u8, 14);
array_impl!(u8, 15);
array_impl!(u8, 16);
array_impl!(u8, 17);
array_impl!(u8, 18);
array_impl!(u8, 19);
array_impl!(u8, 20);
array_impl!(u8, 21);
array_impl!(u8, 22);
array_impl!(u8, 23);
array_impl!(u8, 24);
array_impl!(u8, 25);
array_impl!(u8, 26);
array_impl!(u8, 27);
array_impl!(u8, 28);
array_impl!(u8, 29);
array_impl!(u8, 30);
array_impl!(u8, 31);
array_impl!(u8, 32);
<commit_msg>Update to rustc 1.0.0-dev (e46610966 2015-03-17) (built 2015-03-17)<commit_after>#![feature(hash)]
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]

use std::hash::{Hasher, Hash, SipHasher};

#[inline]
pub fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 {
    d2 + f1 * d1 + f2
}

#[inline]
fn split(hash: u64) -> (u32, u32, u32) {
    const BITS: u32 = 21;
    const MASK: u64 = (1 << BITS) - 1;

    ((hash & MASK) as u32,
     ((hash >> BITS) & MASK) as u32,
     ((hash >> (2 * BITS)) & MASK) as u32)
}

/// A trait implemented by types which can be used in PHF data structures
pub trait PhfHash {
    /// Hashes the value of `self`, factoring in a seed
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32);
}

impl<'a> PhfHash for &'a str {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        self.as_bytes().phf_hash(seed)
    }
}

impl<'a> PhfHash for &'a [u8] {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        (*self).phf_hash(seed)
    }
}

impl PhfHash for str {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        self.as_bytes().phf_hash(seed)
    }
}

impl PhfHash for [u8] {
    #[inline]
    fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
        let mut state = SipHasher::new_with_keys(seed, 0);
        Hasher::write(&mut state, self);
        split(state.finish())
    }
}

macro_rules! sip_impl(
    ($t:ty) => (
        impl PhfHash for $t {
            #[inline]
            fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
                let mut hasher = SipHasher::new_with_keys(seed, 0);
                self.hash(&mut hasher);
                split(hasher.finish())
            }
        }
    )
);

sip_impl!(u8);
sip_impl!(i8);
sip_impl!(u16);
sip_impl!(i16);
sip_impl!(u32);
sip_impl!(i32);
sip_impl!(u64);
sip_impl!(i64);
sip_impl!(char);
sip_impl!(bool);

macro_rules! array_impl(
    ($t:ty, $n:expr) => (
        impl PhfHash for [$t; $n] {
            #[inline]
            fn phf_hash(&self, seed: u64) -> (u32, u32, u32) {
                let mut hasher = SipHasher::new_with_keys(seed, 0);
                Hasher::write(&mut hasher, self);
                split(hasher.finish())
            }
        }
    )
);

array_impl!(u8, 1);
array_impl!(u8, 2);
array_impl!(u8, 3);
array_impl!(u8, 4);
array_impl!(u8, 5);
array_impl!(u8, 6);
array_impl!(u8, 7);
array_impl!(u8, 8);
array_impl!(u8, 9);
array_impl!(u8, 10);
array_impl!(u8, 11);
array_impl!(u8, 12);
array_impl!(u8, 13);
array_impl!(u8, 14);
array_impl!(u8, 15);
array_impl!(u8, 16);
array_impl!(u8, 17);
array_impl!(u8, 18);
array_impl!(u8, 19);
array_impl!(u8, 20);
array_impl!(u8, 21);
array_impl!(u8, 22);
array_impl!(u8, 23);
array_impl!(u8, 24);
array_impl!(u8, 25);
array_impl!(u8, 26);
array_impl!(u8, 27);
array_impl!(u8, 28);
array_impl!(u8, 29);
array_impl!(u8, 30);
array_impl!(u8, 31);
array_impl!(u8, 32);
<|endoftext|>


<commit_before>use std::ops::{Add, Sub, Mul};

macro_rules! wrapping_impl {
    ($trait_name:ident, $method:ident, $t:ty) => {
        impl $trait_name for $t {
            #[inline]
            fn $method(&self, v: &Self) -> Self {
                <$t>::$method(*self, *v)
            }
        }
    };
    ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
        impl $trait_name<$rhs> for $t {
            #[inline]
            fn $method(&self, v: &$rhs) -> Self {
                <$t>::$method(*self, *v)
            }
        }
    }
}

/// Performs addition that wraps around on overflow.
pub trait WrappingAdd: Sized + Add<Self, Output=Self> {
    /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
    /// the type.
    fn wrapping_add(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingAdd, wrapping_add, u8);
wrapping_impl!(WrappingAdd, wrapping_add, u16);
wrapping_impl!(WrappingAdd, wrapping_add, u32);
wrapping_impl!(WrappingAdd, wrapping_add, u64);
wrapping_impl!(WrappingAdd, wrapping_add, usize);

wrapping_impl!(WrappingAdd, wrapping_add, i8);
wrapping_impl!(WrappingAdd, wrapping_add, i16);
wrapping_impl!(WrappingAdd, wrapping_add, i32);
wrapping_impl!(WrappingAdd, wrapping_add, i64);
wrapping_impl!(WrappingAdd, wrapping_add, isize);

/// Performs subtraction that wraps around on overflow.
pub trait WrappingSub: Sized + Sub<Self, Output=Self> {
    /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
    /// of the type.
    fn wrapping_sub(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingSub, wrapping_sub, u8);
wrapping_impl!(WrappingSub, wrapping_sub, u16);
wrapping_impl!(WrappingSub, wrapping_sub, u32);
wrapping_impl!(WrappingSub, wrapping_sub, u64);
wrapping_impl!(WrappingSub, wrapping_sub, usize);

wrapping_impl!(WrappingSub, wrapping_sub, i8);
wrapping_impl!(WrappingSub, wrapping_sub, i16);
wrapping_impl!(WrappingSub, wrapping_sub, i32);
wrapping_impl!(WrappingSub, wrapping_sub, i64);
wrapping_impl!(WrappingSub, wrapping_sub, isize);

/// Performs multiplication that wraps around on overflow.
pub trait WrappingMul: Sized + Mul<Self, Output=Self> {
    /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
    /// of the type.
    fn wrapping_mul(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingMul, wrapping_mul, u8);
wrapping_impl!(WrappingMul, wrapping_mul, u16);
wrapping_impl!(WrappingMul, wrapping_mul, u32);
wrapping_impl!(WrappingMul, wrapping_mul, u64);
wrapping_impl!(WrappingMul, wrapping_mul, usize);

wrapping_impl!(WrappingMul, wrapping_mul, i8);
wrapping_impl!(WrappingMul, wrapping_mul, i16);
wrapping_impl!(WrappingMul, wrapping_mul, i32);
wrapping_impl!(WrappingMul, wrapping_mul, i64);
wrapping_impl!(WrappingMul, wrapping_mul, isize);

#[test]
fn test_wrapping_traits() {
    fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T { a.wrapping_add(&b) }
    fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T { a.wrapping_sub(&b) }
    fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T { a.wrapping_mul(&b) }
    assert_eq!(wrapping_add(255, 1), 0u8);
    assert_eq!(wrapping_sub(0, 1), 255u8);
    assert_eq!(wrapping_mul(255, 2), 254u8);
}
<commit_msg>impl Wrapping ops for Wrapping<T><commit_after>use std::ops::{Add, Sub, Mul};
use std::num::Wrapping;

macro_rules! wrapping_impl {
    ($trait_name:ident, $method:ident, $t:ty) => {
        impl $trait_name for $t {
            #[inline]
            fn $method(&self, v: &Self) -> Self {
                <$t>::$method(*self, *v)
            }
        }
    };
    ($trait_name:ident, $method:ident, $t:ty, $rhs:ty) => {
        impl $trait_name<$rhs> for $t {
            #[inline]
            fn $method(&self, v: &$rhs) -> Self {
                <$t>::$method(*self, *v)
            }
        }
    }
}

/// Performs addition that wraps around on overflow.
pub trait WrappingAdd: Sized + Add<Self, Output=Self> {
    /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
    /// the type.
    fn wrapping_add(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingAdd, wrapping_add, u8);
wrapping_impl!(WrappingAdd, wrapping_add, u16);
wrapping_impl!(WrappingAdd, wrapping_add, u32);
wrapping_impl!(WrappingAdd, wrapping_add, u64);
wrapping_impl!(WrappingAdd, wrapping_add, usize);

wrapping_impl!(WrappingAdd, wrapping_add, i8);
wrapping_impl!(WrappingAdd, wrapping_add, i16);
wrapping_impl!(WrappingAdd, wrapping_add, i32);
wrapping_impl!(WrappingAdd, wrapping_add, i64);
wrapping_impl!(WrappingAdd, wrapping_add, isize);

/// Performs subtraction that wraps around on overflow.
pub trait WrappingSub: Sized + Sub<Self, Output=Self> {
    /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
    /// of the type.
    fn wrapping_sub(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingSub, wrapping_sub, u8);
wrapping_impl!(WrappingSub, wrapping_sub, u16);
wrapping_impl!(WrappingSub, wrapping_sub, u32);
wrapping_impl!(WrappingSub, wrapping_sub, u64);
wrapping_impl!(WrappingSub, wrapping_sub, usize);

wrapping_impl!(WrappingSub, wrapping_sub, i8);
wrapping_impl!(WrappingSub, wrapping_sub, i16);
wrapping_impl!(WrappingSub, wrapping_sub, i32);
wrapping_impl!(WrappingSub, wrapping_sub, i64);
wrapping_impl!(WrappingSub, wrapping_sub, isize);

/// Performs multiplication that wraps around on overflow.
pub trait WrappingMul: Sized + Mul<Self, Output=Self> {
    /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
    /// of the type.
    fn wrapping_mul(&self, v: &Self) -> Self;
}

wrapping_impl!(WrappingMul, wrapping_mul, u8);
wrapping_impl!(WrappingMul, wrapping_mul, u16);
wrapping_impl!(WrappingMul, wrapping_mul, u32);
wrapping_impl!(WrappingMul, wrapping_mul, u64);
wrapping_impl!(WrappingMul, wrapping_mul, usize);

wrapping_impl!(WrappingMul, wrapping_mul, i8);
wrapping_impl!(WrappingMul, wrapping_mul, i16);
wrapping_impl!(WrappingMul, wrapping_mul, i32);
wrapping_impl!(WrappingMul, wrapping_mul, i64);
wrapping_impl!(WrappingMul, wrapping_mul, isize);

// Well this is a bit funny, but all the more appropriate.
impl<T: WrappingAdd> WrappingAdd for Wrapping<T> where Wrapping<T>: Add<Output = Wrapping<T>> {
    fn wrapping_add(&self, v: &Self) -> Self {
        Wrapping(self.0.wrapping_add(&v.0))
    }
}
impl<T: WrappingSub> WrappingSub for Wrapping<T> where Wrapping<T>: Sub<Output = Wrapping<T>> {
    fn wrapping_sub(&self, v: &Self) -> Self {
        Wrapping(self.0.wrapping_sub(&v.0))
    }
}
impl<T: WrappingMul> WrappingMul for Wrapping<T> where Wrapping<T>: Mul<Output = Wrapping<T>> {
    fn wrapping_mul(&self, v: &Self) -> Self {
        Wrapping(self.0.wrapping_mul(&v.0))
    }
}

#[test]
fn test_wrapping_traits() {
    fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T { a.wrapping_add(&b) }
    fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T { a.wrapping_sub(&b) }
    fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T { a.wrapping_mul(&b) }
    assert_eq!(wrapping_add(255, 1), 0u8);
    assert_eq!(wrapping_sub(0, 1), 255u8);
    assert_eq!(wrapping_mul(255, 2), 254u8);
}
<|endoftext|>