<commit_before>// Copyright 2018 Evgeniy Reizner
//
// 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::fmt;
use std::str;
use std::mem;
use std::iter::FilterMap;
use std::slice::{
    Iter,
    IterMut,
};

use {
    Attribute,
    AttributeId,
    AttributeQNameRef,
    AttributeValue,
    QName,
    WriteBuffer,
};

/// An iterator over SVG attributes.
pub trait FilterSvgAttrs: Iterator {
    /// Filters SVG attributes.
    fn svg<'a>(self) -> FilterMap<Self, fn(&Attribute) -> Option<(AttributeId, &Attribute)>>
        where Self: Iterator<Item = &'a Attribute> + Sized,
    {
        fn is_svg(attr: &Attribute) -> Option<(AttributeId, &Attribute)> {
            if let QName::Id(_, id) = attr.name {
                return Some((id, attr));
            }

            None
        }

        self.filter_map(is_svg)
    }
}

impl<'a, I: Iterator<Item = &'a Attribute>> FilterSvgAttrs for I {}

/// An attributes list.
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    /// Constructs a new attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    #[inline]
    pub fn new() -> Attributes {
        Attributes(Vec::new())
    }

    /// Returns an optional reference to [`Attribute`].
    ///
    /// [`Attribute`]: struct.Attribute.html
    #[inline]
    pub fn get<'a, N>(&self, name: N) -> Option<&Attribute>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &self.0 {
            if v.name.as_ref() == name {
                return Some(v);
            }
        }

        None
    }

    /// Returns an optional mutable reference to [`Attribute`].
    ///
    /// [`Attribute`]: struct.Attribute.html
    #[inline]
    pub fn get_mut<'a, N>(&mut self, name: N) -> Option<&mut Attribute>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &mut self.0 {
            if v.name.as_ref() == name {
                return Some(v);
            }
        }

        None
    }

    /// Returns an optional reference to [`AttributeValue`].
    ///
    /// [`AttributeValue`]: enum.AttributeValue.html
    #[inline]
    pub fn get_value<'a, N>(&self, name: N) -> Option<&AttributeValue>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &self.0 {
            if v.name.as_ref() == name {
                return Some(&v.value);
            }
        }

        None
    }

    /// Returns an optional mutable reference to [`AttributeValue`].
    ///
    /// [`AttributeValue`]: enum.AttributeValue.html
    #[inline]
    pub fn get_value_mut<'a, N>(&mut self, name: N) -> Option<&mut AttributeValue>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &mut self.0 {
            if v.name.as_ref() == name {
                return Some(&mut v.value);
            }
        }

        None
    }

    /// Inserts a new attribute. Previous will be overwritten.
    ///
    /// # Panics
    ///
    /// During insert of a linked attribute. Use [`Node::set_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::set_attribute()`]: type.Node.html#method.set_attribute
    pub fn insert(&mut self, attr: Attribute) {
        if cfg!(debug_assertions) {
            if attr.is_link() || attr.is_func_link() {
                panic!("attribute with Link/FuncLink value must be set only via Node::set_attribute");
            }
        }

        self.insert_impl(attr);
    }

    /// Creates a new attribute from name and value and inserts it. Previous will be overwritten.
    ///
    /// [`Node`] attribute value can be set only via [`Node::set_attribute()`] method.
    ///
    /// [`Node`]: type.Node.html
    /// [`Node::set_attribute()`]: type.Node.html#method.set_attribute
    pub fn insert_from<'a, N, T>(&mut self, name: N, value: T)
        where AttributeQNameRef<'a>: From<N>, AttributeValue: From<T>
    {
        self.insert(Attribute::new(name, value));
    }

    /// Inserts a new link attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    pub fn insert_impl(&mut self, attr: Attribute) {
        // Increase capacity on first insert.
        if self.0.capacity() == 0 {
            self.0.reserve(16);
        }

        let idx = self.0.iter().position(|x| x.name == attr.name);
        match idx {
            // We use braces to discard return value.
            Some(i) => { mem::replace(&mut self.0[i], attr); }
            None => self.0.push(attr),
        }
    }

    /// Removes an existing attribute.
    ///
    /// # Panics
    ///
    /// During remove of a linked attribute. Use [`Node::remove_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::remove_attribute()`]: type.Node.html#method.remove_attribute
    pub fn remove<'a, N>(&mut self, name: N)
        where AttributeQNameRef<'a>: From<N>, N: Copy
    {
        // Checks that removed attribute is not linked.
        //
        // Since this check is expensive - we do it only in debug build.
        if cfg!(debug_assertions) {
            let name = AttributeQNameRef::from(name);
            let attr = self.0.iter().find(|x| x.name.as_ref() == name);
            if let Some(attr) = attr {
                if attr.is_link() || attr.is_func_link() {
                    panic!("attribute with Link/FuncLink value must be removed \
                            only via Node::remove_attribute");
                }
            }
        }

        self.remove_impl(name);
    }

    /// Removes an existing attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    pub fn remove_impl<'a, N>(&mut self, name: N)
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        let idx = self.0.iter().position(|x| x.name.as_ref() == name);
        if let Some(i) = idx {
            self.0.remove(i);
        }
    }

    /// Returns `true` if the container contains an attribute with such name.
    #[inline]
    pub fn contains<'a, N>(&self, name: N) -> bool
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        self.0.iter().any(|a| a.name.as_ref() == name)
    }

    /// Returns count of the attributes.
    #[inline]
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Returns `true` if attributes is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// Returns an iterator.
    #[inline]
    pub fn iter(&self) -> Iter<Attribute> {
        self.0.iter()
    }

    /// Returns a mutable iterator.
    #[inline]
    pub fn iter_mut(&mut self) -> IterMut<Attribute> {
        self.0.iter_mut()
    }

    /// Retains only elements specified by the predicate.
    ///
    /// # Panics
    ///
    /// During remove of a linked attribute. Use [`Node::remove_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::remove_attribute()`]: type.Node.html#method.remove_attribute
    #[inline]
    pub fn retain<F>(&mut self, mut f: F)
        where F: FnMut(&Attribute) -> bool
    {
        // Checks that removed attribute is not linked.
        //
        // Since this check is expensive - we do it only in debug build.
        if cfg!(debug_assertions) {
            for attr in &self.0 {
                if !f(attr) {
                    if attr.is_link() || attr.is_func_link() {
                        panic!("attribute with Link/FuncLink value must be removed \
                                only via Node::remove_attribute");
                    }
                }
            }
        }

        self.0.retain(f)
    }

    /// Clears the attributes list, removing all values.
    pub(crate) fn clear(&mut self) {
        self.0.clear();
    }
}

impl IntoIterator for Attributes {
    type Item = Attribute;
    type IntoIter = ::std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl fmt::Debug for Attributes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.is_empty() {
            return write!(f, "Attributes()");
        }

        let mut out = Vec::with_capacity(256);

        out.extend_from_slice(b"Attributes(");

        for attr in self.iter() {
            attr.write_buf(&mut out);
            out.push(b',');
            out.push(b' ');
        }

        out.pop();
        out.pop();
        out.push(b')');

        write!(f, "{}", str::from_utf8(&out).unwrap())
    }
}
<commit_msg>Added `FilterSvgAttrsMut`.<commit_after>// Copyright 2018 Evgeniy Reizner
//
// 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::fmt;
use std::str;
use std::mem;
use std::iter::FilterMap;
use std::slice::{
    Iter,
    IterMut,
};

use {
    Attribute,
    AttributeId,
    AttributeQNameRef,
    AttributeValue,
    QName,
    WriteBuffer,
};

/// An iterator over SVG attributes.
pub trait FilterSvgAttrs: Iterator {
    /// Filters SVG attributes.
    fn svg<'a>(self) -> FilterMap<Self, fn(&Attribute) -> Option<(AttributeId, &Attribute)>>
        where Self: Iterator<Item = &'a Attribute> + Sized
    {
        fn is_svg(attr: &Attribute) -> Option<(AttributeId, &Attribute)> {
            if let QName::Id(_, id) = attr.name {
                return Some((id, attr));
            }

            None
        }

        self.filter_map(is_svg)
    }
}

impl<'a, I: Iterator<Item = &'a Attribute>> FilterSvgAttrs for I {}

/// An iterator over SVG attributes.
pub trait FilterSvgAttrsMut: Iterator {
    /// Filters SVG attributes.
    fn svg<'a>(self) -> FilterMap<Self, fn(&mut Attribute) -> Option<(AttributeId, &mut Attribute)>>
        where Self: Iterator<Item = &'a mut Attribute> + Sized
    {
        fn is_svg(attr: &mut Attribute) -> Option<(AttributeId, &mut Attribute)> {
            if let QName::Id(_, id) = attr.name {
                return Some((id, attr));
            }

            None
        }

        self.filter_map(is_svg)
    }
}

impl<'a, I: Iterator<Item = &'a mut Attribute>> FilterSvgAttrsMut for I {}

/// An attributes list.
pub struct Attributes(Vec<Attribute>);

