<commit_before>// a & a: same side, a & A: Different side
pub const THEOREM_DEFINE: &'static [&'static str] = &["
+ + ! +x+
 0  ! x0x
+ + ! +x+
", "
+ + + + ! + + + +
        !   | x
+ + + + ! +x+-+x+
 0 3    ! x0x3|
+ + + + ! +x+-+x+
        !   | x
+ + + + ! + + + +
", "
+ + + + ! +x+ + +
 0      ! x0x
+ + + + ! +x+-+ +
   3    !   |3 a
+ + + + ! + + + +
        !    A
+ + + + ! + + + +
", "
+ + + ! + + +
      !   xa
+ + + ! + + +
 3 3  ! |3|3|
+ + + ! + + +
      !   xA
+ + + ! + + +
", "
+ + + ! +-+ +
 2    !  2xa
+ + + ! + + +
 3 3  ! |3|3|
+ + + ! + + +
      !   xA
+ + + ! + + +
", "
+ + + + + ! + + + + +
          !   x
+ + + + + ! +x+-+ + +
   3      !   |3 a
+ + + + + ! + + + + +
     3    !    A 3|
+ + + + + ! + + +-+x+
          !       x
+ + + + + ! + + + + +
", "
+ + + + + + ! + + + + + +
            !   x     x
+ + + + + + ! +x+-+x+-+x+
   3   3    !   |3 a 3|
+ + + + + + ! + + + + + +
     3      !    A|3|A
+ + + + + + ! + +x+-+x+ +
            !     x x
+ + + + + + ! + + + + + +
", "
+ + + + ! + +x+ +
  | |   !   | |
+ +-+ + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+-+ ! +-+
 1  ! x1x
+ + ! +x+
", "
+ + ! +-+
x1x ! x1x
+x+ ! +x+
", "
+ + + ! +x+ +
 2|   ! x2|
+-+ + ! +-+x+
      !   x
+ + + ! + + +
", "
+ + ! +x+
|2| ! |2|
+ + ! +x+
", "
+x+ + ! +x+ +
x2    ! x2|
+ + + ! +-+x+
      !   x
+ + + ! + + +
", "
+x+ ! +x+
 2  ! |2|
+x+ ! +x+
", "
+ + + + ! + +x+ +
  |3|   !   |3|
+ +-+ + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+ +x+ + ! + +x+ +
   3    !   |3|
+ + + + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+ + + ! + + +
      !   x
+-+ + ! +-+x+
  |   !   |
+ + + ! + + +
", "
+ + + ! + + +
      !   x
+-+-+ ! +-+-+
      !   x
+ + + ! + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +x+ +
 a 1    !  ax1 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 a 2    !  a 2 A
+ + + + ! + + + +
        !    A
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !   xa
+ + + + ! +x+-+ +
 a 3    !  a|3 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + ! + + +
   a  !    a
+ + + ! + + +
 A 1  !  A 1x
+ + + ! + +x+
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 A 2    !  A 2 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 A 3    !  A 3|
+ + + + ! + +-+x+
        !     x
+ + + + ! + + + +
", "
+ + + ! + + +
  x   !   x
+ + + ! +-+ +
 3 1  !  3 1x
+ + + ! + +x+
", "
+ + + + + ! + + +-+ +
     2x   !    a 2x
+ + + + + ! + + + + +
   3      !   |3 A
+ + + + + ! +x+-+ + +
          !   x
+ + + + + ! + + + + +
", "
+ + + + ! + +-+ +
   2x   !    2x
+ + +-+ ! + + +-+
   3    !   |3
+ + + + ! +x+-+ +
        !   x
+ + + + ! + + + +
", "
+ + + ! + + +
    | !     |
+ + + ! + + +
   3  !   |3
+ + + ! +x+-+
      !   x
+ + + ! + + +
", "
+ +  + + ! + +  + +
      a  !       a
+ +  + + ! + +  + +
   3a    !   |3a
+ +  + + ! +x+--+ +
         !   x
+ +  + + ! + +  + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +x+ +
   1    !  b 1 B
+ + + + ! + +x+ +
   a    !    a
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
   2    !  A 2 A
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +-+ +
   3    !  b 3 B
+ + + + ! + +-+ +
   a    !    a
+ + + + ! + + + +
", "
+ + ! + +
 a  !  a
+ + ! + +
 1  ! x1x
+ + ! + +
 A  !  A
+ + ! + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
   2    !  b 2 B
+ + + + ! + + + +
   A    !    A
+ + + + ! + + + +
", "
+ + ! + +
 a  !  a
+ + ! + +
 3  ! |3|
+ + ! + +
 A  !  A
+ + ! + +
"];

#[cfg(test)]
mod tests {
    use ::theorem::Theorem;

    #[test]
    fn parse() {
        for s in super::THEOREM_DEFINE {
            if !s.parse::<Theorem>().is_ok() {
                println!("{:?}", s.parse::<Theorem>());
                println!("{}", s);
            }
            assert!(s.parse::<Theorem>().is_ok());
        }
    }
}
<commit_msg>Fix test failure<commit_after>// a & a: same side, a & A: Different side
pub const THEOREM_DEFINE: &'static [&'static str] = &["
+ + ! +x+
 0  ! x0x
+ + ! +x+
", "
+ + + + ! + + + +
        !   | x
+ + + + ! +x+-+x+
 0 3    ! x0x3|
+ + + + ! +x+-+x+
        !   | x
+ + + + ! + + + +
", "
+ + + + ! +x+ + +
 0      ! x0x
+ + + + ! +x+-+ +
   3    !   |3 a
+ + + + ! + + + +
        !    A
+ + + + ! + + + +
", "
+ + + ! + + +
      !   xa
+ + + ! + + +
 3 3  ! |3|3|
+ + + ! + + +
      !   xA
+ + + ! + + +
", "
+ + + ! +-+ +
 2    !  2xa
+ + + ! + + +
 3 3  ! |3|3|
+ + + ! + + +
      !   xA
+ + + ! + + +
", "
+ + + + + ! + + + + +
          !   x
+ + + + + ! +x+-+ + +
   3      !   |3 a
+ + + + + ! + + + + +
     3    !    A 3|
+ + + + + ! + + +-+x+
          !       x
+ + + + + ! + + + + +
", "
+ + + + + + ! + + + + + +
            !   x     x
+ + + + + + ! +x+-+x+-+x+
   3   3    !   |3 a 3|
+ + + + + + ! + + + + + +
     3      !    A|3|A
+ + + + + + ! + +x+-+x+ +
            !     x x
+ + + + + + ! + + + + + +
", "
+ + + + ! + +x+ +
  | |   !   | |
+ +-+ + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+-+ ! +-+
 1  ! x1x
+ + ! +x+
", "
+ + ! +-+
x1x ! x1x
+x+ ! +x+
", "
+ + + ! +x+ +
 2|   ! x2|
+-+ + ! +-+x+
      !   x
+ + + ! + + +
", "
+ + ! +x+
|2| ! |2|
+ + ! +x+
", "
+x+ + ! +x+ +
x2    ! x2|
+ + + ! +-+x+
      !   x
+ + + ! + + +
", "
+x+ ! +x+
 2  ! |2|
+x+ ! +x+
", "
+ + + + ! + +x+ +
  |3|   !   |3|
+ +-+ + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+ +x+ + ! + +x+ +
   3    !   |3|
+ + + + ! +x+-+x+
        !   x x
+ + + + ! + + + +
", "
+ + + ! + + +
      !   x
+-+ + ! +-+x+
  |   !   |
+ + + ! + + +
", "
+ + + ! + + +
      !   x
+-+-+ ! +-+-+
      !   x
+ + + ! + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +x+ +
 a 1    !  ax1 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 a 2    !  a 2 A
+ + + + ! + + + +
        !    A
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !   xa
+ + + + ! +x+-+ +
 a 3    !  a|3 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + ! + + +
   a  !    a
+ + + ! + + +
 A 1  !  A 1x
+ + + ! + +x+
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 A 2    !  A 2 b
+ + + + ! + + + +
        !    B
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
 A 3    !  A 3|
+ + + + ! + +-+x+
        !     x
+ + + + ! + + + +
", "
+ + + ! + + +
  x   !   x
+ + + ! +-+ +
 3 1  !  3 1x
+ + + ! + +x+
", "
+ + + + + ! + + +-+ +
     2x   !    a 2x
+ + + + + ! + + + + +
   3      !   |3 A
+ + + + + ! +x+-+ + +
          !   x
+ + + + + ! + + + + +
", "
+ + + + ! + +-+ +
   2x   !    2x
+ + +-+ ! + + +-+
   3    !   |3
+ + + + ! +x+-+ +
        !   x
+ + + + ! + + + +
", "
+ + + ! + + +
    | !     |
+ + + ! + + +
   3  !   |3
+ + + ! +x+-+
      !   x
+ + + ! + + +
", "
+ +  + + ! + +  + +
      a  !       a
+ +  + + ! + +  + +
   3a    !   |3a
+ +  + + ! +x+--+ +
         !   x
+ +  + + ! + +  + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +x+ +
   1    !  b 1 B
+ + + + ! + +x+ +
   a    !    a
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
   2    !  A 2 A
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + +-+ +
   3    !  b 3 B
+ + + + ! + +-+ +
   a    !    a
+ + + + ! + + + +
", "
+ + ! + +
 a  !  a
+ + ! + +
 1  ! x1x
+ + ! + +
 A  !  A
+ + ! + +
", "
+ + + + ! + + + +
   a    !    a
+ + + + ! + + + +
   2    !  b 2 B
+ + + + ! + + + +
   A    !    A
+ + + + ! + + + +
", "
+ + ! + +
 a  !  a
+ + ! + +
 3  ! |3|
+ + ! + +
 A  !  A
+ + ! + +
"];

#[cfg(test)]
mod tests {
    use ::model::theorem::Theorem;

    #[test]
    fn parse() {
        for s in super::THEOREM_DEFINE {
            if !s.parse::<Theorem>().is_ok() {
                println!("{:?}", s.parse::<Theorem>());
                println!("{}", s);
            }
            assert!(s.parse::<Theorem>().is_ok());
        }
    }
}
<|endoftext|>


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

// ignore-pretty issue #37201

// This test is ensuring that parameters are indeed dropped after
// temporaries in a fn body.

use std::cell::RefCell;

use self::d::D;

pub fn main() {
    let log = RefCell::new(vec![]);
    d::println("created empty log");
    test(&log);

    assert_eq!(&log.borrow()[..],
               [
                   //                                    created empty log
                   //    +-- Make D(da_0, 0)
                   //    | +-- Make D(de_1, 1)
                   //    | |                             calling foo
                   //    | |                             entered foo
                   //    | | +-- Make D(de_2, 2)
                   //    | | | +-- Make D(da_1, 3)
                   //    | | | | +-- Make D(de_3, 4)
                   //    | | | | | +-- Make D(de_4, 5)
                   3, // | | | +-- Drop D(da_1, 3)
                   //    | | |   | |
                   4, // | | |   +-- Drop D(de_3, 4)
                   //    | | |     |
                   //    | | |     |                     eval tail of foo
                   //    | | | +-- Make D(de_5, 6)
                   //    | | | | +-- Make D(de_6, 7)
                   5, // | | | | | +-- Drop D(de_4, 5)
                   //    | | | | |
                   2, // | | +-- Drop D(de_2, 2)
                   //    | |   | |
                   6, // | |   +-- Drop D(de_5, 6)
                   //    | |     |
                   1, // | +-- Drop D(de_1, 1)
                   //    |       |
                   0, // +-- Drop D(da_0, 0)
                   //            |
                   //            |                       result D(de_6, 7)
                   7 //          +-- Drop D(de_6, 7)

                       ]);
}

fn test<'a>(log: d::Log<'a>) {
    let da = D::new("da", 0, log);
    let de = D::new("de", 1, log);
    d::println("calling foo");
    let result = foo(da, de);
    d::println(&format!("result {}", result));
}

