<commit_before>// rustfmt/main.rs

use std::io;
use std::str;
use syntax::parse::lexer::{StringReader, TokenAndSpan};
use syntax::parse::lexer;
use syntax::parse::token::Token;
use syntax::parse::token::keywords;
use syntax::parse::token;
use syntax::parse;

static TAB_WIDTH: i32 = 4;

enum ProductionToParse {
    MatchProduction,
    BracesProduction,
    ParenthesesProduction,
}

struct LineToken {
    token_and_span: TokenAndSpan,
    x_pos: i32,
}

impl LineToken {
    fn new(token_and_span: TokenAndSpan) -> LineToken {
        LineToken {
            token_and_span: token_and_span,
            x_pos: 0,
        }
    }

    fn whitespace_needed_after(&self, next: &LineToken) -> bool {
        match (&self.token_and_span.tok, &next.token_and_span.tok) {
            (&token::IDENT(..), &token::IDENT(..)) => true,
            (&token::IDENT(..), &token::NOT) => {
                // Macros.
                false
            }

            (&token::COLON, _) => true,
            (&token::COMMA, _) => true,
            (&token::EQ, _) | (_, &token::EQ) => true,
            (&token::LT, _) | (_, &token::LT) => true,
            (&token::LE, _) | (_, &token::LE) => true,
            (&token::EQEQ, _) | (_, &token::EQEQ) => true,
            (&token::NE, _) | (_, &token::NE) => true,
            (&token::GE, _) | (_, &token::GE) => true,
            (&token::GT, _) | (_, &token::GT) => true,
            (&token::ANDAND, _) | (_, &token::ANDAND) => true,
            (&token::OROR, _) | (_, &token::OROR) => true,
            (&token::TILDE, _) | (_, &token::TILDE) => true,

            (&token::LPAREN, _) => false,
            (_, &token::RPAREN) => false,
            (&token::BINOP(token::AND), _) => false,

            (&token::BINOP(_), _) | (_, &token::BINOP(_)) => true,
            (&token::BINOPEQ(_), _) | (_, &token::BINOPEQ(_)) => true,

            (&token::MOD_SEP, _) | (_, &token::MOD_SEP) => false,

            (&token::RARROW, _) | (_, &token::RARROW) => true,
            (&token::FAT_ARROW, _) | (_, &token::FAT_ARROW) => true,
            (&token::LBRACE, _) | (_, &token::LBRACE) => true,
            (&token::RBRACE, _) | (_, &token::RBRACE) => true,
            _ => false,
        }
    }

    fn length(&self) -> i32 {
        token::to_str(&self.token_and_span.tok).len() as i32
    }

    fn starts_logical_line(&self) -> bool {
        match self.token_and_span.tok {
            token::RBRACE => true,
            _ => false,
        }
    }

    fn preindentation(&self) -> i32 {
        match self.token_and_span.tok {
            token::RBRACE => -TAB_WIDTH,
            _ => 0,
        }
    }
}

struct LogicalLine {
    tokens: Vec<LineToken>,
}

impl LogicalLine {
    fn new() -> LogicalLine {
        LogicalLine {
            tokens: Vec::new(),
        }
    }

    fn layout(&mut self, mut x_pos: i32) {
        if self.tokens.len() == 0 {
            return
        }

        for i in range(0, self.tokens.len()) {
            self.tokens.get_mut(i).x_pos = x_pos;
            x_pos += self.tokens.get(i).length();

            if i < self.tokens.len() - 1 &&
                    self.tokens.get(i).whitespace_needed_after(self.tokens.get(i + 1)) {
                x_pos += 1;
            }
        }
    }

    fn whitespace_after(&self, index: uint) -> i32 {
        if self.tokens.len() <= 1 || index >= self.tokens.len() - 1 {
            return 0
        }

        self.tokens.get(index + 1).x_pos - (self.tokens.get(index).x_pos +
                                            self.tokens.get(index).length())
    }

    fn postindentation(&self) -> i32 {
        match self.tokens.as_slice().last() {
            None => 0,
            Some(line_token) => {
                match line_token.token_and_span.tok {
                    token::LBRACE => TAB_WIDTH,
                    _ => 0,
                }
            }
        }
    }
}

struct Formatter<'a> {
    lexer: StringReader<'a>,
    indent: i32,
    logical_line: LogicalLine,
    last_token: Token,
    newline_after_comma: bool,
}

impl<'a> Formatter<'a> {
    fn new<'a>(lexer: StringReader<'a>) -> Formatter<'a> {
        Formatter {
            lexer: lexer,
            indent: 0,
            logical_line: LogicalLine::new(),
            last_token: token::SEMI,
            newline_after_comma: false,
        }
    }

    fn token_ends_logical_line(&self, line_token: &LineToken) -> bool {
        match line_token.token_and_span.tok {
            token::LBRACE | token::SEMI | token::RBRACE => true,
            token::COMMA => self.newline_after_comma,
            _ => false,
        }
    }

    fn parse_tokens_up_to(&mut self, pred: |&token::Token| -> bool) -> bool {
        while self.next_token() {
            if pred(&self.last_token) {
                return true;
            }
        }
        return false;
    }

    fn parse_productions_up_to(&mut self, pred: |&token::Token| -> bool) -> bool {
        while self.next_token() {
            if pred(&self.last_token) {
                return true;
            }
            self.parse_production();
        }
        return false;
    }

    fn parse_match(&mut self) -> bool {
        // We've already parsed the keyword. Parse until we find a `{`.
        if !self.parse_tokens_up_to(|token| *token == token::LBRACE) {
            return false;
        }

        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        if !self.parse_productions_up_to(|token| *token == token::RBRACE) {
            return false;
        }

        self.newline_after_comma = old_newline_after_comma_setting;
        return true;
    }

    fn parse_braces(&mut self) -> bool {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        // We've already parsed the '{'. Parse until we find a '}'.
        let result = self.parse_productions_up_to(|token| *token == token::RBRACE);

        self.newline_after_comma = old_newline_after_comma_setting;
        return result;
    }

    fn parse_parentheses(&mut self) -> bool {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = false;

        // We've already parsed the '('. Parse until we find a ')'.
        let result = self.parse_productions_up_to(|token| *token == token::RPAREN);

        self.newline_after_comma = old_newline_after_comma_setting;
        return result;
    }

    fn parse_production(&mut self) -> bool {
        let production_to_parse;
        match self.last_token {
            token::IDENT(..) if token::is_keyword(keywords::Match, &self.last_token) => {
                production_to_parse = MatchProduction;
            }
            token::LBRACE => production_to_parse = BracesProduction,
            token::LPAREN => production_to_parse = ParenthesesProduction,
            _ => return true,
        }

        match production_to_parse {
            MatchProduction => return self.parse_match(),
            BracesProduction => return self.parse_braces(),
            ParenthesesProduction => return self.parse_parentheses(),
        }
    }

    fn next_token(&mut self) -> bool {
        use syntax::parse::lexer::Reader;

        loop {
            if self.lexer.is_eof() {
                return false;
            }

            let last_token = self.lexer.peek();
            self.last_token = last_token.tok.clone();
            let line_token = LineToken::new(last_token);
            if line_token.starts_logical_line() && self.logical_line.tokens.len() > 0 {
                self.flush_line();
                continue;
            }

            if self.logical_line.tokens.len() == 0 {
                self.indent += line_token.preindentation();
            }

            drop(self.lexer.next_token());
            let token_ends_logical_line = self.token_ends_logical_line(&line_token);
            self.logical_line.tokens.push(line_token);
            if token_ends_logical_line {
                self.flush_line();
            }

            return true;
        }
    }

    fn flush_line(&mut self) {
        self.logical_line.layout(self.indent);

        for _ in range(0, self.indent) {
            print!(" ");
        }
        for i in range(0, self.logical_line.tokens.len()) {
            print!("{}", token::to_str(&self.logical_line.tokens.get(i).token_and_span.tok));
            for _ in range(0, self.logical_line.whitespace_after(i)) {
                print!(" ");
            }
        }
        println!("");

        self.indent += self.logical_line.postindentation();
        self.logical_line = LogicalLine::new();
    }
}

#[main]
pub fn main() {
    let source = io::stdin().read_to_end().unwrap();
    let source = str::from_utf8(source.as_slice()).unwrap();

    let session = parse::new_parse_sess();
    let filemap = parse::string_to_filemap(&session, source.to_strbuf(), "<stdin>".to_strbuf());
    let lexer = lexer::new_string_reader(&session.span_diagnostic, filemap);
    let mut formatter = Formatter::new(lexer);

    while formatter.next_token() {
        formatter.parse_production();
    }
}

<commit_msg>Fix a few bugs<commit_after>// rustfmt/main.rs

use std::io;
use std::str;
use syntax::parse::lexer::{StringReader, TokenAndSpan};
use syntax::parse::lexer;
use syntax::parse::token::Token;
use syntax::parse::token::keywords;
use syntax::parse::token;
use syntax::parse;

static TAB_WIDTH: i32 = 4;

enum ProductionToParse {
    MatchProduction,
    UseProduction,
    BracesProduction,
    ParenthesesProduction,
}

struct LineToken {
    token_and_span: TokenAndSpan,
    x_pos: i32,
}

impl LineToken {
    fn new(token_and_span: TokenAndSpan) -> LineToken {
        LineToken {
            token_and_span: token_and_span,
            x_pos: 0,
        }
    }

