<commit_before>#[doc="Fundamental layout structures and algorithms."]

import dom::base::{Element, ElementKind, HTMLDivElement, HTMLImageElement, Node, NodeData};
import dom::base::{NodeKind};
import dom::rcu;
import dom::style::Unit;
import gfx::geometry;
import gfx::geometry::{au, zero_size_au};
import geom::point::Point2D;
import geom::rect::Rect;
import geom::size::Size2D;
import image::base::Image;
import util::tree;
import util::color::Color;
import text::TextBox;
import traverse::extended_full_traversal;
import style::style::{SpecifiedStyle};
import vec::{push, push_all};
import std::net::url::Url;
import resource::image_cache_task;
import image_cache_task::ImageCacheTask;
import core::to_str::ToStr;
import std::arc::{ARC, clone};
import task::spawn;

enum BoxKind {
    BlockBox,
    InlineBox,
    IntrinsicBox(@Size2D<au>),
    TextBoxKind(@TextBox)
}

impl BoxKind : cmp::Eq {
    pure fn eq(&&other: BoxKind) -> bool {
        match (self, other) {
          (BlockBox, BlockBox) => true,
          _ => fail ~"unimplemented case in BoxKind.eq"
        }
    }
}

struct Appearance {
    let mut background_image: Option<ImageHolder>;
    let mut background_color: Color;
    let mut width: Unit;
    let mut height: Unit;

    new(kind: NodeKind) {
        self.background_image = None;
        self.background_color = kind.default_color();
        self.width = kind.default_width();
        self.height = kind.default_height();
    }

    // This will be very unhappy if it is getting run in parallel with
    // anything trying to read the background image
    fn get_image() -> Option<~ARC<~Image>> {
        let mut image = None;

        // Do a dance where we swap the ImageHolder out before we can
        // get the image out of it because we can't match against it
        // because holder.get_image() is not pure.
        if (self.background_image).is_some() {
            let mut temp = None;
            temp <-> self.background_image;
            let holder <- option::unwrap(temp);
            image = holder.get_image();
            self.background_image = Some(holder);
        }

        return image;
    }
}

struct Box {
    let tree: tree::Tree<@Box>;
    let node: Node;
    let kind: BoxKind;
    let mut bounds: Rect<au>;
    let appearance: Appearance;

    new(node: Node, kind: BoxKind) {
        self.appearance = node.read(|n| Appearance(*n.kind));
        self.tree = tree::empty();
        self.node = node;
        self.kind = kind;
        self.bounds = geometry::zero_rect_au();
    }
}

#[doc="A struct to store image data.  The image will be loaded once,
 the first time it is requested, and an arc will be stored.  Clones of
 this arc are given out on demand."]
struct ImageHolder {
    // Invariant: at least one of url and image is not none, except
    // occasionally while get_image is being called
    let mut url : Option<Url>;
    let mut image : Option<ARC<~Image>>;
    let image_cache_task: ImageCacheTask;
    let reflow: fn~();

    new(-url : Url, image_cache_task: ImageCacheTask, reflow: fn~()) {
        self.url = Some(copy url);
        self.image = None;
        self.image_cache_task = image_cache_task;
        self.reflow = copy reflow;

        // Tell the image cache we're going to be interested in this url
        // FIXME: These two messages must be sent to prep an image for use
        // but they are intended to be spread out in time. Ideally prefetch
        // should be done as early as possible and decode only once we
        // are sure that the image will be used.
        image_cache_task.send(image_cache_task::Prefetch(copy url));
        image_cache_task.send(image_cache_task::Decode(move url));
    }

    // This function should not be called by two tasks at the same time
    fn get_image() -> Option<~ARC<~Image>> {
        // If this is the first time we've called this function, load
        // the image and store it for the future
        if self.image.is_none() {
            assert self.url.is_some();

            let mut temp = None;
            temp <-> self.url;
            let url = option::unwrap(temp);

            let response_port = Port();
            self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan()));
            self.image = match response_port.recv() {
              image_cache_task::ImageReady(image) => Some(clone(&image)),
              image_cache_task::ImageNotReady => {
                // Need to reflow when the image is available
                let image_cache_task = self.image_cache_task;
                let reflow = copy self.reflow;
                do spawn |copy url, move reflow| {
                    let response_port = Port();
                    image_cache_task.send(image_cache_task::WaitForImage(copy url, response_port.chan()));
                    match response_port.recv() {
                      image_cache_task::ImageReady(*) => reflow(),
                      image_cache_task::ImageNotReady => fail /*not possible*/,
                      image_cache_task::ImageFailed => ()
                    }
                }
                None
              }
              image_cache_task::ImageFailed => {
                #info("image was not ready for %s", url.to_str());
                // FIXME: Need to schedule another layout when the image is ready
                None
              }
            };
        }

        if self.image.is_some() {
            // Temporarily swap out the arc of the image so we can clone
            // it without breaking purity, then put it back and return the
            // clone.  This is not threadsafe.
            let mut temp = None;
            temp <-> self.image;
            let im_arc = option::unwrap(temp);
            self.image = Some(clone(&im_arc));

            return Some(~im_arc);
        } else {
            return None;
        }
    }
}

enum LayoutData = {
    mut specified_style: ~SpecifiedStyle,
    mut box: Option<@Box>
};

// FIXME: This is way too complex! Why do these have to have dummy receivers? --pcw

enum NTree { NTree }
impl NTree : tree::ReadMethods<Node> {
    fn each_child(node: Node, f: fn(Node) -> bool) {
        tree::each_child(self, node, f)
    }

    fn with_tree_fields<R>(&&n: Node, f: fn(tree::Tree<Node>) -> R) -> R {
        n.read(|n| f(n.tree))
    }
}

enum BTree { BTree }

impl BTree : tree::ReadMethods<@Box> {
    fn each_child(node: @Box, f: fn(&&@Box) -> bool) {
        tree::each_child(self, node, f)
    }

    fn with_tree_fields<R>(&&b: @Box, f: fn(tree::Tree<@Box>) -> R) -> R {
        f(b.tree)
    }
}

impl BTree : tree::WriteMethods<@Box> {
    fn add_child(node: @Box, child: @Box) {
        tree::add_child(self, node, child)
    }

    fn with_tree_fields<R>(&&b: @Box, f: fn(tree::Tree<@Box>) -> R) -> R {
        f(b.tree)
    }
}

impl @Box {
    #[doc="The main reflow routine."]
    fn reflow() {
        match self.kind {
            BlockBox => self.reflow_block(),
            InlineBox => self.reflow_inline(),
            IntrinsicBox(size) => self.reflow_intrinsic(*size),
            TextBoxKind(subbox) => self.reflow_text(subbox)
        }
    }

    #[doc="Dumps the box tree, for debugging, with indentation."]
    fn dump_indent(indent: uint) {
        let mut s = ~"";
        for uint::range(0u, indent) |_i| {
            s += ~"    ";
        }

        s += #fmt("%?", self.kind);
        #debug["%s", s];

        for BTree.each_child(self) |kid| {
            kid.dump_indent(indent + 1u)
        }
    }
}

#[doc = "
     Set your width to the maximum available width and return the
     maximum available width any children can use.  Currently children
     are just given the same available width.
