<commit_before>use convert;

use syntax::ast::{Expr, Ident, TokenTree, Stmt};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::ext::quote::rt::ToTokens;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::print::pprust;

// Copy from libsyntax
//
// A variant of 'try!' that panics on Err(FatalError). This is used as a
// crutch on the way towards a non-panic!-prone parser. It should be used
// for fatal parsing errors; eventually we plan to convert all code using
// panictry to just use normal try
macro_rules! panictry {
    ($e:expr) => ({
        use std::result::Result::{Ok, Err};
        use syntax::errors::FatalError;
        match $e {
            Ok(e) => e,
            Err(mut e) => {
                e.emit();
                panic!(FatalError);
            }
        }
    })
}

fn filter_tts_by_span(span: Span, tts: &[TokenTree]) -> Vec<TokenTree> {
    tts.iter()
       .filter(|tt| span.lo <= tt.get_span().lo && tt.get_span().hi <= span.hi)
       .cloned()
       .collect()
}

fn expr_prelude(cx: &ExtCtxt) -> Vec<P<Stmt>> {
    let use_stmt = quote_stmt!(cx, use std::io::Write;);
    let fn_stmt = quote_stmt!(
        cx,
        fn inspect<T: Write>(writer: &mut T, mut vals: Vec<(i32, String)>, offset: i32, repr: &str) {
            fn width(s: &str) -> i32 { s.len() as i32 }
            fn align<T: Write>(writer: &mut T, cur: &mut i32, col: i32, s: &str) {
                while *cur < col {
                    let _ = write!(writer, " ");
                    *cur += 1;
                }
                let _ = write!(writer, "{}", s);
                *cur += width(s);
            }

            vals.sort();

            let _ = writeln!(writer, "{}", repr);
            {
                let mut cur = 0;
                for &(c, _) in &vals {
                    align(writer, &mut cur, offset + c, "|");
                }
                let _ = writeln!(writer, "");
            }
            while !vals.is_empty() {
                let mut cur = 0;
                let mut i = 0;
                while i < vals.len() {
                    if i == vals.len() - 1 ||
                        vals[i].0 + width(&vals[i].1) < vals[i + 1].0 {
                            align(writer, &mut cur, offset + vals[i].0, &vals[i].1);
                            let _ = vals.remove(i);
                        } else {
                            align(writer, &mut cur, offset + vals[i].0, "|");
                            i += 1;
                        }
                }
                let _ = writeln!(writer, "");
            }
        });
    let write_stmt = quote_stmt!(cx, let mut write_buf = vec![];);

    vec![use_stmt.unwrap(), fn_stmt.unwrap(), write_stmt.unwrap()]
}

struct ExprGen {
    ident: Ident,
    tts: Vec<TokenTree>,
    expr: P<Expr>,
    ppstr: String,
}

impl ExprGen {
    fn new(ident: &str, expr: P<Expr>, tts: &[TokenTree]) -> ExprGen {
        let tts = filter_tts_by_span(expr.span, tts);
        let ppstr = pprust::expr_to_string(&expr);

        ExprGen {
            ident: token::gensym_ident(ident),
            tts: tts,
            expr: expr,
            ppstr: ppstr,
        }
    }

    fn ppstr(&self) -> &str {
        &self.ppstr
    }

    fn init_stmt(&self, cx: &mut ExtCtxt, pushed: bool) -> P<Stmt> {
        let ident = self.ident;
        if pushed {
            quote_stmt!(cx, let mut $ident = vec![];).unwrap()
        } else {
            quote_stmt!(cx, let $ident = vec![];).unwrap()
        }
    }

    fn converted_expr(&self, cx: &mut ExtCtxt) -> (P<Expr>, bool) {
        convert::convert_expr(cx, self.expr.clone(), self.ident, &self.tts)
    }

    fn inspect_expr(&self, cx: &mut ExtCtxt, left: &str, right: &str) -> P<Expr> {
        let offset = left.len() as i32;
        let repr = format!("{}{}{}", left, self.ppstr, right);
        let ident = self.ident;
        quote_expr!(cx, inspect(&mut write_buf, $ident, $offset, $repr))
    }
}

pub fn expand_assert(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    let mut parser = cx.new_parser_from_tts(args);
    let cond_expr = panictry!(parser.parse_expr());

    let msg_tts = if panictry!(parser.eat(&token::Token::Comma)) {
        let mut span = sp.clone();
        span.lo = parser.span.lo;
        Some(filter_tts_by_span(span, args))
    } else {
        None
    };

    let prelude = expr_prelude(cx);

    let gen = ExprGen::new("vals", cond_expr, args);
    let inspect = gen.inspect_expr(cx, "power_assert!(", ")");
    let (converted, pushed) = gen.converted_expr(cx);
    let init = gen.init_stmt(cx, pushed);

    let panic_msg = if let Some(tts) = msg_tts {
        quote_expr!(cx, format!($tts))
    } else {
        let msg = format!("assertion failed: {}", gen.ppstr());
        quote_expr!(cx, $msg)
    };

    let expr = quote_expr!(cx, {
        $init;
        let cond = $converted;
        if !cond {
            $prelude;
            let _ = writeln!(&mut write_buf, $panic_msg);
            $inspect;
            panic!(String::from_utf8(write_buf).unwrap())
        }
    });

    // println!("{:?}", expr);

    MacEager::expr(expr)
}

pub fn expand_assert_eq(cx: &mut ExtCtxt,
                        _sp: Span,
                        args: &[TokenTree])
                        -> Box<MacResult + 'static> {
    let mut parser = cx.new_parser_from_tts(args);
    let lhs = panictry!(parser.parse_expr());
    panictry!(parser.expect(&token::Token::Comma));
    let rhs = panictry!(parser.parse_expr());

    let lhs_gen = ExprGen::new("lhs_vals", lhs, args);
    let rhs_gen = ExprGen::new("rhs_vals", rhs, args);

    let prelude = expr_prelude(cx);

    let lhs_inspect = lhs_gen.inspect_expr(cx, "left: ", "");
    let rhs_inspect = rhs_gen.inspect_expr(cx, "right: ", "");
    let (lhs_converted, lhs_pushed) = lhs_gen.converted_expr(cx);
    let (rhs_converted, rhs_pushed) = rhs_gen.converted_expr(cx);
    let lhs_init = lhs_gen.init_stmt(cx, lhs_pushed);
    let rhs_init = rhs_gen.init_stmt(cx, rhs_pushed);
    let assert_msg = format!("power_assert_eq!({}, {})", lhs_gen.ppstr(), rhs_gen.ppstr());

    let expr = quote_expr!(cx, {
        $lhs_init;
        $rhs_init;
        match (&$lhs_converted, &$rhs_converted) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    $prelude;
                    let _ = writeln!(&mut write_buf, "assertion failed: `(left == right)` \
                            (left: `{:?}`, right: `{:?}`)", *left_val, *right_val);
                    let _ = writeln!(&mut write_buf, $assert_msg);
                    $lhs_inspect;
                    $rhs_inspect;
                    panic!(String::from_utf8(write_buf).unwrap());
                }
            }
        }
    });

    // println!("{:?}", expr);

    MacEager::expr(expr)
}
<commit_msg>update to rustc 1.7.0-nightly (2fb0c5ebc 2016-01-14)<commit_after>use convert;

use syntax::ast::{Expr, Ident, TokenTree, Stmt};
use syntax::codemap::Span;
use syntax::ext::base::{ExtCtxt, MacResult, MacEager};
use syntax::ext::quote::rt::ToTokens;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::print::pprust;

// Copy from libsyntax
//
// A variant of 'try!' that panics on Err(FatalError). This is used as a
// crutch on the way towards a non-panic!-prone parser. It should be used
// for fatal parsing errors; eventually we plan to convert all code using
// panictry to just use normal try
macro_rules! panictry {
    ($e:expr) => ({
        use std::result::Result::{Ok, Err};
        use syntax::errors::FatalError;
        match $e {
            Ok(e) => e,
            Err(mut e) => {
                e.emit();
                panic!(FatalError);
            }
        }
    })
}

fn filter_tts_by_span(span: Span, tts: &[TokenTree]) -> Vec<TokenTree> {
    tts.iter()
       .filter(|tt| span.lo <= tt.get_span().lo && tt.get_span().hi <= span.hi)
       .cloned()
       .collect()
}

fn expr_prelude(cx: &ExtCtxt) -> Vec<P<Stmt>> {
    let use_stmt = quote_stmt!(cx, use std::io::Write;);
    let fn_stmt = quote_stmt!(
        cx,
        fn inspect<T: Write>(writer: &mut T, mut vals: Vec<(i32, String)>, offset: i32, repr: &str) {
            fn width(s: &str) -> i32 { s.len() as i32 }
            fn align<T: Write>(writer: &mut T, cur: &mut i32, col: i32, s: &str) {
                while *cur < col {
                    let _ = write!(writer, " ");
                    *cur += 1;
                }
                let _ = write!(writer, "{}", s);
                *cur += width(s);
            }

            vals.sort();

            let _ = writeln!(writer, "{}", repr);
            {
                let mut cur = 0;
                for &(c, _) in &vals {
                    align(writer, &mut cur, offset + c, "|");
                }
                let _ = writeln!(writer, "");
            }
            while !vals.is_empty() {
                let mut cur = 0;
                let mut i = 0;
                while i < vals.len() {
                    if i == vals.len() - 1 ||
                        vals[i].0 + width(&vals[i].1) < vals[i + 1].0 {
                            align(writer, &mut cur, offset + vals[i].0, &vals[i].1);
                            let _ = vals.remove(i);
                        } else {
                            align(writer, &mut cur, offset + vals[i].0, "|");
                            i += 1;
                        }
                }
                let _ = writeln!(writer, "");
            }
        });
    let write_stmt = quote_stmt!(cx, let mut write_buf = vec![];);

    vec![use_stmt.unwrap(), fn_stmt.unwrap(), write_stmt.unwrap()]
}

struct ExprGen {
    ident: Ident,
    tts: Vec<TokenTree>,
    expr: P<Expr>,
    ppstr: String,
}