impl Attributes {
    /// Constructs a new attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    #[inline]
    pub fn new() -> Attributes {
        Attributes(Vec::new())
    }

    /// Returns an optional reference to [`Attribute`].
    ///
    /// [`Attribute`]: struct.Attribute.html
    #[inline]
    pub fn get<'a, N>(&self, name: N) -> Option<&Attribute>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &self.0 {
            if v.name.as_ref() == name {
                return Some(v);
            }
        }

        None
    }

    /// Returns an optional mutable reference to [`Attribute`].
    ///
    /// [`Attribute`]: struct.Attribute.html
    #[inline]
    pub fn get_mut<'a, N>(&mut self, name: N) -> Option<&mut Attribute>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &mut self.0 {
            if v.name.as_ref() == name {
                return Some(v);
            }
        }

        None
    }

    /// Returns an optional reference to [`AttributeValue`].
    ///
    /// [`AttributeValue`]: enum.AttributeValue.html
    #[inline]
    pub fn get_value<'a, N>(&self, name: N) -> Option<&AttributeValue>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &self.0 {
            if v.name.as_ref() == name {
                return Some(&v.value);
            }
        }

        None
    }

    /// Returns an optional mutable reference to [`AttributeValue`].
    ///
    /// [`AttributeValue`]: enum.AttributeValue.html
    #[inline]
    pub fn get_value_mut<'a, N>(&mut self, name: N) -> Option<&mut AttributeValue>
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        for v in &mut self.0 {
            if v.name.as_ref() == name {
                return Some(&mut v.value);
            }
        }

        None
    }

    /// Inserts a new attribute. Previous will be overwritten.
    ///
    /// # Panics
    ///
    /// During insert of a linked attribute. Use [`Node::set_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::set_attribute()`]: type.Node.html#method.set_attribute
    pub fn insert(&mut self, attr: Attribute) {
        if cfg!(debug_assertions) {
            if attr.is_link() || attr.is_func_link() {
                panic!("attribute with Link/FuncLink value must be set only via Node::set_attribute");
            }
        }

        self.insert_impl(attr);
    }

    /// Creates a new attribute from name and value and inserts it. Previous will be overwritten.
    ///
    /// [`Node`] attribute value can be set only via [`Node::set_attribute()`] method.
    ///
    /// [`Node`]: type.Node.html
    /// [`Node::set_attribute()`]: type.Node.html#method.set_attribute
    pub fn insert_from<'a, N, T>(&mut self, name: N, value: T)
        where AttributeQNameRef<'a>: From<N>, AttributeValue: From<T>
    {
        self.insert(Attribute::new(name, value));
    }

    /// Inserts a new link attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    pub fn insert_impl(&mut self, attr: Attribute) {
        // Increase capacity on first insert.
        if self.0.capacity() == 0 {
            self.0.reserve(16);
        }

        let idx = self.0.iter().position(|x| x.name == attr.name);
        match idx {
            // We use braces to discard return value.
            Some(i) => { mem::replace(&mut self.0[i], attr); }
            None => self.0.push(attr),
        }
    }

    /// Removes an existing attribute.
    ///
    /// # Panics
    ///
    /// During remove of a linked attribute. Use [`Node::remove_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::remove_attribute()`]: type.Node.html#method.remove_attribute
    pub fn remove<'a, N>(&mut self, name: N)
        where AttributeQNameRef<'a>: From<N>, N: Copy
    {
        // Checks that removed attribute is not linked.
        //
        // Since this check is expensive - we do it only in debug build.
        if cfg!(debug_assertions) {
            let name = AttributeQNameRef::from(name);
            let attr = self.0.iter().find(|x| x.name.as_ref() == name);
            if let Some(attr) = attr {
                if attr.is_link() || attr.is_func_link() {
                    panic!("attribute with Link/FuncLink value must be removed \
                            only via Node::remove_attribute");
                }
            }
        }

        self.remove_impl(name);
    }

    /// Removes an existing attribute.
    ///
    /// **Warning:** this method is for private use only. Never invoke it directly.
    pub fn remove_impl<'a, N>(&mut self, name: N)
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        let idx = self.0.iter().position(|x| x.name.as_ref() == name);
        if let Some(i) = idx {
            self.0.remove(i);
        }
    }

    /// Returns `true` if the container contains an attribute with such name.
    #[inline]
    pub fn contains<'a, N>(&self, name: N) -> bool
        where AttributeQNameRef<'a>: From<N>
    {
        let name = AttributeQNameRef::from(name);
        self.0.iter().any(|a| a.name.as_ref() == name)
    }

    /// Returns count of the attributes.
    #[inline]
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Returns `true` if attributes is empty.
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// Returns an iterator.
    #[inline]
    pub fn iter(&self) -> Iter<Attribute> {
        self.0.iter()
    }

    /// Returns a mutable iterator.
    #[inline]
    pub fn iter_mut(&mut self) -> IterMut<Attribute> {
        self.0.iter_mut()
    }

    /// Retains only elements specified by the predicate.
    ///
    /// # Panics
    ///
    /// During remove of a linked attribute. Use [`Node::remove_attribute()`] instead.
    ///
    /// Will panic only in debug build.
    ///
    /// [`Node::remove_attribute()`]: type.Node.html#method.remove_attribute
    #[inline]
    pub fn retain<F>(&mut self, mut f: F)
        where F: FnMut(&Attribute) -> bool
    {
        // Checks that removed attribute is not linked.
        //
        // Since this check is expensive - we do it only in debug build.
        if cfg!(debug_assertions) {
            for attr in &self.0 {
                if !f(attr) {
                    if attr.is_link() || attr.is_func_link() {
                        panic!("attribute with Link/FuncLink value must be removed \
                                only via Node::remove_attribute");
                    }
                }
            }
        }

        self.0.retain(f)
    }

    /// Clears the attributes list, removing all values.
    pub(crate) fn clear(&mut self) {
        self.0.clear();
    }
}

impl IntoIterator for Attributes {
    type Item = Attribute;
    type IntoIter = ::std::vec::IntoIter<Self::Item>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl fmt::Debug for Attributes {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.is_empty() {
            return write!(f, "Attributes()");
        }

        let mut out = Vec::with_capacity(256);

        out.extend_from_slice(b"Attributes(");

        for attr in self.iter() {
            attr.write_buf(&mut out);
            out.push(b',');
            out.push(b' ');
        }

        out.pop();
        out.pop();
        out.push(b')');

        write!(f, "{}", str::from_utf8(&out).unwrap())
    }
}
<|endoftext|>


<commit_before>use scaly::containers::Ref;
use scaly::Page;
use scalyc::parser::ProgramSyntax;

pub struct PlanBuilder {}

impl PlanBuilder {
    pub fn new(_rp: *mut Page) -> PlanBuilder {
        PlanBuilder {}
    }

    pub fn build(&mut self, _rp: *mut Page, _program_syntax: Ref<ProgramSyntax>) -> Ref<Module> {
        Ref::new(_rp, Module {})
    }
}

pub struct Module {}
<commit_msg>empty SyntaxVisitor implementation<commit_after>use scaly::containers::Ref;
use scaly::Page;
use scalyc::parser::*;

pub struct PlanBuilder {
    module_builder: Ref<ModuleBuilder>
}

impl PlanBuilder {
    pub fn new(_rp: *mut Page) -> PlanBuilder {
        PlanBuilder {
            module_builder: Ref::new(_rp, ModuleBuilder{})
        }
    }

    pub fn build(&mut self, _rp: *mut Page, mut program_syntax: Ref<ProgramSyntax>) -> Ref<Module> {
        program_syntax.accept(self);
        self.module_builder.export(_rp)
    }
}

impl SyntaxVisitor for PlanBuilder {
    fn open_program(&mut self, _program_syntax: Ref<ProgramSyntax>) -> bool {
        true
    }

    fn close_program(&mut self, _program_syntax: Ref<ProgramSyntax>) {}

    fn open_file(&mut self, _file_syntax: Ref<FileSyntax>) -> bool {
        true
    }

    fn close_file(&mut self, _file_syntax: Ref<FileSyntax>) {}

    fn visit_intrinsic(&mut self, _intrinsic_syntax: Ref<IntrinsicSyntax>) {}

    fn open_calculation(&mut self, _calculation_syntax: Ref<CalculationSyntax>) -> bool {
        true
    }

    fn close_calculation(&mut self, _calculation_syntax: Ref<CalculationSyntax>) {}

    fn open_operation(&mut self, _operation_syntax: Ref<OperationSyntax>) -> bool {
        true
    }

    fn close_operation(&mut self, _operation_syntax: Ref<OperationSyntax>) {}

    fn open_operand(&mut self, _operand_syntax: Ref<OperandSyntax>) -> bool {
        true
    }

    fn close_operand(&mut self, _operand_syntax: Ref<OperandSyntax>) {}

    fn visit_constant(&mut self, _constant_syntax: Ref<ConstantSyntax>) {}
}

pub struct ModuleBuilder {

}

