<commit_before>// This file is part of rgtk.
//
// rgtk 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 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gtk::{self, ffi};
use glib::{to_bool, to_gboolean};
use gtk::FFIWidget;
use gtk::cast::GTK_ABOUT_DIALOG;
use std::ffi::CString;

struct_Widget!(AboutDialog);

impl AboutDialog {
    pub fn new() -> Option<AboutDialog> {
        let tmp_pointer = unsafe { ffi::gtk_about_dialog_new() };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(gtk::FFIWidget::wrap_widget(tmp_pointer))
        }
    }

    pub fn get_program_name(&self) -> Option<String> {
        unsafe {
            let name = ffi::gtk_about_dialog_get_program_name(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if name.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&name)).to_string())
            }
        }
    }

    pub fn set_program_name(&self, name: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(name.as_bytes());

            ffi::gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_version(&self) -> Option<String> {
        unsafe {
            let version = ffi::gtk_about_dialog_get_version(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if version.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&version)).to_string())
            }
        }
    }

    pub fn set_version(&self, version: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(version.as_bytes());

            ffi::gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_copyright(&self) -> Option<String> {
        unsafe {
            let copyright = ffi::gtk_about_dialog_get_copyright(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if copyright.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&copyright)).to_string())
            }
        }
    }

    pub fn set_copyright(&self, copyright: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(copyright.as_bytes());

            ffi::gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_comments(&self) -> Option<String> {
        unsafe {
            let comments = ffi::gtk_about_dialog_get_comments(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if comments.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&comments)).to_string())
            }
        }
    }

    pub fn set_comments(&self, comments: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(comments.as_bytes());

            ffi::gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_license(&self) -> Option<String> {
        unsafe {
            let license = ffi::gtk_about_dialog_get_license(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if license.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&license)).to_string())
            }
        }
    }

    pub fn set_license(&self, license: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(license.as_bytes());

            ffi::gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_wrap_license(&self) -> bool {
        unsafe { to_bool(ffi::gtk_about_dialog_get_wrap_license(GTK_ABOUT_DIALOG(self.unwrap_widget()))) }
    }

    pub fn set_wrap_license(&self, wrap_license: bool) -> () {
        unsafe { ffi::gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(self.unwrap_widget()), to_gboolean(wrap_license)) }
    }

    pub fn get_license_type(&self) -> gtk::License {
        unsafe { ffi::gtk_about_dialog_get_license_type(GTK_ABOUT_DIALOG(self.unwrap_widget())) }
    }

    pub fn set_license_type(&self, license_type: gtk::License) -> () {
        unsafe { ffi::gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(self.unwrap_widget()), license_type) }
    }

    pub fn get_website(&self) -> Option<String> {
        unsafe {
            let website = ffi::gtk_about_dialog_get_website(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if website.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&website)).to_string())
            }
        }
    }

    pub fn set_website(&self, website: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(website.as_bytes());

            ffi::gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_website_label(&self) -> Option<String> {
        unsafe {
            let website_label = ffi::gtk_about_dialog_get_website_label(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if website_label.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&website_label)).to_string())
            }
        }
    }

    pub fn set_website_label(&self, website_label: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(website_label.as_bytes());

            ffi::gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_authors(&self) -> Vec<String> {
        let authors = unsafe { ffi::gtk_about_dialog_get_authors(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !authors.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = authors.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_authors(&self, authors: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in authors.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        unsafe { ffi::gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_artists(&self) -> Vec<String> {
        let artists = unsafe { ffi::gtk_about_dialog_get_artists(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !artists.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = artists.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_artists(&self, artists: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in artists.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        unsafe { ffi::gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_documenters(&self) -> Vec<String> {
        let documenters = unsafe { ffi::gtk_about_dialog_get_documenters(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !documenters.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = documenters.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_documenters(&self, documenters: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in documenters.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        unsafe { ffi::gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_translator_credits(&self) -> Option<String> {
        unsafe {
            let translator_credits = ffi::gtk_about_dialog_get_translator_credits(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if translator_credits.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&translator_credits)).to_string())
            }
        }
    }

    pub fn set_translator_credits(&self, translator_credits: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(translator_credits.as_bytes());

            ffi::gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    /*pub fn get_logo(&self) -> Option<String> {
        let logo = unsafe { ffi::gtk_about_dialog_set_logo(self.pointer)) };

        if logo.is_null() {
            None
        } else {
            Some(unsafe { gtk::FFIWidget::wrap_widget(logo) })
        }
    }

    pub fn set_logo(&self, logo: Pixbuf) -> () {
        unsafe { ffi::gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(self.unwrap_widget()), GDK_PIXBUF(logo.unwrap_widget())) }
    }*/

    pub fn get_logo_icon_name(&self) -> Option<String> {
        unsafe {
            let logo_icon_name = ffi::gtk_about_dialog_get_logo_icon_name(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if logo_icon_name.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&logo_icon_name)).to_string())
            }
        }
    }

    pub fn set_logo_icon_name(&self, logo_icon_name: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(logo_icon_name.as_bytes());

            ffi::gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn add_credit_section(&self, section_name: &str, people: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in people.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        unsafe {
            let c_str = CString::from_slice(section_name.as_bytes());

            ffi::gtk_about_dialog_add_credit_section(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr(), tmp_vec.as_slice().as_ptr())
        }
    }

    /*pub fn show(parent: Window, properties: Vec<String>) -> () {
        unsafe { ffi::gtk_show_about_dialog(GTK_WINDOW(parent), first_property_name, ...) }
    }*/
}

impl_drop!(AboutDialog);
impl_TraitWidget!(AboutDialog);

impl gtk::ContainerTrait for AboutDialog {}
impl gtk::BinTrait for AboutDialog {}
impl gtk::WindowTrait for AboutDialog {}
impl gtk::DialogTrait for AboutDialog {}

impl_widget_events!(AboutDialog);
<commit_msg>Fix invalid c arrays<commit_after>// This file is part of rgtk.
//
// rgtk 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 3 of the License, or
// (at your option) any later version.
//
// rgtk 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 rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gtk::{self, ffi};
use glib::{to_bool, to_gboolean};
use gtk::FFIWidget;
use gtk::cast::GTK_ABOUT_DIALOG;
use std::ffi::CString;

struct_Widget!(AboutDialog);

impl AboutDialog {
    pub fn new() -> Option<AboutDialog> {
        let tmp_pointer = unsafe { ffi::gtk_about_dialog_new() };

        if tmp_pointer.is_null() {
            None
        } else {
            Some(gtk::FFIWidget::wrap_widget(tmp_pointer))
        }
    }

    pub fn get_program_name(&self) -> Option<String> {
        unsafe {
            let name = ffi::gtk_about_dialog_get_program_name(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if name.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&name)).to_string())
            }
        }
    }

    pub fn set_program_name(&self, name: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(name.as_bytes());

            ffi::gtk_about_dialog_set_program_name(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_version(&self) -> Option<String> {
        unsafe {
            let version = ffi::gtk_about_dialog_get_version(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if version.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&version)).to_string())
            }
        }
    }

    pub fn set_version(&self, version: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(version.as_bytes());

            ffi::gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_copyright(&self) -> Option<String> {
        unsafe {
            let copyright = ffi::gtk_about_dialog_get_copyright(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if copyright.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&copyright)).to_string())
            }
        }
    }

    pub fn set_copyright(&self, copyright: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(copyright.as_bytes());

            ffi::gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_comments(&self) -> Option<String> {
        unsafe {
            let comments = ffi::gtk_about_dialog_get_comments(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if comments.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&comments)).to_string())
            }
        }
    }

    pub fn set_comments(&self, comments: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(comments.as_bytes());

            ffi::gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_license(&self) -> Option<String> {
        unsafe {
            let license = ffi::gtk_about_dialog_get_license(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if license.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&license)).to_string())
            }
        }
    }

    pub fn set_license(&self, license: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(license.as_bytes());

            ffi::gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_wrap_license(&self) -> bool {
        unsafe { to_bool(ffi::gtk_about_dialog_get_wrap_license(GTK_ABOUT_DIALOG(self.unwrap_widget()))) }
    }

    pub fn set_wrap_license(&self, wrap_license: bool) -> () {
        unsafe { ffi::gtk_about_dialog_set_wrap_license(GTK_ABOUT_DIALOG(self.unwrap_widget()), to_gboolean(wrap_license)) }
    }

    pub fn get_license_type(&self) -> gtk::License {
        unsafe { ffi::gtk_about_dialog_get_license_type(GTK_ABOUT_DIALOG(self.unwrap_widget())) }
    }

    pub fn set_license_type(&self, license_type: gtk::License) -> () {
        unsafe { ffi::gtk_about_dialog_set_license_type(GTK_ABOUT_DIALOG(self.unwrap_widget()), license_type) }
    }

    pub fn get_website(&self) -> Option<String> {
        unsafe {
            let website = ffi::gtk_about_dialog_get_website(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if website.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&website)).to_string())
            }
        }
    }

    pub fn set_website(&self, website: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(website.as_bytes());

            ffi::gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_website_label(&self) -> Option<String> {
        unsafe {
            let website_label = ffi::gtk_about_dialog_get_website_label(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if website_label.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&website_label)).to_string())
            }
        }
    }

    pub fn set_website_label(&self, website_label: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(website_label.as_bytes());

            ffi::gtk_about_dialog_set_website_label(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn get_authors(&self) -> Vec<String> {
        let authors = unsafe { ffi::gtk_about_dialog_get_authors(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !authors.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = authors.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_authors(&self, authors: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in authors.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        tmp_vec.push(::std::ptr::null_mut());
        unsafe { ffi::gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_artists(&self) -> Vec<String> {
        let artists = unsafe { ffi::gtk_about_dialog_get_artists(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !artists.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = artists.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_artists(&self, artists: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in artists.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        tmp_vec.push(::std::ptr::null_mut());
        unsafe { ffi::gtk_about_dialog_set_artists(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_documenters(&self) -> Vec<String> {
        let documenters = unsafe { ffi::gtk_about_dialog_get_documenters(GTK_ABOUT_DIALOG(self.unwrap_widget())) };
        let mut ret = Vec::new();

        if !documenters.is_null() {
            let mut it = 0;

            unsafe {
                loop {
                    let tmp = documenters.offset(it);

                    if tmp.is_null() {
                        break;
                    }
                    ret.push(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&*tmp)).to_string());
                    it += 1;
                }
            }
        }
        ret
    }

    pub fn set_documenters(&self, documenters: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in documenters.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        tmp_vec.push(::std::ptr::null_mut());
        unsafe { ffi::gtk_about_dialog_set_documenters(GTK_ABOUT_DIALOG(self.unwrap_widget()), tmp_vec.as_slice().as_ptr()) }
    }

    pub fn get_translator_credits(&self) -> Option<String> {
        unsafe {
            let translator_credits = ffi::gtk_about_dialog_get_translator_credits(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if translator_credits.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&translator_credits)).to_string())
            }
        }
    }

    pub fn set_translator_credits(&self, translator_credits: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(translator_credits.as_bytes());

            ffi::gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    /*pub fn get_logo(&self) -> Option<String> {
        let logo = unsafe { ffi::gtk_about_dialog_set_logo(self.pointer)) };

        if logo.is_null() {
            None
        } else {
            Some(unsafe { gtk::FFIWidget::wrap_widget(logo) })
        }
    }

    pub fn set_logo(&self, logo: Pixbuf) -> () {
        unsafe { ffi::gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(self.unwrap_widget()), GDK_PIXBUF(logo.unwrap_widget())) }
    }*/

    pub fn get_logo_icon_name(&self) -> Option<String> {
        unsafe {
            let logo_icon_name = ffi::gtk_about_dialog_get_logo_icon_name(GTK_ABOUT_DIALOG(self.unwrap_widget()));

            if logo_icon_name.is_null() {
                None
            } else {
                Some(String::from_utf8_lossy(::std::ffi::c_str_to_bytes(&logo_icon_name)).to_string())
            }
        }
    }

    pub fn set_logo_icon_name(&self, logo_icon_name: &str) -> () {
        unsafe {
            let c_str = CString::from_slice(logo_icon_name.as_bytes());

            ffi::gtk_about_dialog_set_logo_icon_name(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr())
        };
    }

    pub fn add_credit_section(&self, section_name: &str, people: &Vec<String>) -> () {
        let mut tmp_vec = Vec::new();

        for tmp in people.iter() {
            let c_str = CString::from_slice(tmp.as_bytes());

            tmp_vec.push(c_str.as_ptr());
        }
        tmp_vec.push(::std::ptr::null_mut());
        unsafe {
            let c_str = CString::from_slice(section_name.as_bytes());

            ffi::gtk_about_dialog_add_credit_section(GTK_ABOUT_DIALOG(self.unwrap_widget()), c_str.as_ptr(), tmp_vec.as_slice().as_ptr())
        }
    }

    /*pub fn show(parent: Window, properties: Vec<String>) -> () {
        unsafe { ffi::gtk_show_about_dialog(GTK_WINDOW(parent), first_property_name, ...) }
    }*/
}

impl_drop!(AboutDialog);
impl_TraitWidget!(AboutDialog);

impl gtk::ContainerTrait for AboutDialog {}
impl gtk::BinTrait for AboutDialog {}
impl gtk::WindowTrait for AboutDialog {}
impl gtk::DialogTrait for AboutDialog {}

impl_widget_events!(AboutDialog);
<|endoftext|>


<commit_before><commit_msg>Add testcase.<commit_after>// xfail-pretty

use std;
use rustc;

import rustc::*;
import std::io::*;

import rustc::driver::diagnostic;
import rustc::syntax::ast;
import rustc::syntax::codemap;
import rustc::syntax::parse::parser;
import rustc::syntax::print::*;

fn new_parse_sess() -> parser::parse_sess {
    let cm = codemap::new_codemap();
    let handler = diagnostic::mk_handler(option::none);
    let sess = @{
        cm: cm,
        mutable next_id: 1,
        span_diagnostic: diagnostic::mk_span_handler(handler, cm),
        mutable chpos: 0u,
        mutable byte_pos: 0u
    };
    ret sess;
}

iface fake_ext_ctxt {
    fn session() -> fake_session;
}

type fake_options = {cfg: ast::crate_cfg};

type fake_session = {opts: @fake_options,
                     parse_sess: parser::parse_sess};

impl of fake_ext_ctxt for fake_session {
    fn session() -> fake_session {self}
}

fn mk_ctxt() -> fake_ext_ctxt {
    let opts : fake_options = {cfg: []};
    {opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt
}

fn main() {
    let ext_cx = mk_ctxt();

    let abc = #ast{23};
    check_pp(abc,  pprust::print_expr, "23");

    let expr = #ast{1 - $0 + 8};
    check_pp(expr,  pprust::print_expr, "1 - $0 + 8");

    let expr2 = rustc::syntax::ext::qquote::replace(expr, [abc]);
    check_pp(expr2,  pprust::print_expr, "1 - 23 + 8");

    let expr3 = #ast{2 - $(abc) + 7};
    check_pp(expr3,  pprust::print_expr, "2 - 23 + 7");

    let expr4 = #ast{2 - $(#(3)) + 9};
    check_pp(expr4,  pprust::print_expr, "2 - 3 + 9");

    let ty = #ast(ty){option<int>};
    check_pp(ty, pprust::print_type, "option<int>");

    let item = #ast(item){const x : int = 10;};
    check_pp(item, pprust::print_item, "const x: int = 10;");

    let stmt = #ast(stmt){let x = 20;};
    check_pp(*stmt, pprust::print_stmt, "let x = 20;");

    let pat = #ast(pat){some(_)};
    check_pp(pat, pprust::print_pat, "some(_)");
}

fn check_pp<T>(expr: T, f: fn(pprust::ps, T), expect: str) {
    let buf = mk_mem_buffer();
    let pp = pprust::rust_printer(buf as std::io::writer);
    f(pp, expr);
    pp::eof(pp.s);
    let str = mem_buffer_str(buf);
    stdout().write_line(str);
    if expect != "" {assert str == expect;}
}

<|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/. */

//! Implements parallel traversals over the DOM and flow trees.
//!
//! This code is highly unsafe. Keep this file small and easy to audit.

use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared};
use layout::construct::FlowConstructor;
use layout::context::LayoutContext;
use layout::extra::LayoutAuxMethods;
use layout::flow::{Flow, PreorderFlowTraversal, PostorderFlowTraversal};
use layout::flow;
use layout::layout_task::{AssignHeightsAndStoreOverflowTraversal, AssignWidthsTraversal};
use layout::layout_task::{BubbleWidthsTraversal};
use layout::util::{LayoutDataAccess, OpaqueNode};
use layout::wrapper::{layout_node_to_unsafe_layout_node, LayoutNode, PostorderNodeMutTraversal};
use layout::wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode};

use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
use std::cast;
use std::ptr;
use std::sync::atomics::{AtomicInt, Relaxed, SeqCst};
use style::{Stylist, TNode};

#[allow(dead_code)]
fn static_assertion(node: UnsafeLayoutNode) {
    unsafe {
        let _: PaddedUnsafeFlow = ::std::intrinsics::transmute(node);
    }
}

/// Memory representation that is at least as large as UnsafeLayoutNode, as it must be
/// safely transmutable to and from that type to accommodate the type-unsafe parallel work
/// queue usage that stores both flows and nodes.
pub type PaddedUnsafeFlow = (uint, uint, uint);

trait UnsafeFlowConversions {
    fn to_flow(&self) -> UnsafeFlow;
    fn from_flow(flow: &UnsafeFlow) -> Self;
}

impl UnsafeFlowConversions for PaddedUnsafeFlow {
    fn to_flow(&self) -> UnsafeFlow {
        let (vtable, ptr, _padding) = *self;
        (vtable, ptr)
    }

    fn from_flow(flow: &UnsafeFlow) -> PaddedUnsafeFlow {
        let &(vtable, ptr) = flow;
        (vtable, ptr, 0)
    }
}

/// Vtable + pointer representation of a Flow trait object.
pub type UnsafeFlow = (uint, uint);

fn null_unsafe_flow() -> UnsafeFlow {
    (0, 0)
}

pub fn owned_flow_to_unsafe_flow(flow: *~Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&*flow)
    }
}

pub fn mut_owned_flow_to_unsafe_flow(flow: *mut ~Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&*flow)
    }
}

pub fn borrowed_flow_to_unsafe_flow(flow: &Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&flow)
    }
}

pub fn mut_borrowed_flow_to_unsafe_flow(flow: &mut Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&flow)
    }
}

