<commit_before><commit_msg>Rollup merge of #54225 - pnkfelix:issue-53675-add-test-called-panic, r=petrochenkov<commit_after>// rust-lang/rust#53675: At one point the compiler errored when a test
// named `panic` used the `assert!` macro in expression position.

// compile-pass
// compile-flags: --test

mod in_expression_position {
    #[test]
    fn panic() {
        assert!(true)
    }
}

mod in_statement_position {
    #[test]
    fn panic() {
        assert!(true);
    }
}

mod what_if_we_use_panic_directly_in_expr {
    #[test]
    #[should_panic]
    fn panic() {
        panic!("in expr")
    }
}

mod what_if_we_use_panic_directly_in_stmt {
    #[test]
    #[should_panic]
    fn panic() {
        panic!("in stmt");
    }
}
<|endoftext|>


<commit_before>extern crate rand;

#[allow(non_camel_case_types)]
pub mod ll {
    use libc::{c_int, uint8_t, uint32_t};

    //SDL_pixels.h
    pub struct SDL_Color {
        pub r: uint8_t,
        pub g: uint8_t,
        pub b: uint8_t,
        pub a: uint8_t,
    }

    pub struct SDL_Palette {
        pub ncolors: c_int,
        pub colors: *const SDL_Color,
        pub version: uint32_t,
        pub refcount: c_int
    }

    #[allow(uppercase_variables)]
    pub struct SDL_PixelFormat {
        pub format: SDL_PixelFormatFlag,
        pub palette: *const SDL_Palette,
        pub BitsPerPixel: uint8_t,
        pub BytesPerPixel: uint8_t,
        pub padding: [uint8_t, ..2],
        pub Rmask: uint8_t,
        pub Gmask: uint8_t,
        pub Bmask: uint8_t,
        pub Amask: uint8_t,
        pub Rloss: uint8_t,
        pub Gloss: uint8_t,
        pub Bloss: uint8_t,
        pub Aloss: uint8_t,
        pub Rshift: uint8_t,
        pub Gshift: uint8_t,
        pub Bshift: uint8_t,
        pub Ashift: uint8_t,
        pub refcount: c_int,
        pub next: *const SDL_PixelFormat
    }

    pub type SDL_PixelFormatFlag = uint32_t;
    pub static SDL_PIXELFORMAT_UNKNOWN: SDL_PixelFormatFlag = 0x0;
    pub static SDL_PIXELFORMAT_INDEX1LSB: SDL_PixelFormatFlag = 0x11100100;
    pub static SDL_PIXELFORMAT_INDEX1MSB: SDL_PixelFormatFlag = 0x11200100;
    pub static SDL_PIXELFORMAT_INDEX4LSB: SDL_PixelFormatFlag = 0x12100400;
    pub static SDL_PIXELFORMAT_INDEX4MSB: SDL_PixelFormatFlag = 0x12200400;
    pub static SDL_PIXELFORMAT_INDEX8: SDL_PixelFormatFlag = 0x13000801;
    pub static SDL_PIXELFORMAT_RGB332: SDL_PixelFormatFlag = 0x14110801;
    pub static SDL_PIXELFORMAT_RGB444: SDL_PixelFormatFlag = 0x15120c02;
    pub static SDL_PIXELFORMAT_RGB555: SDL_PixelFormatFlag = 0x15130f02;
    pub static SDL_PIXELFORMAT_BGR555: SDL_PixelFormatFlag = 0x15530f02;
    pub static SDL_PIXELFORMAT_ARGB4444: SDL_PixelFormatFlag = 0x15321002;
    pub static SDL_PIXELFORMAT_RGBA4444: SDL_PixelFormatFlag = 0x15421002;
    pub static SDL_PIXELFORMAT_ABGR4444: SDL_PixelFormatFlag = 0x15721002;
    pub static SDL_PIXELFORMAT_BGRA4444: SDL_PixelFormatFlag = 0x15821002;
    pub static SDL_PIXELFORMAT_ARGB1555: SDL_PixelFormatFlag = 0x15331002;
    pub static SDL_PIXELFORMAT_RGBA5551: SDL_PixelFormatFlag = 0x15441002;
    pub static SDL_PIXELFORMAT_ABGR1555: SDL_PixelFormatFlag = 0x15731002;
    pub static SDL_PIXELFORMAT_BGRA5551: SDL_PixelFormatFlag = 0x15841002;
    pub static SDL_PIXELFORMAT_RGB565: SDL_PixelFormatFlag = 0x15151002;
    pub static SDL_PIXELFORMAT_BGR565: SDL_PixelFormatFlag = 0x15551002;
    pub static SDL_PIXELFORMAT_RGB24: SDL_PixelFormatFlag = 0x17101803;
    pub static SDL_PIXELFORMAT_BGR24: SDL_PixelFormatFlag = 0x17401803;
    pub static SDL_PIXELFORMAT_RGB888: SDL_PixelFormatFlag = 0x16161804;
    pub static SDL_PIXELFORMAT_RGBX8888: SDL_PixelFormatFlag = 0x16261804;
    pub static SDL_PIXELFORMAT_BGR888: SDL_PixelFormatFlag = 0x16561804;
    pub static SDL_PIXELFORMAT_BGRX8888: SDL_PixelFormatFlag = 0x16661804;
    pub static SDL_PIXELFORMAT_ARGB8888: SDL_PixelFormatFlag = 0x16362004;
    pub static SDL_PIXELFORMAT_RGBA8888: SDL_PixelFormatFlag = 0x16462004;
    pub static SDL_PIXELFORMAT_ABGR8888: SDL_PixelFormatFlag = 0x16762004;
    pub static SDL_PIXELFORMAT_BGRA8888: SDL_PixelFormatFlag = 0x16862004;
    pub static SDL_PIXELFORMAT_ARGB2101010: SDL_PixelFormatFlag = 0x16372004;
    pub static SDL_PIXELFORMAT_YV12: SDL_PixelFormatFlag = 0x32315659;
    pub static SDL_PIXELFORMAT_IYUV: SDL_PixelFormatFlag = 0x56555949;
    pub static SDL_PIXELFORMAT_YUY2: SDL_PixelFormatFlag = 0x32595559;
    pub static SDL_PIXELFORMAT_UYVY: SDL_PixelFormatFlag = 0x59565955;
    pub static SDL_PIXELFORMAT_YVYU: SDL_PixelFormatFlag = 0x55595659;

    extern "C" {
        pub fn SDL_GetRGB(pixel: uint32_t, format: *const SDL_PixelFormat, r: *const uint8_t, g: *const uint8_t, b: *const uint8_t);
        pub fn SDL_GetRGBA(pixel: uint32_t, format: *const SDL_PixelFormat, r: *const uint8_t, g: *const uint8_t, b: *const uint8_t, a: *const uint8_t);
        pub fn SDL_MapRGB(format: *const SDL_PixelFormat, r: uint8_t, g: uint8_t, b: uint8_t) -> uint32_t;
        pub fn SDL_MapRGBA(format: *const SDL_PixelFormat, r: uint8_t, g: uint8_t, b: uint8_t, a: uint8_t) -> uint32_t;
    }
}
#[deriving(PartialEq)] #[allow(raw_pointer_deriving)]
pub struct Palette {
    raw: *const ll::SDL_Palette
}

impl_raw_accessors!(Palette, *const ll::SDL_Palette)

#[deriving(PartialEq)]
pub enum Color {
    RGB(u8, u8, u8),
    RGBA(u8, u8, u8, u8)
}

impl Color {
    pub fn to_u32(&self, format: &PixelFormat) -> u32 {
        match self {
            &RGB(r, g, b) => {
                unsafe { ll::SDL_MapRGB(format.raw, r, g, b) }
            }
            &RGBA(r, g, b, a) => {
                unsafe { ll::SDL_MapRGBA(format.raw, r, g, b, a) }
            }
        }
    }

    pub fn from_u32(format: &PixelFormat, pixel: u32) -> Color {
        let r: u8 = 0;
        let g: u8 = 0;
        let b: u8 = 0;
        let a: u8 = 0;

        unsafe {
            ll::SDL_GetRGBA(pixel, format.raw, &r, &g, &b, &a)
        };
        RGBA(r, g, b, a)
    }
}

