<commit_before>use std::collections::HashMap;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Write;
use std::io::Seek;
use std::path::Path;

extern crate env_logger;
extern crate tools;
use tools::find_source_file;
use tools::file_format::analysis::{read_analysis, read_source, read_jumps};
use tools::format::format_file_data;
use tools::git_ops;
use tools::config;
use tools::languages;
use languages::FormatAs;

use tools::output::{PanelItem, PanelSection};

fn main() {
    env_logger::init();

    let args: Vec<_> = env::args().collect();
    let (base_args, fname_args) = args.split_at(3);

    let cfg = config::load(&base_args[1], true);
    println!("Config file read");

    let tree_name = &base_args[2];
    let tree_config = cfg.trees.get(tree_name).unwrap();

    let jumps_fname = format!("{}/jumps", tree_config.paths.index_path);
    //let jumps : std::collections::HashMap<String, tools::analysis::Jump> = std::collections::HashMap::new();
    let jumps = read_jumps(&jumps_fname);
    println!("Jumps read");

    let (blame_commit, head_oid) = match &tree_config.git {
        &Some(ref git) => {
            let head_oid = git.repo.refname_to_id("HEAD").unwrap();
            let blame_commit = if let Some(ref blame_repo) = git.blame_repo {
                let blame_oid = blame_repo.refname_to_id("HEAD").unwrap();
                Some(blame_repo.find_commit(blame_oid).unwrap())
            } else {
                None
            };
            (blame_commit, Some(head_oid))
        },
        &None => (None, None),
    };

    let mut diff_cache = git_ops::TreeDiffCache::new();
    for path in fname_args {
        println!("File {}", path);

        let output_fname = format!("{}/file/{}", tree_config.paths.index_path, path);
        let source_fname = find_source_file(path, &tree_config.paths.files_path, &tree_config.paths.objdir_path);

        let format = languages::select_formatting(path);

        let output_file = File::create(output_fname).unwrap();
        let mut writer = BufWriter::new(output_file);

        let source_file = match File::open(source_fname.clone()) {
            Ok(f) => f,
            Err(_) => {
                println!("Unable to open file");
                continue;
            },
        };

        let path_wrapper = Path::new(&source_fname);
        let metadata = fs::symlink_metadata(path_wrapper).unwrap();
        if metadata.file_type().is_symlink() {
            let dest = fs::read_link(path_wrapper).unwrap();
            write!(writer, "Symlink to {}", dest.to_str().unwrap()).unwrap();
            continue;
        }

        let mut reader = BufReader::new(&source_file);

        match format {
            FormatAs::Binary => {
                let _ = io::copy(&mut reader, &mut writer);
                continue;
            },
            _ => {},
        };

        let analysis_fname = format!("{}/analysis/{}", tree_config.paths.index_path, path);
        let analysis = read_analysis(&analysis_fname, &mut read_source);

        let mut input = String::new();
        match reader.read_to_string(&mut input) {
            Ok(_) => {},
            Err(_) => {
                let mut bytes = Vec::new();
                reader.seek(std::io::SeekFrom::Start(0)).unwrap();
                match reader.read_to_end(&mut bytes) {
                    Ok(_) => {
                        input.push_str(&bytes.iter().map(|c| *c as char).collect::<String>());
                    },
                    Err(e) => {
                        println!("Unable to read file: {:?}", e);
                        continue;
                    }
                }
            }
        }

        let mut extension_mapping = HashMap::new();
        extension_mapping.insert("cpp", ("header", vec!["h", "hh", "hpp", "hxx"]));
        extension_mapping.insert("cc", ("header", vec!["h", "hh", "hpp", "hxx"]));
        extension_mapping.insert("cxx", ("header", vec!["h", "hh", "hpp", "hxx"]));
        extension_mapping.insert("h", ("source", vec!["cpp", "cc", "cxx"]));
        extension_mapping.insert("hh", ("source", vec!["cpp", "cc", "cxx"]));
        extension_mapping.insert("hpp", ("source", vec!["cpp", "cc", "cxx"]));
        extension_mapping.insert("hxx", ("source", vec!["cpp", "cc", "cxx"]));

        let extension = path_wrapper.extension().unwrap_or(&OsStr::new("")).to_str().unwrap();
        let show_header = match extension_mapping.get(extension) {
            Some(&(ref description, ref try_extensions)) => {
                let mut result = None;
                for try_ext in try_extensions {
                    let try_buf = path_wrapper.with_extension(try_ext);
                    let try_path = try_buf.as_path();
                    if try_path.exists() {
                        let (path_base, _) = path.split_at(path.len() - extension.len() - 1);
                        result = Some((description.to_owned(), format!("/{}/source/{}.{}", tree_name, path_base, try_ext)));
                        break;
                    }
                }
                result
            },
            None => {
                None
            }
        };

        let mut panel = if let Some((other_desc, other_path)) = show_header {
            vec![PanelSection {
                name: "Source code".to_owned(),
                items: vec![PanelItem {
                    title: format!("Go to {} file", other_desc),
                    link: other_path,
                    update_link_lineno: false,
                    accel_key: None,
                }],
            }]
        } else {
            vec![]
        };

        let mut rev_panel = if path.contains("__GENERATED__") {
            vec![]
        } else if let Some(oid) = head_oid {
            vec![PanelSection {
                name: "Revision control".to_owned(),
                items: vec![PanelItem {
                    title: "Permalink".to_owned(),
                    link: format!("/{}/rev/{}/{}", tree_name, oid, path),
                    update_link_lineno: true,
                    accel_key: Some('Y'),
                }, PanelItem {
                    title: "Log".to_owned(),
                    link: format!("{}/log/tip/{}", config::get_hg_root(tree_config), path),
                    update_link_lineno: false,
                    accel_key: Some('L'),
                 }, PanelItem {
                    title: "Raw".to_owned(),
                    link: format!("{}/raw-file/tip/{}", config::get_hg_root(tree_config), path),
                    update_link_lineno: false,
                    accel_key: Some('R'),
                }, PanelItem {
                    title: "Blame".to_owned(),
                    link: "javascript:alert('Hover over the gray bar on the left to see blame information.')".to_owned(),
                    update_link_lineno: false,
                    accel_key: None,
                }],
            }]
        } else {
            vec![]
        };

        panel.append(&mut rev_panel);

        let head_commit = head_oid
            .and_then(|oid| tree_config.git.as_ref().unwrap().repo.find_commit(oid).ok());

        format_file_data(&cfg,
                         tree_name,
                         &panel,
                         &head_commit,
                         &blame_commit,
                         path,
                         input,
                         &jumps,
                         &analysis,
                         &mut writer,
                         Some(&mut diff_cache)).unwrap();
    }
}
<commit_msg>Move some computation outside the per-file loop.<commit_after>use std::collections::HashMap;
use std::env;
use std::ffi::OsStr;
use std::fs;
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Write;
use std::io::Seek;
use std::path::Path;

extern crate env_logger;
extern crate tools;
use tools::find_source_file;
use tools::file_format::analysis::{read_analysis, read_source, read_jumps};
use tools::format::format_file_data;
use tools::git_ops;
use tools::config;
use tools::languages;
use languages::FormatAs;

use tools::output::{PanelItem, PanelSection};

