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

use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};

pub fn target() -> Result<Target, String> {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Em,
                vec!["-s".to_string(),
                     "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
                     "-s".to_string(),
                     "ABORTING_MALLOC=0".to_string()]);

    let opts = TargetOptions {
        dynamic_linking: false,
        executables: true,
        exe_suffix: ".js".to_string(),
        linker_is_gnu: true,
        allow_asm: false,
        obj_is_bitcode: true,
        is_like_emscripten: true,
        max_atomic_width: Some(32),
        post_link_args: args,
        target_family: Some("unix".to_string()),
        codegen_backend: "emscripten".to_string(),
        .. Default::default()
    };
    Ok(Target {
        llvm_target: "asmjs-unknown-emscripten".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_c_int_width: "32".to_string(),
        target_os: "emscripten".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(),
        arch: "asmjs".to_string(),
        linker_flavor: LinkerFlavor::Em,
        options: opts,
    })
}
<commit_msg>Explicitely disable WASM code generation for Emscripten<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::{LinkArgs, LinkerFlavor, Target, TargetOptions};

pub fn target() -> Result<Target, String> {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Em,
                vec!["-s".to_string(),
                     "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string(),
                     "-s".to_string(),
                     "ABORTING_MALLOC=0".to_string(),
                     "-s".to_string(),
                     "WASM=0".to_string()]);

    let opts = TargetOptions {
        dynamic_linking: false,
        executables: true,
        exe_suffix: ".js".to_string(),
        linker_is_gnu: true,
        allow_asm: false,
        obj_is_bitcode: true,
        is_like_emscripten: true,
        max_atomic_width: Some(32),
        post_link_args: args,
        target_family: Some("unix".to_string()),
        codegen_backend: "emscripten".to_string(),
        .. Default::default()
    };
    Ok(Target {
        llvm_target: "asmjs-unknown-emscripten".to_string(),
        target_endian: "little".to_string(),
        target_pointer_width: "32".to_string(),
        target_c_int_width: "32".to_string(),
        target_os: "emscripten".to_string(),
        target_env: "".to_string(),
        target_vendor: "unknown".to_string(),
        data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(),
        arch: "asmjs".to_string(),
        linker_flavor: LinkerFlavor::Em,
        options: opts,
    })
}
<|endoftext|>


<commit_before><commit_msg>Remove outdated parts from comments<commit_after><|endoftext|>


<commit_before>// error-pattern:beep boop
fn main() {
    let origin = {x: 0, y: 0};
    let f = {x: (fail "beep boop") with origin};
}
<commit_msg>add annotation for variable that used to infer to bot<commit_after>// error-pattern:beep boop
fn main() {
    let origin = {x: 0, y: 0};
    let f: {x:int,y:int} = {x: (fail "beep boop") with origin};
}
<|endoftext|>


<commit_before><commit_msg>messing around with task and process.<commit_after><|endoftext|>


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

use rustc::session::Session;

use save::generated_code;

use std::cell::Cell;

use syntax::ast;
use syntax::codemap::*;
use syntax::parse::lexer;
use syntax::parse::lexer::{Reader,StringReader};
use syntax::parse::token;
use syntax::parse::token::{keywords, Token};

#[derive(Clone)]
pub struct SpanUtils<'a> {
    pub sess: &'a Session,
    pub err_count: Cell<int>,
}

impl<'a> SpanUtils<'a> {
    // Standard string for extents/location.
    pub fn extent_str(&self, span: Span) -> String {
        let lo_loc = self.sess.codemap().lookup_char_pos(span.lo);
        let hi_loc = self.sess.codemap().lookup_char_pos(span.hi);
        let lo_pos = self.sess.codemap().bytepos_to_file_charpos(span.lo);
        let hi_pos = self.sess.codemap().bytepos_to_file_charpos(span.hi);
        let lo_pos_byte = self.sess.codemap().lookup_byte_offset(span.lo).pos;
        let hi_pos_byte = self.sess.codemap().lookup_byte_offset(span.hi).pos;

        format!("file_name,\"{}\",file_line,{},file_col,{},extent_start,{},extent_start_bytes,{},\
                 file_line_end,{},file_col_end,{},extent_end,{},extent_end_bytes,{}",
                lo_loc.file.name,
                lo_loc.line, lo_loc.col.to_usize(), lo_pos.to_usize(), lo_pos_byte.to_usize(),
                hi_loc.line, hi_loc.col.to_usize(), hi_pos.to_usize(), hi_pos_byte.to_usize())
    }

    // sub_span starts at span.lo, so we need to adjust the positions etc.
    // If sub_span is None, we don't need to adjust.
    pub fn make_sub_span(&self, span: Span, sub_span: Option<Span>) -> Option<Span> {
        let loc = self.sess.codemap().lookup_char_pos(span.lo);
        assert!(!generated_code(span),
                "generated code; we should not be processing this `{}` in {}, line {}",
                 self.snippet(span), loc.file.name, loc.line);

        match sub_span {
            None => None,
            Some(sub) => {
                let FileMapAndBytePos {fm, pos} =
                    self.sess.codemap().lookup_byte_offset(span.lo);
                let base = pos + fm.start_pos;
                Some(Span {
                    lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
                    hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
                    expn_id: NO_EXPANSION,
                })
            }
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.sess.codemap().span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => String::new(),
        }
    }

    pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
        // sadness - we don't have spans for sub-expressions nor access to the tokens
        // so in order to get extents for the function name itself (which dxr expects)
        // we need to re-tokenise the fn definition

        // Note: this is a bit awful - it adds the contents of span to the end of
        // the codemap as a new filemap. This is mostly OK, but means we should
        // not iterate over the codemap. Also, any spans over the new filemap
        // are incompatible with spans over other filemaps.
        let filemap = self.sess.codemap().new_filemap(String::from_str("<anon-dxr>"),
                                                      self.snippet(span));
        let s = self.sess;
        lexer::StringReader::new(s.diagnostic(), filemap)
    }

    // Re-parses a path and returns the span for the last identifier in the path
    pub fn span_for_last_ident(&self, span: Span) -> Option<Span> {
        let mut result = None;

        let mut toks = self.retokenise_span(span);
        let mut bracket_count = 0;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return self.make_sub_span(span, result)
            }
            if bracket_count == 0 &&
               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                result = Some(ts.sp);
            }

            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            }
        }
    }

    // Return the span for the first identifier in the path.
    pub fn span_for_first_ident(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut bracket_count = 0;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return None;
            }
            if bracket_count == 0 &&
               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                return self.make_sub_span(span, Some(ts.sp));
            }

            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            }
        }
    }

    // Return the span for the last ident before a `(` or `<` or '::<' and outside any
    // any brackets, or the last span.
    pub fn sub_span_for_meth_name(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        let mut result = None;
        let mut bracket_count = 0;
        let mut last_span = None;
        while prev.tok != token::Eof {
            last_span = None;
            let mut next = toks.real_token();

            if (next.tok == token::OpenDelim(token::Paren) ||
                next.tok == token::Lt) &&
               bracket_count == 0 &&
               prev.tok.is_ident() {
                result = Some(prev.sp);
            }

            if bracket_count == 0 &&
                next.tok == token::ModSep {
                let old = prev;
                prev = next;
                next = toks.real_token();
                if next.tok == token::Lt &&
                   old.tok.is_ident() {
                    result = Some(old.sp);
                }
            }

            bracket_count += match prev.tok {
                token::OpenDelim(token::Paren) | token::Lt => 1,
                token::CloseDelim(token::Paren) | token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };

            if prev.tok.is_ident() && bracket_count == 0 {
                last_span = Some(prev.sp);
            }
            prev = next;
        }
        if result.is_none() && last_span.is_some() {
            return self.make_sub_span(span, last_span);
        }
        return self.make_sub_span(span, result);
    }

    // Return the span for the last ident before a `<` and outside any
    // brackets, or the last span.
    pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        let mut result = None;
        let mut bracket_count = 0;
        loop {
            let next = toks.real_token();

            if (next.tok == token::Lt ||
                next.tok == token::Colon) &&
               bracket_count == 0 &&
               prev.tok.is_ident() {
                result = Some(prev.sp);
            }

            bracket_count += match prev.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shl) => 2,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };

            if next.tok == token::Eof {
                break;
            }
            prev = next;
        }
        if bracket_count != 0 {
            let loc = self.sess.codemap().lookup_char_pos(span.lo);
            self.sess.span_bug(span,
                &format!("Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
                        self.snippet(span), loc.file.name, loc.line));
        }
        if result.is_none() && prev.tok.is_ident() && bracket_count == 0 {
            return self.make_sub_span(span, Some(prev.sp));
        }
        self.make_sub_span(span, result)
    }

    // Reparse span and return an owned vector of sub spans of the first limit
    // identifier tokens in the given nesting level.
    // example with Foo<Bar<T,V>, Bar<T,V>>
    // Nesting = 0: all idents outside of brackets: ~[Foo]
    // Nesting = 1: idents within one level of brackets: ~[Bar, Bar]
    pub fn spans_with_brackets(&self, span: Span, nesting: int, limit: int) -> Vec<Span> {
        let mut result: Vec<Span> = vec!();

        let mut toks = self.retokenise_span(span);
        // We keep track of how many brackets we're nested in
        let mut bracket_count = 0;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                if bracket_count != 0 {
                    let loc = self.sess.codemap().lookup_char_pos(span.lo);
                    self.sess.span_bug(span, &format!(
                        "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
                         self.snippet(span), loc.file.name, loc.line));
                }
                return result
            }
            if (result.len() as int) == limit {
                return result;
            }
            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shl) => 2,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };
            if ts.tok.is_ident() &&
               bracket_count == nesting {
                result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
            }
        }
    }

    pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        loop {
            if prev.tok == token::Eof {
                return None;
            }
            let next = toks.real_token();
            if next.tok == tok {
                return self.make_sub_span(span, Some(prev.sp));
            }
            prev = next;
        }
    }

    pub fn sub_span_of_token(&self, span: Span, tok: Token) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        loop {
            let next = toks.real_token();
            if next.tok == token::Eof {
                return None;
            }
            if next.tok == tok {
                return self.make_sub_span(span, Some(next.sp));
            }
        }
    }

    pub fn sub_span_after_keyword(&self,
                                  span: Span,
                                  keyword: keywords::Keyword) -> Option<Span> {
        self.sub_span_after(span, |t| t.is_keyword(keyword))
    }

    pub fn sub_span_after_token(&self,
                                span: Span,
                                tok: Token) -> Option<Span> {
        self.sub_span_after(span, |t| t == tok)
    }

    fn sub_span_after<F: Fn(Token) -> bool>(&self,
                                            span: Span,
                                            f: F) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return None;
            }
            if f(ts.tok) {
                let ts = toks.real_token();
                if ts.tok == token::Eof {
                    return None
                } else {
                    return self.make_sub_span(span, Some(ts.sp));
                }
            }
        }
    }

    // Returns a list of the spans of idents in a patch.
    // E.g., For foo::bar<x,t>::baz, we return [foo, bar, baz] (well, their spans)
    pub fn spans_for_path_segments(&self, path: &ast::Path) -> Vec<Span> {
        if generated_code(path.span) {
            return vec!();
        }

        self.spans_with_brackets(path.span, 0, -1)
    }

    // Return an owned vector of the subspans of the param identifier
    // tokens found in span.
    pub fn spans_for_ty_params(&self, span: Span, number: int) -> Vec<Span> {
        if generated_code(span) {
            return vec!();
        }
        // Type params are nested within one level of brackets:
        // i.e. we want ~[A, B] from Foo<A, B<T,U>>
        self.spans_with_brackets(span, 1, number)
    }

    pub fn report_span_err(&self, kind: &str, span: Span) {
        let loc = self.sess.codemap().lookup_char_pos(span.lo);
        info!("({}) Could not find sub_span in `{}` in {}, line {}",
              kind, self.snippet(span), loc.file.name, loc.line);
        self.err_count.set(self.err_count.get()+1);
        if self.err_count.get() > 1000 {
            self.sess.bug("span errors reached 1000, giving up");
        }
    }
}
<commit_msg>Update trans/save's span hacks for fully qualified UFCS paths.<commit_after>// Copyright 2012-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.

