<commit_before>use std::fmt::Debug;
use std::mem;

pub trait Transact<T = ()>: Sized {
    type Output;
    type Error: Debug;

    fn commit(self) -> Result<Self::Output, Self::Error>;

    fn commit_with<F, U, E>(mut self, f: F) -> Result<(Self::Output, U), Self::Error>
    where
        F: FnOnce(&mut Self) -> Result<U, E>,
        E: Into<Self::Error>,
    {
        match f(&mut self) {
            Ok(value) => self.commit().map(|output| (output, value)),
            Err(error) => {
                self.abort();
                Err(error.into())
            }
        }
    }

    fn abort(self) {}
}

pub trait TransactFrom<T>: From<T> + Transact<T> {}

impl<T, U> TransactFrom<U> for T where T: From<U> + Transact<U> {}

pub trait Mutate<T>: Transact<T, Output = T> {
    fn replace(target: &mut T, replacement: T) -> Replace<T, Self>
    where
        Self: TransactFrom<T>,
    {
        Replace::replace(target, replacement)
    }
}

impl<T, U> Mutate<U> for T where T: Transact<U, Output = U> {}

pub trait ClosedInput: Transact<<Self as ClosedInput>::Input> {
    type Input;
}

// TODO: This type definition is part of the public API of this module and may
//       be useful if `transact` is further integrated.
#[allow(dead_code)]
pub type ClosedOutput<T> = <T as Transact<<T as ClosedInput>::Input>>::Output;

trait Drain<T> {
    fn as_option_mut(&mut self) -> &mut Option<T>;

    fn drain(&mut self) -> T {
        self.as_option_mut().take().expect("drained")
    }

    fn undrain(&mut self, value: T) {
        let drained = self.as_option_mut();
        if drained.is_some() {
            panic!("undrained");
        }
        else {
            *drained = Some(value);
        }
    }

    fn try_swap_or<F, U, E>(&mut self, value: T, mut f: F) -> Result<U, E>
    where
        F: FnMut(T) -> Result<(T, U), E>,
    {
        match f(self.drain()) {
            Ok((value, output)) => {
                self.undrain(value);
                Ok(output)
            }
            Err(error) => {
                self.undrain(value);
                Err(error)
            }
        }
    }
}

pub struct Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    inner: Option<(&'a mut T, M)>,
}

impl<'a, T, M> Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    pub fn replace(target: &'a mut T, replacement: T) -> Self {
        let mutant = mem::replace(target, replacement);
        Replace {
            inner: Some((target, M::from(mutant))),
        }
    }

    fn drain_and_commit(&mut self) -> Result<&'a mut T, <Self as Transact<&'a mut T>>::Error> {
        let (target, inner) = self.drain();
        let mutant = inner.commit()?;
        mem::replace(target, mutant);
        Ok(target)
    }

    fn drain_and_abort(&mut self) {
        let (_, inner) = self.drain();
        inner.abort();
    }
}

impl<'a, T, M> AsRef<M> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_ref(&self) -> &M {
        &self.inner.as_ref().unwrap().1
    }
}

impl<'a, T, M> AsMut<M> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_mut(&mut self) -> &mut M {
        &mut self.inner.as_mut().unwrap().1
    }
}

impl<'a, T, M> Drain<(&'a mut T, M)> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_option_mut(&mut self) -> &mut Option<(&'a mut T, M)> {
        &mut self.inner
    }
}

impl<'a, T, M> Drop for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn drop(&mut self) {
        self.drain_and_abort()
    }
}

impl<'a, T, M> From<&'a mut T> for Replace<'a, T, M>
where
    T: Default,
    M: Mutate<T> + TransactFrom<T>,
{
    fn from(target: &'a mut T) -> Self {
        Self::replace(target, Default::default())
    }
}

impl<'a, T, M> Transact<&'a mut T> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    type Output = &'a mut T;
    type Error = <M as Transact<T>>::Error;

    fn commit(mut self) -> Result<Self::Output, Self::Error> {
        let mutant = self.drain_and_commit();
        mem::forget(self);
        mutant
    }

    fn abort(mut self) {
        self.drain_and_abort();
        mem::forget(self);
    }
}
<commit_msg>Remove unneeded `mem::replace`.<commit_after>use std::fmt::Debug;
use std::mem;

pub trait Transact<T = ()>: Sized {
    type Output;
    type Error: Debug;

    fn commit(self) -> Result<Self::Output, Self::Error>;

    fn commit_with<F, U, E>(mut self, f: F) -> Result<(Self::Output, U), Self::Error>
    where
        F: FnOnce(&mut Self) -> Result<U, E>,
        E: Into<Self::Error>,
    {
        match f(&mut self) {
            Ok(value) => self.commit().map(|output| (output, value)),
            Err(error) => {
                self.abort();
                Err(error.into())
            }
        }
    }

    fn abort(self) {}
}

pub trait TransactFrom<T>: From<T> + Transact<T> {}

impl<T, U> TransactFrom<U> for T where T: From<U> + Transact<U> {}

pub trait Mutate<T>: Transact<T, Output = T> {
    fn replace(target: &mut T, replacement: T) -> Replace<T, Self>
    where
        Self: TransactFrom<T>,
    {
        Replace::replace(target, replacement)
    }
}

impl<T, U> Mutate<U> for T where T: Transact<U, Output = U> {}

pub trait ClosedInput: Transact<<Self as ClosedInput>::Input> {
    type Input;
}

// TODO: This type definition is part of the public API of this module and may
//       be useful if `transact` is further integrated.
#[allow(dead_code)]
pub type ClosedOutput<T> = <T as Transact<<T as ClosedInput>::Input>>::Output;

trait Drain<T> {
    fn as_option_mut(&mut self) -> &mut Option<T>;

    fn drain(&mut self) -> T {
        self.as_option_mut().take().expect("drained")
    }

    fn undrain(&mut self, value: T) {
        let drained = self.as_option_mut();
        if drained.is_some() {
            panic!("undrained");
        }
        else {
            *drained = Some(value);
        }
    }

    fn try_swap_or<F, U, E>(&mut self, value: T, mut f: F) -> Result<U, E>
    where
        F: FnMut(T) -> Result<(T, U), E>,
    {
        match f(self.drain()) {
            Ok((value, output)) => {
                self.undrain(value);
                Ok(output)
            }
            Err(error) => {
                self.undrain(value);
                Err(error)
            }
        }
    }
}

pub struct Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    inner: Option<(&'a mut T, M)>,
}

impl<'a, T, M> Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    pub fn replace(target: &'a mut T, replacement: T) -> Self {
        let mutant = mem::replace(target, replacement);
        Replace {
            inner: Some((target, M::from(mutant))),
        }
    }

    fn drain_and_commit(&mut self) -> Result<&'a mut T, <Self as Transact<&'a mut T>>::Error> {
        let (target, inner) = self.drain();
        let mutant = inner.commit()?;
        *target = mutant;
        Ok(target)
    }

    fn drain_and_abort(&mut self) {
        let (_, inner) = self.drain();
        inner.abort();
    }
}

impl<'a, T, M> AsRef<M> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_ref(&self) -> &M {
        &self.inner.as_ref().unwrap().1
    }
}

impl<'a, T, M> AsMut<M> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_mut(&mut self) -> &mut M {
        &mut self.inner.as_mut().unwrap().1
    }
}

impl<'a, T, M> Drain<(&'a mut T, M)> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn as_option_mut(&mut self) -> &mut Option<(&'a mut T, M)> {
        &mut self.inner
    }
}

impl<'a, T, M> Drop for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    fn drop(&mut self) {
        self.drain_and_abort()
    }
}

impl<'a, T, M> From<&'a mut T> for Replace<'a, T, M>
where
    T: Default,
    M: Mutate<T> + TransactFrom<T>,
{
    fn from(target: &'a mut T) -> Self {
        Self::replace(target, Default::default())
    }
}