impl ModuleBuilder {
    pub fn export(&self, _rp: *mut Page) -> Ref<Module> {
        Ref::new(_rp, Module {})
    }
}

pub struct Module {}<|endoftext|>


<commit_before>use crate::{
    analysis::{
        self, conversion_type::ConversionType, namespaces, ref_mode::RefMode,
        rust_type::parameter_rust_type,
    },
    env::Env,
    library::{self, ParameterDirection},
    nameutil,
    traits::*,
};
use std::cmp;

pub trait ToReturnValue {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String;
}

impl ToReturnValue for library::Parameter {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String {
        let rust_type = parameter_rust_type(
            env,
            self.typ,
            self.direction,
            self.nullable,
            RefMode::None,
            self.scope,
        );
        let mut name = rust_type.into_string();
        if is_trampoline
            && self.direction == library::ParameterDirection::Return
            && nameutil::is_gstring(&name)
        {
            name = "String".to_owned();
        }
        let type_str = match ConversionType::of(env, self.typ) {
            ConversionType::Unknown => format!("/*Unknown conversion*/{}", name),
            //TODO: records as in gtk_container_get_path_for_child
            _ => name,
        };
        format!(" -> {}", type_str)
    }
}

impl ToReturnValue for analysis::return_value::Info {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String {
        match self.parameter {
            Some(ref par) => {
                let name = par.to_return_value(env, is_trampoline);
                if self.nullable_return_is_error.is_some() && name.starts_with(" -> Option<") {
                    // Change ` -> Option<T>` to ` -> Result<T, glib::BoolError>`
                    format!(
                        " -> Result<{}, {}BoolError>",
                        &name[11..(name.len() - 1)],
                        if env.namespaces.glib_ns_id == namespaces::MAIN {
                            ""
                        } else {
                            "glib::"
                        }
                    )
                } else {
                    name
                }
            }
            None => String::new(),
        }
    }
}

fn out_parameter_as_return_parts(
    analysis: &analysis::functions::Info,
    is_glib_crate: bool,
) -> (&'static str, &'static str) {
    use crate::analysis::out_parameters::Mode::*;
    let num_out_args = analysis
        .outs
        .iter()
        .filter(|p| p.array_length.is_none())
        .count();
    let num_out_sizes = analysis
        .outs
        .iter()
        .filter(|p| p.array_length.is_some())
        .count();
    // We need to differentiate between array(s)'s size arguments and normal ones. If we have 2
    // "normal" arguments and one "size" argument, we still need to wrap them into "()" so we take
    // that into account. If the opposite, it means that there are two arguments in any case so
    // we need "()" too.
    let num_outs = cmp::max(num_out_args, num_out_sizes);
    match analysis.outs.mode {
        Normal | Combined => {
            if num_outs > 1 {
                ("(", ")")
            } else {
                ("", "")
            }
        }
        Optional => {
            if num_outs > 1 {
                if analysis.ret.nullable_return_is_error.is_some() {
                    if is_glib_crate {
                        ("Result<(", "), crate::BoolError>")
                    } else {
                        ("Result<(", "), glib::BoolError>")
                    }
                } else {
                    ("Option<(", ")>")
                }
            } else if analysis.ret.nullable_return_is_error.is_some() {
                if is_glib_crate {
                    ("Result<", ", crate::BoolError>")
                } else {
                    ("Result<", ", glib::BoolError>")
                }
            } else {
                ("Option<", ">")
            }
        }
        Throws(..) => {
            if num_outs == 1 + 1 {
                //if only one parameter except "glib::Error"
                (
                    "Result<",
                    if is_glib_crate {
                        ", crate::Error>"
                    } else {
                        ", glib::Error>"
                    },
                )
            } else {
                (
                    "Result<(",
                    if is_glib_crate {
                        "), crate::Error>"
                    } else {
                        "), glib::Error>"
                    },
                )
            }
        }
        None => unreachable!(),
    }
}

pub fn out_parameters_as_return(env: &Env, analysis: &analysis::functions::Info) -> String {
    let (prefix, suffix) =
        out_parameter_as_return_parts(analysis, env.namespaces.glib_ns_id == namespaces::MAIN);
    let mut return_str = String::with_capacity(100);
    return_str.push_str(" -> ");
    return_str.push_str(prefix);

    let array_lengths: Vec<_> = analysis
        .outs
        .iter()
        .filter_map(|p| p.array_length)
        .collect();

    let mut skip = 0;
    for (pos, par) in analysis.outs.iter().filter(|par| !par.is_error).enumerate() {
        // The actual return value is inserted with an empty name at position 0
        if !par.name.is_empty() {
            let mangled_par_name = nameutil::mangle_keywords(par.name.as_str());
            let param_pos = analysis
                .parameters
                .c_parameters
                .iter()
                .enumerate()
                .filter_map(|(pos, orig_par)| {
                    if orig_par.name == mangled_par_name {
                        Some(pos)
                    } else {
                        None
                    }
                })
                .next()
                .unwrap();
            if array_lengths.contains(&(param_pos as u32)) {
                skip += 1;
                continue;
            }
        }

        if pos > skip {
            return_str.push_str(", ")
        }
        let s = out_parameter_as_return(par, env);
        return_str.push_str(&s);
    }
    return_str.push_str(suffix);
    return_str
}

fn out_parameter_as_return(par: &library::Parameter, env: &Env) -> String {
    //TODO: upcasts?
    let rust_type = parameter_rust_type(
        env,
        par.typ,
        ParameterDirection::Return,
        par.nullable,
        RefMode::None,
        par.scope,
    );
    let name = rust_type.into_string();
    match ConversionType::of(env, par.typ) {
        ConversionType::Unknown => format!("/*Unknown conversion*/{}", name),
        _ => name,
    }
}
<commit_msg>More code improvements<commit_after>use crate::{
    analysis::{
        self, conversion_type::ConversionType, namespaces, ref_mode::RefMode,
        rust_type::parameter_rust_type,
    },
    env::Env,
    library::{self, ParameterDirection},
    nameutil::{is_gstring, mangle_keywords, use_glib_type},
    traits::*,
};
use std::cmp;

pub trait ToReturnValue {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String;
}

impl ToReturnValue for library::Parameter {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String {
        let rust_type = parameter_rust_type(
            env,
            self.typ,
            self.direction,
            self.nullable,
            RefMode::None,
            self.scope,
        );
        let mut name = rust_type.into_string();
        if is_trampoline
            && self.direction == library::ParameterDirection::Return
            && is_gstring(&name)
        {
            name = "String".to_owned();
        }
        let type_str = match ConversionType::of(env, self.typ) {
            ConversionType::Unknown => format!("/*Unknown conversion*/{}", name),
            //TODO: records as in gtk_container_get_path_for_child
            _ => name,
        };
        format!(" -> {}", type_str)
    }
}

impl ToReturnValue for analysis::return_value::Info {
    fn to_return_value(&self, env: &Env, is_trampoline: bool) -> String {
        match self.parameter {
            Some(ref par) => {
                let name = par.to_return_value(env, is_trampoline);
                if self.nullable_return_is_error.is_some() && name.starts_with(" -> Option<") {
                    // Change ` -> Option<T>` to ` -> Result<T, glib::BoolError>`
                    format!(
                        " -> Result<{}, {}BoolError>",
                        &name[11..(name.len() - 1)],
                        if env.namespaces.glib_ns_id == namespaces::MAIN {
                            ""
                        } else {
                            "glib::"
                        }
                    )
                } else {
                    name
                }
            }
            None => String::new(),
        }
    }
}

fn out_parameter_as_return_parts(
    analysis: &analysis::functions::Info,
    env: &Env,
) -> (&'static str, String) {
    use crate::analysis::out_parameters::Mode::*;
    let num_out_args = analysis
        .outs
        .iter()
        .filter(|p| p.array_length.is_none())
        .count();
    let num_out_sizes = analysis
        .outs
        .iter()
        .filter(|p| p.array_length.is_some())
        .count();
    // We need to differentiate between array(s)'s size arguments and normal ones. If we have 2
    // "normal" arguments and one "size" argument, we still need to wrap them into "()" so we take
    // that into account. If the opposite, it means that there are two arguments in any case so
    // we need "()" too.
    let num_outs = cmp::max(num_out_args, num_out_sizes);
    match analysis.outs.mode {
        Normal | Combined => {
            if num_outs > 1 {
                ("(", ")".to_owned())
            } else {
                ("", String::new())
            }
        }
        Optional => {
            if num_outs > 1 {
                if analysis.ret.nullable_return_is_error.is_some() {
                    (
                        "Result<(",
                        format!("), {}>", use_glib_type(env, "BoolError")),
                    )
                } else {
                    ("Option<(", ")>".to_owned())
                }
            } else if analysis.ret.nullable_return_is_error.is_some() {
                ("Result<", format!(", {}>", use_glib_type(env, "BoolError")))
            } else {
                ("Option<", ">".to_owned())
            }
        }
        Throws(..) => {
            if num_outs == 1 + 1 {
                //if only one parameter except "glib::Error"
                ("Result<", format!(", {}>", use_glib_type(env, "Error")))
            } else {
                ("Result<(", format!("), {}>", use_glib_type(env, "Error")))
            }
        }
        None => unreachable!(),
    }
}

