<commit_before>type T = uint;

/**
 * Divide two numbers, return the result, rounded up.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The smallest integer `q` such that `x/y <= q`.
 */
pure fn div_ceil(x: uint, y: uint) -> uint {
    let div = div(x, y);
    if x % y == 0u { ret div;}
    else { ret div + 1u; }
}

/**
 * Divide two numbers, return the result, rounded to the closest integer.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The integer `q` closest to `x/y`.
 */
pure fn div_round(x: uint, y: uint) -> uint {
    let div = div(x, y);
    if x % y * 2u  < y { ret div;}
    else { ret div + 1u; }
}

/**
 * Divide two numbers, return the result, rounded down.
 *
 * Note: This is the same function as `div`.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The smallest integer `q` such that `x/y <= q`. This
 * is either `x/y` or `x/y + 1`.
 */
pure fn div_floor(x: uint, y: uint) -> uint { ret x / y; }

/// Produce a uint suitable for use in a hash table
pure fn hash(&&x: uint) -> uint { ret x; }

/**
 * Iterate over the range [`lo`..`hi`), or stop when requested
 *
 * # Arguments
 *
 * * lo - The integer at which to start the loop (included)
 * * hi - The integer at which to stop the loop (excluded)
 * * it - A block to execute with each consecutive integer of the range.
 *        Return `true` to continue, `false` to stop.
 *
 * # Return value
 *
 * `true` If execution proceeded correctly, `false` if it was interrupted,
 * that is if `it` returned `false` at any point.
 */
fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
    let mut i = lo;
    while i < hi {
        if (!it(i)) { ret false; }
        i += 1u;
    }
    ret true;
}

/// Returns the smallest power of 2 greater than or equal to `n`
#[inline(always)]
fn next_power_of_two(n: uint) -> uint {
    let halfbits: uint = sys::size_of::<uint>() * 4u;
    let mut tmp: uint = n - 1u;
    let mut shift: uint = 1u;
    while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
    ret tmp + 1u;
}

#[test]
fn test_next_power_of_two() {
    assert (uint::next_power_of_two(0u) == 0u);
    assert (uint::next_power_of_two(1u) == 1u);
    assert (uint::next_power_of_two(2u) == 2u);
    assert (uint::next_power_of_two(3u) == 4u);
    assert (uint::next_power_of_two(4u) == 4u);
    assert (uint::next_power_of_two(5u) == 8u);
    assert (uint::next_power_of_two(6u) == 8u);
    assert (uint::next_power_of_two(7u) == 8u);
    assert (uint::next_power_of_two(8u) == 8u);
    assert (uint::next_power_of_two(9u) == 16u);
    assert (uint::next_power_of_two(10u) == 16u);
    assert (uint::next_power_of_two(11u) == 16u);
    assert (uint::next_power_of_two(12u) == 16u);
    assert (uint::next_power_of_two(13u) == 16u);
    assert (uint::next_power_of_two(14u) == 16u);
    assert (uint::next_power_of_two(15u) == 16u);
    assert (uint::next_power_of_two(16u) == 16u);
    assert (uint::next_power_of_two(17u) == 32u);
    assert (uint::next_power_of_two(18u) == 32u);
    assert (uint::next_power_of_two(19u) == 32u);
    assert (uint::next_power_of_two(20u) == 32u);
    assert (uint::next_power_of_two(21u) == 32u);
    assert (uint::next_power_of_two(22u) == 32u);
    assert (uint::next_power_of_two(23u) == 32u);
    assert (uint::next_power_of_two(24u) == 32u);
    assert (uint::next_power_of_two(25u) == 32u);
    assert (uint::next_power_of_two(26u) == 32u);
    assert (uint::next_power_of_two(27u) == 32u);
    assert (uint::next_power_of_two(28u) == 32u);
    assert (uint::next_power_of_two(29u) == 32u);
    assert (uint::next_power_of_two(30u) == 32u);
    assert (uint::next_power_of_two(31u) == 32u);
    assert (uint::next_power_of_two(32u) == 32u);
    assert (uint::next_power_of_two(33u) == 64u);
    assert (uint::next_power_of_two(34u) == 64u);
    assert (uint::next_power_of_two(35u) == 64u);
    assert (uint::next_power_of_two(36u) == 64u);
    assert (uint::next_power_of_two(37u) == 64u);
    assert (uint::next_power_of_two(38u) == 64u);
    assert (uint::next_power_of_two(39u) == 64u);
}

#[test]
fn test_overflows() {
    assert (uint::max_value > 0u);
    assert (uint::min_value <= 0u);
    assert (uint::min_value + uint::max_value + 1u == 0u);
}

#[test]
fn test_div() {
    assert(uint::div_floor(3u, 4u) == 0u);
    assert(uint::div_ceil(3u, 4u)  == 1u);
    assert(uint::div_round(3u, 4u) == 1u);
}
<commit_msg>Make uint::iterate pure<commit_after>type T = uint;

/**
 * Divide two numbers, return the result, rounded up.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The smallest integer `q` such that `x/y <= q`.
 */
pure fn div_ceil(x: uint, y: uint) -> uint {
    let div = div(x, y);
    if x % y == 0u { ret div;}
    else { ret div + 1u; }
}

/**
 * Divide two numbers, return the result, rounded to the closest integer.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The integer `q` closest to `x/y`.
 */
pure fn div_round(x: uint, y: uint) -> uint {
    let div = div(x, y);
    if x % y * 2u  < y { ret div;}
    else { ret div + 1u; }
}

/**
 * Divide two numbers, return the result, rounded down.
 *
 * Note: This is the same function as `div`.
 *
 * # Arguments
 *
 * * x - an integer
 * * y - an integer distinct from 0u
 *
 * # Return value
 *
 * The smallest integer `q` such that `x/y <= q`. This
 * is either `x/y` or `x/y + 1`.
 */
pure fn div_floor(x: uint, y: uint) -> uint { ret x / y; }

/// Produce a uint suitable for use in a hash table
pure fn hash(&&x: uint) -> uint { ret x; }

/**
 * Iterate over the range [`lo`..`hi`), or stop when requested
 *
 * # Arguments
 *
 * * lo - The integer at which to start the loop (included)
 * * hi - The integer at which to stop the loop (excluded)
 * * it - A block to execute with each consecutive integer of the range.
 *        Return `true` to continue, `false` to stop.
 *
 * # Return value
 *
 * `true` If execution proceeded correctly, `false` if it was interrupted,
 * that is if `it` returned `false` at any point.
 */
pure fn iterate(lo: uint, hi: uint, it: fn(uint) -> bool) -> bool {
    let mut i = lo;
    while i < hi {
        if (!it(i)) { ret false; }
        i += 1u;
    }
    ret true;
}

/// Returns the smallest power of 2 greater than or equal to `n`
#[inline(always)]
fn next_power_of_two(n: uint) -> uint {
    let halfbits: uint = sys::size_of::<uint>() * 4u;
    let mut tmp: uint = n - 1u;
    let mut shift: uint = 1u;
    while shift <= halfbits { tmp |= tmp >> shift; shift <<= 1u; }
    ret tmp + 1u;
}

#[test]
fn test_next_power_of_two() {
    assert (uint::next_power_of_two(0u) == 0u);
    assert (uint::next_power_of_two(1u) == 1u);
    assert (uint::next_power_of_two(2u) == 2u);
    assert (uint::next_power_of_two(3u) == 4u);
    assert (uint::next_power_of_two(4u) == 4u);
    assert (uint::next_power_of_two(5u) == 8u);
    assert (uint::next_power_of_two(6u) == 8u);
    assert (uint::next_power_of_two(7u) == 8u);
    assert (uint::next_power_of_two(8u) == 8u);
    assert (uint::next_power_of_two(9u) == 16u);
    assert (uint::next_power_of_two(10u) == 16u);
    assert (uint::next_power_of_two(11u) == 16u);
    assert (uint::next_power_of_two(12u) == 16u);
    assert (uint::next_power_of_two(13u) == 16u);
    assert (uint::next_power_of_two(14u) == 16u);
    assert (uint::next_power_of_two(15u) == 16u);
    assert (uint::next_power_of_two(16u) == 16u);
    assert (uint::next_power_of_two(17u) == 32u);
    assert (uint::next_power_of_two(18u) == 32u);
    assert (uint::next_power_of_two(19u) == 32u);
    assert (uint::next_power_of_two(20u) == 32u);
    assert (uint::next_power_of_two(21u) == 32u);
    assert (uint::next_power_of_two(22u) == 32u);
    assert (uint::next_power_of_two(23u) == 32u);
    assert (uint::next_power_of_two(24u) == 32u);
    assert (uint::next_power_of_two(25u) == 32u);
    assert (uint::next_power_of_two(26u) == 32u);
    assert (uint::next_power_of_two(27u) == 32u);
    assert (uint::next_power_of_two(28u) == 32u);
    assert (uint::next_power_of_two(29u) == 32u);
    assert (uint::next_power_of_two(30u) == 32u);
    assert (uint::next_power_of_two(31u) == 32u);
    assert (uint::next_power_of_two(32u) == 32u);
    assert (uint::next_power_of_two(33u) == 64u);
    assert (uint::next_power_of_two(34u) == 64u);
    assert (uint::next_power_of_two(35u) == 64u);
    assert (uint::next_power_of_two(36u) == 64u);
    assert (uint::next_power_of_two(37u) == 64u);
    assert (uint::next_power_of_two(38u) == 64u);
    assert (uint::next_power_of_two(39u) == 64u);
}