// FIXME(#33490) Remove the double braces when old trans is gone.
fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {{
    d::println("entered foo");
    let de2 = de1.incr();      // creates D(de_2, 2)
    let de4 = {
        let _da1 = da0.incr(); // creates D(da_1, 3)
        de2.incr().incr()      // creates D(de_3, 4) and D(de_4, 5)
    };
    d::println("eval tail of foo");
    de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
}}

// This module provides simultaneous printouts of the dynamic extents
// of all of the D values, in addition to logging the order that each
// is dropped.

const PREF_INDENT: u32 = 16;

pub mod d {
    #![allow(unused_parens)]
    use std::fmt;
    use std::mem;
    use std::cell::RefCell;

    static mut counter: u32 = 0;
    static mut trails: u64 = 0;

    pub type Log<'a> = &'a RefCell<Vec<u32>>;

    pub fn current_width() -> u32 {
        unsafe { max_width() - trails.leading_zeros() }
    }

    pub fn max_width() -> u32 {
        unsafe {
            (mem::size_of_val(&trails)*8) as u32
        }
    }

    pub fn indent_println(my_trails: u32, s: &str) {
        let mut indent: String = String::new();
        for i in 0..my_trails {
            unsafe {
                if trails & (1 << i) != 0 {
                    indent = indent + "| ";
                } else {
                    indent = indent + "  ";
                }
            }
        }
        println!("{}{}", indent, s);
    }

    pub fn println(s: &str) {
        indent_println(super::PREF_INDENT, s);
    }

    fn first_avail() -> u32 {
        unsafe {
            for i in 0..64 {
                if trails & (1 << i) == 0 {
                    return i;
                }
            }
        }
        panic!("exhausted trails");
    }

    pub struct D<'a> {
        name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
    }

    impl<'a> fmt::Display for D<'a> {
        fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
            write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
        }
    }

    impl<'a> D<'a> {
        pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> {
            unsafe {
                let trail = first_avail();
                let ctr = counter;
                counter += 1;
                trails |= (1 << trail);
                let ret = D {
                    name: name, i: i, log: log, uid: ctr, trail: trail
                };
                indent_println(trail, &format!("+-- Make {}", ret));
                ret
            }
        }
        pub fn incr(&self) -> D<'a> {
            D::new(self.name, self.i + 1, self.log)
        }
    }

    impl<'a> Drop for D<'a> {
        fn drop(&mut self) {
            unsafe { trails &= !(1 << self.trail); };
            self.log.borrow_mut().push(self.uid);
            indent_println(self.trail, &format!("+-- Drop {}", self));
            indent_println(::PREF_INDENT, "");
        }
    }
}
<commit_msg>Rollup merge of #44326 - Eh2406:FIXME#44590, r=arielb1<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-pretty issue #37201

// This test is ensuring that parameters are indeed dropped after
// temporaries in a fn body.

use std::cell::RefCell;

use self::d::D;

pub fn main() {
    let log = RefCell::new(vec![]);
    d::println("created empty log");
    test(&log);

    assert_eq!(&log.borrow()[..],
               [
                   //                                    created empty log
                   //    +-- Make D(da_0, 0)
                   //    | +-- Make D(de_1, 1)
                   //    | |                             calling foo
                   //    | |                             entered foo
                   //    | | +-- Make D(de_2, 2)
                   //    | | | +-- Make D(da_1, 3)
                   //    | | | | +-- Make D(de_3, 4)
                   //    | | | | | +-- Make D(de_4, 5)
                   3, // | | | +-- Drop D(da_1, 3)
                   //    | | |   | |
                   4, // | | |   +-- Drop D(de_3, 4)
                   //    | | |     |
                   //    | | |     |                     eval tail of foo
                   //    | | | +-- Make D(de_5, 6)
                   //    | | | | +-- Make D(de_6, 7)
                   5, // | | | | | +-- Drop D(de_4, 5)
                   //    | | | | |
                   2, // | | +-- Drop D(de_2, 2)
                   //    | |   | |
                   6, // | |   +-- Drop D(de_5, 6)
                   //    | |     |
                   1, // | +-- Drop D(de_1, 1)
                   //    |       |
                   0, // +-- Drop D(da_0, 0)
                   //            |
                   //            |                       result D(de_6, 7)
                   7 //          +-- Drop D(de_6, 7)

                       ]);
}

fn test<'a>(log: d::Log<'a>) {
    let da = D::new("da", 0, log);
    let de = D::new("de", 1, log);
    d::println("calling foo");
    let result = foo(da, de);
    d::println(&format!("result {}", result));
}

fn foo<'a>(da0: D<'a>, de1: D<'a>) -> D<'a> {
    d::println("entered foo");
    let de2 = de1.incr();      // creates D(de_2, 2)
    let de4 = {
        let _da1 = da0.incr(); // creates D(da_1, 3)
        de2.incr().incr()      // creates D(de_3, 4) and D(de_4, 5)
    };
    d::println("eval tail of foo");
    de4.incr().incr()          // creates D(de_5, 6) and D(de_6, 7)
}

// This module provides simultaneous printouts of the dynamic extents
// of all of the D values, in addition to logging the order that each
// is dropped.

const PREF_INDENT: u32 = 16;

pub mod d {
    #![allow(unused_parens)]
    use std::fmt;
    use std::mem;
    use std::cell::RefCell;

    static mut counter: u32 = 0;
    static mut trails: u64 = 0;

    pub type Log<'a> = &'a RefCell<Vec<u32>>;

    pub fn current_width() -> u32 {
        unsafe { max_width() - trails.leading_zeros() }
    }

    pub fn max_width() -> u32 {
        unsafe {
            (mem::size_of_val(&trails)*8) as u32
        }
    }

    pub fn indent_println(my_trails: u32, s: &str) {
        let mut indent: String = String::new();
        for i in 0..my_trails {
            unsafe {
                if trails & (1 << i) != 0 {
                    indent = indent + "| ";
                } else {
                    indent = indent + "  ";
                }
            }
        }
        println!("{}{}", indent, s);
    }

    pub fn println(s: &str) {
        indent_println(super::PREF_INDENT, s);
    }

    fn first_avail() -> u32 {
        unsafe {
            for i in 0..64 {
                if trails & (1 << i) == 0 {
                    return i;
                }
            }
        }
        panic!("exhausted trails");
    }

