<commit_before>use au = gfx::geometry;
use core::dlist::DList;
use css::values::{BoxAuto, BoxLength, Px};
use dl = gfx::display_list;
use dom::rcu;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::geometry::au;
use layout::box::{RenderBox, RenderBoxTree, ImageBox, TextBox, GenericBox};
use layout::flow::{FlowContext, InlineFlow};
use layout::context::LayoutContext;
use num::Num;
use util::tree;

/*
Tentative design: (may not line up with reality)

Lineboxes are represented as offsets into the child list, rather than
as an object that "owns" boxes. Choosing a different set of line
breaks requires a new list of offsets, and possibly some splitting and
merging of TextBoxes.

A similar list will keep track of the mapping between CSS boxes and
the corresponding render boxes in the inline flow.

After line breaks are determined, lender boxes in the inline flow may
overlap visually. For example, in the case of nested inline CSS boxes,
outer inlines must be at least as large as the inner inlines, for
purposes of drawing noninherited things like backgrounds, borders,
outlines.

N.B. roc has an alternative design where the list instead consists of
things like "start outer box, text, start inner box, text, end inner
box, text, end outer box, text". This seems a little complicated to
serve as the starting point, but the current design doesn't make it
hard to try out that alternative.
*/

struct InlineFlowData {
    boxes: ~DList<@RenderBox>
}

fn InlineFlowData() -> InlineFlowData {
    InlineFlowData {
        boxes: ~DList()
    }
}

trait InlineLayout {
    pure fn starts_inline_flow() -> bool;

    fn bubble_widths_inline(ctx: &LayoutContext);
    fn assign_widths_inline(ctx: &LayoutContext);
    fn assign_height_inline(ctx: &LayoutContext);
    fn build_display_list_inline(a: &dl::DisplayListBuilder, b: &Rect<au>, c: &Point2D<au>, d: &dl::DisplayList);
}

impl FlowContext : InlineLayout {
    pure fn starts_inline_flow() -> bool { match self { InlineFlow(*) => true, _ => false } }

    fn bubble_widths_inline(_ctx: &LayoutContext) {
        assert self.starts_inline_flow();

        let mut min_width = au(0);
        let mut pref_width = au(0);

        for self.inline().boxes.each |box| {
            min_width = au::max(min_width, box.get_min_width());
            pref_width = au::max(pref_width, box.get_pref_width());
        }

        self.d().min_width = min_width;
        self.d().pref_width = pref_width;
    }

    /* Recursively (top-down) determines the actual width of child
    contexts and boxes. When called on this context, the context has
    had its width set by the parent context. */
    fn assign_widths_inline(ctx: &LayoutContext) {
        assert self.starts_inline_flow();

        /* Perform inline flow with the available width. */
        //let avail_width = self.d().position.size.width;

        let line_height = au::from_px(20);
        //let mut cur_x = au(0);
        let mut cur_y = au(0);

        for self.inline().boxes.each |box| {
            /* TODO: actually do inline flow.
            - Create a working linebox, and successively put boxes
            into it, splitting if necessary.

            - Set width and height for each positioned element based on
            where its chunks ended up.

            - Save the dvec of this context's lineboxes. */

            /* hack: until text box splitting is hoisted into this
            function, force "reflow" on TextBoxes.  */
            match *box {
                @TextBox(*) => box.reflow_text(ctx),
                _ => {}
            }

            box.d().position.size.width = match *box {
                @ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).width),
                @TextBox(_,d) => d.runs[0].size().width,
                // TODO: this should be set to the extents of its children
                @GenericBox(*) => au(0)
            };

            box.d().position.size.height = match *box {
                @ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).height),
                @TextBox(_,d) => d.runs[0].size().height,
                // TODO: this should be set to the extents of its children
                @GenericBox(*) => au(0)
            };

            box.d().position.origin = Point2D(au(0), cur_y);
            cur_y = cur_y.add(au::max(line_height, box.d().position.size.height));
        } // for boxes.each |box|

    self.d().position.size.height = cur_y;

    /* There are no child contexts, so stop here. */

    // TODO: once there are 'inline-block' elements, this won't be
    // true.  In that case, perform inline flow, and then set the
    // block flow context's width as the width of the
    // 'inline-block' box that created this flow.
    }

    fn assign_height_inline(_ctx: &LayoutContext) {
        // Don't need to set box or ctx heights, since that is done
        // during inline flowing.
    }

    fn build_display_list_inline(builder: &dl::DisplayListBuilder, dirty: &Rect<au>,
                                 offset: &Point2D<au>, list: &dl::DisplayList) {

        assert self.starts_inline_flow();

        // TODO: if the CSS box introducing this inline context is *not* anonymous,
        // we need to draw it too, in a way similar to BlowFlowContext

        // TODO: once we form line boxes and have their cached bounds, we can be
        // smarter and not recurse on a line if nothing in it can intersect dirty
        for self.inline().boxes.each |box| {
            box.build_display_list(builder, dirty, offset, list)
        }

        // TODO: should inline-block elements have flows as children
        // of the inline flow, or should the flow be nested inside the
        // box somehow? Maybe it's best to unify flows and boxes into
        // the same enum, so inline-block flows are normal
        // (indivisible) children in the inline flow child list.
    }

} // @FlowContext : InlineLayout
<commit_msg>More inline flow struct refactor<commit_after>use au = gfx::geometry;
use core::dlist::DList;
use css::values::{BoxAuto, BoxLength, Px};
use dl = gfx::display_list;
use dom::rcu;
use geom::point::Point2D;
use geom::rect::Rect;
use geom::size::Size2D;
use gfx::geometry::au;
use layout::box::{RenderBox, RenderBoxTree, ImageBox, TextBox, GenericBox};
use layout::flow::{FlowContext, InlineFlow};
use layout::context::LayoutContext;
use num::Num;
use util::tree;

/*
Tentative design: (may not line up with reality)

Lineboxes are represented as offsets into the child list, rather than
as an object that "owns" boxes. Choosing a different set of line
breaks requires a new list of offsets, and possibly some splitting and
merging of TextBoxes.

A similar list will keep track of the mapping between CSS boxes and
the corresponding render boxes in the inline flow.

After line breaks are determined, render boxes in the inline flow may
overlap visually. For example, in the case of nested inline CSS boxes,
outer inlines must be at least as large as the inner inlines, for
purposes of drawing noninherited things like backgrounds, borders,
outlines.

N.B. roc has an alternative design where the list instead consists of
things like "start outer box, text, start inner box, text, end inner
box, text, end outer box, text". This seems a little complicated to
serve as the starting point, but the current design doesn't make it
hard to try out that alternative.
*/

type BoxRange = {start: u8, len: u8};

struct InlineFlowData {
    // A flat list of all inline render boxes. Several boxes may
    // correspond to one Node/Element.
    boxes: DList<@RenderBox>,
    // vec of ranges into boxes that represents line positions.
    // these ranges are disjoint, and are the result of inline layout.
    lines: DVec<BoxRange>,
    // vec of ranges into boxes that represent elements. These
    // ranges must be disjoint or well-nested, and are only related to
    // the content of boxes (not lines)
    elems: DVec<BoxRange>
}

fn InlineFlowData() -> InlineFlowData {
    InlineFlowData {
        boxes: DList(),
        lines: DVec(),
        elems: DVec()
    }
}

trait InlineLayout {
    pure fn starts_inline_flow() -> bool;

    fn bubble_widths_inline(ctx: &LayoutContext);
    fn assign_widths_inline(ctx: &LayoutContext);
    fn assign_height_inline(ctx: &LayoutContext);
    fn build_display_list_inline(a: &dl::DisplayListBuilder, b: &Rect<au>, c: &Point2D<au>, d: &dl::DisplayList);
}

impl FlowContext : InlineLayout {
    pure fn starts_inline_flow() -> bool { match self { InlineFlow(*) => true, _ => false } }

    fn bubble_widths_inline(_ctx: &LayoutContext) {
        assert self.starts_inline_flow();

        let mut min_width = au(0);
        let mut pref_width = au(0);

        for self.inline().boxes.each |box| {
            min_width = au::max(min_width, box.get_min_width());
            pref_width = au::max(pref_width, box.get_pref_width());
        }

        self.d().min_width = min_width;
        self.d().pref_width = pref_width;
    }

    /* Recursively (top-down) determines the actual width of child
    contexts and boxes. When called on this context, the context has
    had its width set by the parent context. */
    fn assign_widths_inline(ctx: &LayoutContext) {
        assert self.starts_inline_flow();

        /* Perform inline flow with the available width. */
        //let avail_width = self.d().position.size.width;

        let line_height = au::from_px(20);
        //let mut cur_x = au(0);
        let mut cur_y = au(0);

        for self.inline().boxes.each |box| {
            /* TODO: actually do inline flow.
            - Create a working linebox, and successively put boxes
            into it, splitting if necessary.

            - Set width and height for each positioned element based on
            where its chunks ended up.

            - Save the dvec of this context's lineboxes. */

            /* hack: until text box splitting is hoisted into this
            function, force "reflow" on TextBoxes.  */
            match *box {
                @TextBox(*) => box.reflow_text(ctx),
                _ => {}
            }

            box.d().position.size.width = match *box {
                @ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).width),
                @TextBox(_,d) => d.runs[0].size().width,
                // TODO: this should be set to the extents of its children
                @GenericBox(*) => au(0)
            };

            box.d().position.size.height = match *box {
                @ImageBox(_,img) => au::from_px(img.get_size().get_default(Size2D(0,0)).height),
                @TextBox(_,d) => d.runs[0].size().height,
                // TODO: this should be set to the extents of its children
                @GenericBox(*) => au(0)
            };