    fn whitespace_needed_after(&self, next: &LineToken) -> bool {
        match (&self.token_and_span.tok, &next.token_and_span.tok) {
            (&token::IDENT(..), &token::IDENT(..)) => true,
            (&token::IDENT(..), &token::NOT)
                    if !token::is_any_keyword(&self.token_and_span.tok) => {
                // Macros.
                false
            }

            (&token::IDENT(..), _) if
                    token::is_keyword(keywords::If, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::As, &self.token_and_span.tok) ||
                    token::is_keyword(keywords::Match, &self.token_and_span.tok) => {
                true
            }
            (_, &token::IDENT(..))
                    if token::is_keyword(keywords::If, &next.token_and_span.tok) => {
                true
            }

            (&token::COLON, _) => true,
            (&token::COMMA, _) => true,
            (&token::EQ, _) | (_, &token::EQ) => true,
            (&token::LT, _) | (_, &token::LT) => true,
            (&token::LE, _) | (_, &token::LE) => true,
            (&token::EQEQ, _) | (_, &token::EQEQ) => true,
            (&token::NE, _) | (_, &token::NE) => true,
            (&token::GE, _) | (_, &token::GE) => true,
            (&token::GT, _) | (_, &token::GT) => true,
            (&token::ANDAND, _) | (_, &token::ANDAND) => true,
            (&token::OROR, _) | (_, &token::OROR) => true,
            (&token::TILDE, _) | (_, &token::TILDE) => true,

            (&token::LPAREN, _) => false,
            (_, &token::RPAREN) => false,
            (&token::BINOP(token::AND), _) => false,

            (&token::BINOP(_), _) | (_, &token::BINOP(_)) => true,
            (&token::BINOPEQ(_), _) | (_, &token::BINOPEQ(_)) => true,

            (&token::MOD_SEP, _) | (_, &token::MOD_SEP) => false,

            (&token::RARROW, _) | (_, &token::RARROW) => true,
            (&token::FAT_ARROW, _) | (_, &token::FAT_ARROW) => true,
            (&token::LBRACE, _) | (_, &token::LBRACE) => true,
            (&token::RBRACE, _) | (_, &token::RBRACE) => true,
            _ => false,
        }
    }

    fn length(&self) -> i32 {
        token::to_str(&self.token_and_span.tok).len() as i32
    }

    fn preindentation(&self) -> i32 {
        match self.token_and_span.tok {
            token::RBRACE => -TAB_WIDTH,
            _ => 0,
        }
    }
}

struct LogicalLine {
    tokens: Vec<LineToken>,
}

impl LogicalLine {
    fn new() -> LogicalLine {
        LogicalLine {
            tokens: Vec::new(),
        }
    }

    fn layout(&mut self, mut x_pos: i32) {
        if self.tokens.len() == 0 {
            return
        }

        for i in range(0, self.tokens.len()) {
            self.tokens.get_mut(i).x_pos = x_pos;
            x_pos += self.tokens.get(i).length();

            if i < self.tokens.len() - 1 &&
                    self.tokens.get(i).whitespace_needed_after(self.tokens.get(i + 1)) {
                x_pos += 1;
            }
        }
    }

    fn whitespace_after(&self, index: uint) -> i32 {
        if self.tokens.len() <= 1 || index >= self.tokens.len() - 1 {
            return 0
        }

        self.tokens.get(index + 1).x_pos - (self.tokens.get(index).x_pos +
                                            self.tokens.get(index).length())
    }

    fn postindentation(&self) -> i32 {
        match self.tokens.as_slice().last() {
            None => 0,
            Some(line_token) => {
                match line_token.token_and_span.tok {
                    token::LBRACE => TAB_WIDTH,
                    _ => 0,
                }
            }
        }
    }
}

struct Formatter<'a> {
    lexer: StringReader<'a>,
    indent: i32,
    logical_line: LogicalLine,
    last_token: Token,
    newline_after_comma: bool,
    newline_after_brace: bool,
}

impl<'a> Formatter<'a> {
    fn new<'a>(lexer: StringReader<'a>) -> Formatter<'a> {
        Formatter {
            lexer: lexer,
            indent: 0,
            logical_line: LogicalLine::new(),
            last_token: token::SEMI,
            newline_after_comma: false,
            newline_after_brace: true,
        }
    }

    fn token_ends_logical_line(&self, line_token: &LineToken) -> bool {
        match line_token.token_and_span.tok {
            token::SEMI | token::RBRACE => true,
            token::COMMA => self.newline_after_comma,
            token::LBRACE => self.newline_after_brace,
            _ => false,
        }
    }

    fn token_starts_logical_line(&self, line_token: &LineToken) -> bool {
        match line_token.token_and_span.tok {
            token::RBRACE => self.newline_after_brace,
            _ => false,
        }
    }

    fn parse_tokens_up_to(&mut self, pred: |&token::Token| -> bool) -> bool {
        while self.next_token() {
            if pred(&self.last_token) {
                return true;
            }
        }
        return false;
    }

    fn parse_productions_up_to(&mut self, pred: |&token::Token| -> bool) -> bool {
        while self.next_token() {
            if pred(&self.last_token) {
                return true;
            }
            self.parse_production();
        }
        return false;
    }

    fn parse_match(&mut self) -> bool {
        // We've already parsed the keyword. Parse until we find a `{`.
        if !self.parse_tokens_up_to(|token| *token == token::LBRACE) {
            return false;
        }

        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        if !self.parse_productions_up_to(|token| *token == token::RBRACE) {
            return false;
        }

        self.newline_after_comma = old_newline_after_comma_setting;
        return true;
    }

    fn parse_use(&mut self) -> bool {
        let old_newline_after_brace_setting = self.newline_after_brace;
        self.newline_after_brace = false;

        // We've already parsed the keyword. Parse until we find a `{`.
        if !self.parse_tokens_up_to(|token| *token == token::LBRACE || *token == token::SEMI) {
            return false;
        }

        if self.last_token == token::LBRACE {
            let old_newline_after_comma_setting = self.newline_after_comma;
            self.newline_after_comma = false;

            if !self.parse_productions_up_to(|token| *token == token::RBRACE) {
                return false;
            }

            self.newline_after_comma = old_newline_after_comma_setting;
        }

        self.newline_after_brace = old_newline_after_brace_setting;
        return true;
    }

    fn parse_braces(&mut self) -> bool {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = true;

        // We've already parsed the '{'. Parse until we find a '}'.
        let result = self.parse_productions_up_to(|token| *token == token::RBRACE);

        self.newline_after_comma = old_newline_after_comma_setting;
        return result;
    }

    fn parse_parentheses(&mut self) -> bool {
        let old_newline_after_comma_setting = self.newline_after_comma;
        self.newline_after_comma = false;

        // We've already parsed the '('. Parse until we find a ')'.
        let result = self.parse_productions_up_to(|token| *token == token::RPAREN);

        self.newline_after_comma = old_newline_after_comma_setting;
        return result;
    }

    fn parse_production(&mut self) -> bool {
        let production_to_parse;
        match self.last_token {
            token::IDENT(..) if token::is_keyword(keywords::Match, &self.last_token) => {
                production_to_parse = MatchProduction;
            }
            token::IDENT(..) if token::is_keyword(keywords::Use, &self.last_token) => {
                production_to_parse = UseProduction;
            }
            token::LBRACE => production_to_parse = BracesProduction,
            token::LPAREN => production_to_parse = ParenthesesProduction,
            _ => return true,
        }

        match production_to_parse {
            MatchProduction => return self.parse_match(),
            UseProduction => return self.parse_use(),
            BracesProduction => return self.parse_braces(),
            ParenthesesProduction => return self.parse_parentheses(),
        }
    }

    fn next_token(&mut self) -> bool {
        use syntax::parse::lexer::Reader;

        loop {
            if self.lexer.is_eof() {
                return false;
            }

            let last_token = self.lexer.peek();
            self.last_token = last_token.tok.clone();
            let line_token = LineToken::new(last_token);
            if self.token_starts_logical_line(&line_token) && self.logical_line.tokens.len() > 0 {
                self.flush_line();
                continue;
            }

            if self.logical_line.tokens.len() == 0 {
                self.indent += line_token.preindentation();
            }

            drop(self.lexer.next_token());
            let token_ends_logical_line = self.token_ends_logical_line(&line_token);
            self.logical_line.tokens.push(line_token);
            if token_ends_logical_line {
                self.flush_line();
            }

            return true;
        }
    }

    fn flush_line(&mut self) {
        self.logical_line.layout(self.indent);

        for _ in range(0, self.indent) {
            print!(" ");
        }
        for i in range(0, self.logical_line.tokens.len()) {
            print!("{}", token::to_str(&self.logical_line.tokens.get(i).token_and_span.tok));
            for _ in range(0, self.logical_line.whitespace_after(i)) {
                print!(" ");
            }
        }
        println!("");

        self.indent += self.logical_line.postindentation();
        self.logical_line = LogicalLine::new();
    }
}

#[main]
pub fn main() {
    let source = io::stdin().read_to_end().unwrap();
    let source = str::from_utf8(source.as_slice()).unwrap();

    let session = parse::new_parse_sess();
    let filemap = parse::string_to_filemap(&session, source.to_strbuf(), "<stdin>".to_strbuf());
    let lexer = lexer::new_string_reader(&session.span_diagnostic, filemap);
    let mut formatter = Formatter::new(lexer);

    while formatter.next_token() {
        formatter.parse_production();
    }
}

<|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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:
```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:
```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:
```
extern a;
extern crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:
```
extern a;
extern crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,
```
extern abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##

}

register_diagnostics! {
    E0157,
    E0153,
    E0251, // a named type or value has already been imported in this module
    E0252, // a named type or value has already been imported in this module
    E0253, // not directly importable
    E0254, // import conflicts with imported crate in this module
    E0255, // import conflicts with value in this module
    E0256, // import conflicts with type in this module
    E0257, // inherent implementations are only allowed on types defined in the current module
    E0258, // import conflicts with existing submodule
    E0364, // item is private
    E0365  // item is private
}
<commit_msg>Add missing keyword in `extern crate` declarations.<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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0154: r##"
Imports (`use` statements) are not allowed after non-item statements, such as
variable declarations and expression statements.

Here is an example that demonstrates the error:
```
fn f() {
    // Variable declaration before import
    let x = 0;
    use std::io::Read;
    ...
}
```

The solution is to declare the imports at the top of the block, function, or
file.

Here is the previous example again, with the correct order:
```
fn f() {
    use std::io::Read;
    let x = 0;
    ...
}
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0259: r##"
The name chosen for an external crate conflicts with another external crate that
has been imported into the current module.