#[test]
fn test_overflows() {
    assert (uint::max_value > 0u);
    assert (uint::min_value <= 0u);
    assert (uint::min_value + uint::max_value + 1u == 0u);
}

#[test]
fn test_div() {
    assert(uint::div_floor(3u, 4u) == 0u);
    assert(uint::div_ceil(3u, 4u)  == 1u);
    assert(uint::div_round(3u, 4u) == 1u);
}
<|endoftext|>


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

use syntax::fold::Folder;
use syntax::{ast, fold, attr};
use syntax::codemap;

struct Context<'a> {
    in_cfg: 'a |attrs: &[ast::Attribute]| -> bool,
}

// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(crate: ast::Crate) -> ast::Crate {
    let config = crate.config.clone();
    strip_items(crate, |attrs| in_cfg(config, attrs))
}

impl<'a> fold::Folder for Context<'a> {
    fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
        fold_mod(self, module)
    }
    fn fold_block(&mut self, block: ast::P<ast::Block>) -> ast::P<ast::Block> {
        fold_block(self, block)
    }
    fn fold_foreign_mod(&mut self, foreign_mod: &ast::ForeignMod) -> ast::ForeignMod {
        fold_foreign_mod(self, foreign_mod)
    }
    fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
        fold_item_underscore(self, item)
    }
}

pub fn strip_items(crate: ast::Crate,
                   in_cfg: |attrs: &[ast::Attribute]| -> bool)
                   -> ast::Crate {
    let mut ctxt = Context {
        in_cfg: in_cfg,
    };
    ctxt.fold_crate(crate)
}

fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
                        -> Option<&'r ast::ViewItem> {
    if view_item_in_cfg(cx, view_item) {
        Some(view_item)
    } else {
        None
    }
}

fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
    let filtered_items = m.items.iter()
            .filter(|&a| item_in_cfg(cx, *a))
            .flat_map(|&x| cx.fold_item(x).move_iter())
            .collect();
    let filtered_view_items = m.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::Mod {
        view_items: filtered_view_items,
        items: filtered_items
    }
}

fn filter_foreign_item(cx: &Context, item: @ast::ForeignItem)
                       -> Option<@ast::ForeignItem> {
    if foreign_item_in_cfg(cx, item) {
        Some(item)
    } else {
        None
    }
}

fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
    let filtered_items = nm.items
                           .iter()
                           .filter_map(|a| filter_foreign_item(cx, *a))
                           .collect();
    let filtered_view_items = nm.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::ForeignMod {
        abis: nm.abis,
        view_items: filtered_view_items,
        items: filtered_items
    }
}

fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
    let item = match *item {
        ast::ItemImpl(ref a, ref b, c, ref methods) => {
            let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
                .map(|x| *x).collect();
            ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
        }
        ast::ItemTrait(ref a, ref b, ref methods) => {
            let methods = methods.iter()
                                 .filter(|m| trait_method_in_cfg(cx, *m) )
                                 .map(|x| (*x).clone())
                                 .collect();
            ast::ItemTrait((*a).clone(), (*b).clone(), methods)
        }
        ast::ItemStruct(def, ref generics) => {
            ast::ItemStruct(fold_struct(cx, def), generics.clone())
        }
        ast::ItemEnum(ref def, ref generics) => {
            let mut variants = def.variants.iter().map(|c| c.clone()).filter(|m| {
                (cx.in_cfg)(m.node.attrs)
            }).map(|v| {
                match v.node.kind {
                    ast::TupleVariantKind(..) => v,
                    ast::StructVariantKind(def) => {
                        let def = fold_struct(cx, def);
                        @codemap::Spanned {
                            node: ast::Variant_ {
                                kind: ast::StructVariantKind(def),
                                ..v.node.clone()
                            },
                            ..*v
                        }
                    }
                }
            });
            ast::ItemEnum(ast::EnumDef {
                variants: variants.collect(),
            }, generics.clone())
        }
        ref item => item.clone(),
    };

    fold::noop_fold_item_underscore(&item, cx)
}

fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
    let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
        (cx.in_cfg)(m.node.attrs)
    });
    @ast::StructDef {
        fields: fields.collect(),
        ctor_id: def.ctor_id,
    }
}

fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
    match stmt.node {
      ast::StmtDecl(decl, _) => {
        match decl.node {
          ast::DeclItem(item) => {
            item_in_cfg(cx, item)
          }
          _ => true
        }
      }
      _ => true
    }
}

fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
    let resulting_stmts = b.stmts.iter()
            .filter(|&a| retain_stmt(cx, *a))
            .flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
            .collect();
    let filtered_view_items = b.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::P(ast::Block {
        view_items: filtered_view_items,
        stmts: resulting_stmts,
        expr: b.expr.map(|x| cx.fold_expr(x)),
        id: b.id,
        rules: b.rules,
        span: b.span,
    })
}

fn item_in_cfg(cx: &Context, item: &ast::Item) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn foreign_item_in_cfg(cx: &Context, item: &ast::ForeignItem) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn view_item_in_cfg(cx: &Context, item: &ast::ViewItem) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn method_in_cfg(cx: &Context, meth: &ast::Method) -> bool {
    return (cx.in_cfg)(meth.attrs);
}

fn trait_method_in_cfg(cx: &Context, meth: &ast::TraitMethod) -> bool {
    match *meth {
        ast::Required(ref meth) => (cx.in_cfg)(meth.attrs),
        ast::Provided(meth) => (cx.in_cfg)(meth.attrs)
    }
}

// Determine if an item should be translated in the current crate
// configuration based on the item's attributes
fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool {
    attr::test_cfg(cfg, attrs.iter().map(|x| *x))
}

<commit_msg>front -- collapse iterator actions that require access to the same &mut state<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax::fold::Folder;
use syntax::{ast, fold, attr};
use syntax::codemap;

struct Context<'a> {
    in_cfg: 'a |attrs: &[ast::Attribute]| -> bool,
}

// Support conditional compilation by transforming the AST, stripping out
// any items that do not belong in the current configuration
pub fn strip_unconfigured_items(crate: ast::Crate) -> ast::Crate {
    let config = crate.config.clone();
    strip_items(crate, |attrs| in_cfg(config, attrs))
}

impl<'a> fold::Folder for Context<'a> {
    fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
        fold_mod(self, module)
    }
    fn fold_block(&mut self, block: ast::P<ast::Block>) -> ast::P<ast::Block> {
        fold_block(self, block)
    }
    fn fold_foreign_mod(&mut self, foreign_mod: &ast::ForeignMod) -> ast::ForeignMod {
        fold_foreign_mod(self, foreign_mod)
    }
    fn fold_item_underscore(&mut self, item: &ast::Item_) -> ast::Item_ {
        fold_item_underscore(self, item)
    }
}

pub fn strip_items(crate: ast::Crate,
                   in_cfg: |attrs: &[ast::Attribute]| -> bool)
                   -> ast::Crate {
    let mut ctxt = Context {
        in_cfg: in_cfg,
    };
    ctxt.fold_crate(crate)
}

fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
                        -> Option<&'r ast::ViewItem> {
    if view_item_in_cfg(cx, view_item) {
        Some(view_item)
    } else {
        None
    }
}

fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
    let filtered_items: ~[&@ast::Item] = m.items.iter()
            .filter(|&a| item_in_cfg(cx, *a))
            .collect();
    let flattened_items = filtered_items.move_iter()
            .flat_map(|&x| cx.fold_item(x).move_iter())
            .collect();
    let filtered_view_items = m.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::Mod {
        view_items: filtered_view_items,
        items: flattened_items
    }
}

fn filter_foreign_item(cx: &Context, item: @ast::ForeignItem)
                       -> Option<@ast::ForeignItem> {
    if foreign_item_in_cfg(cx, item) {
        Some(item)
    } else {
        None
    }
}

fn fold_foreign_mod(cx: &mut Context, nm: &ast::ForeignMod) -> ast::ForeignMod {
    let filtered_items = nm.items
                           .iter()
                           .filter_map(|a| filter_foreign_item(cx, *a))
                           .collect();
    let filtered_view_items = nm.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::ForeignMod {
        abis: nm.abis,
        view_items: filtered_view_items,
        items: filtered_items
    }
}

fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
    let item = match *item {
        ast::ItemImpl(ref a, ref b, c, ref methods) => {
            let methods = methods.iter().filter(|m| method_in_cfg(cx, **m))
                .map(|x| *x).collect();
            ast::ItemImpl((*a).clone(), (*b).clone(), c, methods)
        }
        ast::ItemTrait(ref a, ref b, ref methods) => {
            let methods = methods.iter()
                                 .filter(|m| trait_method_in_cfg(cx, *m) )
                                 .map(|x| (*x).clone())
                                 .collect();
            ast::ItemTrait((*a).clone(), (*b).clone(), methods)
        }
        ast::ItemStruct(def, ref generics) => {
            ast::ItemStruct(fold_struct(cx, def), generics.clone())
        }
        ast::ItemEnum(ref def, ref generics) => {
            let mut variants = def.variants.iter().map(|c| c.clone()).
            filter_map(|v| {
                if !(cx.in_cfg)(v.node.attrs) {
                    None
                } else {
                    Some(match v.node.kind {
                                ast::TupleVariantKind(..) => v,
                                ast::StructVariantKind(def) => {
                                    let def = fold_struct(cx, def);
                                    @codemap::Spanned {
                                        node: ast::Variant_ {
                                            kind: ast::StructVariantKind(def),
                                            ..v.node.clone()
                                        },
                                        ..*v
                                    }
                                }
                            })
                    }
                });
            ast::ItemEnum(ast::EnumDef {
                variants: variants.collect(),
            }, generics.clone())
        }
        ref item => item.clone(),
    };

    fold::noop_fold_item_underscore(&item, cx)
}

fn fold_struct(cx: &Context, def: &ast::StructDef) -> @ast::StructDef {
    let mut fields = def.fields.iter().map(|c| c.clone()).filter(|m| {
        (cx.in_cfg)(m.node.attrs)
    });
    @ast::StructDef {
        fields: fields.collect(),
        ctor_id: def.ctor_id,
    }
}

fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
    match stmt.node {
      ast::StmtDecl(decl, _) => {
        match decl.node {
          ast::DeclItem(item) => {
            item_in_cfg(cx, item)
          }
          _ => true
        }
      }
      _ => true
    }
}

fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
    let resulting_stmts: ~[&@ast::Stmt] =
        b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
    let resulting_stmts = resulting_stmts.move_iter()
        .flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
        .collect();
    let filtered_view_items = b.view_items.iter().filter_map(|a| {
        filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
    }).collect();
    ast::P(ast::Block {
        view_items: filtered_view_items,
        stmts: resulting_stmts,
        expr: b.expr.map(|x| cx.fold_expr(x)),
        id: b.id,
        rules: b.rules,
        span: b.span,
    })
}

fn item_in_cfg(cx: &Context, item: &ast::Item) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn foreign_item_in_cfg(cx: &Context, item: &ast::ForeignItem) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn view_item_in_cfg(cx: &Context, item: &ast::ViewItem) -> bool {
    return (cx.in_cfg)(item.attrs);
}

fn method_in_cfg(cx: &Context, meth: &ast::Method) -> bool {
    return (cx.in_cfg)(meth.attrs);
}

fn trait_method_in_cfg(cx: &Context, meth: &ast::TraitMethod) -> bool {
    match *meth {
        ast::Required(ref meth) => (cx.in_cfg)(meth.attrs),
        ast::Provided(meth) => (cx.in_cfg)(meth.attrs)
    }
}

// Determine if an item should be translated in the current crate
// configuration based on the item's attributes
fn in_cfg(cfg: &[@ast::MetaItem], attrs: &[ast::Attribute]) -> bool {
    attr::test_cfg(cfg, attrs.iter().map(|x| *x))
}

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

use io;
use libc;
use sys::fd::FileDesc;

////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
////////////////////////////////////////////////////////////////////////////////

pub struct AnonPipe(FileDesc);

pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
    let mut fds = [0; 2];

    libc::pipe2(&mut fds, libc::O_CLOEXEC).map_err(|err| io::Error::from_raw_os_error(err.errno))?;

    let fd0 = FileDesc::new(fds[0]);
    let fd1 = FileDesc::new(fds[1]);
    Ok((AnonPipe::from_fd(fd0)?, AnonPipe::from_fd(fd1)?))
}

impl AnonPipe {
    pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
        fd.set_cloexec()?;
        Ok(AnonPipe(fd))
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.0.read_to_end(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn fd(&self) -> &FileDesc { &self.0 }
    pub fn into_fd(self) -> FileDesc { self.0 }
}

pub fn read2(_p1: AnonPipe,
             _v1: &mut Vec<u8>,
             _p2: AnonPipe,
             _v2: &mut Vec<u8>) -> io::Result<()> {
    ::sys_common::util::dumb_print(format_args!("read2\n"));
    unimplemented!();
    /*
    // Set both pipes into nonblocking mode as we're gonna be reading from both
    // in the `select` loop below, and we wouldn't want one to block the other!
    let p1 = p1.into_fd();
    let p2 = p2.into_fd();
    p1.set_nonblocking(true)?;
    p2.set_nonblocking(true)?;

    let max = cmp::max(p1.raw(), p2.raw());
    loop {
        // wait for either pipe to become readable using `select`
        cvt_r(|| unsafe {
            let mut read: libc::fd_set = mem::zeroed();
            libc::FD_SET(p1.raw(), &mut read);
            libc::FD_SET(p2.raw(), &mut read);
            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
                         ptr::null_mut())
        })?;

        // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
        // EAGAIN. If we hit EOF, then this will happen because the underlying
        // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
        // this case we flip the other fd back into blocking mode and read
        // whatever's leftover on that file descriptor.
        let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
            match fd.read_to_end(dst) {
                Ok(_) => Ok(true),
                Err(e) => {
                    if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
                       e.raw_os_error() == Some(libc::EAGAIN) {
                        Ok(false)
                    } else {
                        Err(e)
                    }
                }
            }
        };
        if read(&p1, v1)? {
            p2.set_nonblocking(false)?;
            return p2.read_to_end(v2).map(|_| ());
        }
        if read(&p2, v2)? {
            p1.set_nonblocking(false)?;
            return p1.read_to_end(v1).map(|_| ());
        }
    }
    */
}
<commit_msg>Simple implementation of read2<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io;
use libc;
use sys::fd::FileDesc;

////////////////////////////////////////////////////////////////////////////////
// Anonymous pipes
////////////////////////////////////////////////////////////////////////////////

pub struct AnonPipe(FileDesc);

pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
    let mut fds = [0; 2];

    libc::pipe2(&mut fds, libc::O_CLOEXEC).map_err(|err| io::Error::from_raw_os_error(err.errno))?;

    Ok((AnonPipe(FileDesc::new(fds[0])), AnonPipe(FileDesc::new(fds[1]))))
}

impl AnonPipe {
    pub fn from_fd(fd: FileDesc) -> io::Result<AnonPipe> {
        fd.set_cloexec()?;
        Ok(AnonPipe(fd))
    }

    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
        self.0.read(buf)
    }

    pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
        self.0.read_to_end(buf)
    }

    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    pub fn fd(&self) -> &FileDesc { &self.0 }
    pub fn into_fd(self) -> FileDesc { self.0 }
}

pub fn read2(p1: AnonPipe,
             v1: &mut Vec<u8>,
             p2: AnonPipe,
             v2: &mut Vec<u8>) -> io::Result<()> {
    //TODO: Use event based I/O multiplexing
    //unimplemented!()

    p1.read_to_end(v1)?;
    p2.read_to_end(v2)?;

    Ok(())

    /*
    // Set both pipes into nonblocking mode as we're gonna be reading from both
    // in the `select` loop below, and we wouldn't want one to block the other!
    let p1 = p1.into_fd();
    let p2 = p2.into_fd();
    p1.set_nonblocking(true)?;
    p2.set_nonblocking(true)?;

    loop {
        // wait for either pipe to become readable using `select`
        cvt_r(|| unsafe {
            let mut read: libc::fd_set = mem::zeroed();
            libc::FD_SET(p1.raw(), &mut read);
            libc::FD_SET(p2.raw(), &mut read);
            libc::select(max + 1, &mut read, ptr::null_mut(), ptr::null_mut(),
                         ptr::null_mut())
        })?;

        // Read as much as we can from each pipe, ignoring EWOULDBLOCK or
        // EAGAIN. If we hit EOF, then this will happen because the underlying
        // reader will return Ok(0), in which case we'll see `Ok` ourselves. In
        // this case we flip the other fd back into blocking mode and read
        // whatever's leftover on that file descriptor.
        let read = |fd: &FileDesc, dst: &mut Vec<u8>| {
            match fd.read_to_end(dst) {
                Ok(_) => Ok(true),
                Err(e) => {
                    if e.raw_os_error() == Some(libc::EWOULDBLOCK) ||
                       e.raw_os_error() == Some(libc::EAGAIN) {
                        Ok(false)
                    } else {
                        Err(e)
                    }
                }
            }
        };
        if read(&p1, v1)? {
            p2.set_nonblocking(false)?;
            return p2.read_to_end(v2).map(|_| ());
        }
        if read(&p2, v2)? {
            p1.set_nonblocking(false)?;
            return p1.read_to_end(v1).map(|_| ());
        }
    }
    */
}
<|endoftext|>


<commit_before>fn main() -> () {
  let @vec[uint] quux = @[];
}
<commit_msg>test: xfail vector-no-ann-2 in stage0<commit_after>// xfail-stage0

fn main() -> () {
  let @vec[uint] quux = @[];
}
<|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.

//! Sanity checking performed by rustbuild before actually executing anything.
//!
//! This module contains the implementation of ensuring that the build
//! environment looks reasonable before progressing. This will verify that
//! various programs like git and python exist, along with ensuring that all C
//! compilers for cross-compiling are found.
//!
//! In theory if we get past this phase it's a bug if a build fails, but in
//! practice that's likely not true!