    pub struct D<'a> {
        name: &'static str, i: u32, uid: u32, trail: u32, log: Log<'a>
    }

    impl<'a> fmt::Display for D<'a> {
        fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
            write!(w, "D({}_{}, {})", self.name, self.i, self.uid)
        }
    }

    impl<'a> D<'a> {
        pub fn new(name: &'static str, i: u32, log: Log<'a>) -> D<'a> {
            unsafe {
                let trail = first_avail();
                let ctr = counter;
                counter += 1;
                trails |= (1 << trail);
                let ret = D {
                    name: name, i: i, log: log, uid: ctr, trail: trail
                };
                indent_println(trail, &format!("+-- Make {}", ret));
                ret
            }
        }
        pub fn incr(&self) -> D<'a> {
            D::new(self.name, self.i + 1, self.log)
        }
    }

    impl<'a> Drop for D<'a> {
        fn drop(&mut self) {
            unsafe { trails &= !(1 << self.trail); };
            self.log.borrow_mut().push(self.uid);
            indent_println(self.trail, &format!("+-- Drop {}", self));
            indent_println(::PREF_INDENT, "");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor(search): Use noop version of new write_stdout<commit_after><|endoftext|>


<commit_before>use core::cmp::*;

trait Cache<K: Copy Eq, V: Copy> {
    static fn new(size: uint) -> self;
    fn insert(key: &K, value: V);
    fn find(key: &K) -> Option<V>;
    fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V;
    fn evict_all();
}

pub struct MonoCache<K: Copy Eq, V: Copy> {
    mut entry: Option<(K,V)>,
}

pub impl<K: Copy Eq, V: Copy> MonoCache<K,V> : Cache<K,V> {
    static fn new(_size: uint) -> MonoCache<K,V> {
        MonoCache { entry: None }
    }

    fn insert(key: &K, value: V) {
        self.entry = Some((copy *key, value));
    }

    fn find(key: &K) -> Option<V> {
        match self.entry {
            None => None,
            Some((ref k,v)) => if *k == *key { Some(v) } else { None }
        }
    }

    fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V {
        return match self.find(key) {
            None => {
                let value = blk(key);
                self.entry = Some((copy *key, copy value));
                move value
            },
            Some(v) => v
        };
    }
    fn evict_all() {
        self.entry = None;
    }
}

#[test]
fn test_monocache() {
    // TODO: this is hideous because of Rust Issue #3902
    let cache = cache::new::<uint, @str, MonoCache<uint, @str>>(10);
    let one = @"one";
    let two = @"two";
    cache.insert(1, one);

    assert cache.find(1).is_some();
    assert cache.find(2).is_none();
    cache.find_or_create(2, |_v| { two });
    assert cache.find(2).is_some();
    assert cache.find(1).is_none();
}<commit_msg>Fix test bustage in util::cache.<commit_after>use core::cmp::*;

trait Cache<K: Copy Eq, V: Copy> {
    static fn new(size: uint) -> self;
    fn insert(key: &K, value: V);
    fn find(key: &K) -> Option<V>;
    fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V;
    fn evict_all();
}

pub struct MonoCache<K: Copy Eq, V: Copy> {
    mut entry: Option<(K,V)>,
}

pub impl<K: Copy Eq, V: Copy> MonoCache<K,V> : Cache<K,V> {
    static fn new(_size: uint) -> MonoCache<K,V> {
        MonoCache { entry: None }
    }

    fn insert(key: &K, value: V) {
        self.entry = Some((copy *key, value));
    }

    fn find(key: &K) -> Option<V> {
        match self.entry {
            None => None,
            Some((ref k,v)) => if *k == *key { Some(v) } else { None }
        }
    }

    fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V {
        return match self.find(key) {
            None => {
                let value = blk(key);
                self.entry = Some((copy *key, copy value));
                move value
            },
            Some(v) => v
        };
    }
    fn evict_all() {
        self.entry = None;
    }
}

#[test]
fn test_monocache() {
    // TODO: this is hideous because of Rust Issue #3902
    let cache = cache::new::<uint, @str, MonoCache<uint, @str>>(10);
    let one = @"one";
    let two = @"two";
    cache.insert(&1, one);

    assert cache.find(&1).is_some();
    assert cache.find(&2).is_none();
    cache.find_or_create(&2, |_v| { two });
    assert cache.find(&2).is_some();
    assert cache.find(&1).is_none();
}<|endoftext|>


<commit_before><commit_msg>Rollup merge of #80069 - jyn514:core-assert, r=dtolnay<commit_after>// compile-flags: --crate-type=lib
// check-pass
// issue #55482
#![no_std]

macro_rules! foo {
    ($e:expr) => {
        $crate::core::assert!($e);
        $crate::core::assert_eq!($e, true);
    };
}

pub fn foo() { foo!(true); }
<|endoftext|>


<commit_before><commit_msg>needless_continue: Add tests for helper functions to the needless_continue lint.<commit_after>// Tests for the various helper functions used by the needless_continue
// lint that don't belong in utils.
extern crate clippy_lints;
use clippy_lints::needless_continue::{erode_from_back, erode_block, erode_from_front};

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_erode_from_back() {
    let input = "\
{
    let x = 5;
    let y = format!(\"{}\", 42);
}";

    let expected = "\
{
    let x = 5;
    let y = format!(\"{}\", 42);";

    let got = erode_from_back(input);
    assert_eq!(expected, got);
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_erode_from_back_no_brace() {
    let input = "\
let x = 5;
let y = something();
";
    let expected = "";
    let got = erode_from_back(input);
    assert_eq!(expected, got);
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_erode_from_front() {
    let input = "
        {
            something();
            inside_a_block();
        }
    ";
    let expected =
"            something();
            inside_a_block();
        }
    ";
    let got = erode_from_front(input);
    println!("input: {}\nexpected:\n{}\ngot:\n{}", input, expected, got);
    assert_eq!(expected, got);
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_erode_from_front_no_brace() {
    let input = "
            something();
            inside_a_block();
    ";
    let expected =
"something();
            inside_a_block();
    ";
    let got = erode_from_front(input);
    println!("input: {}\nexpected:\n{}\ngot:\n{}", input, expected, got);
    assert_eq!(expected, got);
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn test_erode_block() {

    let input = "
        {
            something();
            inside_a_block();
        }
    ";
    let expected =
"            something();
            inside_a_block();";
    let got = erode_block(input);
    println!("input: {}\nexpected:\n{}\ngot:\n{}", input, expected, got);
    assert_eq!(expected, got);
}

<|endoftext|>


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

// Make sure the destructor is run for newtype structs.

struct Foo(@mut int);

#[unsafe_destructor]
impl Drop for Foo {
    fn finalize(&self) {
        ***self = 23;
    }
}

fn main() {
    let y = @mut 32;
    {
        let x = Foo(y);
    }
    assert_eq!(*y, 23);
}
<|endoftext|>


<commit_before><commit_msg>Add tests for inverted rotations<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Add tests for imag-grep<commit_after><|endoftext|>


<commit_before><commit_msg>Add Entry::set_content()<commit_after><|endoftext|>


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

// Issue #21486: Make sure that all structures are dropped, even when
// created via FRU and control-flow breaks in the middle of
// construction.

use std::sync::atomic::{Ordering, AtomicUsize, ATOMIC_USIZE_INIT};

#[derive(Debug)]
struct Noisy(u8);
impl Drop for Noisy {
    fn drop(&mut self) {
        // println!("splat #{}", self.0);
        event(self.0);
    }
}

#[allow(dead_code)]
#[derive(Debug)]
struct Foo { n0: Noisy, n1: Noisy }
impl Foo {
    fn vals(&self) -> (u8, u8) { (self.n0.0, self.n1.0) }
}

fn leak_1_ret() -> Foo {
    let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
    Foo { n0: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
          .._old_foo
    };
}

fn leak_2_ret() -> Foo {
    let _old_foo = Foo { n0: Noisy(1), n1: Noisy(2) };
    Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
          .._old_foo
    };
}

// In this case, the control flow break happens *before* we construct
// `Foo(Noisy(1),Noisy(2))`, so there should be no record of it in the
// event log.
fn leak_3_ret() -> Foo {
    let _old_foo = || Foo { n0: Noisy(1), n1: Noisy(2) };
    Foo { n1: { return Foo { n0: Noisy(3), n1: Noisy(4) } },
          .._old_foo()
    };
}

pub fn main() {
    reset_log();
    assert_eq!(leak_1_ret().vals(), (3,4));
    assert_eq!(0x01_02_03_04, event_log());

    reset_log();
    assert_eq!(leak_2_ret().vals(), (3,4));
    assert_eq!(0x01_02_03_04, event_log());

    reset_log();
    assert_eq!(leak_3_ret().vals(), (3,4));
    assert_eq!(0x03_04, event_log());
}

static LOG: AtomicUsize = ATOMIC_USIZE_INIT;

fn reset_log() {
    LOG.store(0, Ordering::SeqCst);
}

fn event_log() -> usize {
    LOG.load(Ordering::SeqCst)
}

fn event(tag: u8) {
    let old_log = LOG.load(Ordering::SeqCst);
    let new_log = (old_log << 8) + tag as usize;
    LOG.store(new_log, Ordering::SeqCst);
}
<|endoftext|>


<commit_before><commit_msg>A variant of sdl-demo/main.rs that is designed to be used with the platform-specific SDL_main C/C++/Objective-C sources that take care of requirements that have to be taken care of on the main-thread before handing off control to the user's event loop.<commit_after><|endoftext|>


<commit_before>use alloc::boxed::Box;

use schemes::KScheme;

use super::pciconfig::PciConfig;

#[repr(packed)]
struct HBAPort {
    clb: u32,
    clbu: u32,
    fb: u32,
    fbu: u32,
    is: u32,
    ie: u32,
    cmd: u32,
    rsv0: u32,
    tfd: u32,
    sig: u32,
    ssts: u32,
    sctl: u32,
    serr: u32,
    sact: u32,
    ci: u32,
    sntf: u32,
    fbs: u32,
    rsv1: [u32; 11],
    vendor: [u32; 4]
}

#[repr(packed)]
struct HBAMem {
    cap: u32,
    ghc: u32,
    is: u32,
    pi: u32,
    vs: u32,
    ccc_ctl: u32,
    ccc_pts: u32,
    em_loc: u32,
    em_ctl: u32,
    cap2: u32,
    bohc: u32,
    rsv: [u8; 116],
    vendor: [u8; 96],
    ports: [HBAPort; 32]
}

pub struct Ahci {
    pci: PciConfig,
    mem: *mut HBAMem,
    irq: u8,
}

impl Ahci {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        let mut module = box Ahci {
            pci: pci,
            mem: base as *mut HBAMem,
            irq: irq,
        };

        module.init();

        module
    }

    fn init(&mut self) {
        debugln!("AHCI on: {:X} IRQ: {:X}", self.mem as usize, self.irq);

        let mem = unsafe { &mut * self.mem };

        for i in 0..32 {
            if mem.pi & 1 << i == 1 << i {
                debugln!("Port {}: {:X}", i, mem.ports[i].ssts);
            }
        }
    }
}

impl KScheme for Ahci {
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            debugln!("AHCI IRQ");
        }
    }

    fn on_poll(&mut self) {
    }
}
<commit_msg>Probe AHCI device type<commit_after>use alloc::boxed::Box;

use core::intrinsics::atomic_singlethreadfence;
use core::u32;

use schemes::KScheme;

use super::pciconfig::PciConfig;

const HBA_PxCMD_CR: u32 = 1 << 15;
const HBA_PxCMD_FR: u32 = 1 << 14;
const HBA_PxCMD_FRE: u32 = 1 << 4;
const HBA_PxCMD_ST: u32 = 1;

#[repr(packed)]
struct HBAPort {
    clb: u32,
    clbu: u32,
    fb: u32,
    fbu: u32,
    is: u32,
    ie: u32,
    cmd: u32,
    rsv0: u32,
    tfd: u32,
    sig: u32,
    ssts: u32,
    sctl: u32,
    serr: u32,
    sact: u32,
    ci: u32,
    sntf: u32,
    fbs: u32,
    rsv1: [u32; 11],
    vendor: [u32; 4]
}

#[derive(Debug)]
enum HBAPortType {
    None,
    Unknown(u32),
    SATA,
    SATAPI,
    PM,
    SEMB,
}

const HBA_PORT_PRESENT: u32 = 0x13;
const SATA_SIG_ATA: u32 = 0x00000101;
const SATA_SIG_ATAPI: u32 = 0xEB140101;
const SATA_SIG_PM: u32 = 0x96690101;
const SATA_SIG_SEMB: u32 = 0xC33C0101;

impl HBAPort {
    pub fn probe(&self) -> HBAPortType {
        if self.ssts & HBA_PORT_PRESENT != HBA_PORT_PRESENT {
            HBAPortType::None
        } else {
            match self.sig {
                SATA_SIG_ATA => HBAPortType::SATA,
                SATA_SIG_ATAPI => HBAPortType::SATAPI,
                SATA_SIG_PM => HBAPortType::PM,
                SATA_SIG_SEMB => HBAPortType::SEMB,
                _ => HBAPortType::Unknown(self.sig)
            }
        }
    }

    pub fn start(&mut self) {
        loop {
            if self.cmd & HBA_PxCMD_CR == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
        }

        self.cmd |= HBA_PxCMD_FRE;
        self.cmd |= HBA_PxCMD_ST;
    }

    pub fn stop(&mut self) {
    	self.cmd &= u32::MAX - HBA_PxCMD_ST;

    	loop {
    		if self.cmd & (HBA_PxCMD_FR | HBA_PxCMD_CR) == 0 {
                break;
            }
            unsafe { atomic_singlethreadfence() };
    	}

    	self.cmd &= u32::MAX - HBA_PxCMD_FRE;
    }
}

#[repr(packed)]
struct HBAMem {
    cap: u32,
    ghc: u32,
    is: u32,
    pi: u32,
    vs: u32,
    ccc_ctl: u32,
    ccc_pts: u32,
    em_loc: u32,
    em_ctl: u32,
    cap2: u32,
    bohc: u32,
    rsv: [u8; 116],
    vendor: [u8; 96],
    ports: [HBAPort; 32]
}

pub struct Ahci {
    pci: PciConfig,
    mem: *mut HBAMem,
    irq: u8,
}

impl Ahci {
    pub fn new(mut pci: PciConfig) -> Box<Self> {
        let base = unsafe { (pci.read(0x24) & 0xFFFFFFF0) as usize };
        let irq = unsafe { (pci.read(0x3C) & 0xF) as u8 };

        let mut module = box Ahci {
            pci: pci,
            mem: base as *mut HBAMem,
            irq: irq,
        };

        module.init();

        module
    }

    fn init(&mut self) {
        debugln!("AHCI on: {:X} IRQ: {:X}", self.mem as usize, self.irq);

        let mem = unsafe { &mut * self.mem };

        for i in 0..32 {
            if mem.pi & 1 << i == 1 << i {
                debugln!("Port {}: {:X} {:?}", i, mem.ports[i].ssts, mem.ports[i].probe());
            }
        }
    }
}

impl KScheme for Ahci {
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            debugln!("AHCI IRQ");
        }
    }

    fn on_poll(&mut self) {
    }
}
<|endoftext|>


<commit_before><commit_msg>19 - box, stack and heap<commit_after>use std::mem;

#[allow(dead_code)]
#[deriving(Copy)]
struct Point {
    x: f64,
    y: f64,
}

#[allow(dead_code)]
struct Rectangle {
    p1: Point,
    p2: Point,
}

fn origin() -> Point {
    Point { x: 0.0, y: 0.0 }
}

fn boxed_origin() -> Box<Point> {
    // Allocate this point in the heap, and return a pointer to it
    box Point { x: 0.0, y: 0.0 }
}

fn main() {
    // (all the type annotations are superfluous)
    // Stack allocated variables
    let point: Point = origin();
    let rectangle: Rectangle = Rectangle {
        p1: origin(),
        p2: Point { x: 3.0, y: 4.0 }
    };

    // Heap allocated rectangle
    let boxed_rectangle: Box<Rectangle> = box Rectangle {
        p1: origin(),
        p2: origin()
    };

    // The output of functions can be boxed
    let boxed_point: Box<Point> = box origin();

    // Double indirection
    let box_in_a_box: Box<Box<Point>> = box boxed_origin();

    println!("Point occupies {} bytes in the stack",
             mem::size_of_val(&point));
    println!("Rectangle occupies {} bytes in the stack",
             mem::size_of_val(&rectangle));

    // box size = pointer size
    println!("Boxed point occupies {} bytes in the stack",
             mem::size_of_val(&boxed_point));
    println!("Boxed rectangle occupies {} bytes in the stack",
             mem::size_of_val(&boxed_rectangle));
    println!("Boxed box occupies {} bytes in the stack",
             mem::size_of_val(&box_in_a_box));

    // Copy the data contained in `boxed_point` into `unboxed_point`
    let unboxed_point: Point = *boxed_point;
    println!("Unboxed point occupies {} bytes in the stack",
             mem::size_of_val(&unboxed_point));

    // Unboxing via a destructuring pattern
    let box another_unboxed_point = boxed_point;
    println!("Another unboxed point occupies {} bytes in the stack",
             mem::size_of_val(&another_unboxed_point));
}
<|endoftext|>