/// Information that we need stored in each DOM node.
pub struct DomParallelInfo {
    /// The number of children that still need work done.
    children_count: AtomicInt,
}

impl DomParallelInfo {
    pub fn new() -> DomParallelInfo {
        DomParallelInfo {
            children_count: AtomicInt::new(0),
        }
    }
}

/// Information that we need stored in each flow.
pub struct FlowParallelInfo {
    /// The number of children that still need work done.
    children_count: AtomicInt,
    /// The address of the parent flow.
    parent: UnsafeFlow,
}

impl FlowParallelInfo {
    pub fn new() -> FlowParallelInfo {
        FlowParallelInfo {
            children_count: AtomicInt::new(0),
            parent: null_unsafe_flow(),
        }
    }
}

/// A parallel bottom-up flow traversal.
trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
    /// Process current flow and potentially traverse its ancestors.
    ///
    /// If we are the last child that finished processing, recursively process
    /// our parent. Else, stop.
    /// Also, stop at the root (obviously :P).
    ///
    /// Thus, if we start with all the leaves of a tree, we end up traversing
    /// the whole tree bottom-up because each parent will be processed exactly
    /// once (by the last child that finishes processing).
    ///
    /// The only communication between siblings is that they both
    /// fetch-and-subtract the parent's children count.
    fn run_parallel(&mut self,
                    mut unsafe_flow: UnsafeFlow,
                    _: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
        loop {
            unsafe {
                // Get a real flow.
                let flow: &mut ~Flow = cast::transmute(&unsafe_flow);

                // Perform the appropriate traversal.
                if self.should_process(*flow) {
                    self.process(*flow);
                }

                let base = flow::mut_base(*flow);

                // Reset the count of children for the next layout traversal.
                base.parallel.children_count.store(base.children.len() as int, Relaxed);

                // Possibly enqueue the parent.
                let unsafe_parent = base.parallel.parent;
                if unsafe_parent == null_unsafe_flow() {
                    // We're done!
                    break
                }

                // No, we're not at the root yet. Then are we the last child
                // of our parent to finish processing? If so, we can continue
                // on with our parent; otherwise, we've gotta wait.
                let parent: &mut ~Flow = cast::transmute(&unsafe_parent);
                let parent_base = flow::mut_base(*parent);
                if parent_base.parallel.children_count.fetch_sub(1, SeqCst) == 1 {
                    // We were the last child of our parent. Reflow our parent.
                    unsafe_flow = unsafe_parent
                } else {
                    // Stop.
                    break
                }
            }
        }
    }
}

