<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 ast;
use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
use codemap::{span, dummy_sp};
use diagnostic::span_handler;
use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
use parse::lexer::TokenAndSpan;

use core::hashmap::HashMap;

///an unzipping of `token_tree`s
struct TtFrame {
    forest: @mut ~[ast::token_tree],
    idx: uint,
    dotdotdoted: bool,
    sep: Option<Token>,
    up: Option<@mut TtFrame>,
}

pub struct TtReader {
    sp_diag: @span_handler,
    interner: @ident_interner,
    // the unzipped tree:
    stack: @mut TtFrame,
    /* for MBE-style macro transcription */
    interpolations: HashMap<ident, @named_match>,
    repeat_idx: ~[uint],
    repeat_len: ~[uint],
    /* cached: */
    cur_tok: Token,
    cur_span: span
}

/** This can do Macro-By-Example transcription. On the other hand, if
 *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
 *  should) be none. */
pub fn new_tt_reader(sp_diag: @span_handler,
                     itr: @ident_interner,
                     interp: Option<HashMap<ident,@named_match>>,
                     src: ~[ast::token_tree])
                  -> @mut TtReader {
    let r = @mut TtReader {
        sp_diag: sp_diag,
        interner: itr,
        stack: @mut TtFrame {
            forest: @mut src,
            idx: 0u,
            dotdotdoted: false,
            sep: None,
            up: option::None
        },
        interpolations: match interp { /* just a convienience */
            None => HashMap::new(),
            Some(x) => x
        },
        repeat_idx: ~[],
        repeat_len: ~[],
        /* dummy values, never read: */
        cur_tok: EOF,
        cur_span: dummy_sp()
    };
    tt_next_token(r); /* get cur_tok and cur_span set up */
    return r;
}

fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
    @mut TtFrame {
        forest: @mut (copy *f.forest),
        idx: f.idx,
        dotdotdoted: f.dotdotdoted,
        sep: copy f.sep,
        up: match f.up {
            Some(up_frame) => Some(dup_tt_frame(up_frame)),
            None => None
        }
    }
}

pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader {
    @mut TtReader {
        sp_diag: r.sp_diag,
        interner: r.interner,
        stack: dup_tt_frame(r.stack),
        repeat_idx: copy r.repeat_idx,
        repeat_len: copy r.repeat_len,
        cur_tok: copy r.cur_tok,
        cur_span: r.cur_span,
        interpolations: copy r.interpolations,
    }
}

fn lookup_cur_matched_by_matched(r: &mut TtReader,
                                      start: @named_match)
                                   -> @named_match {
    fn red(ad: @named_match, idx: &uint) -> @named_match {
        match *ad {
          matched_nonterminal(_) => {
            // end of the line; duplicate henceforth
            ad
          }
          matched_seq(ref ads, _) => ads[*idx]
        }
    }
    let r = &mut *r;
    let repeat_idx = &r.repeat_idx;
    vec::foldl(start, *repeat_idx, red)
}

fn lookup_cur_matched(r: &mut TtReader, name: ident) -> @named_match {
    // FIXME (#3850): this looks a bit silly with an extra scope.
    let start;
    { start = *r.interpolations.get(&name); }
    return lookup_cur_matched_by_matched(r, start);
}
enum lis {
    lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
}

fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
    fn lis_merge(lhs: lis, rhs: lis, r: &mut TtReader) -> lis {
        match lhs {
          lis_unconstrained => copy rhs,
          lis_contradiction(_) => copy lhs,
          lis_constraint(l_len, l_id) => match rhs {
            lis_unconstrained => copy lhs,
            lis_contradiction(_) => copy rhs,
            lis_constraint(r_len, _) if l_len == r_len => copy lhs,
            lis_constraint(r_len, r_id) => {
                let l_n = copy *r.interner.get(l_id);
                let r_n = copy *r.interner.get(r_id);
                lis_contradiction(fmt!("Inconsistent lockstep iteration: \
                                       '%s' has %u items, but '%s' has %u",
                                        l_n, l_len, r_n, r_len))
            }
          }
        }
    }
    match *t {
      tt_delim(ref tts) | tt_seq(_, ref tts, _, _) => {
        vec::foldl(lis_unconstrained, *tts, |lis, tt| {
            let lis2 = lockstep_iter_size(tt, r);
            lis_merge(lis, lis2, r)
        })
      }
      tt_tok(*) => lis_unconstrained,
      tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) {
        matched_nonterminal(_) => lis_unconstrained,
        matched_seq(ref ads, _) => lis_constraint(ads.len(), name)
      }
    }
}

// return the next token from the TtReader.
// EFFECT: advances the reader's token field
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
    let ret_val = TokenAndSpan {
        tok: copy r.cur_tok,
        sp: r.cur_span,
    };
    loop {
        {
            let stack = &mut *r.stack;
            let forest = &mut *stack.forest;
            if stack.idx < forest.len() {
                break;
            }
        }

        /* done with this set; pop or repeat? */
        if ! r.stack.dotdotdoted
            || { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } {

            match r.stack.up {
              None => {
                r.cur_tok = EOF;
                return ret_val;
              }
              Some(tt_f) => {
                if r.stack.dotdotdoted {
                    r.repeat_idx.pop();
                    r.repeat_len.pop();
                }

                r.stack = tt_f;
                r.stack.idx += 1u;
              }
            }

        } else { /* repeat */
            r.stack.idx = 0u;
            r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
            match r.stack.sep {
              Some(copy tk) => {
                r.cur_tok = tk; /* repeat same span, I guess */
                return ret_val;
              }
              None => ()
            }
        }
    }
    loop { /* because it's easiest, this handles `tt_delim` not starting
    with a `tt_tok`, even though it won't happen */
        match r.stack.forest[r.stack.idx] {
          tt_delim(copy tts) => {
            r.stack = @mut TtFrame {
                forest: @mut tts,
                idx: 0u,
                dotdotdoted: false,
                sep: None,
                up: option::Some(r.stack)
            };
            // if this could be 0-length, we'd need to potentially recur here
          }
          tt_tok(sp, copy tok) => {
            r.cur_span = sp;
            r.cur_tok = tok;
            r.stack.idx += 1u;
            return ret_val;
          }
          tt_seq(sp, copy tts, copy sep, zerok) => {
            let t = tt_seq(sp, copy tts, copy sep, zerok);
            match lockstep_iter_size(&t, r) {
              lis_unconstrained => {
                r.sp_diag.span_fatal(
                    sp, /* blame macro writer */
                      "attempted to repeat an expression \
                       containing no syntax \
                       variables matched as repeating at this depth");
                  }
                  lis_contradiction(ref msg) => {
                      /* FIXME #2887 blame macro invoker instead*/
                      r.sp_diag.span_fatal(sp, (*msg));
                  }
                  lis_constraint(len, _) => {
                    if len == 0 {
                      if !zerok {
                        r.sp_diag.span_fatal(sp, /* FIXME #2887 blame invoker
                        */
                                             "this must repeat at least \
                                              once");
                          }

                    r.stack.idx += 1u;
                    return tt_next_token(r);
                } else {
                    r.repeat_len.push(len);
                    r.repeat_idx.push(0u);
                    r.stack = @mut TtFrame {
                        forest: @mut tts,
                        idx: 0u,
                        dotdotdoted: true,
                        sep: sep,
                        up: Some(r.stack)
                    };
                }
              }
            }
          }
          // FIXME #2887: think about span stuff here
          tt_nonterminal(sp, ident) => {
            match *lookup_cur_matched(r, ident) {
              /* sidestep the interpolation tricks for ident because
              (a) idents can be in lots of places, so it'd be a pain
              (b) we actually can, since it's a token. */
              matched_nonterminal(nt_ident(sn,b)) => {
                r.cur_span = sp; r.cur_tok = IDENT(sn,b);
                r.stack.idx += 1u;
                return ret_val;
              }
              matched_nonterminal(ref other_whole_nt) => {
                r.cur_span = sp;
                r.cur_tok = INTERPOLATED(copy *other_whole_nt);
                r.stack.idx += 1u;
                return ret_val;
              }
              matched_seq(*) => {
                r.sp_diag.span_fatal(
                    copy r.cur_span, /* blame the macro writer */
                    fmt!("variable '%s' is still repeating at this depth",
                         *r.interner.get(ident)));
              }
            }
          }
        }
    }

}
<commit_msg>Fix ICE in macros<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 ast;
use ast::{token_tree, tt_delim, tt_tok, tt_seq, tt_nonterminal,ident};
use codemap::{span, dummy_sp};
use diagnostic::span_handler;
use ext::tt::macro_parser::{named_match, matched_seq, matched_nonterminal};
use parse::token::{EOF, INTERPOLATED, IDENT, Token, nt_ident, ident_interner};
use parse::lexer::TokenAndSpan;

use core::hashmap::HashMap;

///an unzipping of `token_tree`s
struct TtFrame {
    forest: @mut ~[ast::token_tree],
    idx: uint,
    dotdotdoted: bool,
    sep: Option<Token>,
    up: Option<@mut TtFrame>,
}

pub struct TtReader {
    sp_diag: @span_handler,
    interner: @ident_interner,
    // the unzipped tree:
    stack: @mut TtFrame,
    /* for MBE-style macro transcription */
    interpolations: HashMap<ident, @named_match>,
    repeat_idx: ~[uint],
    repeat_len: ~[uint],
    /* cached: */
    cur_tok: Token,
    cur_span: span
}

/** This can do Macro-By-Example transcription. On the other hand, if
 *  `src` contains no `tt_seq`s and `tt_nonterminal`s, `interp` can (and
 *  should) be none. */
pub fn new_tt_reader(sp_diag: @span_handler,
                     itr: @ident_interner,
                     interp: Option<HashMap<ident,@named_match>>,
                     src: ~[ast::token_tree])
                  -> @mut TtReader {
    let r = @mut TtReader {
        sp_diag: sp_diag,
        interner: itr,
        stack: @mut TtFrame {
            forest: @mut src,
            idx: 0u,
            dotdotdoted: false,
            sep: None,
            up: option::None
        },
        interpolations: match interp { /* just a convienience */
            None => HashMap::new(),
            Some(x) => x
        },
        repeat_idx: ~[],
        repeat_len: ~[],
        /* dummy values, never read: */
        cur_tok: EOF,
        cur_span: dummy_sp()
    };
    tt_next_token(r); /* get cur_tok and cur_span set up */
    return r;
}