"]
fn give_kids_width(+available_width : au, box : @Box) -> au {
    // TODO: give smaller available widths if the width of the
    // containing box is constrained
    match box.kind {
        BlockBox => box.bounds.size.width = available_width,
        InlineBox | IntrinsicBox(*) | TextBoxKind(*) => { }
    }

    available_width
}

#[doc="Wrapper around reflow so it can be passed to traverse"]
fn reflow_wrapper(b : @Box) {
    b.reflow();
}

impl @Box {
    #[doc="
           Run a parallel traversal over the layout tree rooted at
           this box.  On the top-down traversal give each box the
           available width determined by their parent and on the
           bottom-up traversal reflow each box based on their
           attributes and their children's sizes.
    "]
    fn reflow_subtree(available_width : au) {
        extended_full_traversal(self, available_width, give_kids_width, reflow_wrapper);
    }

    #[doc="The trivial reflow routine for instrinsically-sized frames."]
    fn reflow_intrinsic(size: Size2D<au>) {
        self.bounds.size = copy size;

        #debug["reflow_intrinsic size=%?", copy self.bounds];
    }

    #[doc="Dumps the box tree, for debugging."]
    fn dump() {
        self.dump_indent(0u);
    }
}

// Debugging

trait PrivateNodeMethods{
    fn dump_indent(ident: uint);
}

impl Node : PrivateNodeMethods {
    #[doc="Dumps the node tree, for debugging, with indentation."]
    fn dump_indent(indent: uint) {
        let mut s = ~"";
        for uint::range(0u, indent) |_i| {
            s += ~"    ";
        }

        s += #fmt("%?", self.read(|n| copy n.kind ));
        #debug["%s", s];

        for NTree.each_child(self) |kid| {
            kid.dump_indent(indent + 1u)
        }
    }
}

trait NodeMethods {
    fn dump();
}

impl Node : NodeMethods {
    #[doc="Dumps the subtree rooted at this node, for debugging."]
    fn dump() {
        self.dump_indent(0u);
    }
}

#[cfg(test)]
mod test {
    import dom::base::{Element, ElementData, HTMLDivElement, HTMLImageElement, Node, NodeKind};
    import dom::base::{NodeScope};
    import dom::rcu::Scope;

    /*
    use sdl;
    import sdl::video;

    fn with_screen(f: fn(*sdl::surface)) {
        let screen = video::set_video_mode(
            320, 200, 32,
            ~[video::hwsurface], ~[video::doublebuf]);
        assert screen != ptr::null();

        f(screen);

        video::free_surface(screen);
    }
    */

    fn flat_bounds(root: @Box) -> ~[Rect<au>] {
        let mut r = ~[];
        for tree::each_child(BTree, root) |c| {
            push_all(r, flat_bounds(c));
        }

        push(r, copy root.bounds);

        return r;
    }

    #[test]
    #[ignore(reason = "busted")]
    fn do_layout() {
        let s = Scope();

        fn mk_img(size: Size2D<au>) -> ~ElementKind {
            ~HTMLImageElement({mut size: size})
        }

        let n0 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(10))))));
        let n1 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(10))))));
        let n2 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(20))))));
        let n3 = s.new_node(Element(ElementData(~"div", ~HTMLDivElement)));

        tree::add_child(s, n3, n0);
        tree::add_child(s, n3, n1);
        tree::add_child(s, n3, n2);

        let b0 = n0.construct_boxes();
        let b1 = n1.construct_boxes();
        let b2 = n2.construct_boxes();
        let b3 = n3.construct_boxes();

        tree::add_child(BTree, b3, b0);
        tree::add_child(BTree, b3, b1);
        tree::add_child(BTree, b3, b2);

        b3.reflow_subtree(au(100));
        let fb = flat_bounds(b3);
        #debug["fb=%?", fb];
        assert fb == ~[geometry::box(au(0), au(0), au(10), au(10)),   // n0
                       geometry::box(au(0), au(10), au(10), au(15)),  // n1
                       geometry::box(au(0), au(25), au(10), au(20)),  // n2
                       geometry::box(au(0), au(0), au(100), au(45))]; // n3
    }
}

<commit_msg>Add missing case to BoxKind : Eq<commit_after>#[doc="Fundamental layout structures and algorithms."]

import dom::base::{Element, ElementKind, HTMLDivElement, HTMLImageElement, Node, NodeData};
import dom::base::{NodeKind};
import dom::rcu;
import dom::style::Unit;
import gfx::geometry;
import gfx::geometry::{au, zero_size_au};
import geom::point::Point2D;
import geom::rect::Rect;
import geom::size::Size2D;
import image::base::Image;
import util::tree;
import util::color::Color;
import text::TextBox;
import traverse::extended_full_traversal;
import style::style::{SpecifiedStyle};
import vec::{push, push_all};
import std::net::url::Url;
import resource::image_cache_task;
import image_cache_task::ImageCacheTask;
import core::to_str::ToStr;
import std::arc::{ARC, clone};
import task::spawn;

enum BoxKind {
    BlockBox,
    InlineBox,
    IntrinsicBox(@Size2D<au>),
    TextBoxKind(@TextBox)
}

impl BoxKind : cmp::Eq {
    pure fn eq(&&other: BoxKind) -> bool {
        match (self, other) {
          (BlockBox, BlockBox) => true,
          (InlineBox, InlineBox) => true,
          _ => fail ~"unimplemented case in BoxKind.eq"
        }
    }
}

struct Appearance {
    let mut background_image: Option<ImageHolder>;
    let mut background_color: Color;
    let mut width: Unit;
    let mut height: Unit;

    new(kind: NodeKind) {
        self.background_image = None;
        self.background_color = kind.default_color();
        self.width = kind.default_width();
        self.height = kind.default_height();
    }

    // This will be very unhappy if it is getting run in parallel with
    // anything trying to read the background image
    fn get_image() -> Option<~ARC<~Image>> {
        let mut image = None;

        // Do a dance where we swap the ImageHolder out before we can
        // get the image out of it because we can't match against it
        // because holder.get_image() is not pure.
        if (self.background_image).is_some() {
            let mut temp = None;
            temp <-> self.background_image;
            let holder <- option::unwrap(temp);
            image = holder.get_image();
            self.background_image = Some(holder);
        }

        return image;
    }
}

struct Box {
    let tree: tree::Tree<@Box>;
    let node: Node;
    let kind: BoxKind;
    let mut bounds: Rect<au>;
    let appearance: Appearance;

    new(node: Node, kind: BoxKind) {
        self.appearance = node.read(|n| Appearance(*n.kind));
        self.tree = tree::empty();
        self.node = node;
        self.kind = kind;
        self.bounds = geometry::zero_rect_au();
    }
}

#[doc="A struct to store image data.  The image will be loaded once,
 the first time it is requested, and an arc will be stored.  Clones of
 this arc are given out on demand."]
struct ImageHolder {
    // Invariant: at least one of url and image is not none, except
    // occasionally while get_image is being called
    let mut url : Option<Url>;
    let mut image : Option<ARC<~Image>>;
    let image_cache_task: ImageCacheTask;
    let reflow: fn~();

    new(-url : Url, image_cache_task: ImageCacheTask, reflow: fn~()) {
        self.url = Some(copy url);
        self.image = None;
        self.image_cache_task = image_cache_task;
        self.reflow = copy reflow;

        // Tell the image cache we're going to be interested in this url
        // FIXME: These two messages must be sent to prep an image for use
        // but they are intended to be spread out in time. Ideally prefetch
        // should be done as early as possible and decode only once we
        // are sure that the image will be used.
        image_cache_task.send(image_cache_task::Prefetch(copy url));
        image_cache_task.send(image_cache_task::Decode(move url));
    }