impl<'a, T, M> Transact<&'a mut T> for Replace<'a, T, M>
where
    M: Mutate<T> + TransactFrom<T>,
{
    type Output = &'a mut T;
    type Error = <M as Transact<T>>::Error;

    fn commit(mut self) -> Result<Self::Output, Self::Error> {
        let mutant = self.drain_and_commit();
        mem::forget(self);
        mutant
    }

    fn abort(mut self) {
        self.drain_and_abort();
        mem::forget(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.

// This test case makes sure that two identical invocations of the compiler
// (i.e. same code base, same compile-flags, same compiler-versions, etc.)
// produce the same output. In the past, symbol names of monomorphized functions
// were not deterministic (which we want to avoid).
//
// The test tries to exercise as many different paths into symbol name
// generation as possible:
//
// - regular functions
// - generic functions
// - methods
// - statics
// - closures
// - enum variant constructors
// - tuple struct constructors
// - drop glue
// - FnOnce adapters
// - Trait object shims
// - Fn Pointer shims

#![allow(dead_code)]

extern crate reproducible_build_aux;

static STATIC: i32 = 1234;

pub struct Struct<T1, T2> {
    x: T1,
    y: T2,
}

fn regular_fn(_: i32) {}

fn generic_fn<T1, T2>() {}

impl<T1, T2> Drop for Struct<T1, T2> {
    fn drop(&mut self) {}
}

pub enum Enum {
    Variant1,
    Variant2(u32),
    Variant3 { x: u32 }
}

struct TupleStruct(i8, i16, i32, i64);

impl TupleStruct {
    pub fn bar(&self) {}
}

trait Trait<T1, T2> {
    fn foo(&self);
}

impl Trait<i32, u64> for u64 {
    fn foo(&self) {}
}

impl<T: reproducible_build_aux::Marker + 'static> reproducible_build_aux::Trait<T, String> for TupleStruct {
    type Assoc = (u8, i16);

    fn foo(&self) {}
}

fn main() {
    regular_fn(STATIC);
    generic_fn::<u32, char>();
    generic_fn::<char, Struct<u32, u64>>();
    generic_fn::<Struct<u64, u32>, reproducible_build_aux::Struct<u32, u64>>();

    let dropped = Struct {
        x: "",
        y: 'a',
    };

    let _ = Enum::Variant1;
    let _ = Enum::Variant2(0);
    let _ = Enum::Variant3 { x: 0 };
    let _ = TupleStruct(1, 2, 3, 4);

    let closure  = |x| {
        x + 1i32
    };

    fn inner<F: Fn(i32) -> i32>(f: F) -> i32 {
        f(STATIC)
    }

    println!("{}", inner(closure));

    let object_shim: &Trait<i32, u64> = &0u64;
    object_shim.foo();

    fn with_fn_once_adapter<F: FnOnce(i32)>(f: F) {
        f(0);
    }

    with_fn_once_adapter(|_:i32| { });

    reproducible_build_aux::regular_fn(STATIC);
    reproducible_build_aux::generic_fn::<u32, char>();
    reproducible_build_aux::generic_fn::<char, Struct<u32, u64>>();
    reproducible_build_aux::generic_fn::<Struct<u64, u32>,
                                         reproducible_build_aux::Struct<u32, u64>>();

    let _ = reproducible_build_aux::Enum::Variant1;
    let _ = reproducible_build_aux::Enum::Variant2(0);
    let _ = reproducible_build_aux::Enum::Variant3 { x: 0 };
    let _ = reproducible_build_aux::TupleStruct(1, 2, 3, 4);

    let object_shim: &reproducible_build_aux::Trait<char, String, Assoc=(u8, i16)> = &TupleStruct(0, 1, 2, 3);
    object_shim.foo();

    let pointer_shim: &Fn(i32) = &regular_fn;

    TupleStruct(1, 2, 3, 4).bar();
}
<commit_msg>fix tidy<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.

// This test case makes sure that two identical invocations of the compiler
// (i.e. same code base, same compile-flags, same compiler-versions, etc.)
// produce the same output. In the past, symbol names of monomorphized functions
// were not deterministic (which we want to avoid).
//
// The test tries to exercise as many different paths into symbol name
// generation as possible:
//
// - regular functions
// - generic functions
// - methods
// - statics
// - closures
// - enum variant constructors
// - tuple struct constructors
// - drop glue
// - FnOnce adapters
// - Trait object shims
// - Fn Pointer shims

#![allow(dead_code)]

extern crate reproducible_build_aux;

static STATIC: i32 = 1234;

pub struct Struct<T1, T2> {
    x: T1,
    y: T2,
}

fn regular_fn(_: i32) {}

fn generic_fn<T1, T2>() {}

impl<T1, T2> Drop for Struct<T1, T2> {
    fn drop(&mut self) {}
}

pub enum Enum {
    Variant1,
    Variant2(u32),
    Variant3 { x: u32 }
}

struct TupleStruct(i8, i16, i32, i64);

impl TupleStruct {
    pub fn bar(&self) {}
}

trait Trait<T1, T2> {
    fn foo(&self);
}

impl Trait<i32, u64> for u64 {
    fn foo(&self) {}
}

impl<T: reproducible_build_aux::Marker + 'static>
reproducible_build_aux::Trait<T, String> for TupleStruct {
    type Assoc = (u8, i16);

    fn foo(&self) {}
}

fn main() {
    regular_fn(STATIC);
    generic_fn::<u32, char>();
    generic_fn::<char, Struct<u32, u64>>();
    generic_fn::<Struct<u64, u32>, reproducible_build_aux::Struct<u32, u64>>();

    let dropped = Struct {
        x: "",
        y: 'a',
    };

    let _ = Enum::Variant1;
    let _ = Enum::Variant2(0);
    let _ = Enum::Variant3 { x: 0 };
    let _ = TupleStruct(1, 2, 3, 4);

    let closure  = |x| {
        x + 1i32
    };

    fn inner<F: Fn(i32) -> i32>(f: F) -> i32 {
        f(STATIC)
    }

    println!("{}", inner(closure));

    let object_shim: &Trait<i32, u64> = &0u64;
    object_shim.foo();

    fn with_fn_once_adapter<F: FnOnce(i32)>(f: F) {
        f(0);
    }

    with_fn_once_adapter(|_:i32| { });

    reproducible_build_aux::regular_fn(STATIC);
    reproducible_build_aux::generic_fn::<u32, char>();
    reproducible_build_aux::generic_fn::<char, Struct<u32, u64>>();
    reproducible_build_aux::generic_fn::<Struct<u64, u32>,
                                         reproducible_build_aux::Struct<u32, u64>>();

    let _ = reproducible_build_aux::Enum::Variant1;
    let _ = reproducible_build_aux::Enum::Variant2(0);
    let _ = reproducible_build_aux::Enum::Variant3 { x: 0 };
    let _ = reproducible_build_aux::TupleStruct(1, 2, 3, 4);

    let object_shim: &reproducible_build_aux::Trait<char, String, Assoc=(u8, i16)> =
        &TupleStruct(0, 1, 2, 3);
    object_shim.foo();

    let pointer_shim: &Fn(i32) = &regular_fn;

    TupleStruct(1, 2, 3, 4).bar();
}
<|endoftext|>


<commit_before>extern mod xlib;
extern mod cairo;

use xlib::xlib::XExposeEvent;
use xlib::xlib::bindgen::{XOpenDisplay, XDefaultScreen, XRootWindow};
use xlib::xlib::bindgen::{XBlackPixel, XCreateSimpleWindow, XStoreName};
use xlib::xlib::bindgen::{XSelectInput, XCloseDisplay, XNextEvent, XDefaultVisual};
use xlib::xlib::bindgen::{XMapWindow};
use bindgen::{AzCreateColorPattern, AzDrawTargetFillRect, AzReleaseColorPattern};
use bindgen::{AzSanityCheck, AzCreateDrawTargetForCairoSurface, AzReleaseDrawTarget};
use bindgen::{AzDrawTargetGetSize};
use cairo::cairo::{CAIRO_FORMAT_RGB24};
use cairo::cairo::bindgen::{cairo_image_surface_create, cairo_surface_destroy};
use cairo::cairo_xlib::bindgen::{cairo_xlib_surface_create};

#[test]
fn sanity_check() {
    AzSanityCheck();
}

const SIZEX: c_uint = 400 as c_uint;
const SIZEY: c_uint = 400 as c_uint;

const ExposureMask: c_long = (1 << 15) as c_long;
const ButtonPressMask: c_long = (1 << 2) as c_long;

const Expose: c_int = 12 as c_int;
const ButtonPress: c_int = 4 as c_int;

type XEventStub = {
    type_: c_int,
    padding: (
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int
    )
};

fn xexpose(event: *XEventStub) -> *XExposeEvent unsafe {
    cast::reinterpret_cast(&ptr::addr_of(&(*event).padding))
}

#[test]
#[ignore]
fn cairo_it_up() {
    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str(~"test", |cstr| XStoreName(dpy, win, cstr));
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(&e);

    let dt = AzCreateDrawTargetForCairoSurface(cs, { width: SIZEX, height: SIZEY });

    loop {
        unsafe {
            XNextEvent(dpy, cast::reinterpret_cast(&ep));
            log(error, *ep);
            log(error, *xexpose(ep));
            if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
                paint(dt);
            } else if e.type_ == ButtonPress {
                break;
            } else {
                paint(dt);
            }
        }
    }

    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);
}

fn paint(dt: AzDrawTargetRef) {
    log(error, "painting");
    let rect = {
        x: 200f as AzFloat,
        y: 200f as AzFloat,
        width: 100f as AzFloat,
        height: 100f as AzFloat
    };
    let color = {
        r: 0f as AzFloat,
        g: 1f as AzFloat,
        b: 0f as AzFloat,
        a: 1f as AzFloat
    };
    let pattern = AzCreateColorPattern(ptr::addr_of(&color));
    AzDrawTargetFillRect(
        dt,
        ptr::addr_of(&rect),
        unsafe { cast::reinterpret_cast(&pattern) });
    AzReleaseColorPattern(pattern);
}

#[test]
#[ignore(reason="busted on linux 32 bit")]
fn test_draw_target_get_size() {
    let surface = cairo_image_surface_create(
        CAIRO_FORMAT_RGB24, 100 as c_int, 200 as c_int);
    assert surface.is_not_null();
    let dt = AzCreateDrawTargetForCairoSurface(surface);
    assert dt.is_not_null();
    let size = AzDrawTargetGetSize(dt);
    assert size.width == 100 as int32_t;
    assert size.height == 200 as int32_t;
    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(surface);
}

#[test]
#[ignore]
fn fonts() {
    use cairo::*;
    use cairo::bindgen::*;

    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str(~"test", |cstr| XStoreName(dpy, win, cstr));
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(&e);

    loop {
        unsafe {
            XNextEvent(dpy, cast::reinterpret_cast(&ep));
            log(error, *ep);
            log(error, *xexpose(ep));
            if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
                paint(cs);
            } else if e.type_ == ButtonPress {
                break;
            } else {
                paint(cs);
            }
        }
    }

    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);

    fn paint(surf: *cairo_surface_t) {
        use libc::c_double;
        use cairo::*;
        use cairo::bindgen::*;

        let cr: *cairo_t = cairo_create(surf);
        assert cr.is_not_null();

        cairo_set_source_rgb(cr, 0.5 as c_double, 0.1 as c_double, 0.1 as c_double);
        cairo_paint(cr);

        let te: cairo_text_extents_t = {
            x_bearing: 0 as c_double,
            y_bearing: 0 as c_double,
            width: 0 as c_double,
            height: 0 as c_double,
            x_advance: 0 as c_double,
            y_advance: 0 as c_double
        };
        cairo_set_source_rgb(cr, 0.9 as c_double, 0.5 as c_double, 0.5 as c_double);
        str::as_c_str(~"Georgia", |fontname| {
            cairo_select_font_face(cr, fontname, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        });
        cairo_set_font_size(cr, 20.2 as c_double);
        str::as_c_str(~"a", |text| {
            cairo_text_extents(cr, text, ptr::addr_of(&te));
            cairo_move_to(
                cr,
                (100.0 + 0.5) as c_double -
                te.width / (2.0 as c_double) - te.x_bearing,
                (100.0 + 0.5) as c_double -
                te.height / (2.0 as c_double) - te.y_bearing);
            cairo_show_text(cr, text);
        });

        cairo_destroy(cr);
    }
}