fn main() {
    env_logger::init();

    let args: Vec<_> = env::args().collect();
    let (base_args, fname_args) = args.split_at(3);

    let cfg = config::load(&base_args[1], true);
    println!("Config file read");

    let tree_name = &base_args[2];
    let tree_config = cfg.trees.get(tree_name).unwrap();

    let jumps_fname = format!("{}/jumps", tree_config.paths.index_path);
    //let jumps : std::collections::HashMap<String, tools::analysis::Jump> = std::collections::HashMap::new();
    let jumps = read_jumps(&jumps_fname);
    println!("Jumps read");

    let (blame_commit, head_oid) = match &tree_config.git {
        &Some(ref git) => {
            let head_oid = git.repo.refname_to_id("HEAD").unwrap();
            let blame_commit = if let Some(ref blame_repo) = git.blame_repo {
                let blame_oid = blame_repo.refname_to_id("HEAD").unwrap();
                Some(blame_repo.find_commit(blame_oid).unwrap())
            } else {
                None
            };
            (blame_commit, Some(head_oid))
        },
        &None => (None, None),
    };

    let head_commit = head_oid
        .and_then(|oid| tree_config.git.as_ref().unwrap().repo.find_commit(oid).ok());

    let mut extension_mapping = HashMap::new();
    extension_mapping.insert("cpp", ("header", vec!["h", "hh", "hpp", "hxx"]));
    extension_mapping.insert("cc", ("header", vec!["h", "hh", "hpp", "hxx"]));
    extension_mapping.insert("cxx", ("header", vec!["h", "hh", "hpp", "hxx"]));
    extension_mapping.insert("h", ("source", vec!["cpp", "cc", "cxx"]));
    extension_mapping.insert("hh", ("source", vec!["cpp", "cc", "cxx"]));
    extension_mapping.insert("hpp", ("source", vec!["cpp", "cc", "cxx"]));
    extension_mapping.insert("hxx", ("source", vec!["cpp", "cc", "cxx"]));

    let mut diff_cache = git_ops::TreeDiffCache::new();
    for path in fname_args {
        println!("File {}", path);

        let output_fname = format!("{}/file/{}", tree_config.paths.index_path, path);
        let source_fname = find_source_file(path, &tree_config.paths.files_path, &tree_config.paths.objdir_path);

        let format = languages::select_formatting(path);

        let output_file = File::create(output_fname).unwrap();
        let mut writer = BufWriter::new(output_file);

        let source_file = match File::open(source_fname.clone()) {
            Ok(f) => f,
            Err(_) => {
                println!("Unable to open file");
                continue;
            },
        };

        let path_wrapper = Path::new(&source_fname);
        let metadata = fs::symlink_metadata(path_wrapper).unwrap();
        if metadata.file_type().is_symlink() {
            let dest = fs::read_link(path_wrapper).unwrap();
            write!(writer, "Symlink to {}", dest.to_str().unwrap()).unwrap();
            continue;
        }

        let mut reader = BufReader::new(&source_file);

        match format {
            FormatAs::Binary => {
                let _ = io::copy(&mut reader, &mut writer);
                continue;
            },
            _ => {},
        };

        let analysis_fname = format!("{}/analysis/{}", tree_config.paths.index_path, path);
        let analysis = read_analysis(&analysis_fname, &mut read_source);

        let mut input = String::new();
        match reader.read_to_string(&mut input) {
            Ok(_) => {},
            Err(_) => {
                let mut bytes = Vec::new();
                reader.seek(std::io::SeekFrom::Start(0)).unwrap();
                match reader.read_to_end(&mut bytes) {
                    Ok(_) => {
                        input.push_str(&bytes.iter().map(|c| *c as char).collect::<String>());
                    },
                    Err(e) => {
                        println!("Unable to read file: {:?}", e);
                        continue;
                    }
                }
            }
        }

        let extension = path_wrapper.extension().unwrap_or(&OsStr::new("")).to_str().unwrap();
        let show_header = match extension_mapping.get(extension) {
            Some(&(ref description, ref try_extensions)) => {
                let mut result = None;
                for try_ext in try_extensions {
                    let try_buf = path_wrapper.with_extension(try_ext);
                    let try_path = try_buf.as_path();
                    if try_path.exists() {
                        let (path_base, _) = path.split_at(path.len() - extension.len() - 1);
                        result = Some((description.to_owned(), format!("/{}/source/{}.{}", tree_name, path_base, try_ext)));
                        break;
                    }
                }
                result
            },
            None => {
                None
            }
        };

        let mut panel = if let Some((other_desc, other_path)) = show_header {
            vec![PanelSection {
                name: "Source code".to_owned(),
                items: vec![PanelItem {
                    title: format!("Go to {} file", other_desc),
                    link: other_path,
                    update_link_lineno: false,
                    accel_key: None,
                }],
            }]
        } else {
            vec![]
        };

        let mut rev_panel = if path.contains("__GENERATED__") {
            vec![]
        } else if let Some(oid) = head_oid {
            vec![PanelSection {
                name: "Revision control".to_owned(),
                items: vec![PanelItem {
                    title: "Permalink".to_owned(),
                    link: format!("/{}/rev/{}/{}", tree_name, oid, path),
                    update_link_lineno: true,
                    accel_key: Some('Y'),
                }, PanelItem {
                    title: "Log".to_owned(),
                    link: format!("{}/log/tip/{}", config::get_hg_root(tree_config), path),
                    update_link_lineno: false,
                    accel_key: Some('L'),
                 }, PanelItem {
                    title: "Raw".to_owned(),
                    link: format!("{}/raw-file/tip/{}", config::get_hg_root(tree_config), path),
                    update_link_lineno: false,
                    accel_key: Some('R'),
                }, PanelItem {
                    title: "Blame".to_owned(),
                    link: "javascript:alert('Hover over the gray bar on the left to see blame information.')".to_owned(),
                    update_link_lineno: false,
                    accel_key: None,
                }],
            }]
        } else {
            vec![]
        };

        panel.append(&mut rev_panel);

        format_file_data(&cfg,
                         tree_name,
                         &panel,
                         &head_commit,
                         &blame_commit,
                         path,
                         input,
                         &jumps,
                         &analysis,
                         &mut writer,
                         Some(&mut diff_cache)).unwrap();
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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 Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
 * family of digest functions.
 */
pub trait Digest {
    /**
     * Provide message data.
     *
     * # Arguments
     *
     * * input - A vector of message data
     */
    fn input(&mut self, input: &[u8]);

    /**
     * Retrieve the digest result. This method may be called multiple times.
     *
     * # Arguments
     *
     * * out - the vector to hold the result. Must be large enough to contain output_bits().
     */
    fn result(&mut self, out: &mut [u8]);

    /**
     * Reset the digest. This method must be called after result() and before supplying more
     * data.
     */
    fn reset(&mut self);

    /**
     * Get the output size in bits.
     */
    fn output_bits(&self) -> uint;

    /**
     * Get the output size in bytes.
     */
    fn output_bytes(&self) -> uint {
        return (self.output_bits() + 7) / 8;
    }

    /**
     * Get the block size in bytes.
     */
    fn block_size(&self) -> uint;

    /**
     * Convenience function that feeds a string into a digest.
     *
     * # Arguments
     *
     * * `input` The string to feed into the digest
     */
    fn input_str(&mut self, input: &str) {
        self.input(input.as_bytes());
    }

    /**
     * Convenience function that retrieves the result of a digest as a
     * String in hexadecimal format.
     */
    fn result_str(&mut self) -> String {
        let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
        self.result(buf[mut]);
        return to_hex(buf[]);
    }
}

fn to_hex(rr: &[u8]) -> String {
    let mut s = String::new();
    for b in rr.iter() {
        let hex = format!("{:02x}", *b);
        s.push_str(hex[]);
    }
    return s;
}
<commit_msg>Use ToHex to format digest results<commit_after>// Copyright 2012-2013 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 Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
 * family of digest functions.
 */
pub trait Digest {
    /**
     * Provide message data.
     *
     * # Arguments
     *
     * * input - A vector of message data
     */
    fn input(&mut self, input: &[u8]);

    /**
     * Retrieve the digest result. This method may be called multiple times.
     *
     * # Arguments
     *
     * * out - the vector to hold the result. Must be large enough to contain output_bits().
     */
    fn result(&mut self, out: &mut [u8]);

    /**
     * Reset the digest. This method must be called after result() and before supplying more
     * data.
     */
    fn reset(&mut self);

    /**
     * Get the output size in bits.
     */
    fn output_bits(&self) -> uint;

    /**
     * Get the output size in bytes.
     */
    fn output_bytes(&self) -> uint {
        return (self.output_bits() + 7) / 8;
    }

    /**
     * Get the block size in bytes.
     */
    fn block_size(&self) -> uint;

    /**
     * Convenience function that feeds a string into a digest.
     *
     * # Arguments
     *
     * * `input` The string to feed into the digest
     */
    fn input_str(&mut self, input: &str) {
        self.input(input.as_bytes());
    }

    /**
     * Convenience function that retrieves the result of a digest as a
     * String in hexadecimal format.
     */
    fn result_str(&mut self) -> String {
        use serialize::hex::ToHex;

        let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8);
        self.result(buf[mut]);
        return buf[].to_hex();
    }
}
<|endoftext|>


<commit_before>use std::time::{SystemTime, UNIX_EPOCH};

use cairo::ImageSurface;
use cairo_sys;
use glib::translate::ToGlibPtr;
use wlroots::{project_box, Area, CompositorHandle, OutputHandle, OutputHandler,
              OutputLayoutHandle, Renderer, Size, WL_SHM_FORMAT_ARGB8888, SurfaceHandle, Origin};

use awesome::{Drawin, Objectable, DRAWINS_HANDLE, LUA};
use compositor::{Server, View};
use rlua::{self, AnyUserData, Lua};

pub struct Output;

impl OutputHandler for Output {
    fn on_frame(&mut self, compositor: CompositorHandle, output: OutputHandle) {
        with_handles!([(compositor: {compositor}), (output: {output})] => {
            let state: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut layout,
                         ref mut views,
                         .. } = *state;
            let renderer = compositor.renderer.as_mut().expect("gles2 disabled");
            let mut renderer = renderer.render(output, None);
            renderer.clear([0.25, 0.25, 0.25, 1.0]);
            render_views(&mut renderer, layout, views);
            LUA.with(|lua| {
                let mut lua = lua.borrow_mut();
                match render_drawins(&mut *lua, &mut renderer) {
                    Ok(_) => {},
                    Err(err) => {
                        warn!("Error rendering drawins: {:#?}", err);
                    }
                }
            });
        }).unwrap();
    }
}