impl rand::Rand for Color {
    fn rand<R: rand::Rng>(rng: &mut R) -> Color {
        if rng.gen() { RGBA(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
        else { RGB(rng.gen(), rng.gen(), rng.gen()) }
    }
}

#[deriving(PartialEq)] #[allow(raw_pointer_deriving)]
pub struct PixelFormat {
    raw: *const ll::SDL_PixelFormat
}

impl_raw_accessors!(PixelFormat, *const ll::SDL_PixelFormat)
impl_raw_constructor!(PixelFormat -> PixelFormat (raw: *const ll::SDL_PixelFormat))

#[deriving(PartialEq, Show, FromPrimitive)]
pub enum PixelFormatFlag {
    Unknown = ll::SDL_PIXELFORMAT_UNKNOWN as int,
    Index1LSB = ll::SDL_PIXELFORMAT_INDEX1LSB as int,
    Index1MSB = ll::SDL_PIXELFORMAT_INDEX1MSB as int,
    Index4LSB = ll::SDL_PIXELFORMAT_INDEX4LSB as int,
    Index4MSB = ll::SDL_PIXELFORMAT_INDEX4MSB as int,
    Index8 = ll::SDL_PIXELFORMAT_INDEX8 as int,
    RGB332 = ll::SDL_PIXELFORMAT_RGB332 as int,
    RGB444 = ll::SDL_PIXELFORMAT_RGB444 as int,
    RGB555 = ll::SDL_PIXELFORMAT_RGB555 as int,
    BGR555 = ll::SDL_PIXELFORMAT_BGR555 as int,
    ARGB4444 = ll::SDL_PIXELFORMAT_ARGB4444 as int,
    RGBA4444 = ll::SDL_PIXELFORMAT_RGBA4444 as int,
    ABGR4444 = ll::SDL_PIXELFORMAT_ABGR4444 as int,
    BGRA4444 = ll::SDL_PIXELFORMAT_BGRA4444 as int,
    ARGB1555 = ll::SDL_PIXELFORMAT_ARGB1555 as int,
    RGBA5551 = ll::SDL_PIXELFORMAT_RGBA5551 as int,
    ABGR1555 = ll::SDL_PIXELFORMAT_ABGR1555 as int,
    BGRA5551 = ll::SDL_PIXELFORMAT_BGRA5551 as int,
    RGB565 = ll::SDL_PIXELFORMAT_RGB565 as int,
    BGR565 = ll::SDL_PIXELFORMAT_BGR565 as int,
    RGB24 = ll::SDL_PIXELFORMAT_RGB24 as int,
    BGR24 = ll::SDL_PIXELFORMAT_BGR24 as int,
    RGB888 = ll::SDL_PIXELFORMAT_RGB888 as int,
    RGBX8888 = ll::SDL_PIXELFORMAT_RGBX8888 as int,
    BGR888 = ll::SDL_PIXELFORMAT_BGR888 as int,
    BGRX8888 = ll::SDL_PIXELFORMAT_BGRX8888 as int,
    ARGB8888 = ll::SDL_PIXELFORMAT_ARGB8888 as int,
    RGBA8888 = ll::SDL_PIXELFORMAT_RGBA8888 as int,
    ABGR8888 = ll::SDL_PIXELFORMAT_ABGR8888 as int,
    BGRA8888 = ll::SDL_PIXELFORMAT_BGRA8888 as int,
    ARGB2101010 = ll::SDL_PIXELFORMAT_ARGB2101010 as int,
    YV12 = ll::SDL_PIXELFORMAT_YV12 as int,
    IYUV = ll::SDL_PIXELFORMAT_IYUV as int,
    YUY2 = ll::SDL_PIXELFORMAT_YUY2 as int,
    UYVY = ll::SDL_PIXELFORMAT_UYVY as int,
    YVYU = ll::SDL_PIXELFORMAT_YVYU as int
}

impl PixelFormatFlag {
    pub fn byte_size_of_pixels(&self, num_of_pixels: uint) -> uint {
        match *self {
            RGB332
                => num_of_pixels * 1,
            RGB444 | RGB555 | BGR555 | ARGB4444 | RGBA4444 | ABGR4444 |
            BGRA4444 | ARGB1555 | RGBA5551 | ABGR1555 | BGRA5551 | RGB565 |
            BGR565
                => num_of_pixels * 2,
            RGB24 | BGR24
                => num_of_pixels * 3,
            RGB888 | RGBX8888 | BGR888 | BGRX8888 | ARGB8888 | RGBA8888 |
            ABGR8888 | BGRA8888 | ARGB2101010
                => num_of_pixels * 4,
            // YUV formats
            // FIXME: rounding error here?
            YV12 | IYUV
                => num_of_pixels / 2 * 3,
            YUY2 | UYVY | YVYU
                => num_of_pixels * 2,
            // Unsupported formats
            Index8
                => num_of_pixels * 1,
            Unknown | Index1LSB | Index1MSB | Index4LSB | Index4MSB
                => fail!("not supported format: {}", *self),
        }
    }

    pub fn byte_size_per_pixel(&self) -> uint {
        match *self {
            RGB332
                => 1,
            RGB444 | RGB555 | BGR555 | ARGB4444 | RGBA4444 | ABGR4444 |
            BGRA4444 | ARGB1555 | RGBA5551 | ABGR1555 | BGRA5551 | RGB565 |
            BGR565
                => 2,
            RGB24 | BGR24
                => 3,
            RGB888 | RGBX8888 | BGR888 | BGRX8888 | ARGB8888 | RGBA8888 |
            ABGR8888 | BGRA8888 | ARGB2101010
                => 4,
            // YUV formats
            YV12 | IYUV
                => 2,
            YUY2 | UYVY | YVYU
                => 2,
            // Unsupported formats
            Index8
                => 1,
            Unknown | Index1LSB | Index1MSB | Index4LSB | Index4MSB
                => fail!("not supported format: {}", *self),
        }
    }
}
<commit_msg>Added clone trait to color<commit_after>extern crate rand;

#[allow(non_camel_case_types)]
pub mod ll {
    use libc::{c_int, uint8_t, uint32_t};

    //SDL_pixels.h
    pub struct SDL_Color {
        pub r: uint8_t,
        pub g: uint8_t,
        pub b: uint8_t,
        pub a: uint8_t,
    }

    pub struct SDL_Palette {
        pub ncolors: c_int,
        pub colors: *const SDL_Color,
        pub version: uint32_t,
        pub refcount: c_int
    }

    #[allow(uppercase_variables)]
    pub struct SDL_PixelFormat {
        pub format: SDL_PixelFormatFlag,
        pub palette: *const SDL_Palette,
        pub BitsPerPixel: uint8_t,
        pub BytesPerPixel: uint8_t,
        pub padding: [uint8_t, ..2],
        pub Rmask: uint8_t,
        pub Gmask: uint8_t,
        pub Bmask: uint8_t,
        pub Amask: uint8_t,
        pub Rloss: uint8_t,
        pub Gloss: uint8_t,
        pub Bloss: uint8_t,
        pub Aloss: uint8_t,
        pub Rshift: uint8_t,
        pub Gshift: uint8_t,
        pub Bshift: uint8_t,
        pub Ashift: uint8_t,
        pub refcount: c_int,
        pub next: *const SDL_PixelFormat
    }

    pub type SDL_PixelFormatFlag = uint32_t;
    pub static SDL_PIXELFORMAT_UNKNOWN: SDL_PixelFormatFlag = 0x0;
    pub static SDL_PIXELFORMAT_INDEX1LSB: SDL_PixelFormatFlag = 0x11100100;
    pub static SDL_PIXELFORMAT_INDEX1MSB: SDL_PixelFormatFlag = 0x11200100;
    pub static SDL_PIXELFORMAT_INDEX4LSB: SDL_PixelFormatFlag = 0x12100400;
    pub static SDL_PIXELFORMAT_INDEX4MSB: SDL_PixelFormatFlag = 0x12200400;
    pub static SDL_PIXELFORMAT_INDEX8: SDL_PixelFormatFlag = 0x13000801;
    pub static SDL_PIXELFORMAT_RGB332: SDL_PixelFormatFlag = 0x14110801;
    pub static SDL_PIXELFORMAT_RGB444: SDL_PixelFormatFlag = 0x15120c02;
    pub static SDL_PIXELFORMAT_RGB555: SDL_PixelFormatFlag = 0x15130f02;
    pub static SDL_PIXELFORMAT_BGR555: SDL_PixelFormatFlag = 0x15530f02;
    pub static SDL_PIXELFORMAT_ARGB4444: SDL_PixelFormatFlag = 0x15321002;
    pub static SDL_PIXELFORMAT_RGBA4444: SDL_PixelFormatFlag = 0x15421002;
    pub static SDL_PIXELFORMAT_ABGR4444: SDL_PixelFormatFlag = 0x15721002;
    pub static SDL_PIXELFORMAT_BGRA4444: SDL_PixelFormatFlag = 0x15821002;
    pub static SDL_PIXELFORMAT_ARGB1555: SDL_PixelFormatFlag = 0x15331002;
    pub static SDL_PIXELFORMAT_RGBA5551: SDL_PixelFormatFlag = 0x15441002;
    pub static SDL_PIXELFORMAT_ABGR1555: SDL_PixelFormatFlag = 0x15731002;
    pub static SDL_PIXELFORMAT_BGRA5551: SDL_PixelFormatFlag = 0x15841002;
    pub static SDL_PIXELFORMAT_RGB565: SDL_PixelFormatFlag = 0x15151002;
    pub static SDL_PIXELFORMAT_BGR565: SDL_PixelFormatFlag = 0x15551002;
    pub static SDL_PIXELFORMAT_RGB24: SDL_PixelFormatFlag = 0x17101803;
    pub static SDL_PIXELFORMAT_BGR24: SDL_PixelFormatFlag = 0x17401803;
    pub static SDL_PIXELFORMAT_RGB888: SDL_PixelFormatFlag = 0x16161804;
    pub static SDL_PIXELFORMAT_RGBX8888: SDL_PixelFormatFlag = 0x16261804;
    pub static SDL_PIXELFORMAT_BGR888: SDL_PixelFormatFlag = 0x16561804;
    pub static SDL_PIXELFORMAT_BGRX8888: SDL_PixelFormatFlag = 0x16661804;
    pub static SDL_PIXELFORMAT_ARGB8888: SDL_PixelFormatFlag = 0x16362004;
    pub static SDL_PIXELFORMAT_RGBA8888: SDL_PixelFormatFlag = 0x16462004;
    pub static SDL_PIXELFORMAT_ABGR8888: SDL_PixelFormatFlag = 0x16762004;
    pub static SDL_PIXELFORMAT_BGRA8888: SDL_PixelFormatFlag = 0x16862004;
    pub static SDL_PIXELFORMAT_ARGB2101010: SDL_PixelFormatFlag = 0x16372004;
    pub static SDL_PIXELFORMAT_YV12: SDL_PixelFormatFlag = 0x32315659;
    pub static SDL_PIXELFORMAT_IYUV: SDL_PixelFormatFlag = 0x56555949;
    pub static SDL_PIXELFORMAT_YUY2: SDL_PixelFormatFlag = 0x32595559;
    pub static SDL_PIXELFORMAT_UYVY: SDL_PixelFormatFlag = 0x59565955;
    pub static SDL_PIXELFORMAT_YVYU: SDL_PixelFormatFlag = 0x55595659;

    extern "C" {
        pub fn SDL_GetRGB(pixel: uint32_t, format: *const SDL_PixelFormat, r: *const uint8_t, g: *const uint8_t, b: *const uint8_t);
        pub fn SDL_GetRGBA(pixel: uint32_t, format: *const SDL_PixelFormat, r: *const uint8_t, g: *const uint8_t, b: *const uint8_t, a: *const uint8_t);
        pub fn SDL_MapRGB(format: *const SDL_PixelFormat, r: uint8_t, g: uint8_t, b: uint8_t) -> uint32_t;
        pub fn SDL_MapRGBA(format: *const SDL_PixelFormat, r: uint8_t, g: uint8_t, b: uint8_t, a: uint8_t) -> uint32_t;
    }
}
#[deriving(PartialEq)] #[allow(raw_pointer_deriving)]
pub struct Palette {
    raw: *const ll::SDL_Palette
}

impl_raw_accessors!(Palette, *const ll::SDL_Palette)

#[deriving(PartialEq, Clone)]
pub enum Color {
    RGB(u8, u8, u8),
    RGBA(u8, u8, u8, u8)
}

impl Color {
    pub fn to_u32(&self, format: &PixelFormat) -> u32 {
        match self {
            &RGB(r, g, b) => {
                unsafe { ll::SDL_MapRGB(format.raw, r, g, b) }
            }
            &RGBA(r, g, b, a) => {
                unsafe { ll::SDL_MapRGBA(format.raw, r, g, b, a) }
            }
        }
    }

    pub fn from_u32(format: &PixelFormat, pixel: u32) -> Color {
        let r: u8 = 0;
        let g: u8 = 0;
        let b: u8 = 0;
        let a: u8 = 0;

        unsafe {
            ll::SDL_GetRGBA(pixel, format.raw, &r, &g, &b, &a)
        };
        RGBA(r, g, b, a)
    }
}

impl rand::Rand for Color {
    fn rand<R: rand::Rng>(rng: &mut R) -> Color {
        if rng.gen() { RGBA(rng.gen(), rng.gen(), rng.gen(), rng.gen()) }
        else { RGB(rng.gen(), rng.gen(), rng.gen()) }
    }
}

#[deriving(PartialEq)] #[allow(raw_pointer_deriving)]
pub struct PixelFormat {
    raw: *const ll::SDL_PixelFormat
}

impl_raw_accessors!(PixelFormat, *const ll::SDL_PixelFormat)
impl_raw_constructor!(PixelFormat -> PixelFormat (raw: *const ll::SDL_PixelFormat))

#[deriving(PartialEq, Show, FromPrimitive)]
pub enum PixelFormatFlag {
    Unknown = ll::SDL_PIXELFORMAT_UNKNOWN as int,
    Index1LSB = ll::SDL_PIXELFORMAT_INDEX1LSB as int,
    Index1MSB = ll::SDL_PIXELFORMAT_INDEX1MSB as int,
    Index4LSB = ll::SDL_PIXELFORMAT_INDEX4LSB as int,
    Index4MSB = ll::SDL_PIXELFORMAT_INDEX4MSB as int,
    Index8 = ll::SDL_PIXELFORMAT_INDEX8 as int,
    RGB332 = ll::SDL_PIXELFORMAT_RGB332 as int,
    RGB444 = ll::SDL_PIXELFORMAT_RGB444 as int,
    RGB555 = ll::SDL_PIXELFORMAT_RGB555 as int,
    BGR555 = ll::SDL_PIXELFORMAT_BGR555 as int,
    ARGB4444 = ll::SDL_PIXELFORMAT_ARGB4444 as int,
    RGBA4444 = ll::SDL_PIXELFORMAT_RGBA4444 as int,
    ABGR4444 = ll::SDL_PIXELFORMAT_ABGR4444 as int,
    BGRA4444 = ll::SDL_PIXELFORMAT_BGRA4444 as int,
    ARGB1555 = ll::SDL_PIXELFORMAT_ARGB1555 as int,
    RGBA5551 = ll::SDL_PIXELFORMAT_RGBA5551 as int,
    ABGR1555 = ll::SDL_PIXELFORMAT_ABGR1555 as int,
    BGRA5551 = ll::SDL_PIXELFORMAT_BGRA5551 as int,
    RGB565 = ll::SDL_PIXELFORMAT_RGB565 as int,
    BGR565 = ll::SDL_PIXELFORMAT_BGR565 as int,
    RGB24 = ll::SDL_PIXELFORMAT_RGB24 as int,
    BGR24 = ll::SDL_PIXELFORMAT_BGR24 as int,
    RGB888 = ll::SDL_PIXELFORMAT_RGB888 as int,
    RGBX8888 = ll::SDL_PIXELFORMAT_RGBX8888 as int,
    BGR888 = ll::SDL_PIXELFORMAT_BGR888 as int,
    BGRX8888 = ll::SDL_PIXELFORMAT_BGRX8888 as int,
    ARGB8888 = ll::SDL_PIXELFORMAT_ARGB8888 as int,
    RGBA8888 = ll::SDL_PIXELFORMAT_RGBA8888 as int,
    ABGR8888 = ll::SDL_PIXELFORMAT_ABGR8888 as int,
    BGRA8888 = ll::SDL_PIXELFORMAT_BGRA8888 as int,
    ARGB2101010 = ll::SDL_PIXELFORMAT_ARGB2101010 as int,
    YV12 = ll::SDL_PIXELFORMAT_YV12 as int,
    IYUV = ll::SDL_PIXELFORMAT_IYUV as int,
    YUY2 = ll::SDL_PIXELFORMAT_YUY2 as int,
    UYVY = ll::SDL_PIXELFORMAT_UYVY as int,
    YVYU = ll::SDL_PIXELFORMAT_YVYU as int
}

impl PixelFormatFlag {
    pub fn byte_size_of_pixels(&self, num_of_pixels: uint) -> uint {
        match *self {
            RGB332
                => num_of_pixels * 1,
            RGB444 | RGB555 | BGR555 | ARGB4444 | RGBA4444 | ABGR4444 |
            BGRA4444 | ARGB1555 | RGBA5551 | ABGR1555 | BGRA5551 | RGB565 |
            BGR565
                => num_of_pixels * 2,
            RGB24 | BGR24
                => num_of_pixels * 3,
            RGB888 | RGBX8888 | BGR888 | BGRX8888 | ARGB8888 | RGBA8888 |
            ABGR8888 | BGRA8888 | ARGB2101010
                => num_of_pixels * 4,
            // YUV formats
            // FIXME: rounding error here?
            YV12 | IYUV
                => num_of_pixels / 2 * 3,
            YUY2 | UYVY | YVYU
                => num_of_pixels * 2,
            // Unsupported formats
            Index8
                => num_of_pixels * 1,
            Unknown | Index1LSB | Index1MSB | Index4LSB | Index4MSB
                => fail!("not supported format: {}", *self),
        }
    }

    pub fn byte_size_per_pixel(&self) -> uint {
        match *self {
            RGB332
                => 1,
            RGB444 | RGB555 | BGR555 | ARGB4444 | RGBA4444 | ABGR4444 |
            BGRA4444 | ARGB1555 | RGBA5551 | ABGR1555 | BGRA5551 | RGB565 |
            BGR565
                => 2,
            RGB24 | BGR24
                => 3,
            RGB888 | RGBX8888 | BGR888 | BGRX8888 | ARGB8888 | RGBA8888 |
            ABGR8888 | BGRA8888 | ARGB2101010
                => 4,
            // YUV formats
            YV12 | IYUV
                => 2,
            YUY2 | UYVY | YVYU
                => 2,
            // Unsupported formats
            Index8
                => 1,
            Unknown | Index1LSB | Index1MSB | Index4LSB | Index4MSB
                => fail!("not supported format: {}", *self),
        }
    }
}
<|endoftext|>


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

use target::{Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::linux_base::opts();
    // z10 is the oldest CPU supported by LLVM
    base.cpu = "z10".to_string();
    // FIXME: The data_layout string below and the ABI implementation in
    // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
    // Pass the -vector feature string to LLVM to respect this assumption.
    base.features = "-vector".to_string();
    base.max_atomic_width = Some(64);

    Ok(Target {
        llvm_target: "s390x-unknown-linux-gnu".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".to_string(),
        arch: "s390x".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    })
}
<commit_msg>Disable jemalloc on s390x as well (closes #38596)<commit_after>// Copyright 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.

use target::{Target, TargetResult};

pub fn target() -> TargetResult {
    let mut base = super::linux_base::opts();
    // z10 is the oldest CPU supported by LLVM
    base.cpu = "z10".to_string();
    // FIXME: The data_layout string below and the ABI implementation in
    // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
    // Pass the -vector feature string to LLVM to respect this assumption.
    base.features = "-vector".to_string();
    base.max_atomic_width = Some(64);
    // see #36994
    base.exe_allocation_crate = "alloc_system".to_string();

    Ok(Target {
        llvm_target: "s390x-unknown-linux-gnu".to_string(),
        target_endian: "big".to_string(),
        target_pointer_width: "64".to_string(),
        data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".to_string(),
        arch: "s390x".to_string(),
        target_os: "linux".to_string(),
        target_env: "gnu".to_string(),
        target_vendor: "unknown".to_string(),
        options: base,
    })
}
<|endoftext|>


<commit_before>// Diagnostics engine

use std::fmt;
use std::cmp;
use std::rc::Rc;
use std::cell::RefCell;
use super::{Span, SrcMgr};

use colored::{Color, Colorize};

/// Severity of the diagnostic message.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Severity {
    Remark,
    Info,
    Warning,
    Error,
    Fatal,
}

impl Severity {
    /// Get the color corresponding to this severity.
    fn color(&self) -> Color {
        match self {
            Severity::Remark => Color::Blue,
            Severity::Info => Color::Black,
            Severity::Warning => Color::Magenta,
            Severity::Error | Severity::Fatal => Color::Red,
        }
    }
}

impl fmt::Display for Severity {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str = match self {
            Severity::Remark => "remark",
            Severity::Info => "info",
            Severity::Warning => "warning",
            Severity::Error => "error",
            Severity::Fatal => "fatal error",
        };
        write!(f, "{}", str)
    }
}

/// A note for detailed message or suggesting how to fix it.
pub struct Note {
    pub span: Span,
    pub fix: Option<String>,
    pub message: Option<String>,
}

/// A diagnostic message.
pub struct Diagnostic {
    pub severity: Severity,
    pub message: String,
    /// This is the primary span that causes the issue. This will not be displayed.
    /// `new` function will automatically add the span to notes for it to be displayed.
    pub span: Option<Span>,
    pub notes: Vec<Note>
}

/// Helpers for building diagnostic message. Intended to be called in chains.
impl Diagnostic {
    pub fn new(severity: Severity, msg: impl Into<String>, span: Span) -> Self {
        Diagnostic {
            severity,
            message: msg.into(),
            span: Some(span),
            notes: vec![Note {
                span,
                fix: None,
                message: None
            }],
        }
    }