<commit_msg>Update for language changes.<commit_after>extern mod xlib;
extern mod cairo;

use test::xlib::xlib::XExposeEvent;
use test::xlib::xlib::bindgen::{XOpenDisplay, XDefaultScreen, XRootWindow};
use test::xlib::xlib::bindgen::{XBlackPixel, XCreateSimpleWindow, XStoreName};
use test::xlib::xlib::bindgen::{XSelectInput, XCloseDisplay, XNextEvent, XDefaultVisual};
use test::xlib::xlib::bindgen::{XMapWindow};
use bindgen::{AzCreateColorPattern, AzDrawTargetFillRect, AzReleaseColorPattern};
use bindgen::{AzSanityCheck, AzCreateDrawTargetForCairoSurface, AzReleaseDrawTarget};
use bindgen::{AzDrawTargetGetSize};
use test::cairo::cairo::{CAIRO_FORMAT_RGB24};
use test::cairo::cairo::bindgen::{cairo_image_surface_create, cairo_surface_destroy};
use test::cairo::cairo_xlib::bindgen::{cairo_xlib_surface_create};

#[test]
fn sanity_check() {
    AzSanityCheck();
}

const SIZEX: c_uint = 400 as c_uint;
const SIZEY: c_uint = 400 as c_uint;

const ExposureMask: c_long = (1 << 15) as c_long;
const ButtonPressMask: c_long = (1 << 2) as c_long;

const Expose: c_int = 12 as c_int;
const ButtonPress: c_int = 4 as c_int;

type XEventStub = {
    type_: c_int,
    padding: (
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int,
        int, int, int, int, int, int, int, int
    )
};

fn xexpose(event: *XEventStub) -> *XExposeEvent unsafe {
    cast::reinterpret_cast(&ptr::addr_of(&(*event).padding))
}

#[test]
#[ignore]
fn cairo_it_up() {
    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str(~"test", |cstr| XStoreName(dpy, win, cstr));
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(&e);

    let dt = AzCreateDrawTargetForCairoSurface(cs, { width: SIZEX, height: SIZEY });

    loop {
        unsafe {
            XNextEvent(dpy, cast::reinterpret_cast(&ep));
            log(error, *ep);
            log(error, *xexpose(ep));
            if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
                paint(dt);
            } else if e.type_ == ButtonPress {
                break;
            } else {
                paint(dt);
            }
        }
    }

    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);
}

fn paint(dt: AzDrawTargetRef) {
    log(error, "painting");
    let rect = {
        x: 200f as AzFloat,
        y: 200f as AzFloat,
        width: 100f as AzFloat,
        height: 100f as AzFloat
    };
    let color = {
        r: 0f as AzFloat,
        g: 1f as AzFloat,
        b: 0f as AzFloat,
        a: 1f as AzFloat
    };
    let pattern = AzCreateColorPattern(ptr::addr_of(&color));
    AzDrawTargetFillRect(
        dt,
        ptr::addr_of(&rect),
        unsafe { cast::reinterpret_cast(&pattern) });
    AzReleaseColorPattern(pattern);
}

#[test]
#[ignore(reason="busted on linux 32 bit")]
fn test_draw_target_get_size() {
    let surface = cairo_image_surface_create(
        CAIRO_FORMAT_RGB24, 100 as c_int, 200 as c_int);
    assert surface.is_not_null();
    let dt = AzCreateDrawTargetForCairoSurface(surface);
    assert dt.is_not_null();
    let size = AzDrawTargetGetSize(dt);
    assert size.width == 100 as int32_t;
    assert size.height == 200 as int32_t;
    AzReleaseDrawTarget(dt);
    cairo_surface_destroy(surface);
}

#[test]
#[ignore]
fn fonts() {
    use cairo::*;
    use cairo::bindgen::*;

    let dpy = XOpenDisplay(ptr::null());
    assert(ptr::is_not_null(dpy));
    let scr = XDefaultScreen(dpy);
    let rootwin = XRootWindow(dpy, scr);
    let win = XCreateSimpleWindow(
        dpy, rootwin, 1 as c_int, 1 as c_int, SIZEX, SIZEY, 0 as c_uint,
        XBlackPixel(dpy, scr), XBlackPixel(dpy, scr));
    str::as_c_str(~"test", |cstr| XStoreName(dpy, win, cstr));
    XSelectInput(dpy, win, ExposureMask | ButtonPressMask);
    XMapWindow(dpy, win);

    let cs = cairo_xlib_surface_create(
        dpy, win, XDefaultVisual(dpy, 0 as c_int),
        SIZEX as c_int, SIZEY as c_int);

    let e = {
        type_: 0 as c_int,
        padding: (
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
        )
    };
    let ep = ptr::addr_of(&e);

    loop {
        unsafe {
            XNextEvent(dpy, cast::reinterpret_cast(&ep));
            log(error, *ep);
            log(error, *xexpose(ep));
            if e.type_ == Expose && (*xexpose(ep)).count < 1 as c_int {
                paint(cs);
            } else if e.type_ == ButtonPress {
                break;
            } else {
                paint(cs);
            }
        }
    }

    cairo_surface_destroy(cs);
    XCloseDisplay(dpy);

    fn paint(surf: *cairo_surface_t) {
        use libc::c_double;
        use cairo::*;
        use cairo::bindgen::*;

        let cr: *cairo_t = cairo_create(surf);
        assert cr.is_not_null();

        cairo_set_source_rgb(cr, 0.5 as c_double, 0.1 as c_double, 0.1 as c_double);
        cairo_paint(cr);

        let te: cairo_text_extents_t = {
            x_bearing: 0 as c_double,
            y_bearing: 0 as c_double,
            width: 0 as c_double,
            height: 0 as c_double,
            x_advance: 0 as c_double,
            y_advance: 0 as c_double
        };
        cairo_set_source_rgb(cr, 0.9 as c_double, 0.5 as c_double, 0.5 as c_double);
        str::as_c_str(~"Georgia", |fontname| {
            cairo_select_font_face(cr, fontname, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
        });
        cairo_set_font_size(cr, 20.2 as c_double);
        str::as_c_str(~"a", |text| {
            cairo_text_extents(cr, text, ptr::addr_of(&te));
            cairo_move_to(
                cr,
                (100.0 + 0.5) as c_double -
                te.width / (2.0 as c_double) - te.x_bearing,
                (100.0 + 0.5) as c_double -
                te.height / (2.0 as c_double) - te.y_bearing);
            cairo_show_text(cr, text);
        });

        cairo_destroy(cr);
    }
}

<|endoftext|>


<commit_before>struct Stack {
    content: Vec<u32>,
}

impl Stack {
    fn push(&mut self, d: u32) -> Result<u32, &str> {
        self.content.push(d);
        return Ok(d);
    }

    fn pop(&mut self) -> u32 {
        self.content.pop().expect("Stack empty!")
    }

    fn add_digit(&mut self, c: char) -> Result<u32, &str> {
        match c.to_digit(10) {
            Some(n) => self.push(n),
            None    => Err("Invalid character"),
        }
    }

    fn multiply(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        return self.push(l * r);
    }

    fn add(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        return self.push(l + r);
    }

    fn subtract(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        return self.push(l - r);
    }

    fn divide(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        return self.push(l / r);
    }
}

fn evaluate(program: Vec<char>) {
    let mut stack = Stack { content: vec![] };

    for c in program {
        let answer: Result<u32, &str> = match c {
            '*' => stack.multiply(),
            '+' => stack.add(),
            '-' => stack.subtract(),
            '/' => stack.divide(),
            _   => stack.add_digit(c),
        };

        match answer {
            Err(e) => {
                println!("{}", e);
                break;
            },
            _      => continue,
        };
    }

    for c in stack.content {
        println!("{}", c);
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();

    evaluate(program);
}
<commit_msg>Kind of working. Needs a mad refactor.<commit_after>struct Stack {
    content: Vec<u32>,
}

impl Stack {
    fn push(&mut self, d: u32) -> Result<u32, &str> {
        self.content.push(d);
        return Ok(d);
    }

    fn pop(&mut self) -> Option<u32> {
        return self.content.pop();
    }

    fn add_digit(&mut self, c: char) -> Result<u32, &str> {
        match c.to_digit(10) {
            Some(n) => self.push(n),
            None    => Err("Invalid character"),
        }
    }

    fn multiply(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => {
                match r {
                    Some(i) => self.push(n * i),
                    None => Err("Stack empty"),
                }
            },
            None => Err("Stack empty"),
        }
    }

    fn add(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => {
                match r {
                    Some(i) => self.push(n * i),
                    None => Err("Stack empty"),
                }
            },
            None => Err("Stack empty"),
        }
    }

    fn subtract(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => {
                match r {
                    Some(i) => self.push(n * i),
                    None => Err("Stack empty"),
                }
            },
            None => Err("Stack empty"),
        }
    }

    fn divide(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        match l {
            Some(n) => {
                match r {
                    Some(i) => self.push(n * i),
                    None => Err("Stack empty"),
                }
            },
            None => Err("Stack empty"),
        }
    }
}

fn evaluate(program: Vec<char>) {
    let mut stack = Stack { content: vec![] };

    for c in program {
        let answer: Result<u32, &str> = match c {
            '*' => stack.multiply(),
            '+' => stack.add(),
            '-' => stack.subtract(),
            '/' => stack.divide(),
            _   => stack.add_digit(c),
        };

        if answer.is_err() {
            println!("{}", answer.unwrap_err());
            break;
        }
    }

    for c in stack.content {
        println!("{}", c);
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();

    evaluate(program);
}
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(link_args)]
#![feature(start)]

extern crate cairo;
extern crate collections;
extern crate graphics;
extern crate os;
extern crate serde;
extern crate syscall;

