<commit_before>#[doc = "
High-level bindings to work with the libuv library.

This module is geared towards library developers who want to
provide a high-level, abstracted interface to some set of
libuv functionality.
"];

export high_level_loop, hl_loop_ext, high_level_msg;
export run_high_level_loop, interact, ref_handle, unref_handle;

import ll = uv_ll;

#[doc = "
Used to abstract-away direct interaction with a libuv loop.

# Arguments

* async_handle - a pointer to a pointer to a uv_async_t struct used to 'poke'
the C uv loop to process any pending callbacks

* op_chan - a channel used to send function callbacks to be processed
by the C uv loop
"]
enum high_level_loop {
    single_task_loop({
        async_handle: **ll::uv_async_t,
        op_chan: comm::chan<high_level_msg>
    }),
    monitor_task_loop({
        op_chan: comm::chan<high_level_msg>
    })
}

impl hl_loop_ext for high_level_loop {
    fn async_handle() -> **ll::uv_async_t {
        alt self {
          single_task_loop({async_handle, op_chan}) {
            ret async_handle;
          }
          _ {
            fail "variant of hl::high_level_loop that doesn't include" +
                "an async_handle field";
          }
        }
    }
    fn op_chan() -> comm::chan<high_level_msg> {
        alt self {
          single_task_loop({async_handle, op_chan}) {
            ret op_chan;
          }
          monitor_task_loop({op_chan}) {
            ret op_chan;
          }
        }
    }
}

#[doc="
Represents the range of interactions with a `high_level_loop`
"]
enum high_level_msg {
    interaction (fn~(*libc::c_void)),
    auto_ref_handle (*libc::c_void),
    auto_unref_handle (*libc::c_void, *u8),
    tear_down
}

#[doc = "
Given a vanilla `uv_loop_t*`

# Arguments

* loop_ptr - a pointer to a currently unused libuv loop. Its `data` field
will be overwritten before the loop begins
must be a pointer to a clean rust `uv_async_t` record
* msg_po - an active port that receives `high_level_msg`s
* before_run - a unique closure that is invoked after `uv_async_init` is
called on the `async_handle` passed into this callback, just before `uv_run`
is called on the provided `loop_ptr`
* before_msg_drain - a unique closure that is invoked every time the loop is
awoken, but before the port pointed to in the `msg_po` argument is drained
* before_tear_down - called just before the loop invokes `uv_close()` on the
provided `async_handle`. `uv_run` should return shortly after
"]
unsafe fn run_high_level_loop(loop_ptr: *libc::c_void,
                              msg_po: comm::port<high_level_msg>,
                              before_run: fn~(*ll::uv_async_t),
                              before_msg_drain: fn~(*ll::uv_async_t) -> bool,
                              before_tear_down: fn~(*ll::uv_async_t)) {
    // set up the special async handle we'll use to allow multi-task
    // communication with this loop
    let async = ll::async_t();
    let async_handle = ptr::addr_of(async);
    // associate the async handle with the loop
    ll::async_init(loop_ptr, async_handle, high_level_wake_up_cb);

    // initialize our loop data and store it in the loop
    let data: global_loop_data = default_gl_data({
        async_handle: async_handle,
        mut active: true,
        before_msg_drain: before_msg_drain,
        before_tear_down: before_tear_down,
        msg_po_ptr: ptr::addr_of(msg_po),
        mut refd_handles: [mut],
        mut unrefd_handles: [mut]
    });
    let data_ptr = ptr::addr_of(data);
    ll::set_data_for_uv_handle(async_handle, data_ptr);

    // call before_run
    before_run(async_handle);

    log(debug, "about to run high level loop");
    // enter the loop... this blocks until the loop is done..
    ll::run(loop_ptr);
    log(debug, "high-level loop ended");
}

#[doc = "
Provide a callback to be processed by `a_loop`

The primary way to do operations again a running `high_level_loop` that
doesn't involve creating a uv handle via `safe_handle`

# Arguments

* a_loop - a `high_level_loop` that you want to do operations against
* cb - a function callback to be processed on the running loop's
thread. The only parameter is an opaque pointer to the running
uv_loop_t. In the context of this callback, it is safe to use this pointer
to do various uv_* API calls. _DO NOT_ send this pointer out via ports/chans
"]
unsafe fn interact(a_loop: high_level_loop,
                      -cb: fn~(*libc::c_void)) {
    send_high_level_msg(a_loop, interaction(cb));
}

iface uv_handle_manager<T> {
    fn init() -> T;
}

type safe_handle_fields<T> = {
    hl_loop: high_level_loop,
    handle: T,
    close_cb: *u8
};

/*fn safe_handle<T>(a_loop: high_level_loop,
                  handle_val: T,
                  handle_init_cb: fn~(*libc::c_void, *T),
                  close_cb: *u8) {

resource safe_handle_container<T>(handle_fields: safe_handle_fields<T>) {
}
}*/

#[doc="
Needs to be encapsulated within `safe_handle`
"]
fn ref_handle<T>(hl_loop: high_level_loop, handle: *T) unsafe {
    send_high_level_msg(hl_loop, auto_ref_handle(handle as *libc::c_void));
}
#[doc="
Needs to be encapsulated within `safe_handle`
"]
fn unref_handle<T>(hl_loop: high_level_loop, handle: *T,
                   user_close_cb: *u8) unsafe {
    send_high_level_msg(hl_loop, auto_unref_handle(handle as *libc::c_void,
                                                   user_close_cb));
}

// INTERNAL API

// data that lives for the lifetime of the high-evel oo
enum global_loop_data {
    default_gl_data({
        async_handle: *ll::uv_async_t,
        mut active: bool,
        before_msg_drain: fn~(*ll::uv_async_t) -> bool,
        before_tear_down: fn~(*ll::uv_async_t),
        msg_po_ptr: *comm::port<high_level_msg>,
        mut refd_handles: [mut *libc::c_void],
        mut unrefd_handles: [mut *libc::c_void]})
}

unsafe fn send_high_level_msg(hl_loop: high_level_loop,
                              -msg: high_level_msg) unsafe {
    comm::send(hl_loop.op_chan(), msg);

    // if the global async handle == 0, then that means
    // the loop isn't active, so we don't need to wake it up,
    // (the loop's enclosing task should be blocking on a message
    // receive on this port)
    alt hl_loop {
      single_task_loop({async_handle, op_chan}) {
        if ((*async_handle) != 0 as *ll::uv_async_t) {
            log(debug,"global async handle != 0, waking up loop..");
            ll::async_send((*async_handle));
        }
        else {
            log(debug,"GLOBAL ASYNC handle == 0");
        }
      }
      _ {}
    }
}

// this will be invoked by a call to uv::hl::interact() with
// the high_level_loop corresponding to this async_handle. We
// simply check if the loop is active and, if so, invoke the
// user-supplied on_wake callback that is stored in the loop's
// data member
crust fn high_level_wake_up_cb(async_handle: *ll::uv_async_t,
                               status: int) unsafe {
    // nothing here, yet.
    log(debug, #fmt("high_level_wake_up_cb crust.. handle: %? status: %?",
                     async_handle, status));
    let loop_ptr = ll::get_loop_for_uv_handle(async_handle);
    let data = ll::get_data_for_uv_handle(async_handle) as *global_loop_data;
    // we check to see if the loop is "active" (the loop is set to
    // active = false the first time we realize we need to 'tear down',
    // set subsequent calls to the global async handle may be triggered
    // before all of the uv_close() calls are processed and loop exits
    // on its own. So if the loop isn't active, we won't run the user's
    // on_wake callback (and, consequently, let messages pile up, probably
    // in the loops msg_po)
    if (*data).active {
        log(debug, "before on_wake");
        let mut do_msg_drain = (*data).before_msg_drain(async_handle);
        let mut continue = true;
        if do_msg_drain {
            let msg_po = *((*data).msg_po_ptr);
            if comm::peek(msg_po) {
                // if this is true, we'll iterate over the
                // msgs waiting in msg_po until there's no more
                log(debug,"got msg_po");
                while(continue) {
                    log(debug,"before alt'ing on high_level_msg");
                    alt comm::recv(msg_po) {
                      interaction(cb) {
                        log(debug,"got interaction, before cb..");
                        // call it..
                        cb(loop_ptr);
                        log(debug,"after calling cb");
                      }
                      auto_ref_handle(handle) {
                        high_level_ref(data, handle);
                      }
                      auto_unref_handle(handle, user_close_cb) {
                        high_level_unref(data, handle, false, user_close_cb);
                      }
                      tear_down {
                        log(debug,"incoming hl_msg: got tear_down");
                      }
                    }
                    continue = comm::peek(msg_po);
                }
            }
        }
        log(debug, #fmt("after on_wake, continue? %?", continue));
        if !do_msg_drain {
            high_level_tear_down(data);
        }
    }
}

crust fn tear_down_close_cb(handle: *ll::uv_async_t) unsafe {
    log(debug, #fmt("tear_down_close_cb called, closing handle at %?",
                    handle));
    // TODO: iterate through open handles on the loop and uv_close()
    // them all
    //let data = ll::get_data_for_uv_handle(handle) as *global_loop_data;
}

fn high_level_tear_down(data: *global_loop_data) unsafe {
    log(debug, "high_level_tear_down() called, close async_handle");
    // call user-suppled before_tear_down cb
    let async_handle = (*data).async_handle;
    (*data).before_tear_down(async_handle);
    ll::close(async_handle as *libc::c_void, tear_down_close_cb);
}

unsafe fn high_level_ref(data: *global_loop_data, handle: *libc::c_void) {
    log(debug,"incoming hl_msg: got auto_ref_handle");
    let mut refd_handles = (*data).refd_handles;
    let handle_already_refd = refd_handles.contains(handle);
    if handle_already_refd {
        fail "attempt to do a high-level ref an already ref'd handle";
    }
    refd_handles += [handle];
    (*data).refd_handles = refd_handles;
}