    pub fn fix_primary(mut self, fix: impl Into<String>) -> Self {
        self.notes[0].fix = Some(fix.into());
        self
    }

    pub fn fix(mut self, span: Span, fix: impl Into<String>) -> Self {
        self.notes.push(Note {
            span,
            fix: Some(fix.into()),
            message: None,
        });
        self
    }
}

// Helper class for printing column number in a file with tabs and non-ASCII characters.
struct VisualString {
    str: String,
    columns: Vec<usize>,
}

impl VisualString {
    fn new(str: &str, tab: usize) -> VisualString {
        let mut columns = Vec::with_capacity(str.len() + 1);
        columns.push(0);

        // Current visual string and visual length
        let mut vstr = String::new();
        let mut vlen = 0;

        for ch in str.chars() {
            match ch {
                '\r' | '\n' => (),
                '\t' => {
                    let newlen = (vlen + tab) / tab * tab;
                    for _ in vlen..newlen {
                        vstr.push(' ');
                    }
                    vlen = newlen
                }
                _ => {
                    vstr.push(ch);
                    vlen += 1
                }
            }

            for _ in 0..ch.len_utf8() {
                columns.push(vlen);
            }
        }

        // Reserve a column for end-of-line character
        columns.push(vlen + 1);

        VisualString {
            str: vstr,
            columns: columns,
        }
    }

    fn visual_column(&self, pos: usize) -> usize {
        self.columns[pos]
    }