use rustc::session::Session;

use save::generated_code;

use std::cell::Cell;

use syntax::ast;
use syntax::codemap::*;
use syntax::parse::lexer;
use syntax::parse::lexer::{Reader,StringReader};
use syntax::parse::token;
use syntax::parse::token::{keywords, Token};

#[derive(Clone)]
pub struct SpanUtils<'a> {
    pub sess: &'a Session,
    pub err_count: Cell<int>,
}

impl<'a> SpanUtils<'a> {
    // Standard string for extents/location.
    pub fn extent_str(&self, span: Span) -> String {
        let lo_loc = self.sess.codemap().lookup_char_pos(span.lo);
        let hi_loc = self.sess.codemap().lookup_char_pos(span.hi);
        let lo_pos = self.sess.codemap().bytepos_to_file_charpos(span.lo);
        let hi_pos = self.sess.codemap().bytepos_to_file_charpos(span.hi);
        let lo_pos_byte = self.sess.codemap().lookup_byte_offset(span.lo).pos;
        let hi_pos_byte = self.sess.codemap().lookup_byte_offset(span.hi).pos;

        format!("file_name,\"{}\",file_line,{},file_col,{},extent_start,{},extent_start_bytes,{},\
                 file_line_end,{},file_col_end,{},extent_end,{},extent_end_bytes,{}",
                lo_loc.file.name,
                lo_loc.line, lo_loc.col.to_usize(), lo_pos.to_usize(), lo_pos_byte.to_usize(),
                hi_loc.line, hi_loc.col.to_usize(), hi_pos.to_usize(), hi_pos_byte.to_usize())
    }

    // sub_span starts at span.lo, so we need to adjust the positions etc.
    // If sub_span is None, we don't need to adjust.
    pub fn make_sub_span(&self, span: Span, sub_span: Option<Span>) -> Option<Span> {
        let loc = self.sess.codemap().lookup_char_pos(span.lo);
        assert!(!generated_code(span),
                "generated code; we should not be processing this `{}` in {}, line {}",
                 self.snippet(span), loc.file.name, loc.line);

        match sub_span {
            None => None,
            Some(sub) => {
                let FileMapAndBytePos {fm, pos} =
                    self.sess.codemap().lookup_byte_offset(span.lo);
                let base = pos + fm.start_pos;
                Some(Span {
                    lo: base + self.sess.codemap().lookup_byte_offset(sub.lo).pos,
                    hi: base + self.sess.codemap().lookup_byte_offset(sub.hi).pos,
                    expn_id: NO_EXPANSION,
                })
            }
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.sess.codemap().span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => String::new(),
        }
    }

    pub fn retokenise_span(&self, span: Span) -> StringReader<'a> {
        // sadness - we don't have spans for sub-expressions nor access to the tokens
        // so in order to get extents for the function name itself (which dxr expects)
        // we need to re-tokenise the fn definition