/// Render all of the client views.
fn render_views(renderer: &mut Renderer, layout: &mut OutputLayoutHandle, views: &mut [View]) {
    with_handles!([(layout: {&mut *layout})] => {
    for view in views {
        let origin = view.origin;
        view.for_each_surface(&mut |surface: SurfaceHandle, sx, sy| {
            with_handles!([(surface: {surface})] => {
                let (width, height) = surface.current_state().size();
                let (render_width, render_height) =
                    (width * renderer.output.scale() as i32,
                    height * renderer.output.scale() as i32);
                let render_box = Area::new(Origin::new(origin.x + sx, origin.y + sy),
                                           Size::new(render_width,
                                                     render_height));

                if layout.intersects(renderer.output, render_box) {
                    let transform = renderer.output.get_transform().invert();
                    let matrix = project_box(render_box,
                                             transform,
                                             0.0,
                                             renderer.output
                                             .transform_matrix());
                    renderer.render_texture_with_matrix(&surface.texture(),
                    matrix);
                    let start = SystemTime::now();
                    let now = start.duration_since(UNIX_EPOCH)
                        .expect("Time went backwards");
                    surface.send_frame_done(now);
                }
            }).expect("Could not render views")
        });
    }
    }).unwrap();
}

/// Render all of the drawins provided by Lua.
fn render_drawins(lua: &Lua, renderer: &mut Renderer) -> rlua::Result<()> {
    let drawins = lua.named_registry_value::<Vec<AnyUserData>>(DRAWINS_HANDLE)?;
    for drawin in drawins {
        let mut drawin = Drawin::cast(drawin.into())?;
        if !drawin.get_visible()? {
            continue
        }
        let geometry = drawin.get_geometry()?;
        let drawable = drawin.drawable()?;
        let mut drawable_state = drawable.state()?;
        let surface = match drawable_state.surface.as_mut() {
            Some(surface) => surface,
            None => continue
        };
        let Area { size: Size { width, height },
                   .. } = geometry;
        let data = get_data(surface);
        let texture = renderer.create_texture_from_pixels(WL_SHM_FORMAT_ARGB8888,
                                                          (width * 4) as _,
                                                          width as _,
                                                          height as _,
                                                          data)
                              .expect("Could not allocate texture");
        let transform_matrix = renderer.output.transform_matrix();
        let inverted_transform = renderer.output.get_transform().invert();
        let matrix = project_box(geometry, inverted_transform, 0.0, transform_matrix);
        renderer.render_texture_with_matrix(&texture, matrix);
    }
    Ok(())
}

/// Get the data associated with an ImageSurface.
fn get_data(surface: &mut ImageSurface) -> &[u8] {
    use std::slice;
    // NOTE This is safe to do because there's one thread.
    //
    // We know Lua is not modifying it because it's not running.
    //
    // Otherwise we'd need to make a copy of the buffer. This ensure we
    // don't need to do that.
    unsafe {
        let len = surface.get_stride() as usize * surface.get_height() as usize;
        let surface = surface.to_glib_none().0;
        slice::from_raw_parts(cairo_sys::cairo_image_surface_get_data(surface as _), len)
    }
}
<commit_msg>use with_handles later for the layout<commit_after>use std::time::{SystemTime, UNIX_EPOCH};

use cairo::ImageSurface;
use cairo_sys;
use glib::translate::ToGlibPtr;
use wlroots::{project_box, Area, CompositorHandle, OutputHandle, OutputHandler,
              OutputLayoutHandle, Renderer, Size, WL_SHM_FORMAT_ARGB8888, SurfaceHandle, Origin};

use awesome::{Drawin, Objectable, DRAWINS_HANDLE, LUA};
use compositor::{Server, View};
use rlua::{self, AnyUserData, Lua};

pub struct Output;

impl OutputHandler for Output {
    fn on_frame(&mut self, compositor: CompositorHandle, output: OutputHandle) {
        with_handles!([(compositor: {compositor}), (output: {output})] => {
            let state: &mut Server = compositor.data.downcast_mut().unwrap();
            let Server { ref mut layout,
                         ref mut views,
                         .. } = *state;
            let renderer = compositor.renderer.as_mut().expect("gles2 disabled");
            let mut renderer = renderer.render(output, None);
            renderer.clear([0.25, 0.25, 0.25, 1.0]);
            render_views(&mut renderer, layout, views);
            LUA.with(|lua| {
                let mut lua = lua.borrow_mut();
                match render_drawins(&mut *lua, &mut renderer) {
                    Ok(_) => {},
                    Err(err) => {
                        warn!("Error rendering drawins: {:#?}", err);
                    }
                }
            });
        }).unwrap();
    }
}

/// Render all of the client views.
fn render_views(renderer: &mut Renderer, layout: &mut OutputLayoutHandle, views: &mut [View]) {
    for view in views {
        let origin = view.origin;
        view.for_each_surface(&mut |surface: SurfaceHandle, sx, sy| {
            with_handles!([(surface: {surface}), (layout: {&mut *layout})] => {
                let (width, height) = surface.current_state().size();
                let (render_width, render_height) =
                    (width * renderer.output.scale() as i32,
                    height * renderer.output.scale() as i32);
                let render_box = Area::new(Origin::new(origin.x + sx, origin.y + sy),
                                           Size::new(render_width,
                                                     render_height));

                if layout.intersects(renderer.output, render_box) {
                    let transform = renderer.output.get_transform().invert();
                    let matrix = project_box(render_box,
                                             transform,
                                             0.0,
                                             renderer.output
                                             .transform_matrix());
                    renderer.render_texture_with_matrix(&surface.texture(),
                    matrix);
                    let start = SystemTime::now();
                    let now = start.duration_since(UNIX_EPOCH)
                        .expect("Time went backwards");
                    surface.send_frame_done(now);
                }
            }).expect("Could not render views")
        });
    }
}