    fn visual_length(&self) -> usize {
        self.columns[self.columns.len() - 1]
    }

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

impl Diagnostic {
    pub fn print(&self, mgr: &SrcMgr, color: bool, tab: usize) {
        // Stringify and color severity
        let mut severity = format!("{}: ", self.severity);
        if color {
            severity = severity.color(self.severity.color()).to_string();
        }

        // Convert spans to fat spans
        let primary_span = match self.notes.first().and_then(|x| mgr.find_span(x.span)) {
            None => {
                // If the message has no associated file, just print it
                if color {
                    eprintln!("{}{}", severity, self.message.bold());
                } else {
                    eprintln!("{}{}", severity, self.message);
                }
                return
            }
            Some(v) => v,
        };

        // Obtain line map
        let src = &primary_span.source;
        let linemap = src.linemap();

        // Get line number (starting from 0)
        let line = linemap.line_number(primary_span.start);
        // Get position within the line
        let line_start = linemap.line_start_pos(line);
        // Get source code line for handling
        let line_text = linemap.line(src, line);
        let vstr = VisualString::new(line_text, tab);

        // Get colored severity string
        // Generate the error message line
        let mut msg = format!("{}:{}: {}{}", src.filename(), line + 1, severity, self.message);
        if color {
            msg = msg.bold().to_string();
        }

        // Allocate char vectors to hold indicators and hints
        // Make this 1 longer for possibility to point to the line break character.
        let mut indicators = vec![' '; vstr.visual_length() + 1];
        let mut fixes = vec![' '; vstr.visual_length()];
        let mut character = '^';
        let mut has_fix = false;

        // Fill in ^ and ~ characters for all spans
        for note in &self.notes {
            let span = match mgr.find_span(note.span) {
                // The span is non-existent, continue instead
                None => continue,
                Some(v) => v,
            };

            // Unlikely event, we cannot display this
            if !Rc::ptr_eq(&span.source, &primary_span.source) {
                continue
            }

            // Get start and end position, clamped within the line.
            let start = span.start as isize - line_start as isize;
            let start_clamp = cmp::min(cmp::max(start, 0) as usize, line_text.len());
            let end = span.end as isize - line_start as isize;
            let end_clamp = cmp::min(cmp::max(end, 0) as usize, line_text.len() + 1);

            for i in vstr.visual_column(start_clamp)..vstr.visual_column(end_clamp) {
                indicators[i] = character;
            }

            // We can only display it if it partially covers this line
            if note.fix.is_some() && end >= 0 && start <= line_text.len() as isize {
                let mut vptr = cmp::min(cmp::max(start, 0) as usize, line_text.len());
                // Now replace the part in vector with the replacement suggestion
                for ch in note.fix.as_ref().unwrap().chars() {
                    if vptr >= fixes.len() {
                        fixes.push(ch);
                    } else {
                        fixes[vptr] = ch;
                    }
                    vptr += 1;
                }
                has_fix = true;
            }

            // For non-primary notes, the character is different.
            character = '~';
        }

        let mut indicator_line: String = indicators.into_iter().collect();
        if color {
            indicator_line = indicator_line.green().bold().to_string();
        }

        if has_fix {
            let mut line: String = fixes.into_iter().collect();
            if color {
                line = line.green().to_string();
            }

            eprintln!("{}\n{}\n{}\n{}", msg, vstr.visual_text(), indicator_line, line);
        } else {
            eprintln!("{}\n{}\n{}", msg, vstr.visual_text(), indicator_line);
        }
    }
}

/// Diagnostic manager
struct DiagMgrMut {
    src: Rc<SrcMgr>,
    diagnostics: Vec<Diagnostic>,
}

pub struct DiagMgr {
    mutable: RefCell<DiagMgrMut>,
}

impl DiagMgr {
    /// Create a new diagnostics manager
    pub fn new(mgr: Rc<SrcMgr>) -> Self {
        Self {
            mutable: RefCell::new(DiagMgrMut {
                src: mgr,
                diagnostics: Vec::new(),
            })
        }
    }

    /// Add a new diagnostic. Returns `Err` for fatal errors.
    pub fn report(&self, diag: Diagnostic) {
        let mut m = self.mutable.borrow_mut();
        diag.print(&m.src, true, 4);
        let severity = diag.severity;
        m.diagnostics.push(diag);
        if severity == Severity::Fatal {
            panic!(Severity::Fatal);
        }
    }

    /// Clear exsting diagnostics
    pub fn clear(&self) {
        let mut m = self.mutable.borrow_mut();
        m.diagnostics.clear();
    }

    /// Check if there is any fatal error.
    pub fn has_fatal(&self) -> bool {
        let m = self.mutable.borrow();
        m.diagnostics.iter().any(|diag| diag.severity == Severity::Fatal)
    }

    /// Check if there is any error.
    pub fn has_error(&self) -> bool {
        let m = self.mutable.borrow();
        m.diagnostics.iter().any(|diag| diag.severity == Severity::Error || diag.severity == Severity::Fatal)
    }
}
<commit_msg>Add the commonly used error reporting function into DiagMgr.<commit_after>// Diagnostics engine

use std::fmt;
use std::cmp;
use std::rc::Rc;
use std::cell::RefCell;
use super::{Span, SrcMgr};

use colored::{Color, Colorize};

/// Severity of the diagnostic message.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Severity {
    Remark,
    Info,
    Warning,
    Error,
    Fatal,
}

impl Severity {
    /// Get the color corresponding to this severity.
    fn color(&self) -> Color {
        match self {
            Severity::Remark => Color::Blue,
            Severity::Info => Color::Black,
            Severity::Warning => Color::Magenta,
            Severity::Error | Severity::Fatal => Color::Red,
        }
    }
}

impl fmt::Display for Severity {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let str = match self {
            Severity::Remark => "remark",
            Severity::Info => "info",
            Severity::Warning => "warning",
            Severity::Error => "error",
            Severity::Fatal => "fatal error",
        };
        write!(f, "{}", str)
    }
}

/// A note for detailed message or suggesting how to fix it.
pub struct Note {
    pub span: Span,
    pub fix: Option<String>,
    pub message: Option<String>,
}

/// A diagnostic message.
pub struct Diagnostic {
    pub severity: Severity,
    pub message: String,
    /// This is the primary span that causes the issue. This will not be displayed.
    /// `new` function will automatically add the span to notes for it to be displayed.
    pub span: Option<Span>,
    pub notes: Vec<Note>
}

/// Helpers for building diagnostic message. Intended to be called in chains.
impl Diagnostic {
    pub fn new(severity: Severity, msg: impl Into<String>, span: Span) -> Self {
        Diagnostic {
            severity,
            message: msg.into(),
            span: Some(span),
            notes: vec![Note {
                span,
                fix: None,
                message: None
            }],
        }
    }

    pub fn fix_primary(mut self, fix: impl Into<String>) -> Self {
        self.notes[0].fix = Some(fix.into());
        self
    }

    pub fn fix(mut self, span: Span, fix: impl Into<String>) -> Self {
        self.notes.push(Note {
            span,
            fix: Some(fix.into()),
            message: None,
        });
        self
    }
}

// Helper class for printing column number in a file with tabs and non-ASCII characters.
struct VisualString {
    str: String,
    columns: Vec<usize>,
}

impl VisualString {
    fn new(str: &str, tab: usize) -> VisualString {
        let mut columns = Vec::with_capacity(str.len() + 1);
        columns.push(0);

        // Current visual string and visual length
        let mut vstr = String::new();
        let mut vlen = 0;

        for ch in str.chars() {
            match ch {
                '\r' | '\n' => (),
                '\t' => {
                    let newlen = (vlen + tab) / tab * tab;
                    for _ in vlen..newlen {
                        vstr.push(' ');
                    }
                    vlen = newlen
                }
                _ => {
                    vstr.push(ch);
                    vlen += 1
                }
            }

            for _ in 0..ch.len_utf8() {
                columns.push(vlen);
            }
        }

        // Reserve a column for end-of-line character
        columns.push(vlen + 1);

        VisualString {
            str: vstr,
            columns: columns,
        }
    }

    fn visual_column(&self, pos: usize) -> usize {
        self.columns[pos]
    }

    fn visual_length(&self) -> usize {
        self.columns[self.columns.len() - 1]
    }

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

impl Diagnostic {
    pub fn print(&self, mgr: &SrcMgr, color: bool, tab: usize) {
        // Stringify and color severity
        let mut severity = format!("{}: ", self.severity);
        if color {
            severity = severity.color(self.severity.color()).to_string();
        }

        // Convert spans to fat spans
        let primary_span = match self.notes.first().and_then(|x| mgr.find_span(x.span)) {
            None => {
                // If the message has no associated file, just print it
                if color {
                    eprintln!("{}{}", severity, self.message.bold());
                } else {
                    eprintln!("{}{}", severity, self.message);
                }
                return
            }
            Some(v) => v,
        };

        // Obtain line map
        let src = &primary_span.source;
        let linemap = src.linemap();

        // Get line number (starting from 0)
        let line = linemap.line_number(primary_span.start);
        // Get position within the line
        let line_start = linemap.line_start_pos(line);
        // Get source code line for handling
        let line_text = linemap.line(src, line);
        let vstr = VisualString::new(line_text, tab);

        // Get colored severity string
        // Generate the error message line
        let mut msg = format!("{}:{}: {}{}", src.filename(), line + 1, severity, self.message);
        if color {
            msg = msg.bold().to_string();
        }

        // Allocate char vectors to hold indicators and hints
        // Make this 1 longer for possibility to point to the line break character.
        let mut indicators = vec![' '; vstr.visual_length() + 1];
        let mut fixes = vec![' '; vstr.visual_length()];
        let mut character = '^';
        let mut has_fix = false;

        // Fill in ^ and ~ characters for all spans
        for note in &self.notes {
            let span = match mgr.find_span(note.span) {
                // The span is non-existent, continue instead
                None => continue,
                Some(v) => v,
            };

            // Unlikely event, we cannot display this
            if !Rc::ptr_eq(&span.source, &primary_span.source) {
                continue
            }

            // Get start and end position, clamped within the line.
            let start = span.start as isize - line_start as isize;
            let start_clamp = cmp::min(cmp::max(start, 0) as usize, line_text.len());
            let end = span.end as isize - line_start as isize;
            let end_clamp = cmp::min(cmp::max(end, 0) as usize, line_text.len() + 1);

            for i in vstr.visual_column(start_clamp)..vstr.visual_column(end_clamp) {
                indicators[i] = character;
            }

            // We can only display it if it partially covers this line
            if note.fix.is_some() && end >= 0 && start <= line_text.len() as isize {
                let mut vptr = cmp::min(cmp::max(start, 0) as usize, line_text.len());
                // Now replace the part in vector with the replacement suggestion
                for ch in note.fix.as_ref().unwrap().chars() {
                    if vptr >= fixes.len() {
                        fixes.push(ch);
                    } else {
                        fixes[vptr] = ch;
                    }
                    vptr += 1;
                }
                has_fix = true;
            }

            // For non-primary notes, the character is different.
            character = '~';
        }

        let mut indicator_line: String = indicators.into_iter().collect();
        if color {
            indicator_line = indicator_line.green().bold().to_string();
        }

        if has_fix {
            let mut line: String = fixes.into_iter().collect();
            if color {
                line = line.green().to_string();
            }

            eprintln!("{}\n{}\n{}\n{}", msg, vstr.visual_text(), indicator_line, line);
        } else {
            eprintln!("{}\n{}\n{}", msg, vstr.visual_text(), indicator_line);
        }
    }
}

/// Diagnostic manager
struct DiagMgrMut {
    src: Rc<SrcMgr>,
    diagnostics: Vec<Diagnostic>,
}

pub struct DiagMgr {
    mutable: RefCell<DiagMgrMut>,
}

impl DiagMgr {
    /// Create a new diagnostics manager
    pub fn new(mgr: Rc<SrcMgr>) -> Self {
        Self {
            mutable: RefCell::new(DiagMgrMut {
                src: mgr,
                diagnostics: Vec::new(),
            })
        }
    }

    /// Add a new diagnostic. Returns `Err` for fatal errors.
    pub fn report(&self, diag: Diagnostic) {
        let mut m = self.mutable.borrow_mut();
        diag.print(&m.src, true, 4);
        let severity = diag.severity;
        m.diagnostics.push(diag);
        if severity == Severity::Fatal {
            panic!(Severity::Fatal);
        }
    }