/// A parallel top-down flow traversal.
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
    fn run_parallel(&mut self,
                    unsafe_flow: UnsafeFlow,
                    proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>);

    fn run_parallel_helper(&mut self,
                           unsafe_flow: UnsafeFlow,
                           proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>,
                           top_down_func: extern "Rust" fn(PaddedUnsafeFlow,
                                                           &mut WorkerProxy<*mut LayoutContext,
                                                                            PaddedUnsafeFlow>),
                           bottom_up_func: extern "Rust" fn(PaddedUnsafeFlow,
                                                            &mut WorkerProxy<*mut LayoutContext,
                                                                             PaddedUnsafeFlow>)) {
        let mut had_children = false;
        unsafe {
            // Get a real flow.
            let flow: &mut ~Flow = cast::transmute(&unsafe_flow);

            // Perform the appropriate traversal.
            self.process(*flow);

            // Possibly enqueue the children.
            for kid in flow::child_iter(*flow) {
                had_children = true;
                proxy.push(WorkUnit {
                    fun: top_down_func,
                    data: UnsafeFlowConversions::from_flow(&borrowed_flow_to_unsafe_flow(kid)),
                });
            }

        }

        // If there were no more children, start assigning heights.
        if !had_children {
            bottom_up_func(UnsafeFlowConversions::from_flow(&unsafe_flow), proxy)
        }
    }
}

impl<'a> ParallelPostorderFlowTraversal for BubbleWidthsTraversal<'a> {}

impl<'a> ParallelPreorderFlowTraversal for AssignWidthsTraversal<'a> {
    fn run_parallel(&mut self,
                    unsafe_flow: UnsafeFlow,
                    proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
        self.run_parallel_helper(unsafe_flow,
                                 proxy,
                                 assign_widths,
                                 assign_heights_and_store_overflow)
    }
}

impl<'a> ParallelPostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> {}

fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
                         proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
    unsafe {
        let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data());

        // Get a real layout node.
        let node: LayoutNode = ::std::intrinsics::transmute(unsafe_layout_node);

        // Initialize layout data.
        //
        // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
        // parser.
        node.initialize_layout_data(layout_context.layout_chan.clone());

        // Get the parent node.
        let parent_opt = if OpaqueNode::from_layout_node(&node) == layout_context.reflow_root {
            None
        } else {
            node.parent_node()
        };

        // First, check to see whether we can share a style with someone.
        let style_sharing_candidate_cache = layout_context.style_sharing_candidate_cache();
        let sharing_result = node.share_style_if_possible(style_sharing_candidate_cache,
                                                          parent_opt.clone());

        // Otherwise, match and cascade selectors.
        match sharing_result {
            CannotShare(mut shareable) => {
                let mut applicable_declarations = ApplicableDeclarations::new();

                if node.is_element() {
                    // Perform the CSS selector matching.
                    let stylist: &Stylist = cast::transmute(layout_context.stylist);
                    node.match_node(stylist, &mut applicable_declarations, &mut shareable);
                }

                // Perform the CSS cascade.
                node.cascade_node(parent_opt,
                                  layout_context.initial_css_values.get(),
                                  &applicable_declarations,
                                  layout_context.applicable_declarations_cache());

                // Add ourselves to the LRU cache.
                if shareable {
                    style_sharing_candidate_cache.insert_if_possible(&node);
                }
            }
            StyleWasShared(index) => style_sharing_candidate_cache.touch(index),
        }

        // Prepare for flow construction by counting the node's children and storing that count.
        let mut child_count = 0;
        for _ in node.children() {
            child_count += 1;
        }
        if child_count != 0 {
            let mut layout_data_ref = node.mutate_layout_data();
            match *layout_data_ref.get() {
                Some(ref mut layout_data) => {
                    layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
                }
                None => fail!("no layout data"),
            }

            // Enqueue kids.
            for kid in node.children() {
                proxy.push(WorkUnit {
                    fun: recalc_style_for_node,
                    data: layout_node_to_unsafe_layout_node(&kid),
                });
            }
            return
        }

        // If we got here, we're a leaf. Start construction of flows for this node.
        construct_flows(unsafe_layout_node, proxy)
    }
}

fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode,
                   proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
    loop {
        let layout_context: &mut LayoutContext = unsafe {
            cast::transmute(*proxy.user_data())
        };

        // Get a real layout node.
        let node: LayoutNode = unsafe {
            cast::transmute(unsafe_layout_node)
        };

        // Construct flows for this node.
        {
            let mut flow_constructor = FlowConstructor::new(layout_context, None);
            flow_constructor.process(&ThreadSafeLayoutNode::new(&node));
        }

        // Reset the count of children for the next traversal.
        //
        // FIXME(pcwalton): Use children().len() when the implementation of that is efficient.
        let mut child_count = 0;
        for _ in node.children() {
            child_count += 1
        }
        {
            let mut layout_data_ref = node.mutate_layout_data();
            match *layout_data_ref.get() {
                Some(ref mut layout_data) => {
                    layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
                }
                None => fail!("no layout data"),
            }
        }

        // If this is the reflow root, we're done.
        if layout_context.reflow_root == OpaqueNode::from_layout_node(&node) {
            break
        }

        // Otherwise, enqueue the parent.
        match node.parent_node() {
            Some(parent) => {

                // No, we're not at the root yet. Then are we the last sibling of our parent?
                // If so, we can continue on with our parent; otherwise, we've gotta wait.
                unsafe {
                    match *parent.borrow_layout_data_unchecked() {
                        Some(ref parent_layout_data) => {
                            let parent_layout_data = cast::transmute_mut(parent_layout_data);
                            if parent_layout_data.data
                                                 .parallel
                                                 .children_count
                                                 .fetch_sub(1, SeqCst) == 1 {
                                // We were the last child of our parent. Construct flows for our
                                // parent.
                                unsafe_layout_node = layout_node_to_unsafe_layout_node(&parent)
                            } else {
                                // Get out of here and find another node to work on.
                                break
                            }
                        }
                        None => fail!("no layout data for parent?!"),
                    }
                }
            }
            None => fail!("no parent and weren't at reflow root?!"),
        }
    }
}

fn assign_widths(unsafe_flow: PaddedUnsafeFlow,
                 proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
    let layout_context: &mut LayoutContext = unsafe {
        cast::transmute(*proxy.user_data())
    };
    let mut assign_widths_traversal = AssignWidthsTraversal {
        layout_context: layout_context,
    };
    assign_widths_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
}