        // Note: this is a bit awful - it adds the contents of span to the end of
        // the codemap as a new filemap. This is mostly OK, but means we should
        // not iterate over the codemap. Also, any spans over the new filemap
        // are incompatible with spans over other filemaps.
        let filemap = self.sess.codemap().new_filemap(String::from_str("<anon-dxr>"),
                                                      self.snippet(span));
        let s = self.sess;
        lexer::StringReader::new(s.diagnostic(), filemap)
    }

    // Re-parses a path and returns the span for the last identifier in the path
    pub fn span_for_last_ident(&self, span: Span) -> Option<Span> {
        let mut result = None;

        let mut toks = self.retokenise_span(span);
        let mut bracket_count = 0;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return self.make_sub_span(span, result)
            }
            if bracket_count == 0 &&
               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                result = Some(ts.sp);
            }

            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            }
        }
    }

    // Return the span for the first identifier in the path.
    pub fn span_for_first_ident(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut bracket_count = 0;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return None;
            }
            if bracket_count == 0 &&
               (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) {
                return self.make_sub_span(span, Some(ts.sp));
            }

            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            }
        }
    }

    // Return the span for the last ident before a `(` or `<` or '::<' and outside any
    // any brackets, or the last span.
    pub fn sub_span_for_meth_name(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        let mut result = None;
        let mut bracket_count = 0;
        let mut last_span = None;
        while prev.tok != token::Eof {
            last_span = None;
            let mut next = toks.real_token();

            if (next.tok == token::OpenDelim(token::Paren) ||
                next.tok == token::Lt) &&
               bracket_count == 0 &&
               prev.tok.is_ident() {
                result = Some(prev.sp);
            }

            if bracket_count == 0 &&
                next.tok == token::ModSep {
                let old = prev;
                prev = next;
                next = toks.real_token();
                if next.tok == token::Lt &&
                   old.tok.is_ident() {
                    result = Some(old.sp);
                }
            }

            bracket_count += match prev.tok {
                token::OpenDelim(token::Paren) | token::Lt => 1,
                token::CloseDelim(token::Paren) | token::Gt => -1,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };

            if prev.tok.is_ident() && bracket_count == 0 {
                last_span = Some(prev.sp);
            }
            prev = next;
        }
        if result.is_none() && last_span.is_some() {
            return self.make_sub_span(span, last_span);
        }
        return self.make_sub_span(span, result);
    }

    // Return the span for the last ident before a `<` and outside any
    // brackets, or the last span.
    pub fn sub_span_for_type_name(&self, span: Span) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        let mut result = None;
        let mut bracket_count = 0;
        loop {
            let next = toks.real_token();

            if (next.tok == token::Lt ||
                next.tok == token::Colon) &&
               bracket_count == 0 &&
               prev.tok.is_ident() {
                result = Some(prev.sp);
            }

            bracket_count += match prev.tok {
                token::Lt => 1,
                token::Gt => -1,
                token::BinOp(token::Shl) => 2,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };

            if next.tok == token::Eof {
                break;
            }
            prev = next;
        }
        if bracket_count != 0 {
            let loc = self.sess.codemap().lookup_char_pos(span.lo);
            self.sess.span_bug(span,
                &format!("Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
                        self.snippet(span), loc.file.name, loc.line));
        }
        if result.is_none() && prev.tok.is_ident() && bracket_count == 0 {
            return self.make_sub_span(span, Some(prev.sp));
        }
        self.make_sub_span(span, result)
    }

    // Reparse span and return an owned vector of sub spans of the first limit
    // identifier tokens in the given nesting level.
    // example with Foo<Bar<T,V>, Bar<T,V>>
    // Nesting = 0: all idents outside of brackets: ~[Foo]
    // Nesting = 1: idents within one level of brackets: ~[Bar, Bar]
    pub fn spans_with_brackets(&self, span: Span, nesting: int, limit: int) -> Vec<Span> {
        let mut result: Vec<Span> = vec!();

        let mut toks = self.retokenise_span(span);
        // We keep track of how many brackets we're nested in
        let mut bracket_count = 0;
        let mut found_ufcs_sep = false;
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                if bracket_count != 0 {
                    let loc = self.sess.codemap().lookup_char_pos(span.lo);
                    self.sess.span_bug(span, &format!(
                        "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}",
                         self.snippet(span), loc.file.name, loc.line));
                }
                return result
            }
            if (result.len() as int) == limit {
                return result;
            }
            bracket_count += match ts.tok {
                token::Lt => 1,
                token::Gt => {
                    // Ignore the `>::` in `<Type as Trait>::AssocTy`.
                    if !found_ufcs_sep && bracket_count == 0 {
                        found_ufcs_sep = true;
                        0
                    } else {
                        -1
                    }
                }
                token::BinOp(token::Shl) => 2,
                token::BinOp(token::Shr) => -2,
                _ => 0
            };
            if ts.tok.is_ident() && bracket_count == nesting {
                result.push(self.make_sub_span(span, Some(ts.sp)).unwrap());
            }
        }
    }

    pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        let mut prev = toks.real_token();
        loop {
            if prev.tok == token::Eof {
                return None;
            }
            let next = toks.real_token();
            if next.tok == tok {
                return self.make_sub_span(span, Some(prev.sp));
            }
            prev = next;
        }
    }

    pub fn sub_span_of_token(&self, span: Span, tok: Token) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        loop {
            let next = toks.real_token();
            if next.tok == token::Eof {
                return None;
            }
            if next.tok == tok {
                return self.make_sub_span(span, Some(next.sp));
            }
        }
    }

    pub fn sub_span_after_keyword(&self,
                                  span: Span,
                                  keyword: keywords::Keyword) -> Option<Span> {
        self.sub_span_after(span, |t| t.is_keyword(keyword))
    }

    pub fn sub_span_after_token(&self,
                                span: Span,
                                tok: Token) -> Option<Span> {
        self.sub_span_after(span, |t| t == tok)
    }

    fn sub_span_after<F: Fn(Token) -> bool>(&self,
                                            span: Span,
                                            f: F) -> Option<Span> {
        let mut toks = self.retokenise_span(span);
        loop {
            let ts = toks.real_token();
            if ts.tok == token::Eof {
                return None;
            }
            if f(ts.tok) {
                let ts = toks.real_token();
                if ts.tok == token::Eof {
                    return None
                } else {
                    return self.make_sub_span(span, Some(ts.sp));
                }
            }
        }
    }

    // Returns a list of the spans of idents in a patch.
    // E.g., For foo::bar<x,t>::baz, we return [foo, bar, baz] (well, their spans)
    pub fn spans_for_path_segments(&self, path: &ast::Path) -> Vec<Span> {
        if generated_code(path.span) {
            return vec!();
        }

        self.spans_with_brackets(path.span, 0, -1)
    }

    // Return an owned vector of the subspans of the param identifier
    // tokens found in span.
    pub fn spans_for_ty_params(&self, span: Span, number: int) -> Vec<Span> {
        if generated_code(span) {
            return vec!();
        }
        // Type params are nested within one level of brackets:
        // i.e. we want ~[A, B] from Foo<A, B<T,U>>
        self.spans_with_brackets(span, 1, number)
    }

    pub fn report_span_err(&self, kind: &str, span: Span) {
        let loc = self.sess.codemap().lookup_char_pos(span.lo);
        info!("({}) Could not find sub_span in `{}` in {}, line {}",
              kind, self.snippet(span), loc.file.name, loc.line);
        self.err_count.set(self.err_count.get()+1);
        if self.err_count.get() > 1000 {
            self.sess.bug("span errors reached 1000, giving up");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Store driver ID on PCI device entry<commit_after><|endoftext|>


<commit_before><commit_msg>Day 21 in rust<commit_after><|endoftext|>


<commit_before><commit_msg>testsuite: Test that init and forget are both unsafe<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.

use core::unstable::intrinsics::{init, forget};

// Test that the `forget` and `init` intrinsics are really unsafe
pub fn main() {
    let stuff = init::<int>(); //~ ERROR access to unsafe function requires unsafe
    forget(stuff);             //~ ERROR access to unsafe function requires unsafe
}<|endoftext|>


<commit_before><commit_msg>test: Add test for LHS expression check<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.

fn main() {
    1 = 2; //~ ERROR illegal left-hand side expression
    1 += 2; //~ ERROR illegal left-hand side expression
    (1, 2) = (3, 4); //~ ERROR illegal left-hand side expression

    let (a, b) = (1, 2);
    (a, b) = (3, 4); //~ ERROR illegal left-hand side expression

    None = Some(3); //~ ERROR illegal left-hand side expression
}
<|endoftext|>


<commit_before><commit_msg>Specify the Objective trait<commit_after>use std::cmp::Ordering;

/// An *objective* defines a total ordering relation and a distance
/// metric on `solutions` in order to be able to compare any two
/// solutions according to the following two questions:
///
/// - "which solution is better" (total order)
///
/// - "how much better" (distance metric)
///
/// Objectives can be seen as a projection of a (possibly) multi-variate
/// solution value to a scalar value. There can be any number of
/// different projections (objectives) for any given solution value. Of
/// course solution values need not be multi-variate.
///
/// We use the term "solution" here, ignoring the fact that in pratice
/// we often have to evaluate the "fitness" of a solution prior of being
/// able to define any useful ordering relation or distance metric. As
/// the fitness generally is a function of the solution, this is more or
/// less an implementation detail or that of an optimization. Nothing
/// prevents you from using the fitness value here as the solution
/// value.

pub trait Objective {
    /// The solution value type that we define the objective on.
    type Solution;

    /// The output type of the distance metric.
    type Distance: Sized;

    /// An objective defines a total order between two solution values.
    fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering;

    /// An objective defines a distance metric between two solution
    /// values. Distance values can be negative, i.e. the caller is
    /// responsible for obtaining absolute values.
    fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> Self::Distance;
}

#[cfg(test)]
mod tests {
    use std::cmp::Ordering;
    use super::Objective;

    // Our multi-variate fitness/solution value
    struct Tuple(usize, usize);

    // We define three objectives
    struct Objective1;
    struct Objective2;
    struct Objective3;

    impl Objective for Objective1 {
        type Solution = Tuple;
        type Distance = f64;

        fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering {
            a.0.cmp(&b.0)
        }

        fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> Self::Distance {
            (a.0 as f64) - (b.0 as f64)
        }
    }

    impl Objective for Objective2 {
        type Solution = Tuple;
        type Distance = f64;

        fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering {
            a.1.cmp(&b.1)
        }

        fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> Self::Distance {
            (a.1 as f64) - (b.1 as f64)
        }
    }

    // Objective3 is defined on the sum of the tuple values.
    impl Objective for Objective3 {
        type Solution = Tuple;
        type Distance = f64;

        fn total_order(&self, a: &Self::Solution, b: &Self::Solution) -> Ordering {
            (a.0 + a.1).cmp(&(b.0 + b.1))
        }

        fn distance(&self, a: &Self::Solution, b: &Self::Solution) -> Self::Distance {
            (a.0 + a.1) as f64 - (b.0 + b.1) as f64
        }
    }

    #[test]
    fn test_objectives() {
        let a = &Tuple(1, 2);
        let b = &Tuple(2, 1);
        assert_eq!(Ordering::Less, Objective1.total_order(a, b));
        assert_eq!(Ordering::Greater, Objective2.total_order(a, b));
        assert_eq!(Ordering::Equal, Objective3.total_order(a, b));

        assert_eq!(-1.0, Objective1.distance(a, b));
        assert_eq!(1.0, Objective2.distance(a, b));
        assert_eq!(0.0, Objective3.distance(a, b));
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test for decoding headers.<commit_after><|endoftext|>


<commit_before>use crate::tracker::{InfoHash, TorrentTracker};
use serde::{Deserialize, Serialize};
use std::cmp::min;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use warp::{filters, reply, reply::Reply, serve, Filter, Server};

fn view_root() -> impl Reply {
    reply::html(concat!(
        r#"

            <title>udpt/"#,
        env!("CARGO_PKG_VERSION"),
        r#"</title>

            This is your udpt torrent tracker.

    "#
    ))
}

#[derive(Deserialize, Debug)]
struct TorrentInfoQuery {
    offset: Option<u32>,
    limit: Option<u32>,
}

#[derive(Serialize)]
struct TorrentEntry<'a> {
    info_hash: &'a InfoHash,
    #[serde(flatten)]
    data: &'a crate::tracker::TorrentEntry,
}

#[derive(Serialize, Deserialize)]
struct TorrentFlag {
    is_flagged: bool,
}

#[derive(Serialize, Debug)]
#[serde(tag = "status", rename_all = "snake_case")]
enum ActionStatus<'a> {
    Ok,
    Err { reason: std::borrow::Cow<'a, str> },
}

impl warp::reject::Reject for ActionStatus<'static> {}

fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
    #[derive(Deserialize)]
    struct AuthToken {
        token: Option<String>,
    }

    let tokens: HashSet<String> = tokens.into_iter().map(|(_, v)| v).collect();

    let tokens = Arc::new(tokens);
    warp::filters::any::any()
        .map(move || tokens.clone())
        .and(filters::query::query::<AuthToken>())
        .and_then(|tokens: Arc<HashSet<String>>, token: AuthToken| {
            async move {
                if let Some(token) = token.token {
                    if tokens.contains(&token) {
                        return Ok(());
                    }
                }
                Err(warp::reject::custom(ActionStatus::Err {
                    reason: "Access Denied".into(),
                }))
            }
        })
        .untuple_one()
}

pub fn build_server(
    tracker: Arc<TorrentTracker>, tokens: HashMap<String, String>,
) -> Server<impl Filter<Extract = impl Reply> + Clone + Send + Sync + 'static> {
    let root = filters::path::end().map(|| view_root());

    let t1 = tracker.clone();
    // view_torrent_list -> GET /t/?offset=:u32&limit=:u32 HTTP/1.1
    let view_torrent_list = filters::path::end()
        .and(filters::method::get())
        .and(filters::query::query())
        .map(move |limits| {
            let tracker = t1.clone();
            (limits, tracker)
        })
        .and_then(|(limits, tracker): (TorrentInfoQuery, Arc<TorrentTracker>)| {
            async move {
                let offset = limits.offset.unwrap_or(0);
                let limit = min(limits.limit.unwrap_or(1000), 4000);

                let db = tracker.get_database().await;
                let results: Vec<_> = db
                    .iter()
                    .map(|(k, v)| TorrentEntry { info_hash: k, data: v })
                    .skip(offset as usize)
                    .take(limit as usize)
                    .collect();

                Result::<_, warp::reject::Rejection>::Ok(reply::json(&results))
            }
        });

    let t2 = tracker.clone();
    // view_torrent_info -> GET /t/:infohash HTTP/*
    let view_torrent_info = filters::method::get()
        .and(filters::path::param())
        .map(move |info_hash: InfoHash| {
            let tracker = t2.clone();
            (info_hash, tracker)
        })
        .and_then(|(info_hash, tracker): (InfoHash, Arc<TorrentTracker>)| {
            async move {
                let db = tracker.get_database().await;
                let info = match db.get(&info_hash) {
                    Some(v) => v,
                    None => return Err(warp::reject::reject()),
                };

                Ok(reply::json(&TorrentEntry {
                    info_hash: &info_hash,
                    data: info,
                }))
            }
        });

    // DELETE /t/:info_hash
    let t3 = tracker.clone();
    let delete_torrent = filters::method::post()
        .and(filters::path::param())
        .map(move |info_hash: InfoHash| {
            let tracker = t3.clone();
            (info_hash, tracker)
        })
        .and_then(|(info_hash, tracker): (InfoHash, Arc<TorrentTracker>)| {
            async move {
                let resp = match tracker.remove_torrent(&info_hash, true).await.is_ok() {
                    true => ActionStatus::Ok,
                    false => {
                        ActionStatus::Err {
                            reason: "failed to delete torrent".into(),
                        }
                    }
                };

                Result::<_, warp::Rejection>::Ok(reply::json(&resp))
            }
        });

    let t4 = tracker.clone();
    // add_torrent/alter: POST /t/:info_hash
    // (optional) BODY: json: {"is_flagged": boolean}
    let change_torrent = filters::method::post()
        .and(filters::path::param())
        .and(filters::body::content_length_limit(4096))
        .and(filters::body::json())
        .map(move |info_hash: InfoHash, body: Option<TorrentFlag>| {
            let tracker = t4.clone();
            (info_hash, tracker, body)
        })
        .and_then(
            |(info_hash, tracker, body): (InfoHash, Arc<TorrentTracker>, Option<TorrentFlag>)| {
                async move {
                    let is_flagged = body.map(|e| e.is_flagged).unwrap_or(false);
                    if !tracker.set_torrent_flag(&info_hash, is_flagged).await {
                        // torrent doesn't exist, add it...

                        if is_flagged {
                            if tracker.add_torrent(&info_hash).await.is_ok() {
                                tracker.set_torrent_flag(&info_hash, is_flagged).await;
                            } else {
                                return Err(warp::reject::custom(ActionStatus::Err {
                                    reason: "failed to flag torrent".into(),
                                }));
                            }
                        }
                    }

                    Result::<_, warp::Rejection>::Ok(reply::json(&ActionStatus::Ok))
                }
            },
        );
    let torrent_mgmt =
        filters::path::path("t").and(view_torrent_list.or(delete_torrent).or(view_torrent_info).or(change_torrent));

    let server = root.or(authenticate(tokens).and(torrent_mgmt));

    serve(server)
}
<commit_msg>check remote_addr is loopback<commit_after>use crate::tracker::{InfoHash, TorrentTracker};
use serde::{Deserialize, Serialize};
use std::cmp::min;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use warp::{filters, reply, reply::Reply, serve, Filter, Server};

fn view_root() -> impl Reply {
    reply::html(concat!(
        r#"

            <title>udpt/"#,
        env!("CARGO_PKG_VERSION"),
        r#"</title>

            This is your udpt torrent tracker.

    "#
    ))
}

#[derive(Deserialize, Debug)]
struct TorrentInfoQuery {
    offset: Option<u32>,
    limit: Option<u32>,
}

#[derive(Serialize)]
struct TorrentEntry<'a> {
    info_hash: &'a InfoHash,
    #[serde(flatten)]
    data: &'a crate::tracker::TorrentEntry,
}