<commit_before><commit_msg>Macro for Vec creation<commit_after><|endoftext|>


<commit_before><commit_msg>Add write<commit_after><|endoftext|>


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

#![crate_name = "device"]
#![comment = "Back-ends to abstract over the differences between low-level, \
              platform-specific graphics APIs"]
#![license = "ASL2"]
#![crate_type = "lib"]

#![feature(phase)]
#![deny(missing_doc)]

//! Graphics device. Not meant for direct use.

#[phase(plugin, link)] extern crate log;
extern crate libc;

// when cargo is ready, re-enable the cfgs
/* #[cfg(gl)] */ pub use self::gl as back;
/* #[cfg(gl)] */ pub use gl::GlDevice;
/* #[cfg(gl)] */ pub use gl::draw::GlCommandBuffer;
// #[cfg(d3d11)] ... // TODO

use std::fmt;
use std::mem::size_of;

pub mod attrib;
pub mod draw;
pub mod shade;
pub mod state;
pub mod target;
pub mod tex;
/* #[cfg(gl)] */ mod gl;

/// Draw vertex count.
pub type VertexCount = u32;
/// Draw index count.
pub type IndexCount = u32;
/// Draw number of instances
pub type InstanceCount = u32;
/// Index of a uniform block.
pub type UniformBlockIndex = u8;
/// Slot for an attribute.
pub type AttributeSlot = u8;
/// Slot for a uniform buffer object.
pub type UniformBufferSlot = u8;
/// Slot a texture can be bound to.
pub type TextureSlot = u8;

/// A generic handle struct
#[deriving(Clone, Show)]
pub struct Handle<T, I>(T, I);

#[deriving(Clone, Show)]
impl<T: Copy, I> Handle<T, I> {
    /// Get the internal name
    pub fn get_name(&self) -> T {
        let Handle(name, _) = *self;
        name
    }

    /// Get the info reference
    pub fn get_info(&self) -> &I {
        let Handle(_, ref info) = *self;
        info
    }
}

impl<T: Copy + PartialEq, I: PartialEq> PartialEq for Handle<T, I> {
    fn eq(&self, other: &Handle<T,I>) -> bool {
        self.get_name().eq(&other.get_name()) && self.get_info().eq(other.get_info())
    }
}

/// Type-safe buffer handle
#[deriving(Show, Clone)]
pub struct BufferHandle<T> {
    raw: RawBufferHandle,
}

impl<T> BufferHandle<T> {
    /// Create a type-safe BufferHandle from a RawBufferHandle
    pub fn from_raw(handle: RawBufferHandle) -> BufferHandle<T> {
        BufferHandle {
            raw: handle,
        }
    }

    /// Cast the type this BufferHandle references
    pub fn cast<U>(self) -> BufferHandle<U> {
        BufferHandle::from_raw(self.raw)
    }

    /// Get the underlying GL name for this BufferHandle
    pub fn get_name(&self) -> back::Buffer {
        self.raw.get_name()
    }

    /// Get the associated information about the buffer
    pub fn get_info(&self) -> &BufferInfo {
        self.raw.get_info()
    }

    /// Get the underlying raw Handle
    pub fn raw(&self) -> RawBufferHandle {
        self.raw
    }
}

/// Raw (untyped) Buffer Handle
pub type RawBufferHandle = Handle<back::Buffer, BufferInfo>;
/// Array Buffer Handle
pub type ArrayBufferHandle = Handle<back::ArrayBuffer, ()>;
/// Shader Handle
pub type ShaderHandle  = Handle<back::Shader, shade::Stage>;
/// Program Handle
pub type ProgramHandle = Handle<back::Program, shade::ProgramInfo>;
/// Frame Buffer Handle
pub type FrameBufferHandle = Handle<back::FrameBuffer, ()>;
/// Surface Handle
pub type SurfaceHandle = Handle<back::Surface, tex::SurfaceInfo>;
/// Texture Handle
pub type TextureHandle = Handle<back::Texture, tex::TextureInfo>;
/// Sampler Handle
pub type SamplerHandle = Handle<back::Sampler, tex::SamplerInfo>;

/// A helper method to test `#[vertex_format]` without GL context
//#[cfg(test)]
pub fn make_fake_buffer<T>() -> BufferHandle<T> {
    let info = BufferInfo {
        usage: UsageStatic,
        size: 0,
    };
    BufferHandle::from_raw(Handle(0, info))
}

/// Return the framebuffer handle for the screen
pub fn get_main_frame_buffer() -> FrameBufferHandle {
    Handle(0, ())
}

/// Features that the device supports.
#[deriving(Show)]
#[allow(missing_doc)] // pretty self-explanatory fields!
pub struct Capabilities {
    pub shader_model: shade::ShaderModel,
    pub max_draw_buffers : uint,
    pub max_texture_size : uint,
    pub max_vertex_attributes: uint,
    pub uniform_block_supported: bool,
    pub array_buffer_supported: bool,
    pub sampler_objects_supported: bool,
    pub immutable_storage_supported: bool,
    pub instance_call_supported: bool,
    pub instance_rate_supported: bool,
}

/// A trait that slice-like types implement.
pub trait Blob<T> {
    /// Get the address to the data this `Blob` stores.
    fn get_address(&self) -> uint;
    /// Get the number of bytes in this blob.
    fn get_size(&self) -> uint;
}

/// Helper trait for casting &Blob
pub trait RefBlobCast<'a> {
    /// Cast the type the blob references
    fn cast<U>(self) -> &'a Blob<U>+'a;
}

/// Helper trait for casting Box<Blob>
pub trait BoxBlobCast {
    /// Cast the type the blob references
    fn cast<U>(self) -> Box<Blob<U> + Send>;
}

impl<'a, T> RefBlobCast<'a> for &'a Blob<T>+'a {
    fn cast<U>(self) -> &'a Blob<U>+'a {
        unsafe { std::mem::transmute(self) }
    }
}

impl<T> BoxBlobCast for Box<Blob<T> + Send> {
    fn cast<U>(self) -> Box<Blob<U> + Send> {
        unsafe { std::mem::transmute(self) }
    }
}

impl<T: Send> Blob<T> for Vec<T> {
    fn get_address(&self) -> uint {
        self.as_ptr() as uint
    }
    fn get_size(&self) -> uint {
        self.len() * size_of::<T>()
    }
}

impl<'a, T> Blob<T> for &'a [T] {
    fn get_address(&self) -> uint {
        self.as_ptr() as uint
    }
    fn get_size(&self) -> uint {
        self.len() * size_of::<T>()
    }
}

impl<T> fmt::Show for Box<Blob<T> + Send> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Blob({:#x}, {})", self.get_address(), self.get_size())
    }
}

/// Describes what geometric primitives are created from vertex data.
#[deriving(Clone, PartialEq, Show)]
#[repr(u8)]
pub enum PrimitiveType {
    /// Each vertex represents a single point.
    Point,
    /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
    /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
    Line,
    /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
    /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
    /// line, and `b` and `c` form a line.
    LineStrip,
    /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
    /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
    TriangleList,
    /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
    /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
    TriangleStrip,
    /// The first vertex with the last two are forming a triangle. For example, with `[a, b, c, d
    /// ]`, `a` , `b`, and `c` form a triangle, and `a`, `c`, and `d` form a triangle.
    TriangleFan,
    //Quad,
}

/// A type of each index value in the mesh's index buffer
pub type IndexType = attrib::IntSize;

/// A hint as to how this buffer will be used.
///
/// The nature of these hints make them very implementation specific. Different drivers on
/// different hardware will handle them differently. Only careful profiling will tell which is the
/// best to use for a specific buffer.
#[deriving(Clone, PartialEq, Show)]
#[repr(u8)]
pub enum BufferUsage {
    /// Once uploaded, this buffer will rarely change, but will be read from often.
    UsageStatic,
    /// This buffer will be updated "frequently", and will be read from multiple times between
    /// updates.
    UsageDynamic,
    /// This buffer always or almost always be updated after each read.
    UsageStream,
}

/// An information block that is immutable and associated with each buffer
#[deriving(Clone, PartialEq, Show)]
pub struct BufferInfo {
    /// Usage hint
    pub usage: BufferUsage,
    /// Size in bytes
    pub size: uint,
}

/// Serialized device command.
/// While this is supposed to be an internal detail of a device,
/// this particular representation may be used by different backends,
/// such as OpenGL (prior to GLNG) and DirectX (prior to DX12)
#[allow(missing_doc)]
#[deriving(Show)]
pub enum Command {
    BindProgram(back::Program),
    BindArrayBuffer(back::ArrayBuffer),
    BindAttribute(AttributeSlot, back::Buffer, attrib::Format),
    BindIndex(back::Buffer),
    BindFrameBuffer(back::FrameBuffer),
    /// Unbind any surface from the specified target slot
    UnbindTarget(target::Target),
    /// Bind a surface to the specified target slot
    BindTargetSurface(target::Target, back::Surface),
    /// Bind a level of the texture to the specified target slot
    BindTargetTexture(target::Target, back::Texture, target::Level, Option<target::Layer>),
    BindUniformBlock(back::Program, UniformBufferSlot, UniformBlockIndex, back::Buffer),
    BindUniform(shade::Location, shade::UniformValue),
    BindTexture(TextureSlot, tex::TextureKind, back::Texture, Option<SamplerHandle>),
    SetPrimitiveState(state::Primitive),
    SetViewport(target::Rect),
    SetScissor(Option<target::Rect>),
    SetDepthStencilState(Option<state::Depth>, Option<state::Stencil>, state::CullMode),
    SetBlendState(Option<state::Blend>),
    SetColorMask(state::ColorMask),
    UpdateBuffer(back::Buffer, Box<Blob<()> + Send>, uint),
    UpdateTexture(tex::TextureKind, back::Texture, tex::ImageInfo, Box<Blob<()> + Send>),
    // drawing
    Clear(target::ClearData),
    Draw(PrimitiveType, VertexCount, VertexCount, Option<InstanceCount>),
    DrawIndexed(PrimitiveType, IndexType, IndexCount, IndexCount, Option<InstanceCount>),
}

