<commit_before>#[doc(
    brief = "The attribute parsing pass",
    desc =
    "Traverses the document tree, pulling relevant documention out of the \
     corresponding AST nodes. The information gathered here is the basis \
     of the natural-language documentation for a crate."
)];

import rustc::syntax::ast;
import rustc::middle::ast_map;

export mk_pass;

fn mk_pass() -> pass {
    run
}

fn run(
    srv: astsrv::srv,
    doc: doc::cratedoc
) -> doc::cratedoc {
    let fold = fold::fold({
        fold_crate: fold_crate,
        fold_mod: fold_mod,
        fold_fn: fold_fn,
        fold_const: fold_const,
        fold_enum: fold_enum,
        fold_res: fold_res
        with *fold::default_seq_fold(srv)
    });
    fold.fold_crate(fold, doc)
}

fn fold_crate(
    fold: fold::fold<astsrv::srv>,
    doc: doc::cratedoc
) -> doc::cratedoc {

    let srv = fold.ctxt;
    let doc = fold::default_seq_fold_crate(fold, doc);

    let attrs = astsrv::exec(srv) {|ctxt|
        let attrs = ctxt.ast.node.attrs;
        attr_parser::parse_crate(attrs)
    };

    ~{
        topmod: ~{
            name: option::from_maybe(doc.topmod.name, attrs.name)
            with *doc.topmod
        }
    }
}

#[test]
fn should_replace_top_module_name_with_crate_name() {
    let source = "#[link(name = \"bond\")];";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_crate(fold, doc);
    assert doc.topmod.name == "bond";
}

fn parse_item_attrs<T>(
    srv: astsrv::srv,
    id: doc::ast_id,
    parse_attrs: fn~([ast::attribute]) -> T) -> T {
    astsrv::exec(srv) {|ctxt|
        let attrs = alt ctxt.ast_map.get(id) {
          ast_map::node_item(item) { item.attrs }
        };
        parse_attrs(attrs)
    }
}

fn fold_mod(fold: fold::fold<astsrv::srv>, doc: doc::moddoc) -> doc::moddoc {
    let srv = fold.ctxt;
    let attrs = if doc.id == ast::crate_node_id {
        // This is the top-level mod, use the crate attributes
        astsrv::exec(srv) {|ctxt|
            attr_parser::parse_mod(ctxt.ast.node.attrs)
        }
    } else {
        parse_item_attrs(srv, doc.id, attr_parser::parse_mod)
    };
    let doc = fold::default_seq_fold_mod(fold, doc);
    ret merge_mod_attrs(doc, attrs);

    fn merge_mod_attrs(
        doc: doc::moddoc,
        attrs: attr_parser::mod_attrs
    ) -> doc::moddoc {
        ~{
            brief: attrs.brief,
            desc: attrs.desc
            with *doc
        }
    }
}

#[test]
fn fold_mod_should_extract_mod_attributes() {
    let source = "#[doc = \"test\"] mod a { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_mod(fold, doc.topmod.mods()[0]);
    assert doc.desc == some("test");
}

#[test]
fn fold_mod_should_extract_top_mod_attributes() {
    let source = "#[doc = \"test\"];";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_mod(fold, doc.topmod);
    assert doc.desc == some("test");
}

fn fold_fn(
    fold: fold::fold<astsrv::srv>,
    doc: doc::fndoc
) -> doc::fndoc {

    let srv = fold.ctxt;

    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_fn);
    ret merge_fn_attrs(doc, attrs);

    fn merge_fn_attrs(
        doc: doc::fndoc,
        attrs: attr_parser::fn_attrs
    ) -> doc::fndoc {
        ret ~{
            brief: attrs.brief,
            desc: attrs.desc,
            args: merge_arg_attrs(doc.args, attrs.args),
            return: merge_ret_attrs(doc.return, attrs.return),
            failure: attrs.failure
            with *doc
        };
    }

    fn merge_arg_attrs(
        docs: [doc::argdoc],
        attrs: [attr_parser::arg_attrs]
    ) -> [doc::argdoc] {
        vec::map(docs) {|doc|
            alt vec::find(attrs) {|attr|
                attr.name == doc.name
            } {
                some(attr) {
                    ~{
                        desc: some(attr.desc)
                        with *doc
                    }
                }
                none { doc }
            }
        }
        // FIXME: Warning when documenting a non-existent arg
    }

    fn merge_ret_attrs(
        doc: doc::retdoc,
        attrs: option<str>
    ) -> doc::retdoc {
        {
            desc: attrs
            with doc
        }
    }
}

#[test]
fn fold_fn_should_extract_fn_attributes() {
    let source = "#[doc = \"test\"] fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.desc == some("test");
}

#[test]
fn fold_fn_should_extract_arg_attributes() {
    let source = "#[doc(args(a = \"b\"))] fn c(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.args[0].desc == some("b");
}

#[test]
fn fold_fn_should_extract_return_attributes() {
    let source = "#[doc(return = \"what\")] fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = tystr_pass::mk_pass()(srv, doc);
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.return.desc == some("what");
}

#[test]
fn fold_fn_should_preserve_sig() {
    let source = "fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = tystr_pass::mk_pass()(srv, doc);
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.sig == some("fn a() -> int");
}

#[test]
fn fold_fn_should_extract_failure_conditions() {
    let source = "#[doc(failure = \"what\")] fn a() { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.failure == some("what");
}

fn fold_const(
    fold: fold::fold<astsrv::srv>,
    doc: doc::constdoc
) -> doc::constdoc {
    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_mod);

    ~{
        brief: attrs.brief,
        desc: attrs.desc
        with *doc
    }
}

#[test]
fn fold_const_should_extract_docs() {
    let source = "#[doc(brief = \"foo\", desc = \"bar\")]\
                  const a: bool = true;";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_const(fold, doc.topmod.consts()[0]);
    assert doc.brief == some("foo");
    assert doc.desc == some("bar");
}

fn fold_enum(
    fold: fold::fold<astsrv::srv>,
    doc: doc::enumdoc
) -> doc::enumdoc {
    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_enum);

    ~{
        brief: attrs.brief,
        desc: attrs.desc,
        variants: vec::map(doc.variants) {|variant|
            let attrs = astsrv::exec(srv) {|ctxt|
                alt ctxt.ast_map.get(doc.id) {
                  ast_map::node_item(@{
                    node: ast::item_enum(ast_variants, _), _
                  }) {
                    let ast_variant = option::get(
                        vec::find(ast_variants) {|v|
                            v.node.name == variant.name
                        });

                    attr_parser::parse_variant(ast_variant.node.attrs)
                  }
                }
            };

            ~{
                desc: attrs.desc
                with *variant
            }
        }
        with *doc
    }
}

#[test]
fn fold_enum_should_extract_docs() {
    let source = "#[doc(brief = \"a\", desc = \"b\")]\
                  enum a { v }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_enum(fold, doc.topmod.enums()[0]);
    assert doc.brief == some("a");
    assert doc.desc == some("b");
}

#[test]
fn fold_enum_should_extract_variant_docs() {
    let source = "enum a { #[doc = \"c\"] v }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_enum(fold, doc.topmod.enums()[0]);
    assert doc.variants[0].desc == some("c");
}

fn fold_res(
    fold: fold::fold<astsrv::srv>,
    doc: doc::resdoc
) -> doc::resdoc {

    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_fn);

    ~{
        brief: attrs.brief,
        desc: attrs.desc,
        args: vec::map(doc.args) {|doc|
            alt vec::find(attrs.args) {|attr|
                attr.name == doc.name
            } {
                some(attr) {
                    ~{
                        desc: some(attr.desc)
                        with *doc
                    }
                }
                none { doc }
            }
        }
        with *doc
    }
}

#[test]
fn fold_res_should_extract_docs() {
    let source = "#[doc(brief = \"a\", desc = \"b\")]\
                  resource r(b: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_res(fold, doc.topmod.resources()[0]);
    assert doc.brief == some("a");
    assert doc.desc == some("b");
}

#[test]
fn fold_res_should_extract_arg_docs() {
    let source = "#[doc(args(a = \"b\"))]\
                  resource r(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_res(fold, doc.topmod.resources()[0]);
    assert doc.args[0].name == "a";
    assert doc.args[0].desc == some("b");
}<commit_msg>rustdoc: Fix typo in attr_pass<commit_after>#[doc(
    brief = "The attribute parsing pass",
    desc =
    "Traverses the document tree, pulling relevant documention out of the \
     corresponding AST nodes. The information gathered here is the basis \
     of the natural-language documentation for a crate."
)];

import rustc::syntax::ast;
import rustc::middle::ast_map;

export mk_pass;

fn mk_pass() -> pass {
    run
}

fn run(
    srv: astsrv::srv,
    doc: doc::cratedoc
) -> doc::cratedoc {
    let fold = fold::fold({
        fold_crate: fold_crate,
        fold_mod: fold_mod,
        fold_fn: fold_fn,
        fold_const: fold_const,
        fold_enum: fold_enum,
        fold_res: fold_res
        with *fold::default_seq_fold(srv)
    });
    fold.fold_crate(fold, doc)
}

fn fold_crate(
    fold: fold::fold<astsrv::srv>,
    doc: doc::cratedoc
) -> doc::cratedoc {

    let srv = fold.ctxt;
    let doc = fold::default_seq_fold_crate(fold, doc);

    let attrs = astsrv::exec(srv) {|ctxt|
        let attrs = ctxt.ast.node.attrs;
        attr_parser::parse_crate(attrs)
    };

    ~{
        topmod: ~{
            name: option::from_maybe(doc.topmod.name, attrs.name)
            with *doc.topmod
        }
    }
}

#[test]
fn should_replace_top_module_name_with_crate_name() {
    let source = "#[link(name = \"bond\")];";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_crate(fold, doc);
    assert doc.topmod.name == "bond";
}

fn parse_item_attrs<T>(
    srv: astsrv::srv,
    id: doc::ast_id,
    parse_attrs: fn~([ast::attribute]) -> T) -> T {
    astsrv::exec(srv) {|ctxt|
        let attrs = alt ctxt.ast_map.get(id) {
          ast_map::node_item(item) { item.attrs }
        };
        parse_attrs(attrs)
    }
}