#[derive(Serialize, Deserialize)]
struct TorrentFlag {
    is_flagged: bool,
}

#[derive(Serialize, Debug)]
#[serde(tag = "status", rename_all = "snake_case")]
enum ActionStatus<'a> {
    Ok,
    Err { reason: std::borrow::Cow<'a, str> },
}

impl warp::reject::Reject for ActionStatus<'static> {}

fn authenticate(tokens: HashMap<String, String>) -> impl Filter<Extract = (), Error = warp::reject::Rejection> + Clone {
    #[derive(Deserialize)]
    struct AuthToken {
        token: Option<String>,
    }

    let tokens: HashSet<String> = tokens.into_iter().map(|(_, v)| v).collect();

    let tokens = Arc::new(tokens);
    warp::filters::any::any()
        .map(move || tokens.clone())
        .and(filters::query::query::<AuthToken>())
        .and(filters::addr::remote())
        .and_then(
            |tokens: Arc<HashSet<String>>, token: AuthToken, peer_addr: Option<std::net::SocketAddr>| {
                async move {
                    if let Some(addr) = peer_addr {
                        if let Some(token) = token.token {
                            if addr.ip().is_loopback() && tokens.contains(&token) {
                                return Ok(());
                            }
                        }
                    }
                    Err(warp::reject::custom(ActionStatus::Err {
                        reason: "Access Denied".into(),
                    }))
                }
            },
        )
        .untuple_one()
}

pub fn build_server(
    tracker: Arc<TorrentTracker>, tokens: HashMap<String, String>,
) -> Server<impl Filter<Extract = impl Reply> + Clone + Send + Sync + 'static> {
    let root = filters::path::end().map(|| view_root());

    let t1 = tracker.clone();
    // view_torrent_list -> GET /t/?offset=:u32&limit=:u32 HTTP/1.1
    let view_torrent_list = filters::path::end()
        .and(filters::method::get())
        .and(filters::query::query())
        .map(move |limits| {
            let tracker = t1.clone();
            (limits, tracker)
        })
        .and_then(|(limits, tracker): (TorrentInfoQuery, Arc<TorrentTracker>)| {
            async move {
                let offset = limits.offset.unwrap_or(0);
                let limit = min(limits.limit.unwrap_or(1000), 4000);

                let db = tracker.get_database().await;
                let results: Vec<_> = db
                    .iter()
                    .map(|(k, v)| TorrentEntry { info_hash: k, data: v })
                    .skip(offset as usize)
                    .take(limit as usize)
                    .collect();

                Result::<_, warp::reject::Rejection>::Ok(reply::json(&results))
            }
        });

    let t2 = tracker.clone();
    // view_torrent_info -> GET /t/:infohash HTTP/*
    let view_torrent_info = filters::method::get()
        .and(filters::path::param())
        .map(move |info_hash: InfoHash| {
            let tracker = t2.clone();
            (info_hash, tracker)
        })
        .and_then(|(info_hash, tracker): (InfoHash, Arc<TorrentTracker>)| {
            async move {
                let db = tracker.get_database().await;
                let info = match db.get(&info_hash) {
                    Some(v) => v,
                    None => return Err(warp::reject::reject()),
                };

                Ok(reply::json(&TorrentEntry {
                    info_hash: &info_hash,
                    data: info,
                }))
            }
        });

    // DELETE /t/:info_hash
    let t3 = tracker.clone();
    let delete_torrent = filters::method::post()
        .and(filters::path::param())
        .map(move |info_hash: InfoHash| {
            let tracker = t3.clone();
            (info_hash, tracker)
        })
        .and_then(|(info_hash, tracker): (InfoHash, Arc<TorrentTracker>)| {
            async move {
                let resp = match tracker.remove_torrent(&info_hash, true).await.is_ok() {
                    true => ActionStatus::Ok,
                    false => {
                        ActionStatus::Err {
                            reason: "failed to delete torrent".into(),
                        }
                    }
                };

                Result::<_, warp::Rejection>::Ok(reply::json(&resp))
            }
        });

    let t4 = tracker.clone();
    // add_torrent/alter: POST /t/:info_hash
    // (optional) BODY: json: {"is_flagged": boolean}
    let change_torrent = filters::method::post()
        .and(filters::path::param())
        .and(filters::body::content_length_limit(4096))
        .and(filters::body::json())
        .map(move |info_hash: InfoHash, body: Option<TorrentFlag>| {
            let tracker = t4.clone();
            (info_hash, tracker, body)
        })
        .and_then(
            |(info_hash, tracker, body): (InfoHash, Arc<TorrentTracker>, Option<TorrentFlag>)| {
                async move {
                    let is_flagged = body.map(|e| e.is_flagged).unwrap_or(false);
                    if !tracker.set_torrent_flag(&info_hash, is_flagged).await {
                        // torrent doesn't exist, add it...

                        if is_flagged {
                            if tracker.add_torrent(&info_hash).await.is_ok() {
                                tracker.set_torrent_flag(&info_hash, is_flagged).await;
                            } else {
                                return Err(warp::reject::custom(ActionStatus::Err {
                                    reason: "failed to flag torrent".into(),
                                }));
                            }
                        }
                    }

                    Result::<_, warp::Rejection>::Ok(reply::json(&ActionStatus::Ok))
                }
            },
        );
    let torrent_mgmt =
        filters::path::path("t").and(view_torrent_list.or(delete_torrent).or(view_torrent_info).or(change_torrent));

    let server = root.or(authenticate(tokens).and(torrent_mgmt));

    serve(server)
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate env_logger;
extern crate futuremio;
extern crate ssl;

#[macro_use]
extern crate cfg_if;

use std::io::Error;
use std::net::ToSocketAddrs;

use futures::Future;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
    })
}