    /// Create a errpr diagnostic from message and span and report it.
    pub fn report_error<M: Into<String>>(&self, msg: M, span: Span) {
        self.report(Diagnostic::new(
            Severity::Error,
            msg.into(),
            span,
        ));
    }

    /// Create a fatal diagnostic from message and span and report it.
    pub fn report_fatal<M: Into<String>>(&self, msg: M, span: Span) -> ! {
        self.report(Diagnostic::new(
            Severity::Fatal,
            msg.into(),
            span,
        ));
        unreachable!()
    }

    /// Clear exsting diagnostics
    pub fn clear(&self) {
        let mut m = self.mutable.borrow_mut();
        m.diagnostics.clear();
    }

    /// Check if there is any fatal error.
    pub fn has_fatal(&self) -> bool {
        let m = self.mutable.borrow();
        m.diagnostics.iter().any(|diag| diag.severity == Severity::Fatal)
    }

    /// Check if there is any error.
    pub fn has_error(&self) -> bool {
        let m = self.mutable.borrow();
        m.diagnostics.iter().any(|diag| diag.severity == Severity::Error || diag.severity == Severity::Fatal)
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix broken accessor test<commit_after><|endoftext|>


<commit_before><commit_msg>test unwinding past topmost frame of a stack<commit_after>// ignore-windows: Concurrency on Windows is not supported yet.
// error-pattern: unwinding past the topmost frame of the stack

//! Unwinding past the top frame of a stack is Undefined Behavior.

#![feature(rustc_private)]

extern crate libc;

use std::{mem, ptr};

extern "C" fn thread_start(_null: *mut libc::c_void) -> *mut libc::c_void {
    panic!()
}

fn main() {
    unsafe {
        let mut native: libc::pthread_t = mem::zeroed();
        let attr: libc::pthread_attr_t = mem::zeroed();
        // assert_eq!(libc::pthread_attr_init(&mut attr), 0); FIXME: this function is not yet implemented.
        assert_eq!(libc::pthread_create(&mut native, &attr, thread_start, ptr::null_mut()), 0);
        assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
    }
}
<|endoftext|>


<commit_before><commit_msg>New Rust submission<commit_after><|endoftext|>


<commit_before>use redox::Box;
use redox::fs::file::File;
use redox::io::{Read, Write, Seek, SeekFrom};
use redox::mem;
use redox::net::*;
use redox::ptr;
use redox::rand;
use redox::slice;
use redox::str;
use redox::{String, ToString};
use redox::to_num::*;
use redox::Vec;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct UDPHeader {
    pub src: n16,
    pub dst: n16,
    pub len: n16,
    pub checksum: Checksum,
}

pub struct UDP {
    pub header: UDPHeader,
    pub data: Vec<u8>,
}

impl FromBytes for UDP {
    fn from_bytes(bytes: Vec<u8>) -> Option<Self> {
        if bytes.len() >= mem::size_of::<UDPHeader>() {
            unsafe {
                return Option::Some(UDP {
                    header: ptr::read(bytes.as_ptr() as *const UDPHeader),
                    data: bytes[mem::size_of::<UDPHeader>().. bytes.len()].to_vec(),
                });
            }
        }
        Option::None
    }
}

impl ToBytes for UDP {
    fn to_bytes(&self) -> Vec<u8> {
        unsafe {
            let header_ptr: *const UDPHeader = &self.header;
            let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, mem::size_of::<UDPHeader>()));
            ret.push_all(&self.data);
            ret
        }
    }
}

/// UDP resource
pub struct Resource {
    ip: File,
    data: Vec<u8>,
    peer_addr: IPv4Addr,
    peer_port: u16,
    host_port: u16,
}

impl Resource {
    pub fn dup(&self) -> Option<Box<Resource>> {
        match self.ip.dup() {
            Some(ip) => Some(box Resource {
                ip: ip,
                data: self.data.clone(),
                peer_addr: self.peer_addr,
                peer_port: self.peer_port,
                host_port: self.host_port,
            }),
            None => None
        }
    }

    pub fn path(&self, buf: &mut [u8]) -> Option<usize> {
        let path = format!("udp://{}:{}/{}", self.peer_addr.to_string(), self.peer_port, self.host_port);

        let mut i = 0;
        for b in path.bytes() {
            if i < buf.len() {
                buf[i] = b;
                i += 1;
            } else {
                break;
            }
        }

        Some(i)
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        /*

            if self.data.len() > 0 {
                let mut bytes: Vec<u8> = Vec::new();
                mem::swap(&mut self.data, &mut bytes);
                vec.push_all(&bytes);
                return Some(bytes.len());
            }

            loop {
                let mut bytes: Vec<u8> = Vec::new();
                match self.ip.read_to_end(&mut bytes) {
                    Some(_) => {
                        if let Some(datagram) = UDP::from_bytes(bytes) {
                            if datagram.header.dst.get() == self.host_port &&
                               datagram.header.src.get() == self.peer_port {
                                vec.push_all(&datagram.data);
                                return Some(datagram.data.len());
                            }
                        }
                    }
                    None => return None,
                }
            }
            */
        None
    }

    pub fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let udp_data = Vec::from(buf);

        let mut udp = UDP {
            header: UDPHeader {
                src: n16::new(self.host_port),
                dst: n16::new(self.peer_port),
                len: n16::new((mem::size_of::<UDPHeader>() + udp_data.len()) as u16),
                checksum: Checksum { data: 0 },
            },
            data: udp_data,
        };

        unsafe {
            let proto = n16::new(0x11);
            let datagram_len = n16::new((mem::size_of::<UDPHeader>() + udp.data.len()) as u16);
            udp.header.checksum.data =
                Checksum::compile(Checksum::sum((&IP_ADDR as *const IPv4Addr) as usize,
                                                mem::size_of::<IPv4Addr>()) +
                                  Checksum::sum((&self.peer_addr as *const IPv4Addr) as usize,
                                                mem::size_of::<IPv4Addr>()) +
                                  Checksum::sum((&proto as *const n16) as usize,
                                                mem::size_of::<n16>()) +
                                  Checksum::sum((&datagram_len as *const n16) as usize,
                                                mem::size_of::<n16>()) +
                                  Checksum::sum((&udp.header as *const UDPHeader) as usize,
                                                mem::size_of::<UDPHeader>()) +
                                  Checksum::sum(udp.data.as_ptr() as usize, udp.data.len()));
        }

        match self.ip.write(udp.to_bytes().as_slice()) {
            Some(_) => return Some(buf.len()),
            None => return None,
        }
    }

    pub fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        return None;
    }

    pub fn sync(&mut self) -> bool {
        self.ip.sync()
    }
}

/// UDP scheme
pub struct Scheme;

impl Scheme {
    pub fn new() -> Box<Self> {
        box Scheme
    }