            box.d().position.origin = Point2D(au(0), cur_y);
            cur_y = cur_y.add(au::max(line_height, box.d().position.size.height));
        } // for boxes.each |box|

    self.d().position.size.height = cur_y;

    /* There are no child contexts, so stop here. */

    // TODO: once there are 'inline-block' elements, this won't be
    // true.  In that case, perform inline flow, and then set the
    // block flow context's width as the width of the
    // 'inline-block' box that created this flow.
    }

    fn assign_height_inline(_ctx: &LayoutContext) {
        // Don't need to set box or ctx heights, since that is done
        // during inline flowing.
    }

    fn build_display_list_inline(builder: &dl::DisplayListBuilder, dirty: &Rect<au>,
                                 offset: &Point2D<au>, list: &dl::DisplayList) {

        assert self.starts_inline_flow();

        // TODO: if the CSS box introducing this inline context is *not* anonymous,
        // we need to draw it too, in a way similar to BlowFlowContext

        // TODO: once we form line boxes and have their cached bounds, we can be
        // smarter and not recurse on a line if nothing in it can intersect dirty
        for self.inline().boxes.each |box| {
            box.build_display_list(builder, dirty, offset, list)
        }

        // TODO: should inline-block elements have flows as children
        // of the inline flow, or should the flow be nested inside the
        // box somehow? Maybe it's best to unify flows and boxes into
        // the same enum, so inline-block flows are normal
        // (indivisible) children in the inline flow child list.
    }

} // @FlowContext : InlineLayout
<|endoftext|>


<commit_before><commit_msg>Make Address public<commit_after><|endoftext|>


<commit_before>use std::collections::HashMap;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use serde_json::{Value, from_str};
use serde_json::error::Result as R;
use serde_json::Serializer;
use serde::ser::Serialize;
use serde::ser::Serializer as Ser;

use storage::parser::{FileHeaderParser, ParserError};
use storage::file::header::spec::FileHeaderSpec;
use storage::file::header::data::FileHeaderData;

pub struct JsonHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl JsonHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> JsonHeaderParser {
        JsonHeaderParser {
            spec: spec
        }
    }

}

impl Display for JsonHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "JsonHeaderParser"));
        Ok(())
    }

}

impl Debug for JsonHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "JsonHeaderParser, Spec: {:?}", self.spec));
        Ok(())
    }

}

impl FileHeaderParser for JsonHeaderParser {

    fn read(&self, string: Option<String>)
        -> Result<FileHeaderData, ParserError>
    {
        if string.is_some() {
            let s = string.unwrap();
            debug!("Deserializing: {}", s);
            let fromstr : R<Value> = from_str(&s[..]);
            if let Ok(ref content) = fromstr {
                return Ok(visit_json(&content))
            }
            let oe = fromstr.err().unwrap();
            let s = format!("JSON parser error: {}", oe.description());
            let e = ParserError::short(&s[..], s.clone(), 0);
            Err(e)
        } else {
            Ok(FileHeaderData::Null)
        }
    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        let mut s = Vec::<u8>::new();
        {
            let mut ser = Serializer::pretty(&mut s);
            data.serialize(&mut ser).map_err(|e| {
                debug!("Serializer error: {:?}", e);
            }).ok();
        }

        String::from_utf8(s).or(
            Err(ParserError::short("Cannot parse utf8 bytes",
                                   String::from("<not printable>"),
                                   0)))
    }

}

// TODO: This function must be able to return a parser error
fn visit_json(v: &Value) -> FileHeaderData {
    match v {
        &Value::Null             => FileHeaderData::Null,
        &Value::Bool(b)          => FileHeaderData::Bool(b),
        &Value::I64(i)           => FileHeaderData::Integer(i),
        &Value::U64(u)           => FileHeaderData::UInteger(u),
        &Value::F64(f)           => FileHeaderData::Float(f),
        &Value::String(ref s)        => FileHeaderData::Text(s.clone()),
        &Value::Array(ref vec)       => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_json(&i)).collect())
            }
        },
        &Value::Object(ref btree)    => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: k,
                        value: Box::new(visit_json(&v)),
                    }
                ).collect()
            }
        }
    }
}

impl Serialize for FileHeaderData {

    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Ser
    {
        match self {
            &FileHeaderData::Null               => {
                let o : Option<bool> = None;
                o.serialize(ser)
            },
            &FileHeaderData::Bool(ref b)            => b.serialize(ser),
            &FileHeaderData::Integer(ref i)         => i.serialize(ser),
            &FileHeaderData::UInteger(ref u)        => u.serialize(ser),
            &FileHeaderData::Float(ref f)           => f.serialize(ser),
            &FileHeaderData::Text(ref s)            => (&s[..]).serialize(ser),
            &FileHeaderData::Array{values: ref vs}  => vs.serialize(ser),
            &FileHeaderData::Map{keys: ref ks}      => {
                let mut hm = HashMap::new();

                for key in ks {
                    if let &FileHeaderData::Key{name: ref n, value: ref v} = key {
                        hm.insert(n, v);
                    } else {
                        panic!("Not a key: {:?}", key);
                    }
                }

                hm.serialize(ser)
            },
            &FileHeaderData::Key{name: _, value: _} => unreachable!(),

        }
    }

}

#[cfg(test)]
mod test {

    use std::ops::Deref;

    use super::JsonHeaderParser;
    use storage::parser::FileHeaderParser;
    use storage::file::header::data::FileHeaderData as FHD;
    use storage::file::header::spec::FileHeaderSpec as FHS;

    #[test]
    fn test_deserialization() {
        let text = String::from("{\"a\": 1, \"b\": -2}");
        let spec = FHS::Map {
            keys: vec![
                FHS::Key {
                    name: String::from("a"),
                    value_type: Box::new(FHS::UInteger)
                },
                FHS::Key {
                    name: String::from("b"),
                    value_type: Box::new(FHS::Integer)
                }
            ]
        };

        let parser = JsonHeaderParser::new(Some(spec));
        let parsed = parser.read(Some(text));
        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{keys}) => {
                for k in keys {
                    match k {
                        FHD::Key{name, value} => {
                            assert!(name == "a" || name == "b", "Key unknown");
                            match value.deref() {
                                &FHD::UInteger(u) => assert_eq!(u, 1),
                                &FHD::Integer(i) => assert_eq!(i, -2),
                                _ => assert!(false, "Integers are not here"),
                            }
                        },
                        _ => assert!(false, "Key is not a Key"),
                    }
                }
            },

            _ => assert!(false, "Parsed is not a map"),
        }
    }

    #[test]
    fn test_deserialization_without_spec() {
        let text    = String::from("{\"a\": [1], \"b\": {\"c\": -2}}");
        let parser  = JsonHeaderParser::new(None);
        let parsed  = parser.read(Some(text));

        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{keys}) => {
                for k in keys {
                    match_key(&k);
                }
            },

            _ => assert!(false, "Parsed is not a map"),
        }
    }

    fn match_key(k: &FHD) {
        use std::ops::Deref;

        match k {
            &FHD::Key{ref name, ref value} => {
                assert!(name == "a" || name == "b", "Key unknown");
                match value.deref() {
                    &FHD::Array{values: ref vs} => {
                        for value in vs.iter() {
                            match value {
                                &FHD::UInteger(u) => assert_eq!(u, 1),
                                _ => assert!(false, "UInt is not an UInt"),
                            }
                        }
                    }

                    &FHD::Map{keys: ref ks} => {
                        for key in ks.iter() {
                            match key {
                                &FHD::Key{name: ref name, value: ref value} => {
                                    match value.deref() {
                                        &FHD::Integer(i) => {
                                            assert_eq!(i, -2);
                                            assert_eq!(name, "c");
                                        },
                                        _ => assert!(false, "Int is not an Int"),
                                    };
                                },
                                _ => assert!(false, "Key is not a Key"),
                            }
                        }
                    }
                    _ => assert!(false, "Integers are not here"),
                }
            },
            _ => assert!(false, "Key in main Map is not a Key"),
        }
    }

    #[test]
    fn test_desser() {
        use serde_json::error::Result as R;
        use serde_json::{Value, from_str};

        let text    = String::from("{\"a\": [1], \"b\": {\"c\": -2}}");
        let parser  = JsonHeaderParser::new(None);

        let des = parser.read(Some(text.clone()));
        assert!(des.is_ok(), "Deserializing failed");

        let ser = parser.write(&des.unwrap());
        assert!(ser.is_ok(), "Parser error when serializing deserialized text");

        let json_text : R<Value> = from_str(&text[..]);
        let json_ser  : R<Value> = from_str(&ser.unwrap()[..]);

        assert!(json_text.is_ok(), "Could not use serde to serialize text for comparison");
        assert!(json_ser.is_ok(),  "Could not use serde to serialize serialized-deserialized text for comparison");
        assert_eq!(json_text.unwrap(), json_ser.unwrap());
    }

}
<commit_msg>Remove unneeded shorthand field pattern<commit_after>use std::collections::HashMap;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fmt;

use serde_json::{Value, from_str};
use serde_json::error::Result as R;
use serde_json::Serializer;
use serde::ser::Serialize;
use serde::ser::Serializer as Ser;

use storage::parser::{FileHeaderParser, ParserError};
use storage::file::header::spec::FileHeaderSpec;
use storage::file::header::data::FileHeaderData;

pub struct JsonHeaderParser {
    spec: Option<FileHeaderSpec>,
}

impl JsonHeaderParser {

    pub fn new(spec: Option<FileHeaderSpec>) -> JsonHeaderParser {
        JsonHeaderParser {
            spec: spec
        }
    }

}

impl Display for JsonHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "JsonHeaderParser"));
        Ok(())
    }

}

impl Debug for JsonHeaderParser {

    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "JsonHeaderParser, Spec: {:?}", self.spec));
        Ok(())
    }

}