use std::collections::HashSet;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::process::Command;

use build_helper::output;

use Build;

pub fn check(build: &mut Build) {
    let mut checked = HashSet::new();
    let path = env::var_os("PATH").unwrap_or(OsString::new());
    let mut need_cmd = |cmd: &OsStr| {
        if !checked.insert(cmd.to_owned()) {
            return
        }
        for path in env::split_paths(&path).map(|p| p.join(cmd)) {
            if fs::metadata(&path).is_ok() ||
               fs::metadata(path.with_extension("exe")).is_ok() {
                return
            }
        }
        panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
    };

    // If we've got a git directory we're gona need git to update
    // submodules and learn about various other aspects.
    if fs::metadata(build.src.join(".git")).is_ok() {
        need_cmd("git".as_ref());
    }

    // We need cmake, but only if we're actually building LLVM
    for host in build.config.host.iter() {
        if let Some(config) = build.config.target_config.get(host) {
            if config.llvm_config.is_some() {
                continue
            }
        }
        need_cmd("cmake".as_ref());
        if build.config.ninja {
            need_cmd("ninja".as_ref())
        }
        break
    }

    need_cmd("python".as_ref());

    // We're gonna build some custom C code here and there, host triples
    // also build some C++ shims for LLVM so we need a C++ compiler.
    for target in build.config.target.iter() {
        need_cmd(build.cc(target).as_ref());
        if let Some(ar) = build.ar(target) {
            need_cmd(ar.as_ref());
        }
    }
    for host in build.config.host.iter() {
        need_cmd(build.cxx(host).as_ref());
    }

    // Externally configured LLVM requires FileCheck to exist
    let filecheck = build.llvm_filecheck(&build.config.build);
    if !filecheck.starts_with(&build.out) && !filecheck.exists() {
        panic!("filecheck executable {:?} does not exist", filecheck);
    }

    for target in build.config.target.iter() {
        // Either can't build or don't want to run jemalloc on these targets
        if target.contains("rumprun") ||
           target.contains("bitrig") ||
           target.contains("openbsd") ||
           target.contains("msvc") {
            build.config.use_jemalloc = false;
        }

        // Can't compile for iOS unless we're on OSX
        if target.contains("apple-ios") &&
           !build.config.build.contains("apple-darwin") {
            panic!("the iOS target is only supported on OSX");
        }

        // Make sure musl-root is valid if specified
        if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
            match build.config.musl_root {
                Some(ref root) => {
                    if fs::metadata(root.join("lib/libc.a")).is_err() {
                        panic!("couldn't find libc.a in musl dir: {}",
                               root.join("lib").display());
                    }
                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
                        panic!("couldn't find libunwind.a in musl dir: {}",
                               root.join("lib").display());
                    }
                }
                None => {
                    panic!("when targeting MUSL the build.musl-root option \
                            must be specified in config.toml")
                }
            }
        }

        if target.contains("msvc") {
            // There are three builds of cmake on windows: MSVC, MinGW, and
            // Cygwin. The Cygwin build does not have generators for Visual
            // Studio, so detect that here and error.
            let out = output(Command::new("cmake").arg("--help"));
            if !out.contains("Visual Studio") {
                panic!("
cmake does not support Visual Studio generators.

This is likely due to it being an msys/cygwin build of cmake,
rather than the required windows version, built using MinGW
or Visual Studio.

If you are building under msys2 try installing the mingw-w64-x86_64-cmake
package instead of cmake:

$ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
");
            }
        }

        if target.contains("arm-linux-android") {
            need_cmd("adb".as_ref());
        }
    }

    for host in build.flags.host.iter() {
        if !build.config.host.contains(host) {
            panic!("specified host `{}` is not in the ./configure list", host);
        }
    }
    for target in build.flags.target.iter() {
        if !build.config.target.contains(target) {
            panic!("specified target `{}` is not in the ./configure list",
                   target);
        }
    }

    let run = |cmd: &mut Command| {
        cmd.output().map(|output| {
            String::from_utf8_lossy(&output.stdout)
                   .lines().next().unwrap()
                   .to_string()
        })
    };
    build.gdb_version = run(Command::new("gdb").arg("--version")).ok();
    build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
    if build.lldb_version.is_some() {
        build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
    }
}
<commit_msg>Auto merge of #35117 - aravind-pg:path, r=alexcrichton<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.

//! Sanity checking performed by rustbuild before actually executing anything.
//!
//! This module contains the implementation of ensuring that the build
//! environment looks reasonable before progressing. This will verify that
//! various programs like git and python exist, along with ensuring that all C
//! compilers for cross-compiling are found.
//!
//! In theory if we get past this phase it's a bug if a build fails, but in
//! practice that's likely not true!

use std::collections::HashSet;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::process::Command;

use build_helper::output;

use Build;

pub fn check(build: &mut Build) {
    let mut checked = HashSet::new();
    let path = env::var_os("PATH").unwrap_or(OsString::new());
    // On Windows, quotes are invalid characters for filename paths, and if
    // one is present as part of the PATH then that can lead to the system
    // being unable to identify the files properly. See
    // https://github.com/rust-lang/rust/issues/34959 for more details.
    if cfg!(windows) {
        if path.to_string_lossy().contains("\"") {
            panic!("PATH contains invalid character '\"'");
        }
    }
    let mut need_cmd = |cmd: &OsStr| {
        if !checked.insert(cmd.to_owned()) {
            return
        }
        for path in env::split_paths(&path).map(|p| p.join(cmd)) {
            if fs::metadata(&path).is_ok() ||
               fs::metadata(path.with_extension("exe")).is_ok() {
                return
            }
        }
        panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
    };

    // If we've got a git directory we're gona need git to update
    // submodules and learn about various other aspects.
    if fs::metadata(build.src.join(".git")).is_ok() {
        need_cmd("git".as_ref());
    }

    // We need cmake, but only if we're actually building LLVM
    for host in build.config.host.iter() {
        if let Some(config) = build.config.target_config.get(host) {
            if config.llvm_config.is_some() {
                continue
            }
        }
        need_cmd("cmake".as_ref());
        if build.config.ninja {
            need_cmd("ninja".as_ref())
        }
        break
    }

    need_cmd("python".as_ref());

    // We're gonna build some custom C code here and there, host triples
    // also build some C++ shims for LLVM so we need a C++ compiler.
    for target in build.config.target.iter() {
        need_cmd(build.cc(target).as_ref());
        if let Some(ar) = build.ar(target) {
            need_cmd(ar.as_ref());
        }
    }
    for host in build.config.host.iter() {
        need_cmd(build.cxx(host).as_ref());
    }

    // Externally configured LLVM requires FileCheck to exist
    let filecheck = build.llvm_filecheck(&build.config.build);
    if !filecheck.starts_with(&build.out) && !filecheck.exists() {
        panic!("filecheck executable {:?} does not exist", filecheck);
    }

    for target in build.config.target.iter() {
        // Either can't build or don't want to run jemalloc on these targets
        if target.contains("rumprun") ||
           target.contains("bitrig") ||
           target.contains("openbsd") ||
           target.contains("msvc") {
            build.config.use_jemalloc = false;
        }

        // Can't compile for iOS unless we're on OSX
        if target.contains("apple-ios") &&
           !build.config.build.contains("apple-darwin") {
            panic!("the iOS target is only supported on OSX");
        }

        // Make sure musl-root is valid if specified
        if target.contains("musl") && (target.contains("x86_64") || target.contains("i686")) {
            match build.config.musl_root {
                Some(ref root) => {
                    if fs::metadata(root.join("lib/libc.a")).is_err() {
                        panic!("couldn't find libc.a in musl dir: {}",
                               root.join("lib").display());
                    }
                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
                        panic!("couldn't find libunwind.a in musl dir: {}",
                               root.join("lib").display());
                    }
                }
                None => {
                    panic!("when targeting MUSL the build.musl-root option \
                            must be specified in config.toml")
                }
            }
        }

        if target.contains("msvc") {
            // There are three builds of cmake on windows: MSVC, MinGW, and
            // Cygwin. The Cygwin build does not have generators for Visual
            // Studio, so detect that here and error.
            let out = output(Command::new("cmake").arg("--help"));
            if !out.contains("Visual Studio") {
                panic!("
cmake does not support Visual Studio generators.

This is likely due to it being an msys/cygwin build of cmake,
rather than the required windows version, built using MinGW
or Visual Studio.

If you are building under msys2 try installing the mingw-w64-x86_64-cmake
package instead of cmake:

$ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
");
            }
        }

        if target.contains("arm-linux-android") {
            need_cmd("adb".as_ref());
        }
    }

    for host in build.flags.host.iter() {
        if !build.config.host.contains(host) {
            panic!("specified host `{}` is not in the ./configure list", host);
        }
    }
    for target in build.flags.target.iter() {
        if !build.config.target.contains(target) {
            panic!("specified target `{}` is not in the ./configure list",
                   target);
        }
    }

    let run = |cmd: &mut Command| {
        cmd.output().map(|output| {
            String::from_utf8_lossy(&output.stdout)
                   .lines().next().unwrap()
                   .to_string()
        })
    };
    build.gdb_version = run(Command::new("gdb").arg("--version")).ok();
    build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
    if build.lldb_version.is_some() {
        build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
    }
}
<|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.