    pub fn open(&mut self, url: &str) -> Option<Box<Resource>> {
        //Split scheme from the rest of the URL
        let (scheme, mut not_scheme) = url.split_at(url.find(':').unwrap_or(url.len()));

        //Remove the starting two slashes
        if not_scheme.starts_with("//") {
            not_scheme = &not_scheme[2..not_scheme.len() - 2];
        }

        //Check host and port vs path
        if not_scheme.starts_with("/") {
            let host_port = not_scheme[1..not_scheme.len() - 1].to_string().to_num();
            if host_port > 0 && host_port < 65536 {
                if let Some(mut ip) = File::open("ip:///11") {
                    let mut bytes: Vec<u8> = Vec::new();
                    if ip.read_to_end(&mut bytes).is_some() {
                        if let Some(datagram) = UDP::from_bytes(bytes) {
                            if datagram.header.dst.get() as usize == host_port {
                                let mut url_bytes = [0; 4096];
                                if let Some(count) = ip.path(&mut url_bytes) {
                                    let url = unsafe { str::from_utf8_unchecked(&url_bytes[0..count]) };

                                    //Split scheme from the rest of the URL
                                    let (scheme, mut not_scheme) = url.split_at(url.find(':').unwrap_or(url.len()));

                                    //Remove the starting two slashes
                                    if not_scheme.starts_with("//") {
                                        not_scheme = &not_scheme[2..not_scheme.len() - 2];
                                    }

                                    let (host, port) = not_scheme.split_at(not_scheme.find(':').unwrap_or(not_scheme.len()));

                                    let peer_addr = IPv4Addr::from_string(&host.to_string());

                                    return Some(box Resource {
                                        ip: ip,
                                        data: datagram.data,
                                        peer_addr: peer_addr,
                                        peer_port: datagram.header.src.get(),
                                        host_port: host_port as u16,
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }else{
            let (host, port) = not_scheme.split_at(not_scheme.find(':').unwrap_or(not_scheme.len()));

            let peer_port = port.to_string().to_num();
            if peer_port > 0 && peer_port < 65536 {
                let host_port = (rand() % 32768 + 32768) as u16;

                if let Some(ip) = File::open(&format!("ip://{}/11", host)) {
                    return Some(box Resource {
                        ip: ip,
                        data: Vec::new(),
                        peer_addr: IPv4Addr::from_string(&host.to_string()),
                        peer_port: peer_port as u16,
                        host_port: host_port,
                    });
                }
            }
        }

        None
    }
}
<commit_msg>For UDP scheme, return `Self` in `Resource::dup()` and remove unneeded return statements<commit_after>use redox::Box;
use redox::fs::file::File;
use redox::io::{Read, Write, Seek, SeekFrom};
use redox::mem;
use redox::net::*;
use redox::ptr;
use redox::rand;
use redox::slice;
use redox::str;
use redox::{String, ToString};
use redox::to_num::*;
use redox::Vec;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct UDPHeader {
    pub src: n16,
    pub dst: n16,
    pub len: n16,
    pub checksum: Checksum,
}

pub struct UDP {
    pub header: UDPHeader,
    pub data: Vec<u8>,
}

impl FromBytes for UDP {
    fn from_bytes(bytes: Vec<u8>) -> Option<Self> {
        if bytes.len() >= mem::size_of::<UDPHeader>() {
            unsafe {
                return Option::Some(UDP {
                    header: ptr::read(bytes.as_ptr() as *const UDPHeader),
                    data: bytes[mem::size_of::<UDPHeader>().. bytes.len()].to_vec(),
                });
            }
        }
        Option::None
    }
}

impl ToBytes for UDP {
    fn to_bytes(&self) -> Vec<u8> {
        unsafe {
            let header_ptr: *const UDPHeader = &self.header;
            let mut ret = Vec::from(slice::from_raw_parts(header_ptr as *const u8, mem::size_of::<UDPHeader>()));
            ret.push_all(&self.data);
            ret
        }
    }
}

/// UDP resource
pub struct Resource {
    ip: File,
    data: Vec<u8>,
    peer_addr: IPv4Addr,
    peer_port: u16,
    host_port: u16,
}

impl Resource {
    pub fn dup(&self) -> Option<Box<Self>> {
        match self.ip.dup() {
            Some(ip) => Some(box Resource {
                ip: ip,
                data: self.data.clone(),
                peer_addr: self.peer_addr,
                peer_port: self.peer_port,
                host_port: self.host_port,
            }),
            None => None
        }
    }

    pub fn path(&self, buf: &mut [u8]) -> Option<usize> {
        let path = format!("udp://{}:{}/{}", self.peer_addr.to_string(), self.peer_port, self.host_port);

        let mut i = 0;
        for b in path.bytes() {
            if i < buf.len() {
                buf[i] = b;
                i += 1;
            } else {
                break;
            }
        }

        Some(i)
    }

    pub fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        /*

            if self.data.len() > 0 {
                let mut bytes: Vec<u8> = Vec::new();
                mem::swap(&mut self.data, &mut bytes);
                vec.push_all(&bytes);
                return Some(bytes.len());
            }

            loop {
                let mut bytes: Vec<u8> = Vec::new();
                match self.ip.read_to_end(&mut bytes) {
                    Some(_) => {
                        if let Some(datagram) = UDP::from_bytes(bytes) {
                            if datagram.header.dst.get() == self.host_port &&
                               datagram.header.src.get() == self.peer_port {
                                vec.push_all(&datagram.data);
                                return Some(datagram.data.len());
                            }
                        }
                    }
                    None => return None,
                }
            }
            */
        None
    }

    pub fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let udp_data = Vec::from(buf);

        let mut udp = UDP {
            header: UDPHeader {
                src: n16::new(self.host_port),
                dst: n16::new(self.peer_port),
                len: n16::new((mem::size_of::<UDPHeader>() + udp_data.len()) as u16),
                checksum: Checksum { data: 0 },
            },
            data: udp_data,
        };

        unsafe {
            let proto = n16::new(0x11);
            let datagram_len = n16::new((mem::size_of::<UDPHeader>() + udp.data.len()) as u16);
            udp.header.checksum.data =
                Checksum::compile(Checksum::sum((&IP_ADDR as *const IPv4Addr) as usize,
                                                mem::size_of::<IPv4Addr>()) +
                                  Checksum::sum((&self.peer_addr as *const IPv4Addr) as usize,
                                                mem::size_of::<IPv4Addr>()) +
                                  Checksum::sum((&proto as *const n16) as usize,
                                                mem::size_of::<n16>()) +
                                  Checksum::sum((&datagram_len as *const n16) as usize,
                                                mem::size_of::<n16>()) +
                                  Checksum::sum((&udp.header as *const UDPHeader) as usize,
                                                mem::size_of::<UDPHeader>()) +
                                  Checksum::sum(udp.data.as_ptr() as usize, udp.data.len()));
        }

        match self.ip.write(udp.to_bytes().as_slice()) {
            Some(_) => return Some(buf.len()),
            None => return None,
        }
    }

    pub fn seek(&mut self, pos: SeekFrom) -> Option<usize> {
        None
    }

    pub fn sync(&mut self) -> bool {
        self.ip.sync()
    }
}

/// UDP scheme
pub struct Scheme;

impl Scheme {
    pub fn new() -> Box<Self> {
        box Scheme
    }

    pub fn open(&mut self, url: &str) -> Option<Box<Resource>> {
        //Split scheme from the rest of the URL
        let (scheme, mut not_scheme) = url.split_at(url.find(':').unwrap_or(url.len()));

        //Remove the starting two slashes
        if not_scheme.starts_with("//") {
            not_scheme = &not_scheme[2..not_scheme.len() - 2];
        }

        //Check host and port vs path
        if not_scheme.starts_with("/") {
            let host_port = not_scheme[1..not_scheme.len() - 1].to_string().to_num();
            if host_port > 0 && host_port < 65536 {
                if let Some(mut ip) = File::open("ip:///11") {
                    let mut bytes: Vec<u8> = Vec::new();
                    if ip.read_to_end(&mut bytes).is_some() {
                        if let Some(datagram) = UDP::from_bytes(bytes) {
                            if datagram.header.dst.get() as usize == host_port {
                                let mut url_bytes = [0; 4096];
                                if let Some(count) = ip.path(&mut url_bytes) {
                                    let url = unsafe { str::from_utf8_unchecked(&url_bytes[0..count]) };

                                    //Split scheme from the rest of the URL
                                    let (scheme, mut not_scheme) = url.split_at(url.find(':').unwrap_or(url.len()));

                                    //Remove the starting two slashes
                                    if not_scheme.starts_with("//") {
                                        not_scheme = &not_scheme[2..not_scheme.len() - 2];
                                    }

                                    let (host, port) = not_scheme.split_at(not_scheme.find(':').unwrap_or(not_scheme.len()));

                                    let peer_addr = IPv4Addr::from_string(&host.to_string());

                                    return Some(box Resource {
                                        ip: ip,
                                        data: datagram.data,
                                        peer_addr: peer_addr,
                                        peer_port: datagram.header.src.get(),
                                        host_port: host_port as u16,
                                    });
                                }
                            }
                        }
                    }
                }
            }
        } else {
            let (host, port) = not_scheme.split_at(not_scheme.find(':').unwrap_or(not_scheme.len()));

            let peer_port = port.to_string().to_num();
            if peer_port > 0 && peer_port < 65536 {
                let host_port = (rand() % 32768 + 32768) as u16;

                if let Some(ip) = File::open(&format!("ip://{}/11", host)) {
                    return Some(box Resource {
                        ip: ip,
                        data: Vec::new(),
                        peer_addr: IPv4Addr::from_string(&host.to_string()),
                        peer_port: peer_port as u16,
                        host_port: host_port,
                    });
                }
            }
        }

        None
    }
}
<|endoftext|>


<commit_before><commit_msg>Initial commit of toy AA tree implementation<commit_after>type Link<T> = Option<Box<T>>;

struct Node<K, V> {
    key: K,
    value: V,
    left: Link<Node<K, V>>,
    right: Link<Node<K, V>>,
    level: uint
}

struct Tree<K, V> {
    root: Link<Node<K, V>>,
}

impl<K: Ord, V> Node<K, V> {
    fn new(key: K, value: V) -> Node<K, V> {
        Node { key: key, value: value, left: None, right: None, level: 1 }
    }

    fn max(&self) -> &K {
        match self.right {
            None => &self.key,
            Some(ref n) => n.max(),
        }
    }

    fn min(&self) -> &K {
        match self.left {
            None => &self.key,
            Some(ref n) => n.min(),
        }
    }

    fn is_bst(&self) -> bool {
        let check_left = self.left.as_ref().map_or(true,
                            |n| n.is_bst() && *n.max() < self.key);

        if check_left {
            self.right.as_ref().map_or(true,
                            |n| n.is_bst() && *n.min() > self.key)
        } else {
            false
        }
    }

    fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
        match key.cmp(&self.key) {
            Equal => Some(&self.value),
            Less =>
                match self.left {
                    None => None,
                    Some(ref b) => b.find(key),
                },
            Greater =>
                match self.right {
                    None => None,
                    Some(ref b) => b.find(key),
                },
        }
    }
}

fn main() {
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt::Error as FmtError;
use std::fmt::{Display, Formatter};

generate_error_types!(InteractionError, InteractionErrorKind,
    Unknown => "Unknown Error"
);

<commit_msg>libimaginteraction: Replace error module imports with macro helper<commit_after>generate_error_imports!();

generate_error_types!(InteractionError, InteractionErrorKind,
    Unknown => "Unknown Error"
);

<|endoftext|>


<commit_before><commit_msg>And now no allocation at all<commit_after><|endoftext|>


<commit_before><commit_msg>Added a test that joining main is UB.<commit_after>// ignore-windows: Concurrency on Windows is not supported yet.

// Joining the main thread is undefined behavior.

#![feature(rustc_private)]

extern crate libc;

use std::{ptr, thread};

fn main() {
    let thread_id: libc::pthread_t = unsafe { libc::pthread_self() };
    let handle = thread::spawn(move || {
        unsafe {
            assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0); //~ ERROR: Undefined Behavior: trying to join a detached or already joined thread
        }
    });
    thread::yield_now();
    handle.join().unwrap();
}
<|endoftext|>


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

//! Servo's experimental layout system builds a tree of `FlowContext` and `RenderBox` objects and
/// solves layout constraints to obtain positions and display attributes of tree nodes. Positions
/// are computed in several tree traversals driven by the fundamental data dependencies required by
/// inline and block layout.
///
/// Flows are interior nodes in the layout tree and correspond closely to *flow contexts* in the
/// CSS specification. Flows are responsible for positioning their child flow contexts and render
/// boxes. Flows have purpose-specific fields, such as auxiliary line box structs, out-of-flow
/// child lists, and so on.
///
/// Currently, the important types of flows are:
///
/// * `BlockFlow`: A flow that establishes a block context. It has several child flows, each of
///   which are positioned according to block formatting context rules (CSS block boxes). Block
///   flows also contain a single `GenericBox` to represent their rendered borders, padding, etc.
///   (In the future, this render box may be folded into `BlockFlow` to save space.) The BlockFlow
///   at the root of the tree has special behavior: it stretches to the boundaries of the viewport.
///
/// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
///   boxes/flows that are subject to inline layout and line breaking and structs to represent
///   line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
///   similar methods.

use layout::block::BlockFlowData;
use layout::float::FloatFlowData;
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::inline::{InlineFlowData};
use layout::float_context::{FloatContext, Invalid, FloatType};

use std::cell::Cell;
use std::uint;
use std::io::stderr;
use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
use script::dom::node::{AbstractNode, LayoutView};
use servo_util::tree::{TreeNode, TreeNodeRef, TreeUtils};

/// The type of the formatting context and data specific to each context, such as line box
/// structures or float lists.
pub enum FlowContext {
    AbsoluteFlow(@mut FlowData),
    BlockFlow(@mut BlockFlowData),
    FloatFlow(@mut FloatFlowData),
    InlineBlockFlow(@mut FlowData),
    InlineFlow(@mut InlineFlowData),
    TableFlow(@mut FlowData),
}

pub enum FlowContextType {
    Flow_Absolute,
    Flow_Block,
    Flow_Float(FloatType),
    Flow_InlineBlock,
    Flow_Inline,
    Flow_Root,
    Flow_Table
}

impl Clone for FlowContext {
    fn clone(&self) -> FlowContext {
        *self
    }
}

impl FlowContext {
    pub fn teardown(&self) {
        match *self {
          AbsoluteFlow(data) |
          InlineBlockFlow(data) |
          TableFlow(data) => data.teardown(),
          BlockFlow(data) => data.teardown(),
          FloatFlow(data) => data.teardown(),
          InlineFlow(data) => data.teardown()
        }
    }

    /// Like traverse_preorder, but don't end the whole traversal if the callback
    /// returns false.
    fn partially_traverse_preorder(&self, callback: &fn(FlowContext) -> bool) {
        if !callback((*self).clone()) {
            return;
        }

        for self.each_child |kid| {
            // FIXME: Work around rust#2202. We should be able to pass the callback directly.
            kid.partially_traverse_preorder(|a| callback(a));
        }
    }
}

impl FlowData {
    pub fn teardown(&mut self) {
        // Under the assumption that all flows exist in a tree,
        // we must restrict ourselves to finalizing flows that
        // are descendents and subsequent siblings to ourselves,
        // or we risk dynamic borrow failures.
        self.parent = None;

        for self.first_child.iter().advance |flow| {
            flow.teardown();
        }
        self.first_child = None;

        self.last_child = None;

        for self.next_sibling.iter().advance |flow| {
            flow.teardown();
        }
        self.next_sibling = None;

        self.prev_sibling = None;
    }
}

impl TreeNodeRef<FlowData> for FlowContext {
    fn with_base<R>(&self, callback: &fn(&FlowData) -> R) -> R {
        match *self {
            AbsoluteFlow(info) => callback(info),
            BlockFlow(info) => {
                callback(&info.common)
            }
            FloatFlow(info) => callback(&info.common),
            InlineBlockFlow(info) => callback(info),
            InlineFlow(info) => {
                callback(&info.common)
            }
            TableFlow(info) => callback(info)
        }
    }
    fn with_mut_base<R>(&self, callback: &fn(&mut FlowData) -> R) -> R {
        match *self {
            AbsoluteFlow(info) => callback(info),
            BlockFlow(info) => {
                callback(&mut info.common)
            }
            FloatFlow(info) => callback(&mut info.common),
            InlineBlockFlow(info) => callback(info),
            InlineFlow(info) => {
                callback(&mut info.common)
            }
            TableFlow(info) => callback(info),
        }
    }
}

/// Data common to all flows.
///
/// FIXME: We need a naming convention for pseudo-inheritance like this. How about
/// `CommonFlowInfo`?
pub struct FlowData {
    node: AbstractNode<LayoutView>,

    parent: Option<FlowContext>,
    first_child: Option<FlowContext>,
    last_child: Option<FlowContext>,
    prev_sibling: Option<FlowContext>,
    next_sibling: Option<FlowContext>,

    /* TODO (Issue #87): debug only */
    id: int,

    /* layout computations */
    // TODO: min/pref and position are used during disjoint phases of
    // layout; maybe combine into a single enum to save space.
    min_width: Au,
    pref_width: Au,
    position: Rect<Au>,
    floats_in: FloatContext,
    floats_out: FloatContext,
    num_floats: uint,
    abs_position: Point2D<Au>
}

impl TreeNode<FlowContext> for FlowData {
    fn parent_node(&self) -> Option<FlowContext> {
        self.parent
    }

    fn first_child(&self) -> Option<FlowContext> {
        self.first_child
    }

    fn last_child(&self) -> Option<FlowContext> {
        self.last_child
    }

    fn prev_sibling(&self) -> Option<FlowContext> {
        self.prev_sibling
    }

    fn next_sibling(&self) -> Option<FlowContext> {
        self.next_sibling
    }

    fn set_parent_node(&mut self, new_parent_node: Option<FlowContext>) {
        self.parent = new_parent_node
    }

    fn set_first_child(&mut self, new_first_child: Option<FlowContext>) {
        self.first_child = new_first_child
    }

    fn set_last_child(&mut self, new_last_child: Option<FlowContext>) {
        self.last_child = new_last_child
    }

    fn set_prev_sibling(&mut self, new_prev_sibling: Option<FlowContext>) {
        self.prev_sibling = new_prev_sibling
    }

    fn set_next_sibling(&mut self, new_next_sibling: Option<FlowContext>) {
        self.next_sibling = new_next_sibling
    }
}

impl FlowData {
    pub fn new(id: int, node: AbstractNode<LayoutView>) -> FlowData {
        FlowData {
            node: node,

            parent: None,
            first_child: None,
            last_child: None,
            prev_sibling: None,
            next_sibling: None,

            id: id,

            min_width: Au(0),
            pref_width: Au(0),
            position: Au::zero_rect(),
            floats_in: Invalid,
            floats_out: Invalid,
            num_floats: 0,
            abs_position: Point2D(Au(0), Au(0))
        }
    }
}

impl<'self> FlowContext {
    /// A convenience method to return the position of this flow. Fails if the flow is currently
    /// being borrowed mutably.
    #[inline(always)]
    pub fn position(&self) -> Rect<Au> {
        do self.with_base |common_info| {
            common_info.position
        }
    }

    /// A convenience method to return the ID of this flow. Fails if the flow is currently being
    /// borrowed mutably.
    #[inline(always)]
    pub fn id(&self) -> int {
        do self.with_base |info| {
            info.id
        }
    }

    pub fn inline(&self) -> @mut InlineFlowData {
        match *self {
            InlineFlow(info) => info,
            _ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.id()))
        }
    }

    pub fn block(&self) -> @mut BlockFlowData {
        match *self {
            BlockFlow(info) => info,
            _ => fail!(fmt!("Tried to access block data of non-block: f%d", self.id()))
        }
    }

    pub fn root(&self) -> @mut BlockFlowData {
        match *self {
            BlockFlow(info) if info.is_root => info,
            _ => fail!(fmt!("Tried to access root block data of non-root: f%d", self.id()))
        }
    }

    pub fn bubble_widths(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.bubble_widths_block(ctx),
            InlineFlow(info) => info.bubble_widths_inline(ctx),
            FloatFlow(info)  => info.bubble_widths_float(ctx),
            _ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.id()))
        }
    }

    pub fn assign_widths(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.assign_widths_block(ctx),
            InlineFlow(info) => info.assign_widths_inline(ctx),
            FloatFlow(info)  => info.assign_widths_float(ctx),
            _ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.id()))
        }
    }

    pub fn assign_height(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.assign_height_block(ctx),
            InlineFlow(info) => info.assign_height_inline(ctx),
            FloatFlow(info)  => info.assign_height_float(ctx),
            _ => fail!(fmt!("Tried to assign_height of flow: f%d", self.id()))
        }
    }

    pub fn build_display_list<E:ExtraDisplayListData>(&self,
                                                     builder: &DisplayListBuilder,
                                                     dirty: &Rect<Au>,
                                                     list: &Cell<DisplayList<E>>)
                                                     -> bool {

        match *self {
            BlockFlow(info)  => info.build_display_list_block(builder, dirty, list),
            InlineFlow(info) => info.build_display_list_inline(builder, dirty, list),
            FloatFlow(info)  => info.build_display_list_float(builder, dirty, list),
            _ => {
                fail!("Tried to build_display_list_recurse of flow: %?", self)
            }
        }

    }

    // Actual methods that do not require much flow-specific logic
    pub fn foldl_all_boxes<B:Clone>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
        match *self {
            BlockFlow(block) => {
                let block = &mut *block;
                do block.box.map_default(seed.clone()) |box| {
                    cb(seed.clone(), *box)
                }
            }
            InlineFlow(inline) => {
                let inline = &mut *inline;
                do inline.boxes.iter().fold(seed) |acc, box| {
                    cb(acc.clone(), *box)
                }
            }
            _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)),
        }
    }

    pub fn foldl_boxes_for_node<B:Clone>(&self,
                                        node: AbstractNode<LayoutView>,
                                        seed: B,
                                        callback: &fn(a: B, RenderBox) -> B)
                                        -> B {
        do self.foldl_all_boxes(seed) |acc, box| {
            if box.node() == node {
                callback(acc, box)
            } else {
                acc
            }
        }
    }

    pub fn iter_all_boxes(&self, cb: &fn(RenderBox) -> bool) -> bool {
        match *self {
            BlockFlow(block) => {
                let block = &mut *block;
                for block.box.iter().advance |box| {
                    if !cb(*box) {
                        break;
                    }
                }
            }
            InlineFlow(inline) => {
                let inline = &mut *inline;
                for inline.boxes.iter().advance |box| {
                    if !cb(*box) {
                        break;
                    }
                }
            }
            _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
        }

        true
    }

    pub fn iter_boxes_for_node(&self,
                               node: AbstractNode<LayoutView>,
                               callback: &fn(RenderBox) -> bool)
                               -> bool {
        for self.iter_all_boxes |box| {
            if box.node() == node {
                if !callback(box) {
                    break;
                }
            }
        }

        true
    }

    /// Dumps the flow tree for debugging.
    pub fn dump(&self) {
        self.dump_indent(0);
    }

    /// Dumps the flow tree, for debugging, with indentation.
    pub fn dump_indent(&self, indent: uint) {
        let mut s = ~"|";
        for uint::range(0, indent) |_i| {
            s.push_str("---- ");
        }

        s.push_str(self.debug_str());
        stderr().write_line(s);

        // FIXME: this should have a pure/const version?
        for self.each_child |child| {
            child.dump_indent(indent + 1)
        }
    }

    pub fn debug_str(&self) -> ~str {
        let repr = match *self {
            InlineFlow(inline) => {
                let mut s = inline.boxes.iter().fold(~"InlineFlow(children=", |s, box| {
                    fmt!("%s b%d", s, box.id())
                });
                s.push_str(")");
                s
            },
            BlockFlow(block) => {
                match block.box {
                    Some(box) => fmt!("BlockFlow(box=b%d)", box.id()),
                    None => ~"BlockFlow",
                }
            },
            FloatFlow(float) => {
                match float.box {
                    Some(box) => fmt!("FloatFlow(box=b%d)", box.id()),
                    None => ~"FloatFlow",
                }
            },
            _ => ~"(Unknown flow)"
        };

        do self.with_base |base| {
            fmt!("f%? %? floats %? size %?", base.id, repr, base.num_floats, base.position)
        }
    }
}

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