// CommandBuffer is really an associated type, so will look much better when
// Rust supports this natively.
/// An interface for performing draw calls using a specific graphics API
#[allow(missing_doc)]
pub trait Device<C: draw::CommandBuffer> {
    /// Returns the capabilities available to the specific API implementation
    fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
    /// Reset all the states to disabled/default
    fn reset_state(&mut self);
    /// Submit a command buffer for execution
    fn submit(&mut self, cb: &C);
    // resource creation
    fn create_buffer_raw(&mut self, size: uint, usage: BufferUsage) -> BufferHandle<()>;
    fn create_buffer<T>(&mut self, num: uint, usage: BufferUsage) -> BufferHandle<T> {
        self.create_buffer_raw(num * size_of::<T>(), usage).cast()
    }
    fn create_buffer_static<T>(&mut self, &Blob<T>) -> BufferHandle<T>;
    fn create_array_buffer(&mut self) -> Result<ArrayBufferHandle, ()>;
    fn create_shader(&mut self, stage: shade::Stage, code: shade::ShaderSource) ->
                     Result<ShaderHandle, shade::CreateShaderError>;
    fn create_program(&mut self, shaders: &[ShaderHandle]) -> Result<ProgramHandle, ()>;
    fn create_frame_buffer(&mut self) -> FrameBufferHandle;
    fn create_surface(&mut self, info: tex::SurfaceInfo) -> Result<SurfaceHandle, tex::SurfaceError>;
    fn create_texture(&mut self, info: tex::TextureInfo) -> Result<TextureHandle, tex::TextureError>;
    fn create_sampler(&mut self, info: tex::SamplerInfo) -> SamplerHandle;
    // resource deletion
    fn delete_buffer_raw(&mut self, buf: BufferHandle<()>);
    fn delete_buffer<T>(&mut self, buf: BufferHandle<T>) {
        self.delete_buffer_raw(buf.cast());
    }
    fn delete_shader(&mut self, ShaderHandle);
    fn delete_program(&mut self, ProgramHandle);
    fn delete_surface(&mut self, SurfaceHandle);
    fn delete_texture(&mut self, TextureHandle);
    fn delete_sampler(&mut self, SamplerHandle);
    /// Update the information stored in a specific buffer
    fn update_buffer_raw(&mut self, buf: BufferHandle<()>, data: &Blob<()>, offset_bytes: uint);
    fn update_buffer<T>(&mut self, buf: BufferHandle<T>, data: &Blob<T>, offset_elements: uint) {
        self.update_buffer_raw(buf.cast(), data.cast(), size_of::<T>() * offset_elements);
    }
    /// Update the information stored in a texture
    fn update_texture_raw(&mut self, tex: &TextureHandle, img: &tex::ImageInfo,
                          data: &Blob<()>) -> Result<(), tex::TextureError>;
    fn update_texture<T>(&mut self, tex: &TextureHandle, img: &tex::ImageInfo,
                      data: &Blob<T>) -> Result<(), tex::TextureError> {
        self.update_texture_raw(tex, img, data.cast())
    }
    fn generate_mipmap(&mut self, tex: &TextureHandle);
}
<commit_msg>Return *const T from Blob::get_address<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![crate_name = "device"]
#![comment = "Back-ends to abstract over the differences between low-level, \
              platform-specific graphics APIs"]
#![license = "ASL2"]
#![crate_type = "lib"]

#![feature(phase)]
#![deny(missing_doc)]

//! Graphics device. Not meant for direct use.

#[phase(plugin, link)] extern crate log;
extern crate libc;

// when cargo is ready, re-enable the cfgs
/* #[cfg(gl)] */ pub use self::gl as back;
/* #[cfg(gl)] */ pub use gl::GlDevice;
/* #[cfg(gl)] */ pub use gl::draw::GlCommandBuffer;
// #[cfg(d3d11)] ... // TODO

use std::fmt;
use std::mem::size_of;

pub mod attrib;
pub mod draw;
pub mod shade;
pub mod state;
pub mod target;
pub mod tex;
/* #[cfg(gl)] */ mod gl;

/// Draw vertex count.
pub type VertexCount = u32;
/// Draw index count.
pub type IndexCount = u32;
/// Draw number of instances
pub type InstanceCount = u32;
/// Index of a uniform block.
pub type UniformBlockIndex = u8;
/// Slot for an attribute.
pub type AttributeSlot = u8;
/// Slot for a uniform buffer object.
pub type UniformBufferSlot = u8;
/// Slot a texture can be bound to.
pub type TextureSlot = u8;

/// A generic handle struct
#[deriving(Clone, Show)]
pub struct Handle<T, I>(T, I);

#[deriving(Clone, Show)]
impl<T: Copy, I> Handle<T, I> {
    /// Get the internal name
    pub fn get_name(&self) -> T {
        let Handle(name, _) = *self;
        name
    }

    /// Get the info reference
    pub fn get_info(&self) -> &I {
        let Handle(_, ref info) = *self;
        info
    }
}

impl<T: Copy + PartialEq, I: PartialEq> PartialEq for Handle<T, I> {
    fn eq(&self, other: &Handle<T,I>) -> bool {
        self.get_name().eq(&other.get_name()) && self.get_info().eq(other.get_info())
    }
}

/// Type-safe buffer handle
#[deriving(Show, Clone)]
pub struct BufferHandle<T> {
    raw: RawBufferHandle,
}

impl<T> BufferHandle<T> {
    /// Create a type-safe BufferHandle from a RawBufferHandle
    pub fn from_raw(handle: RawBufferHandle) -> BufferHandle<T> {
        BufferHandle {
            raw: handle,
        }
    }

    /// Cast the type this BufferHandle references
    pub fn cast<U>(self) -> BufferHandle<U> {
        BufferHandle::from_raw(self.raw)
    }

    /// Get the underlying GL name for this BufferHandle
    pub fn get_name(&self) -> back::Buffer {
        self.raw.get_name()
    }

    /// Get the associated information about the buffer
    pub fn get_info(&self) -> &BufferInfo {
        self.raw.get_info()
    }

    /// Get the underlying raw Handle
    pub fn raw(&self) -> RawBufferHandle {
        self.raw
    }
}

/// Raw (untyped) Buffer Handle
pub type RawBufferHandle = Handle<back::Buffer, BufferInfo>;
/// Array Buffer Handle
pub type ArrayBufferHandle = Handle<back::ArrayBuffer, ()>;
/// Shader Handle
pub type ShaderHandle  = Handle<back::Shader, shade::Stage>;
/// Program Handle
pub type ProgramHandle = Handle<back::Program, shade::ProgramInfo>;
/// Frame Buffer Handle
pub type FrameBufferHandle = Handle<back::FrameBuffer, ()>;
/// Surface Handle
pub type SurfaceHandle = Handle<back::Surface, tex::SurfaceInfo>;
/// Texture Handle
pub type TextureHandle = Handle<back::Texture, tex::TextureInfo>;
/// Sampler Handle
pub type SamplerHandle = Handle<back::Sampler, tex::SamplerInfo>;

/// A helper method to test `#[vertex_format]` without GL context
//#[cfg(test)]
pub fn make_fake_buffer<T>() -> BufferHandle<T> {
    let info = BufferInfo {
        usage: UsageStatic,
        size: 0,
    };
    BufferHandle::from_raw(Handle(0, info))
}

/// Return the framebuffer handle for the screen
pub fn get_main_frame_buffer() -> FrameBufferHandle {
    Handle(0, ())
}

/// Features that the device supports.
#[deriving(Show)]
#[allow(missing_doc)] // pretty self-explanatory fields!
pub struct Capabilities {
    pub shader_model: shade::ShaderModel,
    pub max_draw_buffers : uint,
    pub max_texture_size : uint,
    pub max_vertex_attributes: uint,
    pub uniform_block_supported: bool,
    pub array_buffer_supported: bool,
    pub sampler_objects_supported: bool,
    pub immutable_storage_supported: bool,
    pub instance_call_supported: bool,
    pub instance_rate_supported: bool,
}

/// A trait that slice-like types implement.
pub trait Blob<T> {
    /// Get the address to the data this `Blob` stores.
    fn get_address(&self) -> *const T;
    /// Get the number of bytes in this blob.
    fn get_size(&self) -> uint;
}

/// Helper trait for casting &Blob
pub trait RefBlobCast<'a> {
    /// Cast the type the blob references
    fn cast<U>(self) -> &'a Blob<U>+'a;
}

/// Helper trait for casting Box<Blob>
pub trait BoxBlobCast {
    /// Cast the type the blob references
    fn cast<U>(self) -> Box<Blob<U> + Send>;
}

impl<'a, T> RefBlobCast<'a> for &'a Blob<T>+'a {
    fn cast<U>(self) -> &'a Blob<U>+'a {
        unsafe { std::mem::transmute(self) }
    }
}

impl<T> BoxBlobCast for Box<Blob<T> + Send> {
    fn cast<U>(self) -> Box<Blob<U> + Send> {
        unsafe { std::mem::transmute(self) }
    }
}

impl<T: Send> Blob<T> for Vec<T> {
    fn get_address(&self) -> *const T {
        self.as_ptr()
    }

    fn get_size(&self) -> uint {
        self.len() * size_of::<T>()
    }
}

impl<'a, T> Blob<T> for &'a [T] {
    fn get_address(&self) -> *const T {
        self.as_ptr()
    }

    fn get_size(&self) -> uint {
        self.len() * size_of::<T>()
    }
}

impl<T> fmt::Show for Box<Blob<T> + Send> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Blob({:#p}, {})", self.get_address(), self.get_size())
    }
}

/// Describes what geometric primitives are created from vertex data.
#[deriving(Clone, PartialEq, Show)]
#[repr(u8)]
pub enum PrimitiveType {
    /// Each vertex represents a single point.
    Point,
    /// Each pair of vertices represent a single line segment. For example, with `[a, b, c, d,
    /// e]`, `a` and `b` form a line, `c` and `d` form a line, and `e` is discarded.
    Line,
    /// Every two consecutive vertices represent a single line segment. Visually forms a "path" of
    /// lines, as they are all connected. For example, with `[a, b, c]`, `a` and `b` form a line
    /// line, and `b` and `c` form a line.
    LineStrip,
    /// Each triplet of vertices represent a single triangle. For example, with `[a, b, c, d, e]`,
    /// `a`, `b`, and `c` form a triangle, `d` and `e` are discarded.
    TriangleList,
    /// Every three consecutive vertices represent a single triangle. For example, with `[a, b, c,
    /// d]`, `a`, `b`, and `c` form a triangle, and `b`, `c`, and `d` form a triangle.
    TriangleStrip,
    /// The first vertex with the last two are forming a triangle. For example, with `[a, b, c, d
    /// ]`, `a` , `b`, and `c` form a triangle, and `a`, `c`, and `d` form a triangle.
    TriangleFan,
    //Quad,
}

/// A type of each index value in the mesh's index buffer
pub type IndexType = attrib::IntSize;

/// A hint as to how this buffer will be used.
///
/// The nature of these hints make them very implementation specific. Different drivers on
/// different hardware will handle them differently. Only careful profiling will tell which is the
/// best to use for a specific buffer.
#[deriving(Clone, PartialEq, Show)]
#[repr(u8)]
pub enum BufferUsage {
    /// Once uploaded, this buffer will rarely change, but will be read from often.
    UsageStatic,
    /// This buffer will be updated "frequently", and will be read from multiple times between
    /// updates.
    UsageDynamic,
    /// This buffer always or almost always be updated after each read.
    UsageStream,
}

/// An information block that is immutable and associated with each buffer
#[deriving(Clone, PartialEq, Show)]
pub struct BufferInfo {
    /// Usage hint
    pub usage: BufferUsage,
    /// Size in bytes
    pub size: uint,
}

/// Serialized device command.
/// While this is supposed to be an internal detail of a device,
/// this particular representation may be used by different backends,
/// such as OpenGL (prior to GLNG) and DirectX (prior to DX12)
#[allow(missing_doc)]
#[deriving(Show)]
pub enum Command {
    BindProgram(back::Program),
    BindArrayBuffer(back::ArrayBuffer),
    BindAttribute(AttributeSlot, back::Buffer, attrib::Format),
    BindIndex(back::Buffer),
    BindFrameBuffer(back::FrameBuffer),
    /// Unbind any surface from the specified target slot
    UnbindTarget(target::Target),
    /// Bind a surface to the specified target slot
    BindTargetSurface(target::Target, back::Surface),
    /// Bind a level of the texture to the specified target slot
    BindTargetTexture(target::Target, back::Texture, target::Level, Option<target::Layer>),
    BindUniformBlock(back::Program, UniformBufferSlot, UniformBlockIndex, back::Buffer),
    BindUniform(shade::Location, shade::UniformValue),
    BindTexture(TextureSlot, tex::TextureKind, back::Texture, Option<SamplerHandle>),
    SetPrimitiveState(state::Primitive),
    SetViewport(target::Rect),
    SetScissor(Option<target::Rect>),
    SetDepthStencilState(Option<state::Depth>, Option<state::Stencil>, state::CullMode),
    SetBlendState(Option<state::Blend>),
    SetColorMask(state::ColorMask),
    UpdateBuffer(back::Buffer, Box<Blob<()> + Send>, uint),
    UpdateTexture(tex::TextureKind, back::Texture, tex::ImageInfo, Box<Blob<()> + Send>),
    // drawing
    Clear(target::ClearData),
    Draw(PrimitiveType, VertexCount, VertexCount, Option<InstanceCount>),
    DrawIndexed(PrimitiveType, IndexType, IndexCount, IndexCount, Option<InstanceCount>),
}