fn fold_mod(fold: fold::fold<astsrv::srv>, doc: doc::moddoc) -> doc::moddoc {
    let srv = fold.ctxt;
    let attrs = if doc.id == ast::crate_node_id {
        // This is the top-level mod, use the crate attributes
        astsrv::exec(srv) {|ctxt|
            attr_parser::parse_mod(ctxt.ast.node.attrs)
        }
    } else {
        parse_item_attrs(srv, doc.id, attr_parser::parse_mod)
    };
    let doc = fold::default_seq_fold_mod(fold, doc);
    ret merge_mod_attrs(doc, attrs);

    fn merge_mod_attrs(
        doc: doc::moddoc,
        attrs: attr_parser::mod_attrs
    ) -> doc::moddoc {
        ~{
            brief: attrs.brief,
            desc: attrs.desc
            with *doc
        }
    }
}

#[test]
fn fold_mod_should_extract_mod_attributes() {
    let source = "#[doc = \"test\"] mod a { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_mod(fold, doc.topmod.mods()[0]);
    assert doc.desc == some("test");
}

#[test]
fn fold_mod_should_extract_top_mod_attributes() {
    let source = "#[doc = \"test\"];";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_mod(fold, doc.topmod);
    assert doc.desc == some("test");
}

fn fold_fn(
    fold: fold::fold<astsrv::srv>,
    doc: doc::fndoc
) -> doc::fndoc {

    let srv = fold.ctxt;

    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_fn);
    ret merge_fn_attrs(doc, attrs);

    fn merge_fn_attrs(
        doc: doc::fndoc,
        attrs: attr_parser::fn_attrs
    ) -> doc::fndoc {
        ret ~{
            brief: attrs.brief,
            desc: attrs.desc,
            args: merge_arg_attrs(doc.args, attrs.args),
            return: merge_ret_attrs(doc.return, attrs.return),
            failure: attrs.failure
            with *doc
        };
    }

    fn merge_arg_attrs(
        docs: [doc::argdoc],
        attrs: [attr_parser::arg_attrs]
    ) -> [doc::argdoc] {
        vec::map(docs) {|doc|
            alt vec::find(attrs) {|attr|
                attr.name == doc.name
            } {
                some(attr) {
                    ~{
                        desc: some(attr.desc)
                        with *doc
                    }
                }
                none { doc }
            }
        }
        // FIXME: Warning when documenting a non-existent arg
    }

    fn merge_ret_attrs(
        doc: doc::retdoc,
        attrs: option<str>
    ) -> doc::retdoc {
        {
            desc: attrs
            with doc
        }
    }
}

#[test]
fn fold_fn_should_extract_fn_attributes() {
    let source = "#[doc = \"test\"] fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.desc == some("test");
}

#[test]
fn fold_fn_should_extract_arg_attributes() {
    let source = "#[doc(args(a = \"b\"))] fn c(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.args[0].desc == some("b");
}

#[test]
fn fold_fn_should_extract_return_attributes() {
    let source = "#[doc(return = \"what\")] fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = tystr_pass::mk_pass()(srv, doc);
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.return.desc == some("what");
}

#[test]
fn fold_fn_should_preserve_sig() {
    let source = "fn a() -> int { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = tystr_pass::mk_pass()(srv, doc);
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.sig == some("fn a() -> int");
}

#[test]
fn fold_fn_should_extract_failure_conditions() {
    let source = "#[doc(failure = \"what\")] fn a() { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_fn(fold, doc.topmod.fns()[0]);
    assert doc.failure == some("what");
}

fn fold_const(
    fold: fold::fold<astsrv::srv>,
    doc: doc::constdoc
) -> doc::constdoc {
    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_const);

    ~{
        brief: attrs.brief,
        desc: attrs.desc
        with *doc
    }
}

#[test]
fn fold_const_should_extract_docs() {
    let source = "#[doc(brief = \"foo\", desc = \"bar\")]\
                  const a: bool = true;";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_const(fold, doc.topmod.consts()[0]);
    assert doc.brief == some("foo");
    assert doc.desc == some("bar");
}

fn fold_enum(
    fold: fold::fold<astsrv::srv>,
    doc: doc::enumdoc
) -> doc::enumdoc {
    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_enum);

    ~{
        brief: attrs.brief,
        desc: attrs.desc,
        variants: vec::map(doc.variants) {|variant|
            let attrs = astsrv::exec(srv) {|ctxt|
                alt ctxt.ast_map.get(doc.id) {
                  ast_map::node_item(@{
                    node: ast::item_enum(ast_variants, _), _
                  }) {
                    let ast_variant = option::get(
                        vec::find(ast_variants) {|v|
                            v.node.name == variant.name
                        });

                    attr_parser::parse_variant(ast_variant.node.attrs)
                  }
                }
            };

            ~{
                desc: attrs.desc
                with *variant
            }
        }
        with *doc
    }
}

#[test]
fn fold_enum_should_extract_docs() {
    let source = "#[doc(brief = \"a\", desc = \"b\")]\
                  enum a { v }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_enum(fold, doc.topmod.enums()[0]);
    assert doc.brief == some("a");
    assert doc.desc == some("b");
}

#[test]
fn fold_enum_should_extract_variant_docs() {
    let source = "enum a { #[doc = \"c\"] v }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_enum(fold, doc.topmod.enums()[0]);
    assert doc.variants[0].desc == some("c");
}

fn fold_res(
    fold: fold::fold<astsrv::srv>,
    doc: doc::resdoc
) -> doc::resdoc {

    let srv = fold.ctxt;
    let attrs = parse_item_attrs(srv, doc.id, attr_parser::parse_fn);

    ~{
        brief: attrs.brief,
        desc: attrs.desc,
        args: vec::map(doc.args) {|doc|
            alt vec::find(attrs.args) {|attr|
                attr.name == doc.name
            } {
                some(attr) {
                    ~{
                        desc: some(attr.desc)
                        with *doc
                    }
                }
                none { doc }
            }
        }
        with *doc
    }
}

#[test]
fn fold_res_should_extract_docs() {
    let source = "#[doc(brief = \"a\", desc = \"b\")]\
                  resource r(b: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_res(fold, doc.topmod.resources()[0]);
    assert doc.brief == some("a");
    assert doc.desc == some("b");
}

#[test]
fn fold_res_should_extract_arg_docs() {
    let source = "#[doc(args(a = \"b\"))]\
                  resource r(a: bool) { }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let fold = fold::default_seq_fold(srv);
    let doc = fold_res(fold, doc.topmod.resources()[0]);
    assert doc.args[0].name == "a";
    assert doc.args[0].desc == some("b");
}<|endoftext|>


<commit_before><commit_msg>More dummy reg's<commit_after><|endoftext|>


<commit_before>use crossbeam;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::ffi::OsStr;
use liquid::Value;
use walkdir::WalkDir;
use document::Document;
use error::{Error, Result};
use config::Config;
use yaml_rust::YamlLoader;
use chrono::{DateTime, UTC, FixedOffset};
use chrono::offset::TimeZone;
use rss::{Channel, Rss};

macro_rules! walker {
    ($dir:expr) => {
        WalkDir::new($dir)
            .into_iter()
            .filter_map(|e| e.ok())
            .filter(|f| {
                // skip directories
                f.file_type().is_file()
                    &&
                    // don't copy hidden files
                    !f.path()
                    .file_name()
                    .and_then(|name| name.to_str())
                    .unwrap_or(".")
                    .starts_with(".")
            })
    }
}

/// The primary build function that tranforms a directory into a site
pub fn build(config: &Config) -> Result<()> {
    trace!("Build configuration: {:?}", config);

    // join("") makes sure path has a trailing slash
    let source = PathBuf::from(&config.source).join("");
    let source = source.as_path();
    let dest = PathBuf::from(&config.dest).join("");
    let dest = dest.as_path();

    let template_extensions: Vec<&OsStr> = config.template_extensions
                                                 .iter()
                                                 .map(OsStr::new)
                                                 .collect();

    let layouts_path = source.join(&config.layouts);
    let posts_path = source.join(&config.posts);

    debug!("Layouts directory: {:?}", layouts_path);
    debug!("Posts directory: {:?}", posts_path);

    let layouts = try!(get_layouts(&layouts_path));

    let mut documents = vec![];

    for entry in walker!(&source) {
        if template_extensions.contains(&entry.path()
                                              .extension()
                                              .unwrap_or(OsStr::new(""))) &&
           entry.path().parent() != Some(layouts_path.as_path()) {
            let mut doc = try!(parse_document(&entry.path(), &source));

            // if the document is in the posts folder it's considered a post
            if entry.path().parent() == Some(posts_path.as_path()) {
                doc.is_post = true;
            }

            documents.push(doc);
        }
    }

    // January 1, 1970 0:00:00 UTC, the beginning of time
    let default_date = UTC.timestamp(0, 0).with_timezone(&FixedOffset::east(0));

    // sort documents by date, if there's no date (none was provided or it couldn't be read) then
    // fall back to the default date
    documents.sort_by(|a, b| {
        b.date.unwrap_or(default_date.clone()).cmp(&a.date.unwrap_or(default_date.clone()))
    });

    // check if we should create an RSS file and create it!
    if let &Some(ref path) = &config.rss {
        try!(create_rss(path, dest, &config, &documents));
    }

    // these are the attributes of all documents that are posts, so that they can be
    // passed to the renderer
    let post_data: Vec<Value> = documents.iter()
                                         .filter(|x| x.is_post)
                                         .map(|x| Value::Object(x.get_attributes()))
                                         .collect();

    // thread handles to join later
    let mut handles = vec![];

    // generate documents (in parallel)
    // TODO I'm probably underutilizing crossbeam
    crossbeam::scope(|scope| {
        for doc in &documents {
            trace!("Generating {}", doc.path);
            let post_data = post_data.clone();
            let layouts = layouts.clone();
            let handle = scope.spawn(move || doc.create_file(&dest, &layouts, &post_data));
            handles.push(handle);
        }
    });

    for handle in handles {
        try!(handle.join());
    }

    // copy all remaining files in the source to the destination
    if source != dest {
        info!("Copying remaining assets");
        let source_str = try!(source.to_str()
                                    .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                                   source)));

        for entry in walker!(&source).filter(|f| {
            !template_extensions.contains(&f.path()
                                            .extension()
                                            .unwrap_or(OsStr::new(""))) &&
            f.path() != dest && f.path() != layouts_path.as_path()
        }) {
            let entry_path = try!(entry.path()
                                       .to_str()
                                       .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                                      entry.path())));

            let relative = try!(entry_path.split(source_str)
                                          .last()
                                          .ok_or(format!("Empty path")));

            if try!(entry.metadata()).is_dir() {
                try!(fs::create_dir_all(&dest.join(relative)));
                debug!("Created new directory {:?}", dest.join(relative));
            } else {
                if let Some(ref parent) = Path::new(relative).parent() {
                    try!(fs::create_dir_all(&dest.join(parent)));
                }

                try!(fs::copy(entry.path(), &dest.join(relative))
                         .map_err(|_| format!("Could not copy {:?}", entry.path())));
                debug!("Copied {:?} to {:?}", entry.path(), dest.join(relative));
            }
        }
    }

    Ok(())
}