Wrong example:
```
extern crate a;
extern crate crate_a as a;
```

The solution is to choose a different name that doesn't conflict with any
external crate imported into the current module.

Correct example:
```
extern crate a;
extern crate crate_a as other_name;
```
"##,

E0260: r##"
The name for an item declaration conflicts with an external crate's name.

For instance,
```
extern crate abc;

struct abc;
```

There are two possible solutions:

Solution #1: Rename the item.

```
extern crate abc;

struct xyz;
```

Solution #2: Import the crate with a different name.

```
extern crate abc as xyz;

struct abc;
```

See the Declaration Statements section of the reference for more information
about what constitutes an Item declaration and what does not:

http://doc.rust-lang.org/reference.html#statements
"##,

E0317: r##"
User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type.

See the Types section of the reference for more information about the primitive
types:

http://doc.rust-lang.org/reference.html#types
"##

}

register_diagnostics! {
    E0157,
    E0153,
    E0251, // a named type or value has already been imported in this module
    E0252, // a named type or value has already been imported in this module
    E0253, // not directly importable
    E0254, // import conflicts with imported crate in this module
    E0255, // import conflicts with value in this module
    E0256, // import conflicts with type in this module
    E0257, // inherent implementations are only allowed on types defined in the current module
    E0258, // import conflicts with existing submodule
    E0364, // item is private
    E0365  // item is private
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

// xfail-test
struct HTMLImageData {
    image: Option<~str>
}

struct ElementData {
    kind: ~ElementKind
}

enum ElementKind {
    HTMLImageElement(HTMLImageData)
}

enum NodeKind {
    Element(ElementData)
}

enum NodeData = {
    kind: ~NodeKind
};

fn main() {
    let mut id = HTMLImageData { image: None };
    let ed = ElementData { kind: ~HTMLImageElement(id) };
    let n = NodeData({kind : ~Element(ed)});
    match n.kind {
        ~Element(ed) => match ed.kind {
            ~HTMLImageElement(d) if d.image.is_some() => { true }
        },
        _ => fail!(~"WAT") //~ ERROR wat
    };
}
<commit_msg>testsuite: Update and un-xfail #3601 test<commit_after>// Copyright 2012-2013 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.

struct HTMLImageData {
    image: Option<~str>
}

struct ElementData {
    kind: ~ElementKind
}

enum ElementKind {
    HTMLImageElement(HTMLImageData)
}

enum NodeKind {
    Element(ElementData)
}

struct NodeData {
    kind: ~NodeKind
}

fn main() {
    let mut id = HTMLImageData { image: None };
    let ed = ElementData { kind: ~HTMLImageElement(id) };
    let n = NodeData {kind : ~Element(ed)};
    // n.b. span could be better
    match n.kind {
        ~Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
            ~HTMLImageElement(ref d) if d.image.is_some() => { true }
        },
        _ => fail!(~"WAT") //~ ERROR unreachable pattern
    };
}
<|endoftext|>


<commit_before>use std::io::{fs, IoResult};
use file::File;

// The purpose of a Dir is to provide a cached list of the file paths
// in the directory being searched for. This object is then passed to
// the Files themselves, which can then check the status of their
// surrounding files, such as whether it needs to be coloured
// differently if a certain other file exists.

pub struct Dir<'a> {
    contents: Vec<Path>,
}

impl<'a> Dir<'a> {
    pub fn readdir(path: Path) -> IoResult<Dir<'a>> {
        fs::readdir(&path).map(|paths| Dir {
            contents: paths,
        })
    }

    pub fn files(&'a self) -> Vec<File<'a>> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, self) {
                Ok(file) => {
                    files.push(file);
                }
                Err(e) => {
                    println!("{}: {}", path.filename_str().unwrap(), e);
                }
            }
        }

        files
    }

    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }
}

<commit_msg>Actually display is better used here<commit_after>use std::io::{fs, IoResult};
use file::File;

// The purpose of a Dir is to provide a cached list of the file paths
// in the directory being searched for. This object is then passed to
// the Files themselves, which can then check the status of their
// surrounding files, such as whether it needs to be coloured
// differently if a certain other file exists.

pub struct Dir<'a> {
    contents: Vec<Path>,
}

impl<'a> Dir<'a> {
    pub fn readdir(path: Path) -> IoResult<Dir<'a>> {
        fs::readdir(&path).map(|paths| Dir {
            contents: paths,
        })
    }

    pub fn files(&'a self) -> Vec<File<'a>> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, self) {
                Ok(file) => {
                    files.push(file);
                }
                Err(e) => {
                    println!("{}: {}", path.display(), e);
                }
            }
        }

        files
    }

    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }
}

<|endoftext|>


<commit_before><commit_msg>Initial import<commit_after>#![feature(globs)]
#![crate_id = "rmdb"]
#![crate_type = "rlib"]
#![crate_type = "staticlib"] // for now
#![allow(non_camel_case_types)]
#![allow(dead_code)] // TODO: remove it once wrapper complete

extern crate libc;

#[link(name = "mdb")]
extern {}

pub mod mdb {
    use libc::{c_int, c_uint, size_t, c_char, c_void, c_uchar, c_ushort, off_t};
    use libc::types::os::common::posix01::pthread_t;

    pub use self::consts::*;
    use self::os::*;

    pub mod consts {
        use libc::{c_int, c_uint};

        // Return codes
        pub static MDB_SUCCESS: c_int = 0;
        pub static MDB_KEYEXIST: c_int = -30799;
        pub static MDB_NOTFOUND: c_int = -30798;
        pub static MDB_PAGE_NOTFOUND: c_int = -30797;
        pub static MDB_CORRUPTED: c_int = -30796;
        pub static MDB_PANIC: c_int = -30795;
        pub static MDB_VERSION_MISMATCH: c_int = -30794;
        pub static MDB_INVALID: c_int = -30793;
        pub static MDB_MAP_FULL: c_int = -30792;
        pub static MDB_DBS_FULL: c_int = -30791;
        pub static MDB_READERS_FULL: c_int = -30790;
        pub static MDB_TLS_FULL: c_int = -30789;
        pub static MDB_TXN_FULL: c_int = -30788;
        pub static MDB_CURSOR_FULL: c_int = -30787;
        pub static MDB_PAGE_FULL: c_int = -30786;
        pub static MDB_MAP_RESIZED: c_int = -30785;
        pub static MDB_INCOMPATIBLE: c_int = -30784;
        pub static MDB_BAD_RSLOT: c_int = -30783;
        pub static MDB_BAD_TXN: c_int = -30782;
        pub static MDB_BAD_VALSIZE: c_int = -30781;

        // Write flags
        pub static MDB_NOOVERWRITE: c_int = 0x10;
        pub static MDB_NODUPDATA: c_int = 0x20;
        pub static MDB_CURRENT: c_int = 0x40;
        pub static MDB_RESERVE: c_int = 0x10000;
        pub static MDB_APPEND: c_int = 0x20000;
        pub static MDB_APPENDDUP: c_int = 0x40000;
        pub static MDB_MULTIPLE: c_int = 0x80000;

        // Database flags
        pub static MDB_REVERSEKEY: c_uint = 0x02;
        pub static MDB_DUPSORT: c_uint = 0x04;
        pub static MDB_INTEGERKEY: c_uint = 0x08;
        pub static MDB_DUPFIXED: c_uint = 0x10;
        pub static MDB_INTEGERDUP: c_uint = 0x20;
        pub static MDB_REVERSEDUP: c_uint =  0x40;
        pub static MDB_CREATE: c_uint = 0x40000;

        // Environment flags
         pub static MDB_FIXEDMAP: c_uint =  0x01;
        pub static MDB_NOSUBDIR: c_uint = 0x4000;
        pub static MDB_NOSYNC: c_uint = 0x10000;
        pub static MDB_RDONLY: c_uint = 0x20000;
        pub static MDB_NOMETASYNC: c_uint = 0x40000;
        pub static MDB_WRITEMAP: c_uint = 0x80000;
        pub static MDB_MAPASYNC: c_uint = 0x100000;
        pub static MDB_NOTLS: c_uint = 0x200000;
        pub static MDB_NOLOCK: c_uint =  0x400000;
        pub static MDB_NORDAHEAD: c_uint = 0x800000;
        pub static MDB_NOMEMINIT: c_uint =  0x1000000;
    }

    #[cfg(target_os = "macos")]
    #[cfg(target_os = "ios")]
    #[cfg(target_os = "linux")]
    #[cfg(target_os = "freebsd")]
    #[cfg(target_os = "android")]
    mod os {
        use libc::{c_ulong, c_int, mode_t, pid_t};
        pub use self::mutex::pthread_mutex_t;

        #[cfg(target_os = "macos")]
        pub type pthread_key_t = c_ulong;
        #[cfg(not(target_os = "macos"))]
        pub type pthread_key_t = c_uint;

        pub type mdb_mode_t = mode_t;
        pub type mdb_filehandle_t = c_int;
        pub type MDB_PID_T = pid_t;

        // TODO: avoid duplication of pthread_mutex_t declaration
        // It should be somehow extracted from std::unstable::mutex
        #[cfg(target_os = "freebsd")]
        mod mutex {
            use libc;
            pub type pthread_mutex_t = *libc::c_void;
        }

        #[cfg(target_os = "macos")]
        #[cfg(target_os = "ios")]
        mod mutex {
            use libc;

            #[cfg(target_arch = "x86_64")]
            static __PTHREAD_MUTEX_SIZE__: uint = 56;
            #[cfg(target_arch = "x86")]
            static __PTHREAD_MUTEX_SIZE__: uint = 40;
            #[cfg(target_arch = "arm")]
            static __PTHREAD_MUTEX_SIZE__: uint = 40;