impl FileHeaderParser for JsonHeaderParser {

    fn read(&self, string: Option<String>)
        -> Result<FileHeaderData, ParserError>
    {
        if string.is_some() {
            let s = string.unwrap();
            debug!("Deserializing: {}", s);
            let fromstr : R<Value> = from_str(&s[..]);
            if let Ok(ref content) = fromstr {
                return Ok(visit_json(&content))
            }
            let oe = fromstr.err().unwrap();
            let s = format!("JSON parser error: {}", oe.description());
            let e = ParserError::short(&s[..], s.clone(), 0);
            Err(e)
        } else {
            Ok(FileHeaderData::Null)
        }
    }

    fn write(&self, data: &FileHeaderData) -> Result<String, ParserError> {
        let mut s = Vec::<u8>::new();
        {
            let mut ser = Serializer::pretty(&mut s);
            data.serialize(&mut ser).map_err(|e| {
                debug!("Serializer error: {:?}", e);
            }).ok();
        }

        String::from_utf8(s).or(
            Err(ParserError::short("Cannot parse utf8 bytes",
                                   String::from("<not printable>"),
                                   0)))
    }

}

// TODO: This function must be able to return a parser error
fn visit_json(v: &Value) -> FileHeaderData {
    match v {
        &Value::Null             => FileHeaderData::Null,
        &Value::Bool(b)          => FileHeaderData::Bool(b),
        &Value::I64(i)           => FileHeaderData::Integer(i),
        &Value::U64(u)           => FileHeaderData::UInteger(u),
        &Value::F64(f)           => FileHeaderData::Float(f),
        &Value::String(ref s)        => FileHeaderData::Text(s.clone()),
        &Value::Array(ref vec)       => {
            FileHeaderData::Array {
                values: Box::new(vec.clone().into_iter().map(|i| visit_json(&i)).collect())
            }
        },
        &Value::Object(ref btree)    => {
            let btree = btree.clone();
            FileHeaderData::Map{
                keys: btree.into_iter().map(|(k, v)|
                    FileHeaderData::Key {
                        name: k,
                        value: Box::new(visit_json(&v)),
                    }
                ).collect()
            }
        }
    }
}

impl Serialize for FileHeaderData {

    fn serialize<S>(&self, ser: &mut S) -> Result<(), S::Error>
        where S: Ser
    {
        match self {
            &FileHeaderData::Null               => {
                let o : Option<bool> = None;
                o.serialize(ser)
            },
            &FileHeaderData::Bool(ref b)            => b.serialize(ser),
            &FileHeaderData::Integer(ref i)         => i.serialize(ser),
            &FileHeaderData::UInteger(ref u)        => u.serialize(ser),
            &FileHeaderData::Float(ref f)           => f.serialize(ser),
            &FileHeaderData::Text(ref s)            => (&s[..]).serialize(ser),
            &FileHeaderData::Array{values: ref vs}  => vs.serialize(ser),
            &FileHeaderData::Map{keys: ref ks}      => {
                let mut hm = HashMap::new();

                for key in ks {
                    if let &FileHeaderData::Key{name: ref n, value: ref v} = key {
                        hm.insert(n, v);
                    } else {
                        panic!("Not a key: {:?}", key);
                    }
                }

                hm.serialize(ser)
            },
            &FileHeaderData::Key{name: _, value: _} => unreachable!(),

        }
    }

}

#[cfg(test)]
mod test {

    use std::ops::Deref;

    use super::JsonHeaderParser;
    use storage::parser::FileHeaderParser;
    use storage::file::header::data::FileHeaderData as FHD;
    use storage::file::header::spec::FileHeaderSpec as FHS;

    #[test]
    fn test_deserialization() {
        let text = String::from("{\"a\": 1, \"b\": -2}");
        let spec = FHS::Map {
            keys: vec![
                FHS::Key {
                    name: String::from("a"),
                    value_type: Box::new(FHS::UInteger)
                },
                FHS::Key {
                    name: String::from("b"),
                    value_type: Box::new(FHS::Integer)
                }
            ]
        };

        let parser = JsonHeaderParser::new(Some(spec));
        let parsed = parser.read(Some(text));
        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{keys}) => {
                for k in keys {
                    match k {
                        FHD::Key{name, value} => {
                            assert!(name == "a" || name == "b", "Key unknown");
                            match value.deref() {
                                &FHD::UInteger(u) => assert_eq!(u, 1),
                                &FHD::Integer(i) => assert_eq!(i, -2),
                                _ => assert!(false, "Integers are not here"),
                            }
                        },
                        _ => assert!(false, "Key is not a Key"),
                    }
                }
            },

            _ => assert!(false, "Parsed is not a map"),
        }
    }

    #[test]
    fn test_deserialization_without_spec() {
        let text    = String::from("{\"a\": [1], \"b\": {\"c\": -2}}");
        let parser  = JsonHeaderParser::new(None);
        let parsed  = parser.read(Some(text));

        assert!(parsed.is_ok(), "Parsed is not ok: {:?}", parsed);

        match parsed.ok() {
            Some(FHD::Map{keys}) => {
                for k in keys {
                    match_key(&k);
                }
            },

            _ => assert!(false, "Parsed is not a map"),
        }
    }

    fn match_key(k: &FHD) {
        use std::ops::Deref;

        match k {
            &FHD::Key{ref name, ref value} => {
                assert!(name == "a" || name == "b", "Key unknown");
                match value.deref() {
                    &FHD::Array{values: ref vs} => {
                        for value in vs.iter() {
                            match value {
                                &FHD::UInteger(u) => assert_eq!(u, 1),
                                _ => assert!(false, "UInt is not an UInt"),
                            }
                        }
                    }

                    &FHD::Map{keys: ref ks} => {
                        for key in ks.iter() {
                            match key {
                                &FHD::Key{ref name, ref value} => {
                                    match value.deref() {
                                        &FHD::Integer(i) => {
                                            assert_eq!(i, -2);
                                            assert_eq!(name, "c");
                                        },
                                        _ => assert!(false, "Int is not an Int"),
                                    };
                                },
                                _ => assert!(false, "Key is not a Key"),
                            }
                        }
                    }
                    _ => assert!(false, "Integers are not here"),
                }
            },
            _ => assert!(false, "Key in main Map is not a Key"),
        }
    }

    #[test]
    fn test_desser() {
        use serde_json::error::Result as R;
        use serde_json::{Value, from_str};

        let text    = String::from("{\"a\": [1], \"b\": {\"c\": -2}}");
        let parser  = JsonHeaderParser::new(None);

        let des = parser.read(Some(text.clone()));
        assert!(des.is_ok(), "Deserializing failed");

        let ser = parser.write(&des.unwrap());
        assert!(ser.is_ok(), "Parser error when serializing deserialized text");

        let json_text : R<Value> = from_str(&text[..]);
        let json_ser  : R<Value> = from_str(&ser.unwrap()[..]);

        assert!(json_text.is_ok(), "Could not use serde to serialize text for comparison");
        assert!(json_ser.is_ok(),  "Could not use serde to serialize serialized-deserialized text for comparison");
        assert_eq!(json_text.unwrap(), json_ser.unwrap());
    }

}
<|endoftext|>


<commit_before>use flexi_logger::{LogSpecification, Logger};
use itertools::Itertools;
use log::LevelFilter;
use log::{info, warn};
use qt_ritual::lib_configs::create_config;
use qt_ritual_common::all_crate_names;
use ritual::cluster_api::{Client, GroupKey, TaskOutput};
use ritual::cpp_checker::{LocalCppChecker, SnippetTask};
use ritual_common::errors::{format_err, FancyUnwrap, Result};
use ritual_common::file_utils::create_dir;
use ritual_common::target::current_target;
use std::collections::HashMap;
use std::env;
use tempdir::TempDir;

const QUEUE_ADDRESS_VAR: &str = "QT_RITUAL_WORKER_QUEUE_ADDRESS";
const RUN_TESTS_VAR: &str = "QT_RITUAL_WORKER_RUN_TESTS";
const QMAKE_PATH_VAR_PREFIX: &str = "QT_RITUAL_QMAKE_";

struct RemoteSnippetTaskData {
    id: u64,
}

fn run() -> Result<()> {
    Logger::with(LogSpecification::default(LevelFilter::Info).build())
        .start()
        .unwrap_or_else(|e| panic!("Logger initialization failed: {}", e));

    let temp_dir = TempDir::new("qt_ritual_cluster_worker")?;
    let supported_moqt_libs = ["moqt_core", "moqt_gui"].iter().map(|crate_name| {
        let lib = GroupKey {
            crate_name: crate_name.to_string(),
            cpp_library_version: None,
        };
        (lib, None)
    });

    let supported_qt_libs = env::vars()
        .filter(|(key, _value)| key.starts_with(QMAKE_PATH_VAR_PREFIX))
        .flat_map(|(key, value)| {
            let version = key[QMAKE_PATH_VAR_PREFIX.len()..].replace("_", ".");
            all_crate_names().iter().map(move |crate_name| {
                let lib = GroupKey {
                    crate_name: crate_name.to_string(),
                    cpp_library_version: Some(version.clone()),
                };
                (lib, Some(value.clone()))
            })
        });

    let supported_libs = supported_moqt_libs.chain(supported_qt_libs);

    let mut checkers = HashMap::new();
    let run_tests = env::var(RUN_TESTS_VAR).ok().map_or(false, |s| s == "1");
    if run_tests {
        info!("running tests");
    }

    for (lib, qmake_path) in supported_libs {
        info!("lib: {:?}", lib);
        let dir = temp_dir.path().join(format!(
            "{}_{}",
            lib.crate_name,
            lib.cpp_library_version
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or("noversion")
        ));
        create_dir(&dir)?;

        let qmake_path = qmake_path.as_ref().map(|s| s.as_str());
        let config = create_config(&lib.crate_name, qmake_path)?;
        let checker = LocalCppChecker::new(dir, &config)?;
        let mut checker = checker.get("0")?;
        if run_tests {
            checker.check_preliminary_tests()?;
        }
        checkers.insert(lib, checker);
    }
    if run_tests {
        info!("all tests passed");
        return Ok(());
    }

    let queue_address = env::var(QUEUE_ADDRESS_VAR)
        .map_err(|err| format_err!("failed to get env var \"{}\": {}", QUEUE_ADDRESS_VAR, err))?;
    info!("connecting to queue");
    let mut client = Client::new(&queue_address, &current_target())?;
    info!("ready");
    client.run(|task| {
        info!("received task: {:?}", task);
        if let Some(checker) = checkers.get_mut(&task.group_key) {
            let mut snippets = task
                .snippets
                .into_iter()
                .map(|item| SnippetTask {
                    snippet: item.snippet,
                    data: RemoteSnippetTaskData { id: item.id },
                    output: None,
                })
                .collect_vec();
            checker.binary_check(&mut snippets, None)?;
            let outputs = snippets
                .into_iter()
                .map(|snippet| TaskOutput {
                    id: snippet.data.id,
                    output: snippet.output.unwrap(),
                })
                .collect_vec();
            Ok(outputs)
        } else {
            warn!("unknown group key: {:?}", task);
            Ok(Vec::new())
        }
    })?;
    Ok(())
}