/// Gets all layout files from the specified path (usually _layouts/)
/// This walks the specified directory recursively
///
/// Returns a map filename -> content
fn get_layouts(layouts_path: &Path) -> Result<HashMap<String, String>> {
    let mut layouts = HashMap::new();

    // go through the layout directory and add
    // filename -> text content to the layout map
    for entry in walker!(layouts_path) {
        let mut text = String::new();
        let mut file = try!(File::open(entry.path()));
        try!(file.read_to_string(&mut text));

        let path = try!(entry.path()
                             .file_name()
                             .and_then(|name| name.to_str())
                             .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                            entry.path().file_name())));

        layouts.insert(path.to_owned(), text);
    }

    Ok(layouts)
}

// creates a new RSS file with the contents of the site blog
fn create_rss(path: &str, dest: &Path, config: &Config, documents: &[Document]) -> Result<()> {
    match (&config.name, &config.description, &config.link) {
        // these three fields are mandatory in the RSS standard
        (&Some(ref name), &Some(ref description), &Some(ref link)) => {
            trace!("Generating RSS data");

            let items = documents.iter()
                                 .filter(|x| x.is_post)
                                 .map(|doc| doc.to_rss(link))
                                 .collect();

            let channel = Channel {
                title: name.to_owned(),
                link: link.to_owned(),
                description: description.to_owned(),
                items: items,
                ..Default::default()
            };

            let rss = Rss(channel);
            let rss_string = rss.to_string();
            trace!("RSS data: {}", rss_string);

            let rss_path = dest.join(path);

            let mut rss_file = try!(File::create(&rss_path));
            try!(rss_file.write_all(&rss_string.into_bytes()));

            info!("Created RSS file at {}", rss_path.display());
            Ok(())
        }
        _ => {
            Err(Error::from("name, description and link need to be defined in the config file to \
                             generate RSS"))
        }
    }
}

fn parse_document(path: &Path, source: &Path) -> Result<Document> {
    let mut attributes = HashMap::new();
    let mut content = try!(parse_file(path));

    // if there is front matter, split the file and parse it
    if content.contains("---") {
        let content2 = content.clone();
        let mut content_splits = content2.split("---");

        // above the split are the attributes
        let attribute_string = content_splits.next().unwrap_or("");

        // everything below the split becomes the new content
        content = content_splits.next().unwrap_or("").to_owned();

        let yaml_result = try!(YamlLoader::load_from_str(attribute_string));

        let yaml_attributes = try!(yaml_result[0]
                                       .as_hash()
                                       .ok_or(format!("Incorrect front matter format in {:?}",
                                                      path)));

        for (key, value) in yaml_attributes {
            // TODO is unwrap_or the best way to handle this?
            attributes.insert(key.as_str().unwrap_or("").to_owned(),
                              value.as_str().unwrap_or("").to_owned());
        }
    }

    let date = attributes.get("date")
                         .and_then(|d| DateTime::parse_from_str(d, "%d %B %Y %H:%M:%S %z").ok());

    let path_str = try!(path.to_str()
                            .ok_or(format!("Cannot convert pathname {:?} to UTF-8", path)));

    let source_str = try!(source.to_str()
                                .ok_or(format!("Cannot convert pathname {:?} to UTF-8", source)));

    let new_path = try!(path_str.split(source_str)
                                .last()
                                .ok_or(format!("Empty path")));

    // construct path
    let mut path_buf = PathBuf::from(new_path);
    path_buf.set_extension("html");

    let path_str = try!(path_buf.to_str()
                                .ok_or(format!("Cannot convert pathname {:?} to UTF-8", path_str)));

    let markdown = path.extension().unwrap_or(OsStr::new("")) == OsStr::new("md");

    let name = try!(path.file_stem()
                        .and_then(|stem| stem.to_str())
                        .ok_or(format!("Invalid UTF-8 in file stem for {:?}", path)));

    Ok(Document::new(name.to_owned(),
                     path_str.to_owned(),
                     attributes,
                     content,
                     false,
                     date,
                     markdown))
}

fn parse_file(path: &Path) -> Result<String> {
    let mut file = try!(File::open(path));
    let mut text = String::new();
    try!(file.read_to_string(&mut text));
    Ok(text)
}
<commit_msg>Wrap shared Vecs in Arc during document creation<commit_after>use crossbeam;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::collections::HashMap;
use std::ffi::OsStr;
use liquid::Value;
use walkdir::WalkDir;
use document::Document;
use error::{Error, Result};
use config::Config;
use yaml_rust::YamlLoader;
use chrono::{DateTime, UTC, FixedOffset};
use chrono::offset::TimeZone;
use rss::{Channel, Rss};
use std::sync::Arc;

macro_rules! walker {
    ($dir:expr) => {
        WalkDir::new($dir)
            .into_iter()
            .filter_map(|e| e.ok())
            .filter(|f| {
                // skip directories
                f.file_type().is_file()
                    &&
                    // don't copy hidden files
                    !f.path()
                    .file_name()
                    .and_then(|name| name.to_str())
                    .unwrap_or(".")
                    .starts_with(".")
            })
    }
}

/// The primary build function that tranforms a directory into a site
pub fn build(config: &Config) -> Result<()> {
    trace!("Build configuration: {:?}", config);

    // join("") makes sure path has a trailing slash
    let source = PathBuf::from(&config.source).join("");
    let source = source.as_path();
    let dest = PathBuf::from(&config.dest).join("");
    let dest = dest.as_path();

    let template_extensions: Vec<&OsStr> = config.template_extensions
                                                 .iter()
                                                 .map(OsStr::new)
                                                 .collect();

    let layouts_path = source.join(&config.layouts);
    let posts_path = source.join(&config.posts);

    debug!("Layouts directory: {:?}", layouts_path);
    debug!("Posts directory: {:?}", posts_path);

    let layouts = try!(get_layouts(&layouts_path));

    let mut documents = vec![];

    for entry in walker!(&source) {
        if template_extensions.contains(&entry.path()
                                              .extension()
                                              .unwrap_or(OsStr::new(""))) &&
           entry.path().parent() != Some(layouts_path.as_path()) {
            let mut doc = try!(parse_document(&entry.path(), &source));

            // if the document is in the posts folder it's considered a post
            if entry.path().parent() == Some(posts_path.as_path()) {
                doc.is_post = true;
            }

            documents.push(doc);
        }
    }

    // January 1, 1970 0:00:00 UTC, the beginning of time
    let default_date = UTC.timestamp(0, 0).with_timezone(&FixedOffset::east(0));

    // sort documents by date, if there's no date (none was provided or it couldn't be read) then
    // fall back to the default date
    documents.sort_by(|a, b| {
        b.date.unwrap_or(default_date.clone()).cmp(&a.date.unwrap_or(default_date.clone()))
    });

    // check if we should create an RSS file and create it!
    if let &Some(ref path) = &config.rss {
        try!(create_rss(path, dest, &config, &documents));
    }

    // these are the attributes of all documents that are posts, so that they can be
    // passed to the renderer
    let post_data: Vec<Value> = documents.iter()
                                         .filter(|x| x.is_post)
                                         .map(|x| Value::Object(x.get_attributes()))
                                         .collect();

    // thread handles to join later
    let mut handles = vec![];

    // generate documents (in parallel)
    crossbeam::scope(|scope| {
        let post_data = Arc::new(post_data);
        let layouts = Arc::new(layouts);

        for doc in &documents {
            trace!("Generating {}", doc.path);
            let post_data = post_data.clone();
            let layouts = layouts.clone();
            let handle = scope.spawn(move || doc.create_file(&dest, &layouts, &post_data));
            handles.push(handle);
        }
    });

    for handle in handles {
        try!(handle.join());
    }

    // copy all remaining files in the source to the destination
    if source != dest {
        info!("Copying remaining assets");
        let source_str = try!(source.to_str()
                                    .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                                   source)));

        for entry in walker!(&source).filter(|f| {
            !template_extensions.contains(&f.path()
                                            .extension()
                                            .unwrap_or(OsStr::new(""))) &&
            f.path() != dest && f.path() != layouts_path.as_path()
        }) {
            let entry_path = try!(entry.path()
                                       .to_str()
                                       .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                                      entry.path())));

            let relative = try!(entry_path.split(source_str)
                                          .last()
                                          .ok_or(format!("Empty path")));

            if try!(entry.metadata()).is_dir() {
                try!(fs::create_dir_all(&dest.join(relative)));
                debug!("Created new directory {:?}", dest.join(relative));
            } else {
                if let Some(ref parent) = Path::new(relative).parent() {
                    try!(fs::create_dir_all(&dest.join(parent)));
                }

                try!(fs::copy(entry.path(), &dest.join(relative))
                         .map_err(|_| format!("Could not copy {:?}", entry.path())));
                debug!("Copied {:?} to {:?}", entry.path(), dest.join(relative));
            }
        }
    }

    Ok(())
}