    // This function should not be called by two tasks at the same time
    fn get_image() -> Option<~ARC<~Image>> {
        // If this is the first time we've called this function, load
        // the image and store it for the future
        if self.image.is_none() {
            assert self.url.is_some();

            let mut temp = None;
            temp <-> self.url;
            let url = option::unwrap(temp);

            let response_port = Port();
            self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan()));
            self.image = match response_port.recv() {
              image_cache_task::ImageReady(image) => Some(clone(&image)),
              image_cache_task::ImageNotReady => {
                // Need to reflow when the image is available
                let image_cache_task = self.image_cache_task;
                let reflow = copy self.reflow;
                do spawn |copy url, move reflow| {
                    let response_port = Port();
                    image_cache_task.send(image_cache_task::WaitForImage(copy url, response_port.chan()));
                    match response_port.recv() {
                      image_cache_task::ImageReady(*) => reflow(),
                      image_cache_task::ImageNotReady => fail /*not possible*/,
                      image_cache_task::ImageFailed => ()
                    }
                }
                None
              }
              image_cache_task::ImageFailed => {
                #info("image was not ready for %s", url.to_str());
                // FIXME: Need to schedule another layout when the image is ready
                None
              }
            };
        }

        if self.image.is_some() {
            // Temporarily swap out the arc of the image so we can clone
            // it without breaking purity, then put it back and return the
            // clone.  This is not threadsafe.
            let mut temp = None;
            temp <-> self.image;
            let im_arc = option::unwrap(temp);
            self.image = Some(clone(&im_arc));

            return Some(~im_arc);
        } else {
            return None;
        }
    }
}

enum LayoutData = {
    mut specified_style: ~SpecifiedStyle,
    mut box: Option<@Box>
};

// FIXME: This is way too complex! Why do these have to have dummy receivers? --pcw

enum NTree { NTree }
impl NTree : tree::ReadMethods<Node> {
    fn each_child(node: Node, f: fn(Node) -> bool) {
        tree::each_child(self, node, f)
    }

    fn with_tree_fields<R>(&&n: Node, f: fn(tree::Tree<Node>) -> R) -> R {
        n.read(|n| f(n.tree))
    }
}

enum BTree { BTree }

impl BTree : tree::ReadMethods<@Box> {
    fn each_child(node: @Box, f: fn(&&@Box) -> bool) {
        tree::each_child(self, node, f)
    }

    fn with_tree_fields<R>(&&b: @Box, f: fn(tree::Tree<@Box>) -> R) -> R {
        f(b.tree)
    }
}

impl BTree : tree::WriteMethods<@Box> {
    fn add_child(node: @Box, child: @Box) {
        tree::add_child(self, node, child)
    }

    fn with_tree_fields<R>(&&b: @Box, f: fn(tree::Tree<@Box>) -> R) -> R {
        f(b.tree)
    }
}

impl @Box {
    #[doc="The main reflow routine."]
    fn reflow() {
        match self.kind {
            BlockBox => self.reflow_block(),
            InlineBox => self.reflow_inline(),
            IntrinsicBox(size) => self.reflow_intrinsic(*size),
            TextBoxKind(subbox) => self.reflow_text(subbox)
        }
    }

    #[doc="Dumps the box tree, for debugging, with indentation."]
    fn dump_indent(indent: uint) {
        let mut s = ~"";
        for uint::range(0u, indent) |_i| {
            s += ~"    ";
        }

        s += #fmt("%?", self.kind);
        #debug["%s", s];

        for BTree.each_child(self) |kid| {
            kid.dump_indent(indent + 1u)
        }
    }
}

#[doc = "
     Set your width to the maximum available width and return the
     maximum available width any children can use.  Currently children
     are just given the same available width.
"]
fn give_kids_width(+available_width : au, box : @Box) -> au {
    // TODO: give smaller available widths if the width of the
    // containing box is constrained
    match box.kind {
        BlockBox => box.bounds.size.width = available_width,
        InlineBox | IntrinsicBox(*) | TextBoxKind(*) => { }
    }

    available_width
}

#[doc="Wrapper around reflow so it can be passed to traverse"]
fn reflow_wrapper(b : @Box) {
    b.reflow();
}

impl @Box {
    #[doc="
           Run a parallel traversal over the layout tree rooted at
           this box.  On the top-down traversal give each box the
           available width determined by their parent and on the
           bottom-up traversal reflow each box based on their
           attributes and their children's sizes.
    "]
    fn reflow_subtree(available_width : au) {
        extended_full_traversal(self, available_width, give_kids_width, reflow_wrapper);
    }

    #[doc="The trivial reflow routine for instrinsically-sized frames."]
    fn reflow_intrinsic(size: Size2D<au>) {
        self.bounds.size = copy size;

        #debug["reflow_intrinsic size=%?", copy self.bounds];
    }

    #[doc="Dumps the box tree, for debugging."]
    fn dump() {
        self.dump_indent(0u);
    }
}

// Debugging

trait PrivateNodeMethods{
    fn dump_indent(ident: uint);
}

impl Node : PrivateNodeMethods {
    #[doc="Dumps the node tree, for debugging, with indentation."]
    fn dump_indent(indent: uint) {
        let mut s = ~"";
        for uint::range(0u, indent) |_i| {
            s += ~"    ";
        }

        s += #fmt("%?", self.read(|n| copy n.kind ));
        #debug["%s", s];

        for NTree.each_child(self) |kid| {
            kid.dump_indent(indent + 1u)
        }
    }
}

trait NodeMethods {
    fn dump();
}

impl Node : NodeMethods {
    #[doc="Dumps the subtree rooted at this node, for debugging."]
    fn dump() {
        self.dump_indent(0u);
    }
}

#[cfg(test)]
mod test {
    import dom::base::{Element, ElementData, HTMLDivElement, HTMLImageElement, Node, NodeKind};
    import dom::base::{NodeScope};
    import dom::rcu::Scope;

    /*
    use sdl;
    import sdl::video;

    fn with_screen(f: fn(*sdl::surface)) {
        let screen = video::set_video_mode(
            320, 200, 32,
            ~[video::hwsurface], ~[video::doublebuf]);
        assert screen != ptr::null();

        f(screen);

        video::free_surface(screen);
    }
    */

    fn flat_bounds(root: @Box) -> ~[Rect<au>] {
        let mut r = ~[];
        for tree::each_child(BTree, root) |c| {
            push_all(r, flat_bounds(c));
        }

        push(r, copy root.bounds);

        return r;
    }