impl ExprGen {
    fn new(ident: &str, expr: P<Expr>, tts: &[TokenTree]) -> ExprGen {
        let tts = filter_tts_by_span(expr.span, tts);
        let ppstr = pprust::expr_to_string(&expr);

        ExprGen {
            ident: token::gensym_ident(ident),
            tts: tts,
            expr: expr,
            ppstr: ppstr,
        }
    }

    fn ppstr(&self) -> &str {
        &self.ppstr
    }

    fn init_stmt(&self, cx: &mut ExtCtxt, pushed: bool) -> P<Stmt> {
        let ident = self.ident;
        if pushed {
            quote_stmt!(cx, let mut $ident = vec![];).unwrap()
        } else {
            quote_stmt!(cx, let $ident = vec![];).unwrap()
        }
    }

    fn converted_expr(&self, cx: &mut ExtCtxt) -> (P<Expr>, bool) {
        convert::convert_expr(cx, self.expr.clone(), self.ident, &self.tts)
    }

    fn inspect_expr(&self, cx: &mut ExtCtxt, left: &str, right: &str) -> P<Expr> {
        let offset = left.len() as i32;
        let repr = format!("{}{}{}", left, self.ppstr, right);
        let ident = self.ident;
        quote_expr!(cx, inspect(&mut write_buf, $ident, $offset, $repr))
    }
}

pub fn expand_assert(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
    let mut parser = cx.new_parser_from_tts(args);
    let cond_expr = panictry!(parser.parse_expr());

    let msg_tts = if parser.eat(&token::Token::Comma) {
        let mut span = sp.clone();
        span.lo = parser.span.lo;
        Some(filter_tts_by_span(span, args))
    } else {
        None
    };

    let prelude = expr_prelude(cx);

    let gen = ExprGen::new("vals", cond_expr, args);
    let inspect = gen.inspect_expr(cx, "power_assert!(", ")");
    let (converted, pushed) = gen.converted_expr(cx);
    let init = gen.init_stmt(cx, pushed);

    let panic_msg = if let Some(tts) = msg_tts {
        quote_expr!(cx, format!($tts))
    } else {
        let msg = format!("assertion failed: {}", gen.ppstr());
        quote_expr!(cx, $msg)
    };

    let expr = quote_expr!(cx, {
        $init;
        let cond = $converted;
        if !cond {
            $prelude;
            let _ = writeln!(&mut write_buf, $panic_msg);
            $inspect;
            panic!(String::from_utf8(write_buf).unwrap())
        }
    });

    // println!("{:?}", expr);

    MacEager::expr(expr)
}

pub fn expand_assert_eq(cx: &mut ExtCtxt,
                        _sp: Span,
                        args: &[TokenTree])
                        -> Box<MacResult + 'static> {
    let mut parser = cx.new_parser_from_tts(args);
    let lhs = panictry!(parser.parse_expr());
    panictry!(parser.expect(&token::Token::Comma));
    let rhs = panictry!(parser.parse_expr());

    let lhs_gen = ExprGen::new("lhs_vals", lhs, args);
    let rhs_gen = ExprGen::new("rhs_vals", rhs, args);

    let prelude = expr_prelude(cx);

    let lhs_inspect = lhs_gen.inspect_expr(cx, "left: ", "");
    let rhs_inspect = rhs_gen.inspect_expr(cx, "right: ", "");
    let (lhs_converted, lhs_pushed) = lhs_gen.converted_expr(cx);
    let (rhs_converted, rhs_pushed) = rhs_gen.converted_expr(cx);
    let lhs_init = lhs_gen.init_stmt(cx, lhs_pushed);
    let rhs_init = rhs_gen.init_stmt(cx, rhs_pushed);
    let assert_msg = format!("power_assert_eq!({}, {})", lhs_gen.ppstr(), rhs_gen.ppstr());

    let expr = quote_expr!(cx, {
        $lhs_init;
        $rhs_init;
        match (&$lhs_converted, &$rhs_converted) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    $prelude;
                    let _ = writeln!(&mut write_buf, "assertion failed: `(left == right)` \
                            (left: `{:?}`, right: `{:?}`)", *left_val, *right_val);
                    let _ = writeln!(&mut write_buf, $assert_msg);
                    $lhs_inspect;
                    $rhs_inspect;
                    panic!(String::from_utf8(write_buf).unwrap());
                }
            }
        }
    });

    // println!("{:?}", expr);

    MacEager::expr(expr)
}
<|endoftext|>


<commit_before>use std::io::Result;
use self::super::{Github, SortDirection, State};
use rep::{Issue, IssueReq, Label};
use rustc_serialize::json;
use std::fmt;
use std::default::Default;

pub enum Filter {
  Assigned,
  Created,
  Mentioned,
  Subscribed,
  All
}

impl fmt::Display for Filter {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Filter::Assigned => "assigned",
      Filter::Created => "created",
      Filter::Mentioned => "mentioned",
      Filter::Subscribed => "subscribed",
      Filter::All => "all"
    })
  }
}

impl Default for Filter {
  fn default() -> Filter {
    Filter::Assigned
  }
}

pub enum Sort {
  Created,
  Updated,
  Comments
}

impl fmt::Display for Sort {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Sort::Created => "created",
      Sort::Updated => "updated",
      Sort::Comments => "comments"
    })
  }
}

impl Default for Sort {
  fn default() -> Sort {
    Sort::Created
  }
}

pub struct IssueRef<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str,
  number: &'static i64
}

impl<'a> IssueRef<'a> {
  /// create a new instance of a github repo issue ref
  pub fn new(
    github: &'a Github<'a>, owner: &'static str, repo: &'static str,
    number: &'static i64) -> IssueRef<'a> {
    IssueRef {
      github: github,
      owner: owner,
      repo: repo,
      number: number
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/issues/{}{}", self.owner, self.repo, self.number, more)
  }

  // add a set of labels to this issue ref
  pub fn label(&self, labels: Vec<&str>) -> Result<Vec<Label>> {
    let body = try!(self.github.post(
      &self.path("/labels"),
      json::encode(&labels).unwrap().as_bytes()
    ));
    Ok(json::decode::<Vec<Label>>(&body).unwrap())
  }
}

pub struct Issues<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str
}

impl<'a> Issues<'a> {
  /// create a new instance of a github repo issue ref
  pub fn new(
    github: &'a Github<'a>, owner: &'static str, repo: &'static str) -> Issues<'a> {
    Issues {
      github: github,
      owner: owner,
      repo: repo
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/issues{}", self.owner, self.repo, more)
  }

  pub fn get(&self, number: &'static i64) -> IssueRef {
    IssueRef::new(self.github, self.owner, self.repo, number)
  }

  pub fn create(&self, is: &IssueReq) -> Result<Issue> {
    let data = json::encode(&is).unwrap();
    let body = try!(
      self.github.post(
        &self.path(""),
        data.as_bytes()
      )
    );
    Ok(json::decode::<Issue>(&body).unwrap())
  }

  pub fn list(
    &self,
    state: State,
    sort: Sort,
    direction: SortDirection,
    assignee: Option<&'static str>,
    creator: Option<&'static str>,
    mentioned: Option<&'static str>,
    labels: Vec<&'static str>,
    since: Option<String>
   ) -> Result<Vec<Issue>> {
    let mut params = Vec::new();
    params.push(format!("state={}", state));
    params.push(format!("sort={}", sort));
    params.push(format!("direction={}", direction));
    if let Some(a) = assignee {
      params.push(format!("assignee={}", a));
    }
    if let Some(c) = creator {
      params.push(format!("creator={}", c));
    }
    let url = self.path(
      &format!("?{}", params.join("&"))
    );
    let body = try!(
      self.github.get(
        &url
      )
    );
    Ok(json::decode::<Vec<Issue>>(&body).unwrap())
  }
}
<commit_msg>edit issue<commit_after>use std::io::Result;
use self::super::{Github, SortDirection, State};
use rep::{Issue, IssueReq, Label};
use rustc_serialize::json;
use std::fmt;
use std::default::Default;

pub enum Filter {
  Assigned,
  Created,
  Mentioned,
  Subscribed,
  All
}

impl fmt::Display for Filter {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Filter::Assigned => "assigned",
      Filter::Created => "created",
      Filter::Mentioned => "mentioned",
      Filter::Subscribed => "subscribed",
      Filter::All => "all"
    })
  }
}

impl Default for Filter {
  fn default() -> Filter {
    Filter::Assigned
  }
}

pub enum Sort {
  Created,
  Updated,
  Comments
}

impl fmt::Display for Sort {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}", match *self {
      Sort::Created => "created",
      Sort::Updated => "updated",
      Sort::Comments => "comments"
    })
  }
}

impl Default for Sort {
  fn default() -> Sort {
    Sort::Created
  }
}

pub struct IssueRef<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str,
  number: &'static i64
}

impl<'a> IssueRef<'a> {
  /// create a new instance of a github repo issue ref
  pub fn new(
    github: &'a Github<'a>, owner: &'static str, repo: &'static str,
    number: &'static i64) -> IssueRef<'a> {
    IssueRef {
      github: github,
      owner: owner,
      repo: repo,
      number: number
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/issues/{}{}", self.owner, self.repo, self.number, more)
  }

  // add a set of labels to this issue ref
  pub fn label(&self, labels: Vec<&str>) -> Result<Vec<Label>> {
    let body = try!(self.github.post(
      &self.path("/labels"),
      json::encode(&labels).unwrap().as_bytes()
    ));
    Ok(json::decode::<Vec<Label>>(&body).unwrap())
  }

  pub fn edit(&self, is: &IssueReq) -> Result<Issue> {
    let data = json::encode(&is).unwrap();
    let body = try!(
      self.github.patch(
        &self.path(""),
        data.as_bytes()
      )
    );
    Ok(json::decode::<Issue>(&body).unwrap())
  }
}

pub struct Issues<'a> {
  github: &'a Github<'a>,
  owner: &'static str,
  repo: &'static str
}

impl<'a> Issues<'a> {
  /// create a new instance of a github repo issue ref
  pub fn new(
    github: &'a Github<'a>, owner: &'static str, repo: &'static str) -> Issues<'a> {
    Issues {
      github: github,
      owner: owner,
      repo: repo
    }
  }

  fn path(&self, more: &str) -> String {
    format!("/repos/{}/{}/issues{}", self.owner, self.repo, more)
  }

  pub fn get(&self, number: &'static i64) -> IssueRef {
    IssueRef::new(self.github, self.owner, self.repo, number)
  }