mod window;

use cairo::bindings::*;
use cairo::cairo::Cairo;
use cairo::surface::CairoSurface;
use collections::btree_map::BTreeMap;
use collections::vec_deque::VecDeque;
use graphics::{Command,Event,Rect};
use os::{File,Mutex,OSMem,Process,Result,Thread};
use std::io::Read;
use std::str;
use std::sync::Arc;
use syscall::libc_helpers;
use window::{Window,WindowId};

struct ServerState {
    lfb_mem: OSMem,
    windows_by_zorder: VecDeque<Arc<Window>>,
    windows_by_id: BTreeMap<WindowId, Arc<Window>>,
    focus_window: Option<Arc<Window>>,
}

fn ref_eq<T>(a: &T, b: &T) -> bool {
    a as *const T == b as *const T
}

impl ServerState {
    fn add_window(&mut self, window: Window) {
        let window = Arc::new(window);
        self.windows_by_zorder.push_front(window.clone());
        self.windows_by_id.insert(window.id(), window.clone());
        self.focus_window = Some(window);
        self.paint_all();
    }

    fn remove_window_impl(
        windows_by_zorder: &mut VecDeque<Arc<Window>>,
        windows_by_id: &mut BTreeMap<WindowId, Arc<Window>>,
        focus_window: &mut Option<Arc<Window>>,
        id: WindowId
    ) {
        if let Some(ref window) = windows_by_id.remove(&id) {
            let index_opt =
                windows_by_zorder
                    .iter()
                    .position(|w| ref_eq::<Window>(&*w, &*window));

            if let Some(index) = index_opt {
                windows_by_zorder.remove(index);
            }

            let action = {
                match *focus_window {
                    Some(ref old_focus_window) if ref_eq::<Window>(old_focus_window, window) => {
                        let next_window_opt =
                            index_opt
                                .and_then(|index| windows_by_zorder.get(index))
                                .or_else(|| windows_by_zorder.front())
                                .map(|w| (*w).clone());

                        Ok(next_window_opt)
                    },

                    _ => Err(()),
                }
            };

            if let Ok(next_window_opt) = action {
                *focus_window = next_window_opt;
            }
        }
    }

    fn remove_window(&mut self, id: WindowId) {
        ServerState::remove_window_impl(
            &mut self.windows_by_zorder,
            &mut self.windows_by_id,
            &mut self.focus_window,
            id);

        self.paint_all();
    }

    fn move_window(&mut self, id: WindowId, pos: Rect) -> Result<()> {
        if let Some(window) = self.windows_by_id.get_mut(&id) {
            window.move_to(pos)?;
        }

        self.paint_all();
        Ok(())
    }

    fn create_surface(&mut self) -> CairoSurface {
        let stride = cairo::stride_for_width(CAIRO_FORMAT_ARGB32, 800);
        CairoSurface::from_slice(&mut self.lfb_mem, CAIRO_FORMAT_ARGB32, 800, 600, stride)
    }

    fn paint_all(&mut self) {
        let cr = Cairo::new(self.create_surface());
        cr.set_source_rgb(0.0, 0.0, 0.5);
        cr.paint();

        let mut i = self.windows_by_zorder.iter_mut();
        while let Some(window) = i.next_back() {
            window.paint_on(&cr);
        }
    }
}

struct Server {
    state: Mutex<ServerState>,
}

impl Server {
    pub fn new() -> Result<Self> {
        let lfb_ptr = syscall::init_video_mode(800, 600, 32)?;
        let stride = cairo::stride_for_width(CAIRO_FORMAT_ARGB32, 800);
        Ok(Server {
            state: Mutex::new(ServerState {
                lfb_mem: unsafe { OSMem::from_raw(lfb_ptr, stride * 600) },
                windows_by_zorder: VecDeque::new(),
                windows_by_id: BTreeMap::new(),
                focus_window: None,
            })?,
        })
    }

    pub fn handle_command(&self, client_process: &Process, server2client: &Arc<Mutex<File>>, command: Command) -> Result<()> {
        let handle = client_process.handle().get();
        println!("[Server] {:?}", command);
        match command {
            Command::Checkpoint { id } => {
                graphics::send_message(&mut *server2client.lock().unwrap(), Event::Checkpoint { id })?;
            },

            Command::CreateWindow { id, pos, shared_mem_handle } => {
                let window = Window::new(client_process, id, pos, shared_mem_handle, server2client.clone())?;
                self.state.lock().unwrap().add_window(window);
            },

            Command::DestroyWindow { id } => {
                let id = WindowId::Id(handle, id);
                self.state.lock().unwrap().remove_window(id);
            },

            Command::InvalidateWindow { id: _id } => {
                self.state.lock().unwrap().paint_all();
            },

            Command::MoveWindow { id, pos } => {
                let id = WindowId::Id(handle, id);
                self.state.lock().unwrap().move_window(id, pos)?;
            }
        }

        Ok(())
    }

    pub fn send_keypress(&self, c: char) -> Result<()> {
        let mut state = self.state.lock().unwrap();
        if let Some(ref mut window) = state.focus_window {
            window.send_keypress(c)?;
        }

        Ok(())
    }
}

struct Connection<'a> {
    server: &'a Server,
    process: Process,
    client2server: File,
    server2client: Arc<Mutex<File>>,
}

impl<'a> Connection<'a> {
    pub fn new(server: &'a Server, filename: &str) -> Result<Self> {
        let (stdin, stdout) = unsafe { (libc_helpers::stdin, libc_helpers::stdout) };
        let client2server = File::create_pipe()?;
        let server2client = File::create_pipe()?;
        let inherit = [
            stdin,
            stdout,
            client2server.handle().get(),
            server2client.handle().get(),
        ];

        Ok(Connection {
            server,
            process: Process::spawn(filename, &inherit)?,
            client2server,
            server2client: Arc::new(Mutex::new(server2client)?)
        })
    }

    pub fn run(mut self) -> Result<()> {
        let mut buf = VecDeque::new();
        loop {
            let c = graphics::read_message(&mut buf, &mut self.client2server)?;
            self.server.handle_command(&self.process, &self.server2client, c)?;
        }
    }
}

fn run() -> Result<()> {
    let server = Arc::new(Server::new()?);

    {
        let server = server.clone();

        let run = move || -> Result<()> {
            let mut stdin = File::open("stdin")?;
            let mut buf = [0; 4];
            loop {
                let len = stdin.read(&mut buf)?;
                if let Ok(s) = str::from_utf8(&buf[..len]) {
                    if let Some(c) = s.chars().next() {
                        server.send_keypress(c)?;
                    }
                }
            }
        };

        Thread::spawn(move || {
            run().map(|()| 0).unwrap_or_else(|num| -(num as i32))
        })?;
    }

    Connection::new(&*server, "graphics_client")?.run()
}

#[cfg(target_arch="x86_64")]
#[link_args = "-T ../../libsyscall/arch/amd64/link.ld"]
extern {
}

#[start]
#[no_mangle]
pub fn start(_: isize, _: *const *const u8) -> isize {
    run().map(|()| 0).unwrap_or_else(|num| -(num as isize))
}
<commit_msg>Simplify<commit_after>#![feature(collections)]
#![feature(link_args)]
#![feature(start)]

extern crate cairo;
extern crate collections;
extern crate graphics;
extern crate os;
extern crate serde;
extern crate syscall;

mod window;

use cairo::bindings::*;
use cairo::cairo::Cairo;
use cairo::surface::CairoSurface;
use collections::btree_map::BTreeMap;
use collections::vec_deque::VecDeque;
use graphics::{Command,Event,Rect};
use os::{File,Mutex,OSMem,Process,Result,Thread};
use std::io::Read;
use std::str;
use std::sync::Arc;
use syscall::libc_helpers;
use window::{Window,WindowId};

struct Server {
    lfb_mem: OSMem,
    windows_by_zorder: VecDeque<Arc<Window>>,
    windows_by_id: BTreeMap<WindowId, Arc<Window>>,
    focus_window: Option<Arc<Window>>,
}

fn ref_eq<T>(a: &T, b: &T) -> bool {
    a as *const T == b as *const T
}

impl Server {
    pub fn new() -> Result<Self> {
        let lfb_ptr = syscall::init_video_mode(800, 600, 32)?;
        let stride = cairo::stride_for_width(CAIRO_FORMAT_ARGB32, 800);
        Ok(Server {
            lfb_mem: unsafe { OSMem::from_raw(lfb_ptr, stride * 600) },
            windows_by_zorder: VecDeque::new(),
            windows_by_id: BTreeMap::new(),
            focus_window: None
        })
    }

    fn add_window(&mut self, window: Window) {
        let window = Arc::new(window);
        self.windows_by_zorder.push_front(window.clone());
        self.windows_by_id.insert(window.id(), window.clone());
        self.focus_window = Some(window);
        self.paint_all();
    }

    fn remove_window_impl(
        windows_by_zorder: &mut VecDeque<Arc<Window>>,
        windows_by_id: &mut BTreeMap<WindowId, Arc<Window>>,
        focus_window: &mut Option<Arc<Window>>,
        id: WindowId
    ) {
        if let Some(ref window) = windows_by_id.remove(&id) {
            let index_opt =
                windows_by_zorder
                    .iter()
                    .position(|w| ref_eq::<Window>(&*w, &*window));

            if let Some(index) = index_opt {
                windows_by_zorder.remove(index);
            }

            let action = {
                match *focus_window {
                    Some(ref old_focus_window) if ref_eq::<Window>(old_focus_window, window) => {
                        let next_window_opt =
                            index_opt
                                .and_then(|index| windows_by_zorder.get(index))
                                .or_else(|| windows_by_zorder.front())
                                .map(|w| (*w).clone());

                        Ok(next_window_opt)
                    },

                    _ => Err(()),
                }
            };

            if let Ok(next_window_opt) = action {
                *focus_window = next_window_opt;
            }
        }
    }