fn dup_tt_frame(f: @mut TtFrame) -> @mut TtFrame {
    @mut TtFrame {
        forest: @mut (copy *f.forest),
        idx: f.idx,
        dotdotdoted: f.dotdotdoted,
        sep: copy f.sep,
        up: match f.up {
            Some(up_frame) => Some(dup_tt_frame(up_frame)),
            None => None
        }
    }
}

pub fn dup_tt_reader(r: @mut TtReader) -> @mut TtReader {
    @mut TtReader {
        sp_diag: r.sp_diag,
        interner: r.interner,
        stack: dup_tt_frame(r.stack),
        repeat_idx: copy r.repeat_idx,
        repeat_len: copy r.repeat_len,
        cur_tok: copy r.cur_tok,
        cur_span: r.cur_span,
        interpolations: copy r.interpolations,
    }
}

fn lookup_cur_matched_by_matched(r: &mut TtReader,
                                      start: @named_match)
                                   -> @named_match {
    fn red(ad: @named_match, idx: &uint) -> @named_match {
        match *ad {
          matched_nonterminal(_) => {
            // end of the line; duplicate henceforth
            ad
          }
          matched_seq(ref ads, _) => ads[*idx]
        }
    }
    let r = &mut *r;
    let repeat_idx = &r.repeat_idx;
    vec::foldl(start, *repeat_idx, red)
}

fn lookup_cur_matched(r: &mut TtReader, name: ident) -> @named_match {
    match r.interpolations.find_copy(&name) {
        Some(s) => lookup_cur_matched_by_matched(r, s),
        None => {
            r.sp_diag.span_fatal(r.cur_span, fmt!("unknown macro variable `%s`",
                                                  *r.interner.get(name)));
        }
    }
}
enum lis {
    lis_unconstrained, lis_constraint(uint, ident), lis_contradiction(~str)
}

fn lockstep_iter_size(t: &token_tree, r: &mut TtReader) -> lis {
    fn lis_merge(lhs: lis, rhs: lis, r: &mut TtReader) -> lis {
        match lhs {
          lis_unconstrained => copy rhs,
          lis_contradiction(_) => copy lhs,
          lis_constraint(l_len, l_id) => match rhs {
            lis_unconstrained => copy lhs,
            lis_contradiction(_) => copy rhs,
            lis_constraint(r_len, _) if l_len == r_len => copy lhs,
            lis_constraint(r_len, r_id) => {
                let l_n = copy *r.interner.get(l_id);
                let r_n = copy *r.interner.get(r_id);
                lis_contradiction(fmt!("Inconsistent lockstep iteration: \
                                       '%s' has %u items, but '%s' has %u",
                                        l_n, l_len, r_n, r_len))
            }
          }
        }
    }
    match *t {
      tt_delim(ref tts) | tt_seq(_, ref tts, _, _) => {
        vec::foldl(lis_unconstrained, *tts, |lis, tt| {
            let lis2 = lockstep_iter_size(tt, r);
            lis_merge(lis, lis2, r)
        })
      }
      tt_tok(*) => lis_unconstrained,
      tt_nonterminal(_, name) => match *lookup_cur_matched(r, name) {
        matched_nonterminal(_) => lis_unconstrained,
        matched_seq(ref ads, _) => lis_constraint(ads.len(), name)
      }
    }
}

// return the next token from the TtReader.
// EFFECT: advances the reader's token field
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
    let ret_val = TokenAndSpan {
        tok: copy r.cur_tok,
        sp: r.cur_span,
    };
    loop {
        {
            let stack = &mut *r.stack;
            let forest = &mut *stack.forest;
            if stack.idx < forest.len() {
                break;
            }
        }

        /* done with this set; pop or repeat? */
        if ! r.stack.dotdotdoted
            || { *r.repeat_idx.last() == *r.repeat_len.last() - 1 } {

            match r.stack.up {
              None => {
                r.cur_tok = EOF;
                return ret_val;
              }
              Some(tt_f) => {
                if r.stack.dotdotdoted {
                    r.repeat_idx.pop();
                    r.repeat_len.pop();
                }

                r.stack = tt_f;
                r.stack.idx += 1u;
              }
            }

        } else { /* repeat */
            r.stack.idx = 0u;
            r.repeat_idx[r.repeat_idx.len() - 1u] += 1u;
            match r.stack.sep {
              Some(copy tk) => {
                r.cur_tok = tk; /* repeat same span, I guess */
                return ret_val;
              }
              None => ()
            }
        }
    }
    loop { /* because it's easiest, this handles `tt_delim` not starting
    with a `tt_tok`, even though it won't happen */
        match r.stack.forest[r.stack.idx] {
          tt_delim(copy tts) => {
            r.stack = @mut TtFrame {
                forest: @mut tts,
                idx: 0u,
                dotdotdoted: false,
                sep: None,
                up: option::Some(r.stack)
            };
            // if this could be 0-length, we'd need to potentially recur here
          }
          tt_tok(sp, copy tok) => {
            r.cur_span = sp;
            r.cur_tok = tok;
            r.stack.idx += 1u;
            return ret_val;
          }
          tt_seq(sp, copy tts, copy sep, zerok) => {
            let t = tt_seq(sp, copy tts, copy sep, zerok);
            match lockstep_iter_size(&t, r) {
              lis_unconstrained => {
                r.sp_diag.span_fatal(
                    sp, /* blame macro writer */
                      "attempted to repeat an expression \
                       containing no syntax \
                       variables matched as repeating at this depth");
                  }
                  lis_contradiction(ref msg) => {
                      /* FIXME #2887 blame macro invoker instead*/
                      r.sp_diag.span_fatal(sp, (*msg));
                  }
                  lis_constraint(len, _) => {
                    if len == 0 {
                      if !zerok {
                        r.sp_diag.span_fatal(sp, /* FIXME #2887 blame invoker
                        */
                                             "this must repeat at least \
                                              once");
                          }

                    r.stack.idx += 1u;
                    return tt_next_token(r);
                } else {
                    r.repeat_len.push(len);
                    r.repeat_idx.push(0u);
                    r.stack = @mut TtFrame {
                        forest: @mut tts,
                        idx: 0u,
                        dotdotdoted: true,
                        sep: sep,
                        up: Some(r.stack)
                    };
                }
              }
            }
          }
          // FIXME #2887: think about span stuff here
          tt_nonterminal(sp, ident) => {
            match *lookup_cur_matched(r, ident) {
              /* sidestep the interpolation tricks for ident because
              (a) idents can be in lots of places, so it'd be a pain
              (b) we actually can, since it's a token. */
              matched_nonterminal(nt_ident(sn,b)) => {
                r.cur_span = sp; r.cur_tok = IDENT(sn,b);
                r.stack.idx += 1u;
                return ret_val;
              }
              matched_nonterminal(ref other_whole_nt) => {
                r.cur_span = sp;
                r.cur_tok = INTERPOLATED(copy *other_whole_nt);
                r.stack.idx += 1u;
                return ret_val;
              }
              matched_seq(*) => {
                r.sp_diag.span_fatal(
                    copy r.cur_span, /* blame the macro writer */
                    fmt!("variable '%s' is still repeating at this depth",
                         *r.interner.get(ident)));
              }
            }
          }
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>rejuv histograms via ticks and overheal instead, for possibly more useful numbers<commit_after>extern crate wow_combat_log;
extern crate chrono;

use std::fs::File;
use std::io::BufReader;
use std::io::{Seek, SeekFrom};
use std::collections::HashMap;
use std::fmt;
use chrono::Duration;

static REJUV_AURAS: &'static [u32] = &[
    774, // Rejuv
    155777, // Rejuv (Germ)
    ];

#[derive(Debug, Clone, Default)]
struct RestoComputation<'a> {
    map: HashMap<&'a str, [usize; 2]>,
    histo: [(u64, u64, u64); 32],
    player: &'a str,
}

impl<'a> RestoComputation<'a> {
    fn new(player: &'a str) -> Self {
        RestoComputation {player: player, .. Default::default() }
    }

    fn reset_stats(&mut self) {
        self.histo = Default::default();
    }

    fn parse_entry(&mut self, log: wow_combat_log::Entry<'a>, filter_start_time: Duration) {
        use wow_combat_log::Entry::*;
        use wow_combat_log::AuraType::*;

        if log.base().is_none() {
            return;
        }
        let base = log.base().unwrap();
        if base.src.name != self.player {
            return;
        }
        let entry = self.map.entry(log.base().unwrap().dst.id).or_insert([0, 0]);
        match log {
            Aura { ty, id, .. } if REJUV_AURAS.contains(&id) && ty != Remove => {
                let i = if id == REJUV_AURAS[0] { 0 } else { 1 };
                entry[i] = 0;
            },

            Heal { id, heal: total_heal, overheal, ty, .. } if REJUV_AURAS.contains(&id) => {
                if log.timestamp() < filter_start_time {
                    return;
                }

                let i = if id == REJUV_AURAS[0] { 0 } else { 1 };
                self.histo[entry[i]].0 += overheal;
                self.histo[entry[i]].1 += total_heal;
                self.histo[entry[i]].2 += 1;
                if entry[i] < self.histo.len() {
                    entry[i] += 1;
                }
            },
            _ => ()
        }
    }
}

impl<'a> fmt::Display for RestoComputation<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let overheal = self.histo.iter().map(|x| x.0).sum::<u64>() as f64;
        let total = self.histo.iter().map(|x| x.1).sum::<u64>() as f64;
        writeln!(f, "total rejuv healing {} ({:.2}% overheal)", total, overheal/total * 100.)?;
        write!(f, "Overheal by tick: ")?;
        for i in &self.histo {
            if i.1 == 0 { break }
            write!(f, "{:.2} ({}), ", i.0 as f64/i.1 as f64 * 100., i.2)?;
        }
        Ok(())
    }
}

impl<'a, 'b, 'c> std::ops::SubAssign<&'b RestoComputation<'c>> for RestoComputation<'a> {
    fn sub_assign(&mut self, rhs: &'b RestoComputation<'c>) {
        for (i, j) in self.histo.iter_mut().zip(rhs.histo.iter()) {
            i.0 -= j.0;
            i.1 -= j.1;
            i.2 -= j.2;
        }
    }
}