/// Gets all layout files from the specified path (usually _layouts/)
/// This walks the specified directory recursively
///
/// Returns a map filename -> content
fn get_layouts(layouts_path: &Path) -> Result<HashMap<String, String>> {
    let mut layouts = HashMap::new();

    // go through the layout directory and add
    // filename -> text content to the layout map
    for entry in walker!(layouts_path) {
        let mut text = String::new();
        let mut file = try!(File::open(entry.path()));
        try!(file.read_to_string(&mut text));

        let path = try!(entry.path()
                             .file_name()
                             .and_then(|name| name.to_str())
                             .ok_or(format!("Cannot convert pathname {:?} to UTF-8",
                                            entry.path().file_name())));

        layouts.insert(path.to_owned(), text);
    }

    Ok(layouts)
}

// creates a new RSS file with the contents of the site blog
fn create_rss(path: &str, dest: &Path, config: &Config, documents: &[Document]) -> Result<()> {
    match (&config.name, &config.description, &config.link) {
        // these three fields are mandatory in the RSS standard
        (&Some(ref name), &Some(ref description), &Some(ref link)) => {
            trace!("Generating RSS data");

            let items = documents.iter()
                                 .filter(|x| x.is_post)
                                 .map(|doc| doc.to_rss(link))
                                 .collect();

            let channel = Channel {
                title: name.to_owned(),
                link: link.to_owned(),
                description: description.to_owned(),
                items: items,
                ..Default::default()
            };

            let rss = Rss(channel);
            let rss_string = rss.to_string();
            trace!("RSS data: {}", rss_string);

            let rss_path = dest.join(path);

            let mut rss_file = try!(File::create(&rss_path));
            try!(rss_file.write_all(&rss_string.into_bytes()));

            info!("Created RSS file at {}", rss_path.display());
            Ok(())
        }
        _ => {
            Err(Error::from("name, description and link need to be defined in the config file to \
                             generate RSS"))
        }
    }
}

fn parse_document(path: &Path, source: &Path) -> Result<Document> {
    let mut attributes = HashMap::new();
    let mut content = try!(parse_file(path));

    // if there is front matter, split the file and parse it
    if content.contains("---") {
        let content2 = content.clone();
        let mut content_splits = content2.split("---");

        // above the split are the attributes
        let attribute_string = content_splits.next().unwrap_or("");

        // everything below the split becomes the new content
        content = content_splits.next().unwrap_or("").to_owned();

        let yaml_result = try!(YamlLoader::load_from_str(attribute_string));

        let yaml_attributes = try!(yaml_result[0]
                                       .as_hash()
                                       .ok_or(format!("Incorrect front matter format in {:?}",
                                                      path)));

        for (key, value) in yaml_attributes {
            // TODO is unwrap_or the best way to handle this?
            attributes.insert(key.as_str().unwrap_or("").to_owned(),
                              value.as_str().unwrap_or("").to_owned());
        }
    }

    let date = attributes.get("date")
                         .and_then(|d| DateTime::parse_from_str(d, "%d %B %Y %H:%M:%S %z").ok());

    let path_str = try!(path.to_str()
                            .ok_or(format!("Cannot convert pathname {:?} to UTF-8", path)));

    let source_str = try!(source.to_str()
                                .ok_or(format!("Cannot convert pathname {:?} to UTF-8", source)));

    let new_path = try!(path_str.split(source_str)
                                .last()
                                .ok_or(format!("Empty path")));

    // construct path
    let mut path_buf = PathBuf::from(new_path);
    path_buf.set_extension("html");

    let path_str = try!(path_buf.to_str()
                                .ok_or(format!("Cannot convert pathname {:?} to UTF-8", path_str)));

    let markdown = path.extension().unwrap_or(OsStr::new("")) == OsStr::new("md");

    let name = try!(path.file_stem()
                        .and_then(|stem| stem.to_str())
                        .ok_or(format!("Invalid UTF-8 in file stem for {:?}", path)));

    Ok(Document::new(name.to_owned(),
                     path_str.to_owned(),
                     attributes,
                     content,
                     false,
                     date,
                     markdown))
}

fn parse_file(path: &Path) -> Result<String> {
    let mut file = try!(File::open(path));
    let mut text = String::new();
    try!(file.read_to_string(&mut text));
    Ok(text)
}
<|endoftext|>


<commit_before><commit_msg>Rename  to<commit_after><|endoftext|>


<commit_before><commit_msg>Adding thread communicator<commit_after>#![feature(alloc)]
#![feature(heap_api)]

extern crate alloc;
use std::thread;
use std::ptr::{self};
use std::mem;
use self::alloc::heap;
use std::sync::{Arc,Barrier};
use std::sync::atomic::{AtomicPtr,AtomicUsize,Ordering};

extern crate crossbeam;
use self::crossbeam::{Scope};

struct ThreadComm<T> {
    n_threads: usize,

    //Slot has a MatrixBuffer, to be broadcast
    slot: AtomicPtr<T>,

    //Slot_reads represents the number of times slot has been read.
    //If slot_reads == n_threads, then it is ready to be written to.
    //If slot_reads < n_threads, it is ready to be read.
    //Each thread is only allowed to read from the slot one time.
    //It is incremented every time slot is read,
    //And it is an integer modulo n_threads
    slot_reads: AtomicUsize,

    barrier: Barrier,

    //I guess subcomms needs to have interor mutability?
    sub_comms: Vec<AtomicPtr<Arc<ThreadComm<T>>>>,
}
impl<T> ThreadComm<T> {
    fn new( n_threads: usize ) -> ThreadComm<T> {
        let init_ptr: *const T = ptr::null();
        let mut sub_comms = Vec::with_capacity(n_threads);
        for i in 0..n_threads {
            let ptr: *const Arc<ThreadComm<T>> = ptr::null();
            sub_comms.push( AtomicPtr::new(ptr as *mut Arc<ThreadComm<T>>) );
        }
        ThreadComm{ n_threads: n_threads,
            slot: AtomicPtr::new( init_ptr as *mut T),
            slot_reads: AtomicUsize::new(n_threads),
            barrier: Barrier::new(n_threads),
            sub_comms: sub_comms,
        }
    }

    fn barrier( &self, _info: &ThreadInfo<T> ) {
        self.barrier.wait();
    }

    fn broadcast( &self, info: &ThreadInfo<T>, to_send: *mut T ) -> *mut T {
        if info.thread_id == 0 {
            //Spin while waiting for the thread communicator to be ready to broadcast
            while self.slot_reads.load( Ordering::Relaxed ) != self.n_threads {}
            self.slot.store( to_send, Ordering::Relaxed );
            self.slot_reads.store( 0, Ordering::Relaxed );
        }
        //Spin while waiting for the thread communicator chief to broadcast
        while self.slot_reads.load( Ordering::Relaxed ) == self.n_threads {}
        self.slot_reads.fetch_add( 1, Ordering::Relaxed );
        self.slot.load( Ordering::Relaxed )
    }
    //Pretty sure with this implementation, split can only be called one time.
    fn split( &self, info: &ThreadInfo<T>, n_way: usize ) -> Arc<ThreadComm<T>> {
        assert!( self.n_threads % n_way == 0 );
        let sub_comm_number = info.thread_id / n_way; // Which subcomm are we going to use?
        let sub_comm_id = info.thread_id % n_way; // What is our id within the subcomm?

        if sub_comm_id == 0 {
            if !self.sub_comms[ sub_comm_number ].load( Ordering::Relaxed ).is_null() {
                self.sub_comms[ sub_comm_number ].store(
                    &mut Arc::new(ThreadComm::new( self.n_threads )) as *mut Arc<ThreadComm<T>>,
                    Ordering::Relaxed );
            }
        }
        while self.sub_comms[ sub_comm_number ].load( Ordering::Relaxed ).is_null() {}
        unsafe{
            let blah = self.sub_comms[sub_comm_number].load( Ordering::Relaxed );
            (*blah).clone()
        }
    }
}
//unsafe impl Sync for ThreadComm {}
//unsafe impl Send for ThreadComm {}

struct ThreadInfo<T> {
    thread_id: usize,
    comm: Arc<ThreadComm<T>>,
}
impl<T> ThreadInfo<T> {
    fn barrier( &self ) {
        self.comm.barrier(&self);
    }
    fn broadcast( &self, to_send: *mut T ) -> *mut T {
        self.comm.broadcast(&self, to_send)
    }
}

struct MatrixBuffer {
    buf: *mut f64,
    len: usize,
}

impl MatrixBuffer {
    fn new( len: usize ) -> MatrixBuffer {
        unsafe {
            let buf = heap::allocate( len * mem::size_of::<f64>(), 4096 ) as *mut f64;
            MatrixBuffer{ buf: buf, len: len }
        }
    }
    fn set( &mut self, id: usize, val: f64  ) {
        unsafe{
            ptr::write( self.buf.offset(id as isize), val );
        }
    }
    fn get( &self, id: usize ) -> f64 {
        unsafe{
            ptr::read( self.buf.offset(id as isize) )
        }
    }
    fn from( &mut self, other: MatrixBuffer ) {
        self.buf = other.buf;
        self.len = other.len;
    }
    fn get_alias( &self ) -> MatrixBuffer {
        MatrixBuffer{ buf: self.buf, len: self.len }
    }
}
unsafe impl Sync for MatrixBuffer {}
unsafe impl Send for MatrixBuffer {}