  pub fn create(&self, is: &IssueReq) -> Result<Issue> {
    let data = json::encode(&is).unwrap();
    let body = try!(
      self.github.post(
        &self.path(""),
        data.as_bytes()
      )
    );
    Ok(json::decode::<Issue>(&body).unwrap())
  }

  pub fn list(
    &self,
    state: State,
    sort: Sort,
    direction: SortDirection,
    assignee: Option<&'static str>,
    creator: Option<&'static str>,
    mentioned: Option<&'static str>,
    labels: Vec<&'static str>,
    since: Option<String>
   ) -> Result<Vec<Issue>> {
    let mut params = Vec::new();
    params.push(format!("state={}", state));
    params.push(format!("sort={}", sort));
    params.push(format!("direction={}", direction));
    if let Some(a) = assignee {
      params.push(format!("assignee={}", a));
    }
    if let Some(c) = creator {
      params.push(format!("creator={}", c));
    }
    let url = self.path(
      &format!("?{}", params.join("&"))
    );
    let body = try!(
      self.github.get(
        &url
      )
    );
    Ok(json::decode::<Vec<Issue>>(&body).unwrap())
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! List of lists.

use traits::{FromPointerReader, FromPointerBuilder, ListIter, IndexMove};
use private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, Pointer};
use Result;

#[derive(Clone, Copy)]
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
    marker: ::std::marker::PhantomData<<T as ::traits::Owned<'static>>::Reader>,
}

impl<'a, T> ::traits::Owned<'a> for Owned<T> where T: for<'b> ::traits::Owned<'b> {
    type Reader = Reader<'a, T>;
    type Builder = Builder<'a, T>;
}

pub struct Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    marker: ::std::marker::PhantomData<<T as ::traits::Owned<'a>>::Reader>,
    reader: ListReader<'a>
}

impl <'a, T> Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn new<'b>(reader: ListReader<'b>) -> Reader<'b, T> {
        Reader::<'b, T> { reader: reader, marker: ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.reader.len() }
    pub fn iter(self) -> ListIter<Reader<'a, T>, Result<<T as ::traits::Owned<'a>>::Reader>> {
        ListIter::new(self, self.len())
    }
}

impl <'a, T> Clone for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn clone(&self) -> Reader<'a, T> {
        Reader { marker : self.marker, reader : self.reader }
    }
}

impl <'a, T> Copy for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {}

impl <'a, T>  IndexMove<u32, Result<<T as ::traits::Owned<'a>>::Reader>> for Reader<'a, T>
where T: for<'b> ::traits::Owned<'b> {
    fn index_move(&self, index : u32) -> Result<<T as ::traits::Owned<'a>>::Reader> {
        self.get(index)
    }
}

impl <'a, T> FromPointerReader<'a> for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn get_from_pointer(reader : &PointerReader<'a>) -> Result<Reader<'a, T>> {
        Ok(Reader { reader: try!(reader.get_list(Pointer, ::std::ptr::null())),
                    marker: ::std::marker::PhantomData })
    }
}

impl <'a, T> Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn get(self, index: u32) -> Result<<T as ::traits::Owned<'a>>::Reader> {
        assert!(index <  self.len());
        FromPointerReader::get_from_pointer(&self.reader.get_pointer_element(index))
    }
}

pub struct Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    marker: ::std::marker::PhantomData<T>,
    builder: ListBuilder<'a>
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn new(builder: ListBuilder<'a>) -> Builder<'a, T> {
        Builder { builder: builder, marker: ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.builder.len() }

    pub fn as_reader(self) -> Reader<'a, T> {
        Reader { reader: self.builder.as_reader(), marker: ::std::marker::PhantomData }
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn init(self, index: u32, size: u32) -> <T as ::traits::Owned<'a>>::Builder {
        FromPointerBuilder::init_pointer(self.builder.get_pointer_element(index), size)
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn reborrow<'b>(&'b mut self) -> Builder<'b, T> {
        Builder {builder: self.builder.borrow(), marker: ::std::marker::PhantomData}
    }
}

impl <'a, T> FromPointerBuilder<'a> for Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn init_pointer(builder: PointerBuilder<'a>, size : u32) -> Builder<'a, T> {
        Builder {
            marker: ::std::marker::PhantomData,
            builder: builder.init_list(Pointer, size)
        }
    }
    fn get_from_pointer(builder: PointerBuilder<'a>) -> Result<Builder<'a, T>> {
        Ok(Builder {
            marker: ::std::marker::PhantomData,
            builder: try!(builder.get_list(Pointer, ::std::ptr::null()))
        })
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn get(self, index: u32) -> Result<<T as ::traits::Owned<'a>>::Builder> {
        assert!(index < self.len());
        FromPointerBuilder::get_from_pointer(self.builder.get_pointer_element(index))
    }
}

impl <'a, T> ::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
    where T: for<'b> ::traits::Owned<'b>
{
    fn set_pointer_builder<'b>(pointer: ::private::layout::PointerBuilder<'b>,
                               value: Reader<'a, T>,
                               canonicalize: bool) -> Result<()> {
        pointer.set_list(&value.reader, canonicalize)
    }
}

impl <'a, T> ::std::iter::IntoIterator for Reader<'a, T>
    where T: for<'b> ::traits::Owned<'b>
{
    type Item = Result<<T as ::traits::Owned<'a>>::Reader>;
    type IntoIter = ListIter<Reader<'a, T>, Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}
<commit_msg>More sensical type for list_list::Owned.marker. Avoids cargo doc bug.<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! List of lists.

use traits::{FromPointerReader, FromPointerBuilder, ListIter, IndexMove};
use private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder, Pointer};
use Result;

#[derive(Clone, Copy)]
pub struct Owned<T> where T: for<'a> ::traits::Owned<'a> {
    marker: ::std::marker::PhantomData<T>,
}

impl<'a, T> ::traits::Owned<'a> for Owned<T> where T: for<'b> ::traits::Owned<'b> {
    type Reader = Reader<'a, T>;
    type Builder = Builder<'a, T>;
}

pub struct Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    marker: ::std::marker::PhantomData<<T as ::traits::Owned<'a>>::Reader>,
    reader: ListReader<'a>
}

impl <'a, T> Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn new<'b>(reader: ListReader<'b>) -> Reader<'b, T> {
        Reader::<'b, T> { reader: reader, marker: ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.reader.len() }
    pub fn iter(self) -> ListIter<Reader<'a, T>, Result<<T as ::traits::Owned<'a>>::Reader>> {
        ListIter::new(self, self.len())
    }
}

impl <'a, T> Clone for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn clone(&self) -> Reader<'a, T> {
        Reader { marker : self.marker, reader : self.reader }
    }
}

impl <'a, T> Copy for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {}

impl <'a, T>  IndexMove<u32, Result<<T as ::traits::Owned<'a>>::Reader>> for Reader<'a, T>
where T: for<'b> ::traits::Owned<'b> {
    fn index_move(&self, index : u32) -> Result<<T as ::traits::Owned<'a>>::Reader> {
        self.get(index)
    }
}

impl <'a, T> FromPointerReader<'a> for Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn get_from_pointer(reader : &PointerReader<'a>) -> Result<Reader<'a, T>> {
        Ok(Reader { reader: try!(reader.get_list(Pointer, ::std::ptr::null())),
                    marker: ::std::marker::PhantomData })
    }
}

impl <'a, T> Reader<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn get(self, index: u32) -> Result<<T as ::traits::Owned<'a>>::Reader> {
        assert!(index <  self.len());
        FromPointerReader::get_from_pointer(&self.reader.get_pointer_element(index))
    }
}

pub struct Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    marker: ::std::marker::PhantomData<T>,
    builder: ListBuilder<'a>
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn new(builder: ListBuilder<'a>) -> Builder<'a, T> {
        Builder { builder: builder, marker: ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.builder.len() }

    pub fn as_reader(self) -> Reader<'a, T> {
        Reader { reader: self.builder.as_reader(), marker: ::std::marker::PhantomData }
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn init(self, index: u32, size: u32) -> <T as ::traits::Owned<'a>>::Builder {
        FromPointerBuilder::init_pointer(self.builder.get_pointer_element(index), size)
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn reborrow<'b>(&'b mut self) -> Builder<'b, T> {
        Builder {builder: self.builder.borrow(), marker: ::std::marker::PhantomData}
    }
}

impl <'a, T> FromPointerBuilder<'a> for Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    fn init_pointer(builder: PointerBuilder<'a>, size : u32) -> Builder<'a, T> {
        Builder {
            marker: ::std::marker::PhantomData,
            builder: builder.init_list(Pointer, size)
        }
    }
    fn get_from_pointer(builder: PointerBuilder<'a>) -> Result<Builder<'a, T>> {
        Ok(Builder {
            marker: ::std::marker::PhantomData,
            builder: try!(builder.get_list(Pointer, ::std::ptr::null()))
        })
    }
}

impl <'a, T> Builder<'a, T> where T: for<'b> ::traits::Owned<'b> {
    pub fn get(self, index: u32) -> Result<<T as ::traits::Owned<'a>>::Builder> {
        assert!(index < self.len());
        FromPointerBuilder::get_from_pointer(self.builder.get_pointer_element(index))
    }
}

impl <'a, T> ::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
    where T: for<'b> ::traits::Owned<'b>
{
    fn set_pointer_builder<'b>(pointer: ::private::layout::PointerBuilder<'b>,
                               value: Reader<'a, T>,
                               canonicalize: bool) -> Result<()> {
        pointer.set_list(&value.reader, canonicalize)
    }
}

impl <'a, T> ::std::iter::IntoIterator for Reader<'a, T>
    where T: for<'b> ::traits::Owned<'b>
{
    type Item = Result<<T as ::traits::Owned<'a>>::Reader>;
    type IntoIter = ListIter<Reader<'a, T>, Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}
<|endoftext|>


<commit_before>use crate::borrow_check::location::{LocationIndex, LocationTable};
use crate::dataflow::indexes::MovePathIndex;
use crate::dataflow::move_paths::{LookupResult, MoveData};
use crate::util::liveness::{categorize, DefUse};
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
use rustc::ty::subst::GenericArg;

use super::TypeChecker;

type VarPointRelations = Vec<(Local, LocationIndex)>;
type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;

struct UseFactsExtractor<'me> {
    var_defined: &'me mut VarPointRelations,
    var_used: &'me mut VarPointRelations,
    location_table: &'me LocationTable,
    var_drop_used: &'me mut Vec<(Local, Location)>,
    move_data: &'me MoveData<'me>,
    path_accessed_at: &'me mut MovePathPointRelations,
}