/// Render all of the drawins provided by Lua.
fn render_drawins(lua: &Lua, renderer: &mut Renderer) -> rlua::Result<()> {
    let drawins = lua.named_registry_value::<Vec<AnyUserData>>(DRAWINS_HANDLE)?;
    for drawin in drawins {
        let mut drawin = Drawin::cast(drawin.into())?;
        if !drawin.get_visible()? {
            continue
        }
        let geometry = drawin.get_geometry()?;
        let drawable = drawin.drawable()?;
        let mut drawable_state = drawable.state()?;
        let surface = match drawable_state.surface.as_mut() {
            Some(surface) => surface,
            None => continue
        };
        let Area { size: Size { width, height },
                   .. } = geometry;
        let data = get_data(surface);
        let texture = renderer.create_texture_from_pixels(WL_SHM_FORMAT_ARGB8888,
                                                          (width * 4) as _,
                                                          width as _,
                                                          height as _,
                                                          data)
                              .expect("Could not allocate texture");
        let transform_matrix = renderer.output.transform_matrix();
        let inverted_transform = renderer.output.get_transform().invert();
        let matrix = project_box(geometry, inverted_transform, 0.0, transform_matrix);
        renderer.render_texture_with_matrix(&texture, matrix);
    }
    Ok(())
}