//! Sanity checking performed by rustbuild before actually executing anything.
//!
//! This module contains the implementation of ensuring that the build
//! environment looks reasonable before progressing. This will verify that
//! various programs like git and python exist, along with ensuring that all C
//! compilers for cross-compiling are found.
//!
//! In theory if we get past this phase it's a bug if a build fails, but in
//! practice that's likely not true!

use std::collections::HashSet;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::process::Command;

use build_helper::output;

use Build;

pub fn check(build: &mut Build) {
    let mut checked = HashSet::new();
    let path = env::var_os("PATH").unwrap_or(OsString::new());
    // On Windows, quotes are invalid characters for filename paths, and if
    // one is present as part of the PATH then that can lead to the system
    // being unable to identify the files properly. See
    // https://github.com/rust-lang/rust/issues/34959 for more details.
    if cfg!(windows) {
        if path.to_string_lossy().contains("\"") {
            panic!("PATH contains invalid character '\"'");
        }
    }
    let have_cmd = |cmd: &OsStr| {
        for path in env::split_paths(&path) {
            let target = path.join(cmd);
            let mut cmd_alt = cmd.to_os_string();
            cmd_alt.push(".exe");
            if target.is_file() ||
               target.with_extension("exe").exists() ||
               target.join(cmd_alt).exists() {
                return Some(target);
            }
        }
        return None;
    };

    let mut need_cmd = |cmd: &OsStr| {
        if !checked.insert(cmd.to_owned()) {
            return
        }
        if have_cmd(cmd).is_none() {
            panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
        }
    };

    // If we've got a git directory we're gona need git to update
    // submodules and learn about various other aspects.
    if build.src_is_git {
        need_cmd("git".as_ref());
    }

    // We need cmake, but only if we're actually building LLVM
    for host in build.config.host.iter() {
        if let Some(config) = build.config.target_config.get(host) {
            if config.llvm_config.is_some() {
                continue
            }
        }
        need_cmd("cmake".as_ref());
        if build.config.ninja {
            // Some Linux distros rename `ninja` to `ninja-build`.
            // CMake can work with either binary name.
            if have_cmd("ninja-build".as_ref()).is_none() {
                need_cmd("ninja".as_ref());
            }
        }
        break
    }

    if build.config.python.is_none() {
        build.config.python = have_cmd("python2.7".as_ref());
    }
    if build.config.python.is_none() {
        build.config.python = have_cmd("python2".as_ref());
    }
    if build.config.python.is_none() {
        need_cmd("python".as_ref());
        build.config.python = Some("python".into());
    }
    need_cmd(build.config.python.as_ref().unwrap().as_ref());

    if let Some(ref s) = build.config.nodejs {
        need_cmd(s.as_ref());
    } else {
        // Look for the nodejs command, needed for emscripten testing
        if let Some(node) = have_cmd("node".as_ref()) {
            build.config.nodejs = Some(node);
        } else if let Some(node) = have_cmd("nodejs".as_ref()) {
            build.config.nodejs = Some(node);
        }
    }

    if let Some(ref gdb) = build.config.gdb {
        need_cmd(gdb.as_ref());
    } else {
        build.config.gdb = have_cmd("gdb".as_ref());
    }

    // We're gonna build some custom C code here and there, host triples
    // also build some C++ shims for LLVM so we need a C++ compiler.
    for target in build.config.target.iter() {
        // On emscripten we don't actually need the C compiler to just
        // build the target artifacts, only for testing. For the sake
        // of easier bot configuration, just skip detection.
        if target.contains("emscripten") {
            continue;
        }

        need_cmd(build.cc(target).as_ref());
        if let Some(ar) = build.ar(target) {
            need_cmd(ar.as_ref());
        }
    }
    for host in build.config.host.iter() {
        need_cmd(build.cxx(host).as_ref());
    }

    // The msvc hosts don't use jemalloc, turn it off globally to
    // avoid packaging the dummy liballoc_jemalloc on that platform.
    for host in build.config.host.iter() {
        if host.contains("msvc") {
            build.config.use_jemalloc = false;
        }
    }

    // Externally configured LLVM requires FileCheck to exist
    let filecheck = build.llvm_filecheck(&build.config.build);
    if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
        panic!("FileCheck executable {:?} does not exist", filecheck);
    }

    for target in build.config.target.iter() {
        // Can't compile for iOS unless we're on macOS
        if target.contains("apple-ios") &&
           !build.config.build.contains("apple-darwin") {
            panic!("the iOS target is only supported on macOS");
        }

        // Make sure musl-root is valid if specified
        if target.contains("musl") && !target.contains("mips") {
            match build.musl_root(target) {
                Some(root) => {
                    if fs::metadata(root.join("lib/libc.a")).is_err() {
                        panic!("couldn't find libc.a in musl dir: {}",
                               root.join("lib").display());
                    }
                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
                        panic!("couldn't find libunwind.a in musl dir: {}",
                               root.join("lib").display());
                    }
                }
                None => {
                    panic!("when targeting MUSL either the rust.musl-root \
                            option or the target.$TARGET.musl-root option must \
                            be specified in config.toml")
                }
            }
        }

        if target.contains("msvc") {
            // There are three builds of cmake on windows: MSVC, MinGW, and
            // Cygwin. The Cygwin build does not have generators for Visual
            // Studio, so detect that here and error.
            let out = output(Command::new("cmake").arg("--help"));
            if !out.contains("Visual Studio") {
                panic!("
cmake does not support Visual Studio generators.

This is likely due to it being an msys/cygwin build of cmake,
rather than the required windows version, built using MinGW
or Visual Studio.

If you are building under msys2 try installing the mingw-w64-x86_64-cmake
package instead of cmake:

$ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
");
            }
        }
    }

    for host in build.flags.host.iter() {
        if !build.config.host.contains(host) {
            panic!("specified host `{}` is not in the ./configure list", host);
        }
    }
    for target in build.flags.target.iter() {
        if !build.config.target.contains(target) {
            panic!("specified target `{}` is not in the ./configure list",
                   target);
        }
    }

    let run = |cmd: &mut Command| {
        cmd.output().map(|output| {
            String::from_utf8_lossy(&output.stdout)
                   .lines().next().unwrap()
                   .to_string()
        })
    };
    build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
    if build.lldb_version.is_some() {
        build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
    }

    if let Some(ref s) = build.config.ccache {
        need_cmd(s.as_ref());
    }
}
<commit_msg>rustbuild: Sanity-check cmake for sanitizers too<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.

//! Sanity checking performed by rustbuild before actually executing anything.
//!
//! This module contains the implementation of ensuring that the build
//! environment looks reasonable before progressing. This will verify that
//! various programs like git and python exist, along with ensuring that all C
//! compilers for cross-compiling are found.
//!
//! In theory if we get past this phase it's a bug if a build fails, but in
//! practice that's likely not true!

use std::collections::HashSet;
use std::env;
use std::ffi::{OsStr, OsString};
use std::fs;
use std::process::Command;

use build_helper::output;

use Build;