    #[test]
    #[ignore(reason = "busted")]
    fn do_layout() {
        let s = Scope();

        fn mk_img(size: Size2D<au>) -> ~ElementKind {
            ~HTMLImageElement({mut size: size})
        }

        let n0 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(10))))));
        let n1 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(10))))));
        let n2 = s.new_node(Element(ElementData(~"img", mk_img(Size2D(au(10),au(20))))));
        let n3 = s.new_node(Element(ElementData(~"div", ~HTMLDivElement)));

        tree::add_child(s, n3, n0);
        tree::add_child(s, n3, n1);
        tree::add_child(s, n3, n2);

        let b0 = n0.construct_boxes();
        let b1 = n1.construct_boxes();
        let b2 = n2.construct_boxes();
        let b3 = n3.construct_boxes();

        tree::add_child(BTree, b3, b0);
        tree::add_child(BTree, b3, b1);
        tree::add_child(BTree, b3, b2);

        b3.reflow_subtree(au(100));
        let fb = flat_bounds(b3);
        #debug["fb=%?", fb];
        assert fb == ~[geometry::box(au(0), au(0), au(10), au(10)),   // n0
                       geometry::box(au(0), au(10), au(10), au(15)),  // n1
                       geometry::box(au(0), au(25), au(10), au(20)),  // n2
                       geometry::box(au(0), au(0), au(100), au(45))]; // n3
    }
}

<|endoftext|>


<commit_before><commit_msg>Add opcodes module<commit_after>pub static INT: u8 = b'I';
pub static BININT: u8 = b'J';
pub static BININT1: u8 = b'K';
pub static BININT2: u8 = b'M';
pub static LONG: u8 = b'L';
pub static LONG1: u8 = b'\x8a';
pub static LONG4: u8 = b'\x8b';
pub static MARK: u8 = b'(';
pub static STOP: u8 = b'.';
pub static POP: u8 = b'0';
pub static POP_MARK: u8 = b'1';
pub static DUP: u8 = b'2';
pub static FLOAT: u8 = b'F';
pub static BINFLOAT: u8 = b'G';
pub static NONE: u8 = b'N';
pub static PERSID: u8 = b'P';
pub static BINPERSID: u8 = b'Q';
pub static REDUCE: u8 = b'R';
pub static STRING: u8 = b'S';
pub static BINSTRING: u8 = b'T';
pub static SHORT_BINSTRING: u8 = b'U';
pub static UNICODE: u8 = b'V';
pub static BINUNICODE: u8 = b'X';
pub static APPEND: u8 = b'a';
pub static BUILD: u8 = b'b';
pub static GLOBAL: u8 = b'c';
pub static DICT: u8 = b'd';
pub static EMPTY_DICT: u8 = b'}';
pub static APPENDS: u8 = b'e';
pub static GET: u8 = b'g';
pub static BINGET: u8 = b'h';
pub static INST: u8 = b'i';
pub static LONG_BINGET: u8 = b'j';
pub static LIST: u8 = b'l';
pub static EMPTY_LIST: u8 = b']';
pub static OBJ: u8 = b'o';
pub static PUT: u8 = b'p';
pub static BINPUT: u8 = b'q';
pub static LONG_BINPUT: u8 = b'r';
pub static SETITEM: u8 = b's';
pub static TUPLE: u8 = b't';
pub static EMPTY_TUPLE: u8 = b')';
pub static SETITEMS: u8 = b'u';
pub static PROTO: u8 = b'\x80';
pub static NEWOBJ: u8 = b'\x81';
pub static EXT1: u8 = b'\x82';
pub static EXT2: u8 = b'\x83';
pub static EXT4: u8 = b'\x84';
pub static TUPLE1: u8 = b'\x85';
pub static TUPLE2: u8 = b'\x86';
pub static TUPLE3: u8 = b'\x87';
pub static NEWTRUE: u8 = b'\x88';
pub static NEWFALSE: u8 = b'\x89';
<|endoftext|>


<commit_before><commit_msg>Fix the command-line MSAA validation so that it permits only 2, 4, or 8<commit_after><|endoftext|>


<commit_before><commit_msg>Fix indexing error in collision response<commit_after><|endoftext|>


<commit_before><commit_msg>rename is_power_of_two<commit_after><|endoftext|>


<commit_before><commit_msg>fix(Usage Strings): fixes a bug ordering of elements in usage strings<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #375 - messense:messense-patch-1, r=Vinatorul<commit_after><|endoftext|>


<commit_before><commit_msg>Refactores function with new structure<commit_after><|endoftext|>


<commit_before>#![feature(libc)]
#![feature(std_misc)]
#![feature(optin_builtin_traits)]

extern crate gag;
extern crate libc;
extern crate num;
#[macro_use] extern crate enum_primitive;
extern crate termbox_sys as termbox;
#[macro_use] extern crate bitflags;

pub use self::style::{Style, RB_BOLD, RB_UNDERLINE, RB_REVERSE, RB_NORMAL};

use std::error::Error;
use std::fmt;
use std::io;
use std::char;
use std::time::duration::Duration;
use std::default::Default;

use num::FromPrimitive;
use termbox::RawEvent;
use libc::c_int;
use gag::Hold;

pub mod keyboard;
pub mod mouse;

pub use keyboard::Key;
pub use mouse::Mouse;

#[derive(Clone, Copy)]
pub enum Event {
    KeyEventRaw(u8, u16, u32),
    KeyEvent(Option<Key>),
    ResizeEvent(i32, i32),
    MouseEvent(Mouse, i32, i32),
    NoEvent
}

bitflags! {
    #[derive(Debug)]
    flags InputMode: u16 {
        const RB_INPUT_CURRENT = 0x00,
        /// When ESC sequence is in the buffer and it doesn't match any known
        /// ESC sequence => ESC means TB_KEY_ESC
        const RB_INPUT_ESC     = 0x01,
        /// When ESC sequence is in the buffer and it doesn't match any known
        /// sequence => ESC enables TB_MOD_ALT modifier for the next keyboard event.
        const RB_INPUT_ALT     = 0x02,
        /// Enables mouse input
        const RB_INPUT_MOUSE   = 0x04
    }
}

#[derive(Clone, Copy, PartialEq)]
#[repr(C,u16)]
pub enum Color {
    Default =  0x00,
    Black =    0x01,
    Red =      0x02,
    Green =    0x03,
    Yellow =   0x04,
    Blue =     0x05,
    Magenta =  0x06,
    Cyan =     0x07,
    White =    0x08,
}

mod style {
    bitflags! {
        #[repr(C)]
        flags Style: u16 {
            const TB_NORMAL_COLOR = 0x000F,
            const RB_BOLD = 0x0100,
            const RB_UNDERLINE = 0x0200,
            const RB_REVERSE = 0x0400,
            const RB_NORMAL = 0x0000,
            const TB_ATTRIB = RB_BOLD.bits | RB_UNDERLINE.bits | RB_REVERSE.bits,
        }
    }

    impl Style {
        pub fn from_color(color: super::Color) -> Style {
            Style { bits: color as u16 & TB_NORMAL_COLOR.bits }
        }
    }
}

const NIL_RAW_EVENT: RawEvent = RawEvent { etype: 0, emod: 0, key: 0, ch: 0, w: 0, h: 0, x: 0, y: 0 };

// FIXME: Rust doesn't support this enum representation.
// #[derive(Copy,FromPrimitive,Debug)]
// #[repr(C,int)]
// pub enum EventErrorKind {
//     Error = -1,
// }
// pub type EventError = Option<EventErrorKind>;
#[allow(non_snake_case)]
pub mod EventErrorKind {
    #[derive(Clone, Copy,Debug)]
    pub struct Error;
}

pub type EventError = Option<EventErrorKind::Error>;

pub type EventResult<T> = Result<T, EventError>;