    fn remove_window(&mut self, id: WindowId) {
        Server::remove_window_impl(
            &mut self.windows_by_zorder,
            &mut self.windows_by_id,
            &mut self.focus_window,
            id);

        self.paint_all();
    }

    fn move_window(&mut self, id: WindowId, pos: Rect) -> Result<()> {
        if let Some(window) = self.windows_by_id.get_mut(&id) {
            window.move_to(pos)?;
        }

        self.paint_all();
        Ok(())
    }

    fn create_surface(&mut self) -> CairoSurface {
        let stride = cairo::stride_for_width(CAIRO_FORMAT_ARGB32, 800);
        CairoSurface::from_slice(&mut self.lfb_mem, CAIRO_FORMAT_ARGB32, 800, 600, stride)
    }

    fn paint_all(&mut self) {
        let cr = Cairo::new(self.create_surface());
        cr.set_source_rgb(0.0, 0.0, 0.5);
        cr.paint();

        let mut i = self.windows_by_zorder.iter_mut();
        while let Some(window) = i.next_back() {
            window.paint_on(&cr);
        }
    }

    pub fn handle_command(&mut self, client_process: &Process, server2client: &Arc<Mutex<File>>, command: Command) -> Result<()> {
        let handle = client_process.handle().get();
        println!("[Server] {:?}", command);
        match command {
            Command::Checkpoint { id } => {
                graphics::send_message(&mut *server2client.lock().unwrap(), Event::Checkpoint { id })?;
            },

            Command::CreateWindow { id, pos, shared_mem_handle } => {
                let window = Window::new(client_process, id, pos, shared_mem_handle, server2client.clone())?;
                self.add_window(window);
            },

            Command::DestroyWindow { id } => {
                let id = WindowId::Id(handle, id);
                self.remove_window(id);
            },

            Command::InvalidateWindow { id: _id } => {
                self.paint_all();
            },

            Command::MoveWindow { id, pos } => {
                let id = WindowId::Id(handle, id);
                self.move_window(id, pos)?;
            }
        }

        Ok(())
    }

    pub fn send_keypress(&mut self, c: char) -> Result<()> {
        if let Some(ref mut window) = self.focus_window {
            window.send_keypress(c)?;
        }

        Ok(())
    }
}

struct Connection<'a> {
    server: &'a Mutex<Server>,
    process: Process,
    client2server: File,
    server2client: Arc<Mutex<File>>,
}

impl<'a> Connection<'a> {
    pub fn new(server: &'a Mutex<Server>, filename: &str) -> Result<Self> {
        let (stdin, stdout) = unsafe { (libc_helpers::stdin, libc_helpers::stdout) };
        let client2server = File::create_pipe()?;
        let server2client = File::create_pipe()?;
        let inherit = [
            stdin,
            stdout,
            client2server.handle().get(),
            server2client.handle().get(),
        ];

        Ok(Connection {
            server,
            process: Process::spawn(filename, &inherit)?,
            client2server,
            server2client: Arc::new(Mutex::new(server2client)?)
        })
    }

    pub fn run(mut self) -> Result<()> {
        let mut buf = VecDeque::new();
        loop {
            let c = graphics::read_message(&mut buf, &mut self.client2server)?;
            self.server.lock().unwrap().handle_command(&self.process, &self.server2client, c)?;
        }
    }
}

fn run() -> Result<()> {
    let server = Arc::new(Mutex::new(Server::new()?)?);

    {
        let server = server.clone();

        let run = move || -> Result<()> {
            let mut stdin = File::open("stdin")?;
            let mut buf = [0; 4];
            loop {
                let len = stdin.read(&mut buf)?;
                if let Ok(s) = str::from_utf8(&buf[..len]) {
                    if let Some(c) = s.chars().next() {
                        server.lock().unwrap().send_keypress(c)?;
                    }
                }
            }
        };

        Thread::spawn(move || {
            run().map(|()| 0).unwrap_or_else(|num| -(num as i32))
        })?;
    }

    Connection::new(&*server, "graphics_client")?.run()
}

#[cfg(target_arch="x86_64")]
#[link_args = "-T ../../libsyscall/arch/amd64/link.ld"]
extern {
}

#[start]
#[no_mangle]
pub fn start(_: isize, _: *const *const u8) -> isize {
    run().map(|()| 0).unwrap_or_else(|num| -(num as isize))
}
<|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/. */

use WindowWrapper;
use blob;
use std::sync::mpsc::Receiver;
use webrender::api::*;
use wrench::Wrench;

pub struct RawtestHarness<'a> {
    wrench: &'a mut Wrench,
    rx: Receiver<()>,
    window: &'a mut WindowWrapper,
}

impl<'a> RawtestHarness<'a> {
    pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper, rx: Receiver<()>) -> Self {
        RawtestHarness {
            wrench,
            rx,
            window,
        }
    }

    pub fn run(mut self) {
        self.retained_blob_images_test();
        self.tile_decomposition();
        self.save_restore();
    }

    fn render_and_get_pixels(&mut self, window_rect: DeviceUintRect) -> Vec<u8> {
        self.rx.recv().unwrap();
        self.wrench.render();
        self.wrench.renderer.read_pixels_rgba8(window_rect)
    }

    fn tile_decomposition(&mut self) {
        // This exposes a crash in tile decomposition
        let layout_size = LayoutSize::new(800., 800.);
        let mut resources = ResourceUpdates::new();

        let blob_img = self.wrench.api.generate_image_key();
        resources.add_image(
            blob_img,
            ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true),
            ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
            Some(128),
        );

        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)));

        // setup some malicious image size parameters
        builder.push_image(
            &info,
            LayoutSize::new(151., 56.0),
            LayoutSize::new(151.0, 56.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            self.wrench.document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench
            .api
            .generate_frame(self.wrench.document_id, None);

        self.rx.recv().unwrap();
        self.wrench.render();
    }

    fn retained_blob_images_test(&mut self) {
        let blob_img;
        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);
        let document_id = self.wrench.document_id;

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let mut resources = ResourceUpdates::new();
        {
            let api = &self.wrench.api;

            blob_img = api.generate_image_key();
            resources.add_image(
                blob_img,
                ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
                ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
                None,
            );
        }
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        // draw the blob the first time
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));

        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench.api.generate_frame(document_id, None);

        // draw the blob image a second time at a different location

        // make a new display list that refers to the first image
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)));
        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(1),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            ResourceUpdates::new(),
        );

        self.wrench.api.generate_frame(document_id, None);

        let pixels_first = self.render_and_get_pixels(window_rect);
        let pixels_second = self.render_and_get_pixels(window_rect);

        // use png;
        // png::save_flipped("out1.png", &pixels_first, window_rect.size);
        // png::save_flipped("out2.png", &pixels_second, window_rect.size);

        assert!(pixels_first != pixels_second);
    }

    // Ensures that content doing a save-restore produces the same results as not
    fn save_restore(&mut self) {
        fn rect(x: f32, y: f32, w: f32, h: f32) -> LayoutRect {
            LayoutRect::new(
                    LayoutPoint::new(x, y),
                    LayoutSize::new(w, h))
        }

        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut do_test = |should_try_and_fail| {
            let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

            let clip = builder.define_clip(None, rect(110., 120., 200., 200.),
                                           None::<ComplexClipRegion>, None);
            builder.push_clip_id(clip);
            builder.push_rect(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                              ColorF::new(0.0, 0.0, 1.0, 1.0));

            if should_try_and_fail {
                builder.save();
                let clip = builder.define_clip(None, rect(80., 80., 90., 90.),
                                           None::<ComplexClipRegion>, None);
                builder.push_clip_id(clip);
                builder.push_rect(&PrimitiveInfo::new(rect(110., 110., 50., 50.)),
                              ColorF::new(0.0, 1.0, 0.0, 1.0));
                builder.push_shadow(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                    Shadow {
                        offset: LayoutVector2D::new(1.0, 1.0),
                        blur_radius: 1.0,
                        color: ColorF::new(0.0, 0.0, 0.0, 1.0),
                    });
                builder.push_line(&PrimitiveInfo::new(rect(110., 110., 50., 2.)),
                                  0.0, LineOrientation::Horizontal,
                                  &ColorF::new(0.0, 0.0, 0.0, 1.0), LineStyle::Solid);
                builder.restore();
            }

            {
                builder.save();
                let clip = builder.define_clip(None, rect(80., 80., 100., 100.),
                                               None::<ComplexClipRegion>, None);
                builder.push_clip_id(clip);
                builder.push_rect(&PrimitiveInfo::new(rect(150., 150., 100., 100.)),
                                  ColorF::new(0.0, 0.0, 1.0, 1.0));

                builder.pop_clip_id();
                builder.clear_save();
            }

            builder.pop_clip_id();

            self.wrench.api.set_display_list(
                self.wrench.document_id,
                Epoch(0),
                root_background_color,
                layout_size,
                builder.finalize(),
                false,
                ResourceUpdates::new(),
            );
            self.wrench
                .api
                .generate_frame(self.wrench.document_id, None);

            self.render_and_get_pixels(window_rect)
        };

        let first = do_test(false);
        let second = do_test(true);

        assert_eq!(first, second);
    }
}
<commit_msg>Add test to make sure that updating blob images updates them<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use WindowWrapper;
use blob;
use std::sync::mpsc::Receiver;
use webrender::api::*;
use wrench::Wrench;

pub struct RawtestHarness<'a> {
    wrench: &'a mut Wrench,
    rx: Receiver<()>,
    window: &'a mut WindowWrapper,
}

impl<'a> RawtestHarness<'a> {
    pub fn new(wrench: &'a mut Wrench, window: &'a mut WindowWrapper, rx: Receiver<()>) -> Self {
        RawtestHarness {
            wrench,
            rx,
            window,
        }
    }

    pub fn run(mut self) {
        self.retained_blob_images_test();
        self.blob_update_test();
        self.tile_decomposition();
        self.save_restore();
    }

    fn render_and_get_pixels(&mut self, window_rect: DeviceUintRect) -> Vec<u8> {
        self.rx.recv().unwrap();
        self.wrench.render();
        self.wrench.renderer.read_pixels_rgba8(window_rect)
    }