            pub struct pthread_mutex_t {
            __sig: libc::c_long,
            __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
            }
        }

        #[cfg(target_os = "linux")]
        mod os {
            use libc;

            // minus 8 because we have an 'align' field
            #[cfg(target_arch = "x86_64")]
            static __SIZEOF_PTHREAD_MUTEX_T: uint = 40 - 8;
            #[cfg(target_arch = "x86")]
            static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
            #[cfg(target_arch = "arm")]
            static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;
            #[cfg(target_arch = "mips")]
            static __SIZEOF_PTHREAD_MUTEX_T: uint = 24 - 8;

            pub struct pthread_mutex_t {
                __align: libc::c_longlong,
                size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
            }

        }
        #[cfg(target_os = "android")]
        mod os {
            use libc;

            pub struct pthread_mutex_t { value: libc::c_int }
            pub struct pthread_cond_t { value: libc::c_int }
        }
    }

    #[cfg(target_os = "windows")]
    mod os {
        use libc::{c_int, c_void};

        pub type mdb_mode_t = c_int;
        pub type mdb_filehandle_t = *c_void;
        pub type pthread_key_t = u32;
        pub type pthread_mutex_t = c_int;
    }

    type pgno_t = MDB_ID;
    type txnid_t = MDB_ID;
    type indx_t = u16;

    type MDB_dbi = c_uint;
    type MDB_ID = size_t;
    type MDB_IDL = *MDB_ID;

    type MDB_rel_func = fn(*MDB_val, *c_void, *c_void, *c_void);
    type MDB_msg_func = fn(*c_char, *c_void) -> c_int;
    type MDB_cmp_func = fn(*MDB_val, *MDB_val) -> c_int;

    type HANDLE = c_int;

    struct MDB_ID2 {
        mid: MDB_ID,
        mptr: *c_void
    }

    type MDB_ID2L = *MDB_ID2;

    struct MDB_val {
        mv_size: size_t,
        mv_data: *c_void,
    }

    struct MDB_rxbody {
        mrb_txnid: txnid_t,
        mrb_pid: MDB_PID_T,
        mrb_tid: pthread_t
    }

    /*
    enum MDB_reader_mru {
        mrx: MDB_rxbody,
        pad: char[] // PADDING
    }

    struct MDB_reader {
        mru: MDB_reader_mru
    }
    */

    struct MDB_txbody {
        mtb_magic: u32,
        mtb_format: u32,
        mtb_mutx: pthread_mutex_t,
        mtb_txnid: txnid_t,
        mtb_numreaders: c_uint
    }

    /*
    enum MDB_txninfo_mt1 {
        mtb: MDB_txbody,
        pad: c_char[] // PADDING
    }

    enum MDB_txninfo_mt2{
        mt2_wmutex: pthread_mutex_t,
        pad: c_char[] // PADDING
    }

    struct MDB_txninfo {
        mt1: MDB_txninfo_mt1,
        mt2: MDB_txninfo_mt2,
        mti_readers: [MDB_reader, ..1]
    }
    */

    struct MDB_pgstate {
        mf_pghead: *pgno_t,
        mf_pglast: txnid_t
    }

    /*
    enum MDB_page_p {
        p_pgno: pgno_t,
        p_next: *c_void
    }

    enum MDB_page_pb {
        struct {
            pb_lower: indx_t,
            pb_upper: indx_t
        },
        pb_pages: u32
    }
    */

    struct MDB_page {
        mp_p: size_t,
        mp_pad: u16,
        mp_flags: u16,
        mp_pb: u32,/*MDB_page_pb,*/
        mp_ptrs: [indx_t, ..1]
    }

    struct MDB_meta {
        mm_magic: u32,
        mm_version: u32,
        mm_address: *c_void,
        mm_mapsize: size_t,
        mm_dbs: [MDB_db, ..2],
        mm_last_pg: pgno_t,
        mm_txnid: txnid_t
    }

    struct MDB_env {
        me_fd: HANDLE,
        me_lfd: HANDLE,
        me_mfd: HANDLE,
        me_flags: u32,
        me_psize: c_uint,
        me_os_psize: c_uint,
        me_maxreaders: c_uint,
        me_numreaders: c_uint,
        me_numdbs: MDB_dbi,
        me_maxdbs: MDB_dbi,
        me_pid: MDB_PID_T,
        me_path: *c_char,
        me_map: *c_char,
        me_txns: *c_void,//MDB_txninfo,
        me_metas: [*MDB_meta, ..2],
        me_pbuf: *c_void,
        me_txn: *MDB_txn,
        me_mapsize: size_t,
        me_size: off_t,
        me_maxpg: pgno_t,
        me_dbxs: *MDB_dbx,
        me_dbflags: *u16,
        me_txkey: pthread_key_t,
        me_pgstate: MDB_pgstate,
        me_dpages: *MDB_page,
        me_free_pgs: MDB_IDL,
        me_dirty_list: MDB_ID2L,
        me_maxfree_1pg: c_int,
        me_nodemax: c_uint
    }

    struct MDB_db {
        md_pad: u32,
        md_flags: u16,
        md_depth: u16,
        md_branch_pages: pgno_t,
        md_leaf_pages: pgno_t,
        md_overflow_pages: pgno_t,
        md_entries: size_t,
        md_root: pgno_t
    }

    struct MDB_dbx {
        md_name: MDB_val,
        md_cmp: *MDB_cmp_func,
        md_dcmp: *MDB_cmp_func,
        md_rel: *MDB_rel_func,
        md_relctx: c_void
    }

    struct MDB_txn {
        mt_parent: *MDB_txn,
        mt_child: *MDB_txn,
        mt_next_pgno: pgno_t,
        mt_txnid: txnid_t,
        mt_env: *MDB_env,
        mt_free_pgs: MDB_IDL,
        mt_spill_pgs: MDB_IDL,
        mt_u: *c_void, /*enum {
            dirty_list: MDB_ID2L,
            reader: *MDB_reader
        },*/
        mt_dbxs: *MDB_dbx,
        mt_dbs: *MDB_db,
        mt_cursors: **MDB_cursor,
        mt_dbflags: *c_uchar,
        mt_numdbs: MDB_dbi,
        mt_flags: c_uint,
        mt_dirty_room: c_uint
    }

    struct MDB_stat {
        ms_psize: c_uint,
        ms_depth: c_uint,
        ms_branch_pages: size_t,
        ms_leaf_pages: size_t,
        ms_overflow_pages: size_t,
        ms_entries: size_t
    }

    struct MDB_envinfo {
        me_mapaddr: *c_void,
        me_mapsize: size_t,
        me_last_pgno: size_t,
        me_last_txnid: size_t,
        me_maxreaders: c_uint,
        me_numreaders: c_uint
    }

    #[repr(C)]
    enum MDB_cursor_op {
        MDB_FIRST,
        MDB_FIRST_DUP,
        MDB_GET_BOTH,
        MDB_GET_BOTH_RANGE,
        MDB_GET_CURRENT,
        MDB_GET_MULTIPLE,
        MDB_LAST,
        MDB_LAST_DUP,
        MDB_NEXT,
        MDB_NEXT_DUP,
        MDB_NEXT_MULTIPLE,
        MDB_NEXT_NODUP,
        MDB_PREV,
        MDB_PREV_DUP,
        MDB_PREV_NODUP,
        MDB_SET,
        MDB_SET_KEY,
        MDB_SET_RANGE

    }

    struct MDB_cursor {
        mc_next: *MDB_cursor,
        mc_backup: *MDB_cursor,
        mc_xcursor: *MDB_xcursor,
        mc_txn: *MDB_txn,
        mc_dbi: MDB_dbi,
        mc_db: *MDB_db,
        mc_dbx: *MDB_dbx,
        mc_dbflag: *c_uchar,
        mc_snum: c_ushort,
        mc_top: c_ushort,
        mc_flags: c_uint,
        mp_pg: *MDB_page,
        mc_ki: indx_t
    }

    struct MDB_xcursor {
        mx_cursor: MDB_cursor,
        mx_db: MDB_db,
        mx_dbx: MDB_dbx,
        mx_dbflag: c_uchar,
    }