unsafe fn high_level_unref(data: *global_loop_data, handle: *libc::c_void,
                   manual_unref: bool, user_close_cb: *u8) {
    log(debug,"incoming hl_msg: got auto_unref_handle");
    let mut refd_handles = (*data).refd_handles;
    let mut unrefd_handles = (*data).unrefd_handles;
    let handle_already_refd = refd_handles.contains(handle);
    if !handle_already_refd {
        fail "attempting to high-level unref an untracked handle";
    }
    let double_unref = unrefd_handles.contains(handle);
    if double_unref {
        if manual_unref {
            // will allow a user to manual unref, but only signal
            // a fail when a double-unref is caused by a user
            fail "attempting to high-level unref an unrefd handle";
        }
    }
    else {
        ll::close(handle, user_close_cb);
        let last_idx = vec::len(refd_handles) - 1u;
        let handle_idx = vec::position_elem(refd_handles, handle);
        alt handle_idx {
          none {
            fail "trying to remove handle that isn't in refd_handles";
          }
          some(idx) {
            refd_handles[idx] <-> refd_handles[last_idx];
            vec::pop(refd_handles);
          }
        }
        (*data).refd_handles = refd_handles;
        unrefd_handles += [handle];
        (*data).unrefd_handles = unrefd_handles;
        if vec::len(refd_handles) == 0u {
            log(debug, "0 referenced handles, start loop teardown");
            high_level_tear_down(data);
        }
        else {
            log(debug, "more than 0 referenced handles");
        }
    }

}
<commit_msg>std: fail if exiting hl_loop has unref_handles at weaken_task exit<commit_after>#[doc = "
High-level bindings to work with the libuv library.

This module is geared towards library developers who want to
provide a high-level, abstracted interface to some set of
libuv functionality.
"];

export high_level_loop, hl_loop_ext, high_level_msg;
export run_high_level_loop, interact, ref_handle, unref_handle;

import ll = uv_ll;

#[doc = "
Used to abstract-away direct interaction with a libuv loop.

# Arguments

* async_handle - a pointer to a pointer to a uv_async_t struct used to 'poke'
the C uv loop to process any pending callbacks

* op_chan - a channel used to send function callbacks to be processed
by the C uv loop
"]
enum high_level_loop {
    single_task_loop({
        async_handle: **ll::uv_async_t,
        op_chan: comm::chan<high_level_msg>
    }),
    monitor_task_loop({
        op_chan: comm::chan<high_level_msg>
    })
}

impl hl_loop_ext for high_level_loop {
    fn async_handle() -> **ll::uv_async_t {
        alt self {
          single_task_loop({async_handle, op_chan}) {
            ret async_handle;
          }
          _ {
            fail "variant of hl::high_level_loop that doesn't include" +
                "an async_handle field";
          }
        }
    }
    fn op_chan() -> comm::chan<high_level_msg> {
        alt self {
          single_task_loop({async_handle, op_chan}) {
            ret op_chan;
          }
          monitor_task_loop({op_chan}) {
            ret op_chan;
          }
        }
    }
}

#[doc="
Represents the range of interactions with a `high_level_loop`
"]
enum high_level_msg {
    interaction (fn~(*libc::c_void)),
    auto_ref_handle (*libc::c_void),
    auto_unref_handle (*libc::c_void, *u8),
    tear_down
}

#[doc = "
Given a vanilla `uv_loop_t*`

# Arguments

* loop_ptr - a pointer to a currently unused libuv loop. Its `data` field
will be overwritten before the loop begins
must be a pointer to a clean rust `uv_async_t` record
* msg_po - an active port that receives `high_level_msg`s
* before_run - a unique closure that is invoked after `uv_async_init` is
called on the `async_handle` passed into this callback, just before `uv_run`
is called on the provided `loop_ptr`
* before_msg_drain - a unique closure that is invoked every time the loop is
awoken, but before the port pointed to in the `msg_po` argument is drained
* before_tear_down - called just before the loop invokes `uv_close()` on the
provided `async_handle`. `uv_run` should return shortly after
"]
unsafe fn run_high_level_loop(loop_ptr: *libc::c_void,
                              msg_po: comm::port<high_level_msg>,
                              before_run: fn~(*ll::uv_async_t),
                              before_msg_drain: fn~(*ll::uv_async_t) -> bool,
                              before_tear_down: fn~(*ll::uv_async_t)) {
    // set up the special async handle we'll use to allow multi-task
    // communication with this loop
    let async = ll::async_t();
    let async_handle = ptr::addr_of(async);
    // associate the async handle with the loop
    ll::async_init(loop_ptr, async_handle, high_level_wake_up_cb);

    // initialize our loop data and store it in the loop
    let data: global_loop_data = default_gl_data({
        async_handle: async_handle,
        mut active: true,
        before_msg_drain: before_msg_drain,
        before_tear_down: before_tear_down,
        msg_po_ptr: ptr::addr_of(msg_po),
        mut refd_handles: [mut],
        mut unrefd_handles: [mut]
    });
    let data_ptr = ptr::addr_of(data);
    ll::set_data_for_uv_handle(async_handle, data_ptr);

    // call before_run
    before_run(async_handle);

    log(debug, "about to run high level loop");
    // enter the loop... this blocks until the loop is done..
    ll::run(loop_ptr);
    log(debug, "high-level loop ended");
}

#[doc = "
Provide a callback to be processed by `a_loop`

The primary way to do operations again a running `high_level_loop` that
doesn't involve creating a uv handle via `safe_handle`

# Arguments

* a_loop - a `high_level_loop` that you want to do operations against
* cb - a function callback to be processed on the running loop's
thread. The only parameter is an opaque pointer to the running
uv_loop_t. In the context of this callback, it is safe to use this pointer
to do various uv_* API calls. _DO NOT_ send this pointer out via ports/chans
"]
unsafe fn interact(a_loop: high_level_loop,
                      -cb: fn~(*libc::c_void)) {
    send_high_level_msg(a_loop, interaction(cb));
}

iface uv_handle_manager<T> {
    fn init() -> T;
}

type safe_handle_fields<T> = {
    hl_loop: high_level_loop,
    handle: T,
    close_cb: *u8
};

/*fn safe_handle<T>(a_loop: high_level_loop,
                  handle_val: T,
                  handle_init_cb: fn~(*libc::c_void, *T),
                  close_cb: *u8) {

resource safe_handle_container<T>(handle_fields: safe_handle_fields<T>) {
}
}*/

#[doc="
Needs to be encapsulated within `safe_handle`
"]
fn ref_handle<T>(hl_loop: high_level_loop, handle: *T) unsafe {
    send_high_level_msg(hl_loop, auto_ref_handle(handle as *libc::c_void));
}
#[doc="
Needs to be encapsulated within `safe_handle`
"]
fn unref_handle<T>(hl_loop: high_level_loop, handle: *T,
                   user_close_cb: *u8) unsafe {
    send_high_level_msg(hl_loop, auto_unref_handle(handle as *libc::c_void,
                                                   user_close_cb));
}

// INTERNAL API

// data that lives for the lifetime of the high-evel oo
enum global_loop_data {
    default_gl_data({
        async_handle: *ll::uv_async_t,
        mut active: bool,
        before_msg_drain: fn~(*ll::uv_async_t) -> bool,
        before_tear_down: fn~(*ll::uv_async_t),
        msg_po_ptr: *comm::port<high_level_msg>,
        mut refd_handles: [mut *libc::c_void],
        mut unrefd_handles: [mut *libc::c_void]})
}

unsafe fn send_high_level_msg(hl_loop: high_level_loop,
                              -msg: high_level_msg) unsafe {
    comm::send(hl_loop.op_chan(), msg);

    // if the global async handle == 0, then that means
    // the loop isn't active, so we don't need to wake it up,
    // (the loop's enclosing task should be blocking on a message
    // receive on this port)
    alt hl_loop {
      single_task_loop({async_handle, op_chan}) {
        if ((*async_handle) != 0 as *ll::uv_async_t) {
            log(debug,"global async handle != 0, waking up loop..");
            ll::async_send((*async_handle));
        }
        else {
            log(debug,"GLOBAL ASYNC handle == 0");
        }
      }
      _ {}
    }
}

// this will be invoked by a call to uv::hl::interact() with
// the high_level_loop corresponding to this async_handle. We
// simply check if the loop is active and, if so, invoke the
// user-supplied on_wake callback that is stored in the loop's
// data member
crust fn high_level_wake_up_cb(async_handle: *ll::uv_async_t,
                               status: int) unsafe {
    // nothing here, yet.
    log(debug, #fmt("high_level_wake_up_cb crust.. handle: %? status: %?",
                     async_handle, status));
    let loop_ptr = ll::get_loop_for_uv_handle(async_handle);
    let data = ll::get_data_for_uv_handle(async_handle) as *global_loop_data;
    // we check to see if the loop is "active" (the loop is set to
    // active = false the first time we realize we need to 'tear down',
    // set subsequent calls to the global async handle may be triggered
    // before all of the uv_close() calls are processed and loop exits
    // on its own. So if the loop isn't active, we won't run the user's
    // on_wake callback (and, consequently, let messages pile up, probably
    // in the loops msg_po)
    if (*data).active {
        log(debug, "before on_wake");
        let mut do_msg_drain = (*data).before_msg_drain(async_handle);
        let mut continue = true;
        if do_msg_drain {
            let msg_po = *((*data).msg_po_ptr);
            if comm::peek(msg_po) {
                // if this is true, we'll iterate over the
                // msgs waiting in msg_po until there's no more
                log(debug,"got msg_po");
                while(continue) {
                    log(debug,"before alt'ing on high_level_msg");
                    alt comm::recv(msg_po) {
                      interaction(cb) {
                        log(debug,"got interaction, before cb..");
                        // call it..
                        cb(loop_ptr);
                        log(debug,"after calling cb");
                      }
                      auto_ref_handle(handle) {
                        high_level_ref(data, handle);
                      }
                      auto_unref_handle(handle, user_close_cb) {
                        high_level_unref(data, handle, false, user_close_cb);
                      }
                      tear_down {
                        log(debug,"incoming hl_msg: got tear_down");
                      }
                    }
                    continue = comm::peek(msg_po);
                }
            }
        }
        log(debug, #fmt("after on_wake, continue? %?", continue));
        if !do_msg_drain {
            high_level_tear_down(data);
        }
    }
}

crust fn tear_down_close_cb(handle: *ll::uv_async_t) unsafe {
    log(debug, #fmt("tear_down_close_cb called, closing handle at %?",
                    handle));
    let data = ll::get_data_for_uv_handle(handle) as *global_loop_data;
    if vec::len((*data).refd_handles) > 0 {
        fail "Didn't unref all high-level handles";
    }
}