cfg_if! {
    if #[cfg(any(feature = "force-openssl",
                 all(not(target_os = "macos"),
                     not(target_os = "windows"))))] {
        extern crate openssl;

        use openssl::ssl as ossl;

        fn get(err: &Error) -> &[ossl::error::OpenSslError] {
            let err = err.get_ref().unwrap();
            match *err.downcast_ref::<ossl::error::Error>().unwrap() {
                ossl::Error::Ssl(ref v) => v,
                ref e => panic!("not an ssl eror: {:?}", e),
            }
        }

        fn verify_failed(err: &Error) {
            assert!(get(err).iter().any(|e| {
                e.reason() == "certificate verify failed"
            }), "bad errors: {:?}", err);
        }

        use verify_failed as assert_expired_error;
        use verify_failed as assert_wrong_host;
        use verify_failed as assert_self_signed;
        use verify_failed as assert_untrusted_root;

        fn assert_dh_too_small(err: &Error) {
            assert!(get(err).iter().any(|e| {
                e.reason() == "dh key too small"
            }), "bad errors: {:?}", err);
        }
    } else if #[cfg(target_os = "macos")] {
        extern crate security_framework;

        use security_framework::base::Error as SfError;

        fn assert_invalid_cert_chain(err: &Error) {
            let err = err.get_ref().unwrap();
            let err = err.downcast_ref::<SfError>().unwrap();
            assert_eq!(err.message().unwrap(), "invalid certificate chain");
        }

        use assert_invalid_cert_chain as assert_expired_error;
        use assert_invalid_cert_chain as assert_wrong_host;
        use assert_invalid_cert_chain as assert_self_signed;
        use assert_invalid_cert_chain as assert_untrusted_root;

        fn assert_dh_too_small(err: &Error) {
            let err = err.get_ref().unwrap();
            let err = err.downcast_ref::<SfError>().unwrap();
            assert_eq!(err.message().unwrap(), "handshake failure");
        }
    } else {
        extern crate winapi;

        fn assert_expired_error(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_EXPIRED as usize);
        }

        fn assert_wrong_host(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_CN_NO_MATCH as usize);
        }

        fn assert_self_signed(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_UNTRUSTEDROOT as usize);
        }

        fn assert_untrusted_root(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_UNTRUSTEDROOT as usize);
        }

        fn assert_dh_too_small(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::SEC_E_INTERNAL_ERROR as usize);
        }
    }
}

fn get_host(host: &'static str) -> Error {
    drop(env_logger::init());

    let addr = format!("{}:443", host);
    let addr = t!(addr.to_socket_addrs()).next().unwrap();

    let mut l = t!(futuremio::Loop::new());
    let client = l.handle().tcp_connect(&addr);
    let data = client.and_then(move |socket| {
        t!(ssl::ClientContext::new()).handshake(host, socket)
    });

    let res = l.run(data);
    assert!(res.is_err());
    res.err().unwrap()
}

#[test]
fn expired() {
    assert_expired_error(&get_host("expired.badssl.com"))
}

#[test]
fn wrong_host() {
    assert_wrong_host(&get_host("wrong.host.badssl.com"))
}

#[test]
fn self_signed() {
    assert_self_signed(&get_host("self-signed.badssl.com"))
}

#[test]
fn untrusted_root() {
    assert_untrusted_root(&get_host("untrusted-root.badssl.com"))
}

#[test]
fn dh_too_small() {
    assert_dh_too_small(&get_host("dh480.badssl.com"))
}
<commit_msg>Remove dh_too_small test<commit_after>extern crate futures;
extern crate env_logger;
extern crate futuremio;
extern crate ssl;

#[macro_use]
extern crate cfg_if;

use std::io::Error;
use std::net::ToSocketAddrs;

use futures::Future;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(e) => e,
        Err(e) => panic!("{} failed with {:?}", stringify!($e), e),
    })
}

cfg_if! {
    if #[cfg(any(feature = "force-openssl",
                 all(not(target_os = "macos"),
                     not(target_os = "windows"))))] {
        extern crate openssl;

        use openssl::ssl as ossl;

        fn get(err: &Error) -> &[ossl::error::OpenSslError] {
            let err = err.get_ref().unwrap();
            match *err.downcast_ref::<ossl::error::Error>().unwrap() {
                ossl::Error::Ssl(ref v) => v,
                ref e => panic!("not an ssl eror: {:?}", e),
            }
        }

        fn verify_failed(err: &Error) {
            assert!(get(err).iter().any(|e| {
                e.reason() == "certificate verify failed"
            }), "bad errors: {:?}", err);
        }

        use verify_failed as assert_expired_error;
        use verify_failed as assert_wrong_host;
        use verify_failed as assert_self_signed;
        use verify_failed as assert_untrusted_root;
    } else if #[cfg(target_os = "macos")] {
        extern crate security_framework;

        use security_framework::base::Error as SfError;

        fn assert_invalid_cert_chain(err: &Error) {
            let err = err.get_ref().unwrap();
            let err = err.downcast_ref::<SfError>().unwrap();
            assert_eq!(err.message().unwrap(), "invalid certificate chain");
        }

        use assert_invalid_cert_chain as assert_expired_error;
        use assert_invalid_cert_chain as assert_wrong_host;
        use assert_invalid_cert_chain as assert_self_signed;
        use assert_invalid_cert_chain as assert_untrusted_root;
    } else {
        extern crate winapi;

        fn assert_expired_error(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_EXPIRED as usize);
        }

        fn assert_wrong_host(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_CN_NO_MATCH as usize);
        }

        fn assert_self_signed(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_UNTRUSTEDROOT as usize);
        }

        fn assert_untrusted_root(err: &Error) {
            let code = err.raw_os_error().unwrap();
            assert_eq!(code as usize, winapi::CERT_E_UNTRUSTEDROOT as usize);
        }
    }
}

fn get_host(host: &'static str) -> Error {
    drop(env_logger::init());

    let addr = format!("{}:443", host);
    let addr = t!(addr.to_socket_addrs()).next().unwrap();

    let mut l = t!(futuremio::Loop::new());
    let client = l.handle().tcp_connect(&addr);
    let data = client.and_then(move |socket| {
        t!(ssl::ClientContext::new()).handshake(host, socket)
    });

    let res = l.run(data);
    assert!(res.is_err());
    res.err().unwrap()
}

#[test]
fn expired() {
    assert_expired_error(&get_host("expired.badssl.com"))
}

#[test]
fn wrong_host() {
    assert_wrong_host(&get_host("wrong.host.badssl.com"))
}

#[test]
fn self_signed() {
    assert_self_signed(&get_host("self-signed.badssl.com"))
}

#[test]
fn untrusted_root() {
    assert_untrusted_root(&get_host("untrusted-root.badssl.com"))
}
<|endoftext|>


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

//! The `servo` test application.
//!
//! Creates a `Browser` instance with a simple implementation of
//! the compositor's `WindowMethods` to create a working web browser.
//!
//! This browser's implementation of `WindowMethods` is built on top
//! of [glutin], the cross-platform OpenGL utility and windowing
//! library.
//!
//! For the engine itself look next door in lib.rs.
//!
//! [glutin]: https://github.com/tomaka/glutin

#![feature(start)]

// The Servo engine
extern crate servo;
// Window graphics compositing and message dispatch
extern crate compositing;
// Servo networking
extern crate net;
// Servo common utilitiess
extern crate util;
// The window backed by glutin
extern crate glutin_app as app;
extern crate time;

#[cfg(target_os="android")]
#[macro_use]
extern crate android_glue;

use std::rc::Rc;
use util::opts;
use net::resource_task;
use servo::Browser;
use compositing::windowing::WindowEvent;

#[cfg(target_os="android")]
use std::borrow::ToOwned;

fn main() {
    // Parse the command line options and store them globally
    if opts::from_cmdline_args(&*get_args()) {
        setup_logging();

        // Possibly interpret the `HOST_FILE` environment variable
        resource_task::global_init();

        let window = if opts::get().headless {
            None
        } else {
            Some(app::create_window(std::ptr::null_mut()))
        };

        // Our wrapper around `Browser` that also implements some
        // callbacks required by the glutin window implementation.
        let mut browser = BrowserWrapper {
            browser: Browser::new(window.clone()),
        };

        maybe_register_glutin_resize_handler(&window, &mut browser);

        browser.browser.handle_event(WindowEvent::InitializeCompositing);

        // Feed events from the window to the browser until the browser
        // says to stop.
        loop {
            let should_continue = match window {
                None => browser.browser.handle_event(WindowEvent::Idle),
                Some(ref window) => {
                    let event = window.wait_events();
                    browser.browser.handle_event(event)
                }
            };
            if !should_continue {
                break
            }
        };

        maybe_unregister_glutin_resize_handler(&window);

        let BrowserWrapper {
            browser
        } = browser;
        browser.shutdown();
    }
}

fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
                                        browser: &mut BrowserWrapper) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.set_nested_event_loop_listener(browser);
            }
        }
    }
}

fn maybe_unregister_glutin_resize_handler(window: &Option<Rc<app::window::Window>>) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.remove_nested_event_loop_listener();
            }
        }
    }
}

struct BrowserWrapper {
    browser: Browser,
}

impl app::NestedEventLoopListener for BrowserWrapper {
    fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool {
        let is_resize = match event {
            WindowEvent::Resize(..) => true,
            _ => false,
        };
        if !self.browser.handle_event(event) {
            return false
        }
        if is_resize {
            self.browser.repaint_synchronously()
        }
        true
    }
}

#[cfg(target_os="android")]
fn setup_logging() {
    android::setup_logging();
}

#[cfg(not(target_os="android"))]
fn setup_logging() {
}

#[cfg(target_os="android")]
fn get_args() -> Vec<String> {
    vec![
        "servo".to_owned(),
        "http://en.wikipedia.org/wiki/Rust".to_owned()
    ]
}

#[cfg(not(target_os="android"))]
fn get_args() -> Vec<String> {
    use std::env;
    env::args().collect()
}

// This macro must be used at toplevel because it defines a nested
// module, but macros can only accept identifiers - not paths -
// preventing the expansion of this macro within the android module
// without use of an additionl stub method or other hackery.
#[cfg(target_os = "android")]
android_start!(main);

#[cfg(target_os = "android")]
mod android {
    extern crate libc;
    extern crate android_glue;

    use self::libc::c_int;
    use std::borrow::ToOwned;

    pub fn setup_logging() {
        use self::libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO};
        //use std::env;