    fn tile_decomposition(&mut self) {
        // This exposes a crash in tile decomposition
        let layout_size = LayoutSize::new(800., 800.);
        let mut resources = ResourceUpdates::new();

        let blob_img = self.wrench.api.generate_image_key();
        resources.add_image(
            blob_img,
            ImageDescriptor::new(151, 56, ImageFormat::BGRA8, true),
            ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
            Some(128),
        );

        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(448.899994, 74.0), LayoutSize::new(151.000031, 56.)));

        // setup some malicious image size parameters
        builder.push_image(
            &info,
            LayoutSize::new(151., 56.0),
            LayoutSize::new(151.0, 56.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            self.wrench.document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench
            .api
            .generate_frame(self.wrench.document_id, None);

        self.rx.recv().unwrap();
        self.wrench.render();
    }

    fn retained_blob_images_test(&mut self) {
        let blob_img;
        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);
        let document_id = self.wrench.document_id;

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let mut resources = ResourceUpdates::new();
        {
            let api = &self.wrench.api;

            blob_img = api.generate_image_key();
            resources.add_image(
                blob_img,
                ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
                ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
                None,
            );
        }
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        // draw the blob the first time
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));

        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench.api.generate_frame(document_id, None);

        // draw the blob image a second time at a different location

        // make a new display list that refers to the first image
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(1.0, 60.0), LayoutSize::new(200.0, 200.0)));
        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(1),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            ResourceUpdates::new(),
        );

        self.wrench.api.generate_frame(document_id, None);

        let pixels_first = self.render_and_get_pixels(window_rect);
        let pixels_second = self.render_and_get_pixels(window_rect);

        // use png;
        // png::save_flipped("out1.png", &pixels_first, window_rect.size);
        // png::save_flipped("out2.png", &pixels_second, window_rect.size);

        assert!(pixels_first != pixels_second);
    }

    fn blob_update_test(&mut self) {
        let blob_img;
        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);
        let document_id = self.wrench.document_id;

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let mut resources = ResourceUpdates::new();
        {
            let api = &self.wrench.api;

            blob_img = api.generate_image_key();
            resources.add_image(
                blob_img,
                ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
                ImageData::new_blob_image(blob::serialize_blob(ColorU::new(50, 50, 150, 255))),
                None,
            );
        }
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        // draw the blob the first time
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));

        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(0),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );
        self.wrench.api.generate_frame(document_id, None);

        // draw the blob image a second time after updating it
        let mut resources = ResourceUpdates::new();
        resources.update_image(
            blob_img,
            ImageDescriptor::new(500, 500, ImageFormat::BGRA8, true),
            ImageData::new_blob_image(blob::serialize_blob(ColorU::new(150, 50, 150, 255))),
            None,
        );

        // make a new display list that refers to the first image
        let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
        let info = LayoutPrimitiveInfo::new(
            LayoutRect::new(LayoutPoint::new(0.0, 60.0), LayoutSize::new(200.0, 200.0)));
        builder.push_image(
            &info,
            LayoutSize::new(200.0, 200.0),
            LayoutSize::new(0.0, 0.0),
            ImageRendering::Auto,
            blob_img,
        );

        self.wrench.api.set_display_list(
            document_id,
            Epoch(1),
            root_background_color,
            layout_size,
            builder.finalize(),
            false,
            resources,
        );

        self.wrench.api.generate_frame(document_id, None);

        let pixels_first = self.render_and_get_pixels(window_rect);
        let pixels_second = self.render_and_get_pixels(window_rect);

        assert!(pixels_first != pixels_second);
    }

    // Ensures that content doing a save-restore produces the same results as not
    fn save_restore(&mut self) {
        fn rect(x: f32, y: f32, w: f32, h: f32) -> LayoutRect {
            LayoutRect::new(
                    LayoutPoint::new(x, y),
                    LayoutSize::new(w, h))
        }

        let window_size = self.window.get_inner_size_pixels();
        let window_size = DeviceUintSize::new(window_size.0, window_size.1);

        let test_size = DeviceUintSize::new(400, 400);

        let window_rect = DeviceUintRect::new(
            DeviceUintPoint::new(0, window_size.height - test_size.height),
            test_size,
        );
        let layout_size = LayoutSize::new(400., 400.);
        let root_background_color = Some(ColorF::new(1.0, 1.0, 1.0, 1.0));

        let mut do_test = |should_try_and_fail| {
            let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);

            let clip = builder.define_clip(None, rect(110., 120., 200., 200.),
                                           None::<ComplexClipRegion>, None);
            builder.push_clip_id(clip);
            builder.push_rect(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                              ColorF::new(0.0, 0.0, 1.0, 1.0));

            if should_try_and_fail {
                builder.save();
                let clip = builder.define_clip(None, rect(80., 80., 90., 90.),
                                           None::<ComplexClipRegion>, None);
                builder.push_clip_id(clip);
                builder.push_rect(&PrimitiveInfo::new(rect(110., 110., 50., 50.)),
                              ColorF::new(0.0, 1.0, 0.0, 1.0));
                builder.push_shadow(&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
                    Shadow {
                        offset: LayoutVector2D::new(1.0, 1.0),
                        blur_radius: 1.0,
                        color: ColorF::new(0.0, 0.0, 0.0, 1.0),
                    });
                builder.push_line(&PrimitiveInfo::new(rect(110., 110., 50., 2.)),
                                  0.0, LineOrientation::Horizontal,
                                  &ColorF::new(0.0, 0.0, 0.0, 1.0), LineStyle::Solid);
                builder.restore();
            }

            {
                builder.save();
                let clip = builder.define_clip(None, rect(80., 80., 100., 100.),
                                               None::<ComplexClipRegion>, None);
                builder.push_clip_id(clip);
                builder.push_rect(&PrimitiveInfo::new(rect(150., 150., 100., 100.)),
                                  ColorF::new(0.0, 0.0, 1.0, 1.0));

                builder.pop_clip_id();
                builder.clear_save();
            }

            builder.pop_clip_id();

            self.wrench.api.set_display_list(
                self.wrench.document_id,
                Epoch(0),
                root_background_color,
                layout_size,
                builder.finalize(),
                false,
                ResourceUpdates::new(),
            );
            self.wrench
                .api
                .generate_frame(self.wrench.document_id, None);

            self.render_and_get_pixels(window_rect)
        };

        let first = do_test(false);
        let second = do_test(true);

        assert_eq!(first, second);
    }
}
<|endoftext|>


<commit_before>use std::io::{Result, Write};

use crate::{
    analysis::{self, special_functions::FunctionType},
    version::Version,
    Env,
};

use super::general::version_condition;

pub(super) fn generate(
    w: &mut dyn Write,
    env: &Env,
    function: &analysis::functions::Info,
    specials: &analysis::special_functions::Infos,
    scope_version: Option<Version>,
) -> Result<bool> {
    if let Some(special) = specials.functions().get(&function.glib_name) {
        match special.type_ {
            FunctionType::StaticStringify => {
                generate_static_to_str(w, env, function, scope_version)
            }
        }
        .map(|()| true)
    } else {
        Ok(false)
    }
}

pub(super) fn generate_static_to_str(
    w: &mut dyn Write,
    env: &Env,
    function: &analysis::functions::Info,
    scope_version: Option<Version>,
) -> Result<()> {
    writeln!(w)?;
    let version = Version::if_stricter_than(function.version, scope_version);
    version_condition(w, env, None, version, false, 1)?;

    writeln!(
        w,
        "\
\t{visibility}fn {rust_fn_name}<'a>(self) -> &'a str {{
\t\tunsafe {{
\t\t\tCStr::from_ptr(
\t\t\t\t{ns}::{glib_fn_name}(self.into_glib())
\t\t\t\t\t.as_ref()
\t\t\t\t\t.expect(\"{glib_fn_name} returned NULL\"),
\t\t\t)
\t\t\t.to_str()
\t\t\t.expect(\"{glib_fn_name} returned an invalid string\")
\t\t}}
\t}}",
        visibility = function.visibility,
        rust_fn_name = function.codegen_name(),
        ns = env.main_sys_crate_name(),
        glib_fn_name = function.glib_name,
    )?;

    Ok(())
}
<commit_msg>codegen/special_functions: Add missing space between `pub` and `fn`<commit_after>use std::io::{Result, Write};

use crate::{
    analysis::{self, special_functions::FunctionType},
    version::Version,
    Env,
};

use super::general::version_condition;

pub(super) fn generate(
    w: &mut dyn Write,
    env: &Env,
    function: &analysis::functions::Info,
    specials: &analysis::special_functions::Infos,
    scope_version: Option<Version>,
) -> Result<bool> {
    if let Some(special) = specials.functions().get(&function.glib_name) {
        match special.type_ {
            FunctionType::StaticStringify => {
                generate_static_to_str(w, env, function, scope_version)
            }
        }
        .map(|()| true)
    } else {
        Ok(false)
    }
}

pub(super) fn generate_static_to_str(
    w: &mut dyn Write,
    env: &Env,
    function: &analysis::functions::Info,
    scope_version: Option<Version>,
) -> Result<()> {
    writeln!(w)?;
    let version = Version::if_stricter_than(function.version, scope_version);
    version_condition(w, env, None, version, false, 1)?;

    writeln!(
        w,
        "\
\t{visibility} fn {rust_fn_name}<'a>(self) -> &'a str {{
\t\tunsafe {{
\t\t\tCStr::from_ptr(
\t\t\t\t{ns}::{glib_fn_name}(self.into_glib())
\t\t\t\t\t.as_ref()
\t\t\t\t\t.expect(\"{glib_fn_name} returned NULL\"),
\t\t\t)
\t\t\t.to_str()
\t\t\t.expect(\"{glib_fn_name} returned an invalid string\")
\t\t}}
\t}}",
        visibility = function.visibility,
        rust_fn_name = function.codegen_name(),
        ns = env.main_sys_crate_name(),
        glib_fn_name = function.glib_name,
    )?;

    Ok(())
}
<|endoftext|>