pub fn out_parameters_as_return(env: &Env, analysis: &analysis::functions::Info) -> String {
    let (prefix, suffix) = out_parameter_as_return_parts(analysis, env);
    let mut return_str = String::with_capacity(100);
    return_str.push_str(" -> ");
    return_str.push_str(prefix);

    let array_lengths: Vec<_> = analysis
        .outs
        .iter()
        .filter_map(|p| p.array_length)
        .collect();

    let mut skip = 0;
    for (pos, par) in analysis.outs.iter().filter(|par| !par.is_error).enumerate() {
        // The actual return value is inserted with an empty name at position 0
        if !par.name.is_empty() {
            let mangled_par_name = mangle_keywords(par.name.as_str());
            let param_pos = analysis
                .parameters
                .c_parameters
                .iter()
                .enumerate()
                .filter_map(|(pos, orig_par)| {
                    if orig_par.name == mangled_par_name {
                        Some(pos)
                    } else {
                        None
                    }
                })
                .next()
                .unwrap();
            if array_lengths.contains(&(param_pos as u32)) {
                skip += 1;
                continue;
            }
        }

        if pos > skip {
            return_str.push_str(", ")
        }
        let s = out_parameter_as_return(par, env);
        return_str.push_str(&s);
    }
    return_str.push_str(&suffix);
    return_str
}

fn out_parameter_as_return(par: &library::Parameter, env: &Env) -> String {
    //TODO: upcasts?
    let rust_type = parameter_rust_type(
        env,
        par.typ,
        ParameterDirection::Return,
        par.nullable,
        RefMode::None,
        par.scope,
    );
    let name = rust_type.into_string();
    match ConversionType::of(env, par.typ) {
        ConversionType::Unknown => format!("/*Unknown conversion*/{}", name),
        _ => name,
    }
}
<|endoftext|>


<commit_before>#![feature(libc)]
extern crate libc;

use std::path::Path;
use std::str::from_utf8_unchecked;

/// Shortcut to path->filename conversion.
///
/// Returns the unchanged `path` if there is a character encoding error or something.
pub fn filename<'a> (path: &'a str) -> &'a str {
  match Path::new (path) .file_name() {
    Some (filename) => match filename.to_str() {
      Some (fstr) => if fstr.ends_with (".rs") {&fstr[0 .. fstr.len() - 3]} else {fstr},
      None => path},
    None => path}}

mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {super::filename (path)}}

// A trick to use the `try_s` macro from both the outside and inside of the crate.
//mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {::filename (path)}}

/// Returns on error, converting the `Err` value to `String` and prepending the current location.
///
/// cf. http://www.reddit.com/r/rust/comments/29wwzw/error_handling_and_result_types/cipcm9a
#[macro_export] macro_rules! try_s {
  ($e: expr) => {match $e {Ok (ok) => ok, Err (err) => {return Err (format! ("{}:{}] {}", ::gstuff::filename (file!()), line!(), err));}}}}

// Like `try_s`, but takes a reference.
#[macro_export] macro_rules! try_sp {
  ($e: expr) => {match $e {&Ok (ref ok) => ok,
    &Err (ref err) => {return Err (format! ("{}:{}] {:?}", ::gstuff::filename (file!()), line!(), err));}}}}

/// Returns a `Err(String)`, prepending the current location (file name and line number) to the string.
///
/// Examples: `ERR! ("too bad")`; `ERR! ("{}", foo)`;
#[macro_export] macro_rules! ERR {
  ($format: expr, $($args: tt)+) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!(), $($args)+))};
  ($format: expr) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!()))}}

/// A helper to build a string on the stack.
///
/// Given an array it makes a writeable cursor available to the passed code block.
///
/// Returns a &str slice pointing at memory between the array start and the cursor.
///
/// Example:
///
///     use std::io::Write;
///     let mut foobar: [u8; 128] = unsafe {std::mem::uninitialized()};
///     let foobar = gstring! (foobar, {
///         write! (foobar, "foo") .expect ("!write");
///         write! (foobar, "bar") .expect ("!write");
///     });
///
/// Alternatives: https://crates.io/crates/stack.
#[macro_export] macro_rules! gstring {($array: ident, $code: block) => {{
  let end = {
    let mut $array = ::std::io::Cursor::new (&mut $array[..]);
    let $array = &mut $array;
    $code;
    $array.position() as usize};
  unsafe {::std::str::from_utf8_unchecked (&$array[0..end])}}}}

/// Takes a netstring from the front of the slice.
///
/// Returns the unpacked netstring and the remainder of the slice.
pub fn netstring (at: &[u8]) -> Result<(&[u8], &[u8]), String> {
  let length_end = match at.iter().position (|&ch| ch < b'0' || ch > b'9') {Some (l) if l > 0 => l, _ => return ERR! ("No len.")};
  match at.get (length_end) {Some (&ch) if ch == b':' => (), _ => return ERR! ("No colon.")};
  let length = unsafe {from_utf8_unchecked (&at[0 .. length_end])};
  let length: usize = try_s! (length.parse());
  let bulk_pos = 0 + length_end + 1;
  let bulk_end = bulk_pos + length;
  match at.get (bulk_end) {Some (&ch) if ch == b',' => (), _ => return ERR! ("No comma.")}
  Ok ((&at[bulk_pos .. bulk_end], &at[bulk_end + 1 ..]))}

/// Wraps `gethostname` to fetch the current hostname into a temporary buffer.
#[cfg(unix)]
pub fn with_hostname (visitor: &mut FnMut (&[u8])) -> Result<(), io::Error> {
  use libc::{c_int, c_char, size_t, gethostname};  // http://man7.org/linux/man-pages/man2/gethostname.2.html
  use std::ffi::CStr;
  use std::io;

  let mut buf = [0; 128];
  let rc = unsafe {gethostname (buf.as_mut_ptr(), (buf.len() - 1) as size_t)};
  if rc == 0 {
    let cs = unsafe {CStr::from_ptr (buf.as_ptr())};
    Ok (visitor (cs.to_bytes()))
  } else {
    Err (io::Error::last_os_error())}}

#[cfg(unix)] #[test]
fn test_hostname() {
  let mut hostname = String::new();
  with_hostname (|bytes| hostname = String::from_utf8_lossy (bytes));}
<commit_msg>with_hostname fixes.<commit_after>#![feature(libc)]
extern crate libc;

use std::path::Path;
use std::str::from_utf8_unchecked;

/// Shortcut to path->filename conversion.
///
/// Returns the unchanged `path` if there is a character encoding error or something.
pub fn filename<'a> (path: &'a str) -> &'a str {
  match Path::new (path) .file_name() {
    Some (filename) => match filename.to_str() {
      Some (fstr) => if fstr.ends_with (".rs") {&fstr[0 .. fstr.len() - 3]} else {fstr},
      None => path},
    None => path}}

mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {super::filename (path)}}

// A trick to use the `try_s` macro from both the outside and inside of the crate.
//mod gstuff {pub fn filename<'a> (path: &'a str) -> &'a str {::filename (path)}}

/// Returns on error, converting the `Err` value to `String` and prepending the current location.
///
/// cf. http://www.reddit.com/r/rust/comments/29wwzw/error_handling_and_result_types/cipcm9a
#[macro_export] macro_rules! try_s {
  ($e: expr) => {match $e {Ok (ok) => ok, Err (err) => {return Err (format! ("{}:{}] {}", ::gstuff::filename (file!()), line!(), err));}}}}

// Like `try_s`, but takes a reference.
#[macro_export] macro_rules! try_sp {
  ($e: expr) => {match $e {&Ok (ref ok) => ok,
    &Err (ref err) => {return Err (format! ("{}:{}] {:?}", ::gstuff::filename (file!()), line!(), err));}}}}

/// Returns a `Err(String)`, prepending the current location (file name and line number) to the string.
///
/// Examples: `ERR! ("too bad")`; `ERR! ("{}", foo)`;
#[macro_export] macro_rules! ERR {
  ($format: expr, $($args: tt)+) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!(), $($args)+))};
  ($format: expr) => {Err (format! (concat! ("{}:{}] ", $format), ::gstuff::filename (file!()), line!()))}}

/// A helper to build a string on the stack.
///
/// Given an array it makes a writeable cursor available to the passed code block.
///
/// Returns a &str slice pointing at memory between the array start and the cursor.
///
/// Example:
///
///     use std::io::Write;
///     let mut foobar: [u8; 128] = unsafe {std::mem::uninitialized()};
///     let foobar = gstring! (foobar, {
///         write! (foobar, "foo") .expect ("!write");
///         write! (foobar, "bar") .expect ("!write");
///     });
///
/// Alternatives: https://crates.io/crates/stack.
#[macro_export] macro_rules! gstring {($array: ident, $code: block) => {{
  let end = {
    let mut $array = ::std::io::Cursor::new (&mut $array[..]);
    let $array = &mut $array;
    $code;
    $array.position() as usize};
  unsafe {::std::str::from_utf8_unchecked (&$array[0..end])}}}}