pub fn blah() {
    let mut mat = MatrixBuffer::new(2);
    mat.set(0, 0.0);
    mat.set(1, 0.0);

    let globalComm = Arc::new(ThreadComm::new( 2 ));

    crossbeam::scope(|scope| {
        for id in 0..2 {
            let mut my_alias = mat.get_alias();
            let mut my_comm  = globalComm.clone();
            scope.spawn(move || {
                //let mut my_alias = ref mat.get_alias();
                let info = ThreadInfo{thread_id: id, comm: my_comm};

                let mat_inside = MatrixBuffer::new(2);

                println!("tid {} broadcasting!", info.thread_id);
                let mut curr_matrix = MatrixBuffer::new(0);
                let ptr = info.broadcast( mat_inside.buf );
                curr_matrix.buf = ptr;
                curr_matrix.set(info.thread_id, 4.0 );

                println!("tid {} barriering!", info.thread_id);
                info.barrier();
                println!("tid {} setting!", info.thread_id );
                if info.thread_id == 0 {
                    print!("{} ", curr_matrix.get( 0 ) );
                    print!("{} ", curr_matrix.get( 1 ) );
                }

                my_alias.set( info.thread_id, 5.0 );
                println!("tid {} done!", info.thread_id );
            });
        }
    });

    for id in 0..2 {
        print!("{} ", mat.get( id ) );
    }
    println!("");
}
<|endoftext|>


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

//! Panic support in the standard library

#![unstable(feature = "std_panic", reason = "awaiting feedback",
            issue = "27719")]

use any::Any;
use boxed::Box;
use cell::UnsafeCell;
use ops::{Deref, DerefMut};
use ptr::{Unique, Shared};
use rc::Rc;
use sync::{Arc, Mutex, RwLock};
use sys_common::unwind;
use thread::Result;

pub use panicking::{take_handler, set_handler, PanicInfo, Location};

/// A marker trait which represents "panic safe" types in Rust.
///
/// This trait is implemented by default for many types and behaves similarly in
/// terms of inference of implementation to the `Send` and `Sync` traits. The
/// purpose of this trait is to encode what types are safe to cross a `recover`
/// boundary with no fear of panic safety.
///
/// ## What is panic safety?
///
/// In Rust a function can "return" early if it either panics or calls a
/// function which transitively panics. This sort of control flow is not always
/// anticipated, and has the possibility of causing subtle bugs through a
/// combination of two cricial components:
///
/// 1. A data structure is in a temporarily invalid state when the thread
///    panics.
/// 2. This broken invariant is then later observed.
///
/// Typically in Rust, it is difficult to perform step (2) because catching a
/// panic involves either spawning a thread (which in turns makes it difficult
/// to later witness broken invariants) or using the `recover` function in this
/// module. Additionally, even if an invariant is witnessed, it typically isn't a
/// problem in Rust because there's no uninitialized values (like in C or C++).
///
/// It is possible, however, for **logical** invariants to be broken in Rust,
/// which can end up causing behavioral bugs. Another key aspect of panic safety
/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
/// memory unsafety.
///
/// That was a bit of a whirlwind tour of panic safety, but for more information
/// about panic safety and how it applies to Rust, see an [associated RFC][rfc].
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// ## What is `RecoverSafe`?
///
/// Now that we've got an idea of what panic safety is in Rust, it's also
/// important to understand what this trait represents. As mentioned above, one
/// way to witness broken invariants is through the `recover` function in this
/// module as it allows catching a panic and then re-using the environment of
/// the closure.
///
/// Simply put, a type `T` implements `RecoverSafe` if it cannot easily allow
/// witnessing a broken invariant through the use of `recover` (catching a
/// panic). This trait is a marker trait, so it is automatically implemented for
/// many types, and it is also structurally composed (e.g. a struct is recover
/// safe if all of its components are recover safe).
///
/// Note, however, that this is not an unsafe trait, so there is not a succinct
/// contract that this trait is providing. Instead it is intended as more of a
/// "speed bump" to alert users of `recover` that broken invariants may be
/// witnessed and may need to be accounted for.
///
/// ## Who implements `RecoverSafe`?
///
/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
/// recover safe. The general idea is that any mutable state which can be shared
/// across `recover` is not recover safe by default. This is because it is very
/// easy to witness a broken invariant outside of `recover` as the data is
/// simply accesed as usual.
///
/// Types like `&Mutex<T>`, however, are recover safe because they implement
/// poisoning by default. They still allow witnessing a broken invariant, but
/// they already provide their own "speed bumps" to do so.
///
/// ## When should `RecoverSafe` be used?
///
/// Is not intended that most types or functions need to worry about this trait.
/// It is only used as a bound on the `recover` function and as mentioned above,
/// the lack of `unsafe` means it is mostly an advisory. The `AssertRecoverSafe`
/// wrapper struct in this module can be used to force this trait to be
/// implemented for any closed over variables passed to the `recover` function
/// (more on this below).
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
                            across a recover boundary"]
pub trait RecoverSafe {}

/// A marker trait representing types where a shared reference is considered
/// recover safe.
///
/// This trait is namely not implemented by `UnsafeCell`, the root of all
/// interior mutability.
///
/// This is a "helper marker trait" used to provide impl blocks for the
/// `RecoverSafe` trait, for more information see that documentation.
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                            and a reference may not be safely transferrable \
                            across a recover boundary"]
pub trait RefRecoverSafe {}

/// A simple wrapper around a type to assert that it is panic safe.
///
/// When using `recover` it may be the case that some of the closed over
/// variables are not panic safe. For example if `&mut T` is captured the
/// compiler will generate a warning indicating that it is not panic safe. It
/// may not be the case, however, that this is actually a problem due to the
/// specific usage of `recover` if panic safety is specifically taken into
/// account. This wrapper struct is useful for a quick and lightweight
/// annotation that a variable is indeed panic safe.
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic::{self, AssertRecoverSafe};
///
/// let mut variable = 4;
///
/// // This code will not compile becuause the closure captures `&mut variable`
/// // which is not considered panic safe by default.
///
/// // panic::recover(|| {
/// //     variable += 3;
/// // });
///
/// // This, however, will compile due to the `AssertRecoverSafe` wrapper
/// let result = {
///     let mut wrapper = AssertRecoverSafe::new(&mut variable);
///     panic::recover(move || {
///         **wrapper += 3;
///     })
/// };
/// // ...
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
pub struct AssertRecoverSafe<T>(T);

// Implementations of the `RecoverSafe` trait:
//
// * By default everything is recover safe
// * pointers T contains mutability of some form are not recover safe
// * Unique, an owning pointer, lifts an implementation
// * Types like Mutex/RwLock which are explicilty poisoned are recover safe
// * Our custom AssertRecoverSafe wrapper is indeed recover safe
impl RecoverSafe for .. {}
impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {}
impl<T: RecoverSafe> RecoverSafe for Unique<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {}
impl<T: ?Sized> RecoverSafe for Mutex<T> {}
impl<T: ?Sized> RecoverSafe for RwLock<T> {}
impl<T> RecoverSafe for AssertRecoverSafe<T> {}

// not covered via the Shared impl above b/c the inner contents use
// Cell/AtomicUsize, but the usage here is recover safe so we can lift the
// impl up one level to Arc/Rc itself
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}

// Pretty simple implementations for the `RefRecoverSafe` marker trait,
// basically just saying that this is a marker trait and `UnsafeCell` is the
// only thing which doesn't implement it (which then transitively applies to
// everything else).
impl RefRecoverSafe for .. {}
impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}

impl<T> AssertRecoverSafe<T> {
    /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
    #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
    pub fn new(t: T) -> AssertRecoverSafe<T> {
        AssertRecoverSafe(t)
    }
}

impl<T> Deref for AssertRecoverSafe<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> DerefMut for AssertRecoverSafe<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

/// Invokes a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok` with the closure's result if the closure
/// does not panic, and will return `Err(cause)` if the closure panics. The
/// `cause` returned is the object with which panic was originally invoked.
///
/// It is currently undefined behavior to unwind from Rust code into foreign
/// code, so this function is particularly useful when Rust is called from
/// another language (normally C). This can run arbitrary Rust code, capturing a
/// panic and allowing a graceful handling of the error.
///
/// It is **not** recommended to use this function for a general try/catch
/// mechanism. The `Result` type is more appropriate to use for functions that
/// can fail on a regular basis.
///
/// The closure provided is required to adhere to the `RecoverSafe` to ensure
/// that all captured variables are safe to cross this recover boundary. The
/// purpose of this bound is to encode the concept of [exception safety][rfc] in
/// the type system. Most usage of this function should not need to worry about
/// this bound as programs are naturally panic safe without `unsafe` code. If it
/// becomes a problem the associated `AssertRecoverSafe` wrapper type in this
/// module can be used to quickly assert that the usage here is indeed exception
/// safe.
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
///     println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = panic::recover(|| {
///     panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
    let mut result = None;
    unsafe {
        let result = &mut result;
        try!(unwind::try(move || *result = Some(f())))
    }
    Ok(result.unwrap())
}

/// Triggers a panic without invoking the panic handler.
///
/// This is designed to be used in conjunction with `recover` to, for example,
/// carry a panic across a layer of C code.
///
/// # Examples
///
/// ```should_panic
/// #![feature(std_panic, recover, panic_propagate)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
///     panic!("oh no!");
/// });
///
/// if let Err(err) = result {
///     panic::propagate(err);
/// }
/// ```
#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
pub fn propagate(payload: Box<Any + Send>) -> ! {
    unwind::rust_panic(payload)
}
<commit_msg>Fix typo<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.

//! Panic support in the standard library

#![unstable(feature = "std_panic", reason = "awaiting feedback",
            issue = "27719")]

use any::Any;
use boxed::Box;
use cell::UnsafeCell;
use ops::{Deref, DerefMut};
use ptr::{Unique, Shared};
use rc::Rc;
use sync::{Arc, Mutex, RwLock};
use sys_common::unwind;
use thread::Result;

pub use panicking::{take_handler, set_handler, PanicInfo, Location};