// A Visitor to walk through the MIR and extract point-wise facts
impl UseFactsExtractor<'_> {
    fn location_to_index(&self, location: Location) -> LocationIndex {
        self.location_table.mid_index(location)
    }

    fn insert_def(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_def()");
        self.var_defined.push((local, self.location_to_index(location)));
    }

    fn insert_use(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_use()");
        self.var_used.push((local, self.location_to_index(location)));
    }

    fn insert_drop_use(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_drop_use()");
        self.var_drop_used.push((local, location));
    }

    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
        debug!("UseFactsExtractor::insert_path_access({:?}, {:?})", path, location);
        self.path_accessed_at.push((path, self.location_to_index(location)));
    }

    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
        match self.move_data.rev_lookup.find(place.as_ref()) {
            LookupResult::Exact(mpi) => Some(mpi),
            LookupResult::Parent(mmpi) => mmpi,
        }
    }
}

impl Visitor<'tcx> for UseFactsExtractor<'_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
        match categorize(context) {
            Some(DefUse::Def) => self.insert_def(local, location),
            Some(DefUse::Use) => self.insert_use(local, location),
            Some(DefUse::Drop) => self.insert_drop_use(local, location),
            _ => (),
        }
    }

    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
        self.super_place(place, context, location);
        match context {
            PlaceContext::NonMutatingUse(_) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }

            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }
            _ => (),
        }
    }
}

pub(super) fn populate_access_facts(
    typeck: &mut TypeChecker<'_, 'tcx>,
    body: ReadOnlyBodyAndCache<'_, 'tcx>,
    location_table: &LocationTable,
    move_data: &MoveData<'_>,
    drop_used: &mut Vec<(Local, Location)>,
) {
    debug!("populate_access_facts()");

    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        let mut extractor = UseFactsExtractor {
            var_defined: &mut facts.var_defined,
            var_used: &mut facts.var_used,
            var_drop_used: drop_used,
            path_accessed_at: &mut facts.path_accessed_at,
            location_table,
            move_data,
        };
        extractor.visit_body(body);

        facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
            (local, location_table.mid_index(location))
        }));

        for (local, local_decl) in body.local_decls.iter_enumerated() {
            debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty);
            let universal_regions = &typeck.borrowck_context.universal_regions;
            typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
                let region_vid = universal_regions.to_region_vid(region);
                facts.var_uses_region.push((local, region_vid));
            });
        }
    }
}

// For every potentially drop()-touched region `region` in `local`'s type
// (`kind`), emit a Polonius `var_drops_region(local, region)` fact.
pub(super) fn add_var_drops_regions(
    typeck: &mut TypeChecker<'_, 'tcx>,
    local: Local,
    kind: &GenericArg<'tcx>,
) {
    debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind);
    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        let universal_regions = &typeck.borrowck_context.universal_regions;
        typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| {
            let region_vid = universal_regions.to_region_vid(drop_live_region);
            facts.var_drops_region.push((local, region_vid));
        });
    }
}
<commit_msg>cleanup polonius liveness fact generation: refactor some type names<commit_after>use crate::borrow_check::location::{LocationIndex, LocationTable};
use crate::dataflow::indexes::MovePathIndex;
use crate::dataflow::move_paths::{LookupResult, MoveData};
use crate::util::liveness::{categorize, DefUse};
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
use rustc::mir::{Local, Location, Place, ReadOnlyBodyAndCache};
use rustc::ty::subst::GenericArg;

use super::TypeChecker;

type VarPointRelation = Vec<(Local, LocationIndex)>;
type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>;

struct UseFactsExtractor<'me> {
    var_defined: &'me mut VarPointRelation,
    var_used: &'me mut VarPointRelation,
    location_table: &'me LocationTable,
    var_drop_used: &'me mut Vec<(Local, Location)>,
    move_data: &'me MoveData<'me>,
    path_accessed_at: &'me mut PathPointRelation,
}

// A Visitor to walk through the MIR and extract point-wise facts
impl UseFactsExtractor<'_> {
    fn location_to_index(&self, location: Location) -> LocationIndex {
        self.location_table.mid_index(location)
    }

    fn insert_def(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_def()");
        self.var_defined.push((local, self.location_to_index(location)));
    }

    fn insert_use(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_use()");
        self.var_used.push((local, self.location_to_index(location)));
    }

    fn insert_drop_use(&mut self, local: Local, location: Location) {
        debug!("UseFactsExtractor::insert_drop_use()");
        self.var_drop_used.push((local, location));
    }

    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
        debug!("UseFactsExtractor::insert_path_access({:?}, {:?})", path, location);
        self.path_accessed_at.push((path, self.location_to_index(location)));
    }

    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
        match self.move_data.rev_lookup.find(place.as_ref()) {
            LookupResult::Exact(mpi) => Some(mpi),
            LookupResult::Parent(mmpi) => mmpi,
        }
    }
}

impl Visitor<'tcx> for UseFactsExtractor<'_> {
    fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
        match categorize(context) {
            Some(DefUse::Def) => self.insert_def(local, location),
            Some(DefUse::Use) => self.insert_use(local, location),
            Some(DefUse::Drop) => self.insert_drop_use(local, location),
            _ => (),
        }
    }

    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
        self.super_place(place, context, location);
        match context {
            PlaceContext::NonMutatingUse(_) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }

            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
                if let Some(mpi) = self.place_to_mpi(place) {
                    self.insert_path_access(mpi, location);
                }
            }
            _ => (),
        }
    }
}

pub(super) fn populate_access_facts(
    typeck: &mut TypeChecker<'_, 'tcx>,
    body: ReadOnlyBodyAndCache<'_, 'tcx>,
    location_table: &LocationTable,
    move_data: &MoveData<'_>,
    drop_used: &mut Vec<(Local, Location)>,
) {
    debug!("populate_access_facts()");

    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        let mut extractor = UseFactsExtractor {
            var_defined: &mut facts.var_defined,
            var_used: &mut facts.var_used,
            var_drop_used: drop_used,
            path_accessed_at: &mut facts.path_accessed_at,
            location_table,
            move_data,
        };
        extractor.visit_body(body);

        facts.var_drop_used.extend(drop_used.iter().map(|&(local, location)| {
            (local, location_table.mid_index(location))
        }));

        for (local, local_decl) in body.local_decls.iter_enumerated() {
            debug!("add var_uses_regions facts - local={:?}, type={:?}", local, local_decl.ty);
            let universal_regions = &typeck.borrowck_context.universal_regions;
            typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
                let region_vid = universal_regions.to_region_vid(region);
                facts.var_uses_region.push((local, region_vid));
            });
        }
    }
}

// For every potentially drop()-touched region `region` in `local`'s type
// (`kind`), emit a Polonius `var_drops_region(local, region)` fact.
pub(super) fn add_var_drops_regions(
    typeck: &mut TypeChecker<'_, 'tcx>,
    local: Local,
    kind: &GenericArg<'tcx>,
) {
    debug!("add_var_drops_region(local={:?}, kind={:?}", local, kind);
    if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
        let universal_regions = &typeck.borrowck_context.universal_regions;
        typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| {
            let region_vid = universal_regions.to_region_vid(drop_live_region);
            facts.var_drops_region.push((local, region_vid));
        });
    }
}
<|endoftext|>


<commit_before>native "rust" mod rustrt {
  fn rust_file_is_dir(str path) -> int;
}

fn path_sep() -> str {
    ret str::from_char(os_fs::path_sep);
}

type path = str;

fn dirname(path p) -> path {
    let int i = str::rindex(p, os_fs::path_sep as u8);
    if (i == -1) {
        i = str::rindex(p, os_fs::alt_path_sep as u8);
        if (i == -1) {
            ret p;
        }
    }
    ret str::substr(p, 0u, i as uint);
}

// FIXME: Need some typestate to avoid bounds check when len(pre) == 0
fn connect(path pre, path post) -> path {
    auto len = str::byte_len(pre);
    if (pre.(len - 1u) == (os_fs::path_sep as u8)) { // Trailing '/'?
        ret pre + post;
    }
    ret pre + path_sep() + post;
}

fn file_is_dir(path p) -> bool {
  ret rustrt::rust_file_is_dir(p) != 0;
}