fn main() {
    run().fancy_unwrap();
}
<commit_msg>skip moqt in cluster worker if it's not present<commit_after>use flexi_logger::{LogSpecification, Logger};
use itertools::Itertools;
use log::LevelFilter;
use log::{info, warn};
use qt_ritual::lib_configs::{create_config, MOQT_INSTALL_DIR_ENV_VAR_NAME};
use qt_ritual_common::all_crate_names;
use ritual::cluster_api::{Client, GroupKey, TaskOutput};
use ritual::cpp_checker::{LocalCppChecker, SnippetTask};
use ritual_common::errors::{format_err, FancyUnwrap, Result};
use ritual_common::file_utils::create_dir;
use ritual_common::target::current_target;
use std::collections::HashMap;
use std::env;
use tempdir::TempDir;

const QUEUE_ADDRESS_VAR: &str = "QT_RITUAL_WORKER_QUEUE_ADDRESS";
const RUN_TESTS_VAR: &str = "QT_RITUAL_WORKER_RUN_TESTS";
const QMAKE_PATH_VAR_PREFIX: &str = "QT_RITUAL_QMAKE_";

struct RemoteSnippetTaskData {
    id: u64,
}

fn run() -> Result<()> {
    Logger::with(LogSpecification::default(LevelFilter::Info).build())
        .start()
        .unwrap_or_else(|e| panic!("Logger initialization failed: {}", e));

    let temp_dir = TempDir::new("qt_ritual_cluster_worker")?;
    let moqt_present = env::var(MOQT_INSTALL_DIR_ENV_VAR_NAME).is_ok();
    let supported_moqt_libs = ["moqt_core", "moqt_gui"]
        .iter()
        .filter(|_| moqt_present)
        .map(|crate_name| {
            let lib = GroupKey {
                crate_name: crate_name.to_string(),
                cpp_library_version: None,
            };
            (lib, None)
        });

    let supported_qt_libs = env::vars()
        .filter(|(key, _value)| key.starts_with(QMAKE_PATH_VAR_PREFIX))
        .flat_map(|(key, value)| {
            let version = key[QMAKE_PATH_VAR_PREFIX.len()..].replace("_", ".");
            all_crate_names().iter().map(move |crate_name| {
                let lib = GroupKey {
                    crate_name: crate_name.to_string(),
                    cpp_library_version: Some(version.clone()),
                };
                (lib, Some(value.clone()))
            })
        });

    let supported_libs = supported_moqt_libs.chain(supported_qt_libs);

    let mut checkers = HashMap::new();
    let run_tests = env::var(RUN_TESTS_VAR).ok().map_or(false, |s| s == "1");
    if run_tests {
        info!("running tests");
    }

    for (lib, qmake_path) in supported_libs {
        info!("lib: {:?}", lib);
        let dir = temp_dir.path().join(format!(
            "{}_{}",
            lib.crate_name,
            lib.cpp_library_version
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or("noversion")
        ));
        create_dir(&dir)?;

        let qmake_path = qmake_path.as_ref().map(|s| s.as_str());
        let config = create_config(&lib.crate_name, qmake_path)?;
        let checker = LocalCppChecker::new(dir, &config)?;
        let mut checker = checker.get("0")?;
        if run_tests {
            checker.check_preliminary_tests()?;
        }
        checkers.insert(lib, checker);
    }
    if run_tests {
        info!("all tests passed");
        return Ok(());
    }

    let queue_address = env::var(QUEUE_ADDRESS_VAR)
        .map_err(|err| format_err!("failed to get env var \"{}\": {}", QUEUE_ADDRESS_VAR, err))?;
    info!("connecting to queue");
    let mut client = Client::new(&queue_address, &current_target())?;
    info!("ready");
    client.run(|task| {
        info!("received task: {:?}", task);
        if let Some(checker) = checkers.get_mut(&task.group_key) {
            let mut snippets = task
                .snippets
                .into_iter()
                .map(|item| SnippetTask {
                    snippet: item.snippet,
                    data: RemoteSnippetTaskData { id: item.id },
                    output: None,
                })
                .collect_vec();
            checker.binary_check(&mut snippets, None)?;
            let outputs = snippets
                .into_iter()
                .map(|snippet| TaskOutput {
                    id: snippet.data.id,
                    output: snippet.output.unwrap(),
                })
                .collect_vec();
            Ok(outputs)
        } else {
            warn!("unknown group key: {:?}", task);
            Ok(Vec::new())
        }
    })?;
    Ok(())
}

fn main() {
    run().fancy_unwrap();
}
<|endoftext|>


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

use dom::bindings::utils::Fallible;
use dom::document::AbstractDocument;
use dom::node::{ScriptView, Node, DocumentFragmentNodeTypeId};
use dom::node::{AbstractNode};
use dom::window::Window;

pub struct DocumentFragment {
    node: Node<ScriptView>,
}

impl DocumentFragment {
    /// Creates a new DocumentFragment.
    pub fn new(document: AbstractDocument) -> DocumentFragment {
        DocumentFragment {
            node: Node::new(DocumentFragmentNodeTypeId, document),
        }
    }

    pub fn Constructor(owner: @mut Window) -> Fallible<AbstractNode<ScriptView>> {
        let cx = owner.page.js_info.get_ref().js_compartment.cx.ptr;
        let fragment = @DocumentFragment::new(owner.Document());
        Ok(unsafe { Node::as_abstract_node(cx, fragment) })
    }
}
<commit_msg>Use Window::get_cx() in DocumentFragment::Constructor.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::utils::Fallible;
use dom::document::AbstractDocument;
use dom::node::{ScriptView, Node, DocumentFragmentNodeTypeId};
use dom::node::{AbstractNode};
use dom::window::Window;

pub struct DocumentFragment {
    node: Node<ScriptView>,
}

impl DocumentFragment {
    /// Creates a new DocumentFragment.
    pub fn new(document: AbstractDocument) -> DocumentFragment {
        DocumentFragment {
            node: Node::new(DocumentFragmentNodeTypeId, document),
        }
    }

    pub fn Constructor(owner: @mut Window) -> Fallible<AbstractNode<ScriptView>> {
        let cx = owner.get_cx();
        let fragment = @DocumentFragment::new(owner.Document());
        Ok(unsafe { Node::as_abstract_node(cx, fragment) })
    }
}
<|endoftext|>


<commit_before><commit_msg>[rust] size of empty struct is zero.<commit_after>use std::mem::size_of;

struct EmptyStruct;

fn main() {
    println!("{}", size_of::<EmptyStruct>()); // 0

    assert_eq!(size_of::<EmptyStruct>(), 0);
}
<|endoftext|>


<commit_before><commit_msg>added pointer example<commit_after>const n: usize = (16*1024);

struct foo {
    chaMem: *mut [u32; n],
}

impl foo {
    pub fn new() -> foo {
        let mem: *mut [u32; n] = unsafe { ::std::mem::transmute(Box::new([1; n])) };
        foo {chaMem: mem}
    }

    pub fn get_sig_ptr(&mut self, cha_signal: *mut *mut u32) {
        unsafe {
            *cha_signal = self.chaMem as *mut _;
        }
    }

    pub fn get_sig_ptr2(&mut self) -> *mut u32 {
        return self.chaMem as *mut _;
    }

    pub fn get_sig_ptr3(&mut self) -> *mut [u32; n] {
        return self.chaMem;
    }

    pub fn get_sig_ptr4(&mut self) -> &mut [u32; n] {
        unsafe {
            return &mut *(self.chaMem);
        }
    }
}

// This code is editable and runnable!
fn main() {
    let mut f = foo::new();

    let mut cha_signal1: *mut u32 = ::std::ptr::null_mut();
    f.get_sig_ptr(&mut cha_signal1);

    for i in 1..n {
        println!("{}", unsafe { *cha_signal1.offset(i as isize) }); // (*cha_signal)[i]
    }

    let mut cha_signal2: *mut u32 = f.get_sig_ptr2();

    for i in 1..n {
        println!("{}", unsafe { *cha_signal2.offset(i as isize) });
    }

    let mut cha_signal3: *mut [u32; n] = f.get_sig_ptr3();

    for i in 1..n {
        println!("{}", unsafe { (*cha_signal3)[i] });
    }

    let mut cha_signal4: &mut [u32; n] = f.get_sig_ptr4();

    for i in 1..n {
        println!("{}", cha_signal4[i]);
    }
}<|endoftext|>