fn main() {
    let mut read = BufReader::new(File::open(std::env::args().nth(1).unwrap()).unwrap());
    let player = std::env::args().nth(2).unwrap();
    let intern = wow_combat_log::Interner::default();
    let start = std::env::args().nth(3).map(|x| Duration::seconds(x.parse().unwrap())).unwrap_or(Duration::zero());
    let end = std::env::args().nth(4).map(|x| Duration::seconds(x.parse().unwrap())).unwrap_or(Duration::max_value());

    let iter = wow_combat_log::iter(&intern, read);
    let iter = iter.take_while(|x| x.timestamp() < end);
    let mut encounter_start = None;
    let mut total = RestoComputation::new(&player);
    let mut encounter = total.clone();
    let mut kills = total.clone();
    let mut bosses = total.clone();

    for log in iter {
        use wow_combat_log::Entry::*;
        match log {
            EncounterStart {..} => {
                encounter_start = Some(log.timestamp());
                bosses -= &encounter;
                kills -= &encounter;
                encounter.reset_stats();
            },
            EncounterEnd {name, kill, ..} => {
                if let Some(s) = encounter_start {
                    println!("duration: {}, start: {}, {}, kill: {}", (log.timestamp() - s).num_seconds(), s.num_seconds(), name, kill);
                    println!("{}", encounter);
                    println!("");
                    encounter_start = None;
                }
                if !kill {
                    kills -= &encounter;
                }
                encounter.reset_stats();
            },
            _ => ()
        }
        encounter.parse_entry(log, start);
        total.parse_entry(log, start);
        kills.parse_entry(log, start);
        bosses.parse_entry(log, start);
    }
    bosses -= &encounter;
    kills -= &encounter;

    println!("-------");
    println!("");
    println!("Log total:");
    println!("{}", total);
    println!("");
    println!("Boss total:");
    println!("{}", bosses);
    println!("");
    println!("Kill total:");
    println!("{}", kills);
}
<|endoftext|>


<commit_before><commit_msg>Add tests for various ways to write 'do' and 'for' without args<commit_after>// no-reformat
// Testing various forms of `do` and `for` with empty arg lists

fn f(f: fn() -> bool) {
}

fn main() {
    do f() || { true }
    do f() { true }
    do f || { true }
    do f { true }
    for f() || { }
    for f() { }
    for f || { }
    for f { }
}
<|endoftext|>


<commit_before>use libimagstore::storeid::StoreId;
use libimagstore::store::Entry;
use libimagstore::store::Result as StoreResult;

use error::{LinkError, LinkErrorKind};
use result::Result;

use toml::Value;

pub type Link = StoreId;

pub trait InternalLinker {

    /// Get the internal links from the implementor object
    fn get_internal_links(&self) -> Result<Vec<Link>>;

    /// Set the internal links for the implementor object
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<Vec<Link>>;

    /// Add an internal link to the implementor object
    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove an internal link from the implementor object
    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>;

}

impl InternalLinker for Entry {

    fn get_internal_links(&self) -> Result<Vec<Link>> {
        process_rw_result(self.get_header().read("imag.links"))
    }

    /// Set the links in a header and return the old links, if any.
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<Vec<Link>> {
        let self_location = self.get_location().clone();
        let mut new_links = vec![];

        for link in links {
            if let Err(e) = add_foreign_link(link, self_location.clone()) {
                return Err(e);
            }
            let link = link.get_location().clone();
            let link = link.to_str();
            if link.is_none() {
                return Err(LinkError::new(LinkErrorKind::InternalConversionError, None));
            }
            let link = link.unwrap();

            new_links.push(Value::String(String::from(link)));
        }

        process_rw_result(self.get_header_mut().set("imag.links", Value::Array(new_links)))
    }

    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let new_link = link.get_location().clone();

        add_foreign_link(link, self.get_location().clone())
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|mut links| {
                        links.push(new_link);

                        // try to convert them to str so we can put them back into the header
                        let links : Vec<Option<Value>> = links
                            .into_iter()
                            .map(|s| s.to_str().map(|s| Value::String(String::from(s))))
                            .collect();

                        if links.iter().any(|o| o.is_none()) {
                            // if any type convert failed we fail as well
                            Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
                        } else {
                            // I know it is ugly
                            let links = links.into_iter().map(|opt| opt.unwrap()).collect();
                            let process = self.get_header_mut().set("imag.links", Value::Array(links));
                            process_rw_result(process)
                                .map(|_| ())
                        }
                    })
            })
    }

    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let own_loc   = link.get_location().clone();
        let other_loc = link.get_location().clone();

        link.get_internal_links()
            .and_then(|links| {
                let links : Vec<Option<Value>> = links.into_iter()
                    .filter(|l| l.clone() != own_loc)
                    .map(|s| {
                        match s.to_str() {
                            Some(s) => Some(Value::String(String::from(s))),
                            _ => None
                        }
                    })
                    .collect();

                if links.iter().any(|o| o.is_none()) {
                    Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
                } else {
                    let links = links.into_iter().map(|opt| opt.unwrap()).collect();
                    process_rw_result(self.get_header_mut().set("imag.links", Value::Array(links)))
                        .map(|_| ())
                }
            })
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        let links : Vec<Option<Value>> = links
                            .into_iter()
                            .filter(|l| l.clone() != other_loc)
                            .map(|s| {
                                match s.to_str() {
                                    Some(s) => Some(Value::String(String::from(s))),
                                    _ => None
                                }
                            })
                            .collect();
                        if links.iter().any(|o| o.is_none()) {
                            Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
                        } else {
                            let links = links.into_iter().map(|opt| opt.unwrap()).collect();
                            process_rw_result(link.get_header_mut().set("imag.links", Value::Array(links)))
                                .map(|_| ())
                        }
                    })
            })
    }

}

/// When Linking A -> B, the specification wants us to link back B -> A.
/// This is a helper function which does this.
fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
    target.get_internal_links()
        .and_then(|mut links| {
            links.push(from);
            let links : Vec<Option<Value>> = links
                .into_iter()
                .map(|s| {
                    match s.to_str() {
                        Some(s) => Some(Value::String(String::from(s))),
                        _ => None
                    }
                })
                .collect();
            if links.iter().any(|o| o.is_none()) {
                Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
            } else {
                let links = links.into_iter().map(|opt| opt.unwrap()).collect();
                process_rw_result(target.get_header_mut().set("imag.links", Value::Array(links)))
                    .map(|_| ())
            }
        })
}

fn process_rw_result(links: StoreResult<Option<Value>>) -> Result<Vec<Link>> {
    if links.is_err() {
        let lerr  = LinkError::new(LinkErrorKind::EntryHeaderReadError,
                                   Some(Box::new(links.err().unwrap())));
        return Err(lerr);
    }
    let links = links.unwrap();

    if links.iter().any(|l| match l { &Value::String(_) => true, _ => false }) {
        return Err(LinkError::new(LinkErrorKind::ExistingLinkTypeWrong, None));
    }

    let links : Vec<Link> = links.into_iter()
        .map(|link| {
            match link {
                Value::String(s) => StoreId::from(s),
                _ => unreachable!(),
            }
        })
        .collect();

    Ok(links)
}

<commit_msg>Refactor common pattern into function<commit_after>use libimagstore::storeid::StoreId;
use libimagstore::store::Entry;
use libimagstore::store::EntryHeader;
use libimagstore::store::Result as StoreResult;

use error::{LinkError, LinkErrorKind};
use result::Result;

use toml::Value;

pub type Link = StoreId;

pub trait InternalLinker {

    /// Get the internal links from the implementor object
    fn get_internal_links(&self) -> Result<Vec<Link>>;

    /// Set the internal links for the implementor object
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<Vec<Link>>;

    /// Add an internal link to the implementor object
    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()>;

    /// Remove an internal link from the implementor object
    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()>;

}

impl InternalLinker for Entry {

    fn get_internal_links(&self) -> Result<Vec<Link>> {
        process_rw_result(self.get_header().read("imag.links"))
    }

    /// Set the links in a header and return the old links, if any.
    fn set_internal_links(&mut self, links: Vec<&mut Entry>) -> Result<Vec<Link>> {
        let self_location = self.get_location().clone();
        let mut new_links = vec![];

        for link in links {
            if let Err(e) = add_foreign_link(link, self_location.clone()) {
                return Err(e);
            }
            let link = link.get_location().clone();
            let link = link.to_str();
            if link.is_none() {
                return Err(LinkError::new(LinkErrorKind::InternalConversionError, None));
            }
            let link = link.unwrap();

            new_links.push(Value::String(String::from(link)));
        }

        process_rw_result(self.get_header_mut().set("imag.links", Value::Array(new_links)))
    }

    fn add_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let new_link = link.get_location().clone();

        add_foreign_link(link, self.get_location().clone())
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|mut links| {
                        links.push(new_link);
                        rewrite_links(self.get_header_mut(), links)
                    })
            })
    }

    fn remove_internal_link(&mut self, link: &mut Entry) -> Result<()> {
        let own_loc   = link.get_location().clone();
        let other_loc = link.get_location().clone();

        link.get_internal_links()
            .and_then(|links| {
                let links = links.into_iter().filter(|l| l.clone() != own_loc).collect();
                rewrite_links(self.get_header_mut(), links)
            })
            .and_then(|_| {
                self.get_internal_links()
                    .and_then(|links| {
                        let links = links.into_iter().filter(|l| l.clone() != other_loc).collect();
                        rewrite_links(link.get_header_mut(), links)
                    })
            })
    }

}

fn rewrite_links(header: &mut EntryHeader, links: Vec<StoreId>) -> Result<()> {
    let links : Vec<Option<Value>> = links
        .into_iter()
        .map(|s| s.to_str().map(|s| Value::String(String::from(s))))
        .collect();

    if links.iter().any(|o| o.is_none()) {
        // if any type convert failed we fail as well
        Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
    } else {
        // I know it is ugly
        let links = links.into_iter().map(|opt| opt.unwrap()).collect();
        let process = header.set("imag.links", Value::Array(links));
        process_rw_result(process).map(|_| ())
    }
}

/// When Linking A -> B, the specification wants us to link back B -> A.
/// This is a helper function which does this.
fn add_foreign_link(target: &mut Entry, from: StoreId) -> Result<()> {
    target.get_internal_links()
        .and_then(|mut links| {
            links.push(from);
            let links : Vec<Option<Value>> = links
                .into_iter()
                .map(|s| {
                    match s.to_str() {
                        Some(s) => Some(Value::String(String::from(s))),
                        _ => None
                    }
                })
                .collect();
            if links.iter().any(|o| o.is_none()) {
                Err(LinkError::new(LinkErrorKind::InternalConversionError, None))
            } else {
                let links = links.into_iter().map(|opt| opt.unwrap()).collect();
                process_rw_result(target.get_header_mut().set("imag.links", Value::Array(links)))
                    .map(|_| ())
            }
        })
}