fn list_dir(path p) -> vec[str] {
  auto pl = str::byte_len(p);
  if (pl == 0u || p.(pl - 1u) as char != os_fs::path_sep) {
    p += path_sep();
  }
  let vec[str] full_paths = [];
  for (str filename in os_fs::list_dir(p)) {
    if (!str::eq(filename, ".")) {if (!str::eq(filename, "..")) {
      vec::push[str](full_paths, p + filename);
    }}
  }
  ret full_paths;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>stdlib: Use if/alt expressions in std::fs<commit_after>native "rust" mod rustrt {
  fn rust_file_is_dir(str path) -> int;
}

fn path_sep() -> str {
    ret str::from_char(os_fs::path_sep);
}

type path = str;

fn dirname(path p) -> path {
    let int i = str::rindex(p, os_fs::path_sep as u8);
    if (i == -1) {
        i = str::rindex(p, os_fs::alt_path_sep as u8);
        if (i == -1) {
            ret p;
        }
    }
    ret str::substr(p, 0u, i as uint);
}

// FIXME: Need some typestate to avoid bounds check when len(pre) == 0
fn connect(path pre, path post) -> path {
    auto len = str::byte_len(pre);
    ret if (pre.(len - 1u) == (os_fs::path_sep as u8)) { // Trailing '/'?
        pre + post
    } else {
        pre + path_sep() + post
    };
}

fn file_is_dir(path p) -> bool {
  ret rustrt::rust_file_is_dir(p) != 0;
}

fn list_dir(path p) -> vec[str] {
  auto pl = str::byte_len(p);
  if (pl == 0u || p.(pl - 1u) as char != os_fs::path_sep) {
    p += path_sep();
  }
  let vec[str] full_paths = [];
  for (str filename in os_fs::list_dir(p)) {
    if (!str::eq(filename, ".")) {if (!str::eq(filename, "..")) {
      vec::push[str](full_paths, p + filename);
    }}
  }
  ret full_paths;
}

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


<commit_before>#![allow(uppercase_variables)]

//! A few linear algebra operations on two-dimensional arrays.

use std::num::{zero, one};

use super::{Array, Dimension, Ix};

/// Column vector.
pub type Col = Array;
/// Rectangular matrix.
pub type Mat = Array;

/// Return the identity matrix of dimension *n*.
pub fn eye(n: Ix) -> Mat
{
    let mut eye = Array::zeros((n, n));
    for i in range(0, n) {
        eye[(i, i)] = one::();
    }
    eye
}

/*
/// Return the inverse matrix of square matrix `a`.
pub fn inverse(a: &Mat) -> Mat
{
    fail!()
}
*/

/// Solve *a x = b* with linear least squares approximation.
///
/// It is used to find the best fit for an overdetermined system,
/// i.e. the number of rows in *a* is larger than the number of
/// unknowns *x*.
///
/// Return best fit for *x*.
pub fn least_squares(a: &Mat, b: &Col) -> Col
{
    // Using transpose: a.T a x = a.T b;
    // a.T a being square gives naive solution
    // x_lstsq = inv(a.T a) a.T b
    //
    // Solve using cholesky decomposition
    // aT a x = aT b
    //
    // Factor aT a into L L.T
    //
    // L L.T x = aT b
    //
    // => L z = aT b
    //  fw subst for z
    // => L.T x = z
    //  bw subst for x estimate
    //
    let (m, n) = a.dim();

    let mut aT = a.clone();
    aT.swap_axes(0, 1);

    let aT_a = aT.mat_mul(a);
    let mut L = cholesky(&aT_a);
    let rhs = aT.mat_mul(&b.reshape((m, 1))).reshape(n);

    // Solve L z = aT b
    let z = subst_fw(&L, &rhs);

    // Solve L.T x = z
    L.swap_axes(0, 1);
    let x_lstsq = subst_bw(&L, &z);
    x_lstsq
}

/// Factor *A = L L.T*.
///
/// https://en.wikipedia.org/wiki/Cholesky_decomposition
///
/// “The Cholesky decomposition is mainly used for the numerical solution of
/// linear equations Ax = b.
///
/// If A is symmetric and positive definite, then we can solve Ax = b by first
/// computing the Cholesky decomposition A = LL*, then solving Ly = b for y by
/// forward substitution, and finally solving L*x = y for x by back
/// substitution.”
///
/// Return L.
pub fn cholesky(a: &Mat) -> Mat
{
    let z = zero::();
    let (m, n) = a.dim();
    assert!(m == n);
    let mut L = Array::::zeros((n, n));
    for i in range(0, m) {
        // Entries 0 .. i before the diagonal
        for j in range(0, i) {
            // L²_1,1
            // L_2,1 L_1,1  L²_2,1 + L²_2,2
            // L_3,1 L_1,1  L_3,1 L_2,1 + L_3,2 L_2,2  L²_3,1 + L²_3,2 + L²_3,3
            let mut lik_ljk_sum = z.clone();
            for k in range(0, j) {
                lik_ljk_sum = lik_ljk_sum + L[(i, k)] * L[(j, k)];
            }

            L[(i, j)] = (a[(i, j)] - lik_ljk_sum) / L[(j, j)];
        }
        // diagonal where i == j
        // L_j,j = Sqrt[A_j,j - Sum_k=1 to (j-1) L²_j,k ]
        let j = i;
        let mut ljk_sum = z.clone();
        for k in range(0, j) {
            let ljk = L[(j, k)];
            ljk_sum = ljk_sum + ljk * ljk;
        }
        L[(j, j)] = (a[(j, j)] - ljk_sum).sqrt();
    }
    L
}

/// Solve *L x = b* where *L* is a lower triangular matrix.
pub fn subst_fw(l: &Mat, b: &Col) -> Col
{
    let (m, n) = l.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut res = Array::zeros(m);
    for i in range(0, m) {
        let mut b_lx_sum = b[i].clone();
        for j in range(0, i) {
            b_lx_sum = b_lx_sum - l[(i, j)] * res[j];
        }
        res[i] = b_lx_sum / l[(i, i)];
    }
    res
}

/// Solve *U x = b* where *U* is an upper triangular matrix.
pub fn subst_bw(u: &Mat, b: &Col) -> Col
{
    let (m, n) = u.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut res = Array::zeros(m);
    for i in range(0, m).rev() {
        let mut b_lx_sum = b[i].clone();
        for j in range(i, m).rev() {
            b_lx_sum = b_lx_sum - u[(i, j)] * res[j];
        }
        res[i] = b_lx_sum / u[(i, i)];
    }
    res
}
<commit_msg>linalg: Use iterators where possible in cholesky and subst<commit_after>#![allow(uppercase_variables)]

//! A few linear algebra operations on two-dimensional arrays.

use std::num::{zero, one};

use super::{Array, Dimension, Ix};

/// Column vector.
pub type Col = Array;
/// Rectangular matrix.
pub type Mat = Array;

/// Return the identity matrix of dimension *n*.
pub fn eye(n: Ix) -> Mat
{
    let mut eye = Array::zeros((n, n));
    for i in range(0, n) {
        eye[(i, i)] = one::();
    }
    eye
}

/*
/// Return the inverse matrix of square matrix `a`.
pub fn inverse(a: &Mat) -> Mat
{
    fail!()
}
*/

/// Solve *a x = b* with linear least squares approximation.
///
/// It is used to find the best fit for an overdetermined system,
/// i.e. the number of rows in *a* is larger than the number of
/// unknowns *x*.
///
/// Return best fit for *x*.
pub fn least_squares(a: &Mat, b: &Col) -> Col
{
    // Using transpose: a.T a x = a.T b;
    // a.T a being square gives naive solution
    // x_lstsq = inv(a.T a) a.T b
    //
    // Solve using cholesky decomposition
    // aT a x = aT b
    //
    // Factor aT a into L L.T
    //
    // L L.T x = aT b
    //
    // => L z = aT b
    //  fw subst for z
    // => L.T x = z
    //  bw subst for x estimate
    //
    let (m, n) = a.dim();

    let mut aT = a.clone();
    aT.swap_axes(0, 1);

    let aT_a = aT.mat_mul(a);
    let mut L = cholesky(&aT_a);
    let rhs = aT.mat_mul(&b.reshape((m, 1))).reshape(n);

    // Solve L z = aT b
    let z = subst_fw(&L, &rhs);

    // Solve L.T x = z
    L.swap_axes(0, 1);
    let x_lstsq = subst_bw(&L, &z);
    x_lstsq
}

/// Factor *a = L L.T*.
///
/// *a* should be hermitian and positive definite.
///
/// https://en.wikipedia.org/wiki/Cholesky_decomposition
///
/// “The Cholesky decomposition is mainly used for the numerical solution of
/// linear equations Ax = b.
///
/// If A is symmetric and positive definite, then we can solve Ax = b by first
/// computing the Cholesky decomposition A = LL*, then solving Ly = b for y by
/// forward substitution, and finally solving L*x = y for x by back
/// substitution.”
///
/// Return L.
pub fn cholesky(a: &Mat) -> Mat
{
    let z = zero::();
    let (m, n) = a.dim();
    assert!(m == n);
    let mut L = Array::::zeros((n, n));
    for i in range(0, m) {
        // Entries 0 .. i before the diagonal
        for j in range(0, i) {
            // L²_1,1
            // L_2,1 L_1,1  L²_2,1 + L²_2,2
            // L_3,1 L_1,1  L_3,1 L_2,1 + L_3,2 L_2,2  L²_3,1 + L²_3,2 + L²_3,3
            let mut lik_ljk_sum = z.clone();
            {
                // L[(i, k)] for k = 0 .. j
                // L[(j, k)] for k = 0 .. j
                let Lik = L.row_iter(i);
                let Ljk = L.row_iter(j);
                for (&lik, &ljk) in Lik.zip(Ljk).take(j) {
                    lik_ljk_sum = lik_ljk_sum + lik * ljk;
                }
            }

            L[(i, j)] = (a[(i, j)] - lik_ljk_sum) / L[(j, j)];
        }
        // diagonal where i == j
        // L_j,j = Sqrt[A_j,j - Sum_k=1 to (j-1) L²_j,k ]
        let j = i;
        let mut ljk_sum = z.clone();
        // L[(j, k)] for k = 0 .. j
        for &ljk in L.row_iter(j).take(j) {
            ljk_sum = ljk_sum + ljk * ljk;
        }
        L[(j, j)] = (a[(j, j)] - ljk_sum).sqrt();
    }
    L
}

/// Solve *L x = b* where *L* is a lower triangular matrix.
pub fn subst_fw(l: &Mat, b: &Col) -> Col
{
    let (m, n) = l.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for (i, bi) in b.iter().enumerate() {
        // b_lx_sum = b[i] - Sum(for j = 0 .. i) L_ij x_j
        let mut b_lx_sum = bi.clone();
        for (lij, xj) in l.row_iter(i).zip(x.iter()).take(i) {
            b_lx_sum = b_lx_sum - (*lij) * (*xj)
        }
        x.as_mut_slice()[i] = b_lx_sum / l[(i, i)];
    }
    Array::from_vec(x)
}

/// Solve *U x = b* where *U* is an upper triangular matrix.
pub fn subst_bw(u: &Mat, b: &Col) -> Col
{
    let (m, n) = u.dim();
    assert!(m == n);
    assert!(m == b.dim());
    let mut x = Vec::from_elem(m, zero::());
    for i in range(0, m).rev() {
        // b_ux_sum = b[i] - Sum(for j = i .. m) U_ij x_j
        let mut b_ux_sum = b[i].clone();
        for (uij, xj) in u.row_iter(i).rev().zip(x.iter().rev()).take(m - i - 1) {
            b_ux_sum = b_ux_sum - (*uij) * (*xj);
        }
        x.as_mut_slice()[i] = b_ux_sum / u[(i, i)];
    }
    Array::from_vec(x)
}
<|endoftext|>


<commit_before>// Copyright(C) 2016 Chris Liebert
extern crate rusqlite;
extern crate time;

use self::rusqlite::Connection;
use std::path::Path;

use common::{Material, Mesh, SceneNode, Scene, Shader, Vertex8f32};

fn create_vertex8f32(px: f64,
                     py: f64,
                     pz: f64,
                     nx: f64,
                     ny: f64,
                     nz: f64,
                     tu: f64,
                     tv: f64)
                     -> Vertex8f32 {
    let position: [f32; 3] = [px as f32, py as f32, pz as f32];
    let normal: [f32; 3] = [nx as f32, ny as f32, nz as f32];
    let texcoord: [f32; 2] = [tu as f32, tv as f32];
    Vertex8f32 {
        position: position,
        normal: normal,
        texcoord: texcoord,
    }
}

pub fn load_db(filename: &str) -> Scene {
    println!("Loading {}", filename);

    let path: &Path = Path::new(filename);
    let conn = Connection::open(path).unwrap();

    // Load vertices
    let mut vertex_stmt = conn.prepare("SELECT px, py, pz, nx, ny, nz, tu, tv FROM vertex")
        .unwrap();
    let vertex_iter = vertex_stmt.query_map(&[], |row| {
            create_vertex8f32(row.get(0),
                              row.get(1),
                              row.get(2),
                              row.get(3),
                              row.get(4),
                              row.get(5),
                              row.get(6),
                              row.get(7))
        })
        .unwrap();

    let mut vertices: Vec<Vertex8f32> = Vec::new();

    for vertex in vertex_iter {
        vertices.push(vertex.unwrap());
    }

    let mut meshes: Vec<Mesh> = Vec::new();

    // Load scene nodes
    let mut scene_node_stmt =
        conn.prepare("SELECT name, material_id, start_position, end_position FROM scene_node")
            .unwrap();
    let scene_node_iter = scene_node_stmt.query_map(&[], |row| {
            SceneNode {
                name: row.get(0),
                material_id: row.get(1),
                start_position: row.get(2),
                end_position: row.get(3),
            }
        })
        .unwrap();

    for scene_node in scene_node_iter {
        let sn = scene_node.unwrap();
        let mut new_vertices: Vec<Vertex8f32> = Vec::new();

        for i in sn.start_position as usize..sn.end_position as usize {
            new_vertices.push(vertices[i]);

        }
        let mesh = Mesh {
            name: sn.name,
            material_id: sn.material_id,
            vertices: new_vertices,
        };
        meshes.push(mesh);
    }

    println!("Loaded {} vertices", vertices.len());

    // Free up some memory
    vertices.clear();

    // Load materials
    let mut material_stmt =
        conn.prepare("SELECT name, diffuse_r, diffuse_g, diffuse_b, diffuse_texname FROM material")
            .unwrap();
    let material_iter = material_stmt.query_map(&[], |row| {
            let diffuse_r: f64 = row.get(1);
            let diffuse_g: f64 = row.get(2);
            let diffuse_b: f64 = row.get(3);
            Material {
                name: row.get(0),
                diffuse: [diffuse_r as f32, diffuse_g as f32, diffuse_b as f32],
                diffuse_texname: row.get(4),
            }
        })
        .unwrap();

    let mut materials: Vec<Material> = Vec::new();

    for material in material_iter {
        materials.push(material.unwrap());
    }

    let mut shader_stmt =
        conn.prepare("SELECT name, vertex_source_140, fragment_source_140 FROM shader")
            .unwrap();
    let shader_iter = shader_stmt.query_map(&[], |row| {
            Shader {
                name: row.get(0),
                vertex_source_140: row.get(1),
                fragment_source_140: row.get(2),
            }
        })
        .unwrap();

    let mut shaders: Vec<Shader> = Vec::new();

    for shader in shader_iter {
        shaders.push(shader.unwrap());
    }

    return Scene {
        materials: materials,
        // scene_nodes: scene_nodes,
        // vertices: vertices,
        meshes: meshes,
        shaders: shaders,
    };
}
<commit_msg>added number of meshes to output<commit_after>// Copyright(C) 2016 Chris Liebert
extern crate rusqlite;
extern crate time;

use self::rusqlite::Connection;
use std::path::Path;

use common::{Material, Mesh, SceneNode, Scene, Shader, Vertex8f32};

fn create_vertex8f32(px: f64,
                     py: f64,
                     pz: f64,
                     nx: f64,
                     ny: f64,
                     nz: f64,
                     tu: f64,
                     tv: f64)
                     -> Vertex8f32 {
    let position: [f32; 3] = [px as f32, py as f32, pz as f32];
    let normal: [f32; 3] = [nx as f32, ny as f32, nz as f32];
    let texcoord: [f32; 2] = [tu as f32, tv as f32];
    Vertex8f32 {
        position: position,
        normal: normal,
        texcoord: texcoord,
    }
}

pub fn load_db(filename: &str) -> Scene {
    println!("Loading {}", filename);

    let path: &Path = Path::new(filename);
    let conn = Connection::open(path).unwrap();

    // Load vertices
    let mut vertex_stmt = conn.prepare("SELECT px, py, pz, nx, ny, nz, tu, tv FROM vertex")
        .unwrap();
    let vertex_iter = vertex_stmt.query_map(&[], |row| {
            create_vertex8f32(row.get(0),
                              row.get(1),
                              row.get(2),
                              row.get(3),
                              row.get(4),
                              row.get(5),
                              row.get(6),
                              row.get(7))
        })
        .unwrap();

    let mut vertices: Vec<Vertex8f32> = Vec::new();

    for vertex in vertex_iter {
        vertices.push(vertex.unwrap());
    }

    let mut meshes: Vec<Mesh> = Vec::new();

    // Load scene nodes
    let mut scene_node_stmt =
        conn.prepare("SELECT name, material_id, start_position, end_position FROM scene_node")
            .unwrap();
    let scene_node_iter = scene_node_stmt.query_map(&[], |row| {
            let material_id: i32 = row.get(1);
            SceneNode {
                name: row.get(0),
                material_id: material_id - 1, // index starts at 1 in database, not 0
                start_position: row.get(2),
                end_position: row.get(3),
            }
        })
        .unwrap();

    for scene_node in scene_node_iter {
        let sn = scene_node.unwrap();
        let mut new_vertices: Vec<Vertex8f32> = Vec::new();

        for i in sn.start_position as usize..(sn.end_position - 1) as usize {
            new_vertices.push(vertices[i]);

        }
        let mesh = Mesh {
            name: sn.name,
            material_id: sn.material_id,
            vertices: new_vertices,
        };
        meshes.push(mesh);
    }

    println!("Loaded {} vertices in {} meshes",
             vertices.len(),
             meshes.len());

    // Free up some memory
    vertices.clear();

    // Load materials
    let mut material_stmt =
        conn.prepare("SELECT name, diffuse_r, diffuse_g, diffuse_b, diffuse_texname FROM material")
            .unwrap();
    let material_iter = material_stmt.query_map(&[], |row| {
            let diffuse_r: f64 = row.get(1);
            let diffuse_g: f64 = row.get(2);
            let diffuse_b: f64 = row.get(3);
            Material {
                name: row.get(0),
                diffuse: [diffuse_r as f32, diffuse_g as f32, diffuse_b as f32],
                diffuse_texname: row.get(4),
            }
        })
        .unwrap();

    let mut materials: Vec<Material> = Vec::new();

    for material in material_iter {
        materials.push(material.unwrap());
    }

    let mut shader_stmt =
        conn.prepare("SELECT name, vertex_source_140, fragment_source_140 FROM shader")
            .unwrap();
    let shader_iter = shader_stmt.query_map(&[], |row| {
            Shader {
                name: row.get(0),
                vertex_source_140: row.get(1),
                fragment_source_140: row.get(2),
            }
        })
        .unwrap();

    let mut shaders: Vec<Shader> = Vec::new();

    for shader in shader_iter {
        shaders.push(shader.unwrap());
    }

    return Scene {
        materials: materials,
        // scene_nodes: scene_nodes,
        // vertices: vertices,
        meshes: meshes,
        shaders: shaders,
    };
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::Write;
use std::path::Path;
use cpu::CpuState;
use memory::Memory;
use cpu::AddressMode;
use std::fmt::UpperHex;

use std::vec;
use cpu::OpcodeDebugInfo;

//collections::vec::Vec<cpu::common_defs::OpcodeDebugInfo>

pub struct NesTest {
    f:File,
    op_info: Vec<OpcodeDebugInfo>,
}

impl NesTest {
    pub fn new<P:AsRef<Path>>(file_path: P, opcode_info:Vec<OpcodeDebugInfo>) -> NesTest {
        NesTest {
            f : File::create(&file_path).unwrap(),
            op_info: opcode_info,
        }
    }

    pub fn log_after_fetch(self: &mut NesTest, cpu_state: &CpuState, mem: &Memory) {
        let pc = cpu_state.pc-1;
        let dr = &cpu_state.decode_register;
        let len = cpu_state.decode_register.info.len;
        let opcode = cpu_state.instruction_register;
        let info = &self.op_info[opcode as usize];

        let mut s:String = format!("{:0>4X}  ",pc).to_owned();

        match len {
            1 => { s.push_str(&format!("{:0>2X}            ",cpu_state.instruction_register)) },
            2 => { s.push_str(&format!("{:0>2X} {:0>2X}    ",cpu_state.instruction_register,mem.read8(pc+1).unwrap())) },
            3 => { s.push_str(&format!("{:0>2X} {:0>2X} {:0>2X} ",cpu_state.instruction_register,mem.read8(pc+1).unwrap(),mem.read8(pc+2).unwrap())) },
            _ => panic!("instructions should have a length of 1, 2, or 3.")
        }

        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { let _ = self.f.write(s.as_bytes()); panic!("Accumulator addressing mode is unimplemented"); },
            AddressMode::Implied      => { let _ = self.f.write(s.as_bytes()); panic!("Implied addressing mode is unimplemented"); },

            //explicit addresses from here on out
            AddressMode::Absolute =>        {
                s.push_str(&format!(" {} ${:0>4X}",info.name,mem.read16(pc+1).unwrap()));
            },
            AddressMode::AbsoluteX       => { let _ = self.f.write(s.as_bytes()); panic!("AbsoluteX addressing mode is unimplemented"); },
            AddressMode::AbsoluteY       => { let _ = self.f.write(s.as_bytes()); panic!("AbsoluteY addressing mode is unimplemented"); },
            AddressMode::Immediate       => {
                s.push_str(&format!(" {} #${:0>2X}",info.name,mem.read8(pc+1).unwrap()));
            }
            AddressMode::Indirect        => { let _ = self.f.write(s.as_bytes()); panic!("Indirect addressing mode is unimplemented"); },
            AddressMode::IndexedIndirect => { let _ = self.f.write(s.as_bytes()); panic!("IndexedIndirect addressing mode is unimplemented"); },
            AddressMode::IndirectIndexed => { let _ = self.f.write(s.as_bytes()); panic!("IndirectIndexed addressing mode is unimplemented"); },
            AddressMode::Relative        => { let _ = self.f.write(s.as_bytes()); panic!("Relative addressing mode is unimplemented"); },
            AddressMode::ZeroPage        => {
                s.push_str(&format!(" {} ${:0>2X} = {:0>2X}",info.name, cpu_state.decode_register.addr_final.unwrap(),cpu_state.decode_register.value_final.unwrap()));
            },
            AddressMode::ZeroPageX       => { let _ = self.f.write(s.as_bytes()); panic!("ZeroPageX addressing mode is unimplemented"); },
            AddressMode::ZeroPageY       => { let _ = self.f.write(s.as_bytes()); panic!("ZeroPageY addressing mode is unimplemented"); },
            _ => { let _ = self.f.write(s.as_bytes()); panic!("unrecognized addressing mode") }
        }
        let len = s.len();
        s.push_str(&format!("{output:>0$}",48-len,output="")); // spacing
        s.push_str(&format!("A:{:0>2X}",cpu_state.a));
        s.push_str(&format!(" X:{:0>2X}",cpu_state.x));
        s.push_str(&format!(" Y:{:0>2X}",cpu_state.y));
        s.push_str(&format!(" P:{:0>2X}",cpu_state.unpack_flags()));
        s.push_str(&format!(" SP:{:0>2X}\n",cpu_state.sp));

        self.f.write(s.as_bytes());
    }
}

<commit_msg>logger now uses the decode_register for the addressing mode logging<commit_after>use std::fs::File;
use std::io::Write;
use std::path::Path;
use cpu::CpuState;
use memory::Memory;
use cpu::AddressMode;
use std::fmt::UpperHex;

use std::vec;
use cpu::OpcodeDebugInfo;

//collections::vec::Vec<cpu::common_defs::OpcodeDebugInfo>

pub struct NesTest {
    f:File,
    op_info: Vec<OpcodeDebugInfo>,
}

impl NesTest {
    pub fn new<P:AsRef<Path>>(file_path: P, opcode_info:Vec<OpcodeDebugInfo>) -> NesTest {
        NesTest {
            f : File::create(&file_path).unwrap(),
            op_info: opcode_info,
        }
    }

    pub fn log_after_fetch(self: &mut NesTest, cpu_state: &CpuState, mem: &Memory) {
        let pc = cpu_state.pc-1;
        let dr = &cpu_state.decode_register;
        let len = cpu_state.decode_register.info.len;
        let opcode = cpu_state.instruction_register;
        let info = &self.op_info[opcode as usize];

        let mut s:String = format!("{:0>4X}  ",pc).to_owned();

        match len {
            1 => { s.push_str(&format!("{:0>2X}            ",cpu_state.instruction_register)) },
            2 => { s.push_str(&format!("{:0>2X} {:0>2X}    ",cpu_state.instruction_register,mem.read8(pc+1).unwrap())) },
            3 => { s.push_str(&format!("{:0>2X} {:0>2X} {:0>2X} ",cpu_state.instruction_register,mem.read8(pc+1).unwrap(),mem.read8(pc+2).unwrap())) },
            _ => panic!("instructions should have a length of 1, 2, or 3.")
        }

        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { let _ = self.f.write(s.as_bytes()); panic!("Accumulator addressing mode is unimplemented"); },
            AddressMode::Implied      => { let _ = self.f.write(s.as_bytes()); panic!("Implied addressing mode is unimplemented"); },

            //explicit addresses from here on out
            AddressMode::Absolute =>        {
                s.push_str(&format!(" {} ${:0>4X}",info.name, cpu_state.decode_register.addr_final.unwrap()));
            },
            AddressMode::AbsoluteX       => { let _ = self.f.write(s.as_bytes()); panic!("AbsoluteX addressing mode is unimplemented"); },
            AddressMode::AbsoluteY       => { let _ = self.f.write(s.as_bytes()); panic!("AbsoluteY addressing mode is unimplemented"); },
            AddressMode::Immediate       => {
                s.push_str(&format!(" {} #${:0>2X}",info.name,cpu_state.decode_register.value_final.unwrap()));
            }
            AddressMode::Indirect        => { let _ = self.f.write(s.as_bytes()); panic!("Indirect addressing mode is unimplemented"); },
            AddressMode::IndexedIndirect => { let _ = self.f.write(s.as_bytes()); panic!("IndexedIndirect addressing mode is unimplemented"); },
            AddressMode::IndirectIndexed => { let _ = self.f.write(s.as_bytes()); panic!("IndirectIndexed addressing mode is unimplemented"); },
            AddressMode::Relative        => { let _ = self.f.write(s.as_bytes()); panic!("Relative addressing mode is unimplemented"); },
            AddressMode::ZeroPage        => {
                s.push_str(&format!(" {} ${:0>2X} = {:0>2X}",info.name, cpu_state.decode_register.addr_final.unwrap(),cpu_state.decode_register.value_final.unwrap()));
            },
            AddressMode::ZeroPageX       => { let _ = self.f.write(s.as_bytes()); panic!("ZeroPageX addressing mode is unimplemented"); },
            AddressMode::ZeroPageY       => { let _ = self.f.write(s.as_bytes()); panic!("ZeroPageY addressing mode is unimplemented"); },
            _ => { let _ = self.f.write(s.as_bytes()); panic!("unrecognized addressing mode") }
        }
        let len = s.len();
        s.push_str(&format!("{output:>0$}",48-len,output="")); // spacing
        s.push_str(&format!("A:{:0>2X}",cpu_state.a));
        s.push_str(&format!(" X:{:0>2X}",cpu_state.x));
        s.push_str(&format!(" Y:{:0>2X}",cpu_state.y));
        s.push_str(&format!(" P:{:0>2X}",cpu_state.unpack_flags()));
        s.push_str(&format!(" SP:{:0>2X}\n",cpu_state.sp));

        self.f.write(s.as_bytes());
    }
}