fn high_level_tear_down(data: *global_loop_data) unsafe {
    log(debug, "high_level_tear_down() called, close async_handle");
    // call user-suppled before_tear_down cb
    let async_handle = (*data).async_handle;
    (*data).before_tear_down(async_handle);
    ll::close(async_handle as *libc::c_void, tear_down_close_cb);
}

unsafe fn high_level_ref(data: *global_loop_data, handle: *libc::c_void) {
    log(debug,"incoming hl_msg: got auto_ref_handle");
    let mut refd_handles = (*data).refd_handles;
    let handle_already_refd = refd_handles.contains(handle);
    if handle_already_refd {
        fail "attempt to do a high-level ref an already ref'd handle";
    }
    refd_handles += [handle];
    (*data).refd_handles = refd_handles;
}

unsafe fn high_level_unref(data: *global_loop_data, handle: *libc::c_void,
                   manual_unref: bool, user_close_cb: *u8) {
    log(debug,"incoming hl_msg: got auto_unref_handle");
    let mut refd_handles = (*data).refd_handles;
    let mut unrefd_handles = (*data).unrefd_handles;
    let handle_already_refd = refd_handles.contains(handle);
    if !handle_already_refd {
        fail "attempting to high-level unref an untracked handle";
    }
    let double_unref = unrefd_handles.contains(handle);
    if double_unref {
        if manual_unref {
            // will allow a user to manual unref, but only signal
            // a fail when a double-unref is caused by a user
            fail "attempting to high-level unref an unrefd handle";
        }
    }
    else {
        ll::close(handle, user_close_cb);
        let last_idx = vec::len(refd_handles) - 1u;
        let handle_idx = vec::position_elem(refd_handles, handle);
        alt handle_idx {
          none {
            fail "trying to remove handle that isn't in refd_handles";
          }
          some(idx) {
            refd_handles[idx] <-> refd_handles[last_idx];
            vec::pop(refd_handles);
          }
        }
        (*data).refd_handles = refd_handles;
        unrefd_handles += [handle];
        (*data).unrefd_handles = unrefd_handles;
        if vec::len(refd_handles) == 0u {
            log(debug, "0 referenced handles, start loop teardown");
            high_level_tear_down(data);
        }
        else {
            log(debug, "more than 0 referenced handles");
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>New header parsing approach<commit_after><|endoftext|>


<commit_before><commit_msg>updating hello to add in test<commit_after><|endoftext|>


<commit_before><commit_msg>Add SphinxParams that contains max hops and payload size<commit_after><|endoftext|>


<commit_before><commit_msg>Use local cargo-travis<commit_after><|endoftext|>


<commit_before><commit_msg>Remove store flush caching as it is not necessary anymore<commit_after><|endoftext|>


<commit_before><commit_msg>Added channels tutorial<commit_after>fn main() {
    let numbers = ~[1,2,3];

    let (tx, rx)  = channel();
    tx.send(numbers);

    spawn(proc() {
        let numbers = rx.recv();
        println!("{}", numbers[2]);
    })
}<|endoftext|>


<commit_before><commit_msg>Fixed issue where spectra wasn't being lzf compressed after refactor.<commit_after><|endoftext|>


<commit_before><commit_msg>fix equippable determination<commit_after><|endoftext|>


<commit_before><commit_msg>Add the renderer file<commit_after>pub mod renderer {
    pub mod glium_sdl2;

    use px8;
    use gfx::{Scale};

    use sdl2::video::gl_attr::GLAttr;
    use sdl2::VideoSubsystem;

    use glium;
    use glium::{DrawError, DrawParameters, IndexBuffer, Program, VertexBuffer, Surface};
    use glium::index::PrimitiveType;
    use glium::program::ProgramChooserCreationError;
    use glium::{Api, GliumCreationError, SwapBuffersError, Version};
    use glium::backend::Facade;
    use glium::texture::{ClientFormat, MipmapsOption, PixelValue, TextureCreationError, UncompressedFloatFormat};
    use glium::texture::pixel_buffer::PixelBuffer;
    use glium::texture::texture2d::Texture2d;

    use glium::uniforms::{MagnifySamplerFilter, MinifySamplerFilter};
    use nalgebra::{Diagonal, Matrix4, Vector4};

    use self::glium_sdl2::{Display, DisplayBuild, GliumSdl2Error};

    #[derive(Clone, Debug)]
    pub enum RendererError {
        Sdl(String),
        Renderer(String),
        Other(String),
    }

    pub type RendererResult<T> = Result<T, RendererError>;

    impl From<DrawError> for RendererError {
        fn from(e: DrawError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<TextureCreationError> for RendererError {
        fn from(e: TextureCreationError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<glium::vertex::BufferCreationError> for RendererError {
        fn from(e: glium::vertex::BufferCreationError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<glium::index::BufferCreationError> for RendererError {
        fn from(e: glium::index::BufferCreationError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<ProgramChooserCreationError> for RendererError {
        fn from(e: ProgramChooserCreationError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<GliumCreationError<GliumSdl2Error>> for RendererError {
        fn from(e: GliumCreationError<GliumSdl2Error>) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    impl From<SwapBuffersError> for RendererError {
        fn from(e: SwapBuffersError) -> RendererError {
            RendererError::Renderer(format!("{:?}", e))
        }
    }

    unsafe impl PixelValue for px8::Color {
        fn get_format() -> ClientFormat {
            ClientFormat::U8
        }
    }

    type Texture = Texture2d;

    #[derive(Copy, Clone)]
    pub struct Vertex {
        position: [f32; 2],
        tex_coords: [f32; 2],
    }

    implement_vertex!(Vertex, position, tex_coords);

    pub struct Renderer {
        vertex_buffer: VertexBuffer<Vertex>,
        index_buffer: IndexBuffer<u16>,
        pixel_buffer: PixelBuffer<px8::Color>,
        program: Program,
        texture: Texture,
        matrix: Matrix4<f32>,
        display: Display,
    }

    const TEXTURE_WIDTH: u32 = 256;
    const TEXTURE_HEIGHT: u32 = 256;
    const TEX_OFFSET_X: f32 = px8::SCREEN_WIDTH as f32 / TEXTURE_WIDTH as f32;
    const TEX_OFFSET_Y: f32 = px8::SCREEN_HEIGHT as f32 / TEXTURE_HEIGHT as f32;

    const ASPECT_RATIO: f32 = px8::SCREEN_WIDTH as f32 / px8::SCREEN_HEIGHT as f32;

    fn aspect_ratio_correction(width: u32, height: u32) -> (f32, f32) {
        let fb_aspect_ratio = width as f32 / height as f32;
        let scale = ASPECT_RATIO / fb_aspect_ratio;
        if fb_aspect_ratio >= ASPECT_RATIO {
            (scale, 1.0)
        } else {
            (1.0, 1.0 / scale)
        }
    }

    impl Renderer {

        pub fn new(sdl_video: VideoSubsystem, fullscreen: bool, scale: Scale) -> RendererResult<Renderer> {
            let display;

            info!("SDL2 Video with opengl [glium]");

            configure_gl_attr(&mut sdl_video.gl_attr());

            if fullscreen {
                info!("SDL2 window fullscreen");

                display = try!(sdl_video.window("PX8",
                                                (px8::SCREEN_WIDTH * scale.factor()) as u32,
                                                (px8::SCREEN_HEIGHT * scale.factor()) as u32)
                    .resizable()
                    .fullscreen()
                    .position_centered()
                    .build_glium());
            } else {
                info!("SDL2 window");

                display = try!(sdl_video.window("PX8",
                                                (px8::SCREEN_WIDTH * scale.factor()) as u32,
                                                (px8::SCREEN_HEIGHT * scale.factor()) as u32)
                    .resizable()
                    .position_centered()
                    .build_glium());
            }

            info!("Init Renderer with GLIUM");

            let vertexes = [
                Vertex {
                    position: [-1.0, -1.0],
                    tex_coords: [0.0, TEX_OFFSET_Y],
                },
                Vertex {
                    position: [-1.0, 1.0],
                    tex_coords: [0.0, 0.0],
                },
                Vertex {
                    position: [1.0, 1.0],
                    tex_coords: [TEX_OFFSET_X, 0.0],
                },
                Vertex {
                    position: [1.0, -1.0],
                    tex_coords: [TEX_OFFSET_X, TEX_OFFSET_Y],
                }
            ];

            info!("Creating VertexBuffer");

            let vertex_buffer = try!(VertexBuffer::immutable(&display, &vertexes));

            info!("Creating IndexBuffer");

            let index_buffer =
            try!(IndexBuffer::immutable(&display, PrimitiveType::TriangleStrip, &[1u16, 2, 0, 3]));

            info!("Compiling shader");

            let program = try!(program!(
              &display,
              140 => {
                vertex: include_str!("shader/vert_140.glsl"),
                fragment: include_str!("shader/frag_140.glsl"),
                outputs_srgb: true
              },
              110 => {
                vertex: include_str!("shader/vert_110.glsl"),
                fragment: include_str!("shader/frag_110.glsl"),
                outputs_srgb: true
              }
            ));

            info!("Creating PixelBuffer");

            let pixel_buffer = PixelBuffer::new_empty(&display, px8::SCREEN_WIDTH * px8::SCREEN_HEIGHT);
            pixel_buffer.write(&vec![px8::Color::Black; pixel_buffer.get_size()]);

            info!("Creating Texture");
            let mut texture = try!(Texture::empty_with_format(&display,
                                                              UncompressedFloatFormat::U8U8U8,
                                                              MipmapsOption::NoMipmap,
                                                              TEXTURE_WIDTH,
                                                              TEXTURE_HEIGHT));

            info!("Uploading Pixels");
            texture.main_level().raw_upload_from_pixel_buffer(pixel_buffer.as_slice(),
                                                              0..px8::SCREEN_WIDTH as u32,
                                                              0..px8::SCREEN_HEIGHT as u32,
                                                              0..1);

            let (width, height) = display.get_context().get_framebuffer_dimensions();
            let (x_scale, y_scale) = aspect_ratio_correction(width, height);
            let matrix = Matrix4::from_diagonal(&Vector4::new(x_scale, y_scale, 1.0, 1.0));

            Ok(Renderer {
                vertex_buffer: vertex_buffer,
                index_buffer: index_buffer,
                pixel_buffer: pixel_buffer,
                program: program,
                texture: texture,
                matrix: matrix,
                display: display,
            })

        }
        pub fn draw<S: Surface>(&self, frame: &mut S) -> RendererResult<()> {
            let uniforms = uniform! {
                matrix: self.matrix.as_ref().clone(),
                tex: self.texture.sampled()
                    .minify_filter(MinifySamplerFilter::Nearest)
                    .magnify_filter(MagnifySamplerFilter::Nearest)
            };

            let params = DrawParameters { ..Default::default() };
            try!(frame.draw(&self.vertex_buffer,
                            &self.index_buffer,
                            &self.program,
                            &uniforms,
                            &params));
            Ok(())
        }

        pub fn blit(&mut self, back_buffer: &px8::ScreenBuffer) {
            self.update_pixels(back_buffer);

            let mut target = self.display.draw();
            target.clear_color(0.0, 0.0, 0.0, 0.0);
            self.draw(&mut target);
            target.finish();
        }

        pub fn update_pixels(&mut self, pixels: &px8::ScreenBuffer) {
            self.pixel_buffer.write(pixels);

            self.texture.main_level().raw_upload_from_pixel_buffer(self.pixel_buffer.as_slice(),
                                                                   0..px8::SCREEN_WIDTH as u32,
                                                                   0..px8::SCREEN_HEIGHT as u32,
                                                                   0..1);
        }

        pub fn update_dimensions(&mut self) {
            let (width, height) = self.display.get_context().get_framebuffer_dimensions();
            let (x_scale, y_scale) = aspect_ratio_correction(width, height);
            self.matrix.m11 = x_scale;
            self.matrix.m22 = y_scale;
        }

        pub fn get_dimensions(&mut self) -> (u32, u32) {
            return self.display.get_context().get_framebuffer_dimensions();
        }
    }

    #[cfg(target_os = "linux")]
    fn configure_gl_attr(gl_attr: &mut GLAttr) {
        info!("Init OPENGL for Linux");
    }

    #[cfg(target_os = "windows")]
    fn configure_gl_attr(gl_attr: &mut GLAttr) {
        info!("Init OPENGL for Windows");
    }

    #[cfg(target_os = "macos")]
    fn configure_gl_attr(gl_attr: &mut GLAttr) {
        info!("Init OPENGL for OSX");

        use sdl2::video::GLProfile;
        gl_attr.set_context_profile(GLProfile::Core);
        gl_attr.set_context_flags().forward_compatible().set();
    }

    #[cfg(target_os = "emscripten")]
    fn configure_gl_attr(gl_attr: &mut GLAttr) {
        info!("Init OPENGL for Emscripten");
    }
}<|endoftext|>


<commit_before><commit_msg>dynamic dispatch using casting<commit_after><|endoftext|>


<commit_before>use redox::*;

#[derive(Copy, Clone)]
pub enum Mode {
    Insert,
    Normal,
}

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn backspace(&mut self, window: &mut Window) {
         if self.offset > 0 {
             window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
             self.string = self.string[0 .. self.offset - 1].to_string() +
                 &self.string[self.offset .. self.string.len()];
             self.offset -= 1;
         }
    }

    fn delete(&mut self, window: &mut Window) {
        if self.offset < self.string.len() {
            window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
            self.string = self.string[0 .. self.offset + 1].to_string() +
                &self.string[self.offset + 1 .. self.string.len() - 1];
        }
    }

    fn up(&mut self) {
        let mut new_offset = 0;
        for i in 2..self.offset {
            match self.string.as_bytes()[self.offset - i] {
                0 => break,
                10 => {
                    new_offset = self.offset - i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn left(&mut self) {
        if self.offset > 0 {
            self.offset -= 1;
        }
    }

    fn right(&mut self) {
        if self.offset < self.string.len() {
            self.offset += 1;
        }
    }

    fn down(&mut self) {
        let mut new_offset = self.string.len();
        for i in self.offset..self.string.len() {
            match self.string.as_bytes()[i] {
                0 => break,
                10 => {
                    new_offset = i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            },
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     576,
                                     400,
                                      &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        let mut mode = Mode::Normal;

        let mut last_change = String::new();

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        use self::Mode::*;
                        match (mode, key_event.scancode) {
                            (Insert, K_ESC) => {
                                mode = Normal;
                            },
                            (Insert, K_BKSP) => self.backspace(&mut window),
                            (Insert, K_DEL) => self.delete(&mut window),
                            (_, K_F5) => self.reload(&mut window),
                            (_, K_F6) => self.save(&mut window),
                            (_, K_HOME) => self.offset = 0,
                            (_, K_UP) => self.up(),
                            (_, K_LEFT) => self.left(),
                            (_, K_RIGHT) => self.right(),
                            (_, K_END) => self.offset = self.string.len(),
                            (_, K_DOWN) => self.down(),
                            (m, _) => match (m, key_event.character) {
                                (Normal, 'i') => {
                                    mode = Insert;
                                    last_change = self.string.clone();
                                },
                                (Normal, 'h') => self.left(),
                                (Normal, 'l') => self.right(),
                                (Normal, 'k') => self.up(),
                                (Normal, 'j') => self.down(),
                                (Normal, 'G') => self.offset = self.string.len(),
                                (Normal, 'a') => {
                                    self.right();
                                    mode = Insert;
                                    last_change = self.string.clone();
                                },
                                (Normal, 'x') => self.delete(&mut window),
                                (Normal, 'X') => self.backspace(&mut window),
                                (Normal, 'u') => {
                                    ::core::mem::swap(&mut last_change, &mut self.string);
                                },
                                (Insert, '\0') => (),
                                (Insert, _) => {
                                    window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                    self.string = self.string[0 .. self.offset].to_string() +
                                                  &key_event.character.to_string() +
                                                  &self.string[self.offset .. self.string.len()];
                                    self.offset += 1;
                                },
                                _ => {},
                            }
                        }

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<commit_msg>Reset cursor on undo<commit_after>use redox::*;

#[derive(Copy, Clone)]
pub enum Mode {
    Insert,
    Normal,
}

pub struct Editor {
    url: String,
    file: Option<File>,
    string: String,
    offset: usize,
    scroll_x: isize,
    scroll_y: isize,
}

impl Editor {
    #[inline(never)]
    pub fn new() -> Self {
        Editor {
            url: String::new(),
            file: Option::None,
            string: String::new(),
            offset: 0,
            scroll_x: 0,
            scroll_y: 0,
        }
    }

    fn backspace(&mut self, window: &mut Window) {
         if self.offset > 0 {
             window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
             self.string = self.string[0 .. self.offset - 1].to_string() +
                 &self.string[self.offset .. self.string.len()];
             self.offset -= 1;
         }
    }

    fn delete(&mut self, window: &mut Window) {
        if self.offset < self.string.len() {
            window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
            self.string = self.string[0 .. self.offset + 1].to_string() +
                &self.string[self.offset + 1 .. self.string.len() - 1];
        }
    }

    fn up(&mut self) {
        let mut new_offset = 0;
        for i in 2..self.offset {
            match self.string.as_bytes()[self.offset - i] {
                0 => break,
                10 => {
                    new_offset = self.offset - i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn left(&mut self) {
        if self.offset > 0 {
            self.offset -= 1;
        }
    }

    fn right(&mut self) {
        if self.offset < self.string.len() {
            self.offset += 1;
        }
    }

    fn down(&mut self) {
        let mut new_offset = self.string.len();
        for i in self.offset..self.string.len() {
            match self.string.as_bytes()[i] {
                0 => break,
                10 => {
                    new_offset = i + 1;
                    break;
                }
                _ => (),
            }
        }
        self.offset = new_offset;
    }

    fn reload(&mut self, window: &mut Window) {
        window.set_title(&("Editor (".to_string() + &self.url + ")"));
        self.offset = 0;
        self.scroll_x = 0;
        self.scroll_y = 0;

        match self.file {
            Option::Some(ref mut file) => {
                file.seek(Seek::Start(0));
                let mut vec: Vec<u8> = Vec::new();
                file.read_to_end(&mut vec);
                self.string = unsafe { String::from_utf8_unchecked(vec) };
            },
            Option::None => self.string = String::new(),
        }
    }

    fn save(&mut self, window: &mut Window) {
        match self.file {
            Option::Some(ref mut file) => {
                window.set_title(&("Editor (".to_string() + &self.url + ") Saved"));
                file.seek(Seek::Start(0));
                file.write(&self.string.as_bytes());
                file.sync();
            }
            Option::None => {
                //TODO: Ask for file to save to
                window.set_title(&("Editor (".to_string() + &self.url + ") No Open File"));
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        let mut redraw = false;

        {
            window.set([255, 255, 255, 255]);

            let scroll_x = self.scroll_x;
            let scroll_y = self.scroll_y;

            let mut offset = 0;

            let mut col = -scroll_x;
            let cols = window.width() as isize / 8;

            let mut row = -scroll_y;
            let rows = window.height() as isize / 16;

            for c in self.string.chars() {
                if offset == self.offset {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                    } else {
                        if col < 0 { //Too far to the left
                            self.scroll_x += col;
                        } else if col >= cols { //Too far to the right
                            self.scroll_x += cols - col + 1;
                        }
                        if row < 0 { //Too far up
                            self.scroll_y += row;
                        } else if row >= rows { //Too far down
                            self.scroll_y += rows - row + 1;
                        }

                        redraw = true;
                    }
                }

                if c == '\n' {
                    col = -scroll_x;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col >= 0 && col < cols && row >= 0 && row < rows {
                        window.char(8 * col, 16 * row, c, [0, 0, 0, 255]);
                    }
                    col += 1;
                }

                offset += 1;
            }

            if offset == self.offset {
                if col >= 0 && col < cols && row >= 0 && row < rows {
                    window.char(8 * col, 16 * row, '_', [128, 128, 128, 255]);
                } else {
                    if col < 0 { //Too far to the left
                        self.scroll_x += col;
                    } else if col >= cols { //Too far to the right
                        self.scroll_x += cols - col + 1;
                    }
                    if row < 0 { //Too far up
                        self.scroll_y += row;
                    } else if row >= rows { //Too far down
                        self.scroll_y += rows - row + 1;
                    }

                    redraw = true;
                }
            }

            window.sync();
        }

        if redraw {
            self.draw_content(window);
        }
    }

    fn main(&mut self, url: &str) {
        let mut window = Window::new((rand() % 400 + 50) as isize,
                                     (rand() % 300 + 50) as isize,
                                     576,
                                     400,
                                      &("Editor (".to_string() + url + ")"));

        self.url = url.to_string();
        self.file = Option::Some(File::open(&self.url));

        self.reload(&mut window);
        self.draw_content(&mut window);

        let mut mode = Mode::Normal;

        let mut last_change = String::new();

        while let Option::Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        use self::Mode::*;
                        match (mode, key_event.scancode) {
                            (Insert, K_ESC) => {
                                mode = Normal;
                            },
                            (Insert, K_BKSP) => self.backspace(&mut window),
                            (Insert, K_DEL) => self.delete(&mut window),
                            (_, K_F5) => self.reload(&mut window),
                            (_, K_F6) => self.save(&mut window),
                            (_, K_HOME) => self.offset = 0,
                            (_, K_UP) => self.up(),
                            (_, K_LEFT) => self.left(),
                            (_, K_RIGHT) => self.right(),
                            (_, K_END) => self.offset = self.string.len(),
                            (_, K_DOWN) => self.down(),
                            (m, _) => match (m, key_event.character) {
                                (Normal, 'i') => {
                                    mode = Insert;
                                    last_change = self.string.clone();
                                },
                                (Normal, 'h') => self.left(),
                                (Normal, 'l') => self.right(),
                                (Normal, 'k') => self.up(),
                                (Normal, 'j') => self.down(),
                                (Normal, 'G') => self.offset = self.string.len(),
                                (Normal, 'a') => {
                                    self.right();
                                    mode = Insert;
                                    last_change = self.string.clone();
                                },
                                (Normal, 'x') => self.delete(&mut window),
                                (Normal, 'X') => self.backspace(&mut window),
                                (Normal, 'u') => {
                                    self.offset = 0;
                                    ::core::mem::swap(&mut last_change, &mut self.string);
                                },
                                (Insert, '\0') => (),
                                (Insert, _) => {
                                    window.set_title(&format!("{}{}{}","Editor (", &self.url, ") Changed"));
                                    self.string = self.string[0 .. self.offset].to_string() +
                                                  &key_event.character.to_string() +
                                                  &self.string[self.offset .. self.string.len()];
                                    self.offset += 1;
                                },
                                _ => {},
                            }
                        }

                        self.draw_content(&mut window);
                    }
                }
                _ => (),
            }
        }
    }
}

pub fn main() {
    match args().get(1) {
        Option::Some(arg) => Editor::new().main(&arg),
        Option::None => Editor::new().main("none://"),
    }
}
<|endoftext|>


<commit_before><commit_msg>Add lalrpop build.rs<commit_after>fn main() {
    lalrpop::process_root().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #46359 - GuillaumeGomez:remove-dead-linkage, r=QuietMisdreavus<commit_after>// Copyright 2017 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.

#![crate_name = "foo"]

#[doc(hidden)]
pub trait Foo {}

trait Dark {}

pub trait Bam {}

pub struct Bar;

struct Hidden;

// @!has foo/struct.Bar.html '//*[@id="impl-Foo"]' 'impl Foo for Bar'
impl Foo for Bar {}
// @!has foo/struct.Bar.html '//*[@id="impl-Dark"]' 'impl Dark for Bar'
impl Dark for Bar {}
// @has foo/struct.Bar.html '//*[@id="impl-Bam"]' 'impl Bam for Bar'
// @has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Bar'
impl Bam for Bar {}
// @!has foo/trait.Bam.html '//*[@id="implementors-list"]' 'impl Bam for Hidden'
impl Bam for Hidden {}
<|endoftext|>


<commit_before><commit_msg>Add test for issue-75983<commit_after>// check-pass

#![feature(trait_alias)]

struct Bar;
trait Foo {}
impl Foo for Bar {}

trait Baz = Foo where Bar: Foo;

fn new() -> impl Baz {
    Bar
}

fn main() {
    let _ = new();
}
<|endoftext|>


<commit_before><commit_msg>Manage device members in the same namespace.<commit_after><|endoftext|>


<commit_before><commit_msg>Test keystrokes<commit_after><|endoftext|>


<commit_before>use alloc::arc::Arc;

use arch::context::{CONTEXT_IMAGE_ADDR, CONTEXT_IMAGE_SIZE, CONTEXT_HEAP_ADDR, CONTEXT_HEAP_SIZE,
                    CONTEXT_MMAP_ADDR, CONTEXT_MMAP_SIZE, CONTEXT_STACK_SIZE, CONTEXT_STACK_ADDR,
                    context_switch, context_userspace, Context, ContextMemory, ContextZone};
use arch::elf::Elf;
use arch::memory;
use arch::regs::Regs;

use collections::string::{String, ToString};
use collections::vec::Vec;

use common::slice::GetSlice;

use core::cell::UnsafeCell;
use core::ops::DerefMut;
use core::{mem, ptr, str};

use fs::Url;

use system::error::{Error, Result, ENOEXEC};

pub fn execute_thread(context_ptr: *mut Context, entry: usize, mut args: Vec<String>) -> ! {
    Context::spawn("kexec".to_string(), box move || {
        let context = unsafe { &mut *context_ptr };

        let mut context_args: Vec<usize> = Vec::new();
        context_args.push(0); // ENVP
        context_args.push(0); // ARGV NULL
        let mut argc = 0;
        while let Some(mut arg) = args.pop() {
            if ! arg.ends_with('\0') {
                arg.push('\0');
            }

            let mut physical_address = arg.as_ptr() as usize;
            if physical_address >= 0x80000000 {
                physical_address -= 0x80000000;
            }

            let virtual_address = unsafe { (*context.image.get()).next_mem() };
            let virtual_size = arg.len();

            mem::forget(arg);

            unsafe {
                (*context.image.get()).memory.push(ContextMemory {
                    physical_address: physical_address,
                    virtual_address: virtual_address,
                    virtual_size: virtual_size,
                    writeable: false,
                    allocated: true,
                });
            }

            context_args.push(virtual_address as usize);
            argc += 1;
        }
        context_args.push(argc);

        context.iopl = 0;

        context.regs = Regs::default();
        context.regs.sp = context.kernel_stack + CONTEXT_STACK_SIZE - 128;

        context.stack = Some(ContextMemory {
            physical_address: unsafe { memory::alloc_aligned(CONTEXT_STACK_SIZE, 4096) },
            virtual_address: CONTEXT_STACK_ADDR,
            virtual_size: CONTEXT_STACK_SIZE,
            writeable: true,
            allocated: true,
        });

        let user_sp = if let Some(ref stack) = context.stack {
            let mut sp = stack.physical_address + stack.virtual_size - 128;
            for arg in context_args.iter() {
                sp -= mem::size_of::<usize>();
                unsafe { ptr::write(sp as *mut usize, *arg) };
            }
            sp - stack.physical_address + stack.virtual_address
        } else {
            0
        };

        unsafe {
            context.push(0x20 | 3);
            context.push(user_sp);
            context.push(1 << 9);
            context.push(0x18 | 3);
            context.push(entry);
            context.push(context_userspace as usize);
        }

        if let Some(vfork) = context.vfork.take() {
            unsafe { (*vfork).blocked = false; }
        }
    });

    loop {
        unsafe { context_switch() };
    }
}

/// Execute an executable
pub fn execute(mut args: Vec<String>) -> Result<usize> {
    let contexts = ::env().contexts.lock();
    let current = try!(contexts.current());

    let mut vec: Vec<u8> = Vec::new();

    let path = current.canonicalize(args.get(0).map_or("", |p| &p));
    let mut url = try!(Url::from_str(&path)).to_cow();
    {
        let mut resource = if let Ok(resource) = url.as_url().open() {
            resource
        } else {
            let path = "file:/bin/".to_string() + args.get(0).map_or("", |p| &p);
            url = try!(Url::from_str(&path)).to_owned().into_cow();
            try!(url.as_url().open())
        };

        'reading: loop {
            let mut bytes = [0; 4096];
            match resource.read(&mut bytes) {
                Ok(0) => break 'reading,
                Ok(count) => vec.extend_from_slice(bytes.get_slice(.. count)),
                Err(err) => return Err(err)
            }
        }
    }

    if vec.starts_with(b"#!") {
        if let Some(mut arg) = args.get_mut(0) {
            *arg = url.as_url().to_string();
        }

        let line = unsafe { str::from_utf8_unchecked(&vec[2..]) }.lines().next().unwrap_or("");
        let mut i = 0;
        for arg in line.trim().split(' ') {
            if ! arg.is_empty() {
                args.insert(i, arg.to_string());
                i += 1;
            }
        }
        if i == 0 {
            args.insert(i, "/bin/sh".to_string());
        }
        execute(args)
    } else {
        match Elf::from(&vec) {
            Ok(executable) => {
                let entry = unsafe { executable.entry() };
                let mut memory = Vec::new();
                unsafe {
                    for segment in executable.load_segment().iter() {
                        let virtual_address = segment.vaddr as usize;
                        let virtual_size = segment.mem_len as usize;

                        let offset = virtual_address % 4096;

                        let physical_address = memory::alloc_aligned(virtual_size + offset, 4096);

                        if physical_address > 0 {
                            // Copy progbits
                            ::memcpy((physical_address + offset) as *mut u8,
                                     (executable.data.as_ptr() as usize + segment.off as usize) as *const u8,
                                     segment.file_len as usize);
                            // Zero bss
                            if segment.mem_len > segment.file_len {
                                ::memset((physical_address + offset + segment.file_len as usize) as *mut u8,
                                        0,
                                        segment.mem_len as usize - segment.file_len as usize);
                            }

                            memory.push(ContextMemory {
                                physical_address: physical_address,
                                virtual_address: virtual_address - offset,
                                virtual_size: virtual_size + offset,
                                writeable: segment.flags & 2 == 2,
                                allocated: true,
                            });
                        }
                    }
                }

                if entry > 0 && ! memory.is_empty() {
                    let mut contexts = ::env().contexts.lock();
                    let mut context = try!(contexts.current_mut());

                    //debugln!("{}: {}: execute {}", context.pid, context.name, url.string);

                    context.name = url.as_url().to_string();
                    context.cwd = Arc::new(UnsafeCell::new(unsafe { (*context.cwd.get()).clone() }));

                    unsafe { context.unmap() };

                    let mut image = ContextZone::new(CONTEXT_IMAGE_ADDR, CONTEXT_IMAGE_SIZE);
                    image.memory = memory;

                    context.image = Arc::new(UnsafeCell::new(image));
                    context.heap = Arc::new(UnsafeCell::new(ContextZone::new(CONTEXT_HEAP_ADDR, CONTEXT_HEAP_SIZE)));
                    context.mmap = Arc::new(UnsafeCell::new(ContextZone::new(CONTEXT_MMAP_ADDR, CONTEXT_MMAP_SIZE)));
                    context.env_vars = Arc::new(UnsafeCell::new(unsafe { (*context.env_vars.get()).clone() }));

                    unsafe { context.map() };

                    execute_thread(context.deref_mut(), entry, args);
                } else {
                    Err(Error::new(ENOEXEC))
                }
            },
            Err(msg) => {
                debugln!("execute: failed to exec '{:?}': {}", url, msg);
                Err(Error::new(ENOEXEC))
            }
        }
    }
}
<commit_msg>Remove zeroing of BSS - redundant<commit_after>use alloc::arc::Arc;

use arch::context::{CONTEXT_IMAGE_ADDR, CONTEXT_IMAGE_SIZE, CONTEXT_HEAP_ADDR, CONTEXT_HEAP_SIZE,
                    CONTEXT_MMAP_ADDR, CONTEXT_MMAP_SIZE, CONTEXT_STACK_SIZE, CONTEXT_STACK_ADDR,
                    context_switch, context_userspace, Context, ContextMemory, ContextZone};
use arch::elf::Elf;
use arch::memory;
use arch::regs::Regs;

use collections::string::{String, ToString};
use collections::vec::Vec;

use common::slice::GetSlice;

use core::cell::UnsafeCell;
use core::ops::DerefMut;
use core::{mem, ptr, str};

use fs::Url;

use system::error::{Error, Result, ENOEXEC};

pub fn execute_thread(context_ptr: *mut Context, entry: usize, mut args: Vec<String>) -> ! {
    Context::spawn("kexec".to_string(), box move || {
        let context = unsafe { &mut *context_ptr };

        let mut context_args: Vec<usize> = Vec::new();
        context_args.push(0); // ENVP
        context_args.push(0); // ARGV NULL
        let mut argc = 0;
        while let Some(mut arg) = args.pop() {
            if ! arg.ends_with('\0') {
                arg.push('\0');
            }

            let mut physical_address = arg.as_ptr() as usize;
            if physical_address >= 0x80000000 {
                physical_address -= 0x80000000;
            }

            let virtual_address = unsafe { (*context.image.get()).next_mem() };
            let virtual_size = arg.len();

            mem::forget(arg);

            unsafe {
                (*context.image.get()).memory.push(ContextMemory {
                    physical_address: physical_address,
                    virtual_address: virtual_address,
                    virtual_size: virtual_size,
                    writeable: false,
                    allocated: true,
                });
            }

            context_args.push(virtual_address as usize);
            argc += 1;
        }
        context_args.push(argc);

        context.iopl = 0;

        context.regs = Regs::default();
        context.regs.sp = context.kernel_stack + CONTEXT_STACK_SIZE - 128;

        context.stack = Some(ContextMemory {
            physical_address: unsafe { memory::alloc_aligned(CONTEXT_STACK_SIZE, 4096) },
            virtual_address: CONTEXT_STACK_ADDR,
            virtual_size: CONTEXT_STACK_SIZE,
            writeable: true,
            allocated: true,
        });

        let user_sp = if let Some(ref stack) = context.stack {
            let mut sp = stack.physical_address + stack.virtual_size - 128;
            for arg in context_args.iter() {
                sp -= mem::size_of::<usize>();
                unsafe { ptr::write(sp as *mut usize, *arg) };
            }
            sp - stack.physical_address + stack.virtual_address
        } else {
            0
        };

        unsafe {
            context.push(0x20 | 3);
            context.push(user_sp);
            context.push(1 << 9);
            context.push(0x18 | 3);
            context.push(entry);
            context.push(context_userspace as usize);
        }

        if let Some(vfork) = context.vfork.take() {
            unsafe { (*vfork).blocked = false; }
        }
    });

    loop {
        unsafe { context_switch() };
    }
}

/// Execute an executable
pub fn execute(mut args: Vec<String>) -> Result<usize> {
    let contexts = ::env().contexts.lock();
    let current = try!(contexts.current());

    let mut vec: Vec<u8> = Vec::new();

    let path = current.canonicalize(args.get(0).map_or("", |p| &p));
    let mut url = try!(Url::from_str(&path)).to_cow();
    {
        let mut resource = if let Ok(resource) = url.as_url().open() {
            resource
        } else {
            let path = "file:/bin/".to_string() + args.get(0).map_or("", |p| &p);
            url = try!(Url::from_str(&path)).to_owned().into_cow();
            try!(url.as_url().open())
        };

        'reading: loop {
            let mut bytes = [0; 4096];
            match resource.read(&mut bytes) {
                Ok(0) => break 'reading,
                Ok(count) => vec.extend_from_slice(bytes.get_slice(.. count)),
                Err(err) => return Err(err)
            }
        }
    }

    if vec.starts_with(b"#!") {
        if let Some(mut arg) = args.get_mut(0) {
            *arg = url.as_url().to_string();
        }

        let line = unsafe { str::from_utf8_unchecked(&vec[2..]) }.lines().next().unwrap_or("");
        let mut i = 0;
        for arg in line.trim().split(' ') {
            if ! arg.is_empty() {
                args.insert(i, arg.to_string());
                i += 1;
            }
        }
        if i == 0 {
            args.insert(i, "/bin/sh".to_string());
        }
        execute(args)
    } else {
        match Elf::from(&vec) {
            Ok(executable) => {
                let entry = unsafe { executable.entry() };
                let mut memory = Vec::new();
                unsafe {
                    for segment in executable.load_segment().iter() {
                        let virtual_address = segment.vaddr as usize;
                        let virtual_size = segment.mem_len as usize;

                        let offset = virtual_address % 4096;

                        let physical_address = memory::alloc_aligned(virtual_size + offset, 4096);

                        if physical_address > 0 {
                            //TODO: Use paging to fix collisions
                            // Copy progbits
                            ::memcpy((physical_address + offset) as *mut u8,
                                     (executable.data.as_ptr() as usize + segment.off as usize) as *const u8,
                                     segment.file_len as usize);

                            memory.push(ContextMemory {
                                physical_address: physical_address,
                                virtual_address: virtual_address - offset,
                                virtual_size: virtual_size + offset,
                                writeable: segment.flags & 2 == 2,
                                allocated: true,
                            });
                        }
                    }
                }

                if entry > 0 && ! memory.is_empty() {
                    let mut contexts = ::env().contexts.lock();
                    let mut context = try!(contexts.current_mut());

                    //debugln!("{}: {}: execute {}", context.pid, context.name, url.string);

                    context.name = url.as_url().to_string();
                    context.cwd = Arc::new(UnsafeCell::new(unsafe { (*context.cwd.get()).clone() }));

                    unsafe { context.unmap() };

                    let mut image = ContextZone::new(CONTEXT_IMAGE_ADDR, CONTEXT_IMAGE_SIZE);
                    image.memory = memory;

                    context.image = Arc::new(UnsafeCell::new(image));
                    context.heap = Arc::new(UnsafeCell::new(ContextZone::new(CONTEXT_HEAP_ADDR, CONTEXT_HEAP_SIZE)));
                    context.mmap = Arc::new(UnsafeCell::new(ContextZone::new(CONTEXT_MMAP_ADDR, CONTEXT_MMAP_SIZE)));
                    context.env_vars = Arc::new(UnsafeCell::new(unsafe { (*context.env_vars.get()).clone() }));

                    unsafe { context.map() };

                    execute_thread(context.deref_mut(), entry, args);
                } else {
                    Err(Error::new(ENOEXEC))
                }
            },
            Err(msg) => {
                debugln!("execute: failed to exec '{:?}': {}", url, msg);
                Err(Error::new(ENOEXEC))
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example for getting the user locale<commit_after>extern crate locale_config;

pub fn main() {
    println!("{}", locale_config::Locale::user_default());
}
<|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.

//! Global initialization and retreival of command line arguments.
//!
//! On some platforms these are stored during runtime startup,
//! and on some they are retrieved from the system on demand.

#![allow(dead_code)] // runtime init functions not used during testing

use ffi::OsString;
use marker::PhantomData;
use vec;

/// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }

/// One-time global cleanup.
pub unsafe fn cleanup() { imp::cleanup() }

/// Returns the command line arguments
pub fn args() -> Args {
    imp::args()
}

pub struct Args {
    iter: vec::IntoIter<OsString>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> { self.iter.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.iter.len() }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
}

mod imp {
    use os::unix::prelude::*;
    use mem;
    use ffi::OsString;
    use marker::PhantomData;
    use slice;
    use str;
    use super::Args;

    use sys_common::mutex::Mutex;

    static mut GLOBAL_ARGS_PTR: usize = 0;
    static LOCK: Mutex = Mutex::new();

    pub unsafe fn init(argc: isize, argv: *const *const u8) {
        let mut args: Vec<Vec<u8>> = Vec::new();
        for i in 0..argc {
            let len = *(argv.offset(i * 2)) as usize;
            let ptr = *(argv.offset(i * 2 + 1));
            args.push(slice::from_raw_parts(ptr, len).to_vec());
        }

        LOCK.lock();
        let ptr = get_global_ptr();
        assert!((*ptr).is_none());
        (*ptr) = Some(box args);
        LOCK.unlock();
    }

    pub unsafe fn cleanup() {
        LOCK.lock();
        *get_global_ptr() = None;
        LOCK.unlock();
    }

    pub fn args() -> Args {
        let bytes = clone().unwrap_or(Vec::new());
        let v: Vec<OsString> = bytes.into_iter().map(|v| {
            OsStringExt::from_vec(v)
        }).collect();
        Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
    }

    fn clone() -> Option<Vec<Vec<u8>>> {
        unsafe {
            LOCK.lock();
            let ptr = get_global_ptr();
            let ret = (*ptr).as_ref().map(|s| (**s).clone());
            LOCK.unlock();
            return ret
        }
    }

    fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
        unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
    }

}
<commit_msg>Fix arguments on Redox<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.

//! Global initialization and retreival of command line arguments.
//!
//! On some platforms these are stored during runtime startup,
//! and on some they are retrieved from the system on demand.

#![allow(dead_code)] // runtime init functions not used during testing

use ffi::OsString;
use marker::PhantomData;
use vec;

/// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) { imp::init(argc, argv) }

/// One-time global cleanup.
pub unsafe fn cleanup() { imp::cleanup() }

/// Returns the command line arguments
pub fn args() -> Args {
    imp::args()
}

pub struct Args {
    iter: vec::IntoIter<OsString>,
    _dont_send_or_sync_me: PhantomData<*mut ()>,
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> { self.iter.next() }
    fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.iter.len() }
}

impl DoubleEndedIterator for Args {
    fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
}

mod imp {
    use os::unix::prelude::*;
    use mem;
    use ffi::{CStr, OsString};
    use marker::PhantomData;
    use libc;
    use super::Args;

    use sys_common::mutex::Mutex;

    static mut GLOBAL_ARGS_PTR: usize = 0;
    static LOCK: Mutex = Mutex::new();

    pub unsafe fn init(argc: isize, argv: *const *const u8) {
        let args = (0..argc).map(|i| {
            CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec()
        }).collect();

        LOCK.lock();
        let ptr = get_global_ptr();
        assert!((*ptr).is_none());
        (*ptr) = Some(box args);
        LOCK.unlock();
    }

    pub unsafe fn cleanup() {
        LOCK.lock();
        *get_global_ptr() = None;
        LOCK.unlock();
    }

    pub fn args() -> Args {
        let bytes = clone().unwrap_or(Vec::new());
        let v: Vec<OsString> = bytes.into_iter().map(|v| {
            OsStringExt::from_vec(v)
        }).collect();
        Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
    }

    fn clone() -> Option<Vec<Vec<u8>>> {
        unsafe {
            LOCK.lock();
            let ptr = get_global_ptr();
            let ret = (*ptr).as_ref().map(|s| (**s).clone());
            LOCK.unlock();
            return ret
        }
    }

    fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
        unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
    }

}
<|endoftext|>


<commit_before><commit_msg>Fix simpleservo build<commit_after><|endoftext|>


<commit_before><commit_msg>single-threaded motifs<commit_after>extern crate graph_map;

use std::sync::Arc;
use graph_map::GraphMMap;

struct GraphMap {
    map: GraphMMap,
    reverse: Vec<u32>,
}

impl GraphMap {
    pub fn new(filename: &str) -> Self {

        let map = GraphMMap::new(filename);

        let mut reverse = vec![0; map.nodes()];
        for node in 0 .. map.nodes() {
            for &neighbor in map.edges(node) {
                if (neighbor as usize) < node {
                    reverse[node] += 1;
                }
                if (neighbor as usize) == node {
                    panic!("self-loop");
                }
            }
        }

        GraphMap {
            map: map,
            reverse: reverse,
        }
    }

    #[inline(always)]
    pub fn nodes(&self) -> u32 { self.map.nodes() as u32 }
    #[inline(always)]
    pub fn edges(&self, node: u32) -> &[u32] { self.map.edges(node as usize) }
    #[inline(always)]
    pub fn forward(&self, node: u32) -> &[u32] {
        &self.edges(node)[(self.reverse[node as usize] as usize)..]
    }
}

fn sum_sequential<F: Fn(&GraphMap, u32, u32)->usize>(graph: &Arc<GraphMap>, peers: u32, logic: F) -> (usize, ::std::time::Duration) {
    let mut sum = 0;
    let mut max_time = Default::default();
    for index in 0 .. peers {
        let timer = ::std::time::Instant::now();
        sum += logic(&*graph, index, peers);
        let elapsed = timer.elapsed();
        if max_time < elapsed { max_time = elapsed; }
    }
    (sum, max_time)
}

fn sum_parallel<F: Fn(&GraphMap, u32, u32)->usize+Sync+Send+'static>(graph: &Arc<GraphMap>, peers: u32, logic: F) -> (usize, ::std::time::Duration) {
    let logic = Arc::new(logic);
    let timer = ::std::time::Instant::now();
    let mut handles = Vec::new();
    for index in 0 .. peers {
        let graph = graph.clone();
        let logic = logic.clone();
        handles.push(::std::thread::spawn(move || { (*logic)(&*graph, index, peers) }));
    }
    let sum: usize = handles.into_iter().map(|h| h.join().unwrap()).sum();
    (sum, timer.elapsed())
}

fn main () {

    let source = std::env::args().nth(1).unwrap();
    let threads = std::env::args().nth(2).unwrap().parse::<u32>().unwrap();

    let graph = ::std::sync::Arc::new(GraphMap::new(&source));

    let edges: usize = (0 .. graph.nodes()).map(|i| graph.edges(i).len()).sum();
    println!("graph loaded: {:?} nodes, {:?} edges", graph.nodes(), edges);

    // Triange measurements
    let (count, time) = sum_parallel(&graph, threads, q0);
    // let (count, time) = sum_sequential(&graph, threads, q0);
    println!("{:?}\tq0: {:?}", time, count);

    // Four-cycle measurements
    let (count, time) = sum_parallel(&graph, threads, q1);
    // let (count, time) = sum_sequential(&graph, threads, q1);
    println!("{:?}\tq1: {:?}", time, count);

    // 2-strut measurements
    let (count, time) = sum_parallel(&graph, threads, q2);
    // let (count, time) = sum_sequential(&graph, threads, q2);
    println!("{:?}\tq2: {:?}", time, count);

    // 2-strut measurements
    let (count, time) = sum_parallel(&graph, threads, q2_star);
    // let (count, time) = sum_sequential(&graph, threads, q2_star);
    println!("{:?}\tq2*: {:?}", time, count);

    // Four-clique measurements
    let (count, time) = sum_parallel(&graph, threads, q3);
    // let (count, time) = sum_sequential(&graph, threads, q3);
    println!("{:?}\tq3: {:?}", time, count);

    // Fan measurements
    let (count, time) = sum_parallel(&graph, threads, q5_star);
    // let (count, time) = sum_sequential(&graph, threads, q5_star);
    println!("{:?}\tq5*: {:?}", time, count);

    // Four-clique with hat measurements.
    let (count, time) = sum_parallel(&graph, threads, q6);
    // let (count, time) = sum_sequential(&graph, threads, q6);
    println!("{:?}\tq6: {:?}", time, count);

    // Four-clique with hat measurements.
    let (count, time) = sum_parallel(&graph, threads, q6_star);
    // let (count, time) = sum_sequential(&graph, threads, q6_star);
    println!("{:?}\tq6*: {:?}", time, count);

    // Five-clique measurements.
    let (count, time) = sum_parallel(&graph, threads, q7);
    // let (count, time) = sum_sequential(&graph, threads, q7);
    println!("{:?}\tq7: {:?}", time, count);
}

/// Q0: Triangle
///
/// Q0(a,b,c) := a ~ b, b ~ c, a ~ c, a < b, b < c
fn q0(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for (index_v2, &v2) in v1f.iter().enumerate() {
            intersect_and(&v1f[(index_v2+1)..], graph.forward(v2), |v3| if v3 != u32::max_value() { count += 1 });
        }
        v1 += peers;
    }
    count
}

/// Q1: Four-cycle
fn q1(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for (index_v2, &v2) in v1f.iter().enumerate() {
            let v2e = gallop_gt(graph.edges(v2), &v1);
            for &v4 in v1f[(index_v2 + 1)..].iter() {
                let v4e = gallop_gt(graph.edges(v4), &v1);
                intersect_and(v2e, v4e, |v3| if v3 != u32::max_value() { count += 1 });
            }
        }
        v1 += peers;
    }
    count
}

/// Q2: 2-Strut
fn q2(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix = Vec::new();
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for &v3 in v1f.iter() {
            intersect_and(graph.edges(v1), graph.edges(v3), |x| prefix.push(x));
            // count += (prefix.len() * (prefix.len() - 1)) / 2;
            for (index_v2, &_v2) in prefix.iter().enumerate() {
                for &v4 in prefix[(index_v2 + 1)..].iter() {
                    if _v2 != u32::max_value() && v4 != u32::max_value() { count += 1 }
                 }
            }
            prefix.clear();
        }
        v1 += peers;
    }
    count
}

/// Q2*: 2-Strut
fn q2_star(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix = Vec::new();
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for &v3 in v1f.iter() {
            intersect_and(graph.edges(v1), graph.edges(v3), |x| prefix.push(x));
            count += (prefix.len() * (prefix.len() - 1)) / 2;
            prefix.clear();
        }
        v1 += peers;
    }
    count
}

// Q3: Four-clique
fn q3(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix = Vec::new();
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for (index_v2, &v2) in v1f.iter().enumerate() {
            intersect_and(&v1f[(index_v2 + 1)..], graph.forward(v2), |v3| prefix.push(v3));
            for (index_v3, &v3) in prefix.iter().enumerate() {
                intersect_and(&prefix[(index_v3 + 1)..], graph.forward(v3), |v4| if v4 != u32::max_value() { count += 1 });
            }
            prefix.clear();
        }
        v1 += peers;
    }
    count
}

/// Q5*: Fan
fn q5_star(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let count = 0;
    let mut tris = Vec::new();
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1e = graph.edges(v1);
        for (index_b, &b) in v1e.iter().enumerate() {
            intersect_and(&v1e[(index_b + 1)..], graph.forward(b), |c| tris.push((b, c)));
        }
        // enumerate 4-paths in `tris`.
        tris.clear();
        v1 += peers;
    }
    count
}

/// Q6: Four-clique with hat
fn q6(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix = Vec::new();
    let mut v2 = index;
    while v2 < graph.nodes() {
        let v2f = graph.forward(v2);
        for &v5 in v2f.iter() {
            intersect_and(graph.edges(v2), graph.edges(v5), |x| prefix.push(x));
            for (index_v3, &v3) in prefix.iter().enumerate() {
                intersect_and(&prefix[(index_v3 + 1)..], graph.forward(v3), |v4| {
                    for &v5 in prefix.iter() {
                        if v5 != v3 && v5 != v4 {
                            count += 1;
                        }
                    }
                });
            }
            prefix.clear();
        }
        v2 += peers;
    }
    count
}

/// Q6: Four-clique with hat
fn q6_star(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix = Vec::new();
    let mut v2 = index;
    while v2 < graph.nodes() {
        let v2f = graph.forward(v2);
        for &v5 in v2f.iter() {
            intersect_and(graph.edges(v2), graph.edges(v5), |x| prefix.push(x));
            for (index_v3, &v3) in prefix.iter().enumerate() {
                intersect_and(&prefix[(index_v3 + 1)..], graph.forward(v3), |_v4| {
                    count += prefix.len() - 2;
                });
            }
            prefix.clear();
        }
        v2 += peers;
    }
    count
}

// Q7: Five-clique
fn q7(graph: &GraphMap, index: u32, peers: u32) -> usize {
    let mut count = 0;
    let mut prefix1 = Vec::new();
    let mut prefix2 = Vec::new();
    let mut v1 = index;
    while v1 < graph.nodes() {
        let v1f = graph.forward(v1);
        for (index_v2, &v2) in v1f.iter().enumerate() {
            intersect_and(&v1f[(index_v2 + 1)..], graph.forward(v2), |v3| prefix1.push(v3));
            for (index_v3, &v3) in prefix1.iter().enumerate() {
                intersect_and(&prefix1[(index_v3 + 1)..], graph.forward(v3), |v4| prefix2.push(v4));
                for (index_v4, &v4) in prefix2.iter().enumerate() {
                    intersect_and(&prefix2[(index_v4 + 1)..], graph.forward(v4), |v5| if v5 != u32::max_value() { count += 1 });
                }
                prefix2.clear();
            }
            prefix1.clear();
        }
        v1 += peers;
    }
    count
}

// fn intersect_many_into(lists: &mut [&[u32]], dest: &mut Vec<u32>) {
//     if lists.len() > 0 {
//         lists.sort_by(|x,y| x.len().cmp(&y.len()));
//         dest.extend_from_slice(lists[0]);
//         let mut lists = &lists[1..];
//         while lists.len() > 0 {
//             let (head, tail) = lists.split_at(1);
//             restrict(dest, head[0]);
//             lists = tail;
//         }
//     }
// }

// fn restrict(aaa: &mut Vec<u32>, mut bbb: &[u32]) {
//
//     let mut cursor = 0;
//     if aaa.len() < bbb.len() / 16 {
//         for index in 0 .. aaa.len() {
//             bbb = gallop(bbb, &aaa[index]);
//             if bbb.len() > 0 && bbb[0] == aaa[index] {
//                 aaa[cursor] = aaa[index];
//                 cursor += 1;
//             }
//         }
//     }
//     else {
//         let mut index = 0;
//         while index < aaa.len() {
//             while bbb.len() > 0 && bbb[0] < aaa[index] {
//                 bbb = &bbb[1..];
//             }
//             if bbb.len() > 0 && aaa[index] == bbb[0] {
//                 aaa[cursor] = aaa[index];
//                 cursor += 1;
//             }
//             index += 1;
//         }
//     }
//     aaa.truncate(cursor);
// }

fn intersect_and<F: FnMut(u32)>(aaa: &[u32], mut bbb: &[u32], mut func: F) {

    if aaa.len() > bbb.len() {
        intersect_and(bbb, aaa, func);
    }
    else {
        if aaa.len() < bbb.len() / 16 {
            for &a in aaa.iter() {
                bbb = gallop_ge(bbb, &a);
                if bbb.len() > 0 && bbb[0] == a {
                    func(a)
                }
            }
        }
        else {
            for &a in aaa.iter() {
                while bbb.len() > 0 && bbb[0] < a {
                    bbb = &bbb[1..];
                }
                if bbb.len() > 0 && a == bbb[0] {
                    func(a);
                }
            }
        }
    }
}

#[inline(always)]
pub fn gallop_ge<'a, T: Ord>(mut slice: &'a [T], value: &T) -> &'a [T] {
    // if empty slice, or already >= element, return
    if slice.len() > 0 && &slice[0] < value {
        let mut step = 1;
        while step < slice.len() && &slice[step] < value {
            slice = &slice[step..];
            step = step << 1;
        }

        step = step >> 1;
        while step > 0 {
            if step < slice.len() && &slice[step] < value {
                slice = &slice[step..];
            }
            step = step >> 1;
        }

        slice = &slice[1..]; // advance one, as we always stayed < value
    }

    return slice;
}

#[inline(always)]
pub fn gallop_gt<'a, T: Ord>(mut slice: &'a [T], value: &T) -> &'a [T] {
    // if empty slice, or already > element, return
    if slice.len() > 0 && &slice[0] <= value {
        let mut step = 1;
        while step < slice.len() && &slice[step] <= value {
            slice = &slice[step..];
            step = step << 1;
        }

        step = step >> 1;
        while step > 0 {
            if step < slice.len() && &slice[step] <= value {
                slice = &slice[step..];
            }
            step = step >> 1;
        }

        slice = &slice[1..]; // advance one, as we always stayed <= value
    }

    return slice;
}
<|endoftext|>


<commit_before><commit_msg>Add 2015 day 21 part 1 solution<commit_after>use std::cmp;
use ItemCategory::*;

struct Character {
    hp: i32,
    damage: i32,
    armor: i32
}

impl Character {
    fn new(hp: i32) -> Character {
        Character {hp, damage: 0, armor: 0}
    }
}

#[derive(Debug, PartialEq)]
enum ItemCategory {
    Weapon,
    Armor,
    Ring
}

#[derive(Debug)]
struct Item {
    category: ItemCategory,
    cost: i32,
    damage: i32,
    armor: i32
}

fn get_damage(attacker: &Character, defender: &Character) -> i32 {
    cmp::max(attacker.damage - defender.armor, 1)
}

fn is_winner<'a>(player: &'a Character, target: &'a Character) -> bool {
    let player_damage = get_damage(player, target);
    let target_damage = get_damage(target, player);
    let player_turns = (player.hp as f32 / target_damage as f32).ceil();
    let target_turns = (target.hp as f32 / player_damage as f32).ceil();

    target_turns <= player_turns
}

fn get_item_combinations<'a>(items: &'a Vec<&'a Item>) -> Vec<Vec<&'a Item>> {
    let weapons = items.iter().filter(|x| x.category == Weapon).collect::<Vec<_>>();
    let armors = items.iter().filter(|x| x.category == Armor).collect::<Vec<_>>();
    let rings = items.iter().filter(|x| x.category == Ring).collect::<Vec<_>>();
    let mut choices = Vec::new();

    for &&weapon in weapons.iter() {
        choices.push(vec![weapon]);

        for &&armor in armors.iter() {
            choices.push(vec![weapon, armor]);

            for i in 0..rings.len() {
                choices.push(vec![weapon, *rings[i]]);
                choices.push(vec![weapon, armor, *rings[i]]);

                for j in i + 1..rings.len() {
                    choices.push(vec![weapon, *rings[i], *rings[j]]);
                    choices.push(vec![weapon, armor, *rings[i], *rings[j]]);
                }
            }
        }
    }

    choices
}

fn get_character(hp: i32, items: &Vec<&Item>) -> Character {
    items.iter().fold(Character::new(hp), |mut character, item| {
        character.damage += item.damage;
        character.armor += item.armor;
        character
    })
}

fn get_winning_items<'a>(
    items: &'a Vec<&'a Item>,
    hp: i32,
    target: &Character
) -> Option<Vec<&'a Item>> {
    get_item_combinations(items).into_iter()
    .filter(|combination| {
        is_winner(&get_character(hp, combination), target)
    })
    .min_by_key(|combination| {
        combination.iter()
            .map(|item| item.cost)
            .sum::<i32>()
    })
}

fn main() {
    let items = vec![
        Item {
            category: Weapon,
            cost: 8,
            damage: 4,
            armor: 0
        },
        Item {
            category: Weapon,
            cost: 10,
            damage: 5,
            armor: 0
        },
        Item {
            category: Weapon,
            cost: 25,
            damage: 6,
            armor: 0
        },
        Item {
            category: Weapon,
            cost: 40,
            damage: 7,
            armor: 0
        },
        Item {
            category: Weapon,
            cost: 74,
            damage: 8,
            armor: 0
        },
        Item {
            category: Armor,
            cost: 13,
            damage: 0,
            armor: 1
        },
        Item {
            category: Armor,
            cost: 31,
            damage: 0,
            armor: 2
        },
        Item {
            category: Armor,
            cost: 53,
            damage: 0,
            armor: 3
        },
        Item {
            category: Armor,
            cost: 75,
            damage: 0,
            armor: 4
        },
        Item {
            category: Armor,
            cost: 102,
            damage: 0,
            armor: 5
        },
        Item {
            category: Ring,
            cost: 25,
            damage: 1,
            armor: 0
        },
        Item {
            category: Ring,
            cost: 50,
            damage: 2,
            armor: 0
        },
        Item {
            category: Ring,
            cost: 100,
            damage: 3,
            armor: 0
        },
        Item {
            category: Ring,
            cost: 20,
            damage: 0,
            armor: 1
        },
        Item {
            category: Ring,
            cost: 40,
            damage: 0,
            armor: 2
        },
        Item {
            category: Ring,
            cost: 80,
            damage: 0,
            armor: 3
        }
    ];

    let boss = Character {
        hp: 100,
        damage: 8,
        armor: 2
    };

    let items = items.iter().collect();

    let combinations = get_winning_items(&items, 100, &boss).unwrap();
    println!("{:#?}", combinations);
}
<|endoftext|>


<commit_before><commit_msg>fix: Removes unimplemented! from LDR/STR<commit_after><|endoftext|>