/// Takes a netstring from the front of the slice.
///
/// Returns the unpacked netstring and the remainder of the slice.
pub fn netstring (at: &[u8]) -> Result<(&[u8], &[u8]), String> {
  let length_end = match at.iter().position (|&ch| ch < b'0' || ch > b'9') {Some (l) if l > 0 => l, _ => return ERR! ("No len.")};
  match at.get (length_end) {Some (&ch) if ch == b':' => (), _ => return ERR! ("No colon.")};
  let length = unsafe {from_utf8_unchecked (&at[0 .. length_end])};
  let length: usize = try_s! (length.parse());
  let bulk_pos = 0 + length_end + 1;
  let bulk_end = bulk_pos + length;
  match at.get (bulk_end) {Some (&ch) if ch == b',' => (), _ => return ERR! ("No comma.")}
  Ok ((&at[bulk_pos .. bulk_end], &at[bulk_end + 1 ..]))}

/// Wraps `gethostname` to fetch the current hostname into a temporary buffer.
#[cfg(unix)]
pub fn with_hostname (visitor: &mut FnMut (&[u8])) -> Result<(), std::io::Error> {
  use libc::{size_t, gethostname};  // http://man7.org/linux/man-pages/man2/gethostname.2.html
  use std::ffi::CStr;
  use std::io;

  let mut buf = [0; 128];
  let rc = unsafe {gethostname (buf.as_mut_ptr(), (buf.len() - 1) as size_t)};
  if rc == 0 {
    let cs = unsafe {CStr::from_ptr (buf.as_ptr())};
    Ok (visitor (cs.to_bytes()))
  } else {
    Err (io::Error::last_os_error())}}

#[cfg(unix)] #[test]
fn test_hostname() {
  let mut hostname = String::new();
  with_hostname (&mut |bytes| hostname = String::from_utf8_lossy (bytes) .into_owned()) .unwrap();}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

//! This crate provides definitions for types that are intrinsic in
//! GObject introspection, unlike all other types that have a definition in
//! a GIR file. All crates generated from GObject introspection data should
//! use these shared definitions.
//!
//! Some types are omitted because a suitable equivalent is readily available
//! in Rust:
//!
//! 1. Fixed-size integer types. These have straightforward built-in
//!    counterparts in Rust.
//! 2. Strings can have GI types `utf8` or `filename`. In the FFI all string
//!    values are represented as raw pointers to `gchar`. A safe
//!    representation of C strings in idiomatic Rust bindings
//!    needs some wrapper types which are not defined here.

extern crate libc;

// The fundamental types are defined in Python module giscanner.ast

pub mod primitive {

    //! Definitions for primitive fundamental types.
    //!
    //! Values of these types don't have associated semantics or state
    //! that would necessitate some kind of wrapper types in safe Rust
    //! bindings. Therefore, these types can be used in both
    //! FFI declarations and idiomatic Rust bindings, unlikely to require
    //! name disambiguation with any generated or binding types.
    //!
    //! The untyped pointer types are also defined in this module,
    //! because safe Rust bindings are unlikely to need to reuse their names.

    #![allow(non_camel_case_types)]

    use libc;

    pub type gboolean       = libc::c_int;
    pub type gchar          = libc::c_char;
    pub type guchar         = libc::c_uchar;
    pub type gshort         = libc::c_short;
    pub type gushort        = libc::c_ushort;
    pub type gint           = libc::c_int;
    pub type guint          = libc::c_uint;
    pub type glong          = libc::c_long;
    pub type gulong         = libc::c_ulong;
    pub type gsize          = libc::size_t;
    pub type gssize         = libc::ssize_t;
    pub type gintptr        = libc::intptr_t;
    pub type guintptr       = libc::uintptr_t;
    pub type gfloat         = libc::c_float;
    pub type gdouble        = libc::c_double;
    pub type gunichar       = u32;
    pub type gpointer       = *mut   libc::c_void;
    pub type gconstpointer  = *const libc::c_void;

    pub const FALSE: gboolean = 0;
    pub const TRUE : gboolean = 1;
}

// For -sys crates only dealing with FFI types, all public names defined
// in this crate should be conflict-free, so we make them available at the
// crate level handy for glob-importing.
// FIXME: Can't glob-import due to https://github.com/rust-lang/rust/issues/4865,
// which is fixed by Rust 1.4.0
pub use primitive::{gboolean, gchar, guchar, gshort, gushort, gint, guint};
pub use primitive::{glong, gulong, gsize, gssize, gintptr, guintptr};
pub use primitive::{gfloat, gdouble, gunichar, gpointer, gconstpointer};
pub use primitive::{FALSE, TRUE};

/// An integer type that designates GObject type identifiers.
///
/// `GType` is considered a fundamental type, regardless of being also
/// introspected both in GLib and GObject. Unlike the primitive types,
/// valid values of `GType` can only result from type registration,
/// so the safe bindings are likely to provide their own `GType` wrapper.
pub type GType = gsize;
<commit_msg>Improved comments<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013-2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

//! This crate provides definitions for types that are intrinsic in
//! GObject introspection, unlike all other types that have a definition in
//! a GIR file. All crates generated from GObject introspection data should
//! use these shared definitions.
//!
//! Some types are omitted because a suitable equivalent is readily available
//! in Rust:
//!
//! 1. Fixed-size integer types. These have straightforward built-in
//!    counterparts in Rust.
//! 2. Strings can have GI types `utf8` or `filename`. In the FFI all string
//!    values are represented as raw pointers to `gchar`. A safe
//!    representation of C strings in idiomatic Rust bindings
//!    needs some wrapper types which are not defined here.

extern crate libc;

// The list of supported fundamental types can be obtained from the code of
// the Python module giscanner.ast, part of gobject-introspection tools:
// https://git.gnome.org/browse/gobject-introspection/tree/giscanner/ast.py

pub mod primitive {

    //! Definitions for primitive fundamental types.
    //!
    //! Values of these types don't have associated semantics or state
    //! that would necessitate some kind of wrapper types in safe Rust
    //! bindings. Therefore, these types can be used in both
    //! FFI declarations and idiomatic Rust bindings, unlikely to require
    //! name disambiguation with any generated or binding types.
    //!
    //! The untyped pointer types are also defined in this module,
    //! because safe Rust bindings are unlikely to need to reuse their names.

    #![allow(non_camel_case_types)]

    use libc;

    pub type gboolean       = libc::c_int;
    pub type gchar          = libc::c_char;
    pub type guchar         = libc::c_uchar;
    pub type gshort         = libc::c_short;
    pub type gushort        = libc::c_ushort;
    pub type gint           = libc::c_int;
    pub type guint          = libc::c_uint;
    pub type glong          = libc::c_long;
    pub type gulong         = libc::c_ulong;
    pub type gsize          = libc::size_t;
    pub type gssize         = libc::ssize_t;
    pub type gintptr        = libc::intptr_t;
    pub type guintptr       = libc::uintptr_t;
    pub type gfloat         = libc::c_float;
    pub type gdouble        = libc::c_double;
    pub type gunichar       = u32;
    pub type gpointer       = *mut   libc::c_void;
    pub type gconstpointer  = *const libc::c_void;

    pub const FALSE: gboolean = 0;
    pub const TRUE : gboolean = 1;
}

// For -sys crates only dealing with FFI types, all public names defined
// in this crate should be conflict-free, so we make them available at the
// crate level handy for glob-importing.
// FIXME: Can't glob-import here due to https://github.com/rust-lang/rust/issues/4865,
// which is fixed by Rust 1.4.0
pub use primitive::{gboolean, gchar, guchar, gshort, gushort, gint, guint};
pub use primitive::{glong, gulong, gsize, gssize, gintptr, guintptr};
pub use primitive::{gfloat, gdouble, gunichar, gpointer, gconstpointer};
pub use primitive::{FALSE, TRUE};

/// An integer type that designates GObject type identifiers.
///
/// `GType` is considered a fundamental type, regardless of being also
/// introspected both in GLib and GObject. Unlike the primitive types,
/// valid values of `GType` can only result from type registration,
/// so the safe bindings are likely to provide their own `GType` wrapper.
pub type GType = gsize;
<|endoftext|>


<commit_before>#![feature(rustc_private)]

extern crate rustc;
extern crate rustc_interface;
extern crate rustc_driver;
extern crate syntax;

use rustc::session::DiagnosticOutput;
use rustc::session::config::{Input, Options,
                             OutputType, OutputTypes};
use rustc_interface::interface;
use syntax::source_map::FileName;

use std::path::PathBuf;

fn main() {
    let src = r#"
    fn main() {}
    "#;

    let args: Vec<String> = std::env::args().collect();

    if args.len() < 4 {
        panic!("expected rustc path");
    }

    let tmpdir = PathBuf::from(&args[1]);

    let mut sysroot = PathBuf::from(&args[3]);
    sysroot.pop();
    sysroot.pop();

    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());

    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
}

fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
    let mut opts = Options::default();
    opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
    opts.maybe_sysroot = Some(sysroot);

    if let Ok(linker) = std::env::var("RUSTC_LINKER") {
        opts.cg.linker = Some(linker.into());
    }

    let name = FileName::anon_source_code(&code);
    let input = Input::Str { name, input: code };

    let config = interface::Config {
        opts,
        crate_cfg: Default::default(),
        input,
        input_path: None,
        output_file: Some(output),
        output_dir: None,
        file_loader: None,
        diagnostic_output: DiagnosticOutput::Default,
        stderr: None,
        crate_name: None,
        lint_caps: Default::default(),
        register_lints: None,
        override_queries: None,
        registry: rustc_driver::diagnostics_registry(),
    };

    interface::run_compiler(config, |compiler| {
        // This runs all the passes prior to linking, too.
        compiler.link().ok();
    });
}
<commit_msg>Fix test.<commit_after>#![feature(rustc_private)]

extern crate rustc;
extern crate rustc_interface;
extern crate rustc_driver;
extern crate syntax;

use rustc::session::DiagnosticOutput;
use rustc::session::config::{Input, Options,
                             OutputType, OutputTypes};
use rustc_interface::interface;
use syntax::source_map::FileName;

use std::path::PathBuf;

fn main() {
    let src = r#"
    fn main() {}
    "#;

    let args: Vec<String> = std::env::args().collect();

    if args.len() < 4 {
        panic!("expected rustc path");
    }

    let tmpdir = PathBuf::from(&args[1]);

    let mut sysroot = PathBuf::from(&args[3]);
    sysroot.pop();
    sysroot.pop();

    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());

    compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
}

fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
    let mut opts = Options::default();
    opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
    opts.maybe_sysroot = Some(sysroot);

    if let Ok(linker) = std::env::var("RUSTC_LINKER") {
        opts.cg.linker = Some(linker.into());
    }

    let name = FileName::anon_source_code(&code);
    let input = Input::Str { name, input: code };

    let config = interface::Config {
        opts,
        crate_cfg: Default::default(),
        input,
        input_path: None,
        output_file: Some(output),
        output_dir: None,
        file_loader: None,
        diagnostic_output: DiagnosticOutput::Default,
        stderr: None,
        crate_name: None,
        lint_caps: Default::default(),
        register_lints: None,
        override_queries: None,
        registry: rustc_driver::diagnostics_registry(),
    };

    interface::run_compiler(config, |compiler| {
        // This runs all the passes prior to linking, too.
        let linker = compiler.enter(|queries| {
            queries.linker()
        });
        if let Ok(linker) = linker {
            linker.link();
        }
    });
}
<|endoftext|>


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

//! Numeric traits for generic mathematics

use std::ops::{Add, Sub, Mul, Div, Rem};

pub use bounds::Bounded;
pub use float::Float;
pub use identities::{Zero, One};
pub use ops::checked::*;
pub use ops::saturating::Saturating;
pub use sign::{Signed, Unsigned};
pub use int::PrimInt;
pub use cast::*;

pub mod identities;
pub mod sign;
pub mod ops;
pub mod bounds;
pub mod float;
pub mod int;
pub mod cast;

/// The base trait for numeric types
pub trait Num: PartialEq + Zero + One
    + Add<Output = Self> + Sub<Output = Self>
    + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
{
    type FromStrRadixErr;

    /// Convert from a string and radix <= 36.
    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
}

macro_rules! int_trait_impl {
    ($name:ident for $($t:ty)*) => ($(
        impl $name for $t {
            type FromStrRadixErr = ::std::num::ParseIntError;
            fn from_str_radix(s: &str, radix: u32)
                              -> Result<Self, ::std::num::ParseIntError>
            {
                <$t>::from_str_radix(s, radix)
            }
        }
    )*)
}
int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);

pub enum FloatErrorKind {
    Empty,
    Invalid,
}
pub struct ParseFloatError {
    pub kind: FloatErrorKind,
}

macro_rules! float_trait_impl {
    ($name:ident for $($t:ty)*) => ($(
        impl $name for $t {
            type FromStrRadixErr = ParseFloatError;

            fn from_str_radix(src: &str, radix: u32)
                              -> Result<Self, Self::FromStrRadixErr>
            {
                use self::FloatErrorKind::*;
                use self::ParseFloatError as PFE;

                // Special values
                match src {
                    "inf"   => return Ok(Float::infinity()),
                    "-inf"  => return Ok(Float::neg_infinity()),
                    "NaN"   => return Ok(Float::nan()),
                    _       => {},
                }

                fn slice_shift_char(src: &str) -> Option<(char, &str)> {
                    src.chars().nth(0).map(|ch| (ch, &src[1..]))
                }

                let (is_positive, src) =  match slice_shift_char(src) {
                    None             => return Err(PFE { kind: Empty }),
                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
                    Some(('-', src)) => (false, src),
                    Some((_, _))     => (true,  src),
                };

                // The significand to accumulate
                let mut sig = if is_positive { 0.0 } else { -0.0 };
                // Necessary to detect overflow
                let mut prev_sig = sig;
                let mut cs = src.chars().enumerate();
                // Exponent prefix and exponent index offset
                let mut exp_info = None::<(char, usize)>;

                // Parse the integer part of the significand
                for (i, c) in cs.by_ref() {
                    match c.to_digit(radix) {
                        Some(digit) => {
                            // shift significand one digit left
                            sig = sig * (radix as $t);

                            // add/subtract current digit depending on sign
                            if is_positive {
                                sig = sig + ((digit as isize) as $t);
                            } else {
                                sig = sig - ((digit as isize) as $t);
                            }

                            // Detect overflow by comparing to last value, except
                            // if we've not seen any non-zero digits.
                            if prev_sig != 0.0 {
                                if is_positive && sig <= prev_sig
                                    { return Ok(Float::infinity()); }
                                if !is_positive && sig >= prev_sig
                                    { return Ok(Float::neg_infinity()); }

                                // Detect overflow by reversing the shift-and-add process
                                if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
                                    { return Ok(Float::infinity()); }
                                if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
                                    { return Ok(Float::neg_infinity()); }
                            }
                            prev_sig = sig;
                        },
                        None => match c {
                            'e' | 'E' | 'p' | 'P' => {
                                exp_info = Some((c, i + 1));
                                break;  // start of exponent
                            },
                            '.' => {
                                break;  // start of fractional part
                            },
                            _ => {
                                return Err(PFE { kind: Invalid });
                            },
                        },
                    }
                }

                // If we are not yet at the exponent parse the fractional
                // part of the significand
                if exp_info.is_none() {
                    let mut power = 1.0;
                    for (i, c) in cs.by_ref() {
                        match c.to_digit(radix) {
                            Some(digit) => {
                                // Decrease power one order of magnitude
                                power = power / (radix as $t);
                                // add/subtract current digit depending on sign
                                sig = if is_positive {
                                    sig + (digit as $t) * power
                                } else {
                                    sig - (digit as $t) * power
                                };
                                // Detect overflow by comparing to last value
                                if is_positive && sig < prev_sig
                                    { return Ok(Float::infinity()); }
                                if !is_positive && sig > prev_sig
                                    { return Ok(Float::neg_infinity()); }
                                prev_sig = sig;
                            },
                            None => match c {
                                'e' | 'E' | 'p' | 'P' => {
                                    exp_info = Some((c, i + 1));
                                    break; // start of exponent
                                },
                                _ => {
                                    return Err(PFE { kind: Invalid });
                                },
                            },
                        }
                    }
                }

                // Parse and calculate the exponent
                let exp = match exp_info {
                    Some((c, offset)) => {
                        let base = match c {
                            'E' | 'e' if radix == 10 => 10.0,
                            'P' | 'p' if radix == 16 => 2.0,
                            _ => return Err(PFE { kind: Invalid }),
                        };

                        // Parse the exponent as decimal integer
                        let src = &src[offset..];
                        let (is_positive, exp) = match slice_shift_char(src) {
                            Some(('-', src)) => (false, src.parse::<usize>()),
                            Some(('+', src)) => (true,  src.parse::<usize>()),
                            Some((_, _))     => (true,  src.parse::<usize>()),
                            None             => return Err(PFE { kind: Invalid }),
                        };

                        match (is_positive, exp) {
                            (true,  Ok(exp)) => base.powi(exp as i32),
                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
                        }
                    },
                    None => 1.0, // no exponent
                };

                Ok(sig * exp)
            }
        }
    )*)
}
float_trait_impl!(Num for f32 f64);
<commit_msg>Reapply ebed6756de732f959bbc72bbb9ec8c4e28b19143<commit_after>// Copyright 2013-2014 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.

//! Numeric traits for generic mathematics

use std::ops::{Add, Sub, Mul, Div, Rem};

pub use bounds::Bounded;
pub use float::Float;
pub use identities::{Zero, One};
pub use ops::checked::*;
pub use ops::saturating::Saturating;
pub use sign::{Signed, Unsigned};
pub use int::PrimInt;
pub use cast::*;