<commit_before><commit_msg>Add codegen test for multiple `asm!` options<commit_after>// compile-flags: -O
// only-x86_64

#![crate_type = "rlib"]
#![feature(asm)]

// CHECK-LABEL: @pure
// CHECK-NOT: asm
// CHECK: ret void
#[no_mangle]
pub unsafe fn pure(x: i32) {
    let y: i32;
    asm!("", out("ax") y, in("bx") x, options(pure), options(nomem));
}

pub static mut VAR: i32 = 0;
pub static mut DUMMY_OUTPUT: i32 = 0;

// CHECK-LABEL: @readonly
// CHECK: call i32 asm
// CHECK: ret i32 1
#[no_mangle]
pub unsafe fn readonly() -> i32 {
    VAR = 1;
    asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly));
    VAR
}

// CHECK-LABEL: @nomem
// CHECK-NOT: store
// CHECK: call i32 asm
// CHECK: store
// CHECK: ret i32 2
#[no_mangle]
pub unsafe fn nomem() -> i32 {
    VAR = 1;
    asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(nomem));
    VAR = 2;
    VAR
}

// CHECK-LABEL: @not_nomem
// CHECK: store
// CHECK: call i32 asm
// CHECK: store
// CHECK: ret i32 2
#[no_mangle]
pub unsafe fn not_nomem() -> i32 {
    VAR = 1;
    asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly));
    VAR = 2;
    VAR
}
<|endoftext|>


<commit_before><commit_msg>dsfsd<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test to make sure trans doesn't choke on any of the intrinsics<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.

#![feature(extended_compare_and_swap)]
use std::sync::atomic::{AtomicIsize, ATOMIC_ISIZE_INIT};
use std::sync::atomic::Ordering::*;

static ATOMIC: AtomicIsize = ATOMIC_ISIZE_INIT;

fn main() {
    // Make sure trans can emit all the intrinsics correctly
    ATOMIC.compare_exchange(0, 1, Relaxed, Relaxed);
    ATOMIC.compare_exchange(0, 1, Acquire, Relaxed);
    ATOMIC.compare_exchange(0, 1, Release, Relaxed);
    ATOMIC.compare_exchange(0, 1, AcqRel, Relaxed);
    ATOMIC.compare_exchange(0, 1, SeqCst, Relaxed);
    ATOMIC.compare_exchange(0, 1, Acquire, Acquire);
    ATOMIC.compare_exchange(0, 1, AcqRel, Acquire);
    ATOMIC.compare_exchange(0, 1, SeqCst, Acquire);
    ATOMIC.compare_exchange(0, 1, SeqCst, SeqCst);
    ATOMIC.compare_exchange_weak(0, 1, Relaxed, Relaxed);
    ATOMIC.compare_exchange_weak(0, 1, Acquire, Relaxed);
    ATOMIC.compare_exchange_weak(0, 1, Release, Relaxed);
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Relaxed);
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Relaxed);
    ATOMIC.compare_exchange_weak(0, 1, Acquire, Acquire);
    ATOMIC.compare_exchange_weak(0, 1, AcqRel, Acquire);
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire);
    ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst);
}
<|endoftext|>


<commit_before><commit_msg>Add test for issue-58951<commit_after>// run-pass
#![feature(existential_type)]

existential type A: Iterator;
fn def_a() -> A { 0..1 }
pub fn use_a() {
    def_a().map(|x| x);
}

fn main() {}
<|endoftext|>


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

use std::path::Path;
use std::process::Command;
use std::fs;

use build_helper::output;
use cmake;

use build::Build;
use build::util::{exe, staticlib};

pub fn llvm(build: &Build, target: &str) {
    // If we're using a custom LLVM bail out here, but we can only use a
    // custom LLVM for the build triple.
    if let Some(config) = build.config.target_config.get(target) {
        if let Some(ref s) = config.llvm_config {
            return check_llvm_version(build, s);
        }
    }

    // If the cleaning trigger is newer than our built artifacts (or if the
    // artifacts are missing) then we keep going, otherwise we bail out.
    let dst = build.llvm_out(target);
    let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
    let llvm_config = dst.join("bin").join(exe("llvm-config", target));
    build.clear_if_dirty(&dst, &stamp);
    if fs::metadata(llvm_config).is_ok() {
        return
    }

    let _ = fs::remove_dir_all(&dst.join("build"));
    t!(fs::create_dir_all(&dst.join("build")));
    let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};

    // http://llvm.org/docs/CMake.html
    let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&dst)
       .profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
       .define("LLVM_ENABLE_ASSERTIONS", assertions)
       .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC")
       .define("LLVM_INCLUDE_EXAMPLES", "OFF")
       .define("LLVM_INCLUDE_TESTS", "OFF")
       .define("LLVM_INCLUDE_DOCS", "OFF")
       .define("LLVM_ENABLE_ZLIB", "OFF")
       .define("WITH_POLLY", "OFF")
       .define("LLVM_ENABLE_TERMINFO", "OFF")
       .define("LLVM_ENABLE_LIBEDIT", "OFF")
       .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string());

    if target.starts_with("i686") {
        cfg.define("LLVM_BUILD_32_BITS", "ON");
    }

    // http://llvm.org/docs/HowToCrossCompileLLVM.html
    if target != build.config.build {
        // FIXME: if the llvm root for the build triple is overridden then we
        //        should use llvm-tblgen from there, also should verify that it
        //        actually exists most of the time in normal installs of LLVM.
        let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
        cfg.define("CMAKE_CROSSCOMPILING", "True")
           .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
           .define("LLVM_TABLEGEN", &host)
           .define("LLVM_DEFAULT_TARGET_TRIPLE", target);
    }

    // MSVC handles compiler business itself
    if !target.contains("msvc") {
        if build.config.ccache {
           cfg.define("CMAKE_C_COMPILER", "ccache")
              .define("CMAKE_C_COMPILER_ARG1", build.cc(target))
              .define("CMAKE_CXX_COMPILER", "ccache")
              .define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
        } else {
           cfg.define("CMAKE_C_COMPILER", build.cc(target))
              .define("CMAKE_CXX_COMPILER", build.cxx(target));
        }
        cfg.build_arg("-j").build_arg(build.jobs().to_string());
    }

    // FIXME: we don't actually need to build all LLVM tools and all LLVM
    //        libraries here, e.g. we just want a few components and a few
    //        tools. Figure out how to filter them down and only build the right
    //        tools and libs on all platforms.
    cfg.build();
}

fn check_llvm_version(build: &Build, llvm_config: &Path) {
    if !build.config.llvm_version_check {
        return
    }

    let mut cmd = Command::new(llvm_config);
    let version = output(cmd.arg("--version"));
    if version.starts_with("3.5") || version.starts_with("3.6") ||
       version.starts_with("3.7") {
        return
    }
    panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
}

pub fn compiler_rt(build: &Build, target: &str) {
    let dst = build.compiler_rt_out(target);
    let arch = target.split('-').next().unwrap();
    let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
    let (dir, build_target, libname) = if target.contains("linux") {
        let os = if target.contains("android") {"-android"} else {""};
        let target = format!("clang_rt.builtins-{}{}", arch, os);
        ("linux".to_string(), target.clone(), target)
    } else if target.contains("darwin") {
        let target = format!("clang_rt.builtins_{}_osx", arch);
        ("builtins".to_string(), target.clone(), target)
    } else if target.contains("windows-gnu") {
        let target = format!("clang_rt.builtins-{}", arch);
        ("windows".to_string(), target.clone(), target)
    } else if target.contains("windows-msvc") {
        (format!("windows/{}", mode),
         "lib/builtins/builtins".to_string(),
         format!("clang_rt.builtins-{}", arch.replace("i686", "i386")))
    } else {
        panic!("can't get os from target: {}", target)
    };
    let output = dst.join("build/lib").join(dir)
                    .join(staticlib(&libname, target));
    build.compiler_rt_built.borrow_mut().insert(target.to_string(),
                                                output.clone());
    if fs::metadata(&output).is_ok() {
        return
    }
    let _ = fs::remove_dir_all(&dst);
    t!(fs::create_dir_all(&dst));
    let build_llvm_config = build.llvm_out(&build.config.build)
                                 .join("bin")
                                 .join(exe("llvm-config", &build.config.build));
    let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&dst)
       .profile(mode)
       .define("LLVM_CONFIG_PATH", build_llvm_config)
       .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
       .define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
       .define("COMPILER_RT_BUILD_EMUTLS", "OFF")
       .define("CMAKE_C_COMPILER", build.cc(target))
       .build_target(&build_target);
    cfg.build();
}
<commit_msg>rustbuild: Fix compiler-rt build on gnueabihf<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::path::Path;
use std::process::Command;
use std::fs;

use build_helper::output;
use cmake;

use build::Build;
use build::util::{exe, staticlib};