/// Unpack a RawEvent to an Event
///
/// if the `raw` parameter is true, then the Event variant will be the raw
/// representation of the event.
///     for instance KeyEventRaw instead of KeyEvent
///
/// This is useful if you want to interpret the raw event data yourself, rather
/// than having rustbox translate it to its own representation.
fn unpack_event(ev_type: c_int, ev: &RawEvent, raw: bool) -> EventResult<Event> {
    match ev_type {
        0 => Ok(Event::NoEvent),
        1 => Ok(
            if raw {
                Event::KeyEventRaw(ev.emod, ev.key, ev.ch)
            } else {
                let k = match ev.key {
                    0 => char::from_u32(ev.ch).map(|c| Key::Char(c)),
                    a => Key::from_code(a),
                };
                Event::KeyEvent(k)
            }),
        2 => Ok(Event::ResizeEvent(ev.w, ev.h)),
        3 => {
            let mouse = Mouse::from_code(ev.key).unwrap_or(Mouse::Left);
            Ok(Event::MouseEvent(mouse, ev.x, ev.y))
        }
        // FIXME: Rust doesn't support this error representation
        // res => FromPrimitive::from_int(res as isize),
        -1 => Err(Some(EventErrorKind::Error)),
        _ => Err(None)
    }
}

enum_from_primitive! {
#[derive(Clone, Copy, Debug)]
#[repr(C,isize)]
pub enum InitErrorKind {
    UnsupportedTerminal = -1,
    FailedToOpenTty = -2,
    PipeTrapError = -3,
}
}

#[derive(Debug)]
pub enum InitError {
    BufferStderrFailed(io::Error),
    AlreadyOpen,
    TermBox(Option<InitErrorKind>),
}

impl fmt::Display for InitError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}

impl Error for InitError {
    fn description(&self) -> &str {
        match *self {
            InitError::BufferStderrFailed(_) => "Could not redirect stderr",
            InitError::AlreadyOpen => "RustBox is already open",
            InitError::TermBox(e) => e.map_or("Unexpected TermBox return code", |e| match e {
                InitErrorKind::UnsupportedTerminal => "Unsupported terminal",
                InitErrorKind::FailedToOpenTty => "Failed to open TTY",
                InitErrorKind::PipeTrapError => "Pipe trap error",
            }),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            InitError::BufferStderrFailed(ref e) => Some(e),
            _ => None
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct RustBox {
   // We only bother to redirect stderr for the moment, since it's used for panic!
   _stderr: Option<Hold>,
}

// Termbox is not thread safe
impl !Send for RustBox {}

#[derive(Clone, Copy,Debug)]
pub struct InitOptions {
    /// Use this option to initialize with a specific input mode
    ///
    /// See InputMode enum for details on the variants.
    pub input_mode: InputMode,

    /// Use this option to automatically buffer stderr while RustBox is running.  It will be
    /// written when RustBox exits.
    ///
    /// This option uses a nonblocking OS pipe to buffer stderr output.  This means that if the
    /// pipe fills up, subsequent writes will fail until RustBox exits.  If this is a concern for
    /// your program, don't use RustBox's default pipe-based redirection; instead, redirect stderr
    /// to a log file or another process that is capable of handling it better.
    pub buffer_stderr: bool,
}

impl Default for InitOptions {
    fn default() -> Self {
        InitOptions {
            input_mode: RB_INPUT_CURRENT,
            buffer_stderr: false,
        }
    }
}

impl RustBox {
    /// Initialize rustbox.
    ///
    /// For the default options, you can use:
    ///
    /// ```
    /// use rustbox::RustBox;
    /// use std::default::Default;
    /// let rb = RustBox::init(Default::default());
    /// ```
    ///
    /// Otherwise, you can specify:
    ///
    /// ```
    /// use rustbox::{RustBox, InitOptions};
    /// use std::default::Default;
    /// let rb = RustBox::init(InitOptions { input_mode: rustbox::InputMode::Esc, ..Default::default() });
    /// ```
    pub fn init(opts: InitOptions) -> Result<RustBox, InitError> {
        let stderr = if opts.buffer_stderr {
            Some(try!(Hold::stderr().map_err(|e| InitError::BufferStderrFailed(e))))
        } else {
            None
        };

        // Create the RustBox.
        let rb = unsafe { match termbox::tb_init() {
            0 => RustBox {
                _stderr: stderr,
            },
            res => {
                return Err(InitError::TermBox(FromPrimitive::from_isize(res as isize)))
            }
        }};
        match opts.input_mode {
            RB_INPUT_CURRENT => (),
            _ => rb.set_input_mode(opts.input_mode),
        }
        Ok(rb)
    }

    pub fn width(&self) -> usize {
        unsafe { termbox::tb_width() as usize }
    }

    pub fn height(&self) -> usize {
        unsafe { termbox::tb_height() as usize }
    }

    pub fn clear(&self) {
        unsafe { termbox::tb_clear() }
    }

    pub fn present(&self) {
        unsafe { termbox::tb_present() }
    }

    pub fn set_cursor(&self, x: isize, y: isize) {
        unsafe { termbox::tb_set_cursor(x as c_int, y as c_int) }
    }

    pub unsafe fn change_cell(&self, x: usize, y: usize, ch: u32, fg: u16, bg: u16) {
        termbox::tb_change_cell(x as c_int, y as c_int, ch, fg, bg)
    }

    pub fn print(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, s: &str) {
        let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
        let bg = Style::from_color(bg);
        for (i, ch) in s.chars().enumerate() {
            unsafe {
                self.change_cell(x+i, y, ch as u32, fg.bits(), bg.bits());
            }
        }
    }

    pub fn print_char(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, ch: char) {
        let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
        let bg = Style::from_color(bg);
        unsafe {
            self.change_cell(x, y, ch as u32, fg.bits(), bg.bits());
        }
    }

    pub fn poll_event(&self, raw: bool) -> EventResult<Event> {
        let ev = NIL_RAW_EVENT;
        let rc = unsafe {
            termbox::tb_poll_event(&ev as *const RawEvent)
        };
        unpack_event(rc, &ev, raw)
    }

    pub fn peek_event(&self, timeout: Duration, raw: bool) -> EventResult<Event> {
        let ev = NIL_RAW_EVENT;
        let rc = unsafe {
            termbox::tb_peek_event(&ev as *const RawEvent, timeout.num_milliseconds() as c_int)
        };
        unpack_event(rc, &ev, raw)
    }

    pub fn set_input_mode(&self, mode: InputMode) {
        unsafe {
            termbox::tb_select_input_mode(mode.bits() as c_int);
        }
    }
}

impl Drop for RustBox {
    fn drop(&mut self) {
        // Since only one instance of the RustBox is ever accessible, we should not
        // need to do this atomically.
        // Note: we should definitely have RUSTBOX_RUNNING = true here.
        unsafe {
            termbox::tb_shutdown();
        }
    }
}
<commit_msg>Revert "Make InputMode a bitflags type"<commit_after>#![feature(libc)]
#![feature(std_misc)]
#![feature(optin_builtin_traits)]

extern crate gag;
extern crate libc;
extern crate num;
#[macro_use] extern crate enum_primitive;
extern crate termbox_sys as termbox;
#[macro_use] extern crate bitflags;

pub use self::style::{Style, RB_BOLD, RB_UNDERLINE, RB_REVERSE, RB_NORMAL};

use std::error::Error;
use std::fmt;
use std::io;
use std::char;
use std::time::duration::Duration;
use std::default::Default;

use num::FromPrimitive;
use termbox::RawEvent;
use libc::c_int;
use gag::Hold;

pub mod keyboard;
pub mod mouse;

pub use keyboard::Key;
pub use mouse::Mouse;

#[derive(Clone, Copy)]
pub enum Event {
    KeyEventRaw(u8, u16, u32),
    KeyEvent(Option<Key>),
    ResizeEvent(i32, i32),
    MouseEvent(Mouse, i32, i32),
    NoEvent
}

#[derive(Clone, Copy, Debug)]
pub enum InputMode {
    Current = 0x00,

    /// When ESC sequence is in the buffer and it doesn't match any known
    /// ESC sequence => ESC means TB_KEY_ESC
    Esc     = 0x01,
    /// When ESC sequence is in the buffer and it doesn't match any known
    /// sequence => ESC enables TB_MOD_ALT modifier for the next keyboard event.
    Alt     = 0x02,
}

#[derive(Clone, Copy, PartialEq)]
#[repr(C,u16)]
pub enum Color {
    Default =  0x00,
    Black =    0x01,
    Red =      0x02,
    Green =    0x03,
    Yellow =   0x04,
    Blue =     0x05,
    Magenta =  0x06,
    Cyan =     0x07,
    White =    0x08,
}

mod style {
    bitflags! {
        #[repr(C)]
        flags Style: u16 {
            const TB_NORMAL_COLOR = 0x000F,
            const RB_BOLD = 0x0100,
            const RB_UNDERLINE = 0x0200,
            const RB_REVERSE = 0x0400,
            const RB_NORMAL = 0x0000,
            const TB_ATTRIB = RB_BOLD.bits | RB_UNDERLINE.bits | RB_REVERSE.bits,
        }
    }

    impl Style {
        pub fn from_color(color: super::Color) -> Style {
            Style { bits: color as u16 & TB_NORMAL_COLOR.bits }
        }
    }
}

const NIL_RAW_EVENT: RawEvent = RawEvent { etype: 0, emod: 0, key: 0, ch: 0, w: 0, h: 0, x: 0, y: 0 };

// FIXME: Rust doesn't support this enum representation.
// #[derive(Copy,FromPrimitive,Debug)]
// #[repr(C,int)]
// pub enum EventErrorKind {
//     Error = -1,
// }
// pub type EventError = Option<EventErrorKind>;
#[allow(non_snake_case)]
pub mod EventErrorKind {
    #[derive(Clone, Copy,Debug)]
    pub struct Error;
}

pub type EventError = Option<EventErrorKind::Error>;

pub type EventResult<T> = Result<T, EventError>;

/// Unpack a RawEvent to an Event
///
/// if the `raw` parameter is true, then the Event variant will be the raw
/// representation of the event.
///     for instance KeyEventRaw instead of KeyEvent
///
/// This is useful if you want to interpret the raw event data yourself, rather
/// than having rustbox translate it to its own representation.
fn unpack_event(ev_type: c_int, ev: &RawEvent, raw: bool) -> EventResult<Event> {
    match ev_type {
        0 => Ok(Event::NoEvent),
        1 => Ok(
            if raw {
                Event::KeyEventRaw(ev.emod, ev.key, ev.ch)
            } else {
                let k = match ev.key {
                    0 => char::from_u32(ev.ch).map(|c| Key::Char(c)),
                    a => Key::from_code(a),
                };
                Event::KeyEvent(k)
            }),
        2 => Ok(Event::ResizeEvent(ev.w, ev.h)),
        3 => {
            let mouse = Mouse::from_code(ev.key).unwrap_or(Mouse::Left);
            Ok(Event::MouseEvent(mouse, ev.x, ev.y))
        }
        // FIXME: Rust doesn't support this error representation
        // res => FromPrimitive::from_int(res as isize),
        -1 => Err(Some(EventErrorKind::Error)),
        _ => Err(None)
    }
}

enum_from_primitive! {
#[derive(Clone, Copy, Debug)]
#[repr(C,isize)]
pub enum InitErrorKind {
    UnsupportedTerminal = -1,
    FailedToOpenTty = -2,
    PipeTrapError = -3,
}
}

#[derive(Debug)]
pub enum InitError {
    BufferStderrFailed(io::Error),
    AlreadyOpen,
    TermBox(Option<InitErrorKind>),
}

impl fmt::Display for InitError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}", self.description())
    }
}