fn process_rw_result(links: StoreResult<Option<Value>>) -> Result<Vec<Link>> {
    if links.is_err() {
        let lerr  = LinkError::new(LinkErrorKind::EntryHeaderReadError,
                                   Some(Box::new(links.err().unwrap())));
        return Err(lerr);
    }
    let links = links.unwrap();

    if links.iter().any(|l| match l { &Value::String(_) => true, _ => false }) {
        return Err(LinkError::new(LinkErrorKind::ExistingLinkTypeWrong, None));
    }

    let links : Vec<Link> = links.into_iter()
        .map(|link| {
            match link {
                Value::String(s) => StoreId::from(s),
                _ => unreachable!(),
            }
        })
        .collect();

    Ok(links)
}

<|endoftext|>


<commit_before><commit_msg>Add a toy dyldinfo example<commit_after>extern crate goblin;
extern crate scroll;

use goblin::mach;
use std::env;
use std::process;
use std::path::Path;
use std::fs::File;
use std::io::Read;
use std::borrow::Cow;

fn usage() -> ! {
    println!("usage: dyldinfo <options> <mach-o file>");
    println!("    -bind             print binds as seen by macho::imports()");
    process::exit(1);
}

fn name_to_str<'a>(name: &'a [u8; 16]) -> Cow<'a, str> {
    for i in 0..16 {
        if name[i] == 0 {
            return String::from_utf8_lossy(&name[0..i])
        }
    }
    String::from_utf8_lossy(&name[..])
}

fn dylib_name(name: &str) -> &str {
    // observed behavior:
    //   "/usr/lib/libc++.1.dylib" => "libc++"
    //   "/usr/lib/libSystem.B.dylib" => "libSystem"
    //   "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation" => "CoreFoundation"
    name
        .rsplit('/').next().unwrap()
        .split('.').next().unwrap()
}

fn print_binds(macho: &mach::MachO) {
    // collect sections and sort by address
    let mut sections: Vec<mach::segment::Section> = Vec::new();
    for sects in macho.segments.sections() {
        sections.extend(sects.map(|r| r.expect("section").0));
    }
    sections.sort_by_key(|s| s.addr);

    // get the imports
    let imports = macho.imports().expect("imports");

    println!("bind information:");

    println!(
        "{:7} {:16} {:14} {:7} {:6} {:16} {}",
        "segment",
        "section",
        "address",
        "type",
        "addend",
        "dylib",
        "symbol"
    );

    for import in imports.iter().filter(|i| !i.is_lazy) {
        // find the section that imported this symbol
        let section = sections.iter()
            .filter(|s| import.address >= s.addr && import.address < (s.addr + s.size))
            .next();

        // get &strs for its name
        let (segname, sectname) = section
            .map(|sect|  (name_to_str(&sect.segname), name_to_str(&sect.sectname)))
            .unwrap_or((Cow::Borrowed("?"), Cow::Borrowed("?")));

        println!(
            "{:7} {:16} 0x{:<12X} {:7} {:6} {:16} {}{}",
            segname,
            sectname,
            import.address,
            "pointer",
            import.addend,
            dylib_name(import.dylib),
            import.name,
            if import.is_weak { " (weak import)" } else { "" }
        );
    }
}

fn main () {
    let len = env::args().len();

    let mut bind = false;

    if len <= 2 {
        usage();
    } else {
        // parse flags
        {
            let mut flags = env::args().collect::<Vec<_>>();
            flags.pop();
            flags.remove(0);
            for option in flags {
                match option.as_str() {
                    "-bind" => { bind = true }
                    other => {
                        println!("unknown flag: {}", other);
                        println!("");
                        usage();
                    }
                }
            }
        }

        // open the file
        let path = env::args_os().last().unwrap();
        let path = Path::new(&path);
        let buffer = { let mut v = Vec::new(); let mut f = File::open(&path).unwrap(); f.read_to_end(&mut v).unwrap(); v};
        match mach::MachO::parse(&buffer, 0) {
            Ok(macho) => {
                if bind {
                    print_binds(&macho);
                }
            },
            Err(err) => {
                println!("err: {:?}", err);
                process::exit(2);
            }
        }
    }
}
<|endoftext|>


<commit_before>// Temporary wrapper modules for migrating syntax to its own crate
import rustsyntax::codemap;
export codemap;

import rustsyntax::ast;
export ast;

import rustsyntax::ast_util;
export ast_util;

import rustsyntax::visit;
export visit;

import rustsyntax::fold;
export fold;

import rustsyntax::print;
export print;

import rustsyntax::parse;
export parse;

export ast;
export ast_util;
export visit;
export fold;
export ext;
export util;

mod util {
    import rustsyntax::util::interner;
    export interner;
}<commit_msg>rustc: Cleanup<commit_after>// Temporary wrapper modules for migrating syntax to its own crate
import rustsyntax::codemap;
export codemap;

import rustsyntax::ast;
export ast;

import rustsyntax::ast_util;
export ast_util;

import rustsyntax::visit;
export visit;

import rustsyntax::fold;
export fold;

import rustsyntax::print;
export print;

import rustsyntax::parse;
export parse;

import rustsyntax::util;
export util;

export ext;
<|endoftext|>


<commit_before><commit_msg>process: Add regression test for signal starvation<commit_after>#![cfg(unix)]

extern crate futures;
extern crate tokio_process;

use futures::{Future, IntoFuture, Stream, stream};
use std::process::{Command, Stdio};
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::time::Duration;
use tokio_process::CommandExt;

fn run_test() {
    let finished = Arc::new(AtomicBool::new(false));
    let finished_clone = finished.clone();

    thread::spawn(move || {
        let _ = stream::iter_ok((0..2).into_iter())
            .map(|i| Command::new("echo")
                 .arg(format!("I am spawned process #{}", i))
                 .stdin(Stdio::null())
                 .stdout(Stdio::null())
                 .stderr(Stdio::null())
                 .spawn_async()
                 .into_future()
                 .flatten()
            )
            .buffered(2)
            .collect()
            .wait();

        finished_clone.store(true, Ordering::SeqCst);
    });

    thread::sleep(Duration::from_millis(100));
    assert!(finished.load(Ordering::SeqCst), "FINISHED flag not set, maybe we deadlocked?");
}

#[test]
fn issue_42() {
    let max = 10;
    for i in 0..max {
        println!("running {}/{}", i, max);
        run_test()
    }
}
<|endoftext|>


<commit_before><commit_msg>Improve executable usage information<commit_after><|endoftext|>


<commit_before><commit_msg>Change executable to use stdout<commit_after><|endoftext|>


<commit_before>import std.io;
import std._vec;
import std._str;

tag boxtype {box_h; box_v; box_hv; box_align;}
tag contexttype {cx_h; cx_v;}

tag token {
  brk(uint);
  word(str);
  cword(str); // closing token
  open(boxtype, uint);
  close;
}

type context = rec(contexttype tp, uint indent);

type ps = @rec(mutable vec[context] context,
               uint width,
               io.writer out,
               mutable vec[token] buffered,
               mutable uint scandepth,
               mutable uint bufferedcol,
               mutable uint col,
               mutable bool start_of_line);

fn mkstate(io.writer out, uint width) -> ps {
  let vec[context] stack = vec(rec(tp=cx_v, indent=0u));
  let vec[token] buff = vec();
  ret @rec(mutable context=stack,
           width=width,
           out=out,
           mutable buffered=buff,
           mutable scandepth=0u,
           mutable bufferedcol=0u,
           mutable col=0u,
           mutable start_of_line=true);
}

impure fn push_context(ps p, contexttype tp, uint indent) {
  before_print(p, false);
  _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
                                    + indent));
}

fn pop_context(ps p) {
  _vec.pop[context](p.context);
}

impure fn add_token(ps p, token tok) {
  if (p.width == 0u) {direct_token(p, tok);}
  else if (p.scandepth == 0u) {do_token(p, tok);}
  else {buffer_token(p, tok);}
}

impure fn direct_token(ps p, token tok) {
  alt (tok) {
    case (brk(?sz)) {
      while (sz > 0u) {p.out.write_str(" "); sz -= 1u;}
    }
    case (word(?w)) {p.out.write_str(w);}
    case (cword(?w)) {p.out.write_str(w);}
    case (_) {}
  }
}

impure fn buffer_token(ps p, token tok) {
  p.buffered += vec(tok);
  p.bufferedcol += token_size(tok);
  alt (p.buffered.(0)) {
    case (brk(_)) {
      alt (tok) {
        case (brk(_)) {
          if (p.scandepth == 1u) {finish_break_scan(p);}
        }
        case (open(box_h,_)) {p.scandepth += 1u;}
        case (open(_,_)) {finish_break_scan(p);}
        case (close) {
          p.scandepth -= 1u;
          if (p.scandepth == 0u) {finish_break_scan(p);}
        }
        case (_) {}
      }
    }
    case (open(_,_)) {
      if (p.bufferedcol > p.width) {finish_block_scan(p, cx_v);}
      else {
        alt (tok) {
          case (open(_,_)) {p.scandepth += 1u;}
          case (close) {
            p.scandepth -= 1u;
            if (p.scandepth == 0u) {finish_block_scan(p, cx_h);}
          }
          case (_) {}
        }
      }
    }
  }
}

impure fn finish_block_scan(ps p, contexttype tp) {
  auto indent;
  alt (p.buffered.(0)){
    case (open(box_hv,?ind)) {
      indent = ind;
    }
    case (open(box_align, _)) {
      indent = p.col - base_indent(p);
    }
  }
  p.scandepth = 0u;
  push_context(p, tp, indent);
  _vec.shift[token](p.buffered);
  for (token t in p.buffered) { add_token(p, t); }
}

impure fn finish_break_scan(ps p) {
  if (p.bufferedcol > p.width) {
    line_break(p);
  }
  else {
    auto width;
    alt (p.buffered.(0)) {case(brk(?w)) {width = w;}}
    auto i = 0u;
    while (i < width) {p.out.write_str(" "); i+=1u;}
    p.col += width;
  }
  p.scandepth = 0u;
  _vec.shift[token](p.buffered);
  for (token t in p.buffered) { add_token(p, t); }
}

impure fn start_scan(ps p, token tok) {
  p.buffered = vec(tok);
  p.scandepth = 1u;
  p.bufferedcol = p.col;
}

fn cur_context(ps p) -> context {
  ret p.context.(_vec.len[context](p.context)-1u);
}
fn base_indent(ps p) -> uint {
  auto i = _vec.len[context](p.context);
  while (i > 0u) {
    i -= 1u;
    auto cx = p.context.(i);
    if (cx.tp == cx_v) {ret cx.indent;}
  }
}