/// A marker trait which represents "panic safe" types in Rust.
///
/// This trait is implemented by default for many types and behaves similarly in
/// terms of inference of implementation to the `Send` and `Sync` traits. The
/// purpose of this trait is to encode what types are safe to cross a `recover`
/// boundary with no fear of panic safety.
///
/// ## What is panic safety?
///
/// In Rust a function can "return" early if it either panics or calls a
/// function which transitively panics. This sort of control flow is not always
/// anticipated, and has the possibility of causing subtle bugs through a
/// combination of two cricial components:
///
/// 1. A data structure is in a temporarily invalid state when the thread
///    panics.
/// 2. This broken invariant is then later observed.
///
/// Typically in Rust, it is difficult to perform step (2) because catching a
/// panic involves either spawning a thread (which in turns makes it difficult
/// to later witness broken invariants) or using the `recover` function in this
/// module. Additionally, even if an invariant is witnessed, it typically isn't a
/// problem in Rust because there's no uninitialized values (like in C or C++).
///
/// It is possible, however, for **logical** invariants to be broken in Rust,
/// which can end up causing behavioral bugs. Another key aspect of panic safety
/// in Rust is that, in the absence of `unsafe` code, a panic cannot lead to
/// memory unsafety.
///
/// That was a bit of a whirlwind tour of panic safety, but for more information
/// about panic safety and how it applies to Rust, see an [associated RFC][rfc].
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// ## What is `RecoverSafe`?
///
/// Now that we've got an idea of what panic safety is in Rust, it's also
/// important to understand what this trait represents. As mentioned above, one
/// way to witness broken invariants is through the `recover` function in this
/// module as it allows catching a panic and then re-using the environment of
/// the closure.
///
/// Simply put, a type `T` implements `RecoverSafe` if it cannot easily allow
/// witnessing a broken invariant through the use of `recover` (catching a
/// panic). This trait is a marker trait, so it is automatically implemented for
/// many types, and it is also structurally composed (e.g. a struct is recover
/// safe if all of its components are recover safe).
///
/// Note, however, that this is not an unsafe trait, so there is not a succinct
/// contract that this trait is providing. Instead it is intended as more of a
/// "speed bump" to alert users of `recover` that broken invariants may be
/// witnessed and may need to be accounted for.
///
/// ## Who implements `RecoverSafe`?
///
/// Types such as `&mut T` and `&RefCell<T>` are examples which are **not**
/// recover safe. The general idea is that any mutable state which can be shared
/// across `recover` is not recover safe by default. This is because it is very
/// easy to witness a broken invariant outside of `recover` as the data is
/// simply accesed as usual.
///
/// Types like `&Mutex<T>`, however, are recover safe because they implement
/// poisoning by default. They still allow witnessing a broken invariant, but
/// they already provide their own "speed bumps" to do so.
///
/// ## When should `RecoverSafe` be used?
///
/// Is not intended that most types or functions need to worry about this trait.
/// It is only used as a bound on the `recover` function and as mentioned above,
/// the lack of `unsafe` means it is mostly an advisory. The `AssertRecoverSafe`
/// wrapper struct in this module can be used to force this trait to be
/// implemented for any closed over variables passed to the `recover` function
/// (more on this below).
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_on_unimplemented = "the type {Self} may not be safely transferred \
                            across a recover boundary"]
pub trait RecoverSafe {}

/// A marker trait representing types where a shared reference is considered
/// recover safe.
///
/// This trait is namely not implemented by `UnsafeCell`, the root of all
/// interior mutability.
///
/// This is a "helper marker trait" used to provide impl blocks for the
/// `RecoverSafe` trait, for more information see that documentation.
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
#[rustc_on_unimplemented = "the type {Self} contains interior mutability \
                            and a reference may not be safely transferrable \
                            across a recover boundary"]
pub trait RefRecoverSafe {}

/// A simple wrapper around a type to assert that it is panic safe.
///
/// When using `recover` it may be the case that some of the closed over
/// variables are not panic safe. For example if `&mut T` is captured the
/// compiler will generate a warning indicating that it is not panic safe. It
/// may not be the case, however, that this is actually a problem due to the
/// specific usage of `recover` if panic safety is specifically taken into
/// account. This wrapper struct is useful for a quick and lightweight
/// annotation that a variable is indeed panic safe.
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic::{self, AssertRecoverSafe};
///
/// let mut variable = 4;
///
/// // This code will not compile because the closure captures `&mut variable`
/// // which is not considered panic safe by default.
///
/// // panic::recover(|| {
/// //     variable += 3;
/// // });
///
/// // This, however, will compile due to the `AssertRecoverSafe` wrapper
/// let result = {
///     let mut wrapper = AssertRecoverSafe::new(&mut variable);
///     panic::recover(move || {
///         **wrapper += 3;
///     })
/// };
/// // ...
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
pub struct AssertRecoverSafe<T>(T);

// Implementations of the `RecoverSafe` trait:
//
// * By default everything is recover safe
// * pointers T contains mutability of some form are not recover safe
// * Unique, an owning pointer, lifts an implementation
// * Types like Mutex/RwLock which are explicilty poisoned are recover safe
// * Our custom AssertRecoverSafe wrapper is indeed recover safe
impl RecoverSafe for .. {}
impl<'a, T: ?Sized> !RecoverSafe for &'a mut T {}
impl<'a, T: RefRecoverSafe + ?Sized> RecoverSafe for &'a T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *const T {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for *mut T {}
impl<T: RecoverSafe> RecoverSafe for Unique<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Shared<T> {}
impl<T: ?Sized> RecoverSafe for Mutex<T> {}
impl<T: ?Sized> RecoverSafe for RwLock<T> {}
impl<T> RecoverSafe for AssertRecoverSafe<T> {}

// not covered via the Shared impl above b/c the inner contents use
// Cell/AtomicUsize, but the usage here is recover safe so we can lift the
// impl up one level to Arc/Rc itself
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Rc<T> {}
impl<T: RefRecoverSafe + ?Sized> RecoverSafe for Arc<T> {}

// Pretty simple implementations for the `RefRecoverSafe` marker trait,
// basically just saying that this is a marker trait and `UnsafeCell` is the
// only thing which doesn't implement it (which then transitively applies to
// everything else).
impl RefRecoverSafe for .. {}
impl<T: ?Sized> !RefRecoverSafe for UnsafeCell<T> {}
impl<T> RefRecoverSafe for AssertRecoverSafe<T> {}

impl<T> AssertRecoverSafe<T> {
    /// Creates a new `AssertRecoverSafe` wrapper around the provided type.
    #[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
    pub fn new(t: T) -> AssertRecoverSafe<T> {
        AssertRecoverSafe(t)
    }
}

impl<T> Deref for AssertRecoverSafe<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T> DerefMut for AssertRecoverSafe<T> {
    fn deref_mut(&mut self) -> &mut T {
        &mut self.0
    }
}

/// Invokes a closure, capturing the cause of panic if one occurs.
///
/// This function will return `Ok` with the closure's result if the closure
/// does not panic, and will return `Err(cause)` if the closure panics. The
/// `cause` returned is the object with which panic was originally invoked.
///
/// It is currently undefined behavior to unwind from Rust code into foreign
/// code, so this function is particularly useful when Rust is called from
/// another language (normally C). This can run arbitrary Rust code, capturing a
/// panic and allowing a graceful handling of the error.
///
/// It is **not** recommended to use this function for a general try/catch
/// mechanism. The `Result` type is more appropriate to use for functions that
/// can fail on a regular basis.
///
/// The closure provided is required to adhere to the `RecoverSafe` to ensure
/// that all captured variables are safe to cross this recover boundary. The
/// purpose of this bound is to encode the concept of [exception safety][rfc] in
/// the type system. Most usage of this function should not need to worry about
/// this bound as programs are naturally panic safe without `unsafe` code. If it
/// becomes a problem the associated `AssertRecoverSafe` wrapper type in this
/// module can be used to quickly assert that the usage here is indeed exception
/// safe.
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// # Examples
///
/// ```
/// #![feature(recover, std_panic)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
///     println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = panic::recover(|| {
///     panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
#[unstable(feature = "recover", reason = "awaiting feedback", issue = "27719")]
pub fn recover<F: FnOnce() -> R + RecoverSafe, R>(f: F) -> Result<R> {
    let mut result = None;
    unsafe {
        let result = &mut result;
        try!(unwind::try(move || *result = Some(f())))
    }
    Ok(result.unwrap())
}

/// Triggers a panic without invoking the panic handler.
///
/// This is designed to be used in conjunction with `recover` to, for example,
/// carry a panic across a layer of C code.
///
/// # Examples
///
/// ```should_panic
/// #![feature(std_panic, recover, panic_propagate)]
///
/// use std::panic;
///
/// let result = panic::recover(|| {
///     panic!("oh no!");
/// });
///
/// if let Err(err) = result {
///     panic::propagate(err);
/// }
/// ```
#[unstable(feature = "panic_propagate", reason = "awaiting feedback", issue = "30752")]
pub fn propagate(payload: Box<Any + Send>) -> ! {
    unwind::rust_panic(payload)
}
<|endoftext|>


<commit_before><commit_msg>Update new code in master to use Point type alias<commit_after><|endoftext|>


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

// ignore-android: FIXME(#9116) Bus error

use std::mem;

#[repr(packed)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct Foo {
    bar: u8,
    baz: u64
}

pub fn main() {
    let foos = [Foo { bar: 1, baz: 2 }; 10];

    assert_eq!(mem::size_of::<[Foo; 10]>(), 90);

    for i in 0..10 {
        assert_eq!(foos[i], Foo { bar: 1, baz: 2});
    }

    for &foo in &foos {
        assert_eq!(foo, Foo { bar: 1, baz: 2 });
    }
}
<commit_msg>Re-enable test on Android<commit_after>// Copyright 2013-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 std::mem;

#[repr(packed)]
#[derive(Copy, Clone, PartialEq, Debug)]
struct Foo {
    bar: u8,
    baz: u64
}