impl Error for InitError {
    fn description(&self) -> &str {
        match *self {
            InitError::BufferStderrFailed(_) => "Could not redirect stderr",
            InitError::AlreadyOpen => "RustBox is already open",
            InitError::TermBox(e) => e.map_or("Unexpected TermBox return code", |e| match e {
                InitErrorKind::UnsupportedTerminal => "Unsupported terminal",
                InitErrorKind::FailedToOpenTty => "Failed to open TTY",
                InitErrorKind::PipeTrapError => "Pipe trap error",
            }),
        }
    }

    fn cause(&self) -> Option<&Error> {
        match *self {
            InitError::BufferStderrFailed(ref e) => Some(e),
            _ => None
        }
    }
}

#[allow(missing_copy_implementations)]
pub struct RustBox {
   // We only bother to redirect stderr for the moment, since it's used for panic!
   _stderr: Option<Hold>,
}

// Termbox is not thread safe
impl !Send for RustBox {}

#[derive(Clone, Copy,Debug)]
pub struct InitOptions {
    /// Use this option to initialize with a specific input mode
    ///
    /// See InputMode enum for details on the variants.
    pub input_mode: InputMode,

    /// Use this option to automatically buffer stderr while RustBox is running.  It will be
    /// written when RustBox exits.
    ///
    /// This option uses a nonblocking OS pipe to buffer stderr output.  This means that if the
    /// pipe fills up, subsequent writes will fail until RustBox exits.  If this is a concern for
    /// your program, don't use RustBox's default pipe-based redirection; instead, redirect stderr
    /// to a log file or another process that is capable of handling it better.
    pub buffer_stderr: bool,
}

impl Default for InitOptions {
    fn default() -> Self {
        InitOptions {
            input_mode: InputMode::Current,
            buffer_stderr: false,
        }
    }
}

impl RustBox {
    /// Initialize rustbox.
    ///
    /// For the default options, you can use:
    ///
    /// ```
    /// use rustbox::RustBox;
    /// use std::default::Default;
    /// let rb = RustBox::init(Default::default());
    /// ```
    ///
    /// Otherwise, you can specify:
    ///
    /// ```
    /// use rustbox::{RustBox, InitOptions};
    /// use std::default::Default;
    /// let rb = RustBox::init(InitOptions { input_mode: rustbox::InputMode::Esc, ..Default::default() });
    /// ```
    pub fn init(opts: InitOptions) -> Result<RustBox, InitError> {
        let stderr = if opts.buffer_stderr {
            Some(try!(Hold::stderr().map_err(|e| InitError::BufferStderrFailed(e))))
        } else {
            None
        };

        // Create the RustBox.
        let rb = unsafe { match termbox::tb_init() {
            0 => RustBox {
                _stderr: stderr,
            },
            res => {
                return Err(InitError::TermBox(FromPrimitive::from_isize(res as isize)))
            }
        }};
        match opts.input_mode {
            InputMode::Current => (),
            _ => rb.set_input_mode(opts.input_mode),
        }
        Ok(rb)
    }