// CommandBuffer is really an associated type, so will look much better when
// Rust supports this natively.
/// An interface for performing draw calls using a specific graphics API
#[allow(missing_doc)]
pub trait Device<C: draw::CommandBuffer> {
    /// Returns the capabilities available to the specific API implementation
    fn get_capabilities<'a>(&'a self) -> &'a Capabilities;
    /// Reset all the states to disabled/default
    fn reset_state(&mut self);
    /// Submit a command buffer for execution
    fn submit(&mut self, cb: &C);
    // resource creation
    fn create_buffer_raw(&mut self, size: uint, usage: BufferUsage) -> BufferHandle<()>;
    fn create_buffer<T>(&mut self, num: uint, usage: BufferUsage) -> BufferHandle<T> {
        self.create_buffer_raw(num * size_of::<T>(), usage).cast()
    }
    fn create_buffer_static<T>(&mut self, &Blob<T>) -> BufferHandle<T>;
    fn create_array_buffer(&mut self) -> Result<ArrayBufferHandle, ()>;
    fn create_shader(&mut self, stage: shade::Stage, code: shade::ShaderSource) ->
                     Result<ShaderHandle, shade::CreateShaderError>;
    fn create_program(&mut self, shaders: &[ShaderHandle]) -> Result<ProgramHandle, ()>;
    fn create_frame_buffer(&mut self) -> FrameBufferHandle;
    fn create_surface(&mut self, info: tex::SurfaceInfo) -> Result<SurfaceHandle, tex::SurfaceError>;
    fn create_texture(&mut self, info: tex::TextureInfo) -> Result<TextureHandle, tex::TextureError>;
    fn create_sampler(&mut self, info: tex::SamplerInfo) -> SamplerHandle;
    // resource deletion
    fn delete_buffer_raw(&mut self, buf: BufferHandle<()>);
    fn delete_buffer<T>(&mut self, buf: BufferHandle<T>) {
        self.delete_buffer_raw(buf.cast());
    }
    fn delete_shader(&mut self, ShaderHandle);
    fn delete_program(&mut self, ProgramHandle);
    fn delete_surface(&mut self, SurfaceHandle);
    fn delete_texture(&mut self, TextureHandle);
    fn delete_sampler(&mut self, SamplerHandle);
    /// Update the information stored in a specific buffer
    fn update_buffer_raw(&mut self, buf: BufferHandle<()>, data: &Blob<()>, offset_bytes: uint);
    fn update_buffer<T>(&mut self, buf: BufferHandle<T>, data: &Blob<T>, offset_elements: uint) {
        self.update_buffer_raw(buf.cast(), data.cast(), size_of::<T>() * offset_elements);
    }
    /// Update the information stored in a texture
    fn update_texture_raw(&mut self, tex: &TextureHandle, img: &tex::ImageInfo,
                          data: &Blob<()>) -> Result<(), tex::TextureError>;
    fn update_texture<T>(&mut self, tex: &TextureHandle, img: &tex::ImageInfo,
                      data: &Blob<T>) -> Result<(), tex::TextureError> {
        self.update_texture_raw(tex, img, data.cast())
    }
    fn generate_mipmap(&mut self, tex: &TextureHandle);
}
<|endoftext|>


<commit_before><commit_msg>add a test for unsized index<commit_after>// compile-pass

// `std::ops::Index` has an `: ?Sized` bound on the `Idx` type param. This is
// an accidental left-over from the times when it `Index` was by-reference.
// Tightening the bound now could be a breaking change. Although no crater
// regression were observed (https://github.com/rust-lang/rust/pull/59527),
// let's be conservative and just add a test for this.
#![feature(unsized_locals)]

use std::ops;

pub struct A;

impl ops::Index<str> for A {
    type Output = ();
    fn index(&self, _: str) -> &Self::Output { panic!() }
}