fn assign_heights_and_store_overflow(unsafe_flow: PaddedUnsafeFlow,
                                     proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
    let layout_context: &mut LayoutContext = unsafe {
        cast::transmute(*proxy.user_data())
    };
    let mut assign_heights_traversal = AssignHeightsAndStoreOverflowTraversal {
        layout_context: layout_context,
    };
    assign_heights_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
}

pub fn recalc_style_for_subtree(root_node: &LayoutNode,
                                layout_context: &mut LayoutContext,
                                queue: &mut WorkQueue<*mut LayoutContext,UnsafeLayoutNode>) {
    unsafe {
        queue.data = cast::transmute(layout_context)
    }

    // Enqueue the root node.
    queue.push(WorkUnit {
        fun: recalc_style_for_node,
        data: layout_node_to_unsafe_layout_node(root_node),
    });

    queue.run();

    queue.data = ptr::mut_null()
}

pub fn traverse_flow_tree_preorder(root: &mut ~Flow,
                                   profiler_chan: ProfilerChan,
                                   layout_context: &mut LayoutContext,
                                   queue: &mut WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>) {
    unsafe {
        queue.data = cast::transmute(layout_context)
    }

    profile(time::LayoutParallelWarmupCategory, profiler_chan, || {
        queue.push(WorkUnit {
            fun: assign_widths,
            data: UnsafeFlowConversions::from_flow(&mut_owned_flow_to_unsafe_flow(root)),
        })
    });

    queue.run();

    queue.data = ptr::mut_null()
}
<commit_msg>layout: Update `parallel.rs` to use `OpaqueNodeMethods`<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/. */

//! Implements parallel traversals over the DOM and flow trees.
//!
//! This code is highly unsafe. Keep this file small and easy to audit.

use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared};
use layout::construct::FlowConstructor;
use layout::context::LayoutContext;
use layout::extra::LayoutAuxMethods;
use layout::flow::{Flow, PreorderFlowTraversal, PostorderFlowTraversal};
use layout::flow;
use layout::layout_task::{AssignHeightsAndStoreOverflowTraversal, AssignWidthsTraversal};
use layout::layout_task::{BubbleWidthsTraversal};
use layout::util::{LayoutDataAccess, OpaqueNodeMethods};
use layout::wrapper::{layout_node_to_unsafe_layout_node, LayoutNode, PostorderNodeMutTraversal};
use layout::wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode};

use gfx::display_list::OpaqueNode;
use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use servo_util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
use std::cast;
use std::ptr;
use std::sync::atomics::{AtomicInt, Relaxed, SeqCst};
use style::{Stylist, TNode};

#[allow(dead_code)]
fn static_assertion(node: UnsafeLayoutNode) {
    unsafe {
        let _: PaddedUnsafeFlow = ::std::intrinsics::transmute(node);
    }
}

/// Memory representation that is at least as large as UnsafeLayoutNode, as it must be
/// safely transmutable to and from that type to accommodate the type-unsafe parallel work
/// queue usage that stores both flows and nodes.
pub type PaddedUnsafeFlow = (uint, uint, uint);

trait UnsafeFlowConversions {
    fn to_flow(&self) -> UnsafeFlow;
    fn from_flow(flow: &UnsafeFlow) -> Self;
}

impl UnsafeFlowConversions for PaddedUnsafeFlow {
    fn to_flow(&self) -> UnsafeFlow {
        let (vtable, ptr, _padding) = *self;
        (vtable, ptr)
    }

    fn from_flow(flow: &UnsafeFlow) -> PaddedUnsafeFlow {
        let &(vtable, ptr) = flow;
        (vtable, ptr, 0)
    }
}

/// Vtable + pointer representation of a Flow trait object.
pub type UnsafeFlow = (uint, uint);

fn null_unsafe_flow() -> UnsafeFlow {
    (0, 0)
}

pub fn owned_flow_to_unsafe_flow(flow: *~Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&*flow)
    }
}

pub fn mut_owned_flow_to_unsafe_flow(flow: *mut ~Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&*flow)
    }
}

pub fn borrowed_flow_to_unsafe_flow(flow: &Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&flow)
    }
}

pub fn mut_borrowed_flow_to_unsafe_flow(flow: &mut Flow) -> UnsafeFlow {
    unsafe {
        cast::transmute_copy(&flow)
    }
}

/// Information that we need stored in each DOM node.
pub struct DomParallelInfo {
    /// The number of children that still need work done.
    children_count: AtomicInt,
}

impl DomParallelInfo {
    pub fn new() -> DomParallelInfo {
        DomParallelInfo {
            children_count: AtomicInt::new(0),
        }
    }
}

/// Information that we need stored in each flow.
pub struct FlowParallelInfo {
    /// The number of children that still need work done.
    children_count: AtomicInt,
    /// The address of the parent flow.
    parent: UnsafeFlow,
}

impl FlowParallelInfo {
    pub fn new() -> FlowParallelInfo {
        FlowParallelInfo {
            children_count: AtomicInt::new(0),
            parent: null_unsafe_flow(),
        }
    }
}

/// A parallel bottom-up flow traversal.
trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
    /// Process current flow and potentially traverse its ancestors.
    ///
    /// If we are the last child that finished processing, recursively process
    /// our parent. Else, stop.
    /// Also, stop at the root (obviously :P).
    ///
    /// Thus, if we start with all the leaves of a tree, we end up traversing
    /// the whole tree bottom-up because each parent will be processed exactly
    /// once (by the last child that finishes processing).
    ///
    /// The only communication between siblings is that they both
    /// fetch-and-subtract the parent's children count.
    fn run_parallel(&mut self,
                    mut unsafe_flow: UnsafeFlow,
                    _: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
        loop {
            unsafe {
                // Get a real flow.
                let flow: &mut ~Flow = cast::transmute(&unsafe_flow);

                // Perform the appropriate traversal.
                if self.should_process(*flow) {
                    self.process(*flow);
                }

                let base = flow::mut_base(*flow);

                // Reset the count of children for the next layout traversal.
                base.parallel.children_count.store(base.children.len() as int, Relaxed);

                // Possibly enqueue the parent.
                let unsafe_parent = base.parallel.parent;
                if unsafe_parent == null_unsafe_flow() {
                    // We're done!
                    break
                }

                // No, we're not at the root yet. Then are we the last child
                // of our parent to finish processing? If so, we can continue
                // on with our parent; otherwise, we've gotta wait.
                let parent: &mut ~Flow = cast::transmute(&unsafe_parent);
                let parent_base = flow::mut_base(*parent);
                if parent_base.parallel.children_count.fetch_sub(1, SeqCst) == 1 {
                    // We were the last child of our parent. Reflow our parent.
                    unsafe_flow = unsafe_parent
                } else {
                    // Stop.
                    break
                }
            }
        }
    }
}

/// A parallel top-down flow traversal.
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
    fn run_parallel(&mut self,
                    unsafe_flow: UnsafeFlow,
                    proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>);

    fn run_parallel_helper(&mut self,
                           unsafe_flow: UnsafeFlow,
                           proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>,
                           top_down_func: extern "Rust" fn(PaddedUnsafeFlow,
                                                           &mut WorkerProxy<*mut LayoutContext,
                                                                            PaddedUnsafeFlow>),
                           bottom_up_func: extern "Rust" fn(PaddedUnsafeFlow,
                                                            &mut WorkerProxy<*mut LayoutContext,
                                                                             PaddedUnsafeFlow>)) {
        let mut had_children = false;
        unsafe {
            // Get a real flow.
            let flow: &mut ~Flow = cast::transmute(&unsafe_flow);

            // Perform the appropriate traversal.
            self.process(*flow);

            // Possibly enqueue the children.
            for kid in flow::child_iter(*flow) {
                had_children = true;
                proxy.push(WorkUnit {
                    fun: top_down_func,
                    data: UnsafeFlowConversions::from_flow(&borrowed_flow_to_unsafe_flow(kid)),
                });
            }

        }

        // If there were no more children, start assigning heights.
        if !had_children {
            bottom_up_func(UnsafeFlowConversions::from_flow(&unsafe_flow), proxy)
        }
    }
}

impl<'a> ParallelPostorderFlowTraversal for BubbleWidthsTraversal<'a> {}

impl<'a> ParallelPreorderFlowTraversal for AssignWidthsTraversal<'a> {
    fn run_parallel(&mut self,
                    unsafe_flow: UnsafeFlow,
                    proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
        self.run_parallel_helper(unsafe_flow,
                                 proxy,
                                 assign_widths,
                                 assign_heights_and_store_overflow)
    }
}

impl<'a> ParallelPostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> {}

fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
                         proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
    unsafe {
        let layout_context: &mut LayoutContext = cast::transmute(*proxy.user_data());

        // Get a real layout node.
        let node: LayoutNode = ::std::intrinsics::transmute(unsafe_layout_node);

        // Initialize layout data.
        //
        // FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
        // parser.
        node.initialize_layout_data(layout_context.layout_chan.clone());

        // Get the parent node.
        let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&node);
        let parent_opt = if opaque_node == layout_context.reflow_root {
            None
        } else {
            node.parent_node()
        };

        // First, check to see whether we can share a style with someone.
        let style_sharing_candidate_cache = layout_context.style_sharing_candidate_cache();
        let sharing_result = node.share_style_if_possible(style_sharing_candidate_cache,
                                                          parent_opt.clone());

        // Otherwise, match and cascade selectors.
        match sharing_result {
            CannotShare(mut shareable) => {
                let mut applicable_declarations = ApplicableDeclarations::new();

                if node.is_element() {
                    // Perform the CSS selector matching.
                    let stylist: &Stylist = cast::transmute(layout_context.stylist);
                    node.match_node(stylist, &mut applicable_declarations, &mut shareable);
                }

                // Perform the CSS cascade.
                node.cascade_node(parent_opt,
                                  layout_context.initial_css_values.get(),
                                  &applicable_declarations,
                                  layout_context.applicable_declarations_cache());

                // Add ourselves to the LRU cache.
                if shareable {
                    style_sharing_candidate_cache.insert_if_possible(&node);
                }
            }
            StyleWasShared(index) => style_sharing_candidate_cache.touch(index),
        }

        // Prepare for flow construction by counting the node's children and storing that count.
        let mut child_count = 0;
        for _ in node.children() {
            child_count += 1;
        }
        if child_count != 0 {
            let mut layout_data_ref = node.mutate_layout_data();
            match *layout_data_ref.get() {
                Some(ref mut layout_data) => {
                    layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
                }
                None => fail!("no layout data"),
            }

            // Enqueue kids.
            for kid in node.children() {
                proxy.push(WorkUnit {
                    fun: recalc_style_for_node,
                    data: layout_node_to_unsafe_layout_node(&kid),
                });
            }
            return
        }

        // If we got here, we're a leaf. Start construction of flows for this node.
        construct_flows(unsafe_layout_node, proxy)
    }
}

fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode,
                   proxy: &mut WorkerProxy<*mut LayoutContext,UnsafeLayoutNode>) {
    loop {
        let layout_context: &mut LayoutContext = unsafe {
            cast::transmute(*proxy.user_data())
        };

        // Get a real layout node.
        let node: LayoutNode = unsafe {
            cast::transmute(unsafe_layout_node)
        };

        // Construct flows for this node.
        {
            let mut flow_constructor = FlowConstructor::new(layout_context, None);
            flow_constructor.process(&ThreadSafeLayoutNode::new(&node));
        }

        // Reset the count of children for the next traversal.
        //
        // FIXME(pcwalton): Use children().len() when the implementation of that is efficient.
        let mut child_count = 0;
        for _ in node.children() {
            child_count += 1
        }
        {
            let mut layout_data_ref = node.mutate_layout_data();
            match *layout_data_ref.get() {
                Some(ref mut layout_data) => {
                    layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
                }
                None => fail!("no layout data"),
            }
        }

        // If this is the reflow root, we're done.
        let opaque_node: OpaqueNode = OpaqueNodeMethods::from_layout_node(&node);
        if layout_context.reflow_root == opaque_node {
            break
        }

        // Otherwise, enqueue the parent.
        match node.parent_node() {
            Some(parent) => {

                // No, we're not at the root yet. Then are we the last sibling of our parent?
                // If so, we can continue on with our parent; otherwise, we've gotta wait.
                unsafe {
                    match *parent.borrow_layout_data_unchecked() {
                        Some(ref parent_layout_data) => {
                            let parent_layout_data = cast::transmute_mut(parent_layout_data);
                            if parent_layout_data.data
                                                 .parallel
                                                 .children_count
                                                 .fetch_sub(1, SeqCst) == 1 {
                                // We were the last child of our parent. Construct flows for our
                                // parent.
                                unsafe_layout_node = layout_node_to_unsafe_layout_node(&parent)
                            } else {
                                // Get out of here and find another node to work on.
                                break
                            }
                        }
                        None => fail!("no layout data for parent?!"),
                    }
                }
            }
            None => fail!("no parent and weren't at reflow root?!"),
        }
    }
}

fn assign_widths(unsafe_flow: PaddedUnsafeFlow,
                 proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
    let layout_context: &mut LayoutContext = unsafe {
        cast::transmute(*proxy.user_data())
    };
    let mut assign_widths_traversal = AssignWidthsTraversal {
        layout_context: layout_context,
    };
    assign_widths_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
}

fn assign_heights_and_store_overflow(unsafe_flow: PaddedUnsafeFlow,
                                     proxy: &mut WorkerProxy<*mut LayoutContext,PaddedUnsafeFlow>) {
    let layout_context: &mut LayoutContext = unsafe {
        cast::transmute(*proxy.user_data())
    };
    let mut assign_heights_traversal = AssignHeightsAndStoreOverflowTraversal {
        layout_context: layout_context,
    };
    assign_heights_traversal.run_parallel(unsafe_flow.to_flow(), proxy)
}

pub fn recalc_style_for_subtree(root_node: &LayoutNode,
                                layout_context: &mut LayoutContext,
                                queue: &mut WorkQueue<*mut LayoutContext,UnsafeLayoutNode>) {
    unsafe {
        queue.data = cast::transmute(layout_context)
    }

    // Enqueue the root node.
    queue.push(WorkUnit {
        fun: recalc_style_for_node,
        data: layout_node_to_unsafe_layout_node(root_node),
    });

    queue.run();

    queue.data = ptr::mut_null()
}

pub fn traverse_flow_tree_preorder(root: &mut ~Flow,
                                   profiler_chan: ProfilerChan,
                                   layout_context: &mut LayoutContext,
                                   queue: &mut WorkQueue<*mut LayoutContext,PaddedUnsafeFlow>) {
    unsafe {
        queue.data = cast::transmute(layout_context)
    }

    profile(time::LayoutParallelWarmupCategory, profiler_chan, || {
        queue.push(WorkUnit {
            fun: assign_widths,
            data: UnsafeFlowConversions::from_flow(&mut_owned_flow_to_unsafe_flow(root)),
        })
    });

    queue.run();

    queue.data = ptr::mut_null()
}
<|endoftext|>


<commit_before><commit_msg>unsafe mutability of static variables<commit_after><|endoftext|>


<commit_before><commit_msg>Implements operations suitable on Option type. It can represents emptiness.<commit_after>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use ncollections::ops::*;

impl<T> Cardinality for Option<T>
{
  type Size = usize;
  fn size(&self) -> usize {
    self.is_some() as usize
  }
}

impl<T> Singleton<T> for Option<T> {
  fn singleton(value: T) -> Option<T> {
    Some(value)
  }
}

impl<T> Empty for Option<T> {
  fn empty() -> Option<T> {
    None
  }
}

impl<T: Bounded> Bounded for Option<T> {
  type Bound = T::Bound;
  fn lower(&self) -> T::Bound {
    debug_assert!(self.is_some(), "Cannot access lower bound on empty `Option` type.");
    self.as_ref().unwrap().lower()
  }
  fn upper(&self) -> T::Bound {
    debug_assert!(self.is_some(), "Cannot access upper bound on empty `Option` type.");
    self.as_ref().unwrap().upper()
  }
}

impl<T: PartialEq+Clone> Intersection for Option<T> {
  type Output = Option<T>;
  fn intersection(&self, other: &Option<T>) -> Option<T> {
    if self.is_empty() || other.is_empty() || self != other {
      None
    }
    else {
      self.clone()
    }
  }
}

impl<T: PartialEq+Clone> Difference for Option<T> {
  type Output = Option<T>;
  fn difference(&self, other: &Option<T>) -> Option<T> {
    if self.is_empty() || self == other {
      None
    }
    else {
      self.clone()
    }
  }
}

impl<T, U> Disjoint<Option<U>> for Option<T> where
  T: Disjoint<U>
{
  fn is_disjoint(&self, other: &Option<U>) -> bool {
    self.is_empty() || other.is_empty() ||
    self.as_ref().unwrap().is_disjoint(other.as_ref().unwrap())
  }
}

impl<U, T> Contains<U> for Option<T> where
  T: Contains<U>
{
  fn contains(&self, value: &U) -> bool {
    self.as_ref().map_or(false, |x| x.contains(value))
  }
}

impl<T, U> Subset<Option<U>> for Option<T> where
  T: Subset<U>
{
  fn is_subset(&self, other: &Option<U>) -> bool {
    if self.is_empty() { true }
    else if other.is_empty() { false }
    else {
      self.as_ref().unwrap().is_subset(other.as_ref().unwrap())
    }
  }
}

impl<T> ProperSubset for Option<T> where
  T: Subset + PartialEq
{
  fn is_proper_subset(&self, other: &Option<T>) -> bool {
    self.is_subset(other) && self != other
  }
}

impl<T> Overlap for Option<T> where
  T: Overlap
{
  fn overlap(&self, other: &Option<T>) -> bool {
    if self.is_empty() || other.is_empty() { false }
    else {
      self.as_ref().unwrap().overlap(other.as_ref().unwrap())
    }
  }
}

fn shrink_if<T, F>(value: &Option<T>, bound: T, cond: F) -> Option<T> where
  T: Ord+Clone,
  F: FnOnce(&T, &T) -> bool
{
  match value {
    &Some(ref x) if cond(x, &bound) => Some(x.clone()),
    _ => None
  }
}

impl<T> ShrinkLeft<T> for Option<T> where
  T: Ord+Clone
{
  fn shrink_left(&self, lb: T) -> Self {
    shrink_if(self, lb, |x, lb| x >= lb)
  }
}