impure fn do_token(ps p, token tok) {
  alt (tok) {
    case (brk(?sz)) {
      alt (cur_context(p).tp) {
        case (cx_h) {
          before_print(p, false);
          start_scan(p, tok);
        }
        case (cx_v) {
          line_break(p);
        }
      }
    }
    case (word(?w)) {
      before_print(p, false);
      p.out.write_str(w);
      p.col += _str.byte_len(w); // TODO char_len
    }
    case (cword(?w)) {
      before_print(p, true);
      p.out.write_str(w);
      p.col += _str.byte_len(w); // TODO char_len
    }
    case (open(?tp, ?indent)) {
      alt (tp) {
        case (box_hv) {start_scan(p, tok);}
        case (box_align) {start_scan(p, tok);}
        case (box_h) {push_context(p, cx_h, indent);}
        case (box_v) {push_context(p, cx_v, indent);}
      }
    }
    case (close) {pop_context(p);}
  }
}

impure fn line_break(ps p) {
  p.out.write_str("\n");
  p.col = 0u;
  p.start_of_line = true;
}

impure fn before_print(ps p, bool closing) {
  if (p.start_of_line) {
    p.start_of_line = false;
    auto ind;
    if (closing) {ind = base_indent(p);}
    else {ind = cur_context(p).indent;}
    p.col = ind;
    while (ind > 0u) {p.out.write_str(" "); ind -= 1u;}
  }
}

fn token_size(token tok) -> uint {
  alt (tok) {
    case (brk(?sz)) {ret sz;}
    case (word(?w)) {ret _str.byte_len(w);}
    case (cword(?w)) {ret _str.byte_len(w);}
    case (open(_, _)) {ret 0u;} // TODO exception for V blocks?
    case (close) {ret 0u;}
  }
}

impure fn box(ps p, uint indent) {add_token(p, open(box_hv, indent));}
impure fn abox(ps p) {add_token(p, open(box_align, 0u));}
impure fn vbox(ps p, uint indent) {add_token(p, open(box_v, indent));}
impure fn hbox(ps p, uint indent) {add_token(p, open(box_h, indent));}
impure fn end(ps p) {add_token(p, close);}
impure fn wrd(ps p, str wrd) {add_token(p, word(wrd));}
impure fn cwrd(ps p, str wrd) {add_token(p, cword(wrd));}
impure fn space(ps p) {add_token(p, brk(1u));}
impure fn spaces(ps p, uint n) {add_token(p, brk(n));}
impure fn line(ps p) {add_token(p, brk(0u));}
<commit_msg>fix pretty-printer<commit_after>import std.io;
import std._vec;
import std._str;

tag boxtype {box_h; box_v; box_hv; box_align;}
tag contexttype {cx_h; cx_v;}

tag token {
  brk(uint);
  word(str);
  cword(str); // closing token
  open(boxtype, uint);
  close;
}

type context = rec(contexttype tp, uint indent);

type ps = @rec(mutable vec[context] context,
               uint width,
               io.writer out,
               mutable vec[token] buffered,
               mutable uint scandepth,
               mutable uint bufferedcol,
               mutable uint col,
               mutable bool start_of_line);

fn mkstate(io.writer out, uint width) -> ps {
  let vec[context] stack = vec(rec(tp=cx_v, indent=0u));
  let vec[token] buff = vec();
  ret @rec(mutable context=stack,
           width=width,
           out=out,
           mutable buffered=buff,
           mutable scandepth=0u,
           mutable bufferedcol=0u,
           mutable col=0u,
           mutable start_of_line=true);
}

impure fn push_context(ps p, contexttype tp, uint indent) {
  before_print(p, false);
  _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
                                    + indent));
}

fn pop_context(ps p) {
  _vec.pop[context](p.context);
}

impure fn add_token(ps p, token tok) {
  if (p.width == 0u) {direct_token(p, tok);}
  else if (p.scandepth == 0u) {do_token(p, tok);}
  else {buffer_token(p, tok);}
}

impure fn direct_token(ps p, token tok) {
  alt (tok) {
    case (brk(?sz)) {
      while (sz > 0u) {p.out.write_str(" "); sz -= 1u;}
    }
    case (word(?w)) {p.out.write_str(w);}
    case (cword(?w)) {p.out.write_str(w);}
    case (_) {}
  }
}

impure fn buffer_token(ps p, token tok) {
  p.buffered += vec(tok);
  p.bufferedcol += token_size(tok);
  alt (p.buffered.(0)) {
    case (brk(_)) {
      alt (tok) {
        case (brk(_)) {
          if (p.scandepth == 1u) {finish_break_scan(p);}
        }
        case (open(box_h,_)) {p.scandepth += 1u;}
        case (open(_,_)) {finish_break_scan(p);}
        case (close) {
          p.scandepth -= 1u;
          if (p.scandepth == 0u) {finish_break_scan(p);}
        }
        case (_) {}
      }
    }
    case (open(_,_)) {
      if (p.bufferedcol > p.width) {finish_block_scan(p, cx_v);}
      else {
        alt (tok) {
          case (open(_,_)) {p.scandepth += 1u;}
          case (close) {
            p.scandepth -= 1u;
            if (p.scandepth == 0u) {finish_block_scan(p, cx_h);}
          }
          case (_) {}
        }
      }
    }
  }
}

impure fn finish_block_scan(ps p, contexttype tp) {
  auto buf = p.buffered;
  auto front = _vec.shift[token](buf);
  auto indent;
  alt (front){
    case (open(box_hv,?ind)) {
      indent = ind;
    }
    case (open(box_align, _)) {
      indent = p.col - base_indent(p);
    }
  }
  p.scandepth = 0u;
  p.buffered = vec();
  push_context(p, tp, indent);
  for (token t in buf) { add_token(p, t); }
}

impure fn finish_break_scan(ps p) {
  auto buf = p.buffered;
  auto front = _vec.shift[token](buf);
  if (p.bufferedcol > p.width) {
    line_break(p);
  }
  else {
    auto width;
    alt (front) {case(brk(?w)) {width = w;}}
    auto i = 0u;
    while (i < width) {p.out.write_str(" "); i+=1u;}
    p.col += width;
  }
  p.scandepth = 0u;
  p.buffered = vec();
  for (token t in buf) { add_token(p, t); }
}

impure fn start_scan(ps p, token tok) {
  p.buffered = vec(tok);
  p.scandepth = 1u;
  p.bufferedcol = p.col;
}

fn cur_context(ps p) -> context {
  ret p.context.(_vec.len[context](p.context)-1u);
}
fn base_indent(ps p) -> uint {
  auto i = _vec.len[context](p.context);
  while (i > 0u) {
    i -= 1u;
    auto cx = p.context.(i);
    if (cx.tp == cx_v) {ret cx.indent;}
  }
}

impure fn do_token(ps p, token tok) {
  alt (tok) {
    case (brk(?sz)) {
      alt (cur_context(p).tp) {
        case (cx_h) {
          before_print(p, false);
          start_scan(p, tok);
        }
        case (cx_v) {
          line_break(p);
        }
      }
    }
    case (word(?w)) {
      before_print(p, false);
      p.out.write_str(w);
      p.col += _str.byte_len(w); // TODO char_len
    }
    case (cword(?w)) {
      before_print(p, true);
      p.out.write_str(w);
      p.col += _str.byte_len(w); // TODO char_len
    }
    case (open(?tp, ?indent)) {
      alt (tp) {
        case (box_hv) {start_scan(p, tok);}
        case (box_align) {start_scan(p, tok);}
        case (box_h) {push_context(p, cx_h, indent);}
        case (box_v) {push_context(p, cx_v, indent);}
      }
    }
    case (close) {pop_context(p);}
  }
}

impure fn line_break(ps p) {
  p.out.write_str("\n");
  p.col = 0u;
  p.start_of_line = true;
}

impure fn before_print(ps p, bool closing) {
  if (p.start_of_line) {
    p.start_of_line = false;
    auto ind;
    if (closing) {ind = base_indent(p);}
    else {ind = cur_context(p).indent;}
    p.col = ind;
    while (ind > 0u) {p.out.write_str(" "); ind -= 1u;}
  }
}

fn token_size(token tok) -> uint {
  alt (tok) {
    case (brk(?sz)) {ret sz;}
    case (word(?w)) {ret _str.byte_len(w);}
    case (cword(?w)) {ret _str.byte_len(w);}
    case (open(_, _)) {ret 0u;} // TODO exception for V blocks?
    case (close) {ret 0u;}
  }
}

impure fn box(ps p, uint indent) {add_token(p, open(box_hv, indent));}
impure fn abox(ps p) {add_token(p, open(box_align, 0u));}
impure fn vbox(ps p, uint indent) {add_token(p, open(box_v, indent));}
impure fn hbox(ps p, uint indent) {add_token(p, open(box_h, indent));}
impure fn end(ps p) {add_token(p, close);}
impure fn wrd(ps p, str wrd) {add_token(p, word(wrd));}
impure fn cwrd(ps p, str wrd) {add_token(p, cword(wrd));}
impure fn space(ps p) {add_token(p, brk(1u));}
impure fn spaces(ps p, uint n) {add_token(p, brk(n));}
impure fn line(ps p) {add_token(p, brk(0u));}
<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Result};
use std::result::Result as StdResult;
use std::rc::Rc;
use std::io;

use vec_map::VecMap;

use Arg;
use args::AnyArg;
use args::settings::{ArgFlags, ArgSettings};

#[allow(missing_debug_implementations)]
#[doc(hidden)]
pub struct PosBuilder<'n, 'e> {
    pub name: &'n str,
    pub help: Option<&'e str>,
    pub requires: Option<Vec<&'e str>>,
    pub blacklist: Option<Vec<&'e str>>,
    pub possible_vals: Option<Vec<&'e str>>,
    pub index: u64,
    pub num_vals: Option<u64>,
    pub max_vals: Option<u64>,
    pub min_vals: Option<u64>,
    pub val_names: Option<VecMap<&'e str>>,
    pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
    pub overrides: Option<Vec<&'e str>>,
    pub settings: ArgFlags,
    pub val_delim: Option<char>,
}

impl<'n, 'e> Default for PosBuilder<'n, 'e> {
    fn default() -> Self {
        PosBuilder {
            name: "",
            help: None,
            requires: None,
            blacklist: None,
            possible_vals: None,
            index: 0,
            num_vals: None,
            min_vals: None,
            max_vals: None,
            val_names: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
            val_delim: Some(','),
        }
    }
}

impl<'n, 'e> PosBuilder<'n, 'e> {
    pub fn new(name: &'n str, idx: u64) -> Self {
        PosBuilder {
            name: name,
            index: idx,
            ..Default::default()
        }
    }