/// Get the data associated with an ImageSurface.
fn get_data(surface: &mut ImageSurface) -> &[u8] {
    use std::slice;
    // NOTE This is safe to do because there's one thread.
    //
    // We know Lua is not modifying it because it's not running.
    //
    // Otherwise we'd need to make a copy of the buffer. This ensure we
    // don't need to do that.
    unsafe {
        let len = surface.get_stride() as usize * surface.get_height() as usize;
        let surface = surface.to_glib_none().0;
        slice::from_raw_parts(cairo_sys::cairo_image_surface_get_data(surface as _), len)
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate sputnikvm;
extern crate bigint;
extern crate serde_json;
extern crate gethrpc;

use serde_json::{Value};
use std::process;
use std::fs::File;
use std::path::Path;
use std::io::{BufReader};
use std::str::FromStr;

use sputnikvm::{Gas, Address};
use bigint::{U256, M256, read_hex};
use sputnikvm::vm::{BlockHeader, Context, SeqVM, Patch};
use gethrpc::{regression, GethRPCClient, RPCCall, RPCBlock, RPCTransaction};

fn from_rpc_block(block: &RPCBlock) -> BlockHeader {
    BlockHeader {
        coinbase: Address::from_str(&block.miner).unwrap(),
        timestamp: M256::from_str(&block.timestamp).unwrap(),
        number: M256::from_str(&block.number).unwrap(),
        difficulty: M256::from_str(&block.difficulty).unwrap(),
        gas_limit: Gas::from_str(&block.gasLimit).unwrap(),
    }
}

fn from_rpc_transaction_and_code(transaction: &RPCTransaction, code: &str) -> Context {
    Context {
        caller: Address::from_str(&transaction.from).unwrap(),
        address: Address::from_str(&transaction.to).unwrap(),
        origin: Address::from_str(&transaction.to).unwrap(),
        value: U256::from_str(&transaction.value).unwrap(),
        code: read_hex(code).unwrap(),
        data: read_hex(&transaction.input).unwrap(),
        gas_limit: Gas::from_str(&transaction.gas).unwrap(),
        gas_price: Gas::from_str(&transaction.gasPrice).unwrap(),
    }
}

fn main() {
    let mut client = GethRPCClient::new("http://127.0.0.1:8545");

    println!("net version: {}", client.net_version());

    let block = client.get_block_by_number(format!("0x{:x}", 49439).as_str());
    println!("block {}, transaction count: {}", block.number, block.transactions.len());

    let block_header = from_rpc_block(&block);
    println!("block header: {:?}", block_header);

    for transaction_hash in block.transactions {
        println!("\nworking on transaction {}", transaction_hash);
        let transaction = client.get_transaction_by_hash(&transaction_hash);
        println!("transaction: {:?}", transaction);
        let receipt = client.get_transaction_receipt(&transaction_hash);
        println!("receipt: {:?}", receipt);
        let code = client.get_code(&transaction.to, &block.number);
        println!("code: {:?}", code);

        let context = from_rpc_transaction_and_code(&transaction, &code);
        println!("context: {:?}", context);

        let mut vm = SeqVM::new(context, block_header.clone(), Patch::empty());
        loop {
            match vm.fire() {
                Ok(()) => {
                    println!("VM exited successfully, checking results ...");
                    break;
                },
                Err(err) => {
                    println!("Unhandled require: {:?}", err);
                    unimplemented!()
                },
            }
        }

        println!("\ntests after the vm has run:");
        println!("2. test gasUsed == {:?}", receipt.gasUsed);
        println!("3. logs and order is {:?}", receipt.logs);
    }

    println!("\nwhen the block is finished, test:");
    println!("1. balances of all used accounts.");
    println!("2. storage values touched.");

    // let matches = clap_app!(regression_test =>
    //     (version: "0.1")
    //     (author: "Ethereum Classic Contributors")
    //     (about: "Gaslighter - Tests the Ethereum Classic Virtual Machine in 5 different ways.")
    //     (@arg KEEP_GOING: -k --keep_going "Don't exit the program even if a test fails.")
    //     (@subcommand reg =>
    //         (about: "Performs an regression test on the entire Ethereum Classic blockchain.\n\nSteps to reproduce:\n* Install Ethereum Classic Geth: `$ go install github.com/ethereumproject/go-ethereum/cmd/geth`.\n* Run Geth with this command: `$ ~/go/bin/geth`.\n* Wait for the chain to sync.\n* <ctrl-c>\n* Change directory into the gaslighter directory `$ cd gaslighter`\n* Run this command: `$ RUST_BACKTRACE=1 RUST_LOG=gaslighter cargo run --bin gaslighter -- -k reg -c ~/.ethereum/chaindata/`")
    //         (@arg RPC: -r --rpc +takes_value +required "Domain of Ethereum Classic Geth's RPC endpoint. e.g. `-r localhost:8888`.")
    //     )
    // ).get_matches();
    // let mut has_regression_test_passed = true;
    // let keep_going = if matches.is_present("KEEP_GOING") { true } else { false };
    // if let Some(ref matches) = matches.subcommand_matches("reg") {
    //     let path = matches.value_of("RPC").unwrap();
    //     has_regression_test_passed = regression(path);
    // }
    // if has_regression_test_passed {
    //     process::exit(0);
    // } else {
    //     process::exit(1);
    // }
}
<commit_msg>Problem: block header and context println is too verbose<commit_after>#[macro_use]
extern crate clap;
extern crate sputnikvm;
extern crate bigint;
extern crate serde_json;
extern crate gethrpc;

use serde_json::{Value};
use std::process;
use std::fs::File;
use std::path::Path;
use std::io::{BufReader};
use std::str::FromStr;

use sputnikvm::{Gas, Address};
use bigint::{U256, M256, read_hex};
use sputnikvm::vm::{BlockHeader, Context, SeqVM, Patch};
use gethrpc::{regression, GethRPCClient, RPCCall, RPCBlock, RPCTransaction};

fn from_rpc_block(block: &RPCBlock) -> BlockHeader {
    BlockHeader {
        coinbase: Address::from_str(&block.miner).unwrap(),
        timestamp: M256::from_str(&block.timestamp).unwrap(),
        number: M256::from_str(&block.number).unwrap(),
        difficulty: M256::from_str(&block.difficulty).unwrap(),
        gas_limit: Gas::from_str(&block.gasLimit).unwrap(),
    }
}

fn from_rpc_transaction_and_code(transaction: &RPCTransaction, code: &str) -> Context {
    Context {
        caller: Address::from_str(&transaction.from).unwrap(),
        address: Address::from_str(&transaction.to).unwrap(),
        origin: Address::from_str(&transaction.to).unwrap(),
        value: U256::from_str(&transaction.value).unwrap(),
        code: read_hex(code).unwrap(),
        data: read_hex(&transaction.input).unwrap(),
        gas_limit: Gas::from_str(&transaction.gas).unwrap(),
        gas_price: Gas::from_str(&transaction.gasPrice).unwrap(),
    }
}

fn main() {
    let mut client = GethRPCClient::new("http://127.0.0.1:8545");

    println!("net version: {}", client.net_version());

    let block = client.get_block_by_number(format!("0x{:x}", 49439).as_str());
    println!("block {}, transaction count: {}", block.number, block.transactions.len());

    let block_header = from_rpc_block(&block);

    for transaction_hash in block.transactions {
        println!("\nworking on transaction {}", transaction_hash);
        let transaction = client.get_transaction_by_hash(&transaction_hash);
        println!("transaction: {:?}", transaction);
        let receipt = client.get_transaction_receipt(&transaction_hash);
        println!("receipt: {:?}", receipt);
        let code = client.get_code(&transaction.to, &block.number);
        println!("code: {:?}", code);

        let context = from_rpc_transaction_and_code(&transaction, &code);

        let mut vm = SeqVM::new(context, block_header.clone(), Patch::empty());
        loop {
            match vm.fire() {
                Ok(()) => {
                    println!("VM exited successfully, checking results ...");
                    break;
                },
                Err(err) => {
                    println!("Unhandled require: {:?}", err);
                    unimplemented!()
                },
            }
        }

        println!("\ntests after the vm has run:");
        println!("2. test gasUsed == {:?}", receipt.gasUsed);
        println!("3. logs and order is {:?}", receipt.logs);
    }

    println!("\nwhen the block is finished, test:");
    println!("1. balances of all used accounts.");
    println!("2. storage values touched.");

    // let matches = clap_app!(regression_test =>
    //     (version: "0.1")
    //     (author: "Ethereum Classic Contributors")
    //     (about: "Gaslighter - Tests the Ethereum Classic Virtual Machine in 5 different ways.")
    //     (@arg KEEP_GOING: -k --keep_going "Don't exit the program even if a test fails.")
    //     (@subcommand reg =>
    //         (about: "Performs an regression test on the entire Ethereum Classic blockchain.\n\nSteps to reproduce:\n* Install Ethereum Classic Geth: `$ go install github.com/ethereumproject/go-ethereum/cmd/geth`.\n* Run Geth with this command: `$ ~/go/bin/geth`.\n* Wait for the chain to sync.\n* <ctrl-c>\n* Change directory into the gaslighter directory `$ cd gaslighter`\n* Run this command: `$ RUST_BACKTRACE=1 RUST_LOG=gaslighter cargo run --bin gaslighter -- -k reg -c ~/.ethereum/chaindata/`")
    //         (@arg RPC: -r --rpc +takes_value +required "Domain of Ethereum Classic Geth's RPC endpoint. e.g. `-r localhost:8888`.")
    //     )
    // ).get_matches();
    // let mut has_regression_test_passed = true;
    // let keep_going = if matches.is_present("KEEP_GOING") { true } else { false };
    // if let Some(ref matches) = matches.subcommand_matches("reg") {
    //     let path = matches.value_of("RPC").unwrap();
    //     has_regression_test_passed = regression(path);
    // }
    // if has_regression_test_passed {
    //     process::exit(0);
    // } else {
    //     process::exit(1);
    // }
}
<|endoftext|>


<commit_before>//! Bubble sort algorithm.
//!
//! The `bubble` module contains the simple sorting algorithm "Bubble Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Bubble_sort

extern crate libc;

use std::slice;

/// Simple sort: bubble sort.
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
///
///
/// # Notes
///
///
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::simplesorts::bubble::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: PartialOrd>(input: &mut [T]) {
    unimplemented!();
}

#[no_mangle]
pub extern fn ffi_bubblesort_i8(array_pointer: *const libc::int8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i16(array_pointer: *const libc::int16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i32(array_pointer: *const libc::int32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i64(array_pointer: *const libc::int64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_bubblesort_u8(array_pointer: *const libc::uint8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u16(array_pointer: *const libc::uint16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u32(array_pointer: *const libc::uint32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u64(array_pointer: *const libc::uint64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_bubblesort_f32(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_f64(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f64, n as usize)
    };
    sort(&mut to_sort);
}
<commit_msg>Implement bubble sort.<commit_after>//! Bubble sort algorithm.
//!
//! The `bubble` module contains the simple sorting algorithm "Bubble Sort".
//!
//! Source: https://en.wikipedia.org/wiki/Bubble_sort

extern crate libc;

use std::slice;

/// Simple sort: bubble sort.
///
/// # Details
///
///
///
/// # Scaling
///
///
///
/// # Optimizations
///
///
///
/// # Notes
///
///
///
/// The type T of the vector elements to sort _must_ implement the `PartialOrd` trait so the
/// compiler knows how to compare the elements and sort them.
///
/// # Examples
///
/// ```
/// let mut data: Vec<i32> = vec![4, 2, 3, 1, 5];
/// sorting::simplesorts::bubble::sort(&mut data);
/// assert_eq!(vec![1, 2, 3, 4, 5], data);
/// ```
///
pub fn sort<T: PartialOrd>(input: &mut [T]) {
    let n = input.len();

    for i in 0..n {
        for j in 0..n-i-1 {
            if input[j] > input[j+1] {
                input.swap(j,j+1);
            }
        }
    }
}

#[no_mangle]
pub extern fn ffi_bubblesort_i8(array_pointer: *const libc::int8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i16(array_pointer: *const libc::int16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i32(array_pointer: *const libc::int32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_i64(array_pointer: *const libc::int64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut i64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_bubblesort_u8(array_pointer: *const libc::uint8_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u8, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u16(array_pointer: *const libc::uint16_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u16, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u32(array_pointer: *const libc::uint32_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_u64(array_pointer: *const libc::uint64_t, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut u64, n as usize)
    };
    sort(&mut to_sort);
}

#[no_mangle]
pub extern "C" fn ffi_bubblesort_f32(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f32, n as usize)
    };
    sort(&mut to_sort);
}
#[no_mangle]
pub extern "C" fn ffi_bubblesort_f64(array_pointer: *const libc::c_void, n: libc::size_t) {
    assert!(!array_pointer.is_null());
    assert!(n != 0);
    let mut to_sort = unsafe {
        slice::from_raw_parts_mut(array_pointer as *mut f64, n as usize)
    };
    sort(&mut to_sort);
}
<|endoftext|>


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

extern crate grust;
extern crate "grust-Gio-2_0" as gio;

use gio::File;
use grust::refcount::{Ref,SyncRef};
use grust::native::LoopRunner;
use grust::object;

use std::string;

// Test timeout in milliseconds
// static TEST_TIMEOUT: uint = 3000u;

fn tcase(test: proc(): Send) {
    test()
}

#[test]
fn utf8_buf_to_string() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().to_string();
        assert_eq!(path, String::from_str("/dev/null"));
    })
}

#[test]
fn utf8_buf_into_string() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_string();
        assert_eq!(path, String::from_str("/dev/null"));
    })
}

#[test]
fn utf8_buf_into_collection() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn utf8_buf_to_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().to_c_str();
        assert_eq!(path, "/dev/null".to_c_str());
    })
}

#[test]
fn utf8_buf_with_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        f.borrow_mut().get_path().with_c_str(|p| {
            let s = unsafe { string::raw::from_buf(p as *const u8) };
            assert_eq!(s, String::from_str("/dev/null"));
        });
    })
}

#[test]
fn utf8_str_eq() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path1 = f.borrow_mut().get_path().into_collection();
        let path2 = f.borrow_mut().get_path().into_collection();
        assert!(path1 == path2);
    })
}

#[test]
fn utf8_str_ne() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let mut g = File::new_for_path("/dev/zero");
        let path1 = f.borrow_mut().get_path().into_collection();
        let path2 = g.borrow_mut().get_path().into_collection();
        assert!(path1 != path2);
    })
}

#[test]
fn utf8_str_len() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        assert_eq!(path.len(), "/dev/null".len());
    })
}

#[test]
fn utf8_sized_with_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        path.with_c_str(|p| {
            let s = unsafe { string::raw::from_buf(p as *const u8) };
            assert_eq!(s, String::from_str("/dev/null"));
        });
    })
}