impl<T> ShrinkRight<T> for Option<T> where
  T: Ord+Clone
{
  fn shrink_right(&self, ub: T) -> Self {
    shrink_if(self, ub, |x, ub| x <= ub)
  }
}

impl<T> StrictShrinkLeft<T> for Option<T> where
  T: Ord+Clone
{
  fn strict_shrink_left(&self, lb: T) -> Self {
    shrink_if(self, lb, |x, lb| x > lb)
  }
}

impl<T> StrictShrinkRight<T> for Option<T> where
  T: Ord+Clone
{
  fn strict_shrink_right(&self, ub: T) -> Self {
    shrink_if(self, ub, |x, ub| x < ub)
  }
}

#[allow(non_upper_case_globals)]
#[cfg(test)]
mod tests {
  use ncollections::ops::*;

  const empty: Option<i32> = None;
  const zero: Option<i32> = Some(0);
  const ten: Option<i32> = Some(10);

  #[test]
  fn cardinality_test() {
    assert_eq!(empty.size(), 0);
    assert_eq!(zero.size(), 1);
    assert_eq!(ten.size(), 1);
    assert!(empty.is_empty());
    assert!(!empty.is_singleton());
    assert!(!zero.is_empty());
    assert!(zero.is_singleton());
  }

  #[test]
  fn constructors_test() {
    assert_eq!(empty, Empty::empty());
    assert_eq!(zero, Singleton::singleton(0));
  }

  #[test]
  fn bound_test() {
    assert_eq!(zero.lower(), 0);
    assert_eq!(zero.upper(), 0);
    assert_eq!(ten.lower(), 10);
    assert_eq!(ten.upper(), 10);
  }

  #[test]
  #[should_panic]
  fn bound_upper_panic_test() {
    empty.upper();
  }

  #[test]
  #[should_panic]
  fn bound_lower_panic_test() {
    empty.lower();
  }

  #[test]
  fn intersection_test() {
    let sym_cases = vec![
      (empty, empty, empty),
      (empty, zero, empty),
      (zero, zero, zero),
      (zero, ten, empty),
      (ten, ten, ten)
    ];

    for (x,y,r) in sym_cases.into_iter() {
      assert!(x.intersection(&y) == r, "{:?} intersection {:?} is not equal to {:?}", x, y, r);
      assert!(y.intersection(&x) == r, "{:?} intersection {:?} is not equal to {:?}", y, x, r);
    }
  }

  #[test]
  fn difference_test() {
    let cases = vec![
      (empty, empty,  empty, empty),
      (empty, zero,   empty, zero),
      (zero, zero,    empty, empty),
      (zero, ten,     zero, ten),
      (ten, ten,      empty, empty)
    ];

    for (x,y,r1,r2) in cases.into_iter() {
      assert!(x.difference(&y) == r1, "{:?} difference {:?} is not equal to {:?}", x, y, r1);
      assert!(y.difference(&x) == r2, "{:?} difference {:?} is not equal to {:?}", y, x, r2);
    }
  }

  #[test]
  fn is_disjoint_test() {
    let sym_cases = vec![
      (empty, empty, true),
      (empty, zero, true),
      (zero, zero, false),
      (zero, ten, true),
      (ten, ten, false)
    ];

    for (x,y,r) in sym_cases.into_iter() {
      assert!(x.is_disjoint(&y) == r, "{:?} disjoint {:?} is not equal to {:?}", x, y, r);
      assert!(y.is_disjoint(&x) == r, "{:?} disjoint {:?} is not equal to {:?}", y, x, r);
    }
  }

  #[test]
  fn contains_test() {
    let cases = vec![
      (empty, 0, false),
      (empty, 1, false),
      (zero, 0, true),
      (zero, 1, false),
      (ten, 9, false),
      (ten, 10, true)
    ];

    for (x,y,r) in cases.into_iter() {
      assert!(x.contains(&y) == r, "{:?} contains {:?} is not equal to {:?}", x, y, r);
    }
  }

  #[test]
  fn subset_test() {
    let cases = vec![
      (empty, empty,  true, true),
      (empty, zero,   true, false),
      (zero, zero,    true, true),
      (zero, ten,     false, false),
      (ten, ten,      true, true)
    ];

    for (x,y,r1,r2) in cases.into_iter() {
      assert!(x.is_subset(&y) == r1, "{:?} subset {:?} is not equal to {:?}", x, y, r1);
      assert!(y.is_subset(&x) == r2, "{:?} subset {:?} is not equal to {:?}", y, x, r2);
    }
  }

  #[test]
  fn proper_subset_test() {
    let cases = vec![
      (empty, empty,  false, false),
      (empty, zero,   true, false),
      (zero, zero,    false, false),
      (zero, ten,     false, false),
      (ten, ten,      false, false)
    ];

    for (x,y,r1,r2) in cases.into_iter() {
      assert!(x.is_proper_subset(&y) == r1, "{:?} proper_subset {:?} is not equal to {:?}", x, y, r1);
      assert!(y.is_proper_subset(&x) == r2, "{:?} proper_subset {:?} is not equal to {:?}", y, x, r2);
    }
  }

  #[test]
  fn overlap_test() {
    let sym_cases = vec![
      (empty, empty, false),
      (empty, zero, false),
      (zero, zero, true),
      (zero, ten, false),
      (ten, ten, true)
    ];

    for (x,y,r) in sym_cases.into_iter() {
      assert!(x.overlap(&y) == r, "{:?} overlap {:?} is not equal to {:?}", x, y, r);
      assert!(y.overlap(&x) == r, "{:?} overlap {:?} is not equal to {:?}", y, x, r);
    }
  }

  #[test]
  fn shrink_tests() {
    // First two elements are data. The next are resp. for shrink_left, shrink_right,
    // strict_shrink_left and strict_shrink_right.
    let cases = vec![
      (empty, 0, empty, empty, empty, empty),
      (empty, 1, empty, empty, empty, empty),
      (zero, 0, zero, zero, empty, empty),
      (zero, 1, empty, zero, empty, zero),
      (ten, 9, ten, empty, ten, empty),
      (ten, 10, ten, ten, empty, empty),
      (ten, 11, empty, ten, empty, ten),
    ];

    for (x,y,r1,r2,r3,r4) in cases.into_iter() {
      assert!(x.shrink_left(y) == r1, "{:?} shrink_left {:?} is not equal to {:?}", x, y, r1);
      assert!(x.shrink_right(y) == r2, "{:?} shrink_right {:?} is not equal to {:?}", x, y, r2);
      assert!(x.strict_shrink_left(y) == r3, "{:?} strict_shrink_left {:?} is not equal to {:?}", x, y, r3);
      assert!(x.strict_shrink_right(y) == r4, "{:?} strict_shrink_right {:?} is not equal to {:?}", x, y, r4);
    }
  }
}
<|endoftext|>


<commit_before><commit_msg>Add test for try operator on Result<commit_after>// run-pass

#![feature(try_trait_v2)]
#![feature(const_trait_impl)]
#![feature(const_try)]
#![feature(const_convert)]

fn main() {
    const fn foo() -> Result<bool, ()> {
        Err(())?;
        Ok(true)
    }

    const FOO: Result<bool, ()> = foo();
    assert_eq!(Err(()), FOO);
}
<|endoftext|>


<commit_before><commit_msg>rustdoc: Add a test for fixed issue #16019<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.

macro_rules! define_struct {
    ($rounds:expr) => (
        struct Struct {
            sk: [u32; $rounds + 1]
        }
        )
}

define_struct!(2);
<|endoftext|>


<commit_before><commit_msg>Reduce database lookup upon insertion<commit_after><|endoftext|>


<commit_before><commit_msg>Whoops (add java.rs)<commit_after>use std::io::{Write, Result};
use {Function, Type, TypeKind};

fn to_camel_case(snake_case: &str) -> String {
    let mut camel_case = String::new();

    for (u, split) in snake_case.split('_').enumerate() {
        for (i, c) in split.char_indices() {
            if u != 0 && i == 0 {
                camel_case.extend(c.to_uppercase());
            } else {
                camel_case.push(c);
            }
        }
    }

    camel_case
}

fn get_type(ty: &Type) -> &str {
    match (ty.kind, ty.name.as_str()) {
        (TypeKind::Ref, "c_char") => "String",
        (TypeKind::Ref, _) |
        (TypeKind::RefMut, _) => "Pointer",
        (_, t) if !ty.is_custom => {
            match t {
                "i8" => "byte",
                "i16" => "short",
                "i32" => "int",
                "i64" => "long",
                "u8" => "byte",
                "u16" => "short",
                "u32" => "int",
                "u64" => "long",
                "usize" => "NativeLong", // Not really correct
                "f32" => "float",
                "f64" => "double",
                "bool" => "byte",
                "()" => "void",
                "c_char" => "byte",
                x => x,
            }
        }
        _ => "Pointer",
    }
}