impl ops::IndexMut<str> for A {
    fn index_mut(&mut self, _: str) -> &mut Self::Output { panic!() }
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Move text handling operations to it's own struct<commit_after><|endoftext|>


<commit_before>use audio::ac97::AC97;
use audio::intelhda::IntelHDA;

use core::cell::UnsafeCell;

use common::debug;

use disk::ahci::Ahci;
use disk::ide::Ide;

use drivers::pci::config::PciConfig;

use env::Environment;

use network::intel8254x::Intel8254x;
use network::rtl8139::Rtl8139;

use schemes::file::FileScheme;

use usb::ehci::Ehci;
use usb::ohci::Ohci;
use usb::uhci::Uhci;
use usb::xhci::Xhci;

/// PCI device
pub unsafe fn pci_device(env: &mut Environment,
                         mut pci: PciConfig,
                         class_id: u32,
                         subclass_id: u32,
                         interface_id: u32,
                         vendor_code: u32,
                         device_code: u32) {
    if class_id == 0x01 {
        if subclass_id == 0x01 {
            if let Some(module) = FileScheme::new(Ide::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        } else if subclass_id == 0x06 {
            if let Some(module) = FileScheme::new(Ahci::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        }
    } else if class_id == 0x0C && subclass_id == 0x03 {
        if interface_id == 0x30 {
            let base = pci.read(0x10) as usize;

            let mut module = box Xhci {
                pci: pci,
                base: base & 0xFFFFFFF0,
                memory_mapped: base & 1 == 0,
                irq: pci.read(0x3C) as u8 & 0xF,
            };
            module.init();
            env.schemes.push(UnsafeCell::new(module));
        } else if interface_id == 0x20 {
            env.schemes.push(UnsafeCell::new(Ehci::new(pci)));
        } else if interface_id == 0x10 {
            env.schemes.push(UnsafeCell::new(Ohci::new(pci)));
        } else if interface_id == 0x00 {
            env.schemes.push(UnsafeCell::new(Uhci::new(pci)));
        } else {
            debug!("Unknown USB interface version {:X}\n", interface_id);
        }
    } else {
        match vendor_code {
            0x10EC => match device_code { // REALTEK
                0x8139 => env.schemes.push(UnsafeCell::new(Rtl8139::new(pci))),
                _ => (),
            },
            0x8086 => match device_code { // INTEL
                0x100E => env.schemes.push(UnsafeCell::new(Intel8254x::new(pci))),
                0x2415 => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                0x24C5 => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                0x2668 => {
                    let base = pci.read(0x10) as usize;
                    let mut module = box IntelHDA {
                        pci: pci,
                        base: base & 0xFFFFFFF0,
                        memory_mapped: base & 1 == 0,
                        irq: pci.read(0x3C) as u8 & 0xF,
                    };
                    module.init();
                    env.schemes.push(UnsafeCell::new(module));
                }
                _ => (),
            },
            _ => (),
        }
    }
}

/// Initialize PCI session
pub unsafe fn pci_init(env: &mut Environment) {
    for bus in 0..256 {
        for slot in 0..32 {
            for func in 0..8 {
                let mut pci = PciConfig::new(bus as u8, slot as u8, func as u8);
                let id = pci.read(0);

                if (id & 0xFFFF) != 0xFFFF {
                    let class_id = pci.read(8);

                    debug!(" * PCI {}, {}, {}: ID {:X} CL {:X}",
                           bus,
                           slot,
                           func,
                           id,
                           class_id);

                    for i in 0..6 {
                        let bar = pci.read(i * 4 + 0x10);
                        if bar > 0 {
                            debug!(" BAR{}: {:X}", i, bar);

                            pci.write(i * 4 + 0x10, 0xFFFFFFFF);
                            let size = (0xFFFFFFFF - (pci.read(i * 4 + 0x10) & 0xFFFFFFF0)) + 1;
                            pci.write(i * 4 + 0x10, bar);

                            if size > 0 {
                                debug!(" {}", size);
                            }
                        }
                    }

                    debug::dl();

                    pci_device(env,
                               pci,
                               (class_id >> 24) & 0xFF,
                               (class_id >> 16) & 0xFF,
                               (class_id >> 8) & 0xFF,
                               id & 0xFFFF,
                               (id >> 16) & 0xFFFF);
                }
            }
        }
    }
}
<commit_msg>[PCI refactor] Use constants instead of raw numbers<commit_after>use audio::ac97::AC97;
use audio::intelhda::IntelHDA;

use core::cell::UnsafeCell;

use common::debug;

use disk::ahci::Ahci;
use disk::ide::Ide;

use env::Environment;

use network::intel8254x::Intel8254x;
use network::rtl8139::Rtl8139;

use schemes::file::FileScheme;

use usb::ehci::Ehci;
use usb::ohci::Ohci;
use usb::uhci::Uhci;
use usb::xhci::Xhci;

use super::config::PciConfig;
use super::common::class::*;
use super::common::subclass::*;
use super::common::programming_interface::*;

/// PCI device
pub unsafe fn pci_device(env: &mut Environment,
                         mut pci: PciConfig,
                         class_id: u8,
                         subclass_id: u8,
                         interface_id: u8,
                         vendor_code: u16,
                         device_code: u16) {
    if class_id == MASS_STORAGE {
        if subclass_id == IDE {
            if let Some(module) = FileScheme::new(Ide::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        } else if subclass_id == SATA && interface_id == AHCI {
            if let Some(module) = FileScheme::new(Ahci::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        }
    } else if class_id == SERIAL_BUS && subclass_id == USB {
        if interface_id == XHCI {
            let base = pci.read(0x10) as usize;

            let mut module = box Xhci {
                pci: pci,
                base: base & 0xFFFFFFF0,
                memory_mapped: base & 1 == 0,
                irq: pci.read(0x3C) as u8 & 0xF,
            };
            module.init();
            env.schemes.push(UnsafeCell::new(module));
        } else if interface_id == EHCI {
            env.schemes.push(UnsafeCell::new(Ehci::new(pci)));
        } else if interface_id == OHCI {
            env.schemes.push(UnsafeCell::new(Ohci::new(pci)));
        } else if interface_id == UHCI {
            env.schemes.push(UnsafeCell::new(Uhci::new(pci)));
        } else {
            debug!("Unknown USB interface version {:X}\n", interface_id);
        }
    } else {
        match vendor_code {
            0x10EC => match device_code { // REALTEK
                0x8139 => env.schemes.push(UnsafeCell::new(Rtl8139::new(pci))),
                _ => (),
            },
            0x8086 => match device_code { // INTEL
                0x100E => env.schemes.push(UnsafeCell::new(Intel8254x::new(pci))),
                0x2415 => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                0x24C5 => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                0x2668 => {
                    let base = pci.read(0x10) as usize;
                    let mut module = box IntelHDA {
                        pci: pci,
                        base: base & 0xFFFFFFF0,
                        memory_mapped: base & 1 == 0,
                        irq: pci.read(0x3C) as u8 & 0xF,
                    };
                    module.init();
                    env.schemes.push(UnsafeCell::new(module));
                }
                _ => (),
            },
            _ => (),
        }
    }
}

/// Initialize PCI session
pub unsafe fn pci_init(env: &mut Environment) {
    for bus in 0..256 {
        for slot in 0..32 {
            for func in 0..8 {
                let mut pci = PciConfig::new(bus as u8, slot as u8, func as u8);
                let id = pci.read(0);

                if (id & 0xFFFF) != 0xFFFF {
                    let class_id = pci.read(8);

                    debug!(" * PCI {}, {}, {}: ID {:X} CL {:X}",
                           bus,
                           slot,
                           func,
                           id,
                           class_id);

                    for i in 0..6 {
                        let bar = pci.read(i * 4 + 0x10);
                        if bar > 0 {
                            debug!(" BAR{}: {:X}", i, bar);

                            pci.write(i * 4 + 0x10, 0xFFFFFFFF);
                            let size = (0xFFFFFFFF - (pci.read(i * 4 + 0x10) & 0xFFFFFFF0)) + 1;
                            pci.write(i * 4 + 0x10, bar);

                            if size > 0 {
                                debug!(" {}", size);
                            }
                        }
                    }

                    debug::dl();

                    pci_device(env,
                               pci,
                               ((class_id >> 24) & 0xFF) as u8,
                               ((class_id >> 16) & 0xFF) as u8,
                               ((class_id >> 8) & 0xFF) as u8,
                               (id & 0xFFFF) as u16,
                               ((id >> 16) & 0xFFFF) as u16);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add `http-server.rs` example.<commit_after>extern crate mioco;
extern crate env_logger;
extern crate httparse;

use std::net::SocketAddr;
use std::str::FromStr;
use std::io::{Write, Read};
use mioco::mio::tcp::{TcpSocket};

const DEFAULT_LISTEN_ADDR : &'static str = "127.0.0.1:5555";

fn listend_addr() -> SocketAddr {
    FromStr::from_str(DEFAULT_LISTEN_ADDR).unwrap()
}

const RESPONSE: &'static str = "HTTP/1.1 200 OK\r
Content-Length: 14\r
\r
Hello World\r
\r";

const RESPONSE_404: &'static str = "HTTP/1.1 404 Not Found\r
Content-Length: 14\r
\r
Hello World\r
\r";

fn main() {
    env_logger::init().unwrap();
    let addr = listend_addr();

    let sock = TcpSocket::v4().unwrap();
    sock.bind(&addr).unwrap();
    let sock = sock.listen(1024).unwrap();

    println!("Starting mioco http server on {:?}", sock.local_addr().unwrap());

    mioco::start(move |mioco| {
        for _ in 0..mioco.thread_num() {
            let sock = try!(sock.try_clone());
            mioco.spawn(move |mioco| {

                let sock = mioco.wrap(sock);

                loop {
                    let conn = try!(sock.accept());
                    mioco.spawn(move |mioco| {
                        let mut conn = mioco.wrap(conn);

                        let mut buf_i = 0;
                        let mut buf = [0u8; 1024];

                        let mut headers = [httparse::EMPTY_HEADER; 16];
                        loop {
                            let len = try!(conn.read(&mut buf[buf_i..]));

                            if len == 0 {
                                return Ok(());
                            }

                            buf_i += len;

                            let mut req = httparse::Request::new(&mut headers);
                            let res = req.parse(&buf[0..buf_i]).unwrap();

                            if res.is_complete() {
                                let req_len = res.unwrap();
                                match req.path {
                                    Some(ref _path) => {
                                        let _ = try!(conn.write_all(&RESPONSE.as_bytes()));
                                        if req_len != buf_i {
                                            // request has a body; TODO: handle it
                                        }
                                        buf_i = 0;
                                    },
                                    None => {
                                        let _ = try!(conn.write_all(&RESPONSE_404.as_bytes()));
                                        return Ok(());
                                    }
                                }
                            }
                        }
                    });
                }
            });
        }
        Ok(())
    });
}
<|endoftext|>


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

// compile-flags:-Znll

fn can_panic() -> Box<usize> {
    Box::new(44)
}

fn main() {
    let mut x = Box::new(22);
    x = can_panic();
}

// Check that:
// - `_1` is the variable corresponding to `x`
// and
// - `_1` is live when `can_panic` is called (because it may be dropped)
//
// END RUST SOURCE
// START rustc.node12.nll.0.mir
//    | Variables live on entry to the block bb0:
//    bb0: {
//        StorageLive(_1);                 // scope 1 at /Users/nmatsakis/versioned/rust-3/src/test/mir-opt/nll/liveness-call-subtlety.rs:18:9: 18:14
//        _1 = const <std::boxed::Box<T>>::new(const 22usize) -> bb1; // scope 1 at /Users/nmatsakis/versioned/rust-3/src/test/mir-opt/nll/liveness-call-subtlety.rs:18:17: 18:29
//    }
// END rustc.node12.nll.0.mir
// START rustc.node12.nll.0.mir
//    | Variables live on entry to the block bb1:
//    | - _1
//    bb1: {
//        StorageLive(_2);                 // scope 1 at /Users/nmatsakis/versioned/rust-3/src/test/mir-opt/nll/liveness-call-subtlety.rs:19:9: 19:20
//        _2 = const can_panic() -> [return: bb2, unwind: bb4]; // scope 1 at /Users/nmatsakis/versioned/rust-3/src/test/mir-opt/nll/liveness-call-subtlety.rs:19:9: 19:20
//    }
// END rustc.node12.nll.0.mir
<|endoftext|>


<commit_before><commit_msg>Fix naming.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix: Do not create entries with Store::retrieve()<commit_after><|endoftext|>


<commit_before><commit_msg>Add remove var command<commit_after><|endoftext|>


<commit_before><commit_msg>Fix `BorrowMutError` and simplify codes.<commit_after><|endoftext|>


<commit_before>use common::context::*;
use common::scheduler::*;

use graphics::bmp::*;

use programs::common::*;
use programs::editor::*;
use programs::executor::*;
use programs::filemanager::*;
use programs::viewer::*;

pub struct Session {
    pub display: Display,
    pub background: BMP,
    pub cursor: BMP,
    pub icon: BMP,
    pub mouse_point: Point,
    last_mouse_event: MouseEvent,
    pub items: Vec<Box<SessionItem>>,
    pub windows: Vec<*mut Window>,
    pub windows_ordered: Vec<*mut Window>,
    pub redraw: usize
}

impl Session {
    pub fn new() -> Session {
        unsafe {
            Session {
                display: Display::root(),
                background: BMP::new(),
                cursor: BMP::new(),
                icon: BMP::new(),
                mouse_point: Point::new(0, 0),
                last_mouse_event: MouseEvent {
                    x: 0,
                    y: 0,
                    left_button: false,
                    middle_button: false,
                    right_button: false,
                    valid: false
                },
                items: Vec::new(),
                windows: Vec::new(),
                windows_ordered: Vec::new(),
                redraw: REDRAW_ALL
            }
        }
    }

    pub unsafe fn add_window(&mut self, add_window_ptr: *mut Window){
        self.windows.push(add_window_ptr);
        self.windows_ordered.push(add_window_ptr);
        self.redraw = max(self.redraw, REDRAW_ALL);
    }

    pub unsafe fn remove_window(&mut self, remove_window_ptr: *mut Window){
        let mut i = 0;
        while i < self.windows.len() {
            let mut remove = false;

            match self.windows.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                }else{
                    i += 1;
                },
                Option::None => break
            }

            if remove {
                self.windows.remove(i);
                self.redraw = max(self.redraw, REDRAW_ALL);
            }
        }

        i = 0;
        while i < self.windows_ordered.len() {
            let mut remove = false;

            match self.windows_ordered.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                }else{
                    i += 1;
                },
                Option::None => break
            }

            if remove {
                self.windows_ordered.remove(i);
                self.redraw = max(self.redraw, REDRAW_ALL);
            }
        }
    }

    pub unsafe fn on_irq(&mut self, irq: u8){
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_irq(irq);
            end_no_ints(reenable);
        }
    }

    pub unsafe fn on_poll(&mut self){
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_poll();
            end_no_ints(reenable);
        }
    }

    pub fn open(&self, url: &URL) -> Box<Resource>{
        if url.scheme().len() == 0 {
            let mut list = String::new();

            for item in self.items.iter() {
                let scheme = item.scheme();
                if scheme.len() > 0 {
                    if list.len() > 0 {
                        list = list + "\n" + scheme;
                    }else{
                        list = scheme;
                    }
                }
            }

            return box VecResource::new(URL::new(), ResourceType::Dir, list.to_utf8());
        }else{
            for item in self.items.iter() {
                if item.scheme() == url.scheme() {
                    return item.open(url);
                }
            }
            return box NoneResource;
        }
    }

    fn item_main(&mut self, mut item: Box<SessionItem>, url: URL){
        Context::spawn(box move ||{
            item.main(url);
        });
    }

    fn on_key(&mut self, key_event: KeyEvent){
        if self.windows.len() > 0 {
            match self.windows.get(self.windows.len() - 1){
                Option::Some(window_ptr) => {
                    unsafe{
                        (**window_ptr).on_key(key_event);
                        self.redraw = max(self.redraw, REDRAW_ALL);
                    }
                },
                Option::None => ()
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent){
        let mut catcher = -1;
        for reverse_i in 0..self.windows.len() {
            let i = self.windows.len() - 1 - reverse_i;
            match self.windows.get(i){
                Option::Some(window_ptr) => unsafe{
                    if (**window_ptr).on_mouse(mouse_event, catcher < 0) {
                        catcher = i as isize;

                        self.redraw = max(self.redraw, REDRAW_ALL);
                    }
                },
                Option::None => ()
            }
        }

        //Not caught, can be caught by task bar
        if catcher < 0 {
            if mouse_event.left_button &&  !self.last_mouse_event.left_button && mouse_event.y >= self.display.height as isize - 32 {
                if mouse_event.x <= 56 {
                    self.item_main(box FileManager::new(), URL::from_string(&"file:///".to_string()));
                }else{
                    let mut chars = 32;
                    while chars > 4 && (chars*8 + 3*4) * self.windows.len() > self.display.width {
                        chars -= 1;
                    }

                    for i in 0..self.windows_ordered.len() {
                        let x = (5*8 + 2*8 + (chars*8 + 3*4) * i) as isize;
                        let w = (chars*8 + 2*4) as usize;
                        if mouse_event.x >= x && mouse_event.x < x + w as isize {
                            match self.windows_ordered.get(i) {
                                Option::Some(window_ptr) => unsafe {
                                    for j in 0..self.windows.len() {
                                        match self.windows.get(j){
                                            Option::Some(catcher_window_ptr) => if catcher_window_ptr == window_ptr {
                                                if j == self.windows.len() - 1 {
                                                    (**window_ptr).minimized = !(**window_ptr).minimized;
                                                }else{
                                                    catcher = j as isize;
                                                    (**window_ptr).minimized = false;
                                                }
                                                break;
                                            },
                                            Option::None => break
                                        }
                                    }
                                    self.redraw = max(self.redraw, REDRAW_ALL);
                                },
                                Option::None => ()
                            }
                            break;
                        }
                    }
                }
            }
        }

        if catcher >= 0 && catcher < self.windows.len() as isize - 1 {
            match self.windows.remove(catcher as usize){
                Option::Some(window_ptr) => self.windows.push(window_ptr),
                Option::None => ()
            }
        }

        self.last_mouse_event = mouse_event;
    }

    pub unsafe fn redraw(&mut self){
        if self.redraw > REDRAW_NONE {
            if self.redraw >= REDRAW_ALL {
                self.display.set(Color::new(64, 64, 64));
                if self.background.data > 0 {
                    self.display.image(Point::new((self.display.width as isize - self.background.size.width as isize)/2, (self.display.height as isize - self.background.size.height as isize)/2), self.background.data, self.background.size);
                }

                for i in 0..self.windows.len(){
                    match self.windows.get(i) {
                        Option::Some(window_ptr) => {
                            (**window_ptr).focused = i == self.windows.len() - 1;
                            (**window_ptr).draw(&self.display);
                        },
                        Option::None => ()
                    }
                }

                self.display.rect(Point::new(0, self.display.height as isize - 32), Size::new(self.display.width, 32), Color::new(0, 0, 0));
                if self.icon.data > 0 {
                    self.display.image_alpha(Point::new(12, self.display.height as isize - 32), self.icon.data, self.icon.size);
                }else{
                    self.display.text(Point::new(8, self.display.height as isize - 24), &String::from_str("Redox"), Color::new(255, 255, 255));
                }

                let mut chars = 32;
                while chars > 4 && (chars*8 + 3*4) * self.windows.len() > self.display.width {
                    chars -= 1;
                }

                for i in 0..self.windows_ordered.len() {
                    match self.windows_ordered.get(i) {
                        Option::Some(window_ptr) => {
                            let x = (5*8 + 2*8 + (chars*8 + 3*4) * i) as isize;
                            let w = (chars*8 + 2*4) as usize;
                            self.display.rect(Point::new(x, self.display.height as isize - 32), Size::new(w, 32), (**window_ptr).border_color);
                            self.display.text(Point::new(x + 4, self.display.height as isize - 24), &(**window_ptr).title.substr(0, chars as usize), (**window_ptr).title_color);
                        },
                        Option::None => ()
                    }
                }
            }

            let reenable = start_no_ints();

            self.display.flip();

            if self.cursor.data > 0 {
                self.display.image_alpha_onscreen(self.mouse_point, self.cursor.data, self.cursor.size);
            }else{
                self.display.char_onscreen(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9), 'X', Color::new(255, 255, 255));
            }

            self.redraw = REDRAW_NONE;

            end_no_ints(reenable);
        }
    }

    pub fn event(&mut self, event: Event){
        match event.to_option() {
            EventOption::Mouse(mouse_event) => self.on_mouse(mouse_event),
            EventOption::Key(key_event) => self.on_key(key_event),
            EventOption::Redraw(redraw_event) => self.redraw = max(self.redraw, redraw_event.redraw),
            EventOption::Open(open_event) => {
                let url_string = open_event.url_string;
                let url = URL::from_string(&url_string);

                if url_string.ends_with(".md".to_string()) || url_string.ends_with(".rs".to_string()) || url_string.ends_with(".sh".to_string()){
                    self.item_main(box Editor::new(), url);
                }else if url_string.ends_with(".bin".to_string()){
                    self.item_main(box Executor::new(), url);
                }else if url_string.ends_with(".bmp".to_string()){
                    self.item_main(box Viewer::new(), url);
                }else{
                    d("No program found: ");
                    url.d();
                    dl();
                }
            }
            _ => ()
        }
    }
}
<commit_msg>Bug fixes for windows<commit_after>use common::context::*;
use common::scheduler::*;

use graphics::bmp::*;

use programs::common::*;
use programs::editor::*;
use programs::executor::*;
use programs::filemanager::*;
use programs::viewer::*;

pub struct Session {
    pub display: Display,
    pub background: BMP,
    pub cursor: BMP,
    pub icon: BMP,
    pub mouse_point: Point,
    last_mouse_event: MouseEvent,
    pub items: Vec<Box<SessionItem>>,
    pub windows: Vec<*mut Window>,
    pub windows_ordered: Vec<*mut Window>,
    pub redraw: usize
}

impl Session {
    pub fn new() -> Session {
        unsafe {
            Session {
                display: Display::root(),
                background: BMP::new(),
                cursor: BMP::new(),
                icon: BMP::new(),
                mouse_point: Point::new(0, 0),
                last_mouse_event: MouseEvent {
                    x: 0,
                    y: 0,
                    left_button: false,
                    middle_button: false,
                    right_button: false,
                    valid: false
                },
                items: Vec::new(),
                windows: Vec::new(),
                windows_ordered: Vec::new(),
                redraw: REDRAW_ALL
            }
        }
    }

    pub unsafe fn add_window(&mut self, add_window_ptr: *mut Window){
        self.windows.push(add_window_ptr);
        self.windows_ordered.push(add_window_ptr);
        self.redraw = max(self.redraw, REDRAW_ALL);
    }

    pub unsafe fn remove_window(&mut self, remove_window_ptr: *mut Window){
        let mut i = 0;
        while i < self.windows.len() {
            let mut remove = false;

            match self.windows.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                }else{
                    i += 1;
                },
                Option::None => break
            }

            if remove {
                self.windows.remove(i);
                self.redraw = max(self.redraw, REDRAW_ALL);
            }
        }

        i = 0;
        while i < self.windows_ordered.len() {
            let mut remove = false;

            match self.windows_ordered.get(i) {
                Option::Some(window_ptr) => if *window_ptr == remove_window_ptr {
                    remove = true;
                }else{
                    i += 1;
                },
                Option::None => break
            }

            if remove {
                self.windows_ordered.remove(i);
                self.redraw = max(self.redraw, REDRAW_ALL);
            }
        }
    }

    pub unsafe fn on_irq(&mut self, irq: u8){
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_irq(irq);
            end_no_ints(reenable);
        }
    }

    pub unsafe fn on_poll(&mut self){
        for item in self.items.iter() {
            let reenable = start_no_ints();
            item.on_poll();
            end_no_ints(reenable);
        }
    }

    pub fn open(&self, url: &URL) -> Box<Resource>{
        if url.scheme().len() == 0 {
            let mut list = String::new();

            for item in self.items.iter() {
                let scheme = item.scheme();
                if scheme.len() > 0 {
                    if list.len() > 0 {
                        list = list + "\n" + scheme;
                    }else{
                        list = scheme;
                    }
                }
            }

            return box VecResource::new(URL::new(), ResourceType::Dir, list.to_utf8());
        }else{
            for item in self.items.iter() {
                if item.scheme() == url.scheme() {
                    return item.open(url);
                }
            }
            return box NoneResource;
        }
    }

    fn item_main(&mut self, mut item: Box<SessionItem>, url: URL){
        Context::spawn(box move ||{
            item.main(url);
        });
    }

    fn on_key(&mut self, key_event: KeyEvent){
        if self.windows.len() > 0 {
            match self.windows.get(self.windows.len() - 1){
                Option::Some(window_ptr) => {
                    unsafe{
                        (**window_ptr).on_key(key_event);
                        self.redraw = max(self.redraw, REDRAW_ALL);
                    }
                },
                Option::None => ()
            }
        }
    }

    fn on_mouse(&mut self, mouse_event: MouseEvent){
        let mut catcher = -1;

        if mouse_event.y >= self.display.height as isize - 32 {
            if mouse_event.left_button &&  !self.last_mouse_event.left_button {
                if mouse_event.x <= 56 {
                    self.item_main(box FileManager::new(), URL::from_string(&"file:///".to_string()));
                }else{
                    let mut chars = 32;
                    while chars > 4 && (chars*8 + 3*4) * self.windows.len() > self.display.width {
                        chars -= 1;
                    }

                    for i in 0..self.windows_ordered.len() {
                        let x = (5*8 + 2*8 + (chars*8 + 3*4) * i) as isize;
                        let w = (chars*8 + 2*4) as usize;
                        if mouse_event.x >= x && mouse_event.x < x + w as isize {
                            match self.windows_ordered.get(i) {
                                Option::Some(window_ptr) => unsafe {
                                    for j in 0..self.windows.len() {
                                        match self.windows.get(j){
                                            Option::Some(catcher_window_ptr) => if catcher_window_ptr == window_ptr {
                                                if j == self.windows.len() - 1 {
                                                    (**window_ptr).minimized = !(**window_ptr).minimized;
                                                }else{
                                                    catcher = j as isize;
                                                    (**window_ptr).minimized = false;
                                                }
                                                break;
                                            },
                                            Option::None => break
                                        }
                                    }
                                    self.redraw = max(self.redraw, REDRAW_ALL);
                                },
                                Option::None => ()
                            }
                            break;
                        }
                    }
                }
            }
        }else{
            for reverse_i in 0..self.windows.len() {
                let i = self.windows.len() - 1 - reverse_i;
                match self.windows.get(i){
                    Option::Some(window_ptr) => unsafe{
                        if (**window_ptr).on_mouse(mouse_event, catcher < 0) {
                            catcher = i as isize;

                            self.redraw = max(self.redraw, REDRAW_ALL);
                        }
                    },
                    Option::None => ()
                }
            }
        }

        if catcher >= 0 && catcher < self.windows.len() as isize - 1 {
            match self.windows.remove(catcher as usize){
                Option::Some(window_ptr) => self.windows.push(window_ptr),
                Option::None => ()
            }
        }

        self.last_mouse_event = mouse_event;
    }

    pub unsafe fn redraw(&mut self){
        if self.redraw > REDRAW_NONE {
            if self.redraw >= REDRAW_ALL {
                self.display.set(Color::new(64, 64, 64));
                if self.background.data > 0 {
                    self.display.image(Point::new((self.display.width as isize - self.background.size.width as isize)/2, (self.display.height as isize - self.background.size.height as isize)/2), self.background.data, self.background.size);
                }

                for i in 0..self.windows.len(){
                    match self.windows.get(i) {
                        Option::Some(window_ptr) => {
                            (**window_ptr).focused = i == self.windows.len() - 1;
                            (**window_ptr).draw(&self.display);
                        },
                        Option::None => ()
                    }
                }

                self.display.rect(Point::new(0, self.display.height as isize - 32), Size::new(self.display.width, 32), Color::new(0, 0, 0));
                if self.icon.data > 0 {
                    self.display.image_alpha(Point::new(12, self.display.height as isize - 32), self.icon.data, self.icon.size);
                }else{
                    self.display.text(Point::new(8, self.display.height as isize - 24), &String::from_str("Redox"), Color::new(255, 255, 255));
                }

                let mut chars = 32;
                while chars > 4 && (chars*8 + 3*4) * self.windows.len() > self.display.width {
                    chars -= 1;
                }

                for i in 0..self.windows_ordered.len() {
                    match self.windows_ordered.get(i) {
                        Option::Some(window_ptr) => {
                            let x = (5*8 + 2*8 + (chars*8 + 3*4) * i) as isize;
                            let w = (chars*8 + 2*4) as usize;
                            self.display.rect(Point::new(x, self.display.height as isize - 32), Size::new(w, 32), (**window_ptr).border_color);
                            self.display.text(Point::new(x + 4, self.display.height as isize - 24), &(**window_ptr).title.substr(0, chars as usize), (**window_ptr).title_color);
                        },
                        Option::None => ()
                    }
                }
            }

            let reenable = start_no_ints();

            self.display.flip();

            if self.cursor.data > 0 {
                self.display.image_alpha_onscreen(self.mouse_point, self.cursor.data, self.cursor.size);
            }else{
                self.display.char_onscreen(Point::new(self.mouse_point.x - 3, self.mouse_point.y - 9), 'X', Color::new(255, 255, 255));
            }

            self.redraw = REDRAW_NONE;

            end_no_ints(reenable);
        }
    }

    pub fn event(&mut self, event: Event){
        match event.to_option() {
            EventOption::Mouse(mouse_event) => self.on_mouse(mouse_event),
            EventOption::Key(key_event) => self.on_key(key_event),
            EventOption::Redraw(redraw_event) => self.redraw = max(self.redraw, redraw_event.redraw),
            EventOption::Open(open_event) => {
                let url_string = open_event.url_string;
                let url = URL::from_string(&url_string);

                if url_string.ends_with(".md".to_string()) || url_string.ends_with(".rs".to_string()) || url_string.ends_with(".sh".to_string()){
                    self.item_main(box Editor::new(), url);
                }else if url_string.ends_with(".bin".to_string()){
                    self.item_main(box Executor::new(), url);
                }else if url_string.ends_with(".bmp".to_string()){
                    self.item_main(box Viewer::new(), url);
                }else{
                    d("No program found: ");
                    url.d();
                    dl();
                }
            }
            _ => ()
        }
    }
}
<|endoftext|>