pub fn llvm(build: &Build, target: &str) {
    // If we're using a custom LLVM bail out here, but we can only use a
    // custom LLVM for the build triple.
    if let Some(config) = build.config.target_config.get(target) {
        if let Some(ref s) = config.llvm_config {
            return check_llvm_version(build, s);
        }
    }

    // If the cleaning trigger is newer than our built artifacts (or if the
    // artifacts are missing) then we keep going, otherwise we bail out.
    let dst = build.llvm_out(target);
    let stamp = build.src.join("src/rustllvm/llvm-auto-clean-trigger");
    let llvm_config = dst.join("bin").join(exe("llvm-config", target));
    build.clear_if_dirty(&dst, &stamp);
    if fs::metadata(llvm_config).is_ok() {
        return
    }

    let _ = fs::remove_dir_all(&dst.join("build"));
    t!(fs::create_dir_all(&dst.join("build")));
    let assertions = if build.config.llvm_assertions {"ON"} else {"OFF"};

    // http://llvm.org/docs/CMake.html
    let mut cfg = cmake::Config::new(build.src.join("src/llvm"));
    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&dst)
       .profile(if build.config.llvm_optimize {"Release"} else {"Debug"})
       .define("LLVM_ENABLE_ASSERTIONS", assertions)
       .define("LLVM_TARGETS_TO_BUILD", "X86;ARM;AArch64;Mips;PowerPC")
       .define("LLVM_INCLUDE_EXAMPLES", "OFF")
       .define("LLVM_INCLUDE_TESTS", "OFF")
       .define("LLVM_INCLUDE_DOCS", "OFF")
       .define("LLVM_ENABLE_ZLIB", "OFF")
       .define("WITH_POLLY", "OFF")
       .define("LLVM_ENABLE_TERMINFO", "OFF")
       .define("LLVM_ENABLE_LIBEDIT", "OFF")
       .define("LLVM_PARALLEL_COMPILE_JOBS", build.jobs().to_string());

    if target.starts_with("i686") {
        cfg.define("LLVM_BUILD_32_BITS", "ON");
    }

    // http://llvm.org/docs/HowToCrossCompileLLVM.html
    if target != build.config.build {
        // FIXME: if the llvm root for the build triple is overridden then we
        //        should use llvm-tblgen from there, also should verify that it
        //        actually exists most of the time in normal installs of LLVM.
        let host = build.llvm_out(&build.config.build).join("bin/llvm-tblgen");
        cfg.define("CMAKE_CROSSCOMPILING", "True")
           .define("LLVM_TARGET_ARCH", target.split('-').next().unwrap())
           .define("LLVM_TABLEGEN", &host)
           .define("LLVM_DEFAULT_TARGET_TRIPLE", target);
    }

    // MSVC handles compiler business itself
    if !target.contains("msvc") {
        if build.config.ccache {
           cfg.define("CMAKE_C_COMPILER", "ccache")
              .define("CMAKE_C_COMPILER_ARG1", build.cc(target))
              .define("CMAKE_CXX_COMPILER", "ccache")
              .define("CMAKE_CXX_COMPILER_ARG1", build.cxx(target));
        } else {
           cfg.define("CMAKE_C_COMPILER", build.cc(target))
              .define("CMAKE_CXX_COMPILER", build.cxx(target));
        }
        cfg.build_arg("-j").build_arg(build.jobs().to_string());
    }

    // FIXME: we don't actually need to build all LLVM tools and all LLVM
    //        libraries here, e.g. we just want a few components and a few
    //        tools. Figure out how to filter them down and only build the right
    //        tools and libs on all platforms.
    cfg.build();
}

fn check_llvm_version(build: &Build, llvm_config: &Path) {
    if !build.config.llvm_version_check {
        return
    }

    let mut cmd = Command::new(llvm_config);
    let version = output(cmd.arg("--version"));
    if version.starts_with("3.5") || version.starts_with("3.6") ||
       version.starts_with("3.7") {
        return
    }
    panic!("\n\nbad LLVM version: {}, need >=3.5\n\n", version)
}

pub fn compiler_rt(build: &Build, target: &str) {
    let dst = build.compiler_rt_out(target);
    let arch = target.split('-').next().unwrap();
    let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
    let (dir, build_target, libname) = if target.contains("linux") {
        let os = if target.contains("android") {"-android"} else {""};
        let arch = if arch.starts_with("arm") && target.contains("eabihf") {
            "armhf"
        } else {
            arch
        };
        let target = format!("clang_rt.builtins-{}{}", arch, os);
        ("linux".to_string(), target.clone(), target)
    } else if target.contains("darwin") {
        let target = format!("clang_rt.builtins_{}_osx", arch);
        ("builtins".to_string(), target.clone(), target)
    } else if target.contains("windows-gnu") {
        let target = format!("clang_rt.builtins-{}", arch);
        ("windows".to_string(), target.clone(), target)
    } else if target.contains("windows-msvc") {
        (format!("windows/{}", mode),
         "lib/builtins/builtins".to_string(),
         format!("clang_rt.builtins-{}", arch.replace("i686", "i386")))
    } else {
        panic!("can't get os from target: {}", target)
    };
    let output = dst.join("build/lib").join(dir)
                    .join(staticlib(&libname, target));
    build.compiler_rt_built.borrow_mut().insert(target.to_string(),
                                                output.clone());
    if fs::metadata(&output).is_ok() {
        return
    }
    let _ = fs::remove_dir_all(&dst);
    t!(fs::create_dir_all(&dst));
    let build_llvm_config = build.llvm_out(&build.config.build)
                                 .join("bin")
                                 .join(exe("llvm-config", &build.config.build));
    let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
    cfg.target(target)
       .host(&build.config.build)
       .out_dir(&dst)
       .profile(mode)
       .define("LLVM_CONFIG_PATH", build_llvm_config)
       .define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
       .define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
       .define("COMPILER_RT_BUILD_EMUTLS", "OFF")
       // inform about c/c++ compilers, the c++ compiler isn't actually used but
       // it's needed to get the initial configure to work on all platforms.
       .define("CMAKE_C_COMPILER", build.cc(target))
       .define("CMAKE_CXX_COMPILER", build.cc(target))
       .build_target(&build_target);
    cfg.build();
}
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>utility to measure mem usage<commit_after>#![feature(alloc)]
#![feature(libc)]

extern crate rand;
extern crate burst_trie;
extern crate libc;

use std::cmp::max;
use std::io::Read;
use std::io;
use std::thread;
use std::default::Default;
use burst_trie::BurstTrieMap;
use std::collections::{HashMap, BTreeMap};
use std::ascii::AsciiExt;
use libc::*;

extern {fn je_malloc_stats_print (write_cb: extern fn (*const c_void, *const c_char), cbopaque: *const c_void, opts: *const c_char);}
extern fn write_cb (_: *const c_void, message: *const c_char) {
    print! ("{}", String::from_utf8_lossy (unsafe {std::ffi::CStr::from_ptr (message as *const i8) .to_bytes()}));
}

fn stats_print() {
    unsafe {je_malloc_stats_print (write_cb, std::ptr::null(), std::ptr::null())};
}

fn main() {
    let words = gen_words(10000, 3, 25);
    // let words = read_words();
    println!("--sample--\n{:#?}--", &words[..10]);
    let mut word_counts: HashMap<String, usize> = Default::default();
    for word in words {
        let len = word.len();
        word_counts.insert(word, len);
    }
    stats_print();

    // word_counts.print_structure();
}

fn read_words() -> Vec<String> {
    let mut input = String::new();
    io::stdin().read_to_string(&mut input).unwrap();
    input.split_whitespace()
        .map(|w| w.trim_matches(|c| ['.', '"', ':', ';', ',', '!', '?', ')', '(', '_']
                  .contains(&c)))
        .map(|w| w.to_lowercase())
        .filter(|w| !w.is_empty())
        .collect()
}

fn gen_words(count: usize, min_len: usize, max_len: usize) -> Vec<String> {
    use rand::{Rng, StdRng, SeedableRng};
    static SEED: &'static[usize] = &[0, 1, 1, 2, 3, 5, 8, 13, 21, 34];
    let mut rng: StdRng = SeedableRng::from_seed(SEED);
    (0..count).map(|_| {
        let key_len = rng.gen_range(min_len, max_len);
        rng.gen_ascii_chars().take(key_len).collect::<String>()
    }).collect()
}<|endoftext|>


<commit_before><commit_msg>Pick more appropriate int types for fortuna<commit_after><|endoftext|>


<commit_before><commit_msg>Update matcher.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Rename RqlError{,Type} to QueryError{,Kind}<commit_after><|endoftext|>


<commit_before>use core::cmp::min;
use core::mem::size_of;
use core::ptr;

use common::scheduler::*;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * 4;
pub const PAGE_SIZE: usize = 4 * 1024;

pub const CLUSTER_ADDRESS: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * 4 ;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4 * 1024; // Of 4 K chunks

#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * size_of::<usize>()) as *mut usize,
                   address);
    }
}

pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() + number * CLUSTER_SIZE
}

pub unsafe fn cluster_init() {
    //First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    //Next, set all valid clusters to the free value
    //TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

pub unsafe fn alloc(size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && cluster_to_address(i) % align == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    size
}

pub unsafe fn unalloc(ptr: usize) {
    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc(size);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = min(old_size, size);

                    ::memmove(ret as *mut u8, ptr as *const u8, copy_size);
                }
                unalloc(ptr);
            }
        }
    }

    end_no_ints(reenable);

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}
<commit_msg>Implement common::memory::Memory<commit_after>use core::cmp::min;
use core::mem::size_of;
use core::ptr;

use common::scheduler::*;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * 4;
pub const PAGE_SIZE: usize = 4 * 1024;

pub const CLUSTER_ADDRESS: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * 4 ;
pub const CLUSTER_COUNT: usize = 1024 * 1024; // 4 GiB
pub const CLUSTER_SIZE: usize = 4 * 1024; // Of 4 K chunks

#[repr(packed)]
struct MemoryMapEntry {
    base: u64,
    len: u64,
    class: u32,
    acpi: u32,
}

struct Memory {
    address: usize,
}

impl Memory {
    pub fn new(size: usize) -> Option<Self> {
        let alloc = alloc(size);
        if alloc > 0 {
            Some(Memory { address: alloc })
        }
        else { None }
    }

    pub fn renew(&self, size: usize) -> Option<Self> {
        let realloc = realloc(self.address, size);
        if realloc > 0 {
            Some(Memory { address: realloc })
        }
        else { None }
    }
}

impl Drop for Memory {
    fn drop(&mut self) {
        unalloc(self.address)
    }
}