        //env::set_var("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra");
        redirect_output(STDERR_FILENO);
        redirect_output(STDOUT_FILENO);
    }

    struct FilePtr(*mut self::libc::types::common::c95::FILE);

    unsafe impl Send for FilePtr {}

    fn redirect_output(file_no: c_int) {
        use self::libc::funcs::posix88::unistd::{pipe, dup2};
        use self::libc::funcs::posix88::stdio::fdopen;
        use self::libc::funcs::c95::stdio::fgets;
        use util::task::spawn_named;
        use std::ffi::CString;
        use std::str::from_utf8;

        unsafe {
            let mut pipes: [c_int; 2] = [ 0, 0 ];
            pipe(pipes.as_mut_ptr());
            dup2(pipes[1], file_no);
            let mode = CString::new("r").unwrap();
            let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr()));
            spawn_named("android-logger".to_owned(), move || {
                loop {
                    let mut read_buffer: Vec<u8> = vec!();
                    read_buffer.reserve(1024);
                    let FilePtr(input_file) = input_file;
                    fgets(read_buffer.as_mut_ptr() as *mut i8, read_buffer.len() as i32, input_file);
                    let cs = CString::new(read_buffer).unwrap();
                    match from_utf8(cs.as_bytes()) {
                        Ok(s) => android_glue::write_log(s),
                        _ => {}
                    }
                }
            });
        }
    }

}
<commit_msg>Auto merge of #6108 - glennw:android-logs, r=larsbergstrom<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! The `servo` test application.
//!
//! Creates a `Browser` instance with a simple implementation of
//! the compositor's `WindowMethods` to create a working web browser.
//!
//! This browser's implementation of `WindowMethods` is built on top
//! of [glutin], the cross-platform OpenGL utility and windowing
//! library.
//!
//! For the engine itself look next door in lib.rs.
//!
//! [glutin]: https://github.com/tomaka/glutin

#![feature(start)]

// The Servo engine
extern crate servo;
// Window graphics compositing and message dispatch
extern crate compositing;
// Servo networking
extern crate net;
// Servo common utilitiess
extern crate util;
// The window backed by glutin
extern crate glutin_app as app;
extern crate time;

#[cfg(target_os="android")]
#[macro_use]
extern crate android_glue;

use std::rc::Rc;
use util::opts;
use net::resource_task;
use servo::Browser;
use compositing::windowing::WindowEvent;

#[cfg(target_os="android")]
use std::borrow::ToOwned;

fn main() {
    // Parse the command line options and store them globally
    if opts::from_cmdline_args(&*get_args()) {
        setup_logging();

        // Possibly interpret the `HOST_FILE` environment variable
        resource_task::global_init();

        let window = if opts::get().headless {
            None
        } else {
            Some(app::create_window(std::ptr::null_mut()))
        };

        // Our wrapper around `Browser` that also implements some
        // callbacks required by the glutin window implementation.
        let mut browser = BrowserWrapper {
            browser: Browser::new(window.clone()),
        };

        maybe_register_glutin_resize_handler(&window, &mut browser);

        browser.browser.handle_event(WindowEvent::InitializeCompositing);

        // Feed events from the window to the browser until the browser
        // says to stop.
        loop {
            let should_continue = match window {
                None => browser.browser.handle_event(WindowEvent::Idle),
                Some(ref window) => {
                    let event = window.wait_events();
                    browser.browser.handle_event(event)
                }
            };
            if !should_continue {
                break
            }
        };

        maybe_unregister_glutin_resize_handler(&window);

        let BrowserWrapper {
            browser
        } = browser;
        browser.shutdown();
    }
}

fn maybe_register_glutin_resize_handler(window: &Option<Rc<app::window::Window>>,
                                        browser: &mut BrowserWrapper) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.set_nested_event_loop_listener(browser);
            }
        }
    }
}

fn maybe_unregister_glutin_resize_handler(window: &Option<Rc<app::window::Window>>) {
    match *window {
        None => {}
        Some(ref window) => {
            unsafe {
                window.remove_nested_event_loop_listener();
            }
        }
    }
}

struct BrowserWrapper {
    browser: Browser,
}

impl app::NestedEventLoopListener for BrowserWrapper {
    fn handle_event_from_nested_event_loop(&mut self, event: WindowEvent) -> bool {
        let is_resize = match event {
            WindowEvent::Resize(..) => true,
            _ => false,
        };
        if !self.browser.handle_event(event) {
            return false
        }
        if is_resize {
            self.browser.repaint_synchronously()
        }
        true
    }
}

#[cfg(target_os="android")]
fn setup_logging() {
    android::setup_logging();
}

#[cfg(not(target_os="android"))]
fn setup_logging() {
}

#[cfg(target_os="android")]
fn get_args() -> Vec<String> {
    vec![
        "servo".to_owned(),
        "http://en.wikipedia.org/wiki/Rust".to_owned()
    ]
}

#[cfg(not(target_os="android"))]
fn get_args() -> Vec<String> {
    use std::env;
    env::args().collect()
}

// This macro must be used at toplevel because it defines a nested
// module, but macros can only accept identifiers - not paths -
// preventing the expansion of this macro within the android module
// without use of an additionl stub method or other hackery.
#[cfg(target_os = "android")]
android_start!(main);

#[cfg(target_os = "android")]
mod android {
    extern crate libc;
    extern crate android_glue;

    use self::libc::c_int;
    use std::borrow::ToOwned;

    pub fn setup_logging() {
        use self::libc::consts::os::posix88::{STDERR_FILENO, STDOUT_FILENO};
        //use std::env;

        //env::set_var("RUST_LOG", "servo,gfx,msg,util,layers,js,std,rt,extra");
        redirect_output(STDERR_FILENO);
        redirect_output(STDOUT_FILENO);
    }

    struct FilePtr(*mut self::libc::types::common::c95::FILE);

    unsafe impl Send for FilePtr {}