pub fn main() {
    let foos = [Foo { bar: 1, baz: 2 }; 10];

    assert_eq!(mem::size_of::<[Foo; 10]>(), 90);

    for i in 0..10 {
        assert_eq!(foos[i], Foo { bar: 1, baz: 2});
    }

    for &foo in &foos {
        assert_eq!(foo, Foo { bar: 1, baz: 2 });
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix incorrect names on some Orruk Megaboss integration test cases<commit_after><|endoftext|>


<commit_before><commit_msg>Chunkier menu buttons<commit_after><|endoftext|>


<commit_before><commit_msg>Add test with cargo configuration file<commit_after><|endoftext|>


<commit_before><commit_msg>clean room<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for issue-66205<commit_after>// check-pass

#![allow(incomplete_features, dead_code, unconditional_recursion)]
#![feature(const_generics)]

fn fact<const N: usize>() {
    fact::<{ N - 1 }>();
}

fn main() {}
<|endoftext|>


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

// compile-flags: -O

#![crate_type="rlib"]

// CHECK-LABEL: @memzero
// CHECK-NOT: store
// CHECK: call void @llvm.memset
// CHECK-NOT: store
#[no_mangle]
pub fn memzero(data: &mut [u8]) {
    for i in 0..data.len() {
        data[i] = 0;
    }
}
<commit_msg>bump llvm version of failing codegen test<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -O
// min-llvm-version 6.0

#![crate_type="rlib"]

// CHECK-LABEL: @memzero
// CHECK-NOT: store
// CHECK: call void @llvm.memset
// CHECK-NOT: store
#[no_mangle]
pub fn memzero(data: &mut [u8]) {
    for i in 0..data.len() {
        data[i] = 0;
    }
}
<|endoftext|>


<commit_before>extern crate serialize;
extern crate nickel;
extern crate http;

use http::status::NotFound;
use nickel::{
    Nickel, NickelError, ErrorWithStatusCode, Continue, Halt, Request, Response,
    QueryString, JsonBody, StaticFilesHandler, MiddlewareResult, HttpRouter
};
use std::io::net::ip::Ipv4Addr;

#[deriving(Decodable, Encodable)]
struct Person {
    firstname: String,
    lastname:  String,
}

fn main() {
    let mut server = Nickel::new();

    // we would love to use a closure for the handler but it seems to be hard
    // to achieve with the current version of rust.

    //this is an example middleware function that just logs each request
    fn logger(request: &Request, _response: &mut Response) -> MiddlewareResult {
        println!("logging request: {}", request.origin.request_uri);

        // a request is supposed to return a `bool` to indicate whether additional
        // middleware should continue executing or should be stopped.
        Ok(Continue)
    }

    // middleware is optional and can be registered with `utilize`
    server.utilize(logger);

    // this will cause json bodies automatically being parsed
    server.utilize(Nickel::json_body_parser());

    // this will cause the query string to be parsed on each request
    server.utilize(Nickel::query_string());

    let mut router = Nickel::router();

    fn user_handler(request: &Request, _response: &mut Response) -> String {
        format!("This is user: {}", request.param("userid"))
    }

    // go to http://localhost:6767/user/4711 to see this route in action
    router.get("/user/:userid", user_handler);

    fn bar_handler(_request: &Request, response: &mut Response) {
        response.send("This is the /bar handler");
    }

    // go to http://localhost:6767/bar to see this route in action
    router.get("/bar", bar_handler);

    fn simple_wildcard(_request: &Request, response: &mut Response) {
        response.send("This matches /some/crazy/route but not /some/super/crazy/route");
    }

    // go to http://localhost:6767/some/crazy/route to see this route in action
    router.get("/some/*/route", simple_wildcard);

    fn double_wildcard(_request: &Request, _response: &mut Response) -> &'static str {
        "This matches /a/crazy/route and also /a/super/crazy/route"
    }

    // go to http://localhost:6767/a/nice/route or http://localhost:6767/a/super/nice/route to see this route in action
    router.get("/a/**/route", double_wildcard);

    // try it with curl
    // curl 'http://localhost:6767/a/post/request' -H 'Content-Type: application/json;charset=UTF-8'  --data-binary $'{ "firstname": "John","lastname": "Connor" }'
    fn post_handler(request: &Request, _response: &mut Response) -> String {
        let person = request.json_as::<Person>().unwrap();
        format!("Hello {} {}", person.firstname, person.lastname)
    }

    // go to http://localhost:6767/a/post/request to see this route in action
    router.post("/a/post/request", post_handler);

    // try calling http://localhost:6767/query?foo=bar
    fn query_handler(request: &Request, _response: &mut Response) -> String {
        format!("Your foo values in the query string are: {}", request.query("foo", "This is only a default value!"))
    }

    router.get("/query", query_handler);

    server.utilize(router);

    // go to http://localhost:6767/thoughtram_logo_brain.png to see static file serving in action
    server.utilize(StaticFilesHandler::new("examples/assets/"));

    //this is how to overwrite the default error handler to handle 404 cases with a custom view
    fn custom_404(err: &NickelError, _req: &Request, response: &mut Response) -> MiddlewareResult {
        match err.kind {
            ErrorWithStatusCode(NotFound) => {
                response.content_type("html")
                        .status_code(NotFound)
                        .send("
Call the police!
");
                Ok(Halt)
            },
            _ => Ok(Continue)
        }
    }

    server.handle_error(custom_404);

    server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
}
<commit_msg>docs(examples): add example of a route propogating an error<commit_after>extern crate serialize;
extern crate nickel;
extern crate http;

use http::status::{NotFound, BadRequest};
use nickel::{
    Nickel, NickelError, ErrorWithStatusCode, Continue, Halt, Request, Response,
    QueryString, JsonBody, StaticFilesHandler, MiddlewareResult, HttpRouter
};
use std::io::net::ip::Ipv4Addr;

#[deriving(Decodable, Encodable)]
struct Person {
    firstname: String,
    lastname:  String,
}

fn main() {
    let mut server = Nickel::new();

    // we would love to use a closure for the handler but it seems to be hard
    // to achieve with the current version of rust.

    //this is an example middleware function that just logs each request
    fn logger(request: &Request, _response: &mut Response) -> MiddlewareResult {
        println!("logging request: {}", request.origin.request_uri);

        // a request is supposed to return a `bool` to indicate whether additional
        // middleware should continue executing or should be stopped.
        Ok(Continue)
    }

    // middleware is optional and can be registered with `utilize`
    server.utilize(logger);

    // this will cause json bodies automatically being parsed
    server.utilize(Nickel::json_body_parser());

    // this will cause the query string to be parsed on each request
    server.utilize(Nickel::query_string());

    let mut router = Nickel::router();

    fn user_handler(request: &Request, _response: &mut Response) -> String {
        format!("This is user: {}", request.param("userid"))
    }

    // go to http://localhost:6767/user/4711 to see this route in action
    router.get("/user/:userid", user_handler);

    fn bar_handler(_request: &Request, response: &mut Response) {
        response.send("This is the /bar handler");
    }

    // go to http://localhost:6767/bar to see this route in action
    router.get("/bar", bar_handler);

    fn simple_wildcard(_request: &Request, response: &mut Response) {
        response.send("This matches /some/crazy/route but not /some/super/crazy/route");
    }

    // go to http://localhost:6767/some/crazy/route to see this route in action
    router.get("/some/*/route", simple_wildcard);

    fn double_wildcard(_request: &Request, _response: &mut Response) -> &'static str {
        "This matches /a/crazy/route and also /a/super/crazy/route"
    }

    // go to http://localhost:6767/a/nice/route or http://localhost:6767/a/super/nice/route to see this route in action
    router.get("/a/**/route", double_wildcard);

    // try it with curl
    // curl 'http://localhost:6767/a/post/request' -H 'Content-Type: application/json;charset=UTF-8'  --data-binary $'{ "firstname": "John","lastname": "Connor" }'
    fn post_handler(request: &Request, _response: &mut Response) -> String {
        let person = request.json_as::<Person>().unwrap();
        format!("Hello {} {}", person.firstname, person.lastname)
    }

    // go to http://localhost:6767/a/post/request to see this route in action
    router.post("/a/post/request", post_handler);

    // try calling http://localhost:6767/query?foo=bar
    fn query_handler(request: &Request, _response: &mut Response) -> String {
        format!("Your foo values in the query string are: {}", request.query("foo", "This is only a default value!"))
    }

    router.get("/query", query_handler);

    // try calling http://localhost:6767/strict?state=valid
    // then try calling http://localhost:6767/strict?state=invalid
    fn strict_handler(request: &Request, response: &mut Response) -> MiddlewareResult {
        if request.query("state", "invalid")[0].as_slice() != "valid" {
            Err(NickelError::new("Error Parsing JSON", ErrorWithStatusCode(BadRequest)))
        } else {
            response.send("Congratulations on conforming!");
            Ok(Halt)
        }
    }

    router.get("/strict", strict_handler);

    server.utilize(router);

    // go to http://localhost:6767/thoughtram_logo_brain.png to see static file serving in action
    server.utilize(StaticFilesHandler::new("examples/assets/"));

    //this is how to overwrite the default error handler to handle 404 cases with a custom view
    fn custom_404(err: &NickelError, _req: &Request, response: &mut Response) -> MiddlewareResult {
        match err.kind {
            ErrorWithStatusCode(NotFound) => {
                response.content_type("html")
                        .status_code(NotFound)
                        .send("
Call the police!
");
                Ok(Halt)
            },
            _ => Ok(Continue)
        }
    }

    server.handle_error(custom_404);

    server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
}
<|endoftext|>


<commit_before>use core::mem::size_of;

use super::SDTHeader;

#[repr(packed)]
#[derive(Clone, Copy, Debug, Default)]
struct RSDP {
    signature: [u8; 8],
    checksum: u8,
    oemid: [u8; 6],
    revision: u8,
    addr: u32
}

const SIGNATURE: &'static [u8] = b"RSD PTR ";

impl RSDP {
    pub fn new() -> Option<Self> {
        //Search top of bios region
        let mut search_ptr = 0xE0000;
        while search_ptr < 0xFFFFF {
            let rsdp = search_ptr as *const RSDP;
            if unsafe { (*rsdp).valid() } {
                return Some(unsafe { *rsdp });
            }
            search_ptr += 16;
        }

        None
    }

    //TODO: Checksum validation
    pub fn valid(&self) -> bool {
        if self.signature == SIGNATURE {
            let ptr = (self as *const Self) as *const u8;
            let sum = (0..size_of::<Self>() as isize).fold(0, |sum, i| sum + unsafe { *ptr.offset(i) });

            sum == 0
        } else {
            false
        }
    }
}

#[repr(packed)]
#[derive(Clone, Debug, Default)]
pub struct RSDT {
    pub header: SDTHeader,
    pub addrs: &'static [u32]
}

impl RSDT {
    pub fn new() -> Result<Self, &'static str> {
        match RSDP::new() {
            Some(rsdp) => {
                let header = rsdp.addr as *const SDTHeader;
                if unsafe { (*header).valid("RSDT") } {
                    Ok(RSDT {
                        header: unsafe { (*header).clone() },
                        addrs: unsafe { (*header).data() }
                    })
                } else {
                    Err("Did not find RSDT")
                }
            },
            None => {
                Err("Did not find RSDP")
            }
        }
    }
}
<commit_msg>Refactor `RSDP::new()` to return a `Result` instead<commit_after>use core::mem::size_of;

use super::SDTHeader;

#[repr(packed)]
#[derive(Clone, Copy, Debug, Default)]
struct RSDP {
    signature: [u8; 8],
    checksum: u8,
    oemid: [u8; 6],
    revision: u8,
    addr: u32
}

const SIGNATURE: &'static [u8] = b"RSD PTR ";

impl RSDP {
    pub fn new() -> Result<Self, &'static str> {
        //Search top of bios region
        let mut search_ptr = 0xE0000;
        while search_ptr < 0xFFFFF {
            let rsdp = search_ptr as *const RSDP;
            if unsafe { (*rsdp).valid() } {
                return Ok(unsafe { *rsdp });
            }
            search_ptr += 16;
        }

        Err("Did not find RSDP")
    }

    //TODO: Checksum validation
    pub fn valid(&self) -> bool {
        if self.signature == SIGNATURE {
            let ptr = (self as *const Self) as *const u8;
            let sum = (0..size_of::<Self>() as isize).fold(0, |sum, i| sum + unsafe { *ptr.offset(i) });

            sum == 0
        } else {
            false
        }
    }
}