//! Servo's experimental layout system builds a tree of `FlowContext` and `RenderBox` objects and
/// solves layout constraints to obtain positions and display attributes of tree nodes. Positions
/// are computed in several tree traversals driven by the fundamental data dependencies required by
/// inline and block layout.
///
/// Flows are interior nodes in the layout tree and correspond closely to *flow contexts* in the
/// CSS specification. Flows are responsible for positioning their child flow contexts and render
/// boxes. Flows have purpose-specific fields, such as auxiliary line box structs, out-of-flow
/// child lists, and so on.
///
/// Currently, the important types of flows are:
///
/// * `BlockFlow`: A flow that establishes a block context. It has several child flows, each of
///   which are positioned according to block formatting context rules (CSS block boxes). Block
///   flows also contain a single `GenericBox` to represent their rendered borders, padding, etc.
///   (In the future, this render box may be folded into `BlockFlow` to save space.) The BlockFlow
///   at the root of the tree has special behavior: it stretches to the boundaries of the viewport.
///
/// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
///   boxes/flows that are subject to inline layout and line breaking and structs to represent
///   line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
///   similar methods.

use layout::block::BlockFlowData;
use layout::float::FloatFlowData;
use layout::box::RenderBox;
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::inline::{InlineFlowData};
use layout::float_context::{FloatContext, Invalid, FloatType};

use std::cell::Cell;
use std::uint;
use std::io::stderr;
use geom::point::Point2D;
use geom::rect::Rect;
use gfx::display_list::DisplayList;
use gfx::geometry::Au;
use script::dom::node::{AbstractNode, LayoutView};
use servo_util::tree::{TreeNode, TreeNodeRef, TreeUtils};