    extern "C" {
        fn mdb_version(major: *c_int, minor: *c_int, patch: *c_int) -> *c_char;
        fn mdb_stderror(err: c_int) -> *c_char;
        fn mdb_env_create(env: **MDB_env) -> c_int;
        fn mdb_env_open(env: *MDB_env, path: *c_char, flags: c_uint, mode: mdb_mode_t) -> c_int;
        fn mdb_env_copy(env: *MDB_env, path: *c_char) -> c_int;
        fn mdb_env_copyfd(env: *MDB_env, fd: mdb_filehandle_t) -> c_int;
        fn mdb_env_stat(env: *MDB_env, stat: *MDB_stat) -> c_int;
        fn mdb_env_info(env: *MDB_env, info: *MDB_envinfo) -> c_int;
        fn mdb_env_sync(env: *MDB_env, force: c_int) -> c_int;
        fn mdb_env_close(env: *MDB_env);
        fn mdb_env_set_flags(env: *MDB_env, flags: c_uint, onoff: c_int) -> c_int;
        fn mdb_env_get_flags(env: *MDB_env, flags: c_uint) -> c_int;
        fn mdb_env_get_path(env: *MDB_env, path: **c_char) -> c_int;
        fn mdb_env_get_fd(env: *MDB_env, fd: *mdb_filehandle_t) -> c_int;
        fn mdb_env_set_mapsize(env: *MDB_env, size: size_t) -> c_int;
        fn mdb_env_set_maxreaders(env: *MDB_env, readers: c_uint) -> c_int;
        fn mdb_env_get_maxreaders(env: *MDB_env, readers: *c_uint) -> c_int;
        fn mdb_env_set_maxdbs(env: *MDB_env, dbs: MDB_dbi) -> c_int;
        fn mdb_env_get_maxkeysize(env: *MDB_env) -> c_int;
        fn mdb_txn_begin(env: *MDB_env, parent: *MDB_txn, flags: c_uint, txn: **MDB_txn) -> c_int;
        fn mdb_txn_env(txn: *MDB_txn) -> *MDB_env;
        fn mdb_txn_commit(txn: *MDB_txn) -> c_int;
        fn mdb_txn_abort(txn: *MDB_txn);
        fn mdb_txn_reset(txn: *MDB_txn);
        fn mdb_txn_renew(txn: *MDB_txn) -> c_int;
        fn mdb_dbi_open(txn: *MDB_txn, name: **c_char, flags: c_uint, dbi: *MDB_dbi) -> c_int;
        fn mdb_stat(txn: *MDB_txn, dbi: MDB_dbi, stat: *MDB_stat) -> c_int;
        fn mdb_dbi_flags(txn: *MDB_txn, dbi: MDB_dbi, flags: *c_uint) -> c_int;
        fn mdb_dbi_close(txn: *MDB_txn, dbi: MDB_dbi);
        fn mdb_drop(txn: *MDB_txn, dbi: MDB_dbi, del: c_int) -> c_int;
        fn mdb_set_compare(txn: *MDB_txn, dbi: MDB_dbi, cmp: MDB_cmp_func) -> c_int;
        fn mdb_set_dupsort(txn: *MDB_txn, dbi: MDB_dbi, cmp: MDB_cmp_func) -> c_int;
        fn mdb_set_relfunc(txn: *MDB_txn, dbi: MDB_dbi, rel: MDB_rel_func) -> c_int;
        fn mdb_set_relctx(txn: *MDB_txn, dbi: MDB_dbi, ctx: *c_void) -> c_int;
        fn mdb_get(txn: *MDB_txn, dbi: MDB_dbi, key: *MDB_val, data: *MDB_val) -> c_int;
        fn mdb_put(txn: *MDB_txn, dbi: MDB_dbi, key: *MDB_val, data: *MDB_val, flags: c_uint) -> c_int;
        fn mdb_del(txn: *MDB_txn, dbi: MDB_dbi, key: *MDB_val, data: *MDB_val) -> c_int;
        fn mdb_cursor_open(txn: *MDB_txn, dbi: MDB_dbi, cursor: **MDB_cursor) -> c_int;
        fn mdb_cursor_close(cursor: *MDB_cursor) -> c_int;
        fn mdb_cursor_renew(txn: *MDB_txn, cursor: *MDB_cursor) -> c_int;
        fn mdb_cursor_txn(cursor: *MDB_cursor) -> *MDB_txn;
        fn mdb_cursor_dbi(cursor: *MDB_cursor) -> *MDB_dbi;
        fn mdb_cursor_get(cursor: *MDB_cursor, key: *MDB_val, data: *MDB_val, op: MDB_cursor_op) -> c_int;
        fn mdb_cursor_put(cursor: *MDB_cursor, key: *MDB_val, data: *MDB_val, flags: c_uint) -> c_int;
        fn mdb_cursor_del(cursor: *MDB_cursor, flags: c_uint) -> c_int;
        fn mdb_cursor_count(cursor: *MDB_cursor, countp: *size_t) -> c_int;
        fn mdb_cmp(txn: *MDB_txn, dbi: MDB_dbi, a: *MDB_val, b: *MDB_val) -> c_int;
        fn mdb_dcmp(txn: *MDB_txn, dbi: MDB_dbi, a: *MDB_val, b: *MDB_val) -> c_int;
        fn mdb_reader_list(env: *MDB_env, func: MDB_msg_func, ctx: *c_void) -> c_int;
        fn mdb_reader_check(env: *MDB_env, dead: *c_int) -> c_int;
    }
}
<|endoftext|>


<commit_before>use core::ptr;

//
// PAGE_DIRECTORY:
// 1024 dwords pointing to page tables
// PAGE_TABLES:
// 1024 * 1024 dwords pointing to pages
// PAGE_END:
//

pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_ENTRY_SIZE: usize = 4;
pub const PAGE_SIZE: usize = 4096;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;
pub const PAGE_END: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;

/// A memory page
pub struct Page {
    /// The virtual address
    virtual_address: usize,
}