<|endoftext|>


<commit_before>macro_rules! verbose {
    ($config: expr, $status: expr, $message: expr) => (
        $config
            .shell()
            .verbose(
                |sh| -> CargoResult<()> { sh.status($status, $message) },
            )?
    )
}

#[cfg(feature = "debug")]
macro_rules! debug {
    ($config: expr, $message: expr) => (
        $config.shell().status_with_color("DEBUG", $message, ::termcolor::Color::White)?
    );
    ($config: expr, $($arg: tt)*) => (
        $config.shell().status_with_color("DEBUG", format!($($arg)*), ::termcolor::Color::White)?
    );
}

#[cfg(not(feature = "debug"))]
macro_rules! debug {
    ($config: expr, $message: expr) => ();
    ($config: expr, $($arg: tt)*) => ();
}
<commit_msg>style: rustfmt run<commit_after>macro_rules! verbose {
    ($config: expr, $status: expr, $message: expr) => {
        $config
            .shell()
            .verbose(|sh| -> CargoResult<()> { sh.status($status, $message) })?
    };
}

#[cfg(feature = "debug")]
macro_rules! debug {
    ($config: expr, $message: expr) => (
        $config.shell().status_with_color("DEBUG", $message, ::termcolor::Color::White)?
    );
    ($config: expr, $($arg: tt)*) => (
        $config.shell().status_with_color("DEBUG", format!($($arg)*), ::termcolor::Color::White)?
    );
}