/// The type of the formatting context and data specific to each context, such as line box
/// structures or float lists.
#[deriving(Clone)]
pub enum FlowContext {
    AbsoluteFlow(@mut FlowData),
    BlockFlow(@mut BlockFlowData),
    FloatFlow(@mut FloatFlowData),
    InlineBlockFlow(@mut FlowData),
    InlineFlow(@mut InlineFlowData),
    TableFlow(@mut FlowData),
}

pub enum FlowContextType {
    Flow_Absolute,
    Flow_Block,
    Flow_Float(FloatType),
    Flow_InlineBlock,
    Flow_Inline,
    Flow_Root,
    Flow_Table
}

impl FlowContext {
    pub fn teardown(&self) {
        match *self {
          AbsoluteFlow(data) |
          InlineBlockFlow(data) |
          TableFlow(data) => data.teardown(),
          BlockFlow(data) => data.teardown(),
          FloatFlow(data) => data.teardown(),
          InlineFlow(data) => data.teardown()
        }
    }

    /// Like traverse_preorder, but don't end the whole traversal if the callback
    /// returns false.
    fn partially_traverse_preorder(&self, callback: &fn(FlowContext) -> bool) {
        if !callback((*self).clone()) {
            return;
        }

        for self.each_child |kid| {
            // FIXME: Work around rust#2202. We should be able to pass the callback directly.
            kid.partially_traverse_preorder(|a| callback(a));
        }
    }
}

impl FlowData {
    pub fn teardown(&mut self) {
        // Under the assumption that all flows exist in a tree,
        // we must restrict ourselves to finalizing flows that
        // are descendents and subsequent siblings to ourselves,
        // or we risk dynamic borrow failures.
        self.parent = None;

        for self.first_child.iter().advance |flow| {
            flow.teardown();
        }
        self.first_child = None;

        self.last_child = None;

        for self.next_sibling.iter().advance |flow| {
            flow.teardown();
        }
        self.next_sibling = None;

        self.prev_sibling = None;
    }
}

impl TreeNodeRef<FlowData> for FlowContext {
    fn with_base<R>(&self, callback: &fn(&FlowData) -> R) -> R {
        match *self {
            AbsoluteFlow(info) => callback(info),
            BlockFlow(info) => {
                callback(&info.common)
            }
            FloatFlow(info) => callback(&info.common),
            InlineBlockFlow(info) => callback(info),
            InlineFlow(info) => {
                callback(&info.common)
            }
            TableFlow(info) => callback(info)
        }
    }
    fn with_mut_base<R>(&self, callback: &fn(&mut FlowData) -> R) -> R {
        match *self {
            AbsoluteFlow(info) => callback(info),
            BlockFlow(info) => {
                callback(&mut info.common)
            }
            FloatFlow(info) => callback(&mut info.common),
            InlineBlockFlow(info) => callback(info),
            InlineFlow(info) => {
                callback(&mut info.common)
            }
            TableFlow(info) => callback(info),
        }
    }
}

/// Data common to all flows.
///
/// FIXME: We need a naming convention for pseudo-inheritance like this. How about
/// `CommonFlowInfo`?
pub struct FlowData {
    node: AbstractNode<LayoutView>,

    parent: Option<FlowContext>,
    first_child: Option<FlowContext>,
    last_child: Option<FlowContext>,
    prev_sibling: Option<FlowContext>,
    next_sibling: Option<FlowContext>,

    /* TODO (Issue #87): debug only */
    id: int,

    /* layout computations */
    // TODO: min/pref and position are used during disjoint phases of
    // layout; maybe combine into a single enum to save space.
    min_width: Au,
    pref_width: Au,
    position: Rect<Au>,
    floats_in: FloatContext,
    floats_out: FloatContext,
    num_floats: uint,
    abs_position: Point2D<Au>
}

impl TreeNode<FlowContext> for FlowData {
    fn parent_node(&self) -> Option<FlowContext> {
        self.parent
    }

    fn first_child(&self) -> Option<FlowContext> {
        self.first_child
    }

    fn last_child(&self) -> Option<FlowContext> {
        self.last_child
    }

    fn prev_sibling(&self) -> Option<FlowContext> {
        self.prev_sibling
    }

    fn next_sibling(&self) -> Option<FlowContext> {
        self.next_sibling
    }

    fn set_parent_node(&mut self, new_parent_node: Option<FlowContext>) {
        self.parent = new_parent_node
    }

    fn set_first_child(&mut self, new_first_child: Option<FlowContext>) {
        self.first_child = new_first_child
    }

    fn set_last_child(&mut self, new_last_child: Option<FlowContext>) {
        self.last_child = new_last_child
    }

    fn set_prev_sibling(&mut self, new_prev_sibling: Option<FlowContext>) {
        self.prev_sibling = new_prev_sibling
    }

    fn set_next_sibling(&mut self, new_next_sibling: Option<FlowContext>) {
        self.next_sibling = new_next_sibling
    }
}

impl FlowData {
    pub fn new(id: int, node: AbstractNode<LayoutView>) -> FlowData {
        FlowData {
            node: node,

            parent: None,
            first_child: None,
            last_child: None,
            prev_sibling: None,
            next_sibling: None,

            id: id,

            min_width: Au(0),
            pref_width: Au(0),
            position: Au::zero_rect(),
            floats_in: Invalid,
            floats_out: Invalid,
            num_floats: 0,
            abs_position: Point2D(Au(0), Au(0))
        }
    }
}

impl<'self> FlowContext {
    /// A convenience method to return the position of this flow. Fails if the flow is currently
    /// being borrowed mutably.
    #[inline(always)]
    pub fn position(&self) -> Rect<Au> {
        do self.with_base |common_info| {
            common_info.position
        }
    }

    /// A convenience method to return the ID of this flow. Fails if the flow is currently being
    /// borrowed mutably.
    #[inline(always)]
    pub fn id(&self) -> int {
        do self.with_base |info| {
            info.id
        }
    }

    pub fn inline(&self) -> @mut InlineFlowData {
        match *self {
            InlineFlow(info) => info,
            _ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.id()))
        }
    }

    pub fn block(&self) -> @mut BlockFlowData {
        match *self {
            BlockFlow(info) => info,
            _ => fail!(fmt!("Tried to access block data of non-block: f%d", self.id()))
        }
    }

    pub fn root(&self) -> @mut BlockFlowData {
        match *self {
            BlockFlow(info) if info.is_root => info,
            _ => fail!(fmt!("Tried to access root block data of non-root: f%d", self.id()))
        }
    }

    pub fn bubble_widths(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.bubble_widths_block(ctx),
            InlineFlow(info) => info.bubble_widths_inline(ctx),
            FloatFlow(info)  => info.bubble_widths_float(ctx),
            _ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.id()))
        }
    }

    pub fn assign_widths(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.assign_widths_block(ctx),
            InlineFlow(info) => info.assign_widths_inline(ctx),
            FloatFlow(info)  => info.assign_widths_float(ctx),
            _ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.id()))
        }
    }

    pub fn assign_height(&self, ctx: &mut LayoutContext) {
        match *self {
            BlockFlow(info)  => info.assign_height_block(ctx),
            InlineFlow(info) => info.assign_height_inline(ctx),
            FloatFlow(info)  => info.assign_height_float(ctx),
            _ => fail!(fmt!("Tried to assign_height of flow: f%d", self.id()))
        }
    }

    pub fn build_display_list<E:ExtraDisplayListData>(&self,
                                                     builder: &DisplayListBuilder,
                                                     dirty: &Rect<Au>,
                                                     list: &Cell<DisplayList<E>>)
                                                     -> bool {

        match *self {
            BlockFlow(info)  => info.build_display_list_block(builder, dirty, list),
            InlineFlow(info) => info.build_display_list_inline(builder, dirty, list),
            FloatFlow(info)  => info.build_display_list_float(builder, dirty, list),
            _ => {
                fail!("Tried to build_display_list_recurse of flow: %?", self)
            }
        }

    }

    // Actual methods that do not require much flow-specific logic
    pub fn foldl_all_boxes<B:Clone>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
        match *self {
            BlockFlow(block) => {
                let block = &mut *block;
                do block.box.map_default(seed.clone()) |box| {
                    cb(seed.clone(), *box)
                }
            }
            InlineFlow(inline) => {
                let inline = &mut *inline;
                do inline.boxes.iter().fold(seed) |acc, box| {
                    cb(acc.clone(), *box)
                }
            }
            _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self)),
        }
    }

    pub fn foldl_boxes_for_node<B:Clone>(&self,
                                        node: AbstractNode<LayoutView>,
                                        seed: B,
                                        callback: &fn(a: B, RenderBox) -> B)
                                        -> B {
        do self.foldl_all_boxes(seed) |acc, box| {
            if box.node() == node {
                callback(acc, box)
            } else {
                acc
            }
        }
    }

    pub fn iter_all_boxes(&self, cb: &fn(RenderBox) -> bool) -> bool {
        match *self {
            BlockFlow(block) => {
                let block = &mut *block;
                for block.box.iter().advance |box| {
                    if !cb(*box) {
                        break;
                    }
                }
            }
            InlineFlow(inline) => {
                let inline = &mut *inline;
                for inline.boxes.iter().advance |box| {
                    if !cb(*box) {
                        break;
                    }
                }
            }
            _ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
        }

        true
    }

    pub fn iter_boxes_for_node(&self,
                               node: AbstractNode<LayoutView>,
                               callback: &fn(RenderBox) -> bool)
                               -> bool {
        for self.iter_all_boxes |box| {
            if box.node() == node {
                if !callback(box) {
                    break;
                }
            }
        }

        true
    }

    /// Dumps the flow tree for debugging.
    pub fn dump(&self) {
        self.dump_indent(0);
    }

    /// Dumps the flow tree, for debugging, with indentation.
    pub fn dump_indent(&self, indent: uint) {
        let mut s = ~"|";
        for uint::range(0, indent) |_i| {
            s.push_str("---- ");
        }

        s.push_str(self.debug_str());
        stderr().write_line(s);

        // FIXME: this should have a pure/const version?
        for self.each_child |child| {
            child.dump_indent(indent + 1)
        }
    }

    pub fn debug_str(&self) -> ~str {
        let repr = match *self {
            InlineFlow(inline) => {
                let mut s = inline.boxes.iter().fold(~"InlineFlow(children=", |s, box| {
                    fmt!("%s b%d", s, box.id())
                });
                s.push_str(")");
                s
            },
            BlockFlow(block) => {
                match block.box {
                    Some(box) => fmt!("BlockFlow(box=b%d)", box.id()),
                    None => ~"BlockFlow",
                }
            },
            FloatFlow(float) => {
                match float.box {
                    Some(box) => fmt!("FloatFlow(box=b%d)", box.id()),
                    None => ~"FloatFlow",
                }
            },
            _ => ~"(Unknown flow)"
        };

        do self.with_base |base| {
            fmt!("f%? %? floats %? size %?", base.id, repr, base.num_floats, base.position)
        }
    }
}

<|endoftext|>