<commit_before>use cairo;

use crate::reference_utils::{Compare, Evaluate, Reference};
use crate::utils::{load_svg, render_document, SurfaceSize};

#[test]
fn invalid_filter_reference_cancels_filter_chain() {
    // The <rect> has a filter chain with two URLs listed, but the second one doesn't resolve.
    // The whole filter chain should be ignored.
    let svg = load_svg(
        br##"<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400">
  <defs>
    <filter id="filter">
      <feColorMatrix type="hueRotate" values="240"/>
    </filter>
  </defs>

  <rect x="100" y="100" width="200" height="200" fill="lime" filter="url(#filter) url(#nonexistent)"/>
</svg>
"##,
    ).unwrap();

    let output_surf = render_document(
        &svg,
        SurfaceSize(400, 400),
        |_| (),
        cairo::Rectangle {
            x: 0.0,
            y: 0.0,
            width: 400.0,
            height: 400.0,
        },
    )
    .unwrap();

    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 400, 400).unwrap();

    {
        let cr = cairo::Context::new(&reference_surf);

        cr.rectangle(100.0, 100.0, 200.0, 200.0);
        cr.set_source_rgb(0.0, 1.0, 0.0);
        cr.fill();
    }

    Reference::from_surface(reference_surf)
        .compare(&output_surf)
        .evaluate(
            &output_surf,
            "invalid_filter_reference_cancels_filter_chain",
        );
}
<commit_msg>Add test for invalid references to non-filter elements<commit_after>use cairo;

use crate::reference_utils::{Compare, Evaluate, Reference};
use crate::utils::{load_svg, render_document, SurfaceSize};

#[test]
fn invalid_filter_reference_cancels_filter_chain() {
    // The <rect> has a filter chain with two URLs listed, but the second one doesn't resolve.
    // The whole filter chain should be ignored.
    let svg = load_svg(
        br##"<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400">
  <defs>
    <filter id="filter">
      <feColorMatrix type="hueRotate" values="240"/>
    </filter>
  </defs>

  <rect x="100" y="100" width="200" height="200" fill="lime" filter="url(#filter) url(#nonexistent)"/>
</svg>
"##,
    ).unwrap();

    let output_surf = render_document(
        &svg,
        SurfaceSize(400, 400),
        |_| (),
        cairo::Rectangle {
            x: 0.0,
            y: 0.0,
            width: 400.0,
            height: 400.0,
        },
    )
    .unwrap();

    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 400, 400).unwrap();

    {
        let cr = cairo::Context::new(&reference_surf);

        cr.rectangle(100.0, 100.0, 200.0, 200.0);
        cr.set_source_rgb(0.0, 1.0, 0.0);
        cr.fill();
    }

    Reference::from_surface(reference_surf)
        .compare(&output_surf)
        .evaluate(
            &output_surf,
            "invalid_filter_reference_cancels_filter_chain",
        );
}

#[test]
fn non_filter_reference_cancels_filter_chain() {
    // The <rect> has a filter chain, but one of the URLs does not point to a <filter>.
    // The whole filter chain should be ignored.
    let svg = load_svg(
        br##"<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="400">
  <defs>
    <filter id="filter">
      <feColorMatrix type="hueRotate" values="240"/>
    </filter>
    <g id="not_a_filter"/>
  </defs>

  <rect x="100" y="100" width="200" height="200" fill="lime" filter="url(#filter) url(#not_a_filter)"/>
</svg>
"##,
    ).unwrap();

    let output_surf = render_document(
        &svg,
        SurfaceSize(400, 400),
        |_| (),
        cairo::Rectangle {
            x: 0.0,
            y: 0.0,
            width: 400.0,
            height: 400.0,
        },
    )
    .unwrap();

    let reference_surf = cairo::ImageSurface::create(cairo::Format::ARgb32, 400, 400).unwrap();

    {
        let cr = cairo::Context::new(&reference_surf);

        cr.rectangle(100.0, 100.0, 200.0, 200.0);
        cr.set_source_rgb(0.0, 1.0, 0.0);
        cr.fill();
    }

    Reference::from_surface(reference_surf)
        .compare(&output_surf)
        .evaluate(&output_surf, "non_filter_reference_cancels_filter_chain");
}
<|endoftext|>


<commit_before>use std::convert::TryFrom;

use rustc_middle::middle::lang_items::PanicLocationLangItem;
use rustc_middle::ty::subst::Subst;
use rustc_span::{Span, Symbol};
use rustc_target::abi::LayoutOf;

use crate::interpret::{
    intrinsics::{InterpCx, Machine},
    MPlaceTy, MemoryKind, Scalar,
};

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
    /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
    /// frame which is not `#[track_caller]`. If the first frame found lacks `#[track_caller]`, then
    /// `None` is returned and the callsite of the function invocation itself should be used.
    crate fn find_closest_untracked_caller_location(&self) -> Span {
        self.stack
            .iter()
            .rev()
            // Skip `#[track_caller]` frames.
            .skip_while(|frame| frame.instance.def.requires_caller_location(*self.tcx))
            // Find next frame with source info.
            .find_map(|frame| frame.current_source_info())
            .map(|si| si.span)
            // Fallback to current frame. That one has to have source_info as only
            // currently unwinding frames without cleanup do *not* have it -- and those
            // frames do not call this intrinsic.
            .unwrap_or_else(|| self.frame().current_source_info().unwrap().span)
    }

    /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
    crate fn alloc_caller_location(
        &mut self,
        filename: Symbol,
        line: u32,
        col: u32,
    ) -> MPlaceTy<'tcx, M::PointerTag> {
        let file = self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation);
        let line = Scalar::from_u32(line);
        let col = Scalar::from_u32(col);

        // Allocate memory for `CallerLocation` struct.
        let loc_ty = self
            .tcx
            .type_of(self.tcx.require_lang_item(PanicLocationLangItem, None))
            .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter()));
        let loc_layout = self.layout_of(loc_ty).unwrap();
        let location = self.allocate(loc_layout, MemoryKind::CallerLocation);

        // Initialize fields.
        self.write_immediate(file.to_ref(), self.mplace_field(location, 0).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");
        self.write_scalar(line, self.mplace_field(location, 1).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");
        self.write_scalar(col, self.mplace_field(location, 2).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");

        location
    }

    crate fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
        let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
        let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
        (
            Symbol::intern(&caller.file.name.to_string()),
            u32::try_from(caller.line).unwrap(),
            u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),
        )
    }

    pub fn alloc_caller_location_for_span(&mut self, span: Span) -> MPlaceTy<'tcx, M::PointerTag> {
        let (file, line, column) = self.location_triple_for_span(span);
        self.alloc_caller_location(file, line, column)
    }
}
<commit_msg>avoid an unreachable fallback<commit_after>use std::convert::TryFrom;

use rustc_middle::middle::lang_items::PanicLocationLangItem;
use rustc_middle::ty::subst::Subst;
use rustc_span::{Span, Symbol};
use rustc_target::abi::LayoutOf;

use crate::interpret::{
    intrinsics::{InterpCx, Machine},
    MPlaceTy, MemoryKind, Scalar,
};

impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
    /// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
    /// frame which is not `#[track_caller]`.
    crate fn find_closest_untracked_caller_location(&self) -> Span {
        self.stack
            .iter()
            .rev()
            // Find first non-`#[track_caller]` frame.
            .find(|frame| !frame.instance.def.requires_caller_location(*self.tcx))
            // Assert that there is always such a frame.
            .unwrap()
            .current_source_info()
            // Assert that the frame we look at is actually executing code currently
            // (`current_source_info` is None when we are unwinding and the frame does
            // not require cleanup).
            .unwrap()
            .span
    }

    /// Allocate a `const core::panic::Location` with the provided filename and line/column numbers.
    crate fn alloc_caller_location(
        &mut self,
        filename: Symbol,
        line: u32,
        col: u32,
    ) -> MPlaceTy<'tcx, M::PointerTag> {
        let file = self.allocate_str(&filename.as_str(), MemoryKind::CallerLocation);
        let line = Scalar::from_u32(line);
        let col = Scalar::from_u32(col);

        // Allocate memory for `CallerLocation` struct.
        let loc_ty = self
            .tcx
            .type_of(self.tcx.require_lang_item(PanicLocationLangItem, None))
            .subst(*self.tcx, self.tcx.mk_substs([self.tcx.lifetimes.re_erased.into()].iter()));
        let loc_layout = self.layout_of(loc_ty).unwrap();
        let location = self.allocate(loc_layout, MemoryKind::CallerLocation);

        // Initialize fields.
        self.write_immediate(file.to_ref(), self.mplace_field(location, 0).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");
        self.write_scalar(line, self.mplace_field(location, 1).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");
        self.write_scalar(col, self.mplace_field(location, 2).unwrap().into())
            .expect("writing to memory we just allocated cannot fail");

        location
    }

    crate fn location_triple_for_span(&self, span: Span) -> (Symbol, u32, u32) {
        let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
        let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
        (
            Symbol::intern(&caller.file.name.to_string()),
            u32::try_from(caller.line).unwrap(),
            u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),
        )
    }

    pub fn alloc_caller_location_for_span(&mut self, span: Span) -> MPlaceTy<'tcx, M::PointerTag> {
        let (file, line, column) = self.location_triple_for_span(span);
        self.alloc_caller_location(file, line, column)
    }
}
<|endoftext|>


<commit_before>
#[derive(Deserialize, Debug)]
#[derive(Copy, Clone)]
enum WalletScheme {
    DatabasePerWallet,
    MultiWalletSingleTable,
    MultiWalletMultiTable
}