    pub fn width(&self) -> usize {
        unsafe { termbox::tb_width() as usize }
    }

    pub fn height(&self) -> usize {
        unsafe { termbox::tb_height() as usize }
    }

    pub fn clear(&self) {
        unsafe { termbox::tb_clear() }
    }

    pub fn present(&self) {
        unsafe { termbox::tb_present() }
    }

    pub fn set_cursor(&self, x: isize, y: isize) {
        unsafe { termbox::tb_set_cursor(x as c_int, y as c_int) }
    }

    pub unsafe fn change_cell(&self, x: usize, y: usize, ch: u32, fg: u16, bg: u16) {
        termbox::tb_change_cell(x as c_int, y as c_int, ch, fg, bg)
    }

    pub fn print(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, s: &str) {
        let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
        let bg = Style::from_color(bg);
        for (i, ch) in s.chars().enumerate() {
            unsafe {
                self.change_cell(x+i, y, ch as u32, fg.bits(), bg.bits());
            }
        }
    }

    pub fn print_char(&self, x: usize, y: usize, sty: Style, fg: Color, bg: Color, ch: char) {
        let fg = Style::from_color(fg) | (sty & style::TB_ATTRIB);
        let bg = Style::from_color(bg);
        unsafe {
            self.change_cell(x, y, ch as u32, fg.bits(), bg.bits());
        }
    }

    pub fn poll_event(&self, raw: bool) -> EventResult<Event> {
        let ev = NIL_RAW_EVENT;
        let rc = unsafe {
            termbox::tb_poll_event(&ev as *const RawEvent)
        };
        unpack_event(rc, &ev, raw)
    }

    pub fn peek_event(&self, timeout: Duration, raw: bool) -> EventResult<Event> {
        let ev = NIL_RAW_EVENT;
        let rc = unsafe {
            termbox::tb_peek_event(&ev as *const RawEvent, timeout.num_milliseconds() as c_int)
        };
        unpack_event(rc, &ev, raw)
    }

    pub fn set_input_mode(&self, mode: InputMode) {
        unsafe {
            termbox::tb_select_input_mode(mode as c_int);
        }
    }
}