pub fn write<W: Write>(mut writer: W, functions: &[Function]) -> Result<()> {
    let mut prefix = String::from("");

    write!(writer,
           "{}",
           r#"package livesplitcore;

import com.sun.jna.*;

public interface LiveSplitCore extends Library {
    LiveSplitCore INSTANCE = (LiveSplitCore) Native.loadLibrary("livesplit-core", LiveSplitCore.class);
"#)?;

    for function in functions {
        let name = function.name.to_string();
        let mut splits = name.splitn(2, '_');
        let new_prefix = splits.next().unwrap();
        if !prefix.is_empty() && new_prefix != prefix {
            writeln!(writer, "")?;
        }
        prefix = new_prefix.to_string();

        write!(writer,
               r#"
    {} {}("#,
               get_type(&function.output),
               &function.name)?;

        for (i, &(ref name, ref typ)) in function.inputs.iter().enumerate() {
            if i != 0 {
                write!(writer, ", ")?;
            }
            write!(writer,
                   "{} {}",
                   get_type(typ),
                   if name == "this" {
                       String::from("self")
                   } else {
                       to_camel_case(name)
                   })?;
        }

        write!(writer, ");")?;
    }

    writeln!(writer,
             "{}",
             r#"
}"#)
}
<|endoftext|>


<commit_before><commit_msg>send reset command to start the game environment<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>style refactors from code review<commit_after><|endoftext|>


<commit_before><commit_msg>Started part B for day 9 [WIP]<commit_after>use regex::Regex;

pub fn solve(data: &str) {

    println!("{}", "------------- [ PART B ] -------------");
    println!("NOOT NOOT! its da sound of da pingu 🐧");
    println!("{}", "--------------------------------------");
}

pub struct Node {
    content_length: usize,
    multiplier: usize,
    nodes: Vec<Node>
}

impl Node {
    pub fn len(&self) -> usize {
        self.multiplier * (self.content_length + self.nodes.iter().fold(0, {|v, n| v + n.len() }))
    }
}

#[cfg(test)]
mod node_tests {
    use part_b::Node;

    #[test]
    fn test_solve_without_subnodes() {
        let subject = Node { content_length: 10, multiplier: 3, nodes: Vec::new() };
        assert_eq!(subject.len(), 30);
    }

    #[test]
    fn test_solve_with_one_level_subnodes() {
        // example: (22x11)(3x5)ICQ(9x5)IYUPTHPKX

        let subnodes = vec![
            Node { content_length: 3, multiplier: 5, nodes: Vec::new() },
            Node { content_length: 9, multiplier: 5, nodes: Vec::new() },
        ];

        let subject = Node {
            content_length: 0,
            multiplier: 22,
            nodes: subnodes
        };

        assert_eq!(subject.len(), 1320);
    }

    fn test_solve_with_multi_level_subnodes() {
        // example: (answer should be 5220)
        // (127x2)                          => (1098 + 140 + 1372) * 2 = 5220
        //      (41x6)                      => (144 + 39) * 6 = 1098
        //          (16x9)SIUZCKMFZFXKUYTQ  => 144
        //          (13x3)YBCVHJPPFAONV     => 39
        //      (10x14)BTRWBQRUHA           => 10 * 14 = 140
        //      (57x4)                      => (180 + 55 + 72 + 36) * 4 = 1372
        //          (12x15)ZUMPYOEOOBFW     => 180
        //          (5x11)YNLIJ             => 55
        //          (8x9)GBQFPTOH           => 72
        //          (9x3)GPFCSAPZD          => 36

        let subject = Node {
            content_length: 0,
            multiplier: 2,
            nodes: vec![
                Node {
                    content_length: 0,
                    multiplier: 6,
                    nodes: vec![
                        Node { content_length: 16, multiplier: 9, nodes: Vec::new() },
                        Node { content_length: 13, multiplier: 3, nodes: Vec::new() },
                    ]
                },

                Node {
                    content_length: 10,
                    multiplier: 14,
                    nodes: Vec::new()
                },

                Node {
                    content_length: 0,
                    multiplier: 4,
                    nodes: vec![
                        Node { content_length: 12, multiplier: 15, nodes: Vec::new() },
                        Node { content_length: 5, multiplier: 11, nodes: Vec::new() },
                        Node { content_length: 8, multiplier: 9, nodes: Vec::new() },
                        Node { content_length: 9, multiplier: 3, nodes: Vec::new() },
                    ]
                },
            ]
        };

        assert_eq!(subject.len(), 5220);

    }
}
<|endoftext|>


<commit_before><commit_msg>refactor(scanner): use shorthand for property assign<commit_after><|endoftext|>


<commit_before>use std::fmt;
use std::str::FromStr;
use header::{Header, HeaderFormat};
use super::util::{from_one_comma_delimited, fmt_comma_delimited};

/// The Cache-Control header.
#[deriving(PartialEq, Clone, Show)]
pub struct CacheControl(pub Vec<CacheDirective>);

deref!(CacheControl -> Vec<CacheDirective>);

impl Header for CacheControl {
    fn header_name(_: Option<CacheControl>) -> &'static str {
        "Cache-Control"
    }

    fn parse_header(raw: &[Vec<u8>]) -> Option<CacheControl> {
        let directives = raw.iter()
            .filter_map(|line| from_one_comma_delimited(line[]))
            .collect::<Vec<Vec<CacheDirective>>>()
            .concat_vec();
        if directives.len() > 0 {
            Some(CacheControl(directives))
        } else {
            None
        }
    }
}

impl HeaderFormat for CacheControl {
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt_comma_delimited(fmt, self[])
    }
}

/// CacheControl contains a list of these directives.
#[deriving(PartialEq, Clone)]
pub enum CacheDirective {
    /// "no-cache"
    NoCache,
    /// "no-store"
    NoStore,
    /// "no-transform"
    NoTransform,
    /// "only-if-cached"
    OnlyIfCached,

    // request directives
    /// "max-age=delta"
    MaxAge(uint),
    /// "max-stale=delta"
    MaxStale(uint),
    /// "min-fresh=delta"
    MinFresh(uint),

    // response directives
    /// "must-revalidate"
    MustRevalidate,
    /// "public"
    Public,
    /// "private"
    Private,
    /// "proxy-revalidate"
    ProxyRevalidate,
    /// "s-maxage=delta"
    SMaxAge(uint),

    /// Extension directives. Optionally include an argument.
    Extension(String, Option<String>)
}

impl fmt::Show for CacheDirective {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::CacheDirective::*;
        match *self {
            NoCache => "no-cache",
            NoStore => "no-store",
            NoTransform => "no-transform",
            OnlyIfCached => "only-if-cached",

            MaxAge(secs) => return write!(f, "max-age={}", secs),
            MaxStale(secs) => return write!(f, "max-stale={}", secs),
            MinFresh(secs) => return write!(f, "min-fresh={}", secs),

            MustRevalidate => "must-revalidate",
            Public => "public",
            Private => "private",
            ProxyRevalidate => "proxy-revalidate",
            SMaxAge(secs) => return write!(f, "s-maxage={}", secs),

            Extension(ref name, None) => name[],
            Extension(ref name, Some(ref arg)) => return write!(f, "{}={}", name, arg),

        }.fmt(f)
    }
}

impl FromStr for CacheDirective {
    fn from_str(s: &str) -> Option<CacheDirective> {
        use self::CacheDirective::*;
        match s {
            "no-cache" => Some(NoCache),
            "no-store" => Some(NoStore),
            "no-transform" => Some(NoTransform),
            "only-if-cached" => Some(OnlyIfCached),
            "must-revalidate" => Some(MustRevalidate),
            "public" => Some(Public),
            "private" => Some(Private),
            "proxy-revalidate" => Some(ProxyRevalidate),
            "" => None,
            _ => match s.find('=') {
                Some(idx) if idx+1 < s.len() => match (s[..idx], s[idx+1..].trim_chars('"')) {
                    ("max-age" , secs) => secs.parse().map(MaxAge),
                    ("max-stale", secs) => secs.parse().map(MaxStale),
                    ("min-fresh", secs) => secs.parse().map(MinFresh),
                    ("s-maxage", secs) => secs.parse().map(SMaxAge),
                    (left, right) => Some(Extension(left.to_string(), Some(right.to_string())))
                },
                Some(_) => None,
                None => Some(Extension(s.to_string(), None))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use header::Header;
    use super::*;

    #[test]
    fn test_parse_multiple_headers() {
        let cache = Header::parse_header(&[b"no-cache".to_vec(), b"private".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::NoCache,
                                                 CacheDirective::Private])))
    }

    #[test]
    fn test_parse_argument() {
        let cache = Header::parse_header(&[b"max-age=100, private".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::MaxAge(100),
                                                 CacheDirective::Private])))
    }

    #[test]
    fn test_parse_quote_form() {
        let cache = Header::parse_header(&[b"max-age=\"200\"".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::MaxAge(200)])))
    }

    #[test]
    fn test_parse_extension() {
        let cache = Header::parse_header(&[b"foo, bar=baz".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::Extension("foo".to_string(), None),
                                                 CacheDirective::Extension("bar".to_string(), Some("baz".to_string()))])))
    }

    #[test]
    fn test_parse_bad_syntax() {
        let cache: Option<CacheControl> = Header::parse_header(&[b"foo=".to_vec()]);
        assert_eq!(cache, None)
    }
}

bench_header!(normal, CacheControl, { vec![b"no-cache, private".to_vec(), b"max-age=100".to_vec()] });

<commit_msg>Replaced deprecated reference to trim_chars with trim_matches<commit_after>use std::fmt;
use std::str::FromStr;
use header::{Header, HeaderFormat};
use super::util::{from_one_comma_delimited, fmt_comma_delimited};