#[cfg(not(feature = "debug"))]
macro_rules! debug {
    ($config: expr, $message: expr) => {};
    ($config: expr, $($arg: tt)*) => {};
}
<|endoftext|>


<commit_before>// Rust Bitcoin Library
// Written in 2014 by
//     Andrew Poelstra <apoelstra@wpsoftware.net>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

//! Macros
//!
//! Macros available to users of the Bitcoin library

#[macro_export]
macro_rules! nu_select {
    ($($name:pat = $rx:expr => $code:expr),+) => ({
        nu_select!{ $($name = $rx, recv => $code),+ }
    });
    ($($name:pat = $rx:expr, $meth:ident => $code:expr),+) => ({
        use rustrt::local::Local;
        use rustrt::task::Task;
        use sync::comm::Packet;

        // Is anything already ready to receive? Grab it without waiting.
        $(
            if (&$rx as &Packet).can_recv() {
                let $name = $rx.$meth();
                $code
            }
        )else+
        else {
            // Start selecting on as many as we need to before getting a bite.
            // Keep count of how many, since we need to abort every selection
            // that we started.
            let mut started_count = 0;
            // Restrict lifetime of borrows in `packets`
            {
                let packets = [ $( &$rx as &Packet, )+ ];

                let task: Box<Task> = Local::take();
                task.deschedule(packets.len(), |task| {
                    match packets[started_count].start_selection(task) {
                        Ok(()) => {
                            started_count += 1;
                            Ok(())
                        }
                        Err(task) => Err(task)
                    }
                });
            }

            let mut i = 0;
            let ret = $(
                // Abort the receivers, stopping at the first ready one to get its data.
                if { i += 1; i <= started_count } &&
                     // If start_selection() failed, abort_selection() will fail too,
                     // but it still counts as "data available".
                     ($rx.abort_selection() || i == started_count) {
                    // React to the first
                    let $name = $rx.$meth();
                    $code
                })else+
                else {
                    fail!("we didn't find the ready receiver, but we should have had one");
                };
            // At this point, the first i receivers have been aborted. We need to abort the rest:
            $(if i > 0 {
                i -= 1;
            } else {
                $rx.abort_selection();
            })+
            let _ = i; // Shut up `i -= 1 but i is never read` warning
            // Return
            ret
        }
    })
}