impl Drop for RustBox {
    fn drop(&mut self) {
        // Since only one instance of the RustBox is ever accessible, we should not
        // need to do this atomically.
        // Note: we should definitely have RUSTBOX_RUNNING = true here.
        unsafe {
            termbox::tb_shutdown();
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>coap work<commit_after><|endoftext|>


<commit_before>use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::file::*;
use redox::io::*;
use redox::console::*;
use redox::env::*;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// A command
pub struct Command {
    pub name: String,
    pub main: Box<Fn(&Vec<String>)>,
}

impl Command {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();
        commands.push(Command {
            name: "echo".to_string(),
            main: box |args: &Vec<String>| {
                let mut echo = String::new();
                let mut first = true;
                for i in 1..args.len() {
                    match args.get(i) {
                        Some(arg) => {
                            if first {
                                first = false
                            } else {
                                echo = echo + " ";
                            }
                            echo = echo + arg;
                        }
                        None => (),
                    }
                }
                println!("{}", echo);
            },
        });

        commands.push(Command {
            name: "open".to_string(),
            main: box |args: &Vec<String>| {
                match args.get(1) {
                    Some(arg) => {
                        File::exec(arg);
                    },
                    None => (),
                }
            },
        });

        commands.push(Command {
            name: "run".to_string(),
            main: box |args: &Vec<String>| {
                match args.get(1) {
                    Some(arg) => {
                        let path = arg.clone();
                        println!("URL: {}", path);

                        let mut commands = String::new();
                        if let Some(mut file) = File::open(&path) {
                            file.read_to_string(&mut commands);
                        }

                        for command in commands.split('\n') {
                            exec!(command);
                        }
                    }
                    None => (),
                }
            },
        });

        commands.push(Command {
            name: "send".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    for i in 2..args.len() {
                        if let Some(arg) = args.get(i) {
                            if i >= 3 {
                                string.push_str(" ");
                            }
                            string.push_str(arg);
                        }
                    }
                    string.push_str("\r\n\r\n");

                    match file.write(&string.as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "url".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "url_hex".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "wget".to_string(),
            main: box |args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            },
        });

		let mut command_list = String::new();
		command_list = commands.iter().fold(command_list, |l , n| l + " " + &n.name);

        commands.push(Command {
			name: "help".to_string(),
			main: box move |args: &Vec<String>| {
                println!("Commands:{}", command_list);
			},
		});

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application {
    commands: Vec<Command>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl Application {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &String) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if *command_string == "$" {
            let mut variables = String::new();
            for variable in self.variables.iter() {
                variables = variables + "\n" + &variable.name + "=" + &variable.value;
            }
            println!("{}", variables);
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if arg.len() > 0 {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        match args.get(0) {
            Some(cmd) => {
                if cmd == "if" {
                    let mut value = false;

                    match args.get(1) {
                        Some(left) => match args.get(2) {
                            Some(cmp) => match args.get(3) {
                                Some(right) => {
                                    if cmp == "==" {
                                        value = *left == *right;
                                    } else if cmp == "!=" {
                                        value = *left != *right;
                                    } else if cmp == ">" {
                                        value = left.to_num_signed() > right.to_num_signed();
                                    } else if cmp == ">=" {
                                        value = left.to_num_signed() >= right.to_num_signed();
                                    } else if cmp == "<" {
                                        value = left.to_num_signed() < right.to_num_signed();
                                    } else if cmp == "<=" {
                                        value = left.to_num_signed() <= right.to_num_signed();
                                    } else {
                                        println!("Unknown comparison: {}", cmp);
                                    }
                                }
                                None => (),
                            },
                            None => (),
                        },
                        None => (),
                    }

                    self.modes.insert(0, Mode { value: value });
                    return;
                }

                if cmd == "else" {
                    let mut syntax_error = false;
                    match self.modes.get_mut(0) {
                        Some(mode) => mode.value = !mode.value,
                        None => syntax_error = true,
                    }
                    if syntax_error {
                        println!("Syntax error: else found with no previous if");
                    }
                    return;
                }

                if cmd == "fi" {
                    let mut syntax_error = false;
                    if self.modes.len() > 0 {
                        self.modes.remove(0);
                    } else {
                        syntax_error = true;
                    }
                    if syntax_error {
                        println!("Syntax error: fi found with no previous if");
                    }
                    return;
                }

                for mode in self.modes.iter() {
                    if !mode.value {
                        return;
                    }
                }

                //Set variables
                match cmd.find('=') {
                    Some(i) => {
                        let name = cmd[0 .. i].to_string();
                        let mut value = cmd[i + 1 .. cmd.len()].to_string();

                        if name.len() == 0 {
                            return;
                        }

                        for i in 1..args.len() {
                            match args.get(i) {
                                Some(arg) => value = value + " " + &arg,
                                None => (),
                            }
                        }

                        if value.len() == 0 {
                            let mut remove = -1;
                            for i in 0..self.variables.len() {
                                match self.variables.get(i) {
                                    Some(variable) => if variable.name == name {
                                        remove = i as isize;
                                        break;
                                    },
                                    None => break,
                                }
                            }

                            if remove >= 0 {
                                self.variables.remove(remove as usize);
                            }
                        } else {
                            for variable in self.variables.iter_mut() {
                                if variable.name == name {
                                    variable.value = value;
                                    return;
                                }
                            }

                            self.variables.push(Variable {
                                name: name,
                                value: value,
                            });
                        }
                        return;
                    }
                    None => (),
                }

                //Commands
                for command in self.commands.iter() {
                    if &command.name == cmd {
                        (*command.main)(&args);
                        return;
                    }
                }

                println!("Unknown command: '{}'", cmd);

            }
            None => (),
        }
    }

    /// Run the application
    pub fn main(&mut self) {
        console_title(&"Terminal".to_string());

        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("# {}", command);
            self.on_command(&command);
        }

        while let Some(command) = readln!() {
            println!("# {}", command);
            if command.len() > 0 {
                self.on_command(&command);
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = box Application::new();
        application = app.deref_mut();
        app.main();
    }
}
<commit_msg>formatting<commit_after>use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::file::*;
use redox::io::*;
use redox::console::*;
use redox::env::*;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// A command
pub struct Command {
    pub name: String,
    pub main: Box<Fn(&Vec<String>)>,
}

impl Command {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();
        commands.push(Command {
            name: "echo".to_string(),
            main: box |args: &Vec<String>| {
                let mut echo = String::new();
                let mut first = true;
                for i in 1..args.len() {
                    match args.get(i) {
                        Some(arg) => {
                            if first {
                                first = false
                            } else {
                                echo = echo + " ";
                            }
                            echo = echo + arg;
                        }
                        None => (),
                    }
                }
                println!("{}", echo);
            },
        });

        commands.push(Command {
            name: "open".to_string(),
            main: box |args: &Vec<String>| {
                match args.get(1) {
                    Some(arg) => {
                        File::exec(arg);
                    },
                    None => (),
                }
            },
        });

        commands.push(Command {
            name: "run".to_string(),
            main: box |args: &Vec<String>| {
                match args.get(1) {
                    Some(arg) => {
                        let path = arg.clone();
                        println!("URL: {}", path);

                        let mut commands = String::new();
                        if let Some(mut file) = File::open(&path) {
                            file.read_to_string(&mut commands);
                        }

                        for command in commands.split('\n') {
                            exec!(command);
                        }
                    }
                    None => (),
                }
            },
        });

        commands.push(Command {
            name: "send".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    for i in 2..args.len() {
                        if let Some(arg) = args.get(i) {
                            if i >= 3 {
                                string.push_str(" ");
                            }
                            string.push_str(arg);
                        }
                    }
                    string.push_str("\r\n\r\n");

                    match file.write(&string.as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "url".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "url_hex".to_string(),
            main: box |args: &Vec<String>| {
                let path;
                match args.get(1) {
                    Some(arg) => path = arg.clone(),
                    None => path = String::new(),
                }
                println!("URL: {}", path);

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            },
        });

        commands.push(Command {
            name: "wget".to_string(),
            main: box |args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            },
        });

        let mut command_list = String::new();
        command_list = commands.iter().fold(command_list, |l , c| l + " " + &c.name);

        commands.push(Command {
            name: "help".to_string(),
            main: box move |args: &Vec<String>| {
                println!("Commands:{}", command_list);
            },
         });

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application {
    commands: Vec<Command>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl Application {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &String) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if *command_string == "$" {
            let mut variables = String::new();
            for variable in self.variables.iter() {
                variables = variables + "\n" + &variable.name + "=" + &variable.value;
            }
            println!("{}", variables);
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if arg.len() > 0 {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        match args.get(0) {
            Some(cmd) => {
                if cmd == "if" {
                    let mut value = false;

                    match args.get(1) {
                        Some(left) => match args.get(2) {
                            Some(cmp) => match args.get(3) {
                                Some(right) => {
                                    if cmp == "==" {
                                        value = *left == *right;
                                    } else if cmp == "!=" {
                                        value = *left != *right;
                                    } else if cmp == ">" {
                                        value = left.to_num_signed() > right.to_num_signed();
                                    } else if cmp == ">=" {
                                        value = left.to_num_signed() >= right.to_num_signed();
                                    } else if cmp == "<" {
                                        value = left.to_num_signed() < right.to_num_signed();
                                    } else if cmp == "<=" {
                                        value = left.to_num_signed() <= right.to_num_signed();
                                    } else {
                                        println!("Unknown comparison: {}", cmp);
                                    }
                                }
                                None => (),
                            },
                            None => (),
                        },
                        None => (),
                    }

                    self.modes.insert(0, Mode { value: value });
                    return;
                }

                if cmd == "else" {
                    let mut syntax_error = false;
                    match self.modes.get_mut(0) {
                        Some(mode) => mode.value = !mode.value,
                        None => syntax_error = true,
                    }
                    if syntax_error {
                        println!("Syntax error: else found with no previous if");
                    }
                    return;
                }

                if cmd == "fi" {
                    let mut syntax_error = false;
                    if self.modes.len() > 0 {
                        self.modes.remove(0);
                    } else {
                        syntax_error = true;
                    }
                    if syntax_error {
                        println!("Syntax error: fi found with no previous if");
                    }
                    return;
                }

                for mode in self.modes.iter() {
                    if !mode.value {
                        return;
                    }
                }

                //Set variables
                match cmd.find('=') {
                    Some(i) => {
                        let name = cmd[0 .. i].to_string();
                        let mut value = cmd[i + 1 .. cmd.len()].to_string();

                        if name.len() == 0 {
                            return;
                        }

                        for i in 1..args.len() {
                            match args.get(i) {
                                Some(arg) => value = value + " " + &arg,
                                None => (),
                            }
                        }

                        if value.len() == 0 {
                            let mut remove = -1;
                            for i in 0..self.variables.len() {
                                match self.variables.get(i) {
                                    Some(variable) => if variable.name == name {
                                        remove = i as isize;
                                        break;
                                    },
                                    None => break,
                                }
                            }

                            if remove >= 0 {
                                self.variables.remove(remove as usize);
                            }
                        } else {
                            for variable in self.variables.iter_mut() {
                                if variable.name == name {
                                    variable.value = value;
                                    return;
                                }
                            }

                            self.variables.push(Variable {
                                name: name,
                                value: value,
                            });
                        }
                        return;
                    }
                    None => (),
                }

                //Commands
                for command in self.commands.iter() {
                    if &command.name == cmd {
                        (*command.main)(&args);
                        return;
                    }
                }

                println!("Unknown command: '{}'", cmd);

            }
            None => (),
        }
    }

    /// Run the application
    pub fn main(&mut self) {
        console_title(&"Terminal".to_string());

        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("# {}", command);
            self.on_command(&command);
        }

        while let Some(command) = readln!() {
            println!("# {}", command);
            if command.len() > 0 {
                self.on_command(&command);
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = box Application::new();
        application = app.deref_mut();
        app.main();
    }
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2090<commit_after>// https://leetcode.com/problems/k-radius-subarray-averages/
pub fn get_averages(nums: Vec<i32>, k: i32) -> Vec<i32> {
    todo!()
}

fn main() {
    println!("{:?}", get_averages(vec![7, 4, 3, 9, 1, 8, 5, 2, 6], 3)); // [-1,-1,-1,5,4,4,-1,-1,-1]
    println!("{:?}", get_averages(vec![100000], 0)); // [100000]
    println!("{:?}", get_averages(vec![8], 100000)); // [-1]
}
<|endoftext|>