const MEMORY_MAP: *const MemoryMapEntry = 0x500 as *const MemoryMapEntry;

pub unsafe fn cluster(number: usize) -> usize {
    if number < CLUSTER_COUNT {
        ptr::read((CLUSTER_ADDRESS + number * size_of::<usize>()) as *const usize)
    } else {
        0
    }
}

pub unsafe fn set_cluster(number: usize, address: usize) {
    if number < CLUSTER_COUNT {
        ptr::write((CLUSTER_ADDRESS + number * size_of::<usize>()) as *mut usize,
                   address);
    }
}

pub unsafe fn address_to_cluster(address: usize) -> usize {
    if address >= CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() {
        (address - CLUSTER_ADDRESS - CLUSTER_COUNT * size_of::<usize>()) / CLUSTER_SIZE
    } else {
        0
    }
}

pub unsafe fn cluster_to_address(number: usize) -> usize {
    CLUSTER_ADDRESS + CLUSTER_COUNT * size_of::<usize>() + number * CLUSTER_SIZE
}

pub unsafe fn cluster_init() {
    //First, set all clusters to the not present value
    for cluster in 0..CLUSTER_COUNT {
        set_cluster(cluster, 0xFFFFFFFF);
    }

    //Next, set all valid clusters to the free value
    //TODO: Optimize this function
    for i in 0..((0x5000 - 0x500) / size_of::<MemoryMapEntry>()) {
        let entry = &*MEMORY_MAP.offset(i as isize);
        if entry.len > 0 && entry.class == 1 {
            for cluster in 0..CLUSTER_COUNT {
                let address = cluster_to_address(cluster);
                if address as u64 >= entry.base &&
                   (address as u64 + CLUSTER_SIZE as u64) <= (entry.base + entry.len) {
                    set_cluster(cluster, 0);
                }
            }
        }
    }
}

pub unsafe fn alloc(size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_aligned(size: usize, align: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size > 0 {
        let mut number = 0;
        let mut count = 0;

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 && cluster_to_address(i) % align == 0 {
                if count == 0 {
                    number = i;
                }
                count += 1;
                if count * CLUSTER_SIZE > size {
                    break;
                }
            } else {
                count = 0;
            }
        }
        if count * CLUSTER_SIZE > size {
            let address = cluster_to_address(number);
            for i in number..number + count {
                set_cluster(i, address);
            }
            ret = address;
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    ret
}

pub unsafe fn alloc_type<T>() -> *mut T {
    alloc(size_of::<T>()) as *mut T
}

pub unsafe fn alloc_size(ptr: usize) -> usize {
    let mut size = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                size += CLUSTER_SIZE;
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);

    size
}

pub unsafe fn unalloc(ptr: usize) {
    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if ptr > 0 {
        for i in address_to_cluster(ptr)..CLUSTER_COUNT {
            if cluster(i) == ptr {
                set_cluster(i, 0);
            } else {
                break;
            }
        }
    }

    //Memory allocation must be atomic
    end_no_ints(reenable);
}

pub unsafe fn realloc(ptr: usize, size: usize) -> usize {
    let mut ret = 0;

    //Memory allocation must be atomic
    let reenable = start_no_ints();

    if size == 0 {
        if ptr > 0 {
            unalloc(ptr);
        }
    } else {
        let old_size = alloc_size(ptr);
        if size <= old_size {
            ret = ptr;
        } else {
            ret = alloc(size);
            if ptr > 0 {
                if ret > 0 {
                    let copy_size = min(old_size, size);

                    ::memmove(ret as *mut u8, ptr as *const u8, copy_size);
                }
                unalloc(ptr);
            }
        }
    }

    end_no_ints(reenable);

    ret
}

pub unsafe fn realloc_inplace(ptr: usize, size: usize) -> usize {
    let old_size = alloc_size(ptr);
    if size <= old_size {
        size
    } else {
        old_size
    }
}

pub fn memory_used() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) != 0 && cluster(i) != 0xFFFFFFFF {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}

pub fn memory_free() -> usize {
    let mut ret = 0;
    unsafe {
        //Memory allocation must be atomic
        let reenable = start_no_ints();

        for i in 0..CLUSTER_COUNT {
            if cluster(i) == 0 {
                ret += CLUSTER_SIZE;
            }
        }

        //Memory allocation must be atomic
        end_no_ints(reenable);
    }
    ret
}
<|endoftext|>


<commit_before><commit_msg>Building list of new cells<commit_after><|endoftext|>


<commit_before><commit_msg>16 - pattern matching<commit_after>fn main() {
    let number: int = 13;
    // TODO ^ Try different values for `number`

    println!("Tell me about {}", number);
    match number {
        // Match a single value
        1 => println!("One!"),
        // Match several values
        2 | 3 | 5 | 7 | 11 => println!("This is a prime"),
        // Match an inclusive range
        13...19 => println!("A teen"),
        // Handle the rest of cases
        _ => println!("Ain't special"),
    }

    let boolean = true;
    // Match is an expression too
    let binary: int = match boolean {
        // The arms of a match must cover all the possible values
        false => 0,
        true => 1,
        // TODO ^ Try commenting out one of these arms
    };

    println!("{} -> {}", boolean, binary);
}
<|endoftext|>


<commit_before><commit_msg>Make sure we notice when a u16 is loaded at offset 1 into a u8 allocation<commit_after>// This should fail even without validation or Stacked Borrows.
// compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows

fn main() {
    // Make sure we notice when a u16 is loaded at offset 1 into a u8 allocation.
    // (This would be missed if u8 allocations are *always* at odd addresses.)
    for _ in 0..10 { // Try many times as this might work by chance.
        let x = [0u8; 4];
        let ptr = x.as_ptr().wrapping_offset(1).cast::<u16>();
        let _val = unsafe { *ptr }; //~ERROR but alignment
    }
}
<|endoftext|>


<commit_before><commit_msg>InviteState in Sync response is stripped events<commit_after><|endoftext|>


<commit_before><commit_msg>Start implementing new import format<commit_after>
use serde::{Serialize, Deserialize};
use std::path::{Path, PathBuf};
use std::fs;

use crate::api::user::UserInput;

const CONTEST_FILE_NAME: &str = "turingarena.yaml";

#[derive(Debug, Serialize, Deserialize)]
struct ContestFile {
    /// Title of the contest
    title: String,

    /// Start time of the contest
    start: Option<String>,

    /// End time of the contest
    end: Option<String>,

    /// Users of the contest
    users: Vec<ContestUser>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ContestUser {
    /// Id of the user
    id: String,

    /// Name of the user
    name: String,

    /// Access token of the user
    token: String,

    /// Role of the user. Currently supported: user, admin
    role: Option<String>,
}

/// Load a contest file
fn load_contest(path: &Path) -> Result<(), failure::Error> {
    let contest = serde_yaml::from_slice::<ContestFile>(&fs::read(path)?)?;

    for user in contest.users {
        let user_input = UserInput {
            id: user.id,
            display_name: user.name,
            token: user.token,
        };
    }

    Ok(())
}

/// Search for a contest file in the current directory
/// or parent directories
fn find_contest_file(path: &Path, max_depth: u32) -> Option<PathBuf> {
    let mut dir = path;

    for _ in 0..max_depth {
        let contest = dir.join(CONTEST_FILE_NAME);
        if contest.exists() {
            return Some(contest)
        }
        dir = match dir.parent() {
            Some(dir) => dir,
            None => return None,
        }
    }

    None
}

<|endoftext|>


<commit_before><commit_msg>Mem validation<commit_after>use elements::{Module, ResizableLimits, MemoryType};

pub struct Error(pub String);

pub fn validate_module(module: &Module) -> Result<(), Error> {
	if let Some(mem_section) = module.memory_section() {
		mem_section
			.entries()
			.iter()
			.map(MemoryType::validate)
			.collect::<Result<_, _>>()?
	}

	Ok(())
}

impl ResizableLimits {
	fn validate(&self) -> Result<(), Error> {
		if let Some(maximum) = self.maximum() {
			if self.initial() >= maximum {
				return Err(Error(format!(
					"maximum limit {} is lesser than minimum {}",
					maximum,
					self.initial()
				)));
			}
		}
		Ok(())
	}
}

impl MemoryType {
	fn validate(&self) -> Result<(), Error> {
		self.limits().validate()
	}
}

#[cfg(test)]
mod tests {
	use super::validate_module;
	use builder::module;
	use elements::{BlockType, ExportEntry, External, FunctionType, GlobalEntry, GlobalType,
	               ImportEntry, InitExpr, Internal, MemoryType, Opcode, Opcodes, TableType,
	               ValueType};

	#[test]
	fn empty_is_valid() {
		let module = module().build();
		assert!(validate_module(&module).is_ok());
	}

	#[test]
	fn mem_limits() {
		// min > max
		let m = module()
			.memory()
				.with_min(10)
				.with_max(Some(9))
				.build()
			.build();
		assert!(validate_module(&m).is_err());

		// mod is always valid without max.
		let m = module()
			.memory()
				.with_min(10)
				.build()
			.build();
		assert!(validate_module(&m).is_ok());
	}
}
<|endoftext|>


<commit_before>use backends::Backend;
use message::WireMessage;
use errors::Result;

pub struct NullBackend;

impl NullBackend {
    pub fn new() -> NullBackend {
        NullBackend {}
    }
}

impl Backend for NullBackend {
    fn panic_on_error(&self) -> bool {
        false
    }

    fn log_message(&self, _: WireMessage) -> Result<()> {
        Ok(())
    }
}<commit_msg>Add docs to NullBackend<commit_after>use backends::Backend;
use message::WireMessage;
use errors::Result;

/// The `NullBackend` is a utility backend which discards all messages
pub struct NullBackend;

impl NullBackend {
    /// Construct a new NullBackend
    pub fn new() -> NullBackend {
        NullBackend {}
    }
}

impl Backend for NullBackend {
    fn panic_on_error(&self) -> bool {
        false
    }