#[repr(packed)]
#[derive(Clone, Debug, Default)]
pub struct RSDT {
    pub header: SDTHeader,
    pub addrs: &'static [u32]
}

impl RSDT {
    pub fn new() -> Result<Self, &'static str> {
        match RSDP::new() {
            Ok(rsdp) => {
                let header = rsdp.addr as *const SDTHeader;
                if unsafe { (*header).valid("RSDT") } {
                    Ok(RSDT {
                        header: unsafe { (*header).clone() },
                        addrs: unsafe { (*header).data() }
                    })
                } else {
                    Err("Did not find RSDT")
                }
            },
            Err(e) => Err(e),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove not needed return keywords<commit_after><|endoftext|>


<commit_before><commit_msg>Add compile-fail test for the `with` attribute<commit_after>#[macro_use]
extern crate serde_derive;

#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
    #[serde(with = "w", serialize_with = "s")] //~^^ HELP: duplicate serde attribute `serialize_with`
    x: (),
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Wrong starting error for roll<commit_after><|endoftext|>


<commit_before>use std;
import std::rand;
import uint::range;

// random uint less than n
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }

// random choice from a vec
fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }

// k in n chance of being true
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }

const iters : uint = 1000u;
const vlen  : uint = 100u;

enum maybe_pointy {
    none,
    p(@pointy)
}

type pointy = {
    mut a : maybe_pointy,
    mut b : ~maybe_pointy,
    mut c : @maybe_pointy,

    mut f : fn@()->(),
    mut g : fn~()->(),

    mut m : [maybe_pointy],
    mut n : [mut maybe_pointy],
    mut o : {x : int, y : maybe_pointy}
};
// To add: objects; ifaces; anything type-parameterized?

fn empty_pointy() -> @pointy {
    ret @{
        mut a : none,
        mut b : ~none,
        mut c : @none,

        mut f : fn@()->(){},
        mut g : fn~()->(){},

        mut m : [],
        mut n : [mut],
        mut o : {x : 0, y : none}
    }
}

fn nopP(_x : @pointy) { }
fn nop<T>(_x: T) { }

fn test_cycles(r : rand::rng, k: uint, n: uint)
{
    let v : [mut @pointy] = [mut];

    // Create a graph with no edges
    range(0u, vlen) {|_i|
        v += [mut empty_pointy()];
    }

    // Fill in the graph with random edges, with density k/n
    range(0u, vlen) {|i|
        if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }

        if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
        if (false)               { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
          // https://github.com/mozilla/rust/issues/1899

        if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
    }

    // Drop refs one at a time
    range(0u, vlen) {|i|
        v[i] = empty_pointy()
    }
}

fn main()
{
    let r = rand::mk_rng();
    range(0u, iters) {|i|
        test_cycles(r, i, iters);
    }
}
<commit_msg>Update CC fuzzer<commit_after>use std;
import std::rand;
import uint::range;

// random uint less than n
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }

// random choice from a vec
fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }

// k in n chance of being true
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }

const iters : uint = 1000u;
const vlen  : uint = 100u;

enum maybe_pointy {
    none,
    p(@pointy)
}

type pointy = {
    mut a : maybe_pointy,
    mut b : ~maybe_pointy,
    mut c : @maybe_pointy,

    mut f : fn@()->(),
    mut g : fn~()->(),

    mut m : [maybe_pointy],
    mut n : [mut maybe_pointy],
    mut o : {x : int, y : maybe_pointy}
};
// To add: objects; ifaces; anything type-parameterized?

fn empty_pointy() -> @pointy {
    ret @{
        mut a : none,
        mut b : ~none,
        mut c : @none,

        mut f : fn@()->(){},
        mut g : fn~()->(){},

        mut m : [],
        mut n : [mut],
        mut o : {x : 0, y : none}
    }
}

fn nopP(_x : @pointy) { }
fn nop<T>(_x: T) { }

fn test_cycles(r : rand::rng, k: uint, n: uint)
{
    let v : [mut @pointy] = [mut];

    // Create a graph with no edges
    range(0u, vlen) {|_i|
        v += [mut empty_pointy()];
    }

    // Fill in the graph with random edges, with density k/n
    range(0u, vlen) {|i|
        if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
        if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }

        if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
        //if (false)               { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
          // https://github.com/mozilla/rust/issues/1899

        if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
        if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
    }

    // Drop refs one at a time
    range(0u, vlen) {|i|
        v[i] = empty_pointy()
    }
}

fn main()
{
    let r = rand::rng();
    range(0u, iters) {|i|
        test_cycles(r, i, iters);
    }
}
<|endoftext|>


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

extern crate env_logger;
extern crate gfx_corell;
#[cfg(all(target_os = "windows", not(feature = "vulkan")))]
extern crate gfx_device_dx12ll as back;
#[cfg(feature = "vulkan")]
extern crate gfx_device_vulkanll as back;

extern crate winit;

use gfx_corell::{Instance, Adapter, Surface, SwapChain, QueueFamily};

pub type ColorFormat = gfx_corell::format::Rgba8;

fn main() {
    env_logger::init().unwrap();
    let window = winit::WindowBuilder::new()
        .with_dimensions(1024, 768)
        .with_title("triangle (Low Level)".to_string())
        .build()
        .unwrap();

    // instantiate backend
    let instance = back::Instance::create();
    let physical_devices = instance.enumerate_adapters();
    let surface = instance.create_surface(&window);

    let queue_descs = physical_devices[0].get_queue_families().map(|family| { (family, family.num_queues()) });

    for device in &physical_devices {
        println!("{:?}", device.get_info());
    }

    // build a new device and associated command queues
    let (device, queues) = physical_devices[0].open(queue_descs);

    let mut swap_chain = surface.build_swapchain::<ColorFormat>(&queues[0]);

    'main: loop {
        for event in window.poll_events() {
            match event {
                winit::Event::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape)) |
                winit::Event::Closed => break 'main,
                _ => {},
            }
        }

        let frame = swap_chain.acquire_frame();

        // rendering

        // present frame
        swap_chain.present();
    }
}<commit_msg>Fix OSX compilation of trianglell example due to lack of d3d12 or vulkan support.<commit_after>// Copyright 2017 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate env_logger;
extern crate gfx_corell;
#[cfg(all(target_os = "windows", not(feature = "vulkan")))]
extern crate gfx_device_dx12ll as back;
#[cfg(feature = "vulkan")]
extern crate gfx_device_vulkanll as back;

extern crate winit;

use gfx_corell::{Instance, Adapter, Surface, SwapChain, QueueFamily};

pub type ColorFormat = gfx_corell::format::Rgba8;

#[cfg(any(feature = "vulkan", target_os = "windows"))]
fn main() {
    env_logger::init().unwrap();
    let window = winit::WindowBuilder::new()
        .with_dimensions(1024, 768)
        .with_title("triangle (Low Level)".to_string())
        .build()
        .unwrap();

    // instantiate backend
    let instance = back::Instance::create();
    let physical_devices = instance.enumerate_adapters();
    let surface = instance.create_surface(&window);

    let queue_descs = physical_devices[0].get_queue_families().map(|family| { (family, family.num_queues()) });

    for device in &physical_devices {
        println!("{:?}", device.get_info());
    }

    // build a new device and associated command queues
    let (device, queues) = physical_devices[0].open(queue_descs);

    let mut swap_chain = surface.build_swapchain::<ColorFormat>(&queues[0]);

    'main: loop {
        for event in window.poll_events() {
            match event {
                winit::Event::KeyboardInput(_, _, Some(winit::VirtualKeyCode::Escape)) |
                winit::Event::Closed => break 'main,
                _ => {},
            }
        }

        let frame = swap_chain.acquire_frame();

        // rendering

        // present frame
        swap_chain.present();
    }
}

#[cfg(not(any(feature = "vulkan", target_os = "windows")))]
fn main() {}
<|endoftext|>