pub fn check(build: &mut Build) {
    let mut checked = HashSet::new();
    let path = env::var_os("PATH").unwrap_or(OsString::new());
    // On Windows, quotes are invalid characters for filename paths, and if
    // one is present as part of the PATH then that can lead to the system
    // being unable to identify the files properly. See
    // https://github.com/rust-lang/rust/issues/34959 for more details.
    if cfg!(windows) {
        if path.to_string_lossy().contains("\"") {
            panic!("PATH contains invalid character '\"'");
        }
    }
    let have_cmd = |cmd: &OsStr| {
        for path in env::split_paths(&path) {
            let target = path.join(cmd);
            let mut cmd_alt = cmd.to_os_string();
            cmd_alt.push(".exe");
            if target.is_file() ||
               target.with_extension("exe").exists() ||
               target.join(cmd_alt).exists() {
                return Some(target);
            }
        }
        return None;
    };

    let mut need_cmd = |cmd: &OsStr| {
        if !checked.insert(cmd.to_owned()) {
            return
        }
        if have_cmd(cmd).is_none() {
            panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
        }
    };

    // If we've got a git directory we're gona need git to update
    // submodules and learn about various other aspects.
    if build.src_is_git {
        need_cmd("git".as_ref());
    }

    // We need cmake, but only if we're actually building LLVM or sanitizers.
    let building_llvm = build.config.host.iter()
        .filter_map(|host| build.config.target_config.get(host))
        .any(|config| config.llvm_config.is_none());
    if building_llvm || build.config.sanitizers {
        need_cmd("cmake".as_ref());
    }

    // Ninja is currently only used for LLVM itself.
    if building_llvm && build.config.ninja {
        // Some Linux distros rename `ninja` to `ninja-build`.
        // CMake can work with either binary name.
        if have_cmd("ninja-build".as_ref()).is_none() {
            need_cmd("ninja".as_ref());
        }
    }

    if build.config.python.is_none() {
        build.config.python = have_cmd("python2.7".as_ref());
    }
    if build.config.python.is_none() {
        build.config.python = have_cmd("python2".as_ref());
    }
    if build.config.python.is_none() {
        need_cmd("python".as_ref());
        build.config.python = Some("python".into());
    }
    need_cmd(build.config.python.as_ref().unwrap().as_ref());

    if let Some(ref s) = build.config.nodejs {
        need_cmd(s.as_ref());
    } else {
        // Look for the nodejs command, needed for emscripten testing
        if let Some(node) = have_cmd("node".as_ref()) {
            build.config.nodejs = Some(node);
        } else if let Some(node) = have_cmd("nodejs".as_ref()) {
            build.config.nodejs = Some(node);
        }
    }

    if let Some(ref gdb) = build.config.gdb {
        need_cmd(gdb.as_ref());
    } else {
        build.config.gdb = have_cmd("gdb".as_ref());
    }

    // We're gonna build some custom C code here and there, host triples
    // also build some C++ shims for LLVM so we need a C++ compiler.
    for target in build.config.target.iter() {
        // On emscripten we don't actually need the C compiler to just
        // build the target artifacts, only for testing. For the sake
        // of easier bot configuration, just skip detection.
        if target.contains("emscripten") {
            continue;
        }

        need_cmd(build.cc(target).as_ref());
        if let Some(ar) = build.ar(target) {
            need_cmd(ar.as_ref());
        }
    }
    for host in build.config.host.iter() {
        need_cmd(build.cxx(host).as_ref());
    }

    // The msvc hosts don't use jemalloc, turn it off globally to
    // avoid packaging the dummy liballoc_jemalloc on that platform.
    for host in build.config.host.iter() {
        if host.contains("msvc") {
            build.config.use_jemalloc = false;
        }
    }

    // Externally configured LLVM requires FileCheck to exist
    let filecheck = build.llvm_filecheck(&build.config.build);
    if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests {
        panic!("FileCheck executable {:?} does not exist", filecheck);
    }

    for target in build.config.target.iter() {
        // Can't compile for iOS unless we're on macOS
        if target.contains("apple-ios") &&
           !build.config.build.contains("apple-darwin") {
            panic!("the iOS target is only supported on macOS");
        }

        // Make sure musl-root is valid if specified
        if target.contains("musl") && !target.contains("mips") {
            match build.musl_root(target) {
                Some(root) => {
                    if fs::metadata(root.join("lib/libc.a")).is_err() {
                        panic!("couldn't find libc.a in musl dir: {}",
                               root.join("lib").display());
                    }
                    if fs::metadata(root.join("lib/libunwind.a")).is_err() {
                        panic!("couldn't find libunwind.a in musl dir: {}",
                               root.join("lib").display());
                    }
                }
                None => {
                    panic!("when targeting MUSL either the rust.musl-root \
                            option or the target.$TARGET.musl-root option must \
                            be specified in config.toml")
                }
            }
        }

        if target.contains("msvc") {
            // There are three builds of cmake on windows: MSVC, MinGW, and
            // Cygwin. The Cygwin build does not have generators for Visual
            // Studio, so detect that here and error.
            let out = output(Command::new("cmake").arg("--help"));
            if !out.contains("Visual Studio") {
                panic!("
cmake does not support Visual Studio generators.

This is likely due to it being an msys/cygwin build of cmake,
rather than the required windows version, built using MinGW
or Visual Studio.

If you are building under msys2 try installing the mingw-w64-x86_64-cmake
package instead of cmake:

$ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
");
            }
        }
    }

    for host in build.flags.host.iter() {
        if !build.config.host.contains(host) {
            panic!("specified host `{}` is not in the ./configure list", host);
        }
    }
    for target in build.flags.target.iter() {
        if !build.config.target.contains(target) {
            panic!("specified target `{}` is not in the ./configure list",
                   target);
        }
    }

    let run = |cmd: &mut Command| {
        cmd.output().map(|output| {
            String::from_utf8_lossy(&output.stdout)
                   .lines().next().unwrap()
                   .to_string()
        })
    };
    build.lldb_version = run(Command::new("lldb").arg("--version")).ok();
    if build.lldb_version.is_some() {
        build.lldb_python_dir = run(Command::new("lldb").arg("-P")).ok();
    }

    if let Some(ref s) = build.config.ccache {
        need_cmd(s.as_ref());
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test case for wasm non-clash.<commit_after>// check-pass
#![crate_type = "lib"]

#[cfg(target_arch = "wasm32")]
mod wasm_non_clash {
    mod a {
        #[link(wasm_import_module = "a")]
        extern "C" {
            pub fn foo();
        }
    }

    mod b {
        #[link(wasm_import_module = "b")]
        extern "C" {
            pub fn foo() -> usize;
            // #79581: These declarations shouldn't clash because foreign fn names are mangled
            // on wasm32.
        }
    }
}
<|endoftext|>


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

use compositing::resize_rate_limiter::ResizeRateLimiter;
use dom::event::Event;
use platform::{Application, Window};

use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
use core::cell::Cell;
use core::comm::{Chan, SharedChan, Port};
use core::util;
use geom::matrix::identity;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::compositor::{Compositor, LayerBuffer, LayerBufferSet};
use gfx::opts::Opts;
use layers;
use servo_util::time;

mod resize_rate_limiter;

/// Type of the function that is called when the screen is to be redisplayed.
pub type CompositeCallback = @fn();

/// Type of the function that is called when the window is resized.
pub type ResizeCallback = @fn(uint, uint);

/// The implementation of the layers-based compositor.
#[deriving(Clone)]
pub struct CompositorImpl {
    chan: SharedChan<Msg>
}

impl CompositorImpl {
    /// Creates a new compositor instance.
    pub fn new(dom_event_chan: SharedChan<Event>, opts: Opts) -> CompositorImpl {
        let dom_event_chan = Cell(dom_event_chan);
        let chan: Chan<Msg> = do on_osmain |port| {
            debug!("preparing to enter main loop");
            mainloop(port, dom_event_chan.take(), &opts);
        };

        CompositorImpl {
            chan: SharedChan::new(chan)
        }
    }
}

/// Messages to the compositor.
pub enum Msg {
    BeginDrawing(Chan<LayerBufferSet>),
    Draw(Chan<LayerBufferSet>, LayerBufferSet),
    AddKeyHandler(Chan<()>),
    Exit
}

/// Azure surface wrapping to work with the layers infrastructure.
struct AzureDrawTargetImageData {
    draw_target: DrawTarget,
    data_source_surface: DataSourceSurface,
    size: Size2D<uint>
}

impl layers::layers::ImageData for AzureDrawTargetImageData {
    fn size(&self) -> Size2D<uint> {
        self.size
    }
    fn stride(&self) -> uint {
        self.data_source_surface.stride() as uint
    }
    fn format(&self) -> layers::layers::Format {
        // FIXME: This is not always correct. We should query the Azure draw target for the format.
        layers::layers::ARGB32Format
    }
    fn with_data(&self, f: layers::layers::WithDataFn) {
        do self.data_source_surface.with_data |data| {
            f(data);
        }
    }
}

fn mainloop(po: Port<Msg>, dom_event_chan: SharedChan<Event>, opts: &Opts) {
    let key_handlers: @mut ~[Chan<()>] = @mut ~[];

    let app = Application::new();
    let window = Window::new(&app);

    let surfaces = @mut SurfaceSet(opts.render_backend);

    let context = layers::rendergl::init_render_context();

    // Create an initial layer tree.
    //
    // TODO: There should be no initial layer tree until the renderer creates one from the display
    // list. This is only here because we don't have that logic in the renderer yet.
    let root_layer = @mut layers::layers::ContainerLayer();
    let original_layer_transform;
    {
        let image_data = @layers::layers::BasicImageData::new(Size2D(0u, 0u),
                                                              0,
                                                              layers::layers::RGB24Format,
                                                              ~[]);
        let image = @mut layers::layers::Image::new(image_data as @layers::layers::ImageData);
        let image_layer = @mut layers::layers::ImageLayer(image);
        original_layer_transform = image_layer.common.transform;
        image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
        root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
    }

    let scene = @mut layers::scene::Scene(layers::layers::ContainerLayerKind(root_layer),
                                          Size2D(800.0, 600.0),
                                          identity());

    let done = @mut false;
    let resize_rate_limiter = @mut ResizeRateLimiter(dom_event_chan);
    let check_for_messages: @fn() = || {
        // Periodically check if content responded to our last resize event
        resize_rate_limiter.check_resize_response();

        // Handle messages
        while po.peek() {
            match po.recv() {
                AddKeyHandler(key_ch) => key_handlers.push(key_ch),
                BeginDrawing(sender) => lend_surface(surfaces, sender),
                Draw(sender, draw_target) => {
                    debug!("osmain: received new frame");
                    return_surface(surfaces, draw_target);
                    lend_surface(surfaces, sender);

                    // Iterate over the children of the container layer.
                    let mut current_layer_child = root_layer.first_child;

                    // Replace the image layer data with the buffer data.
                    let buffers = util::replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]);
                    for buffers.each |buffer| {
                        let width = buffer.rect.size.width as uint;
                        let height = buffer.rect.size.height as uint;

                        debug!("osmain: compositing buffer rect %?", &buffer.rect);

                        let image_data = @AzureDrawTargetImageData {
                            draw_target: buffer.draw_target.clone(),
                            data_source_surface: buffer.draw_target.snapshot().get_data_surface(),
                            size: Size2D(width, height)
                        };
                        let image = @mut layers::layers::Image::new(image_data as @layers::layers::ImageData);

                        // Find or create an image layer.
                        let image_layer;
                        current_layer_child = match current_layer_child {
                            None => {
                                debug!("osmain: adding new image layer");
                                image_layer = @mut layers::layers::ImageLayer(image);
                                root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
                                None
                            }
                            Some(layers::layers::ImageLayerKind(existing_image_layer)) => {
                                image_layer = existing_image_layer;
                                image_layer.set_image(image);

                                // Move on to the next sibling.
                                do current_layer_child.get().with_common |common| {
                                    common.next_sibling
                                }
                            }
                            Some(_) => fail!(~"found unexpected layer kind"),
                        };

                        // Set the layer's transform.
                        let x = buffer.rect.origin.x as f32;
                        let y = buffer.rect.origin.y as f32;
                        image_layer.common.set_transform(
                            original_layer_transform.translate(x, y, 0.0)
                                .scale(width as f32, height as f32, 1.0));
                    }
                    surfaces.front.layer_buffer_set.buffers = buffers;
                }
                Exit => {
                    *done = true;
                }
            }
        }
    };

    do window.set_composite_callback {
        do time::time(~"compositing") {
            // Adjust the layer dimensions as necessary to correspond to the size of the window.
            scene.size = window.size();

            // Render the scene.
            layers::rendergl::render_scene(context, scene);
        }

        window.present();
    }

    do window.set_resize_callback |width, height| {
        debug!("osmain: window resized to %ux%u", width, height);
        resize_rate_limiter.window_resized(width, height);
    }

    // Enter the main event loop.
    while !*done {
        // Check for new messages coming from the rendering task.
        check_for_messages();

        // Check for messages coming from the windowing system.
        window.check_loop();
    }
}

/// Implementation of the abstract `Compositor` interface.
impl Compositor for CompositorImpl {
    fn begin_drawing(&self, next_dt: Chan<LayerBufferSet>) {
        self.chan.send(BeginDrawing(next_dt))
    }
    fn draw(&self, next_dt: Chan<LayerBufferSet>, draw_me: LayerBufferSet) {
        self.chan.send(Draw(next_dt, draw_me))
    }
}

struct SurfaceSet {
    front: Surface,
    back: Surface,
}

fn lend_surface(surfaces: &mut SurfaceSet, receiver: Chan<LayerBufferSet>) {
    // We are in a position to lend out the surface?
    assert!(surfaces.front.have);
    // Ok then take it
    let old_layer_buffers = util::replace(&mut surfaces.front.layer_buffer_set.buffers, ~[]);
    let new_layer_buffers = do old_layer_buffers.map |layer_buffer| {
        let draw_target_ref = &layer_buffer.draw_target;
        let layer_buffer = LayerBuffer {
            draw_target: draw_target_ref.clone(),
            rect: copy layer_buffer.rect,
            stride: layer_buffer.stride
        };
        debug!("osmain: lending surface %?", layer_buffer);
        layer_buffer
    };
    surfaces.front.layer_buffer_set.buffers = old_layer_buffers;

    let new_layer_buffer_set = LayerBufferSet { buffers: new_layer_buffers };
    receiver.send(new_layer_buffer_set);
    // Now we don't have it
    surfaces.front.have = false;
    // But we (hopefully) have another!
    surfaces.front <-> surfaces.back;
    // Let's look
    assert!(surfaces.front.have);
}

fn return_surface(surfaces: &mut SurfaceSet, layer_buffer_set: LayerBufferSet) {
    //#debug("osmain: returning surface %?", layer_buffer_set);
    // We have room for a return
    assert!(surfaces.front.have);
    assert!(!surfaces.back.have);

    surfaces.back.layer_buffer_set = layer_buffer_set;

    // Now we have it again
    surfaces.back.have = true;
}

fn SurfaceSet(backend: BackendType) -> SurfaceSet {
    SurfaceSet { front: Surface(backend), back: Surface(backend) }
}

struct Surface {
    layer_buffer_set: LayerBufferSet,
    have: bool,
}

fn Surface(backend: BackendType) -> Surface {
    let layer_buffer = LayerBuffer {
        draw_target: DrawTarget::new(backend, Size2D(800i32, 600i32), B8G8R8A8),
        rect: Rect(Point2D(0u, 0u), Size2D(800u, 600u)),
        stride: 800 * 4
    };
    let layer_buffer_set = LayerBufferSet {
        buffers: ~[ layer_buffer ]
    };
    Surface {
        layer_buffer_set: layer_buffer_set,
        have: true
    }
}

/// A function for spawning into the platform's main thread.
fn on_osmain<T: Owned>(f: ~fn(po: Port<T>)) -> Chan<T> {
    let (setup_po, setup_ch) = comm::stream();
    do task::task().sched_mode(task::PlatformThread).spawn {
        let (po, ch) = comm::stream();
        setup_ch.send(ch);
        f(po);
    }
    setup_po.recv()
}

<|endoftext|>


<commit_before><commit_msg>Added missing #[macro_export] directive<commit_after><|endoftext|>


<commit_before><commit_msg>Implement NormalizedSurfaceMesh<commit_after><|endoftext|>


<commit_before>// -*- rust -*-

use std;
import std.map;
import std.util;

fn test_simple() {
  log "*** starting test_simple";

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // FIXME: can't use std.util.id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  check (hm.insert(10u, 12u));
  check (hm.insert(11u, 13u));
  check (hm.insert(12u, 14u));

  check (hm.get(11u) == 13u);
  check (hm.get(12u) == 14u);
  check (hm.get(10u) == 12u);

  check (!hm.insert(12u, 14u));
  check (hm.get(12u) == 14u);

  check (!hm.insert(12u, 12u));
  check (hm.get(12u) == 12u);

  log "*** finished test_simple";
}

/**
 * Force map growth and rehashing.
 */
fn test_growth() {
  log "*** starting test_growth";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // FIXME: can't use std.util.id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  check (hm.insert(num_to_insert, 17u));
  check (hm.get(num_to_insert) == 17u);

  log "-----";

  hm.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_growth";
}

fn test_removal() {
  log "*** starting test_removal";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // This hash function intentionally causes collisions between
    // consecutive integer pairs.
    ret (u / 2u) * 2u;
  }

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 1u;
  }

  check (hm.size() == num_to_insert);

  log "-----";
  log "removing evens";

  i = 0u;
  while (i < num_to_insert) {
    /**
     * FIXME (issue #150): we want to check the removed value as in the
     * following:

    let util.option[uint] v = hm.remove(i);
    alt (v) {
      case (util.some[uint](u)) {
        check (u == (i * i));
      }
      case (util.none[uint]()) { fail; }
    }

     * but we util.option is a tag type so util.some and util.none are
     * off limits until we parse the dwarf for tag types.
     */

    hm.remove(i);
    i += 2u;
  }

  check (hm.size() == (num_to_insert / 2u));

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 2u;
  }

  check (hm.size() == num_to_insert);

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  check (hm.size() == num_to_insert);

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_removal";
}