#[test]
fn new_ref() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let mut g = Ref::new(f.borrow_mut());
        let path = g.borrow_mut().get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn clone() {
    tcase(proc() {
        let rf = File::new_for_path("/dev/null");
        let mut rg = rf.clone();
        let g = rg.borrow_mut();
        let path = g.get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn async() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let runner = LoopRunner::new();
        runner.run_after(|mainloop| {
            let mut rml = SyncRef::new(mainloop);
            f.read_async(0, None,
                box proc(obj, res) {
                    let f: &mut File = object::cast_mut(obj);
                    match f.read_finish(res) {
                        Ok(_)  => {}
                        Err(_) => { println!("Error!") }  // TODO: impl Fmt for Error
                    }
                    rml.quit();
                });
        });
    })
}
<commit_msg>Homogenized a test name<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

extern crate grust;
extern crate "grust-Gio-2_0" as gio;

use gio::File;
use grust::refcount::{Ref,SyncRef};
use grust::native::LoopRunner;
use grust::object;

use std::string;

// Test timeout in milliseconds
// static TEST_TIMEOUT: uint = 3000u;

fn tcase(test: proc(): Send) {
    test()
}

#[test]
fn utf8_buf_to_string() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().to_string();
        assert_eq!(path, String::from_str("/dev/null"));
    })
}

#[test]
fn utf8_buf_into_string() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_string();
        assert_eq!(path, String::from_str("/dev/null"));
    })
}

#[test]
fn utf8_buf_into_collection() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn utf8_buf_to_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().to_c_str();
        assert_eq!(path, "/dev/null".to_c_str());
    })
}

#[test]
fn utf8_buf_with_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        f.borrow_mut().get_path().with_c_str(|p| {
            let s = unsafe { string::raw::from_buf(p as *const u8) };
            assert_eq!(s, String::from_str("/dev/null"));
        });
    })
}

#[test]
fn utf8_str_eq() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path1 = f.borrow_mut().get_path().into_collection();
        let path2 = f.borrow_mut().get_path().into_collection();
        assert!(path1 == path2);
    })
}

#[test]
fn utf8_str_ne() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let mut g = File::new_for_path("/dev/zero");
        let path1 = f.borrow_mut().get_path().into_collection();
        let path2 = g.borrow_mut().get_path().into_collection();
        assert!(path1 != path2);
    })
}

#[test]
fn utf8_str_len() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        assert_eq!(path.len(), "/dev/null".len());
    })
}

#[test]
fn utf8_str_with_c_str() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let path = f.borrow_mut().get_path().into_collection();
        path.with_c_str(|p| {
            let s = unsafe { string::raw::from_buf(p as *const u8) };
            assert_eq!(s, String::from_str("/dev/null"));
        });
    })
}

#[test]
fn new_ref() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let mut g = Ref::new(f.borrow_mut());
        let path = g.borrow_mut().get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn clone() {
    tcase(proc() {
        let rf = File::new_for_path("/dev/null");
        let mut rg = rf.clone();
        let g = rg.borrow_mut();
        let path = g.get_path().into_collection();
        assert_eq!(path.as_slice(), "/dev/null");
    })
}

#[test]
fn async() {
    tcase(proc() {
        let mut f = File::new_for_path("/dev/null");
        let runner = LoopRunner::new();
        runner.run_after(|mainloop| {
            let mut rml = SyncRef::new(mainloop);
            f.read_async(0, None,
                box proc(obj, res) {
                    let f: &mut File = object::cast_mut(obj);
                    match f.read_finish(res) {
                        Ok(_)  => {}
                        Err(_) => { println!("Error!") }  // TODO: impl Fmt for Error
                    }
                    rml.quit();
                });
        });
    })
}
<|endoftext|>


<commit_before>fn get_version() -> Result<String, String> {
    //TODO:
    //  Gets the version of the package
}

fn put_version() -> Result<bool, String> {
    //TODO:
    // Sets/Updates the version of the package
}<commit_msg>Basic function for parsing package version list.<commit_after>use std::fs::File;
use std::io::{ BufRead, BufReader };
use std::path::Path;

fn parse_list(path: &Path) -> Result<Vec<(String, u32)>, String> {
    let list = match File::open(path) {
        Ok(x) => x,
        Err(why) => return Err(format!("{}", why))
    };
    let list = BufReader::new(list);

    let parsed_packages = Vec::new();
    for line in list.lines() {
        let split: Vec<&str> = line.unwrap_or(String::from("")).trim().split('=').collect();
        let package_name = String::from(split[0]);
        let package_version = split[1].parse::<u32>().unwrap_or(0); // For this reason, version of packages MUST NOT BE 0

        if !package_name.is_empty() || package_version != 0 {
            parsed_packages.push((package_name, package_version));
        }
    }

    if parsed_packages.len() > 0 {
        return Ok(parsed_packages)
    } else {
        return Err(String::from("No package found."))
    }
}

fn get_version(name: &str, path: &Path) -> Option<u32> {
    //TODO:
    //  Gets the version of the package

}

fn put_version() -> Result<bool, String>{
    //TODO:
    // Sets/Updates the version of the package
}<|endoftext|>


<commit_before>use std::collections::HashMap;

use chrono::prelude::*;
use tera::{Map, Value};
use toml;

use errors::Result;
use utils::de::fix_toml_dates;

/// The front matter of every page
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(default)]
pub struct PageFrontMatter {
    /// <title> of the page
    pub title: Option<String>,
    /// Description in <meta> that appears when linked, e.g. on twitter
    pub description: Option<String>,
    /// Date if we want to order pages (ie blog post)
    #[serde(default, deserialize_with = "utils::de::from_toml_datetime")]
    pub date: Option<String>,
    /// Chrono converted datetime
    #[serde(default, skip_deserializing)]
    pub datetime: Option<NaiveDateTime>,
    /// The converted date into a (year, month, day) tuple
    #[serde(default, skip_deserializing)]
    pub datetime_tuple: Option<(i32, u32, u32)>,
    /// Whether this page is a draft and should be ignored for pagination etc
    pub draft: bool,
    /// The page slug. Will be used instead of the filename if present
    /// Can't be an empty string if present
    pub slug: Option<String>,
    /// The path the page appears at, overrides the slug if set in the front-matter
    /// otherwise is set after parsing front matter and sections
    /// Can't be an empty string if present
    pub path: Option<String>,
    pub taxonomies: HashMap<String, Vec<String>>,
    /// Integer to use to order content. Lowest is at the bottom, highest first
    pub order: Option<usize>,
    /// Integer to use to order content. Highest is at the bottom, lowest first
    pub weight: Option<usize>,
    /// All aliases for that page. Zola will create HTML templates that will
    /// redirect to this
    #[serde(skip_serializing)]
    pub aliases: Vec<String>,
    /// Specify a template different from `page.html` to use for that page
    #[serde(skip_serializing)]
    pub template: Option<String>,
    /// Whether the page is included in the search index
    /// Defaults to `true` but is only used if search if explicitly enabled in the config.
    #[serde(skip_serializing)]
    pub in_search_index: bool,
    /// Any extra parameter present in the front matter
    pub extra: Map<String, Value>,
}

impl PageFrontMatter {
    pub fn parse(toml: &str) -> Result<PageFrontMatter> {
        let mut f: PageFrontMatter = match toml::from_str(toml) {
            Ok(d) => d,
            Err(e) => bail!(e),
        };

        if let Some(ref slug) = f.slug {
            if slug == "" {
                bail!("`slug` can't be empty if present")
            }
        }

        if let Some(ref path) = f.path {
            if path == "" {
                bail!("`path` can't be empty if present")
            }
        }

        f.extra = match fix_toml_dates(f.extra) {
            Value::Object(o) => o,
            _ => unreachable!("Got something other than a table in page extra"),
        };

        f.date_to_datetime();

        Ok(f)
    }