pub mod identities;
pub mod sign;
pub mod ops;
pub mod bounds;
pub mod float;
pub mod int;
pub mod cast;

/// The base trait for numeric types
pub trait Num: PartialEq + Zero + One
    + Add<Output = Self> + Sub<Output = Self>
    + Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
{
    type FromStrRadixErr;

    /// Convert from a string and radix <= 36.
    fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>;
}

macro_rules! int_trait_impl {
    ($name:ident for $($t:ty)*) => ($(
        impl $name for $t {
            type FromStrRadixErr = ::std::num::ParseIntError;
            fn from_str_radix(s: &str, radix: u32)
                              -> Result<Self, ::std::num::ParseIntError>
            {
                <$t>::from_str_radix(s, radix)
            }
        }
    )*)
}
int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);

#[derive(Debug)]
pub enum FloatErrorKind {
    Empty,
    Invalid,
}
// FIXME: std::num::ParseFloatError is stable in 1.0, but opaque to us,
// so there's not really any way for us to reuse it.
#[derive(Debug)]
pub struct ParseFloatError {
    pub kind: FloatErrorKind,
}

// FIXME: The standard library from_str_radix on floats was deprecated, so we're stuck
// with this implementation ourselves until we want to make a breaking change.
// (would have to drop it from `Num` though)
macro_rules! float_trait_impl {
    ($name:ident for $($t:ty)*) => ($(
        impl $name for $t {
            type FromStrRadixErr = ParseFloatError;

            fn from_str_radix(src: &str, radix: u32)
                              -> Result<Self, Self::FromStrRadixErr>
            {
                use self::FloatErrorKind::*;
                use self::ParseFloatError as PFE;

                // Special values
                match src {
                    "inf"   => return Ok(Float::infinity()),
                    "-inf"  => return Ok(Float::neg_infinity()),
                    "NaN"   => return Ok(Float::nan()),
                    _       => {},
                }

                fn slice_shift_char(src: &str) -> Option<(char, &str)> {
                    src.chars().nth(0).map(|ch| (ch, &src[1..]))
                }

                let (is_positive, src) =  match slice_shift_char(src) {
                    None             => return Err(PFE { kind: Empty }),
                    Some(('-', ""))  => return Err(PFE { kind: Empty }),
                    Some(('-', src)) => (false, src),
                    Some((_, _))     => (true,  src),
                };

                // The significand to accumulate
                let mut sig = if is_positive { 0.0 } else { -0.0 };
                // Necessary to detect overflow
                let mut prev_sig = sig;
                let mut cs = src.chars().enumerate();
                // Exponent prefix and exponent index offset
                let mut exp_info = None::<(char, usize)>;

                // Parse the integer part of the significand
                for (i, c) in cs.by_ref() {
                    match c.to_digit(radix) {
                        Some(digit) => {
                            // shift significand one digit left
                            sig = sig * (radix as $t);

                            // add/subtract current digit depending on sign
                            if is_positive {
                                sig = sig + ((digit as isize) as $t);
                            } else {
                                sig = sig - ((digit as isize) as $t);
                            }

                            // Detect overflow by comparing to last value, except
                            // if we've not seen any non-zero digits.
                            if prev_sig != 0.0 {
                                if is_positive && sig <= prev_sig
                                    { return Ok(Float::infinity()); }
                                if !is_positive && sig >= prev_sig
                                    { return Ok(Float::neg_infinity()); }

                                // Detect overflow by reversing the shift-and-add process
                                if is_positive && (prev_sig != (sig - digit as $t) / radix as $t)
                                    { return Ok(Float::infinity()); }
                                if !is_positive && (prev_sig != (sig + digit as $t) / radix as $t)
                                    { return Ok(Float::neg_infinity()); }
                            }
                            prev_sig = sig;
                        },
                        None => match c {
                            'e' | 'E' | 'p' | 'P' => {
                                exp_info = Some((c, i + 1));
                                break;  // start of exponent
                            },
                            '.' => {
                                break;  // start of fractional part
                            },
                            _ => {
                                return Err(PFE { kind: Invalid });
                            },
                        },
                    }
                }

                // If we are not yet at the exponent parse the fractional
                // part of the significand
                if exp_info.is_none() {
                    let mut power = 1.0;
                    for (i, c) in cs.by_ref() {
                        match c.to_digit(radix) {
                            Some(digit) => {
                                // Decrease power one order of magnitude
                                power = power / (radix as $t);
                                // add/subtract current digit depending on sign
                                sig = if is_positive {
                                    sig + (digit as $t) * power
                                } else {
                                    sig - (digit as $t) * power
                                };
                                // Detect overflow by comparing to last value
                                if is_positive && sig < prev_sig
                                    { return Ok(Float::infinity()); }
                                if !is_positive && sig > prev_sig
                                    { return Ok(Float::neg_infinity()); }
                                prev_sig = sig;
                            },
                            None => match c {
                                'e' | 'E' | 'p' | 'P' => {
                                    exp_info = Some((c, i + 1));
                                    break; // start of exponent
                                },
                                _ => {
                                    return Err(PFE { kind: Invalid });
                                },
                            },
                        }
                    }
                }

                // Parse and calculate the exponent
                let exp = match exp_info {
                    Some((c, offset)) => {
                        let base = match c {
                            'E' | 'e' if radix == 10 => 10.0,
                            'P' | 'p' if radix == 16 => 2.0,
                            _ => return Err(PFE { kind: Invalid }),
                        };

                        // Parse the exponent as decimal integer
                        let src = &src[offset..];
                        let (is_positive, exp) = match slice_shift_char(src) {
                            Some(('-', src)) => (false, src.parse::<usize>()),
                            Some(('+', src)) => (true,  src.parse::<usize>()),
                            Some((_, _))     => (true,  src.parse::<usize>()),
                            None             => return Err(PFE { kind: Invalid }),
                        };

                        match (is_positive, exp) {
                            (true,  Ok(exp)) => base.powi(exp as i32),
                            (false, Ok(exp)) => 1.0 / base.powi(exp as i32),
                            (_, Err(_))      => return Err(PFE { kind: Invalid }),
                        }
                    },
                    None => 1.0, // no exponent
                };

                Ok(sig * exp)
            }
        }
    )*)
}
float_trait_impl!(Num for f32 f64);

#[test]
fn from_str_radix_unwrap() {
    // The Result error must impl Debug to allow unwrap()

    let i: i32 = Num::from_str_radix("0", 10).unwrap();
    assert_eq!(i, 0);

    let f: f32 = Num::from_str_radix("0.0", 10).unwrap();
    assert_eq!(f, 0.0);
}
<|endoftext|>


<commit_before>extern crate curl;
extern crate http;
extern crate hyper;

extern crate test;

use std::fmt::{mod, Show};
use std::io::IoResult;
use std::io::net::ip::Ipv4Addr;
use hyper::server::{Request, Response, Server};

fn listen() -> hyper::server::Listening {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 0);
    server.listen(handle).unwrap()
}

fn handle(_req: Request, mut res: Response) -> IoResult<()> {
    try!(res.write(b"Benchmarking hyper vs others!"));
    res.end()
}

#[bench]
fn bench_curl(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        curl::http::handle()
            .get(url)
            .header("X-Foo", "Bar")
            .exec()
            .unwrap()
    });
    listening.close().unwrap()
}

struct Foo;

impl hyper::header::Header for Foo {
    fn header_name(_: Option<Foo>) -> &'static str {
        "x-foo"
    }
    fn parse_header(_: &[Vec<u8>]) -> Option<Foo> {
        None
    }
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        "Bar".fmt(fmt)
    }
}

#[bench]
fn bench_hyper(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req = hyper::get(hyper::Url::parse(url).unwrap()).unwrap();
        req.headers.set(Foo);

        req
            .send().unwrap()
            .read_to_string().unwrap()
    });
    listening.close().unwrap()
}

#[bench]
fn bench_http(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req: http::client::RequestWriter = http::client::RequestWriter::new(
            http::method::Get,
            hyper::Url::parse(url).unwrap()
        ).unwrap();
        req.headers.extensions.insert("x-foo".to_string(), "Bar".to_string());
        // cant unwrap because Err contains RequestWriter, which does not implement Show
        let mut res = match req.read_response() {
            Ok(res) => res,
            Err(..) => fail!("http response failed")
        };
        res.read_to_string().unwrap();
    });
    listening.close().unwrap()
}
<commit_msg>fix benches/client with new Handler<commit_after>extern crate curl;
extern crate http;
extern crate hyper;

extern crate test;

use std::fmt::{mod, Show};
use std::io::net::ip::Ipv4Addr;
use hyper::server::{Incoming, Server};

fn listen() -> hyper::server::Listening {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 0);
    server.listen(handle).unwrap()
}

fn handle(mut incoming: Incoming) {
    for (_, mut res) in incoming {
        res.write(b"Benchmarking hyper vs others!").unwrap();
        res.end().unwrap();
    }
}