fn main() {
  test_simple();
  test_growth();
  test_removal();
}
<commit_msg>Pinching myself for certainty. ;p<commit_after>// -*- rust -*-

use std;
import std.map;
import std.util;

fn test_simple() {
  log "*** starting test_simple";

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // FIXME: can't use std.util.id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  check (hm.insert(10u, 12u));
  check (hm.insert(11u, 13u));
  check (hm.insert(12u, 14u));

  check (hm.get(11u) == 13u);
  check (hm.get(12u) == 14u);
  check (hm.get(10u) == 12u);

  check (!hm.insert(12u, 14u));
  check (hm.get(12u) == 14u);

  check (!hm.insert(12u, 12u));
  check (hm.get(12u) == 12u);

  log "*** finished test_simple";
}

/**
 * Force map growth and rehashing.
 */
fn test_growth() {
  log "*** starting test_growth";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // FIXME: can't use std.util.id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  check (hm.insert(num_to_insert, 17u));
  check (hm.get(num_to_insert) == 17u);

  log "-----";

  hm.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_growth";
}

fn test_removal() {
  log "*** starting test_removal";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // This hash function intentionally causes collisions between
    // consecutive integer pairs.
    ret (u / 2u) * 2u;
  }

  check (hash(0u) == hash(1u));
  check (hash(2u) == hash(3u));
  check (hash(0u) != hash(2u));

  let map.hashfn[uint] hasher = hash;
  let map.eqfn[uint] eqer = eq;
  let map.hashmap[uint, uint] hm = map.mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 1u;
  }

  check (hm.size() == num_to_insert);

  log "-----";
  log "removing evens";

  i = 0u;
  while (i < num_to_insert) {
    /**
     * FIXME (issue #150): we want to check the removed value as in the
     * following:

    let util.option[uint] v = hm.remove(i);
    alt (v) {
      case (util.some[uint](u)) {
        check (u == (i * i));
      }
      case (util.none[uint]()) { fail; }
    }

     * but we util.option is a tag type so util.some and util.none are
     * off limits until we parse the dwarf for tag types.
     */

    hm.remove(i);
    i += 2u;
  }

  check (hm.size() == (num_to_insert / 2u));

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    check (hm.insert(i, i * i));
    log "inserting " + std._uint.to_str(i, 10u)
      + " -> " + std._uint.to_str(i * i, 10u);
    i += 2u;
  }

  check (hm.size() == num_to_insert);

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  check (hm.size() == num_to_insert);

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + std._uint.to_str(i, 10u) + ") = "
      + std._uint.to_str(hm.get(i), 10u);
    check (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_removal";
}