    fn redirect_output(file_no: c_int) {
        use self::libc::funcs::posix88::unistd::{pipe, dup2};
        use self::libc::funcs::posix88::stdio::fdopen;
        use self::libc::funcs::c95::stdio::fgets;
        use util::task::spawn_named;
        use std::ffi::CString;
        use std::str::from_utf8;
        use std::ffi::CStr;

        unsafe {
            let mut pipes: [c_int; 2] = [ 0, 0 ];
            pipe(pipes.as_mut_ptr());
            dup2(pipes[1], file_no);
            let mode = CString::new("r").unwrap();
            let input_file = FilePtr(fdopen(pipes[0], mode.as_ptr()));
            spawn_named("android-logger".to_owned(), move || {
                static READ_SIZE: usize = 1024;
                let mut read_buffer = vec![0; READ_SIZE];
                let FilePtr(input_file) = input_file;
                loop {
                    fgets(read_buffer.as_mut_ptr(), (read_buffer.len() as i32)-1, input_file);
                    let c_str = CStr::from_ptr(read_buffer.as_ptr());
                    let slice = from_utf8(c_str.to_bytes()).unwrap();
                    android_glue::write_log(slice);
                }
            });
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>Initial commit.<commit_after>extern mod extra;
use extra::treemap::TreeMap;
use std::vec;

type R = float;
type Deg = u8;
fn deg(n: int) -> Deg { n as Deg }

type Dim = u8;
fn dim(d: int) -> Dim { d as Dim }

#[deriving(Eq, IterBytes, TotalOrd, TotalEq, Clone, Ord)]
pub struct Monomial {
  exps: ~[Deg]
}

impl Monomial {

  fn with_exps(exps: ~[Deg]) -> Monomial {
    if exps.len() == 0 { fail!("Monomial requires non-empty array of exponents."); }
    else {
      Monomial {exps: exps}
    }
  }

  fn domain_dim(&self) -> Dim {
    self.exps.len() as Dim
  }

  fn one(d: Dim) -> Monomial {
    let exps = vec::from_elem(d as uint, 0 as Deg);
    Monomial::with_exps(exps)
  }
}

impl ToStr for Monomial {
  fn to_str(&self) -> ~str {
    match self.domain_dim() {
      1 => { fmt!("x^%?", self.exps[0]) }
      2 => { fmt!("x^%?y^%?", self.exps[0], self.exps[1]) }
      3 => { fmt!("x^%?y^%?z^%?", self.exps[0], self.exps[1], self.exps[2]) }
      _ => { /* join(map(i->"x$i^$(int(m.exps[i]))", 1:ddim), " ") */ ~"TODO" }
    }
  }
}

#[deriving(Eq, IterBytes, Clone, Ord)]
pub struct Polynomial {
  mons: ~[Monomial],
  coefs: ~[R]
}

impl Polynomial {

  fn with_mons_and_coefs(mons: ~[Monomial], coefs: ~[R]) -> Polynomial {
    if mons.len() != coefs.len() { fail!("size of coefficent and monomial arrays must match"); }
    else if mons.len() == 0 { fail!("polynomial requires one or more terms"); }
    else {
      Polynomial { mons: mons, coefs: coefs }
    }
  }

  fn canonical_form(&self) -> Polynomial {

    let combined_coefs_by_mon = {
      let mut mon_to_coef:TreeMap<&Monomial,R> = TreeMap::new();
      for i in range(0, self.mons.len()) {
        let (mon, mon_coef) = (&self.mons[i], self.coefs[i]);
        if mon_coef != 0 as R {
          let updated = match mon_to_coef.find_mut(&mon) {
            Some(coef) => { *coef += mon_coef; true }, None => false
          };
          if !updated {
            mon_to_coef.insert(mon, mon_coef);
          }
        }
      }
      mon_to_coef
    };

    let mut mons:~[Monomial] = vec::with_capacity(combined_coefs_by_mon.len());
    let mut coefs:~[R] = vec::with_capacity(combined_coefs_by_mon.len());
    for (&mon, &coef) in combined_coefs_by_mon.iter() {
      if coef != 0 as R {
        mons.push(mon.clone());
        coefs.push(coef);
      }
    }

    if mons.len() != 0 {
      Polynomial::with_mons_and_coefs(mons, coefs)
    }
    else {
      Polynomial::zero(self.domain_dim())
    }
  }

  fn domain_dim(&self) -> Dim {
    self.mons[0].domain_dim()
  }

  fn zero(d: Dim) -> Polynomial {
    Polynomial::with_mons_and_coefs(~[Monomial::one(d)], ~[0 as R])
  }
}

impl ToStr for Polynomial {
  fn to_str(&self) -> ~str {
    // join(map(i->"$(p.coefs[i]) $(p.mons[i])", 1:length(p.mons)), " + ")
    fmt!("Polynomial %?", *self)
  }
}

fn main() {
  let x = Monomial::with_exps(~[deg(1), deg(0)]);
  let y = Monomial::with_exps(~[deg(0), deg(1)]);
  let xy = Monomial::with_exps(~[deg(1), deg(1)]);
  let mons = ~[x.clone(), y.clone(), xy.clone(), x.clone(), xy.clone()];
  let p = Polynomial::with_mons_and_coefs(mons, ~[1.0, -1.0, 2.0, -1.0, 2.0]);
  let cfp = p.canonical_form();
  println(fmt!("Canonical form of %s is %s", p.to_str(), cfp.to_str()));
}
<|endoftext|>


<commit_before><commit_msg>Send title and author in message<commit_after><|endoftext|>


<commit_before><commit_msg>Add an example dump command for printing the output of parser.read().<commit_after>extern crate wasmparser;

use std::io;
use std::io::prelude::*;
use std::fs::File;
use std::str;
use std::env;
use wasmparser::Parser;
use wasmparser::ParserState;

fn get_name(bytes: &[u8]) -> &str {
    str::from_utf8(bytes).ok().unwrap()
}

fn main() {
    let args = env::args().collect::<Vec<_>>();
    if args.len() != 2 {
        println!("Usage: {} in.wasm", args[0]);
        return;
    }

    let ref buf: Vec<u8> = read_wasm(&args[1]).unwrap();
    let mut parser = Parser::new(buf);
    loop {
        let state = parser.read();
        match *state {
            ParserState::ExportSectionEntry {
                field,
                ref kind,
                index,
            } => {
                println!("ExportSectionEntry {{ field: \"{}\", kind: {:?}, index: {} }}",
                         get_name(field),
                         kind,
                         index);
            }
            ParserState::ImportSectionEntry {
                module,
                field,
                ref ty,
            } => {
                println!("ImportSectionEntry {{ module: \"{}\", field: \"{}\", ty: {:?} }}",
                         get_name(module),
                         get_name(field),
                         ty);
            }
            ParserState::EndWasm => break,
            ParserState::Error(msg) => panic!("Error: {}", msg),
            _ => println!("{:?}", state),
        }
    }
}

fn read_wasm(file: &str) -> io::Result<Vec<u8>> {
    let mut data = Vec::new();
    let mut f = File::open(file)?;
    f.read_to_end(&mut data)?;
    Ok(data)
}
<|endoftext|>


<commit_before>import task;
import vec;

import comm;
import comm::{chan, port, send, recv};
import net;

native "c-stack-cdecl" mod rustrt {
    type socket;
    type server;
    fn aio_init();
    fn aio_run();
    fn aio_stop();
    fn aio_connect(host: *u8, port: int, connected: chan<socket>);
    fn aio_serve(host: *u8, port: int, acceptChan: chan<socket>) -> server;
    fn aio_writedata(s: socket, buf: *u8, size: uint, status: chan<bool>);
    fn aio_read(s: socket, reader: chan<[u8]>);
    fn aio_close_server(s: server, status: chan<bool>);
    fn aio_close_socket(s: socket);
    fn aio_is_null_client(s: socket) -> bool;
}

// FIXME: these should be unsafe pointers or something, but those aren't
// currently in the sendable kind, so we'll unsafely cast between ints.
type server = rustrt::server;
type client = rustrt::socket;
tag pending_connection { remote(net::ip_addr, int); incoming(server); }

tag socket_event { connected(client); closed; received([u8]); }

tag server_event { pending(chan<chan<socket_event>>); }

tag request {
    quit;
    connect(pending_connection, chan<socket_event>);
    serve(net::ip_addr, int, chan<server_event>, chan<server>);
    write(client, [u8], chan<bool>);
    close_server(server, chan<bool>);
    close_client(client);
}

type ctx = chan<request>;

fn ip_to_sbuf(ip: net::ip_addr) -> *u8 unsafe {

    // FIXME: This is broken. We're creating a vector, getting a pointer
    // to its buffer, then dropping the vector. On top of that, the vector
    // created by str::bytes is not null-terminated.
    vec::to_ptr(str::bytes(net::format_addr(ip)))
}

fn connect_task(ip: net::ip_addr, portnum: int, evt: chan<socket_event>) {
    let connecter = port();
    rustrt::aio_connect(ip_to_sbuf(ip), portnum, chan(connecter));
    let client = recv(connecter);
    new_client(client, evt);
}

fn new_client(client: client, evt: chan<socket_event>) {
    // Start the read before notifying about the connect.  This avoids a race
    // condition where the receiver can close the socket before we start
    // reading.
    let reader: port<[u8]> = port();
    rustrt::aio_read(client, chan(reader));

    send(evt, connected(client));

    while true {
        log "waiting for bytes";
        let data: [u8] = recv(reader);
        log "got some bytes";
        log vec::len::<u8>(data);
        if vec::len::<u8>(data) == 0u {
            log "got empty buffer, bailing";
            break;
        }
        log "got non-empty buffer, sending";
        send(evt, received(data));
        log "sent non-empty buffer";
    }
    log "done reading";
    send(evt, closed);
    log "close message sent";
}

fn accept_task(client: client, events: chan<server_event>) {
    log "accept task was spawned";
    let p = port();
    send(events, pending(chan(p)));
    let evt = recv(p);
    new_client(client, evt);
    log "done accepting";
}

fn server_task(ip: net::ip_addr, portnum: int, events: chan<server_event>,
               server: chan<server>) {
    let accepter = port();
    send(server, rustrt::aio_serve(ip_to_sbuf(ip), portnum, chan(accepter)));

    let client: client;
    while true {
        log "preparing to accept a client";
        client = recv(accepter);
        if rustrt::aio_is_null_client(client) {
            log "client was actually null, returning";
            ret;
        } else { task::spawn(bind accept_task(client, events)); }
    }
}

fn request_task(c: chan<ctx>) {
    // Create a port to accept IO requests on
    let p = port();
    // Hand of its channel to our spawner
    send(c, chan(p));
    log "uv run task spawned";
    // Spin for requests
    let req: request;
    while true {
        req = recv(p);
        alt req {
          quit. {
            log "got quit message";
            log "stopping libuv";
            rustrt::aio_stop();
            ret;
          }
          connect(remote(ip, portnum), client) {
            task::spawn(bind connect_task(ip, portnum, client));
          }
          serve(ip, portnum, events, server) {
            task::spawn(bind server_task(ip, portnum, events, server));
          }
          write(socket, v, status) unsafe {
            rustrt::aio_writedata(socket, vec::unsafe::to_ptr::<u8>(v),
                                  vec::len::<u8>(v), status);
          }
          close_server(server, status) {
            log "closing server";
            rustrt::aio_close_server(server, status);
          }
          close_client(client) {
            log "closing client";
            rustrt::aio_close_socket(client);
          }
        }
    }
}

fn iotask(c: chan<ctx>) {
    log "io task spawned";
    // Initialize before accepting requests
    rustrt::aio_init();

    log "io task init";
    // Spawn our request task
    let reqtask = task::spawn_joinable(bind request_task(c));

    log "uv run task init";
    // Enter IO loop. This never returns until aio_stop is called.
    rustrt::aio_run();
    log "waiting for request task to finish";

    task::join(reqtask);
}

fn new() -> ctx {
    let p: port<ctx> = port();
    task::spawn(bind iotask(chan(p)));
    ret recv(p);
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Convert std::aio to new spawn functions<commit_after>import task;
import vec;

import comm;
import comm::{chan, port, send, recv};
import net;

native "c-stack-cdecl" mod rustrt {
    type socket;
    type server;
    fn aio_init();
    fn aio_run();
    fn aio_stop();
    fn aio_connect(host: *u8, port: int, connected: chan<socket>);
    fn aio_serve(host: *u8, port: int, acceptChan: chan<socket>) -> server;
    fn aio_writedata(s: socket, buf: *u8, size: uint, status: chan<bool>);
    fn aio_read(s: socket, reader: chan<[u8]>);
    fn aio_close_server(s: server, status: chan<bool>);
    fn aio_close_socket(s: socket);
    fn aio_is_null_client(s: socket) -> bool;
}

// FIXME: these should be unsafe pointers or something, but those aren't
// currently in the sendable kind, so we'll unsafely cast between ints.
type server = rustrt::server;
type client = rustrt::socket;
tag pending_connection { remote(net::ip_addr, int); incoming(server); }

tag socket_event { connected(client); closed; received([u8]); }

tag server_event { pending(chan<chan<socket_event>>); }

tag request {
    quit;
    connect(pending_connection, chan<socket_event>);
    serve(net::ip_addr, int, chan<server_event>, chan<server>);
    write(client, [u8], chan<bool>);
    close_server(server, chan<bool>);
    close_client(client);
}

type ctx = chan<request>;

fn ip_to_sbuf(ip: net::ip_addr) -> *u8 unsafe {

    // FIXME: This is broken. We're creating a vector, getting a pointer
    // to its buffer, then dropping the vector. On top of that, the vector
    // created by str::bytes is not null-terminated.
    vec::to_ptr(str::bytes(net::format_addr(ip)))
}

fn# connect_task(args: (net::ip_addr, int, chan<socket_event>)) {
    let (ip, portnum, evt) = args;
    let connecter = port();
    rustrt::aio_connect(ip_to_sbuf(ip), portnum, chan(connecter));
    let client = recv(connecter);
    new_client(client, evt);
}

fn new_client(client: client, evt: chan<socket_event>) {
    // Start the read before notifying about the connect.  This avoids a race
    // condition where the receiver can close the socket before we start
    // reading.
    let reader: port<[u8]> = port();
    rustrt::aio_read(client, chan(reader));

    send(evt, connected(client));

    while true {
        log "waiting for bytes";
        let data: [u8] = recv(reader);
        log "got some bytes";
        log vec::len::<u8>(data);
        if vec::len::<u8>(data) == 0u {
            log "got empty buffer, bailing";
            break;
        }
        log "got non-empty buffer, sending";
        send(evt, received(data));
        log "sent non-empty buffer";
    }
    log "done reading";
    send(evt, closed);
    log "close message sent";
}

fn# accept_task(args: (client, chan<server_event>)) {
    let (client, events) = args;
    log "accept task was spawned";
    let p = port();
    send(events, pending(chan(p)));
    let evt = recv(p);
    new_client(client, evt);
    log "done accepting";
}

fn# server_task(args: (net::ip_addr, int, chan<server_event>,
                       chan<server>)) {
    let (ip, portnum, events, server) = args;
    let accepter = port();
    send(server, rustrt::aio_serve(ip_to_sbuf(ip), portnum, chan(accepter)));

    let client: client;
    while true {
        log "preparing to accept a client";
        client = recv(accepter);
        if rustrt::aio_is_null_client(client) {
            log "client was actually null, returning";
            ret;
        } else { task::spawn2((client, events), accept_task); }
    }
}