    /// Converts the TOML datetime to a Chrono naive datetime
    /// Also grabs the year/month/day tuple that will be used in serialization
    pub fn date_to_datetime(&mut self) {
        self.datetime = if let Some(ref d) = self.date {
            if d.contains('T') {
                DateTime::parse_from_rfc3339(&d).ok().and_then(|s| Some(s.naive_local()))
            } else {
                NaiveDate::parse_from_str(&d, "%Y-%m-%d")
                    .ok()
                    .and_then(|s| Some(s.and_hms(0, 0, 0)))
            }
        } else {
            None
        };

        self.datetime_tuple = if let Some(ref dt) = self.datetime {
            Some((dt.year(), dt.month(), dt.day()))
        } else {
            None
        };
    }

    pub fn order(&self) -> usize {
        self.order.unwrap()
    }

    pub fn weight(&self) -> usize {
        self.weight.unwrap()
    }
}

impl Default for PageFrontMatter {
    fn default() -> PageFrontMatter {
        PageFrontMatter {
            title: None,
            description: None,
            date: None,
            datetime: None,
            datetime_tuple: None,
            draft: false,
            slug: None,
            path: None,
            taxonomies: HashMap::new(),
            order: None,
            weight: None,
            aliases: Vec::new(),
            in_search_index: true,
            template: None,
            extra: Map::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::PageFrontMatter;
    use tera::to_value;

    #[test]
    fn can_have_empty_front_matter() {
        let content = r#"  "#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
    }

    #[test]
    fn can_parse_valid_front_matter() {
        let content = r#"
    title = "Hello"
    description = "hey there""#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_ok());
        let res = res.unwrap();
        assert_eq!(res.title.unwrap(), "Hello".to_string());
        assert_eq!(res.description.unwrap(), "hey there".to_string())
    }

    #[test]
    fn errors_with_invalid_front_matter() {
        let content = r#"title = 1\n"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn errors_on_present_but_empty_slug() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    slug = """#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn errors_on_present_but_empty_path() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    path = """#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn can_parse_date_yyyy_mm_dd() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2016-10-10
    "#;
        let res = PageFrontMatter::parse(content).unwrap();
        assert!(res.date.is_some());
    }

    #[test]
    fn can_parse_date_rfc3339() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002-10-02T15:00:00Z
    "#;
        let res = PageFrontMatter::parse(content).unwrap();
        assert!(res.date.is_some());
    }

    #[test]
    fn cannot_parse_random_date_format() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002/10/12"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn cannot_parse_invalid_date_format() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn cannot_parse_date_as_string() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = "2002-14-01""#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn can_parse_dates_in_extra() {
        let content = r#"
    title = "Hello"
    description = "hey there"

    [extra]
    some-date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        assert_eq!(res.unwrap().extra["some-date"], to_value("2002-14-01").unwrap());
    }

    #[test]
    fn can_parse_nested_dates_in_extra() {
        let content = r#"
    title = "Hello"
    description = "hey there"

    [extra.something]
    some-date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
    }

    #[test]
    fn can_parse_taxonomies() {
        let content = r#"
title = "Hello World"

[taxonomies]
tags = ["Rust", "JavaScript"]
categories = ["Dev"]
"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        let res2 = res.unwrap();
        assert_eq!(res2.taxonomies["categories"], vec!["Dev"]);
        assert_eq!(res2.taxonomies["tags"], vec!["Rust", "JavaScript"]);
    }
}
<commit_msg>Fix build for 1.28<commit_after>use std::collections::HashMap;

use chrono::prelude::*;
use serde::Deserialize;
use tera::{Map, Value};
use toml;

use errors::Result;
use utils::de::fix_toml_dates;

/// The front matter of every page
#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(default)]
pub struct PageFrontMatter {
    /// <title> of the page
    pub title: Option<String>,
    /// Description in <meta> that appears when linked, e.g. on twitter
    pub description: Option<String>,
    /// Date if we want to order pages (ie blog post)
    #[serde(default, deserialize_with = "utils::de::from_toml_datetime")]
    pub date: Option<String>,
    /// Chrono converted datetime
    #[serde(default, skip_deserializing)]
    pub datetime: Option<NaiveDateTime>,
    /// The converted date into a (year, month, day) tuple
    #[serde(default, skip_deserializing)]
    pub datetime_tuple: Option<(i32, u32, u32)>,
    /// Whether this page is a draft and should be ignored for pagination etc
    pub draft: bool,
    /// The page slug. Will be used instead of the filename if present
    /// Can't be an empty string if present
    pub slug: Option<String>,
    /// The path the page appears at, overrides the slug if set in the front-matter
    /// otherwise is set after parsing front matter and sections
    /// Can't be an empty string if present
    pub path: Option<String>,
    pub taxonomies: HashMap<String, Vec<String>>,
    /// Integer to use to order content. Lowest is at the bottom, highest first
    pub order: Option<usize>,
    /// Integer to use to order content. Highest is at the bottom, lowest first
    pub weight: Option<usize>,
    /// All aliases for that page. Zola will create HTML templates that will
    /// redirect to this
    #[serde(skip_serializing)]
    pub aliases: Vec<String>,
    /// Specify a template different from `page.html` to use for that page
    #[serde(skip_serializing)]
    pub template: Option<String>,
    /// Whether the page is included in the search index
    /// Defaults to `true` but is only used if search if explicitly enabled in the config.
    #[serde(skip_serializing)]
    pub in_search_index: bool,
    /// Any extra parameter present in the front matter
    pub extra: Map<String, Value>,
}

impl PageFrontMatter {
    pub fn parse(toml: &str) -> Result<PageFrontMatter> {
        let mut f: PageFrontMatter = match toml::from_str(toml) {
            Ok(d) => d,
            Err(e) => bail!(e),
        };

        if let Some(ref slug) = f.slug {
            if slug == "" {
                bail!("`slug` can't be empty if present")
            }
        }

        if let Some(ref path) = f.path {
            if path == "" {
                bail!("`path` can't be empty if present")
            }
        }

        f.extra = match fix_toml_dates(f.extra) {
            Value::Object(o) => o,
            _ => unreachable!("Got something other than a table in page extra"),
        };

        f.date_to_datetime();

        Ok(f)
    }

    /// Converts the TOML datetime to a Chrono naive datetime
    /// Also grabs the year/month/day tuple that will be used in serialization
    pub fn date_to_datetime(&mut self) {
        self.datetime = if let Some(ref d) = self.date {
            if d.contains('T') {
                DateTime::parse_from_rfc3339(&d).ok().and_then(|s| Some(s.naive_local()))
            } else {
                NaiveDate::parse_from_str(&d, "%Y-%m-%d")
                    .ok()
                    .and_then(|s| Some(s.and_hms(0, 0, 0)))
            }
        } else {
            None
        };

        self.datetime_tuple = if let Some(ref dt) = self.datetime {
            Some((dt.year(), dt.month(), dt.day()))
        } else {
            None
        };
    }

    pub fn order(&self) -> usize {
        self.order.unwrap()
    }

    pub fn weight(&self) -> usize {
        self.weight.unwrap()
    }
}