    pub fn from_arg(a: &Arg<'n, 'e>, idx: u64, reqs: &mut Vec<&'e str>) -> Self {
        assert!(a.short.is_none() || a.long.is_none(),
            format!("Argument \"{}\" has conflicting requirements, both index() and short(), \
                or long(), were supplied", a.name));

        // Create the Positional Argument Builder with each HashSet = None to only
        // allocate
        // those that require it
        let mut pb = PosBuilder {
            name: a.name,
            index: idx,
            num_vals: a.num_vals,
            min_vals: a.min_vals,
            max_vals: a.max_vals,
            val_names: a.val_names.clone(),
            blacklist: a.blacklist.clone(),
            overrides: a.overrides.clone(),
            requires: a.requires.clone(),
            possible_vals: a.possible_vals.clone(),
            help: a.help,
            val_delim: a.val_delim,
            settings: a.settings.clone(),
            ..Default::default()
        };
        if a.max_vals.is_some()
            || a.min_vals.is_some()
            || (a.num_vals.is_some() && a.num_vals.unwrap() > 1) {
            pb.settings.set(ArgSettings::Multiple);
        }
        if let Some(ref p) = a.validator {
            pb.validator = Some(p.clone());
        }
        // If the arg is required, add all it's requirements to master required list
        if a.is_set(ArgSettings::Required) {
            if let Some(ref areqs) = a.requires {
                for r in areqs { reqs.push(*r); }
            }
        }
        pb
    }

    pub fn write_help<W: io::Write>(&self, w: &mut W, tab: &str, longest: usize, skip_pv: bool) -> io::Result<()> {
        try!(write!(w, "{}", tab));
        try!(write!(w, "{}", self.name));
        if self.settings.is_set(ArgSettings::Multiple) {
            try!(write!(w, "..."));
        }
        write_spaces!((longest + 4) - (self.to_string().len()), w);
        if let Some(h) = self.help {
            if h.contains("{n}") {
                let mut hel = h.split("{n}");
                while let Some(part) = hel.next() {
                    try!(write!(w, "{}\n", part));
                    write_spaces!(longest + 6, w);
                    try!(write!(w, "{}", hel.next().unwrap_or("")));
                }
            } else {
                try!(write!(w, "{}", h));
            }
            if !skip_pv {
                if let Some(ref pv) = self.possible_vals {
                    try!(write!(w, " [values: {}]", pv.join(", ")));
                }
            }
        }
        write!(w, "\n")
    }
}

impl<'n, 'e> Display for PosBuilder<'n, 'e> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        if self.settings.is_set(ArgSettings::Required) {
            try!(write!(f, "<{}>", self.name));
        } else {
            try!(write!(f, "[{}]", self.name));
        }
        if self.settings.is_set(ArgSettings::Multiple) {
            try!(write!(f, "..."));
        }

        Ok(())
    }
}

impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
    fn name(&self) -> &'n str { self.name }
    fn overrides(&self) -> Option<&[&'e str]> { self.overrides.as_ref().map(|o| &o[..]) }
    fn requires(&self) -> Option<&[&'e str]> { self.requires.as_ref().map(|o| &o[..]) }
    fn blacklist(&self) -> Option<&[&'e str]> { self.blacklist.as_ref().map(|o| &o[..]) }
    fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
    fn set(&mut self, s: ArgSettings) { self.settings.set(s) }
    fn has_switch(&self) -> bool { false }
    fn max_vals(&self) -> Option<u64> { self.max_vals }
    fn num_vals(&self) -> Option<u64> { self.num_vals }
    fn possible_vals(&self) -> Option<&[&'e str]> { self.possible_vals.as_ref().map(|o| &o[..]) }
    fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
        self.validator.as_ref()
    }
    fn min_vals(&self) -> Option<u64> { self.min_vals }
    fn short(&self) -> Option<char> { None }
    fn long(&self) -> Option<&'e str> { None }
    fn val_delim(&self) -> Option<char> { self.val_delim }
}

#[cfg(test)]
mod test {
    use super::PosBuilder;
    use args::settings::ArgSettings;

    #[test]
    fn posbuilder_display() {
        let mut p = PosBuilder::new("pos", 1);
        p.settings.set(ArgSettings::Multiple);

        assert_eq!(&*format!("{}", p), "[pos]...");

        let mut p2 = PosBuilder::new("pos", 1);
        p2.settings.set(ArgSettings::Required);

        assert_eq!(&*format!("{}", p2), "<pos>");
    }
}
<commit_msg>imp(Positional Arguments): now displays value name if appropriate<commit_after>use std::fmt::{Display, Formatter, Result};
use std::result::Result as StdResult;
use std::rc::Rc;
use std::io;

use vec_map::VecMap;

use Arg;
use args::AnyArg;
use args::settings::{ArgFlags, ArgSettings};

#[allow(missing_debug_implementations)]
#[doc(hidden)]
pub struct PosBuilder<'n, 'e> {
    pub name: &'n str,
    pub help: Option<&'e str>,
    pub requires: Option<Vec<&'e str>>,
    pub blacklist: Option<Vec<&'e str>>,
    pub possible_vals: Option<Vec<&'e str>>,
    pub index: u64,
    pub num_vals: Option<u64>,
    pub max_vals: Option<u64>,
    pub min_vals: Option<u64>,
    pub val_names: Option<VecMap<&'e str>>,
    pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
    pub overrides: Option<Vec<&'e str>>,
    pub settings: ArgFlags,
    pub val_delim: Option<char>,
}

impl<'n, 'e> Default for PosBuilder<'n, 'e> {
    fn default() -> Self {
        PosBuilder {
            name: "",
            help: None,
            requires: None,
            blacklist: None,
            possible_vals: None,
            index: 0,
            num_vals: None,
            min_vals: None,
            max_vals: None,
            val_names: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
            val_delim: Some(','),
        }
    }
}

impl<'n, 'e> PosBuilder<'n, 'e> {
    pub fn new(name: &'n str, idx: u64) -> Self {
        PosBuilder {
            name: name,
            index: idx,
            ..Default::default()
        }
    }

    pub fn from_arg(a: &Arg<'n, 'e>, idx: u64, reqs: &mut Vec<&'e str>) -> Self {
        assert!(a.short.is_none() || a.long.is_none(),
            format!("Argument \"{}\" has conflicting requirements, both index() and short(), \
                or long(), were supplied", a.name));

        // Create the Positional Argument Builder with each HashSet = None to only
        // allocate
        // those that require it
        let mut pb = PosBuilder {
            name: a.name,
            index: idx,
            num_vals: a.num_vals,
            min_vals: a.min_vals,
            max_vals: a.max_vals,
            val_names: a.val_names.clone(),
            blacklist: a.blacklist.clone(),
            overrides: a.overrides.clone(),
            requires: a.requires.clone(),
            possible_vals: a.possible_vals.clone(),
            help: a.help,
            val_delim: a.val_delim,
            settings: a.settings.clone(),
            ..Default::default()
        };
        if a.max_vals.is_some()
            || a.min_vals.is_some()
            || (a.num_vals.is_some() && a.num_vals.unwrap() > 1) {
            pb.settings.set(ArgSettings::Multiple);
        }
        if let Some(ref p) = a.validator {
            pb.validator = Some(p.clone());
        }
        // If the arg is required, add all it's requirements to master required list
        if a.is_set(ArgSettings::Required) {
            if let Some(ref areqs) = a.requires {
                for r in areqs { reqs.push(*r); }
            }
        }
        pb
    }

    pub fn write_help<W: io::Write>(&self, w: &mut W, tab: &str, longest: usize, skip_pv: bool) -> io::Result<()> {
        try!(write!(w, "{}", tab));
        try!(write!(w, "{}", self.name));
        if self.settings.is_set(ArgSettings::Multiple) {
            try!(write!(w, "..."));
        }
        write_spaces!((longest + 4) - (self.to_string().len()), w);
        if let Some(h) = self.help {
            if h.contains("{n}") {
                let mut hel = h.split("{n}");
                while let Some(part) = hel.next() {
                    try!(write!(w, "{}\n", part));
                    write_spaces!(longest + 6, w);
                    try!(write!(w, "{}", hel.next().unwrap_or("")));
                }
            } else {
                try!(write!(w, "{}", h));
            }
            if !skip_pv {
                if let Some(ref pv) = self.possible_vals {
                    try!(write!(w, " [values: {}]", pv.join(", ")));
                }
            }
        }
        write!(w, "\n")
    }
}

impl<'n, 'e> Display for PosBuilder<'n, 'e> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        if self.settings.is_set(ArgSettings::Required) {
            if let Some(ref names) = self.val_names {
                try!(write!(f, "{}", names.values().map(|n| format!("<{}>", n)).collect::<Vec<_>>().join(" ")));
            } else {
                try!(write!(f, "<{}>", self.name));
            }
        } else {
            if let Some(ref names) = self.val_names {
                try!(write!(f, "{}", names.values().map(|n| format!("[{}]", n)).collect::<Vec<_>>().join(" ")));
            } else {
                try!(write!(f, "[{}]", self.name));
            }
        }
        if self.settings.is_set(ArgSettings::Multiple) && self.val_names.is_none() {
            try!(write!(f, "..."));
        }

        Ok(())
    }
}

impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
    fn name(&self) -> &'n str { self.name }
    fn overrides(&self) -> Option<&[&'e str]> { self.overrides.as_ref().map(|o| &o[..]) }
    fn requires(&self) -> Option<&[&'e str]> { self.requires.as_ref().map(|o| &o[..]) }
    fn blacklist(&self) -> Option<&[&'e str]> { self.blacklist.as_ref().map(|o| &o[..]) }
    fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
    fn set(&mut self, s: ArgSettings) { self.settings.set(s) }
    fn has_switch(&self) -> bool { false }
    fn max_vals(&self) -> Option<u64> { self.max_vals }
    fn num_vals(&self) -> Option<u64> { self.num_vals }
    fn possible_vals(&self) -> Option<&[&'e str]> { self.possible_vals.as_ref().map(|o| &o[..]) }
    fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
        self.validator.as_ref()
    }
    fn min_vals(&self) -> Option<u64> { self.min_vals }
    fn short(&self) -> Option<char> { None }
    fn long(&self) -> Option<&'e str> { None }
    fn val_delim(&self) -> Option<char> { self.val_delim }
}

#[cfg(test)]
mod test {
    use super::PosBuilder;
    use args::settings::ArgSettings;

    #[test]
    fn posbuilder_display() {
        let mut p = PosBuilder::new("pos", 1);
        p.settings.set(ArgSettings::Multiple);

        assert_eq!(&*format!("{}", p), "[pos]...");

        let mut p2 = PosBuilder::new("pos", 1);
        p2.settings.set(ArgSettings::Required);

        assert_eq!(&*format!("{}", p2), "<pos>");
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix Italian greeting on example.rs<commit_after><|endoftext|>


<commit_before><commit_msg>feat(Pane): Find command line cmd & args<commit_after><|endoftext|>


<commit_before><commit_msg>Cryptocurrency refactored<commit_after>use exonum::events::Error as EventsError;
use exonum::crypto::{HexValue, FromHexError, Hash};
use exonum::storage::{Result as StorageResult, View as StorageView, Error as StorageError};
use std::io;
use std::collections::BTreeMap;
use iron::IronError;
use iron::prelude::*;
use iron::status;
use iron::headers::Cookie;
use iron::prelude::*;
use iron::modifiers::Header;
use hyper::header::{ContentType, SetCookie};

use serde_json;
use cookie::Cookie as CookiePair;
use serde_json::value::ToJson;
use exonum::crypto::PublicKey;
use exonum::crypto::SecretKey;
use router::Router;

#[derive(Debug)]
pub enum ApiError {
    Storage(StorageError),
    Events(EventsError),
    FromHex(FromHexError),
    Io(::std::io::Error),
    FileNotFound(Hash),
    FileToBig,
    FileExists(Hash),
    IncorrectRequest,
    Unauthorized,
}

impl ::std::fmt::Display for ApiError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl ::std::error::Error for ApiError {
    fn description(&self) -> &str {
        match *self {
            ApiError::Storage(_) => "Storage",
            ApiError::Events(_) => "Events",
            ApiError::FromHex(_) => "FromHex",
            ApiError::Io(_) => "Io",
            ApiError::FileNotFound(_) => "FileNotFound",
            ApiError::FileToBig => "FileToBig",
            ApiError::FileExists(_) => "FileExists",
            ApiError::IncorrectRequest => "IncorrectRequest",
            ApiError::Unauthorized => "Unauthorized",
        }
    }
}

impl From<io::Error> for ApiError {
    fn from(e: io::Error) -> ApiError {
        ApiError::Io(e)
    }
}

impl From<StorageError> for ApiError {
    fn from(e: StorageError) -> ApiError {
        ApiError::Storage(e)
    }
}

impl From<EventsError> for ApiError {
    fn from(e: EventsError) -> ApiError {
        ApiError::Events(e)
    }
}

impl From<FromHexError> for ApiError {
    fn from(e: FromHexError) -> ApiError {
        ApiError::FromHex(e)
    }
}

impl From<ApiError> for IronError {
    fn from(e: ApiError) -> IronError {
        use std::error::Error;

        let mut body = BTreeMap::new();
        body.insert("type", e.description().into());
        let code = match e {
            ApiError::FileExists(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            ApiError::FileNotFound(hash) => {
                body.insert("hash", hash.to_hex());
                status::Conflict
            }
            _ => status::Conflict,
        };
        IronError {
            error: Box::new(e),
            response: Response::with((code, body.to_json().to_string())),
        }
    }
}

pub trait Api {
    fn load_hex_value_from_cookie<'a>(&self,
                                      request: &'a Request,
                                      key: &str)
                                      -> StorageResult<Vec<u8>> {
        if let Some(&Cookie(ref cookies)) = request.headers.get() {
            for cookie in cookies.iter() {
                match CookiePair::parse(cookie.as_str()) {
                    Ok(c) => {
                        if c.name() == key {
                            if let Ok(value) = HexValue::from_hex(c.value()) {
                                return Ok(value);
                            }
                        }
                    }
                    Err(_) => {}
                }
            }
        }
        Err(StorageError::new(format!("Unable to find value with given key {}", key)))
    }

    fn load_keypair_from_cookies(&self,
                                 request: &Request)
                                 -> Result<(PublicKey, SecretKey), ApiError> {
        let public_key =
            PublicKey::from_slice(self.load_hex_value_from_cookie(&request, "public_key")?
                .as_ref());
        let secret_key =
            SecretKey::from_slice(self.load_hex_value_from_cookie(&request, "secret_key")?
                .as_ref());

        let public_key = public_key.ok_or(ApiError::Unauthorized)?;
        let secret_key = secret_key.ok_or(ApiError::Unauthorized)?;
        Ok((public_key, secret_key))
    }

    fn ok_response_with_cookies(&self,
                                json: &serde_json::Value,
                                cookies: Option<Vec<String>>)
                                -> IronResult<Response> {
        let mut resp = Response::with((status::Ok, json.as_str().unwrap()));
        resp.headers.set(ContentType::json());
        if let Some(cookies) = cookies {
            resp.headers.set(SetCookie(cookies));
        }
        Ok(resp)
    }

    fn ok_response(&self, json: &serde_json::Value) -> IronResult<Response> {
        self.ok_response_with_cookies(json, None)
    }

    fn wire<'b>(&self, router: &'b mut Router);
}<|endoftext|>


<commit_before><commit_msg>Test for issue 1896 (which appears to be fixed)<commit_after>type t<T> = { f: fn() -> T };

fn f<T>(_x: t<T>) {}

fn main() {
  let x: t<()> = { f: { || () } }; //! ERROR expressions with stack closure
    f(x);
}
<|endoftext|>


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

// Timing functions.
use extra::time::precise_time_ns;
use std::cell::Cell;
use std::comm::{Port, SharedChan};
use extra::sort::tim_sort;
use std::iterator::AdditiveIterator;
use std::hashmap::HashMap;

// front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)]
pub struct ProfilerChan {
    chan: SharedChan<ProfilerMsg>,
}

impl ProfilerChan {
    pub fn new(chan: Chan<ProfilerMsg>) -> ProfilerChan {
        ProfilerChan {
            chan: SharedChan::new(chan),
        }
    }
    pub fn send(&self, msg: ProfilerMsg) {
        self.chan.send(msg);
    }
}

pub enum ProfilerMsg {
    // Normal message used for reporting time
    TimeMsg(ProfilerCategory, float),
    // Message used to force print the profiling metrics
    PrintMsg,
}

#[deriving(Eq, Clone, IterBytes)]
pub enum ProfilerCategory {
    CompositingCategory,
    LayoutQueryCategory,
    LayoutPerformCategory,
    LayoutAuxInitCategory,
    LayoutSelectorMatchCategory,
    LayoutTreeBuilderCategory,
    LayoutMainCategory,
    LayoutShapingCategory,
    LayoutDispListBuildCategory,
    GfxRegenAvailableFontsCategory,
    RenderingDrawingCategory,
    RenderingPrepBuffCategory,
    RenderingCategory,
    // FIXME(rust#8803): workaround for lack of CTFE function on enum types to return length
    NumBuckets,
}
type ProfilerBuckets = HashMap<ProfilerCategory, ~[float]>;

// back end of the profiler that handles data aggregation and performance metrics
pub struct Profiler {
    port: Port<ProfilerMsg>,
    buckets: ProfilerBuckets,
    last_msg: Option<ProfilerMsg>,
}

impl ProfilerCategory {
    // convenience function to not have to cast every time
    pub fn num_buckets() -> uint {
        NumBuckets as uint
    }

    // enumeration of all ProfilerCategory types
    fn empty_buckets() -> ProfilerBuckets {
        let mut buckets = HashMap::with_capacity(NumBuckets as uint);
        buckets.insert(CompositingCategory, ~[]);
        buckets.insert(LayoutQueryCategory, ~[]);
        buckets.insert(LayoutPerformCategory, ~[]);
        buckets.insert(LayoutAuxInitCategory, ~[]);
        buckets.insert(LayoutSelectorMatchCategory, ~[]);
        buckets.insert(LayoutTreeBuilderCategory, ~[]);
        buckets.insert(LayoutMainCategory, ~[]);
        buckets.insert(LayoutShapingCategory, ~[]);
        buckets.insert(LayoutDispListBuildCategory, ~[]);
        buckets.insert(GfxRegenAvailableFontsCategory, ~[]);
        buckets.insert(RenderingDrawingCategory, ~[]);
        buckets.insert(RenderingPrepBuffCategory, ~[]);
        buckets.insert(RenderingCategory, ~[]);

        buckets
    }

    // some categories are subcategories of LayoutPerformCategory
    // and should be printed to indicate this
    pub fn format(self) -> ~str {
        let padding = match self {
            LayoutAuxInitCategory | LayoutSelectorMatchCategory | LayoutTreeBuilderCategory |
            LayoutMainCategory | LayoutDispListBuildCategory | LayoutShapingCategory=> " - ",
            _ => ""
        };
        fmt!("%s%?", padding, self)
    }
}

impl Profiler {
    pub fn create(port: Port<ProfilerMsg>) {
        let port = Cell::new(port);
        do spawn {
            let mut profiler = Profiler::new(port.take());
            profiler.start();
        }
    }

    pub fn new(port: Port<ProfilerMsg>) -> Profiler {
        Profiler {
            port: port,
            buckets: ProfilerCategory::empty_buckets(),
            last_msg: None,
        }
    }

    pub fn start(&mut self) {
        loop {
            let msg = self.port.try_recv();
            match msg {
               Some (msg) => self.handle_msg(msg),
               None => break
            }
        }
    }

    fn handle_msg(&mut self, msg: ProfilerMsg) {
        match msg {
            TimeMsg(category, t) => self.buckets.get_mut(&category).push(t),
            PrintMsg => match self.last_msg {
                // only print if more data has arrived since the last printout
                Some(TimeMsg(*)) => self.print_buckets(),
                _ => ()
            },
        };
        self.last_msg = Some(msg);
    }

    fn print_buckets(&mut self) {
        println(fmt!("%31s %15s %15s %15s %15s %15s",
                         "_category_", "_mean (ms)_", "_median (ms)_",
                         "_min (ms)_", "_max (ms)_", "_bucket size_"));
        for (category, data) in self.buckets.mut_iter() {
            tim_sort(*data);
            let data_len = data.len();
            if data_len > 0 {
                let (mean, median, &min, &max) =
                    (data.iter().map(|&x|x).sum() / (data_len as float),
                     data[data_len / 2],
                     data.iter().min().unwrap(),
                     data.iter().max().unwrap());
                println(fmt!("%-30s: %15.4f %15.4f %15.4f %15.4f %15u",
                             category.format(), mean, median, min, max, data_len));
            }
        }
        println("");
    }
}

pub fn profile<T>(category: ProfilerCategory,
                  profiler_chan: ProfilerChan,
                  callback: &fn() -> T)
                  -> T {
    let start_time = precise_time_ns();
    let val = callback();
    let end_time = precise_time_ns();
    let ms = ((end_time - start_time) as float / 1000000f);
    profiler_chan.send(TimeMsg(category, ms));
    return val;
}

pub fn time<T>(msg: &str, callback: &fn() -> T) -> T{
    let start_time = precise_time_ns();
    let val = callback();
    let end_time = precise_time_ns();
    let ms = ((end_time - start_time) as float / 1000000f);
    if ms >= 5f {
        debug!("%s took %? ms", msg, ms);
    }
    return val;
}

#[cfg(test)]
mod test {
    // ensure that the order of the buckets matches the order of the enum categories
    #[test]
    fn check_order() {
        let buckets = ProfilerCategory::empty_buckets();
        assert!(buckets.len() == NumBuckets as uint);
    }
}
<commit_msg>use TreeMap instead of HashMap for profiler buckets<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/. */

// Timing functions.
use extra::time::precise_time_ns;
use std::cell::Cell;
use std::comm::{Port, SharedChan};
use extra::sort::tim_sort;
use std::iterator::AdditiveIterator;
use extra::treemap::TreeMap;

// front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)]
pub struct ProfilerChan {
    chan: SharedChan<ProfilerMsg>,
}

impl ProfilerChan {
    pub fn new(chan: Chan<ProfilerMsg>) -> ProfilerChan {
        ProfilerChan {
            chan: SharedChan::new(chan),
        }
    }
    pub fn send(&self, msg: ProfilerMsg) {
        self.chan.send(msg);
    }
}

pub enum ProfilerMsg {
    // Normal message used for reporting time
    TimeMsg(ProfilerCategory, float),
    // Message used to force print the profiling metrics
    PrintMsg,
}

#[deriving(Eq, Clone, TotalEq, TotalOrd)]
pub enum ProfilerCategory {
    CompositingCategory,
    LayoutQueryCategory,
    LayoutPerformCategory,
    LayoutAuxInitCategory,
    LayoutSelectorMatchCategory,
    LayoutTreeBuilderCategory,
    LayoutMainCategory,
    LayoutShapingCategory,
    LayoutDispListBuildCategory,
    GfxRegenAvailableFontsCategory,
    RenderingDrawingCategory,
    RenderingPrepBuffCategory,
    RenderingCategory,
    // FIXME(rust#8803): workaround for lack of CTFE function on enum types to return length
    NumBuckets,
}
type ProfilerBuckets = TreeMap<ProfilerCategory, ~[float]>;

// back end of the profiler that handles data aggregation and performance metrics
pub struct Profiler {
    port: Port<ProfilerMsg>,
    buckets: ProfilerBuckets,
    last_msg: Option<ProfilerMsg>,
}

impl ProfilerCategory {
    // convenience function to not have to cast every time
    pub fn num_buckets() -> uint {
        NumBuckets as uint
    }

    // enumeration of all ProfilerCategory types
    fn empty_buckets() -> ProfilerBuckets {
        let mut buckets = TreeMap::new();
        buckets.insert(CompositingCategory, ~[]);
        buckets.insert(LayoutQueryCategory, ~[]);
        buckets.insert(LayoutPerformCategory, ~[]);
        buckets.insert(LayoutAuxInitCategory, ~[]);
        buckets.insert(LayoutSelectorMatchCategory, ~[]);
        buckets.insert(LayoutTreeBuilderCategory, ~[]);
        buckets.insert(LayoutMainCategory, ~[]);
        buckets.insert(LayoutShapingCategory, ~[]);
        buckets.insert(LayoutDispListBuildCategory, ~[]);
        buckets.insert(GfxRegenAvailableFontsCategory, ~[]);
        buckets.insert(RenderingDrawingCategory, ~[]);
        buckets.insert(RenderingPrepBuffCategory, ~[]);
        buckets.insert(RenderingCategory, ~[]);

        buckets
    }

    // some categories are subcategories of LayoutPerformCategory
    // and should be printed to indicate this
    pub fn format(self) -> ~str {
        let padding = match self {
            LayoutAuxInitCategory | LayoutSelectorMatchCategory | LayoutTreeBuilderCategory |
            LayoutMainCategory | LayoutDispListBuildCategory | LayoutShapingCategory=> " - ",
            _ => ""
        };
        fmt!("%s%?", padding, self)
    }
}

impl Profiler {
    pub fn create(port: Port<ProfilerMsg>) {
        let port = Cell::new(port);
        do spawn {
            let mut profiler = Profiler::new(port.take());
            profiler.start();
        }
    }

    pub fn new(port: Port<ProfilerMsg>) -> Profiler {
        Profiler {
            port: port,
            buckets: ProfilerCategory::empty_buckets(),
            last_msg: None,
        }
    }

    pub fn start(&mut self) {
        loop {
            let msg = self.port.try_recv();
            match msg {
               Some (msg) => self.handle_msg(msg),
               None => break
            }
        }
    }

    fn handle_msg(&mut self, msg: ProfilerMsg) {
        match msg {
            TimeMsg(category, t) => self.buckets.find_mut(&category).unwrap().push(t),
            PrintMsg => match self.last_msg {
                // only print if more data has arrived since the last printout
                Some(TimeMsg(*)) => self.print_buckets(),
                _ => ()
            },
        };
        self.last_msg = Some(msg);
    }

    fn print_buckets(&mut self) {
        println(fmt!("%31s %15s %15s %15s %15s %15s",
                         "_category_", "_mean (ms)_", "_median (ms)_",
                         "_min (ms)_", "_max (ms)_", "_bucket size_"));
        for (category, data) in self.buckets.iter() {
            // FIXME(XXX): TreeMap currently lacks mut_iter()
            let mut data = data.clone();
            tim_sort(data);
            let data_len = data.len();
            if data_len > 0 {
                let (mean, median, &min, &max) =
                    (data.iter().map(|&x|x).sum() / (data_len as float),
                     data[data_len / 2],
                     data.iter().min().unwrap(),
                     data.iter().max().unwrap());
                println(fmt!("%-30s: %15.4f %15.4f %15.4f %15.4f %15u",
                             category.format(), mean, median, min, max, data_len));
            }
        }
        println("");
    }
}

pub fn profile<T>(category: ProfilerCategory,
                  profiler_chan: ProfilerChan,
                  callback: &fn() -> T)
                  -> T {
    let start_time = precise_time_ns();
    let val = callback();
    let end_time = precise_time_ns();
    let ms = ((end_time - start_time) as float / 1000000f);
    profiler_chan.send(TimeMsg(category, ms));
    return val;
}

pub fn time<T>(msg: &str, callback: &fn() -> T) -> T{
    let start_time = precise_time_ns();
    let val = callback();
    let end_time = precise_time_ns();
    let ms = ((end_time - start_time) as float / 1000000f);
    if ms >= 5f {
        debug!("%s took %? ms", msg, ms);
    }
    return val;
}

#[cfg(test)]
mod test {
    // ensure that the order of the buckets matches the order of the enum categories
    #[test]
    fn check_order() {
        let buckets = ProfilerCategory::empty_buckets();
        assert!(buckets.len() == NumBuckets as uint);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example code.<commit_after>extern crate libcapstone_sys;

use libcapstone_sys::*;

fn main() {
    assert!(support(CS_ARCH_X86));

    let engine = Builder::new(CS_ARCH_X86, CS_MODE_64)
        .syntax(CS_OPT_SYNTAX_INTEL)
        .detail(CS_OPT_ON)
        .build()
        .expect("Could not create capstone engine");

    let instructions = engine.disasm_all(&[0x31, 0xed, 0x49, 0x89, 0xd1], 0x4a7aa0)
        .expect("Could not disassemble instructions");

    for instruction in instructions.iter() {
        println!("Instruction: id={}, address={}, size={}, bytes={:?}, mnemonic={}, op_str={}, \
                  detail={:?}",
                 instruction.id,
                 instruction.address,
                 instruction.size,
                 instruction.bytes,
                 instruction.get_mnemonic().unwrap(),
                 instruction.get_op_str().unwrap(),
                 instruction.detail);
    }
}
<|endoftext|>


<commit_before><commit_msg>Rust: Add template<commit_after>// adventofcode - day 0
// part 0

use std::io::prelude::*;
use std::fs::File;

fn main(){
    println!("Advent of Code - day 0 | part 0");

    // import data
    let data = import_data();

}

// This function simply imports the data set from a file called input.txt
fn import_data() -> String {
    let mut file = match File::open("input.txt") {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    let mut data = String::new();
    match file.read_to_string(&mut data){
        Ok(_) => {},
        Err(e) => panic!("file error: {}", e),
    };

	data
}
<|endoftext|>


<commit_before><commit_msg>rust tutorial part 2<commit_after>use std::os;
use std::io::File;

fn main() {
	let args: ~[~str] = os::args();
    if args.len() != 3 {
        println!("Usage: {:s} <file1> <file2>", args[0]);
    } else {
    	let file1 = args[1].clone();
    	let file2 = args[2].clone();
    	let path1 = Path::new(file1.clone());
    	let path2 = Path::new(file2.clone());
        let share1 = File::open(&path1);
        let share2 = File::open(&path2);

        match (share1, share2) {
        	(Some(mut s1), Some(mut s2)) => {
        		let s1_bytes: ~[u8] = s1.read_to_end();
        		let s2_bytes: ~[u8] = s2.read_to_end();
        		let msg_file
                    = File::create(&Path::new("msg"));

                match (msg_file) {
                	Some(msg) => join(s1_bytes, s2_bytes, msg),
                	None => fail!("Error opening output file!"),
                }

        	},
        	(_, _) => fail!("Error opening input files!"),
        }
    }

}

fn xor(a: &[u8], b: &[u8]) -> ~[u8] {
    let mut ret = ~[];
    for i in range(0, a.len()) {
		ret.push(a[i] ^ b[i]);
    }
    ret
}

fn join(s1_bytes: &[u8], s2_bytes: &[u8], mut msg_file: File) {
	let decrypted_bytes = xor(s1_bytes, s2_bytes);
	msg_file.write(decrypted_bytes);
}<|endoftext|>


<commit_before><commit_msg>acutally add the file<commit_after>use std;
use common::*;
use endian::*;
use message::*;
use serialize::*;

pub struct PackedOutputStream {
    inner : @OutputStream
}

impl OutputStream for PackedOutputStream {
    pub fn write(@self, buf : &[u8]) {
        // TODO
        self.inner.write(buf)
    }
}

pub fn writePackedMessage(outputStream : @OutputStream,
                          message : &MessageBuilder) {
    let packedOutputStream = @PackedOutputStream {inner : outputStream} as @OutputStream;
    writeMessage(packedOutputStream, message);
}<|endoftext|>