impl Page {
    /// Initialize the memory page
    pub unsafe fn init() {
        for table_i in 0..PAGE_TABLE_SIZE {
            ptr::write((PAGE_DIRECTORY + table_i * PAGE_ENTRY_SIZE) as *mut u32,
                       // TODO: Use more restrictive flags
                       (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u32 |
                       0b11 << 1 | 1); //Allow userspace, read/write, present

            for entry_i in 0..PAGE_TABLE_SIZE {
                Page::new((table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE).map_identity();
            }
        }

        asm!("mov cr3, $0
            mov $0, cr0
            or $0, $1
            mov cr0, $0"
            :
            : "r"(PAGE_DIRECTORY), "r"(0x80000000 as usize)
            : "memory"
            : "intel", "volatile");
    }

    /// Create a new memory page from a virtual address
    pub fn new(virtual_address: usize) -> Self {
        Page { virtual_address: virtual_address }
    }

    /// Get the entry address
    fn entry_address(&self) -> usize {
        let page = self.virtual_address / PAGE_SIZE;
        let table = page / PAGE_TABLE_SIZE;
        let entry = page % PAGE_TABLE_SIZE;

        PAGE_TABLES + (table * PAGE_TABLE_SIZE + entry) * PAGE_ENTRY_SIZE
    }

    /// Flush the memory page
    unsafe fn flush(&self) {
        asm!("invlpg [$0]"
            :
            : "{eax}"(self.virtual_address)
            : "memory"
            : "intel", "volatile");
    }

    /// Get the current physical address
    pub fn phys_addr(&self) -> usize {
        unsafe { (ptr::read(self.entry_address() as *mut u32) & 0xFFFFF000) as usize }
    }

    /// Get the current virtual address
    pub fn virt_addr(&self) -> usize {
        self.virtual_address & 0xFFFFF000
    }

    /// Map the memory page to a given physical memory address
    pub unsafe fn map(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                //TODO: Remove 1 << 2 which is there to allow for userspace arg access
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //read/write, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read access
    pub unsafe fn map_user_read(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //Allow userspace, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read/write access
    pub unsafe fn map_user_write(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1 << 1 | 1); //Allow userspace, read/write, present
        self.flush();
    }

    /// Map to the virtual address
    pub unsafe fn map_identity(&mut self) {
        let physical_address = self.virtual_address;
        self.map(physical_address);
    }

    /// Unmap the memory page
    pub unsafe fn unmap(&mut self) {
        ptr::write(self.entry_address() as *mut u32, 0);
        self.flush();
    }
}
<commit_msg>Move paging directory down to 0x200000<commit_after>use core::ptr;

//
// PAGE_DIRECTORY:
// 1024 dwords pointing to page tables
// PAGE_TABLES:
// 1024 * 1024 dwords pointing to pages
// PAGE_END:
//

pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_ENTRY_SIZE: usize = 4;
pub const PAGE_SIZE: usize = 4096;

pub const PAGE_DIRECTORY: usize = 0x200000;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;
pub const PAGE_END: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;

/// A memory page
pub struct Page {
    /// The virtual address
    virtual_address: usize,
}

impl Page {
    /// Initialize the memory page
    pub unsafe fn init() {
        for table_i in 0..PAGE_TABLE_SIZE {
            ptr::write((PAGE_DIRECTORY + table_i * PAGE_ENTRY_SIZE) as *mut u32,
                       // TODO: Use more restrictive flags
                       (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u32 |
                       0b11 << 1 | 1); //Allow userspace, read/write, present

            for entry_i in 0..PAGE_TABLE_SIZE {
                Page::new((table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE).map_identity();
            }
        }

        asm!("mov cr3, $0
            mov $0, cr0
            or $0, $1
            mov cr0, $0"
            :
            : "r"(PAGE_DIRECTORY), "r"(0x80000000 as usize)
            : "memory"
            : "intel", "volatile");
    }

    /// Create a new memory page from a virtual address
    pub fn new(virtual_address: usize) -> Self {
        Page { virtual_address: virtual_address }
    }

    /// Get the entry address
    fn entry_address(&self) -> usize {
        let page = self.virtual_address / PAGE_SIZE;
        let table = page / PAGE_TABLE_SIZE;
        let entry = page % PAGE_TABLE_SIZE;

        PAGE_TABLES + (table * PAGE_TABLE_SIZE + entry) * PAGE_ENTRY_SIZE
    }

    /// Flush the memory page
    unsafe fn flush(&self) {
        asm!("invlpg [$0]"
            :
            : "{eax}"(self.virtual_address)
            : "memory"
            : "intel", "volatile");
    }

    /// Get the current physical address
    pub fn phys_addr(&self) -> usize {
        unsafe { (ptr::read(self.entry_address() as *mut u32) & 0xFFFFF000) as usize }
    }

    /// Get the current virtual address
    pub fn virt_addr(&self) -> usize {
        self.virtual_address & 0xFFFFF000
    }

    /// Map the memory page to a given physical memory address
    pub unsafe fn map(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                //TODO: Remove 1 << 2 which is there to allow for userspace arg access
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //read/write, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read access
    pub unsafe fn map_user_read(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //Allow userspace, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read/write access
    pub unsafe fn map_user_write(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1 << 1 | 1); //Allow userspace, read/write, present
        self.flush();
    }

    /// Map to the virtual address
    pub unsafe fn map_identity(&mut self) {
        let physical_address = self.virtual_address;
        self.map(physical_address);
    }

    /// Unmap the memory page
    pub unsafe fn unmap(&mut self) {
        ptr::write(self.entry_address() as *mut u32, 0);
        self.flush();
    }
}
<|endoftext|>


<commit_before>use std::default;

use token::{
    Error,
    Token,
    assert_tokens,
    assert_ser_tokens,
    assert_de_tokens,
    assert_de_tokens_error
};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Default {
    a1: i32,
    #[serde(default)]
    a2: i32,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct DisallowUnknown {
    a1: i32,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")]
struct RenameStruct {
    a1: i32,
    #[serde(rename="a3")]
    a2: i32,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))]
struct RenameStructSerializeDeserialize {
    a1: i32,
    #[serde(rename(serialize="a4", deserialize="a5"))]
    a2: i32,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")]
enum RenameEnum {
    #[serde(rename="bruce_wayne")]
    Batman,
    #[serde(rename="clark_kent")]
    Superman(i8),
    #[serde(rename="diana_prince")]
    WonderWoman(i8, i8),
    #[serde(rename="barry_allan")]
    Flash {
        #[serde(rename="b")]
        a: i32,
    },
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))]
enum RenameEnumSerializeDeserialize<A> {
    #[serde(rename(serialize="dick_grayson", deserialize="jason_todd"))]
    Robin {
        a: i8,
        #[serde(rename(serialize="c", deserialize="d"))]
        b: A,
    },
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct SkipSerializingFields<A: default::Default> {
    a: i8,
    #[serde(skip_serializing, default)]
    b: A,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct SkipSerializingIfEmptyFields<A: default::Default> {
    a: i8,
    #[serde(skip_serializing_if_empty, default)]
    b: Vec<A>,
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct SkipSerializingIfNoneFields<A: default::Default> {
    a: i8,
    #[serde(skip_serializing_if_none, default)]
    b: Option<A>,
}

#[test]
fn test_default() {
    assert_de_tokens(
        &Default { a1: 1, a2: 2 },
        vec![
            Token::StructStart("Default", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a2"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &Default { a1: 1, a2: 0 },
        vec![
            Token::StructStart("Default", Some(1)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_ignore_unknown() {
    // 'Default' allows unknown. Basic smoke test of ignore...
    assert_de_tokens(
        &Default { a1: 1, a2: 2},
        vec![
            Token::StructStart("Default", Some(5)),

            Token::MapSep,
            Token::Str("whoops1"),
            Token::I32(2),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("whoops2"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(2),
            Token::SeqEnd,

            Token::MapSep,
            Token::Str("a2"),
            Token::I32(2),

            Token::MapSep,
            Token::Str("whoops3"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens_error::<DisallowUnknown>(
        vec![
            Token::StructStart("DisallowUnknown", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("whoops"),
            Token::I32(2),

            Token::MapEnd,
        ],
        Error::UnknownFieldError("whoops".to_owned())
    );
}

#[test]
fn test_rename_struct() {
    assert_tokens(
        &RenameStruct { a1: 1, a2: 2 },
        vec![
            Token::StructStart("Superhero", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a3"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_rename_struct_serialize_deserialize() {
    assert_ser_tokens(
        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
        &[
            Token::StructStart("SuperheroSer", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a4"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
        vec![
            Token::StructStart("SuperheroDe", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a5"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_rename_enum() {
    assert_tokens(
        &RenameEnum::Batman,
        vec![
            Token::EnumUnit("Superhero", "bruce_wayne"),
        ]
    );

    assert_tokens(
        &RenameEnum::Superman(0),
        vec![
            Token::EnumNewtype("Superhero", "clark_kent"),
            Token::I8(0),
        ]
    );

    assert_tokens(
        &RenameEnum::WonderWoman(0, 1),
        vec![
            Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),

            Token::SeqSep,
            Token::I8(0),

            Token::SeqSep,
            Token::I8(1),

            Token::SeqEnd,
        ]
    );

    assert_tokens(
        &RenameEnum::Flash { a: 1 },
        vec![
            Token::EnumMapStart("Superhero", "barry_allan", Some(1)),

            Token::MapSep,
            Token::Str("b"),
            Token::I32(1),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_enum_serialize_deserialize() {
    assert_ser_tokens(
        &RenameEnumSerializeDeserialize::Robin {
            a: 0,
            b: String::new(),
        },
        &[
            Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(0),

            Token::MapSep,
            Token::Str("c"),
            Token::Str(""),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &RenameEnumSerializeDeserialize::Robin {
            a: 0,
            b: String::new(),
        },
        vec![
            Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(0),

            Token::MapSep,
            Token::Str("d"),
            Token::Str(""),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_skip_serializing_fields() {
    assert_ser_tokens(
        &SkipSerializingFields {
            a: 1,
            b: 2,
        },
        &[
            Token::StructStart("SkipSerializingFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &SkipSerializingFields {
            a: 1,
            b: 0,
        },
        vec![
            Token::StructStart("SkipSerializingFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_skip_serializing_fields_if_empty() {
    assert_ser_tokens(
        &SkipSerializingIfEmptyFields::<i32> {
            a: 1,
            b: vec![],
        },
        &[
            Token::StructStart("SkipSerializingIfEmptyFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &SkipSerializingIfEmptyFields::<i32> {
            a: 1,
            b: vec![],
        },
        vec![
            Token::StructStart("SkipSerializingIfEmptyFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &SkipSerializingIfEmptyFields {
            a: 1,
            b: vec![2],
        },
        &[
            Token::StructStart("SkipSerializingIfEmptyFields", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("b"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(2),
            Token::SeqEnd,

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &SkipSerializingIfEmptyFields {
            a: 1,
            b: vec![2],
        },
        vec![
            Token::StructStart("SkipSerializingIfEmptyFields", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("b"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(2),
            Token::SeqEnd,

            Token::MapEnd,
        ]
    );
}

#[test]
fn test_skip_serializing_fields_if_none() {
    assert_ser_tokens(
        &SkipSerializingIfNoneFields::<i32> {
            a: 1,
            b: None,
        },
        &[
            Token::StructStart("SkipSerializingIfNoneFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &SkipSerializingIfNoneFields::<i32> {
            a: 1,
            b: None,
        },
        vec![
            Token::StructStart("SkipSerializingIfNoneFields", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &SkipSerializingIfNoneFields {
            a: 1,
            b: Some(2),
        },
        &[
            Token::StructStart("SkipSerializingIfNoneFields", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("b"),
            Token::Option(true),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &SkipSerializingIfNoneFields {
            a: 1,
            b: Some(2),
        },
        vec![
            Token::StructStart("SkipSerializingIfNoneFields", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("b"),
            Token::Option(true),
            Token::I32(2),

            Token::MapEnd,
        ]
    );
}
<commit_msg>refactor(tests): Rename and move some structs and enums<commit_after>use token::{
    Error,
    Token,
    assert_tokens,
    assert_ser_tokens,
    assert_de_tokens,
    assert_de_tokens_error
};

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Default {
    a1: i32,
    #[serde(default)]
    a2: i32,
}

#[test]
fn test_default() {
    assert_de_tokens(
        &Default { a1: 1, a2: 2 },
        vec![
            Token::StructStart("Default", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a2"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &Default { a1: 1, a2: 0 },
        vec![
            Token::StructStart("Default", Some(1)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapEnd,
        ]
    );
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct DenyUnknown {
    a1: i32,
}

#[test]
fn test_ignore_unknown() {
    // 'Default' allows unknown. Basic smoke test of ignore...
    assert_de_tokens(
        &Default { a1: 1, a2: 2},
        vec![
            Token::StructStart("Default", Some(5)),

            Token::MapSep,
            Token::Str("whoops1"),
            Token::I32(2),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("whoops2"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(2),
            Token::SeqEnd,

            Token::MapSep,
            Token::Str("a2"),
            Token::I32(2),

            Token::MapSep,
            Token::Str("whoops3"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens_error::<DenyUnknown>(
        vec![
            Token::StructStart("DenyUnknown", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("whoops"),
            Token::I32(2),

            Token::MapEnd,
        ],
        Error::UnknownFieldError("whoops".to_owned())
    );
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")]
struct RenameStruct {
    a1: i32,
    #[serde(rename="a3")]
    a2: i32,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))]
struct RenameStructSerializeDeserialize {
    a1: i32,
    #[serde(rename(serialize="a4", deserialize="a5"))]
    a2: i32,
}

#[test]
fn test_rename_struct() {
    assert_tokens(
        &RenameStruct { a1: 1, a2: 2 },
        vec![
            Token::StructStart("Superhero", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a3"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
        &[
            Token::StructStart("SuperheroSer", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a4"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &RenameStructSerializeDeserialize { a1: 1, a2: 2 },
        vec![
            Token::StructStart("SuperheroDe", Some(2)),

            Token::MapSep,
            Token::Str("a1"),
            Token::I32(1),

            Token::MapSep,
            Token::Str("a5"),
            Token::I32(2),

            Token::MapEnd,
        ]
    );
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename="Superhero")]
enum RenameEnum {
    #[serde(rename="bruce_wayne")]
    Batman,
    #[serde(rename="clark_kent")]
    Superman(i8),
    #[serde(rename="diana_prince")]
    WonderWoman(i8, i8),
    #[serde(rename="barry_allan")]
    Flash {
        #[serde(rename="b")]
        a: i32,
    },
}

#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename(serialize="SuperheroSer", deserialize="SuperheroDe"))]
enum RenameEnumSerializeDeserialize<A> {
    #[serde(rename(serialize="dick_grayson", deserialize="jason_todd"))]
    Robin {
        a: i8,
        #[serde(rename(serialize="c", deserialize="d"))]
        b: A,
    },
}

#[test]
fn test_rename_enum() {
    assert_tokens(
        &RenameEnum::Batman,
        vec![
            Token::EnumUnit("Superhero", "bruce_wayne"),
        ]
    );

    assert_tokens(
        &RenameEnum::Superman(0),
        vec![
            Token::EnumNewtype("Superhero", "clark_kent"),
            Token::I8(0),
        ]
    );

    assert_tokens(
        &RenameEnum::WonderWoman(0, 1),
        vec![
            Token::EnumSeqStart("Superhero", "diana_prince", Some(2)),

            Token::SeqSep,
            Token::I8(0),

            Token::SeqSep,
            Token::I8(1),

            Token::SeqEnd,
        ]
    );

    assert_tokens(
        &RenameEnum::Flash { a: 1 },
        vec![
            Token::EnumMapStart("Superhero", "barry_allan", Some(1)),

            Token::MapSep,
            Token::Str("b"),
            Token::I32(1),

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &RenameEnumSerializeDeserialize::Robin {
            a: 0,
            b: String::new(),
        },
        &[
            Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(0),

            Token::MapSep,
            Token::Str("c"),
            Token::Str(""),

            Token::MapEnd,
        ]
    );

    assert_de_tokens(
        &RenameEnumSerializeDeserialize::Robin {
            a: 0,
            b: String::new(),
        },
        vec![
            Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(0),

            Token::MapSep,
            Token::Str("d"),
            Token::Str(""),

            Token::MapEnd,
        ]
    );
}

#[derive(Debug, PartialEq, Serialize)]
struct SkipSerializingStruct<'a, B, D, E> {
    a: &'a i8,
    #[serde(skip_serializing)]
    b: B,
    #[serde(skip_serializing_if_none)]
    d: Option<D>,
    #[serde(skip_serializing_if_empty)]
    e: Vec<E>,
}

#[test]
fn test_skip_serializing_struct() {
    let a = 1;
    assert_ser_tokens(
        &SkipSerializingStruct {
            a: &a,
            b: 2,
            d: Some(4),
            e: vec![5],
        },
        &[
            Token::StructStart("SkipSerializingStruct", Some(3)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("d"),
            Token::Option(true),
            Token::I32(4),

            Token::MapSep,
            Token::Str("e"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(5),
            Token::SeqEnd,

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &SkipSerializingStruct {
            a: &a,
            b: 2,
            d: None::<u8>,
            e: Vec::<u8>::new(),
        },
        &[
            Token::StructStart("SkipSerializingStruct", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );
}

#[derive(Debug, PartialEq, Serialize)]
enum SkipSerializingEnum<'a, B, D, E> {
    Struct {
        a: &'a i8,
        #[serde(skip_serializing)]
        _b: B,
        #[serde(skip_serializing_if_none)]
        d: Option<D>,
        #[serde(skip_serializing_if_empty)]
        e: Vec<E>,
    }
}

#[test]
fn test_skip_serializing_enum() {
    let a = 1;
    assert_ser_tokens(
        &SkipSerializingEnum::Struct {
            a: &a,
            _b: 2,
            d: Some(4),
            e: vec![5],
        },
        &[
            Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(3)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapSep,
            Token::Str("d"),
            Token::Option(true),
            Token::I32(4),

            Token::MapSep,
            Token::Str("e"),
            Token::SeqStart(Some(1)),
            Token::SeqSep,
            Token::I32(5),
            Token::SeqEnd,

            Token::MapEnd,
        ]
    );

    assert_ser_tokens(
        &SkipSerializingEnum::Struct {
            a: &a,
            _b: 2,
            d: None::<u8>,
            e: Vec::<u8>::new(),
        },
        &[
            Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(1)),

            Token::MapSep,
            Token::Str("a"),
            Token::I8(1),

            Token::MapEnd,
        ]
    );
}
<|endoftext|>


<commit_before><commit_msg>Implement a max_by() function<commit_after>pub fn max_by<T: Clone>(items: &[T], predicate: |&T| -> uint) -> Option<T> {
    let mut item: Option<T> = None;
    let mut max_value: uint = 0;

    for i in items.iter() {
        let value = predicate(i);
        if  value > max_value {
            max_value = value;
            item = Some((*i).clone());
        }
    }

    item
}
<|endoftext|>


<commit_before><commit_msg>Replace unwraps with 'let Ok(..) = ...'<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #61666 - JohnTitor:add-test-for-ice, r=Centril<commit_after>// compile-pass
// #55266

struct VTable<DST: ?Sized> {
    _to_dst_ptr: fn(*mut ()) -> *mut DST,
}

trait HasVTableFor<DST: ?Sized + 'static> {
    const VTABLE: &'static VTable<DST>;
}

impl<T, DST: ?Sized + 'static> HasVTableFor<DST> for T {
    const VTABLE: &'static VTable<DST> = &VTable {
        _to_dst_ptr: |_: *mut ()| unsafe { std::mem::zeroed() },
    };
}

pub fn push<DST: ?Sized + 'static, T>() {
    <T as HasVTableFor<DST>>::VTABLE;
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>get tokens from env in runtime<commit_after><|endoftext|>


<commit_before>use std;
import std::ivec;

fn ivec_equal[T](&T[] v, &T[] u, fn (&T, &T) -> bool element_equality_test) -> bool {
    auto Lv = ivec::len(v);
    if (Lv != ivec::len(u)) {
        ret false;
    }
    auto i = 0u;
    while (i < Lv) {
        if (!element_equality_test(v.(i), u.(i))) {
            ret false;
        }
        i += 1u;
    }
    ret true;
}

fn builtin_equal[T](&T a, &T b) -> bool {
    ret a == b;
}

fn main() {
    // These pass
    assert  builtin_equal(5, 5);
    assert !builtin_equal(5, 4);

    // This passes
    assert !ivec_equal(~[5, 5], ~[5], builtin_equal);

    // These crash
    // https://github.com/graydon/rust/issues/633
    assert !ivec_equal(~[5, 5], ~[5, 4], builtin_equal);
    assert !ivec_equal(~[5, 5], ~[4, 5], builtin_equal);
    assert  ivec_equal(~[5, 5], ~[5, 5], builtin_equal);

    log_err "Pass";
}
<commit_msg>Remove comments complaining about https://github.com/graydon/rust/issues/633 since it is fixed<commit_after>use std;
import std::ivec;

fn ivec_equal[T](&T[] v, &T[] u, fn (&T, &T) -> bool element_equality_test) -> bool {
    auto Lv = ivec::len(v);
    if (Lv != ivec::len(u)) {
        ret false;
    }
    auto i = 0u;
    while (i < Lv) {
        if (!element_equality_test(v.(i), u.(i))) {
            ret false;
        }
        i += 1u;
    }
    ret true;
}

fn builtin_equal[T](&T a, &T b) -> bool {
    ret a == b;
}

fn main() {
    assert  builtin_equal(5, 5);
    assert !builtin_equal(5, 4);
    assert !ivec_equal(~[5, 5], ~[5], builtin_equal);
    assert !ivec_equal(~[5, 5], ~[5, 4], builtin_equal);
    assert !ivec_equal(~[5, 5], ~[4, 5], builtin_equal);
    assert  ivec_equal(~[5, 5], ~[5, 5], builtin_equal);

    log_err "Pass";
}
<|endoftext|>


<commit_before><commit_msg>Our first test!<commit_after>// Smoke test - hello world.

fn main() {
    println!("Hello world!");
}
<|endoftext|>


<commit_before><commit_msg>Refactor(sync): bust syncfile filtering out into separate function<commit_after><|endoftext|>


<commit_before><commit_msg>Refactore(core): return list of unmapped files from filter_syncfiles; sort list<commit_after><|endoftext|>


<commit_before><commit_msg>Added a check to see if polygons contain the position of the other shape to work with engulf overlaps<commit_after><|endoftext|>


<commit_before><commit_msg>Improved console output<commit_after><|endoftext|>


<commit_before><commit_msg>Start parsing out journeys, somewhat crudely mind.<commit_after><|endoftext|>


<commit_before><commit_msg>Refactored threads for clarity. Using iterator functions (map, collect) instead of for loop over range for clarity and idiomatic programming. Added new loop state to acquisition loop.<commit_after><|endoftext|>


<commit_before><commit_msg>Add app skeleton<commit_after>fn main() {
    println!("Welcome to rustcalc!");
}
<|endoftext|>


<commit_before><commit_msg>cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>Add main.rs<commit_after>fn main() {
    println!("Hello, world!");
}
<|endoftext|>


<commit_before><commit_msg>Implemented sub / pub for acquired data.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix merge<commit_after><|endoftext|>


<commit_before>// Copyright 2013 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.

//! Readers and Writers for in-memory buffers
//!
//! # XXX
//!
//! * Should probably have something like this for strings.
//! * Should they implement Closable? Would take extra state.

use cmp::min;
use prelude::*;
use super::*;
use vec;

/// Writes to an owned, growable byte vector
pub struct MemWriter {
    buf: ~[u8]
}

impl MemWriter {
    pub fn new() -> MemWriter { MemWriter { buf: vec::with_capacity(128) } }
}

impl Writer for MemWriter {
    fn write(&mut self, buf: &[u8]) {
        self.buf.push_all(buf)
    }

    fn flush(&mut self) { /* no-op */ }
}

impl Seek for MemWriter {
    fn tell(&self) -> u64 { self.buf.len() as u64 }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

impl Decorator<~[u8]> for MemWriter {

    fn inner(self) -> ~[u8] {
        match self {
            MemWriter { buf: buf } => buf
        }
    }

    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
        match *self {
            MemWriter { buf: ref buf } => buf
        }
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
        match *self {
            MemWriter { buf: ref mut buf } => buf
        }
    }
}

/// Reads from an owned byte vector
pub struct MemReader {
    buf: ~[u8],
    pos: uint
}

impl MemReader {
    pub fn new(buf: ~[u8]) -> MemReader {
        MemReader {
            buf: buf,
            pos: 0
        }
    }
}

impl Reader for MemReader {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        { if self.eof() { return None; } }

        let write_len = min(buf.len(), self.buf.len() - self.pos);
        {
            let input = self.buf.slice(self.pos, self.pos + write_len);
            let output = buf.mut_slice(0, write_len);
            assert_eq!(input.len(), output.len());
            vec::bytes::copy_memory(output, input, write_len);
        }
        self.pos += write_len;
        assert!(self.pos <= self.buf.len());

        return Some(write_len);
    }

    fn eof(&mut self) -> bool { self.pos == self.buf.len() }
}

impl Seek for MemReader {
    fn tell(&self) -> u64 { self.pos as u64 }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

impl Decorator<~[u8]> for MemReader {

    fn inner(self) -> ~[u8] {
        match self {
            MemReader { buf: buf, _ } => buf
        }
    }

    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
        match *self {
            MemReader { buf: ref buf, _ } => buf
        }
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
        match *self {
            MemReader { buf: ref mut buf, _ } => buf
        }
    }
}

/// Writes to a fixed-size byte slice
struct BufWriter<'self> {
    buf: &'self mut [u8],
    pos: uint
}

impl<'self> BufWriter<'self> {
    pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
        BufWriter {
            buf: buf,
            pos: 0
        }
    }
}

impl<'self> Writer for BufWriter<'self> {
    fn write(&mut self, _buf: &[u8]) { fail!() }

    fn flush(&mut self) { fail!() }
}

impl<'self> Seek for BufWriter<'self> {
    fn tell(&self) -> u64 { fail!() }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

/// Reads from a fixed-size byte slice
struct BufReader<'self> {
    buf: &'self [u8],
    pos: uint
}

impl<'self> BufReader<'self> {
    pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
        BufReader {
            buf: buf,
            pos: 0
        }
    }
}

impl<'self> Reader for BufReader<'self> {
    fn read(&mut self, _buf: &mut [u8]) -> Option<uint> { fail!() }

    fn eof(&mut self) -> bool { fail!() }
}

impl<'self> Seek for BufReader<'self> {
    fn tell(&self) -> u64 { fail!() }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

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

    #[test]
    fn test_mem_writer() {
        let mut writer = MemWriter::new();
        assert_eq!(writer.tell(), 0);
        writer.write([0]);
        assert_eq!(writer.tell(), 1);
        writer.write([1, 2, 3]);
        writer.write([4, 5, 6, 7]);
        assert_eq!(writer.tell(), 8);
        assert_eq!(writer.inner(), ~[0, 1, 2, 3, 4, 5 , 6, 7]);
    }

    #[test]
    fn test_mem_reader() {
        let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
        let mut buf = [];
        assert_eq!(reader.read(buf), Some(0));
        assert_eq!(reader.tell(), 0);
        let mut buf = [0];
        assert_eq!(reader.read(buf), Some(1));
        assert_eq!(reader.tell(), 1);
        assert_eq!(buf, [0]);
        let mut buf = [0, ..4];
        assert_eq!(reader.read(buf), Some(4));
        assert_eq!(reader.tell(), 5);
        assert_eq!(buf, [1, 2, 3, 4]);
        assert_eq!(reader.read(buf), Some(3));
        assert_eq!(buf.slice(0, 3), [5, 6, 7]);
        assert!(reader.eof());
        assert_eq!(reader.read(buf), None);
        assert!(reader.eof());
    }
}
<commit_msg>auto merge of #8934 : sfackler/rust/bufreader, r=brson<commit_after>// Copyright 2013 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.

//! Readers and Writers for in-memory buffers
//!
//! # XXX
//!
//! * Should probably have something like this for strings.
//! * Should they implement Closable? Would take extra state.

use cmp::min;
use prelude::*;
use super::*;
use vec;

/// Writes to an owned, growable byte vector
pub struct MemWriter {
    buf: ~[u8]
}

impl MemWriter {
    pub fn new() -> MemWriter { MemWriter { buf: vec::with_capacity(128) } }
}

impl Writer for MemWriter {
    fn write(&mut self, buf: &[u8]) {
        self.buf.push_all(buf)
    }

    fn flush(&mut self) { /* no-op */ }
}

impl Seek for MemWriter {
    fn tell(&self) -> u64 { self.buf.len() as u64 }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

impl Decorator<~[u8]> for MemWriter {

    fn inner(self) -> ~[u8] {
        match self {
            MemWriter { buf: buf } => buf
        }
    }

    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
        match *self {
            MemWriter { buf: ref buf } => buf
        }
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
        match *self {
            MemWriter { buf: ref mut buf } => buf
        }
    }
}

/// Reads from an owned byte vector
pub struct MemReader {
    buf: ~[u8],
    pos: uint
}

impl MemReader {
    pub fn new(buf: ~[u8]) -> MemReader {
        MemReader {
            buf: buf,
            pos: 0
        }
    }
}

impl Reader for MemReader {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        { if self.eof() { return None; } }

        let write_len = min(buf.len(), self.buf.len() - self.pos);
        {
            let input = self.buf.slice(self.pos, self.pos + write_len);
            let output = buf.mut_slice(0, write_len);
            assert_eq!(input.len(), output.len());
            vec::bytes::copy_memory(output, input, write_len);
        }
        self.pos += write_len;
        assert!(self.pos <= self.buf.len());

        return Some(write_len);
    }

    fn eof(&mut self) -> bool { self.pos == self.buf.len() }
}

impl Seek for MemReader {
    fn tell(&self) -> u64 { self.pos as u64 }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

impl Decorator<~[u8]> for MemReader {

    fn inner(self) -> ~[u8] {
        match self {
            MemReader { buf: buf, _ } => buf
        }
    }

    fn inner_ref<'a>(&'a self) -> &'a ~[u8] {
        match *self {
            MemReader { buf: ref buf, _ } => buf
        }
    }

    fn inner_mut_ref<'a>(&'a mut self) -> &'a mut ~[u8] {
        match *self {
            MemReader { buf: ref mut buf, _ } => buf
        }
    }
}

/// Writes to a fixed-size byte slice
struct BufWriter<'self> {
    buf: &'self mut [u8],
    pos: uint
}

impl<'self> BufWriter<'self> {
    pub fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a> {
        BufWriter {
            buf: buf,
            pos: 0
        }
    }
}

impl<'self> Writer for BufWriter<'self> {
    fn write(&mut self, _buf: &[u8]) { fail!() }

    fn flush(&mut self) { fail!() }
}

impl<'self> Seek for BufWriter<'self> {
    fn tell(&self) -> u64 { fail!() }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

/// Reads from a fixed-size byte slice
struct BufReader<'self> {
    buf: &'self [u8],
    pos: uint
}

impl<'self> BufReader<'self> {
    pub fn new<'a>(buf: &'a [u8]) -> BufReader<'a> {
        BufReader {
            buf: buf,
            pos: 0
        }
    }
}

impl<'self> Reader for BufReader<'self> {
    fn read(&mut self, buf: &mut [u8]) -> Option<uint> {
        { if self.eof() { return None; } }

        let write_len = min(buf.len(), self.buf.len() - self.pos);
        {
            let input = self.buf.slice(self.pos, self.pos + write_len);
            let output = buf.mut_slice(0, write_len);
            assert_eq!(input.len(), output.len());
            vec::bytes::copy_memory(output, input, write_len);
        }
        self.pos += write_len;
        assert!(self.pos <= self.buf.len());

        return Some(write_len);
     }

    fn eof(&mut self) -> bool { self.pos == self.buf.len() }
}

impl<'self> Seek for BufReader<'self> {
    fn tell(&self) -> u64 { self.pos as u64 }

    fn seek(&mut self, _pos: i64, _style: SeekStyle) { fail!() }
}

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

    #[test]
    fn test_mem_writer() {
        let mut writer = MemWriter::new();
        assert_eq!(writer.tell(), 0);
        writer.write([0]);
        assert_eq!(writer.tell(), 1);
        writer.write([1, 2, 3]);
        writer.write([4, 5, 6, 7]);
        assert_eq!(writer.tell(), 8);
        assert_eq!(writer.inner(), ~[0, 1, 2, 3, 4, 5 , 6, 7]);
    }

    #[test]
    fn test_mem_reader() {
        let mut reader = MemReader::new(~[0, 1, 2, 3, 4, 5, 6, 7]);
        let mut buf = [];
        assert_eq!(reader.read(buf), Some(0));
        assert_eq!(reader.tell(), 0);
        let mut buf = [0];
        assert_eq!(reader.read(buf), Some(1));
        assert_eq!(reader.tell(), 1);
        assert_eq!(buf, [0]);
        let mut buf = [0, ..4];
        assert_eq!(reader.read(buf), Some(4));
        assert_eq!(reader.tell(), 5);
        assert_eq!(buf, [1, 2, 3, 4]);
        assert_eq!(reader.read(buf), Some(3));
        assert_eq!(buf.slice(0, 3), [5, 6, 7]);
        assert!(reader.eof());
        assert_eq!(reader.read(buf), None);
        assert!(reader.eof());
    }

    #[test]
    fn test_buf_reader() {
        let in_buf = ~[0, 1, 2, 3, 4, 5, 6, 7];
        let mut reader = BufReader::new(in_buf);
        let mut buf = [];
        assert_eq!(reader.read(buf), Some(0));
        assert_eq!(reader.tell(), 0);
        let mut buf = [0];
        assert_eq!(reader.read(buf), Some(1));
        assert_eq!(reader.tell(), 1);
        assert_eq!(buf, [0]);
        let mut buf = [0, ..4];
        assert_eq!(reader.read(buf), Some(4));
        assert_eq!(reader.tell(), 5);
        assert_eq!(buf, [1, 2, 3, 4]);
        assert_eq!(reader.read(buf), Some(3));
        assert_eq!(buf.slice(0, 3), [5, 6, 7]);
        assert!(reader.eof());
        assert_eq!(reader.read(buf), None);
        assert!(reader.eof());
    }
}
<|endoftext|>


<commit_before>//! Exeuctors
//!
//! This module contains tools for managing the raw execution of futures,
//! which is needed when building *executors* (places where futures can run).
// TODO: more dox

pub use task_impl::{Spawn, spawn, Unpark, Executor, Run};
<commit_msg>Fix minor documentation typo<commit_after>//! Executors
//!
//! This module contains tools for managing the raw execution of futures,
//! which is needed when building *executors* (places where futures can run).
// TODO: more dox

pub use task_impl::{Spawn, spawn, Unpark, Executor, Run};
<|endoftext|>


<commit_before><commit_msg>Fix setf bitmask<commit_after><|endoftext|>