impl Default for PageFrontMatter {
    fn default() -> PageFrontMatter {
        PageFrontMatter {
            title: None,
            description: None,
            date: None,
            datetime: None,
            datetime_tuple: None,
            draft: false,
            slug: None,
            path: None,
            taxonomies: HashMap::new(),
            order: None,
            weight: None,
            aliases: Vec::new(),
            in_search_index: true,
            template: None,
            extra: Map::new(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::PageFrontMatter;
    use tera::to_value;

    #[test]
    fn can_have_empty_front_matter() {
        let content = r#"  "#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
    }

    #[test]
    fn can_parse_valid_front_matter() {
        let content = r#"
    title = "Hello"
    description = "hey there""#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_ok());
        let res = res.unwrap();
        assert_eq!(res.title.unwrap(), "Hello".to_string());
        assert_eq!(res.description.unwrap(), "hey there".to_string())
    }

    #[test]
    fn errors_with_invalid_front_matter() {
        let content = r#"title = 1\n"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn errors_on_present_but_empty_slug() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    slug = """#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn errors_on_present_but_empty_path() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    path = """#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn can_parse_date_yyyy_mm_dd() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2016-10-10
    "#;
        let res = PageFrontMatter::parse(content).unwrap();
        assert!(res.date.is_some());
    }

    #[test]
    fn can_parse_date_rfc3339() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002-10-02T15:00:00Z
    "#;
        let res = PageFrontMatter::parse(content).unwrap();
        assert!(res.date.is_some());
    }

    #[test]
    fn cannot_parse_random_date_format() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002/10/12"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn cannot_parse_invalid_date_format() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn cannot_parse_date_as_string() {
        let content = r#"
    title = "Hello"
    description = "hey there"
    date = "2002-14-01""#;
        let res = PageFrontMatter::parse(content);
        assert!(res.is_err());
    }

    #[test]
    fn can_parse_dates_in_extra() {
        let content = r#"
    title = "Hello"
    description = "hey there"

    [extra]
    some-date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        assert_eq!(res.unwrap().extra["some-date"], to_value("2002-14-01").unwrap());
    }

    #[test]
    fn can_parse_nested_dates_in_extra() {
        let content = r#"
    title = "Hello"
    description = "hey there"

    [extra.something]
    some-date = 2002-14-01"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
    }

    #[test]
    fn can_parse_taxonomies() {
        let content = r#"
title = "Hello World"

[taxonomies]
tags = ["Rust", "JavaScript"]
categories = ["Dev"]
"#;
        let res = PageFrontMatter::parse(content);
        println!("{:?}", res);
        assert!(res.is_ok());
        let res2 = res.unwrap();
        assert_eq!(res2.taxonomies["categories"], vec!["Dev"]);
        assert_eq!(res2.taxonomies["tags"], vec!["Rust", "JavaScript"]);
    }
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Closures/Value_capture
#[allow(unstable)]
use std::iter::{count, Counter, Map};
use std::num::Float;

// given a number x, return the (boxed) closure that
// computes x squared
fn closure_gen<'a>(x: u32) -> Box<Fn() -> f64 + 'a> {
    Box::new(move |&:| (x as f64).powi(2))
}

// type alias for the closure iterator
type ClosureIter<'a> = Map<u32, Box<Fn() -> f64 + 'a>, Counter<u32>, fn(u32) -> Box<Fn() -> f64 + 'a>>;

// return an iterator that on every iteration returns
// a closure computing the index of the iteration squared
fn closures_iterator<'a>() -> ClosureIter<'a> {
    let cl_gen : fn(u32) -> Box<Fn() -> f64 + 'a> = closure_gen;
    count(0, 1).map(cl_gen)
}

#[cfg(not(test))]
fn main() {
    // Take the first 9 closures from the iterator and call them
    for c in closures_iterator().take(9) {
        println!("{}", c())
    }
}

#[cfg(test)]
mod test {
    use std::num::Float;
    use super::{closure_gen, closures_iterator};

    #[test]
    fn closure_generator() {
        let five_squarer = closure_gen(5);
        assert!(five_squarer() == 25f64);
    }

    #[test]
    fn closure_iterator() {
        for (idx, f) in closures_iterator().take(9).enumerate() {
            assert!(f() == (idx as f64).powi(2));
        }
    }
}<commit_msg>missing ! in closures_value_capture<commit_after>// http://rosettacode.org/wiki/Closures/Value_capture
#![allow(unstable)]
use std::iter::{count, Counter, Map};
use std::num::Float;

// given a number x, return the (boxed) closure that
// computes x squared
fn closure_gen<'a>(x: u32) -> Box<Fn() -> f64 + 'a> {
    Box::new(move |&:| (x as f64).powi(2))
}

// type alias for the closure iterator
type ClosureIter<'a> = Map<u32, Box<Fn() -> f64 + 'a>, Counter<u32>, fn(u32) -> Box<Fn() -> f64 + 'a>>;

// return an iterator that on every iteration returns
// a closure computing the index of the iteration squared
fn closures_iterator<'a>() -> ClosureIter<'a> {
    let cl_gen : fn(u32) -> Box<Fn() -> f64 + 'a> = closure_gen;
    count(0, 1).map(cl_gen)
}

#[cfg(not(test))]
fn main() {
    // Take the first 9 closures from the iterator and call them
    for c in closures_iterator().take(9) {
        println!("{}", c())
    }
}

#[cfg(test)]
mod test {
    use std::num::Float;
    use super::{closure_gen, closures_iterator};

    #[test]
    fn closure_generator() {
        let five_squarer = closure_gen(5);
        assert!(five_squarer() == 25f64);
    }

    #[test]
    fn closure_iterator() {
        for (idx, f) in closures_iterator().take(9).enumerate() {
            assert!(f() == (idx as f64).powi(2));
        }
    }
}<|endoftext|>


<commit_before>use std::sync::atomic::{AtomicPtr, Ordering};
use std::ptr;

unsafe impl<T: Send> Send for AtomicOption<T> {}
unsafe impl<T: Send> Sync for AtomicOption<T> {}

#[derive(Debug)]
pub struct AtomicOption<T> {
    inner: AtomicPtr<T>,
}

impl<T> Drop for AtomicOption<T> {
    fn drop(&mut self) {
        let inner = self.inner.load(Ordering::Relaxed);
        if !inner.is_null() {
            unsafe {
                Box::from_raw(inner);
            }
        }
    }
}

impl<T> AtomicOption<T> {
    pub fn new() -> AtomicOption<T> {
        AtomicOption { inner: AtomicPtr::new(ptr::null_mut()) }
    }

    fn swap_inner(&self, ptr: *mut T, order: Ordering) -> Option<Box<T>> {
        let old = self.inner.swap(ptr, order);
        if old.is_null() {
            None
        } else {
            Some(unsafe { Box::from_raw(old) })
        }
    }

    // allows re-use of allocation
    pub fn swap_box(&self, t: Box<T>, order: Ordering) -> Option<Box<T>> {
        self.swap_inner(Box::into_raw(t), order)
    }

    pub fn swap(&self, t: T, order: Ordering) -> Option<T> {
        self.swap_box(Box::new(t), order).map(|old| *old)
    }

    pub fn take(&self, order: Ordering) -> Option<T> {
        self.swap_inner(ptr::null_mut(), order).map(|old| *old)
    }
}
<commit_msg>address feedback, explicitly drop AtomicOption's inner state<commit_after>use std::sync::atomic::{AtomicPtr, Ordering};
use std::ptr;

unsafe impl<T: Send> Send for AtomicOption<T> {}
unsafe impl<T: Send> Sync for AtomicOption<T> {}

#[derive(Debug)]
pub struct AtomicOption<T> {
    inner: AtomicPtr<T>,
}

impl<T> Drop for AtomicOption<T> {
    fn drop(&mut self) {
        let inner = self.inner.load(Ordering::Relaxed);
        if !inner.is_null() {
            unsafe {
                drop(Box::from_raw(inner));
            }
        }
    }
}

impl<T> AtomicOption<T> {
    pub fn new() -> AtomicOption<T> {
        AtomicOption { inner: AtomicPtr::new(ptr::null_mut()) }
    }

    fn swap_inner(&self, ptr: *mut T, order: Ordering) -> Option<Box<T>> {
        let old = self.inner.swap(ptr, order);
        if old.is_null() {
            None
        } else {
            Some(unsafe { Box::from_raw(old) })
        }
    }

    // allows re-use of allocation
    pub fn swap_box(&self, t: Box<T>, order: Ordering) -> Option<Box<T>> {
        self.swap_inner(Box::into_raw(t), order)
    }

    pub fn swap(&self, t: T, order: Ordering) -> Option<T> {
        self.swap_box(Box::new(t), order).map(|old| *old)
    }

    pub fn take(&self, order: Ordering) -> Option<T> {
        self.swap_inner(ptr::null_mut(), order).map(|old| *old)
    }
}
<|endoftext|>