/// The Cache-Control header.
#[deriving(PartialEq, Clone, Show)]
pub struct CacheControl(pub Vec<CacheDirective>);

deref!(CacheControl -> Vec<CacheDirective>);

impl Header for CacheControl {
    fn header_name(_: Option<CacheControl>) -> &'static str {
        "Cache-Control"
    }

    fn parse_header(raw: &[Vec<u8>]) -> Option<CacheControl> {
        let directives = raw.iter()
            .filter_map(|line| from_one_comma_delimited(line[]))
            .collect::<Vec<Vec<CacheDirective>>>()
            .concat_vec();
        if directives.len() > 0 {
            Some(CacheControl(directives))
        } else {
            None
        }
    }
}

impl HeaderFormat for CacheControl {
    fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt_comma_delimited(fmt, self[])
    }
}

/// CacheControl contains a list of these directives.
#[deriving(PartialEq, Clone)]
pub enum CacheDirective {
    /// "no-cache"
    NoCache,
    /// "no-store"
    NoStore,
    /// "no-transform"
    NoTransform,
    /// "only-if-cached"
    OnlyIfCached,

    // request directives
    /// "max-age=delta"
    MaxAge(uint),
    /// "max-stale=delta"
    MaxStale(uint),
    /// "min-fresh=delta"
    MinFresh(uint),

    // response directives
    /// "must-revalidate"
    MustRevalidate,
    /// "public"
    Public,
    /// "private"
    Private,
    /// "proxy-revalidate"
    ProxyRevalidate,
    /// "s-maxage=delta"
    SMaxAge(uint),

    /// Extension directives. Optionally include an argument.
    Extension(String, Option<String>)
}

impl fmt::Show for CacheDirective {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::CacheDirective::*;
        match *self {
            NoCache => "no-cache",
            NoStore => "no-store",
            NoTransform => "no-transform",
            OnlyIfCached => "only-if-cached",

            MaxAge(secs) => return write!(f, "max-age={}", secs),
            MaxStale(secs) => return write!(f, "max-stale={}", secs),
            MinFresh(secs) => return write!(f, "min-fresh={}", secs),

            MustRevalidate => "must-revalidate",
            Public => "public",
            Private => "private",
            ProxyRevalidate => "proxy-revalidate",
            SMaxAge(secs) => return write!(f, "s-maxage={}", secs),

            Extension(ref name, None) => name[],
            Extension(ref name, Some(ref arg)) => return write!(f, "{}={}", name, arg),

        }.fmt(f)
    }
}

impl FromStr for CacheDirective {
    fn from_str(s: &str) -> Option<CacheDirective> {
        use self::CacheDirective::*;
        match s {
            "no-cache" => Some(NoCache),
            "no-store" => Some(NoStore),
            "no-transform" => Some(NoTransform),
            "only-if-cached" => Some(OnlyIfCached),
            "must-revalidate" => Some(MustRevalidate),
            "public" => Some(Public),
            "private" => Some(Private),
            "proxy-revalidate" => Some(ProxyRevalidate),
            "" => None,
            _ => match s.find('=') {
                Some(idx) if idx+1 < s.len() => match (s[..idx], s[idx+1..].trim_matches('"')) {
                    ("max-age" , secs) => secs.parse().map(MaxAge),
                    ("max-stale", secs) => secs.parse().map(MaxStale),
                    ("min-fresh", secs) => secs.parse().map(MinFresh),
                    ("s-maxage", secs) => secs.parse().map(SMaxAge),
                    (left, right) => Some(Extension(left.to_string(), Some(right.to_string())))
                },
                Some(_) => None,
                None => Some(Extension(s.to_string(), None))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use header::Header;
    use super::*;

    #[test]
    fn test_parse_multiple_headers() {
        let cache = Header::parse_header(&[b"no-cache".to_vec(), b"private".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::NoCache,
                                                 CacheDirective::Private])))
    }

    #[test]
    fn test_parse_argument() {
        let cache = Header::parse_header(&[b"max-age=100, private".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::MaxAge(100),
                                                 CacheDirective::Private])))
    }

    #[test]
    fn test_parse_quote_form() {
        let cache = Header::parse_header(&[b"max-age=\"200\"".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::MaxAge(200)])))
    }

    #[test]
    fn test_parse_extension() {
        let cache = Header::parse_header(&[b"foo, bar=baz".to_vec()]);
        assert_eq!(cache, Some(CacheControl(vec![CacheDirective::Extension("foo".to_string(), None),
                                                 CacheDirective::Extension("bar".to_string(), Some("baz".to_string()))])))
    }

    #[test]
    fn test_parse_bad_syntax() {
        let cache: Option<CacheControl> = Header::parse_header(&[b"foo=".to_vec()]);
        assert_eq!(cache, None)
    }
}

bench_header!(normal, CacheControl, { vec![b"no-cache, private".to_vec(), b"max-age=100".to_vec()] });

<|endoftext|>


<commit_before><commit_msg>Add a non-regression test for issue #8372<commit_after>// Copyright 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.

// The `for` loop use to keep a mutable borrow when executing its body,
// making it impossible to re-use the iterator as follows.
// https://github.com/rust-lang/rust/issues/8372
//
// This was fixed in https://github.com/rust-lang/rust/pull/15809

pub fn main() {
    let mut for_loop_values = Vec::new();
    let mut explicit_next_call_values = Vec::new();

    let mut iter = range(1i, 10);
    for i in iter {
        for_loop_values.push(i);
        explicit_next_call_values.push(iter.next());
    }

    assert_eq!(for_loop_values, vec![1, 3, 5, 7, 9]);
    assert_eq!(explicit_next_call_values, vec![Some(2), Some(4), Some(6), Some(8), None]);
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #1994 - RalfJung:unaligned-ptr-test, r=RalfJung<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>// Copyright 2018 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::fmt;
use std::str::FromStr;

/// The edition of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum Edition {
    // editions must be kept in order, newest to oldest

    /// The 2015 edition
    Edition2015,
    /// The 2018 edition
    Edition2018,

    // when adding new editions, be sure to update:
    //
    // - Update the `ALL_EDITIONS` const
    // - Update the EDITION_NAME_LIST const
    // - add a `rust_####()` function to the session
    // - update the enum in Cargo's sources as well
}

// must be in order from oldest to newest
pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018];

pub const EDITION_NAME_LIST: &'static str = "2015|2018";

pub const DEFAULT_EDITION: Edition = Edition::Edition2015;

impl fmt::Display for Edition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match *self {
            Edition::Edition2015 => "2015",
            Edition::Edition2018 => "2018",
        };
        write!(f, "{}", s)
    }
}

impl Edition {
    pub fn lint_name(&self) -> &'static str {
        match *self {
            Edition::Edition2015 => "edition_2015",
            Edition::Edition2018 => "edition_2018",
        }
    }

    pub fn feature_name(&self) -> &'static str {
        match *self {
            Edition::Edition2015 => "rust_2015_preview",
            Edition::Edition2018 => "rust_2018_preview",
        }
    }

    pub fn is_stable(&self) -> bool {
        match *self {
            Edition::Edition2015 => true,
            Edition::Edition2018 => false,
        }
    }
}

impl FromStr for Edition {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, ()> {
        match s {
            "2015" => Ok(Edition::Edition2015),
            "2018" => Ok(Edition::Edition2018),
            _ => Err(())
        }
    }
}
<commit_msg>Rename breakage lints<commit_after>// Copyright 2018 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::fmt;
use std::str::FromStr;

/// The edition of the compiler (RFC 2052)
#[derive(Clone, Copy, Hash, PartialOrd, Ord, Eq, PartialEq, Debug)]
#[non_exhaustive]
pub enum Edition {
    // editions must be kept in order, newest to oldest

    /// The 2015 edition
    Edition2015,
    /// The 2018 edition
    Edition2018,

    // when adding new editions, be sure to update:
    //
    // - Update the `ALL_EDITIONS` const
    // - Update the EDITION_NAME_LIST const
    // - add a `rust_####()` function to the session
    // - update the enum in Cargo's sources as well
}

// must be in order from oldest to newest
pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018];

pub const EDITION_NAME_LIST: &'static str = "2015|2018";

pub const DEFAULT_EDITION: Edition = Edition::Edition2015;

impl fmt::Display for Edition {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match *self {
            Edition::Edition2015 => "2015",
            Edition::Edition2018 => "2018",
        };
        write!(f, "{}", s)
    }
}

impl Edition {
    pub fn lint_name(&self) -> &'static str {
        match *self {
            Edition::Edition2015 => "rust_2015_breakage",
            Edition::Edition2018 => "rust_2018_breakage",
        }
    }

    pub fn feature_name(&self) -> &'static str {
        match *self {
            Edition::Edition2015 => "rust_2015_preview",
            Edition::Edition2018 => "rust_2018_preview",
        }
    }

    pub fn is_stable(&self) -> bool {
        match *self {
            Edition::Edition2015 => true,
            Edition::Edition2018 => false,
        }
    }
}

impl FromStr for Edition {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, ()> {
        match s {
            "2015" => Ok(Edition::Edition2015),
            "2018" => Ok(Edition::Edition2018),
            _ => Err(())
        }
    }
}
<|endoftext|>