#[macro_export]
macro_rules! user_enum {
    (
        $(#[$attr:meta])*
        pub enum $name:ident {
            $(#[$doc:meta]
              $elem:ident <-> $txt:expr),*
        }
    ) => (
        $(#[$attr])*
        pub enum $name {
            $(#[$doc] $elem),*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                f.pad(match *self {
                    $($name::$elem => $txt),*
                })
            }
        }

        impl ::std::fmt::Display for $name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                f.pad(match *self {
                    $($name::$elem => $txt),*
                })
            }
        }

        impl ::std::str::FromStr for $name {
            type Err = ::std::io::Error;
            #[inline]
            fn from_str(s: &str) -> Result<Self, Self::Err> {
                match s {
                    $($txt => Ok($name::$elem)),*,
                    _ => Err(::std::io::Error::new(
                        ::std::io::ErrorKind::InvalidInput,
                        format!("Unknown network (type {})", s),
                    )),
                }
            }
        }

        #[cfg(feature = "serde")]
        impl<'de> $crate::serde::Deserialize<'de> for $name {
            #[inline]
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
            where
                D: $crate::serde::Deserializer<'de>,
            {
                use $crate::std::fmt::{self, Formatter};

                struct Visitor;
                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
                    type Value = $name;

                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
                        formatter.write_str("an enum value")
                    }

                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        static FIELDS: &'static [&'static str] = &[$(stringify!($txt)),*];

                        $( if v == $txt { Ok($name::$elem) } )else*
                        else {
                            Err(E::unknown_variant(v, FIELDS))
                        }
                    }

                    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        self.visit_str(v)
                    }

                    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        self.visit_str(&v)
                    }

                }

                deserializer.deserialize_str(Visitor)
            }
        }

        #[cfg(feature = "serde")]
        impl ::serde::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: ::serde::Serializer,
            {
                serializer.serialize_str(&self.to_string())
            }
        }
    );
}

<commit_msg>Remove nu_select macro<commit_after>// Rust Bitcoin Library
// Written in 2014 by
//     Andrew Poelstra <apoelstra@wpsoftware.net>
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

//! Macros
//!
//! Macros available to users of the Bitcoin library

#[macro_export]
macro_rules! user_enum {
    (
        $(#[$attr:meta])*
        pub enum $name:ident {
            $(#[$doc:meta]
              $elem:ident <-> $txt:expr),*
        }
    ) => (
        $(#[$attr])*
        pub enum $name {
            $(#[$doc] $elem),*
        }

        impl ::std::fmt::Debug for $name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                f.pad(match *self {
                    $($name::$elem => $txt),*
                })
            }
        }

        impl ::std::fmt::Display for $name {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                f.pad(match *self {
                    $($name::$elem => $txt),*
                })
            }
        }

        impl ::std::str::FromStr for $name {
            type Err = ::std::io::Error;
            #[inline]
            fn from_str(s: &str) -> Result<Self, Self::Err> {
                match s {
                    $($txt => Ok($name::$elem)),*,
                    _ => Err(::std::io::Error::new(
                        ::std::io::ErrorKind::InvalidInput,
                        format!("Unknown network (type {})", s),
                    )),
                }
            }
        }

        #[cfg(feature = "serde")]
        impl<'de> $crate::serde::Deserialize<'de> for $name {
            #[inline]
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
            where
                D: $crate::serde::Deserializer<'de>,
            {
                use $crate::std::fmt::{self, Formatter};

                struct Visitor;
                impl<'de> $crate::serde::de::Visitor<'de> for Visitor {
                    type Value = $name;

                    fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
                        formatter.write_str("an enum value")
                    }

                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        static FIELDS: &'static [&'static str] = &[$(stringify!($txt)),*];

                        $( if v == $txt { Ok($name::$elem) } )else*
                        else {
                            Err(E::unknown_variant(v, FIELDS))
                        }
                    }

                    fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        self.visit_str(v)
                    }

                    fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
                    where
                        E: $crate::serde::de::Error,
                    {
                        self.visit_str(&v)
                    }

                }

                deserializer.deserialize_str(Visitor)
            }
        }

        #[cfg(feature = "serde")]
        impl ::serde::Serialize for $name {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: ::serde::Serializer,
            {
                serializer.serialize_str(&self.to_string())
            }
        }
    );
}

<|endoftext|>


<commit_before>#[macro_export]
macro_rules! start_tag {
  ($name:expr) => {
    ($crate::Event::StartTag {
      name: ::std::borrow::Cow::from($name),
      attrs: $crate::Attribute::none(),
    })
  };
  ($name:expr, $attrs:expr) => {
    ($crate::Event::StartTag {
      name: ::std::borrow::Cow::from($name),
      attrs: $attrs,
    })
  };
}

#[macro_export]
macro_rules! closed_tag {
  ($name:expr) => {
    ($crate::Event::ClosedTag {
      name: ::std::borrow::Cow::from($name),
      attrs: $crate::Attribute::none(),
    })
  };
  ($name:expr, $attrs:expr) => {
    ($crate::Event::ClosedTag {
      name: ::std::borrow::Cow::from($name),
      attrs: $attrs,
    })
  };
}

#[macro_export]
macro_rules! end_tag {
  ($name:expr) => {
    ($crate::Event::EndTag {
      name: ::std::borrow::Cow::from($name),
    })
  };
}

#[macro_export]
macro_rules! text {
  ($text:expr) => {
    ($crate::Event::Text(::std::borrow::Cow::from($text)))
  };
}

#[macro_export]
macro_rules! raw_html {
  ($html:expr) => {
    ($crate::Event::RawHtml(::std::borrow::Cow::from($html)))
  };
}

#[macro_export]
macro_rules! attr {
  ($name:expr => $value:expr) => {
    ($crate::Attribute {
      name: ::std::borrow::Cow::from($name),
      value: ::std::borrow::Cow::from($value),
    })
  }
}

#[macro_export]
macro_rules! attrs {
  ($($name:expr => $value:expr),+) => {
    (::std::borrow::Cow::Owned(vec![
      $(attr!($name => $value)),+
    ]))
  }
}
<commit_msg>Reformat macros<commit_after>#[macro_export]
macro_rules! start_tag {
    ($name:expr) => {
        ($crate::Event::StartTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $crate::Attribute::none(),
        })
    };
    ($name:expr, $attrs:expr) => {
        ($crate::Event::StartTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $attrs,
        })
    };
}

#[macro_export]
macro_rules! closed_tag {
    ($name:expr) => {
        ($crate::Event::ClosedTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $crate::Attribute::none(),
        })
    };
    ($name:expr, $attrs:expr) => {
        ($crate::Event::ClosedTag {
            name: ::std::borrow::Cow::from($name),
            attrs: $attrs,
        })
    };
}

#[macro_export]
macro_rules! end_tag {
    ($name:expr) => {
        ($crate::Event::EndTag {
            name: ::std::borrow::Cow::from($name),
        })
    };
}

#[macro_export]
macro_rules! text {
    ($text:expr) => {
        ($crate::Event::Text(::std::borrow::Cow::from($text)))
    };
}

#[macro_export]
macro_rules! raw_html {
    ($html:expr) => {
        ($crate::Event::RawHtml(::std::borrow::Cow::from($html)))
    };
}

#[macro_export]
macro_rules! attr {
    ($name:expr => $value:expr) => {
        ($crate::Attribute {
            name: ::std::borrow::Cow::from($name),
            value: ::std::borrow::Cow::from($value),
        })
    }
}

#[macro_export]
macro_rules! attrs {
    ($($name:expr => $value:expr),+) => {
        (::std::borrow::Cow::Owned(vec![
            $(attr!($name => $value)),+
        ]))
    }
}
<|endoftext|>


<commit_before>// Used to specify checks that shouldn't fail (but might in unsafe)
macro_rules! dbg_gl_error {
    ($($pat:pat => $msg:expr),*) => {
        if cfg!(debug_assertions) {
            let err = $crate::Context::get_error();
            match err {
                $(Some($pat) => {
                    panic!("OpenGL error {:?} - {}", err, $msg)
                }),*
                None => { }
            }
        }
    }
}

// Used to specify checks that should *never* be able to fail (even in unsafe!)
macro_rules! dbg_gl_sanity_check {
    ($($pat:pat => $msg:expr),*) => {
        dbg_gl_error! { $($pat => concat!("Sanity check failed: ", $msg)),* }
    }
}

macro_rules! gl_enum {
    (
        pub gl_enum $name:ident {
            $($variant:ident as $const_name:ident = $value:expr),+
        }
    ) => {
        #[derive(Debug, Clone, Copy)]
        pub enum $name {
            $($variant = $value as isize),+
        }
        $(pub const $const_name: $name = $name::$variant;)+
    }
}
<commit_msg>Add `from_gl()` and `gl_enum()` to all `gl_enum!` types<commit_after>// Used to specify checks that shouldn't fail (but might in unsafe)
macro_rules! dbg_gl_error {
    ($($pat:pat => $msg:expr),*) => {
        if cfg!(debug_assertions) {
            let err = $crate::Context::get_error();
            match err {
                $(Some($pat) => {
                    panic!("OpenGL error {:?} - {}", err, $msg)
                }),*
                None => { }
            }
        }
    }
}

// Used to specify checks that should *never* be able to fail (even in unsafe!)
macro_rules! dbg_gl_sanity_check {
    ($($pat:pat => $msg:expr),*) => {
        dbg_gl_error! { $($pat => concat!("Sanity check failed: ", $msg)),* }
    }
}

macro_rules! gl_enum {
    (
        pub gl_enum $name:ident {
            $($variant:ident as $const_name:ident = $value:expr),+
        }
    ) => {
        #[derive(Debug, Clone, Copy)]
        pub enum $name {
            $($variant = $value as isize),+
        }
        $(pub const $const_name: $name = $name::$variant;)+

        #[allow(dead_code)]
        impl $name {
            pub fn from_gl(gl_enum: $crate::gl::types::GLenum)
                -> Result<Self, ()>
            {
                match gl_enum {
                    $(x if x == $value => { Ok($name::$variant) },)+
                    _ => { Err(()) }
                }
            }

            pub fn gl_enum(&self) -> $crate::gl::types::GLenum {
                *self as $crate::gl::types::GLenum
            }
        }
    }
}
<|endoftext|>