trait WalletStrategy {
    // initialize storage based on wallet storage strategy
    fn init_storage(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError>;
    // determine phyisical table name based on wallet strategy
    fn table_name(&self, config: &PostgresConfig, base_name: &str) -> str;
    // determine additional query parameters based on wallet strategy
    fn query_qualifier(&self, config: &PostgresConfig) -> str;
}
<commit_msg>Wallet updated w.i.p.<commit_after>
#[derive(Deserialize, Debug)]
#[derive(Copy, Clone)]
enum WalletScheme {
    DatabasePerWallet,
    MultiWalletSingleTable,
    MultiWalletMultiTable
}

trait WalletStrategy {
    // initialize storage based on wallet storage strategy
    fn init_storage(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError>;
    // initialize a single wallet based on wallet storage strategy
    fn init_wallet(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError>;
    // determine phyisical table name based on wallet strategy
    fn table_name(&self, config: &PostgresConfig, base_name: &str) -> str;
    // determine additional query parameters based on wallet strategy
    fn query_qualifier(&self, config: &PostgresConfig) -> str;
}

pub struct DatabasePerWalletStrategy {}
pub struct MultiWalletSingleTableStrategy {}
pub struct MultiWalletMultiTableStrategy {}

impl WalletStrategy for DatabasePerWalletStrategy {
    // initialize storage based on wallet storage strategy
    fn init_storage(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // no-op
        Ok(())
    }
    // initialize a single wallet based on wallet storage strategy
    fn init_wallet(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // create database for wallet
    }
    // determine phyisical table name based on wallet strategy
    fn table_name(&self, config: &PostgresConfig, base_name: &str) -> str {
    }
    // determine additional query parameters based on wallet strategy
    fn query_qualifier(&self, config: &PostgresConfig) -> str {
    }
}

impl WalletStrategy for MultiWalletSingleTableStrategy {
    // initialize storage based on wallet storage strategy
    fn init_storage(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // create database and tables for storage
    }
    // initialize a single wallet based on wallet storage strategy
    fn init_wallet(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // no-op
        Ok(())
    }
    // determine phyisical table name based on wallet strategy
    fn table_name(&self, config: &PostgresConfig, base_name: &str) -> str {
    }
    // determine additional query parameters based on wallet strategy
    fn query_qualifier(&self, config: &PostgresConfig) -> str {
    }
}

impl WalletStrategy for MultiWalletMultiTableStrategy {
    // initialize storage based on wallet storage strategy
    fn init_storage(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // create database for storage
    }
    // initialize a single wallet based on wallet storage strategy
    fn init_wallet(&self, config: &PostgresConfig, credentials: &PostgresCredentials) -> Result<(), WalletStorageError> {
        // create tables for wallet storage
    }
    // determine phyisical table name based on wallet strategy
    fn table_name(&self, config: &PostgresConfig, base_name: &str) -> str {
    }
    // determine additional query parameters based on wallet strategy
    fn query_qualifier(&self, config: &PostgresConfig) -> str {
    }
}
<|endoftext|>


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

// xfail-fast
#[legacy_modes];

extern mod std;
use std::map::*;

enum cat_type { tuxedo, tabby, tortoiseshell }

impl cat_type : cmp::Eq {
    pure fn eq(&self, other: &cat_type) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) }
}

// Very silly -- this just returns the value of the name field
// for any int value that's less than the meows field

// ok: T should be in scope when resolving the trait ref for map
struct cat<T> {
  // Yes, you can have negative meows
  priv mut meows : int,

  mut how_hungry : int,
  name : T,
}

impl<T: Copy> cat<T> {
  fn speak() { self.meow(); }

  fn eat() -> bool {
    if self.how_hungry > 0 {
        error!("OM NOM NOM");
        self.how_hungry -= 2;
        return true;
    }
    else {
        error!("Not hungry!");
        return false;
    }
  }
}

impl<T: Copy> cat<T> : StdMap<int, T> {
  pure fn size() -> uint { self.meows as uint }
  fn insert(+k: int, +_v: T) -> bool {
    self.meows += k;
    true
  }
  pure fn contains_key(+k: int) -> bool { k <= self.meows }
  pure fn contains_key_ref(k: &int) -> bool { self.contains_key(*k) }

  pure fn get(+k:int) -> T { match self.find(k) {
      Some(v) => { v }
      None    => { die!(~"epic fail"); }
    }
  }
  pure fn find(+k:int) -> Option<T> { if k <= self.meows {
        Some(self.name)
     }
     else { None }
  }

  fn update_with_key(+key: int, +val: T, ff: fn(+k: int, +v0: T, +v1: T) -> T) -> bool {
    match self.find(key) {
      None            => return self.insert(key, val),
      Some(copy orig) => return self.insert(key, ff(key, orig, val))
    }
  }

  fn update(+key: int, +val: T, ff: fn(+v0: T, +v1: T) -> T) -> bool {
    match self.find(key) {
      None            => return self.insert(key, val),
      Some(copy orig) => return self.insert(key, ff(orig, val))
    }
  }

  fn remove(+k:int) -> bool {
    match self.find(k) {
      Some(x) => {
        self.meows -= k; true
      }
      None => { false }
    }
  }

  pure fn each(f: fn(+v: int, +v: T) -> bool) {
    let mut n = int::abs(self.meows);
    while n > 0 {
        if !f(n, self.name) { break; }
        n -= 1;
    }
  }

  pure fn each_key(&&f: fn(+v: int) -> bool) {
    for self.each |k, _v| { if !f(k) { break; } loop;};
  }
  pure fn each_value(&&f: fn(+v: T) -> bool) {
    for self.each |_k, v| { if !f(v) { break; } loop;};
  }

  pure fn each_ref(f: fn(k: &int, v: &T) -> bool) {}
  pure fn each_key_ref(f: fn(k: &int) -> bool) {}
  pure fn each_value_ref(f: fn(k: &T) -> bool) {}

  fn clear() { }
}

priv impl<T: Copy> cat<T> {
    fn meow() {
      self.meows += 1;
      error!("Meow %d", self.meows);
      if self.meows % 5 == 0 {
          self.how_hungry += 1;
      }
    }
}

fn cat<T: Copy>(in_x : int, in_y : int, in_name: T) -> cat<T> {
    cat {
        meows: in_x,
        how_hungry: in_y,
        name: in_name
    }
}

pub fn main() {
  let nyan : cat<~str> = cat(0, 2, ~"nyan");
  for uint::range(1u, 5u) |_i| { nyan.speak(); }
  assert(nyan.find(1) == Some(~"nyan"));
  assert(nyan.find(10) == None);
  let spotty : cat<cat_type> = cat(2, 57, tuxedo);
  for uint::range(0u, 6u) |_i| { spotty.speak(); }
  assert(spotty.size() == 8u);
  assert(spotty.contains_key(2));
  assert(spotty.get(3) == tuxedo);
}
<commit_msg>cat modernization (cleanup of a run-pass test)<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-fast

use core::container::{Container, Mutable, Map};

enum cat_type { tuxedo, tabby, tortoiseshell }

impl cat_type : cmp::Eq {
    pure fn eq(&self, other: &cat_type) -> bool {
        ((*self) as uint) == ((*other) as uint)
    }
    pure fn ne(&self, other: &cat_type) -> bool { !(*self).eq(other) }
}

// Very silly -- this just returns the value of the name field
// for any int value that's less than the meows field

// ok: T should be in scope when resolving the trait ref for map
struct cat<T> {
    // Yes, you can have negative meows
    priv mut meows : int,

    mut how_hungry : int,
    name : T,
}

impl<T> cat<T> {
    fn speak(&mut self) { self.meow(); }

    fn eat(&mut self) -> bool {
        if self.how_hungry > 0 {
            error!("OM NOM NOM");
            self.how_hungry -= 2;
            return true;
        } else {
            error!("Not hungry!");
            return false;
        }
    }
}

impl<T> cat<T>: Container {
    pure fn len(&self) -> uint { self.meows as uint }
    pure fn is_empty(&self) -> bool { self.meows == 0 }
}

impl<T> cat<T>: Mutable {
    fn clear(&mut self) {}
}

impl<T> cat<T>: Map<int, T> {
    pure fn contains_key(&self, k: &int) -> bool { *k <= self.meows }

    pure fn each(&self, f: fn(v: &int, v: &T) -> bool) {
        let mut n = int::abs(self.meows);
        while n > 0 {
            if !f(&n, &self.name) { break; }
            n -= 1;
        }
    }

    pure fn each_key(&self, f: fn(v: &int) -> bool) {
        for self.each |k, _| { if !f(k) { break; } loop;};
    }

    pure fn each_value(&self, f: fn(v: &T) -> bool) {
        for self.each |_, v| { if !f(v) { break; } loop;};
    }

    fn insert(&mut self, k: int, _: T) -> bool {
        self.meows += k;
        true
    }

    pure fn find(&self, k: &int) -> Option<&self/T> {
        if *k <= self.meows {
            Some(&self.name)
        } else {
            None
        }
    }

    fn remove(&mut self, k: &int) -> bool {
        match self.find(k) {
          Some(_) => {
              self.meows -= *k; true
          }
          None => { false }
        }
    }
}

impl<T> cat<T> {
    pure fn get(&self, k: &int) -> &self/T {
        match self.find(k) {
          Some(v) => { v }
          None    => { die!(~"epic fail"); }
        }
    }

    static pure fn new(in_x: int, in_y: int, in_name: T) -> cat<T> {
        cat{meows: in_x, how_hungry: in_y, name: in_name }
    }
}

priv impl<T> cat<T> {
    fn meow(&mut self) {
        self.meows += 1;
        error!("Meow %d", self.meows);
        if self.meows % 5 == 0 {
            self.how_hungry += 1;
        }
    }
}

fn main() {
    let mut nyan: cat<~str> = cat::new(0, 2, ~"nyan");
    for uint::range(1, 5) |_| { nyan.speak(); }
    assert(*nyan.find(&1).unwrap() == ~"nyan");
    assert(nyan.find(&10) == None);
    let mut spotty: cat<cat_type> = cat::new(2, 57, tuxedo);
    for uint::range(0, 6) |_| { spotty.speak(); }
    assert(spotty.len() == 8);
    assert(spotty.contains_key(&2));
    assert(spotty.get(&3) == &tuxedo);
}
<|endoftext|>