fn main() {
  test_simple();
  test_growth();
  test_removal();
}
<|endoftext|>


<commit_before>// xfail-stage0

use std;
import std::str;

fn test_bytes_len() {
  assert (str::byte_len("") == 0u);
  assert (str::byte_len("hello world") == 11u);
  assert (str::byte_len("\x63") == 1u);
  assert (str::byte_len("\xa2") == 2u);
  assert (str::byte_len("\u03c0") == 2u);
  assert (str::byte_len("\u2620") == 3u);
  assert (str::byte_len("\U0001d11e") == 4u);
}

fn test_index_and_rindex() {
  assert (str::index("hello", 'e' as u8) == 1);
  assert (str::index("hello", 'o' as u8) == 4);
  assert (str::index("hello", 'z' as u8) == -1);
  assert (str::rindex("hello", 'l' as u8) == 3);
  assert (str::rindex("hello", 'h' as u8) == 0);
  assert (str::rindex("hello", 'z' as u8) == -1);
}

fn test_split() {
  fn t(&str s, char c, int i, &str k) {
    log "splitting: " + s;
    log i;
    auto v = str::split(s, c as u8);
    log "split to: ";
    for (str z in v) {
      log z;
    }
    log "comparing: " + v.(i) + " vs. " + k;
    assert (str::eq(v.(i), k));
  }
  t("abc.hello.there", '.', 0, "abc");
  t("abc.hello.there", '.', 1, "hello");
  t("abc.hello.there", '.', 2, "there");
  t(".hello.there", '.', 0, "");
  t(".hello.there", '.', 1, "hello");
  t("...hello.there.", '.', 3, "hello");
  t("...hello.there.", '.', 5, "");
}

fn test_find() {
  fn t(&str haystack, &str needle, int i) {
    let int j = str::find(haystack,needle);
    log "searched for " + needle;
    log j;
    assert (i == j);
  }
  t("this is a simple", "is a", 5);
  t("this is a simple", "is z", -1);
  t("this is a simple", "", 0);
  t("this is a simple", "simple", 10);
  t("this", "simple", -1);
}

fn test_substr() {
  fn t(&str a, &str b, int start) {
    assert (str::eq(str::substr(a, start as uint,
                              str::byte_len(b)), b));
  }

  t("hello", "llo", 2);
  t("hello", "el", 1);
  t("substr should not be a challenge", "not", 14);
}

fn test_concat() {
  fn t(&vec[str] v, &str s) {
    assert (str::eq(str::concat(v), s));
  }

  t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
  let vec[str] v = [];
  t(v, "");
  t(["hi"], "hi");
}

fn test_connect() {
  fn t(&vec[str] v, &str sep, &str s) {
    assert (str::eq(str::connect(v, sep), s));
  }

  t(["you", "know", "I'm", "no", "good"], " ", "you know I'm no good");
  let vec[str] v = [];
  t(v, " ", "");
  t(["hi"], " ", "hi");
}

fn test_to_upper() {
  // to_upper doesn't understand unicode yet,
  // but we need to at least preserve it
  auto unicode = "\u65e5\u672c";
  auto input = "abcDEF" + unicode + "xyz:.;";
  auto expected = "ABCDEF" + unicode + "XYZ:.;";
  auto actual = str::to_upper(input);
  assert (str::eq(expected, actual));
}

fn test_slice() {
  assert (str::eq("ab", str::slice("abc", 0u, 2u)));
  assert (str::eq("bc", str::slice("abc", 1u, 3u)));
  assert (str::eq("", str::slice("abc", 1u, 1u)));

  fn a_million_letter_a() -> str {
    auto i = 0;
    auto res = "";
    while (i < 100000) {
      res += "aaaaaaaaaa";
      i += 1;
    }
    ret res;
  }

  fn half_a_million_letter_a() -> str {
    auto i = 0;
    auto res = "";
    while (i < 100000) {
      res += "aaaaa";
      i += 1;
    }
    ret res;
  }

  assert (str::eq(half_a_million_letter_a(),
                 str::slice(a_million_letter_a(),
                           0u,
                           500000u)));
}

fn main() {
  test_bytes_len();
  test_index_and_rindex();
  test_split();
  test_find();
  test_substr();
  test_concat();
  test_connect();
  test_to_upper();
  test_slice();
}
<commit_msg>stdlib: Add regression tests for std::str<commit_after>// xfail-stage0

use std;
import std::str;

fn test_bytes_len() {
  assert (str::byte_len("") == 0u);
  assert (str::byte_len("hello world") == 11u);
  assert (str::byte_len("\x63") == 1u);
  assert (str::byte_len("\xa2") == 2u);
  assert (str::byte_len("\u03c0") == 2u);
  assert (str::byte_len("\u2620") == 3u);
  assert (str::byte_len("\U0001d11e") == 4u);
}

fn test_index_and_rindex() {
  assert (str::index("hello", 'e' as u8) == 1);
  assert (str::index("hello", 'o' as u8) == 4);
  assert (str::index("hello", 'z' as u8) == -1);
  assert (str::rindex("hello", 'l' as u8) == 3);
  assert (str::rindex("hello", 'h' as u8) == 0);
  assert (str::rindex("hello", 'z' as u8) == -1);
}

fn test_split() {
  fn t(&str s, char c, int i, &str k) {
    log "splitting: " + s;
    log i;
    auto v = str::split(s, c as u8);
    log "split to: ";
    for (str z in v) {
      log z;
    }
    log "comparing: " + v.(i) + " vs. " + k;
    assert (str::eq(v.(i), k));
  }
  t("abc.hello.there", '.', 0, "abc");
  t("abc.hello.there", '.', 1, "hello");
  t("abc.hello.there", '.', 2, "there");
  t(".hello.there", '.', 0, "");
  t(".hello.there", '.', 1, "hello");
  t("...hello.there.", '.', 3, "hello");
  t("...hello.there.", '.', 5, "");
}

fn test_find() {
  fn t(&str haystack, &str needle, int i) {
    let int j = str::find(haystack,needle);
    log "searched for " + needle;
    log j;
    assert (i == j);
  }
  t("this is a simple", "is a", 5);
  t("this is a simple", "is z", -1);
  t("this is a simple", "", 0);
  t("this is a simple", "simple", 10);
  t("this", "simple", -1);
}

fn test_substr() {
  fn t(&str a, &str b, int start) {
    assert (str::eq(str::substr(a, start as uint,
                              str::byte_len(b)), b));
  }

  t("hello", "llo", 2);
  t("hello", "el", 1);
  t("substr should not be a challenge", "not", 14);
}

fn test_concat() {
  fn t(&vec[str] v, &str s) {
    assert (str::eq(str::concat(v), s));
  }

  t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
  let vec[str] v = [];
  t(v, "");
  t(["hi"], "hi");
}

fn test_connect() {
  fn t(&vec[str] v, &str sep, &str s) {
    assert (str::eq(str::connect(v, sep), s));
  }

  t(["you", "know", "I'm", "no", "good"], " ", "you know I'm no good");
  let vec[str] v = [];
  t(v, " ", "");
  t(["hi"], " ", "hi");
}

fn test_to_upper() {
  // to_upper doesn't understand unicode yet,
  // but we need to at least preserve it
  auto unicode = "\u65e5\u672c";
  auto input = "abcDEF" + unicode + "xyz:.;";
  auto expected = "ABCDEF" + unicode + "XYZ:.;";
  auto actual = str::to_upper(input);
  assert (str::eq(expected, actual));
}

fn test_slice() {
  assert (str::eq("ab", str::slice("abc", 0u, 2u)));
  assert (str::eq("bc", str::slice("abc", 1u, 3u)));
  assert (str::eq("", str::slice("abc", 1u, 1u)));

  fn a_million_letter_a() -> str {
    auto i = 0;
    auto res = "";
    while (i < 100000) {
      res += "aaaaaaaaaa";
      i += 1;
    }
    ret res;
  }

  fn half_a_million_letter_a() -> str {
    auto i = 0;
    auto res = "";
    while (i < 100000) {
      res += "aaaaa";
      i += 1;
    }
    ret res;
  }

  assert (str::eq(half_a_million_letter_a(),
                 str::slice(a_million_letter_a(),
                           0u,
                           500000u)));
}

fn test_ends_with() {
  assert (str::ends_with("", ""));
  assert (str::ends_with("abc", ""));
  assert (str::ends_with("abc", "c"));
  assert (!str::ends_with("a", "abc"));
  assert (!str::ends_with("", "abc"));
}

fn main() {
  test_bytes_len();
  test_index_and_rindex();
  test_split();
  test_find();
  test_substr();
  test_concat();
  test_connect();
  test_to_upper();
  test_slice();
  test_ends_with();
}
<|endoftext|>


<commit_before><commit_msg>enums can be used as functions<commit_after><|endoftext|>