#[bench]
fn bench_curl(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        curl::http::handle()
            .get(url)
            .header("X-Foo", "Bar")
            .exec()
            .unwrap()
    });
    listening.close().unwrap()
}

struct Foo;

impl hyper::header::Header for Foo {
    fn header_name(_: Option<Foo>) -> &'static str {
        "x-foo"
    }
    fn parse_header(_: &[Vec<u8>]) -> Option<Foo> {
        None
    }
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        "Bar".fmt(fmt)
    }
}

#[bench]
fn bench_hyper(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req = hyper::get(hyper::Url::parse(url).unwrap()).unwrap();
        req.headers.set(Foo);

        req
            .send().unwrap()
            .read_to_string().unwrap()
    });
    listening.close().unwrap()
}

#[bench]
fn bench_http(b: &mut test::Bencher) {
    let listening = listen();
    let s = format!("http://{}/", listening.socket_addr);
    let url = s.as_slice();
    b.iter(|| {
        let mut req: http::client::RequestWriter = http::client::RequestWriter::new(
            http::method::Get,
            hyper::Url::parse(url).unwrap()
        ).unwrap();
        req.headers.extensions.insert("x-foo".to_string(), "Bar".to_string());
        // cant unwrap because Err contains RequestWriter, which does not implement Show
        let mut res = match req.read_response() {
            Ok(res) => res,
            Err(..) => fail!("http response failed")
        };
        res.read_to_string().unwrap();
    });
    listening.close().unwrap()
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<commit_msg>Add documentation for rice partition types<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

/// General enum that holds all the different subframe data types.
#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

/// Fixed linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

/// Finite Impulse Response (FIR) linear prediction subframe.
#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

/// Header for a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

/// Contents of a Rice partitioned residual.
#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<|endoftext|>


<commit_before>#![no_main]

use arbitrary::Arbitrary;
use libfuzzer_sys::fuzz_target;

#[derive(Arbitrary, Debug, Clone)]
enum FloatInput {
    F32(f32),
    F64(f64),
}

#[derive(Arbitrary, Debug, Clone)]
struct Inputs {
    inputs: Vec<(FloatInput, bool)>,
}

fuzz_target!(|input: Inputs| {
    let mut buffer = ryu::Buffer::new();
    for input_step in input.inputs {
        match input_step {
            (FloatInput::F32(val), false) => buffer.format(val),
            (FloatInput::F32(val), true) => buffer.format_finite(val),
            (FloatInput::F64(val), false) => buffer.format(val),
            (FloatInput::F64(val), true) => buffer.format_finite(val),
        };
    }
});
<commit_msg>Remove unneeded Clone impls from fuzz target<commit_after>#![no_main]

use arbitrary::Arbitrary;
use libfuzzer_sys::fuzz_target;

#[derive(Arbitrary, Debug)]
enum FloatInput {
    F32(f32),
    F64(f64),
}

#[derive(Arbitrary, Debug)]
struct Inputs {
    inputs: Vec<(FloatInput, bool)>,
}

fuzz_target!(|input: Inputs| {
    let mut buffer = ryu::Buffer::new();
    for input_step in input.inputs {
        match input_step {
            (FloatInput::F32(val), false) => buffer.format(val),
            (FloatInput::F32(val), true) => buffer.format_finite(val),
            (FloatInput::F64(val), false) => buffer.format(val),
            (FloatInput::F64(val), true) => buffer.format_finite(val),
        };
    }
});
<|endoftext|>


<commit_before>extern mod fuse;

use std::libc::{c_int, mode_t, off_t, size_t, ENOENT, S_IFDIR, S_IFREG};
use std::default::Default;

struct HelloFS;

static hello_world: &'static str = "Hello World!\n";

fn hello_dir_attr () -> fuse::fuse_attr {
	fuse::fuse_attr {
		ino: 1, mode: S_IFDIR as u32|493, nlink: 2, uid: 501, gid: 20, ..Default::default()
	}
}

fn hello_txt_attr () -> fuse::fuse_attr {
	fuse::fuse_attr {
		ino: 2, size: 13, mode: S_IFREG as u32|420, nlink: 1, uid: 501, gid: 20, ..Default::default()
	}
}

impl fuse::Filesystem for HelloFS {
	fn lookup (&mut self, parent: u64, name: &[u8]) -> Result<~fuse::fuse_entry_out, c_int> {
		if parent == 1 && name == bytes!("hello.txt") {
			Ok(~fuse::fuse_entry_out { nodeid: 2, generation: 0, attr: hello_txt_attr(), entry_valid: 1, entry_valid_nsec: 0, attr_valid: 1, attr_valid_nsec: 0 })
		} else {
			Err(ENOENT)
		}
	}

	fn getattr (&mut self, ino: u64) -> Result<~fuse::fuse_attr_out, c_int> {
		match ino {
			1 => Ok(~fuse::fuse_attr_out { attr_valid: 1, attr_valid_nsec: 0, dummy: 0, attr: hello_dir_attr() }),
			2 => Ok(~fuse::fuse_attr_out { attr_valid: 1, attr_valid_nsec: 0, dummy: 0, attr: hello_txt_attr() }),
			_ => Err(ENOENT),
		}
	}

	fn read (&mut self, ino: u64, _fh: u64, offset: off_t, _size: size_t) -> Result<~[u8], c_int> {
		if ino == 2 {
			Ok(hello_world.as_bytes().tailn(offset as uint).to_owned())
		} else {
			Err(ENOENT)
		}
	}

	fn readdir (&mut self, ino: u64, _fh: u64, offset: off_t, buffer: ~fuse::DirBuffer) -> Result<~fuse::DirBuffer, c_int> {
		if ino == 1 {
			let mut buffer = buffer;
			if offset == 0 {
				buffer.fill(1, 0, hello_dir_attr().mode as mode_t, ".");
				buffer.fill(1, 1, hello_dir_attr().mode as mode_t, "..");
				buffer.fill(2, 2, hello_txt_attr().mode as mode_t, "hello.txt");
			}
			Ok(buffer)
		} else {
			Err(ENOENT)
		}
	}
}

fn main () {
	let mountpoint = Path::new(::std::os::args()[1]);
	fuse::mount(HelloFS, &mountpoint, []);
}
<commit_msg>Use mut keyword on parameter directly<commit_after>extern mod fuse;

use std::libc::{c_int, mode_t, off_t, size_t, ENOENT, S_IFDIR, S_IFREG};
use std::default::Default;

struct HelloFS;

static hello_world: &'static str = "Hello World!\n";

fn hello_dir_attr () -> fuse::fuse_attr {
	fuse::fuse_attr {
		ino: 1, mode: S_IFDIR as u32|493, nlink: 2, uid: 501, gid: 20, ..Default::default()
	}
}

fn hello_txt_attr () -> fuse::fuse_attr {
	fuse::fuse_attr {
		ino: 2, size: 13, mode: S_IFREG as u32|420, nlink: 1, uid: 501, gid: 20, ..Default::default()
	}
}

impl fuse::Filesystem for HelloFS {
	fn lookup (&mut self, parent: u64, name: &[u8]) -> Result<~fuse::fuse_entry_out, c_int> {
		if parent == 1 && name == bytes!("hello.txt") {
			Ok(~fuse::fuse_entry_out { nodeid: 2, generation: 0, attr: hello_txt_attr(), entry_valid: 1, entry_valid_nsec: 0, attr_valid: 1, attr_valid_nsec: 0 })
		} else {
			Err(ENOENT)
		}
	}

	fn getattr (&mut self, ino: u64) -> Result<~fuse::fuse_attr_out, c_int> {
		match ino {
			1 => Ok(~fuse::fuse_attr_out { attr_valid: 1, attr_valid_nsec: 0, dummy: 0, attr: hello_dir_attr() }),
			2 => Ok(~fuse::fuse_attr_out { attr_valid: 1, attr_valid_nsec: 0, dummy: 0, attr: hello_txt_attr() }),
			_ => Err(ENOENT),
		}
	}

	fn read (&mut self, ino: u64, _fh: u64, offset: off_t, _size: size_t) -> Result<~[u8], c_int> {
		if ino == 2 {
			Ok(hello_world.as_bytes().tailn(offset as uint).to_owned())
		} else {
			Err(ENOENT)
		}
	}

	fn readdir (&mut self, ino: u64, _fh: u64, offset: off_t, mut buffer: ~fuse::DirBuffer) -> Result<~fuse::DirBuffer, c_int> {
		if ino == 1 {
			if offset == 0 {
				buffer.fill(1, 0, hello_dir_attr().mode as mode_t, ".");
				buffer.fill(1, 1, hello_dir_attr().mode as mode_t, "..");
				buffer.fill(2, 2, hello_txt_attr().mode as mode_t, "hello.txt");
			}
			Ok(buffer)
		} else {
			Err(ENOENT)
		}
	}
}

fn main () {
	let mountpoint = Path::new(::std::os::args()[1]);
	fuse::mount(HelloFS, &mountpoint, []);
}
<|endoftext|>