    /// Log a message.
    ///
    /// Logging a message with NullBackend is a noop and will never fail.
    fn log_message(&self, _: WireMessage) -> Result<()> {
        Ok(())
    }
}<|endoftext|>


<commit_before>use std::iter::Iterator;

use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, &File);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = File>>(&self, files: I) {
        for file in files {
            self.print_file(&file);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: &File) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", f);
        } else {
            info!("[File]: {}", f.id());
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: &File) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = File>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.owner_name())[..]);

            let id : String = file.id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<commit_msg>ui: Change to take Rc<RefCell<File>> instead of File<commit_after>use std::cell::RefCell;
use std::iter::Iterator;
use std::rc::Rc;
use std::ops::Deref;

use storage::file::File;

pub trait FilePrinter {

    fn new(verbose: bool, debug: bool) -> Self;

    /*
     * Print a single file
     */
    fn print_file(&self, Rc<RefCell<File>>);

    /*
     * Print a list of files
     */
    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        for file in files {
            self.print_file(file);
        }
    }

}

struct DebugPrinter {
    debug: bool,
}

impl FilePrinter for DebugPrinter {

    fn new(_: bool, debug: bool) -> DebugPrinter {
        DebugPrinter {
            debug: debug,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("[DebugPrinter] ->\n{:?}", f);
        }
    }

}

struct SimplePrinter {
    verbose:    bool,
    debug:      bool,
}

impl FilePrinter for SimplePrinter {

    fn new(verbose: bool, debug: bool) -> SimplePrinter {
        SimplePrinter {
            debug:      debug,
            verbose:    verbose,
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        if self.debug {
            debug!("{:?}", f);
        } else if self.verbose {
            info!("{}", &*f.deref().borrow());
        } else {
            info!("[File]: {}", f.deref().borrow().id());
        }
    }

}

pub struct TablePrinter {
    verbose:    bool,
    debug:      bool,
    sp:         SimplePrinter,
}

impl FilePrinter for TablePrinter {

    fn new(verbose: bool, debug: bool) -> TablePrinter {
        TablePrinter {
            debug:      debug,
            verbose:    verbose,
            sp:         SimplePrinter::new(verbose, debug),
        }
    }

    fn print_file(&self, f: Rc<RefCell<File>>) {
        self.sp.print_file(f);
    }

    fn print_files<I: Iterator<Item = Rc<RefCell<File>>>>(&self, files: I) {
        use prettytable::Table;
        use prettytable::row::Row;
        use prettytable::cell::Cell;

        let titles = row!["File#", "Owner", "ID"];

        let mut tab = Table::new();
        tab.set_titles(titles);

        let mut i = 0;
        for file in files {
            debug!("Printing file: {:?}", file);
            i += 1;
            let cell_i  = Cell::new(&format!("{}", i)[..]);
            let cell_o  = Cell::new(&format!("{}", file.deref().borrow().owner_name())[..]);

            let id : String = file.deref().borrow().id().clone().into();
            let cell_id = Cell::new(&id[..]);
            let row = Row::new(vec![cell_i, cell_o, cell_id]);
            tab.add_row(row);
        }

        if i != 0 {
            debug!("Printing {} table entries", i);
            tab.printstd();
        } else {
            debug!("Not printing table because there are zero entries");
        }
    }

}
<|endoftext|>


<commit_before><commit_msg>Obtain the stage input attributes from shader reflection<commit_after><|endoftext|>


<commit_before><commit_msg>Add feature(scoped) as thread::scoped is considered to be unstable<commit_after><|endoftext|>


<commit_before><commit_msg>added suit enum<commit_after><|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.

// write_volatile causes an LLVM assert with composite types

#![feature(volatile)]
use std::ptr::{read_volatile, write_volatile};

#[derive(Debug, Eq, PartialEq)]
struct A(u32);
#[derive(Debug, Eq, PartialEq)]
struct B(u64);
#[derive(Debug, Eq, PartialEq)]
struct C(u32, u32);
#[derive(Debug, Eq, PartialEq)]
struct D(u64, u64);
#[derive(Debug, Eq, PartialEq)]
struct E([u64; 32]);

fn main() {
    unsafe {
        let mut x: u32 = 0;
        write_volatile(&mut x, 1);
        assert_eq!(read_volatile(&x), 1);
        assert_eq!(x, 1);

        let mut x: u64 = 0;
        write_volatile(&mut x, 1);
        assert_eq!(read_volatile(&x), 1);
        assert_eq!(x, 1);

        let mut x = A(0);
        write_volatile(&mut x, A(1));
        assert_eq!(read_volatile(&x), A(1));
        assert_eq!(x, A(1));

        let mut x = B(0);
        write_volatile(&mut x, B(1));
        assert_eq!(read_volatile(&x), B(1));
        assert_eq!(x, B(1));

        let mut x = C(0, 0);
        write_volatile(&mut x, C(1, 1));
        assert_eq!(read_volatile(&x), C(1, 1));
        assert_eq!(x, C(1, 1));

        let mut x = D(0, 0);
        write_volatile(&mut x, D(1, 1));
        assert_eq!(read_volatile(&x), D(1, 1));
        assert_eq!(x, D(1, 1));

        let mut x = E([0; 32]);
        write_volatile(&mut x, E([1; 32]));
        assert_eq!(read_volatile(&x), E([1; 32]));
        assert_eq!(x, E([1; 32]));
    }
}
<commit_msg>FIN: ignore failing test on emscripten, see #41299<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.

// write_volatile causes an LLVM assert with composite types

// ignore-emscripten See #41299: probably a bad optimization

#![feature(volatile)]
use std::ptr::{read_volatile, write_volatile};

#[derive(Debug, Eq, PartialEq)]
struct A(u32);
#[derive(Debug, Eq, PartialEq)]
struct B(u64);
#[derive(Debug, Eq, PartialEq)]
struct C(u32, u32);
#[derive(Debug, Eq, PartialEq)]
struct D(u64, u64);
#[derive(Debug, Eq, PartialEq)]
struct E([u64; 32]);

fn main() {
    unsafe {
        let mut x: u32 = 0;
        write_volatile(&mut x, 1);
        assert_eq!(read_volatile(&x), 1);
        assert_eq!(x, 1);

        let mut x: u64 = 0;
        write_volatile(&mut x, 1);
        assert_eq!(read_volatile(&x), 1);
        assert_eq!(x, 1);

        let mut x = A(0);
        write_volatile(&mut x, A(1));
        assert_eq!(read_volatile(&x), A(1));
        assert_eq!(x, A(1));

        let mut x = B(0);
        write_volatile(&mut x, B(1));
        assert_eq!(read_volatile(&x), B(1));
        assert_eq!(x, B(1));

        let mut x = C(0, 0);
        write_volatile(&mut x, C(1, 1));
        assert_eq!(read_volatile(&x), C(1, 1));
        assert_eq!(x, C(1, 1));

        let mut x = D(0, 0);
        write_volatile(&mut x, D(1, 1));
        assert_eq!(read_volatile(&x), D(1, 1));
        assert_eq!(x, D(1, 1));

        let mut x = E([0; 32]);
        write_volatile(&mut x, E([1; 32]));
        assert_eq!(read_volatile(&x), E([1; 32]));
        assert_eq!(x, E([1; 32]));
    }
}
<|endoftext|>


<commit_before><commit_msg>Rollup merge of #44277 - mattico:test-33185, r=nikomatsakis<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.

#![allow(dead_code)]

#[macro_export]
macro_rules! state {
    ( $( $name:ident : $field:ty )* ) => (
        #[derive(Default)]
        struct State {
            $($name : $field),*
        }
    )
}

state! { x: i64 }

pub fn main() {
}
<|endoftext|>


<commit_before><commit_msg>Use tolerance > 0 in Path::contains_point()<commit_after><|endoftext|>


<commit_before><commit_msg>Add a version of the arithmetic example that returns an AST as an enum<commit_after>#![feature(plugin)]
#![plugin(peg_syntax_ext)]
use arithmetic::expression;

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Expression {
	Number(i64),
	Sum(Box<Expression>, Box<Expression>),
	Product(Box<Expression>, Box<Expression>),
}

peg! arithmetic(r#"
use super::Expression;

#[pub]
expression -> Expression
	= sum

sum -> Expression
	= l:product "+" r:product { Expression::Sum(Box::new(l), Box::new(r)) }
	/ product

product -> Expression
	= l:atom "*" r:atom { Expression::Product(Box::new(l), Box::new(r)) }
	/ atom

atom -> Expression
	= number
	/ "(" v:sum ")" { v }

number -> Expression
	= [0-9]+ { Expression::Number(match_str.parse().unwrap()) }
"#);

#[test]
fn main() {
	assert_eq!(expression("1+1"), Ok(Expression::Sum(
		Box::new(Expression::Number(1)),
		Box::new(Expression::Number(1)))
	));
	assert_eq!(expression("5*5"), Ok(Expression::Product(
		Box::new(Expression::Number(5)),
		Box::new(Expression::Number(5)))
	));
	assert_eq!(expression("2+3*4"), Ok(Expression::Sum(
		Box::new(Expression::Number(2)),
		Box::new(Expression::Product(
			Box::new(Expression::Number(3)),
			Box::new(Expression::Number(4))
		)),
	)));
	assert!(expression("(22+)+1").is_err());
	assert!(expression("1++1").is_err());
	assert!(expression("3)+1").is_err());
}
<|endoftext|>


<commit_before><commit_msg>Warn on errors writing to the backend<commit_after><|endoftext|>