fn# request_task(c: chan<ctx>) {
    // Create a port to accept IO requests on
    let p = port();
    // Hand of its channel to our spawner
    send(c, chan(p));
    log "uv run task spawned";
    // Spin for requests
    let req: request;
    while true {
        req = recv(p);
        alt req {
          quit. {
            log "got quit message";
            log "stopping libuv";
            rustrt::aio_stop();
            ret;
          }
          connect(remote(ip, portnum), client) {
            task::spawn2((ip, portnum, client), connect_task);
          }
          serve(ip, portnum, events, server) {
            task::spawn2((ip, portnum, events, server), server_task);
          }
          write(socket, v, status) unsafe {
            rustrt::aio_writedata(socket, vec::unsafe::to_ptr::<u8>(v),
                                  vec::len::<u8>(v), status);
          }
          close_server(server, status) {
            log "closing server";
            rustrt::aio_close_server(server, status);
          }
          close_client(client) {
            log "closing client";
            rustrt::aio_close_socket(client);
          }
        }
    }
}

fn# iotask(c: chan<ctx>) {
    log "io task spawned";
    // Initialize before accepting requests
    rustrt::aio_init();

    log "io task init";
    // Spawn our request task
    let reqtask = task::spawn_joinable2(c, request_task);

    log "uv run task init";
    // Enter IO loop. This never returns until aio_stop is called.
    rustrt::aio_run();
    log "waiting for request task to finish";

    task::join(reqtask);
}

fn new() -> ctx {
    let p: port<ctx> = port();
    task::spawn2(chan(p), iotask);
    ret recv(p);
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>git work<commit_after><|endoftext|>


<commit_before><commit_msg>add trait file<commit_after>pub trait SortVec<T: Ord> {
    /// The length of the vector.
    fn len(&self) -> usize;

    /// Append an element to the end of the vector.
    fn push(&mut self, value: T);

    /// Set the `i`th element of the vector.
    /// Panics if the vector contains fewer than `i` elements.
    fn set(&mut self, index: usize, value: T);

    /// Truncate this vector and reset the sort if necessary.
    fn truncate(&mut self, len: usize);

    /// Sort the vector
    fn sort(&mut self);
}

pub trait IntoSortedIterator {
    type Item: Ord;
    type IntoSortedIter: Iterator<Item=Self::Item>;

    /// A sorted iterator over the vector.
    fn sorted_iter(self) -> Self::IntoSortedIter;
}

impl<T: Ord> SortVec<T> for Vec<T> {
    fn len(&self) -> usize {
        self.len()
    }
    fn push(&mut self, val: T) {
        self.push(val);
    }
    fn set(&mut self, index: usize, val: T) {
        self[index] = val;
    }
    fn truncate(&mut self, size: usize) {
        self.truncate(size);
    }
    fn sort(&mut self) {
        (**self).sort();
    }
}

// impl<'a, T: Ord> IntoSortedIterator for &'a Vec<T> {
//     type Item = T;
//     type IntoSortedIter = Iter<T>;

//     fn sorted_iter(self) {

//     }
// }
<|endoftext|>


<commit_before><commit_msg>examples: FlagSubCommand pacman<commit_after>// Working with flag subcommands allows behavior similar to the popular Archlinux package manager Pacman.
// Man page: https://jlk.fjfi.cvut.cz/arch/manpages/man/pacman.8
//
// It's suggested that you read examples/20_subcommands.rs prior to learning about `FlagSubCommand`s
//
// This differs from normal subcommands because it allows passing subcommand as `clap::Arg` in short or long args.
//
//            Top Level App (pacman)                              TOP
//                           |
//    ---------------------------------------------------
//   /     |        |        |         |        \        \
// sync  database remove    files      query   deptest   upgrade  LEVEL 1
//
// Given the above hierachy, valid runtime uses would be (not an all inclusive list):
//
// $ pacman -Ss
//           ^--- subcommand followed by an arg in its scope.
//
// $ pacman -Qs
//
// $ pacman -Rns
//
// NOTE: Subcommands short flags don't have to be uppercase.
//
// $ pacman --sync --search
//            ^--- subcommand
//
// $ pacman sync -s
//          ^--- subcommand
//
// NOTE: this isn't valid for pacman, but `clap::FlagSubCommand`
// adds support for both flags and standard subcommands out of the box.
// Allowing your users to make the choice of what feels more intuitive for them.
//
// Notice only one command per "level" may be used. You could not, for example, do:
//
// $ pacman -SQR
//
// It's also important to know that subcommands each have their own set of matches and may have args
// with the same name as other subcommands in a different part of the tree heirachy (i.e. the arg
// names aren't in a flat namespace).
//
// In order to use subcommands in clap, you only need to know which subcommand you're at in your
// tree, and which args are defined on that subcommand.
//
// Let's make a quick program to illustrate. We'll be using the same example as above but for
// brevity sake we won't implement all of the subcommands, only a few.
use clap::{App, AppSettings, Arg, FlagSubCommand};

fn main() {
    let matches = App::new("pacman")
        .about("package manager utility")
        .version("5.2.1")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .author("Pacman Development Team")
        // Query subcommand
        //
        // Only a few of its arguments are implemented below.
        .subcommand(
            // When getting the subcommand name the long version is used (in this case "query").
            // If you want to use a different name then `FlagSubCommand::with_name("name", 's', "long")`.
            //
            // NOTE: if the name has been changed then it can be used as that:
            //
            // $ MyProg name
            //
            // $ MyProg --long
            //
            // $ MyProg -s
            FlagSubCommand::new('Q', "query")
                .about("Query the package database.")
                .arg(
                    Arg::new("search")
                        .short('s')
                        .long("search")
                        .about("search locally-installed packages for matching strings")
                        .takes_value(true),
                )
                .arg(
                    Arg::new("info")
                        .long("info")
                        .short('i')
                        .about("view package information (-ii for backup files)")
                        .multiple(true),
                ),
        )
        // Sync subcommand
        //
        // Only a few of its arguments are implemented below.
        .subcommand(
            FlagSubCommand::new('S', "sync")
                .about("Synchronize packages.")
                .arg(
                    Arg::new("search")
                        .short('s')
                        .long("search")
                        .about("search remote repositories for matching strings")
                        .takes_value(true),
                )
                .arg(
                    Arg::new("info")
                        .long("info")
                        .short('i')
                        .about("view package information (-ii for extended information)")
                        .multiple(true),
                )
                .arg(
                    Arg::new("package")
                        .about("package")
                        .multiple(true)
                        .takes_value(true),
                ),
        )
        .get_matches();

    match matches.subcommand() {
        ("sync", Some(sync_matches)) => {
            if sync_matches.is_present("info") {
                // Values required here, so it's safe to unwrap
                let packages: Vec<_> = sync_matches.values_of("info").unwrap().collect();
                println!("Retrieving info for {:?}...", packages);
            } else if sync_matches.is_present("search") {
                // Values required here, so it's safe to unwrap
                let queries: Vec<_> = sync_matches.values_of("search").unwrap().collect();
                println!("Searching for {:?}...", queries);
            } else {
                match sync_matches.values_of("package") {
                    Some(packages) => {
                        let pkgs: Vec<_> = packages.collect();
                        println!("Installing {:?}...", pkgs);
                    }
                    None => panic!("No targets specified (use -h for help)"),
                }
            }
        }
        ("query", Some(query_matches)) => {
            if query_matches.is_present("info") {
                // Values required here, so it's safe to unwrap
                let packages: Vec<_> = query_matches.values_of("info").unwrap().collect();
                println!("Retrieving info for {:?}...", packages);
            } else if query_matches.is_present("search") {
                // Values required here, so it's safe to unwrap
                let queries: Vec<_> = query_matches.values_of("search").unwrap().collect();
                println!("Searching Locally for {:?}...", queries);
            } else {
                // Query was called without any arguments
                println!("Displaying all locally installed packages...");
            }
        }
        ("", None) => panic!("error: no operation specified (use -h for help)"), // If no subcommand was used
        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable
    }
}
<|endoftext|>


<commit_before><commit_msg>added copy<commit_after><|endoftext|>


<commit_before><commit_msg>languages/rust/learn-rust/3-chapter/11-code.rs<commit_after><|endoftext|>


<commit_before><commit_msg>languages/rust/learn-rust/3-chapter/18-code.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Don't rely on Deref inside `hash`.<commit_after><|endoftext|>


<commit_before><commit_msg>aggro set<commit_after><|endoftext|>