<commit_before>#[macro_use]
extern crate clap;
extern crate scmp;

use std::process::Command;
use std::os::unix::process::CommandExt;
use scmp::*;

fn setup_seccomp() -> Result<(), std::io::Error> {
    unsafe {
        let ctx0 = seccomp_init(SCMP_ACT_TRAP);
        assert!(!ctx0.is_null());
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_execve as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_brk as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_access as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_open as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_read as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_write as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_stat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_close as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mprotect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_arch_prctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_munmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_tid_address as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_robust_list as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigaction as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigprocmask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getrlimit as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_statfs as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fcntl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_geteuid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_umask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_pipe as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_clone as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_wait4 as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_exit_group as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_dup as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_ioctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getpid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_gettid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_tgkill as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigreturn as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_socket as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_connect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lseek as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_openat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlinkat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utimensat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_load(ctx0) == 0);
    }
    return Ok(());
}

fn main() {
    let matches = clap_app!(myapp =>
        (@arg ARCHIVE: +required ... "Archives to extract")
    ).get_matches();

    for arch in matches.values_of("ARCHIVE").unwrap() {
        println!("Extract {}", arch);
        if
            arch.ends_with(".tgz")
            || arch.ends_with(".tar.gz")
            || arch.ends_with(".tar.Z")
            || arch.ends_with(".tbz2")
            || arch.ends_with(".tar.bz2")
            || arch.ends_with(".tlz")
            || arch.ends_with(".tar.lz")
            || arch.ends_with(".tar.lzma")
            || arch.ends_with(".tar.lzo")
            || arch.ends_with(".tar.xz")
        {
            let status = Command::new("tar")
                .arg("-xf")
                .arg(arch)
                .before_exec(setup_seccomp)
                .status()
                .expect("Failed to launch tar");
            assert!(status.success(), "tar wasn't successful");
        } else {
            println!("Can't handle {}", arch);
        }
    }
}
<commit_msg>Add zip support<commit_after>#[macro_use]
extern crate clap;
extern crate scmp;

use std::process::Command;
use std::os::unix::process::CommandExt;
use scmp::*;

fn setup_seccomp() -> Result<(), std::io::Error> {
    unsafe {
        let ctx0 = seccomp_init(SCMP_ACT_TRAP);
        assert!(!ctx0.is_null());
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_execve as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_brk as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_access as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_open as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_read as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_write as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_stat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_close as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_mprotect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_arch_prctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_munmap as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_tid_address as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_set_robust_list as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigaction as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigprocmask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getrlimit as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_statfs as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fcntl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_geteuid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_umask as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_pipe as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_clone as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_wait4 as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_exit_group as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_dup as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_ioctl as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_getpid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_gettid as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_tgkill as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_rt_sigreturn as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_socket as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_connect as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lseek as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_openat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlinkat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utimensat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_lstat as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_fchmod as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_unlink as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_rule_add_array(ctx0, SCMP_ACT_ALLOW, __NR_utime as i32, 0, std::ptr::null()) == 0);
        assert!(seccomp_load(ctx0) == 0);
    }
    return Ok(());
}

fn main() {
    let matches = clap_app!(myapp =>
        (@arg ARCHIVE: +required ... "Archives to extract")
    ).get_matches();

    for arch in matches.values_of("ARCHIVE").unwrap() {
        println!("Extract {}", arch);
        if
            arch.ends_with(".tgz")
            || arch.ends_with(".tar.gz")
            || arch.ends_with(".tar.Z")
            || arch.ends_with(".tbz2")
            || arch.ends_with(".tar.bz2")
            || arch.ends_with(".tlz")
            || arch.ends_with(".tar.lz")
            || arch.ends_with(".tar.lzma")
            || arch.ends_with(".tar.lzo")
            || arch.ends_with(".tar.xz")
        {
            let status = Command::new("tar")
                .arg("-xf")
                .arg(arch)
                .before_exec(setup_seccomp)
                .status()
                .expect("Failed to launch tar");
            assert!(status.success(), "tar wasn't successful");
        } else if arch.ends_with(".zip") {
            let status = Command::new("unzip")
                .arg("--")
                .arg(arch)
                .before_exec(setup_seccomp)
                .status()
                .expect("Failed to launch unzip");
            assert!(status.success(), "unzip wasn't successful");
        } else {
            println!("Can't handle {}", arch);
        }
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate docopt;
extern crate mazes;
extern crate rustc_serialize;

use std::io::prelude::*;
use std::io;
use std::fs::File;
use std::path::Path;
use std::process::exit;
use std::rc::Rc;

use docopt::Docopt;

use mazes::squaregrid::{CoordinateSmallVec, GridCoordinate, GridDisplay, SquareGrid};
use mazes::generators;
use mazes::renderers;
use mazes::pathing;

const USAGE: &'static str = "Mazes

Usage:
    mazes_driver -h | --help
    mazes_driver [--grid-size=<n>]
    mazes_driver render (binary|sidewinder) [text --text-out=<path> (--show-distances|--show-path) (--furthest-end-point --start-point-x=<x> --start-point-y=<y>|--end-point-x=<e1> --end-point-y=<e2> --start-point-x=<x> --start-point-y=<y>) (--start-point-x=<x> --start-point-y=<y>)] [image --image-out=<path> --cell-pixels=<n> --colour-distances --show-path --screen-view --mark-start-end] [--grid-size=<n>]

Options:
    -h --help              Show this screen.
    --grid-size=<n>        The grid size is n * n [default: 20].
    --text-out=<path>      Output file path for a textual rendering of a maze.
    --show-distances       Show the distance from the start point to all other points on the grid. The start point is the longest path start if not specified.
    --show-path            Show the path from the start to end point. Choose the start/end point automatically from the longest path if not specified.
    --furthest-end-point   Chooses an endpoint that is the furthest distance from the start point. The start point is the longest path start if not specified.
    --start-point-x=<x>    x coordinate of the path start
    --start-point-y=<y>    y coordinate of the path start
    --end-point-x=<e1>     x coordinate of the path end
    --end-point-y=<e2>     y coordinate of the path end
    --image-out=<path>     Output file path for an image rendering of a maze.
    --cell-pixels=<n>      Pixel count to render one cell wall in a maze [default: 10] max 255.
    --colour-distances     Indicate the distance from a starting point to any cell by the cell's background colour.
    --screen-view          When rendering to an image and saving to a file, also show the image on the screen.
    --mark-start-end       Draw an 'S' (start) and 'E' (end) to show the path start and end points.
";
#[derive(RustcDecodable, Debug)]
struct MazeArgs {
    flag_grid_size: u32,
    cmd_render: bool,
    cmd_binary: bool,
    cmd_sidewinder: bool,
    cmd_text: bool,
    flag_text_out: String,
    cmd_image: bool,
    flag_image_out: String,
    flag_cell_pixels: u8,
    flag_screen_view: bool,
    flag_colour_distances: bool,
    flag_show_distances: bool,
    flag_mark_start_end: bool,
    flag_show_path: bool,
    flag_furthest_end_point: bool,
    flag_start_point_x: Option<u32>,
    flag_start_point_y: Option<u32>,
    flag_end_point_x: Option<u32>,
    flag_end_point_y: Option<u32>,
}

fn main() {

    let args: MazeArgs = Docopt::new(USAGE)
                             .and_then(|d| d.decode())
                             .unwrap_or_else(|e| e.exit());

    let grid_size = args.flag_grid_size;
    let any_render_option = args.cmd_text || args.cmd_image;

    // Do whatever defaults we want if not given a specific 'render' command
    let do_image_render = !args.cmd_render || args.cmd_image ||
                          (!any_render_option && grid_size >= 25);
    let do_text_render = args.cmd_render &&
                         (args.cmd_text || (!any_render_option && grid_size < 25));

    let mut maze_grid = SquareGrid::<u32>::new(grid_size);

    generate_maze_on_grid(&mut maze_grid, &args);

    let longest_path = longest_path_from_arg_constraints(&args, &maze_grid);

    if do_text_render {

        set_maze_griddisplay(&mut maze_grid, &args, &longest_path);

        if args.flag_text_out.is_empty() {
            println!("{}", maze_grid);
        } else {
            write_text_to_file(&format!("{}", maze_grid), &args.flag_text_out)
                .expect(&format!("Failed to write maze to text file {}", args.flag_text_out));
        }
    }

    if do_image_render {
        let is_image_path_set = !args.flag_image_out.is_empty();
        let out_image_path = if is_image_path_set {
            Some(Path::new(&args.flag_image_out))
        } else {
            None
        };

        let start_opt = get_start_point(&args, &longest_path);
        let end_opt = get_end_point(&args, &longest_path);

        let distances = if args.flag_colour_distances || args.flag_mark_start_end || args.flag_show_path {
            let (start_x, start_y) = start_opt.unwrap();
            Some(pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                    .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate from which to show path distances.")))
        } else {
            None
        };

        let path_opt = if args.flag_show_path {
                let (end_x, end_y) = end_opt.unwrap();
                pathing::shortest_path(&maze_grid, distances.as_ref().unwrap(),
                                       GridCoordinate::new(end_x, end_y))
            }
            else { None };
        let render_options = renderers::RenderOptionsBuilder::new()
                                         .show_on_screen(args.flag_screen_view || !is_image_path_set)
                                         .colour_distances(args.flag_colour_distances)
                                         .mark_start_end(args.flag_mark_start_end)
                                         .start(start_opt.map(|x_y_pair| GridCoordinate::from(x_y_pair)))
                                         .end(end_opt.map(|x_y_pair| GridCoordinate::from(x_y_pair)))
                                         .show_path(args.flag_show_path)
                                         .distances(distances.as_ref())
                                         .output_file(out_image_path)
                                         .path(path_opt)
                                         .cell_side_pixels_length(args.flag_cell_pixels)
                                         .build();
        renderers::render_square_grid(&maze_grid, &render_options);
    }
}

fn generate_maze_on_grid(mut maze_grid: &mut SquareGrid<u32>, maze_args: &MazeArgs) {

    if maze_args.cmd_render {
        if maze_args.cmd_binary {
            generators::binary_tree(&mut maze_grid);
        }
        if maze_args.cmd_sidewinder {
            generators::sidewinder(&mut maze_grid);
        }
    } else {
        generators::sidewinder(&mut maze_grid);
    }
}

/// Wade through all the maze driver argments and decide how the grid should have cells displayed as text
/// - Nothing in the cells
/// - Start and End point markers if supplied else nothing
/// - Distances from some start cell to all other cells
/// - Shortest path between a start and end point
/// Default to finding the start and end point of the longest path in the maze if required to show a path
/// or asked to find the point furthest away from a start point
/// Use the start of the longest path if asked to show distances to all other cells but no start provided
fn set_maze_griddisplay(maze_grid: &mut SquareGrid<u32>,
                        maze_args: &MazeArgs,
                        longest_path: &[GridCoordinate]) {

    let start_opt = get_start_point(&maze_args, &longest_path);
    let end_opt = get_end_point(&maze_args, &longest_path);

    if maze_args.flag_show_distances || maze_args.flag_show_path {

        let (start_x, start_y) = start_opt.unwrap();
        let distances = Rc::new(pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate from which to show path distances.")));

        if maze_args.flag_show_distances {

            // Ignore any endpoint or furthest point request (docopt cannot nest these mutual exclusions?)
            // Show the distances to everywhere else
            maze_grid.set_grid_display(Some(distances.clone() as Rc<GridDisplay>));

        } else if maze_args.flag_show_path {

            // We need a start and an end
            let (end_x, end_y) = end_opt.unwrap();

            // Given a start and end point - show the shortest path between these two points
            let path_opt = pathing::shortest_path(&maze_grid,
                                                  &distances,
                                                  GridCoordinate::new(end_x, end_y));

            if let Some(path) = path_opt {
                let display_path = Rc::new(pathing::PathDisplay::new(&path));
                maze_grid.set_grid_display(Some(display_path as Rc<GridDisplay>));
            } else {
                // Somehow there is no route, maze generation failed to make a perfect maze
                let start_points = as_coordinate_smallvec(GridCoordinate::new(start_x, start_y));
                let end_points = as_coordinate_smallvec(GridCoordinate::new(end_x, end_y));
                let display_start_end_points =
                    Rc::new(pathing::StartEndPointsDisplay::new(start_points, end_points));
                maze_grid.set_grid_display(Some(display_start_end_points as Rc<GridDisplay>));
            }
        }
    } else {

        // Show the start and end points that exist.
        let start_points = if let Some((start_x, start_y)) = start_opt {
            as_coordinate_smallvec(GridCoordinate::new(start_x, start_y))
        } else {
            CoordinateSmallVec::new()
        };
        let end_points = if let Some((end_x, end_y)) = end_opt {
            as_coordinate_smallvec(GridCoordinate::new(end_x, end_y))
        } else {
            CoordinateSmallVec::new()
        };
        let display_start_end_points = Rc::new(pathing::StartEndPointsDisplay::new(start_points,
                                                                                end_points));
        maze_grid.set_grid_display(Some(display_start_end_points as Rc<GridDisplay>));
    }
}

fn longest_path_from_arg_constraints(maze_args: &MazeArgs, maze_grid: &SquareGrid<u32>) -> Vec<GridCoordinate> {

    println!("{:?}", (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                  maze_args.flag_end_point_x, maze_args.flag_end_point_y));

    let single_point: Option<(u32, u32)> = match (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                  maze_args.flag_end_point_x, maze_args.flag_end_point_y) {
        (Some(_), Some(_), Some(_), Some(_)) => None,
        (Some(start_x), Some(start_y), _, _) => Some((start_x, start_y)),
        (_, _, Some(end_x), Some(end_y)) => Some((end_x, end_y)),
        _ => None
    };

    if let Some((x, y)) = single_point {
        let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(x, y))
                                            .unwrap_or_else(|| exit_with_msg("Provided invalid coordinate."));
        let furthest_points = pathing::furthest_points_on_grid(&maze_grid, &distances);
        let end_coord = furthest_points[0];
        pathing::shortest_path(&maze_grid, &distances, end_coord).unwrap_or_else(|| Vec::new())
    } else {
        // Fully defined start and end, so we can only find the path for it.
        if let (Some(start_x), Some(start_y), Some(end_x), Some(end_y)) = (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                                           maze_args.flag_end_point_x, maze_args.flag_end_point_y) {

            let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                                            .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate."));
            let end_coord = GridCoordinate::new(end_x, end_y);
            pathing::shortest_path(&maze_grid, &distances, end_coord).unwrap_or_else(|| Vec::new())
        } else {
            // No points given, just find the actual longest path
            pathing::dijkstra_longest_path::<_, u32>(&maze_grid).unwrap_or_else(|| Vec::new())
        }
    }
}

fn get_start_point(maze_args: &MazeArgs, longest_path: &[GridCoordinate]) -> Option<(u32, u32)> {

    if let (Some(start_x), Some(start_y)) = (maze_args.flag_start_point_x,
                                             maze_args.flag_start_point_y) {
        Some((start_x, start_y))

    } else if maze_arg_requires_start_and_end_point(maze_args) {

        // We do not have a start so make one up
        let start = longest_path.first().unwrap();
        Some((start.x, start.y))
    } else {
        None
    }
}
fn get_end_point(maze_args: &MazeArgs, longest_path: &[GridCoordinate]) -> Option<(u32, u32)> {

    if let (Some(end_x), Some(end_y)) = (maze_args.flag_end_point_x, maze_args.flag_end_point_y) {
        Some((end_x, end_y))

    } else if maze_arg_requires_start_and_end_point(maze_args) {

        // We do not have an end but we need to make one up
        let end = longest_path.last().unwrap();
        Some((end.x, end.y))
    } else {
        None
    }
}

fn maze_arg_requires_start_and_end_point(maze_args: &MazeArgs) -> bool {
    maze_args.flag_furthest_end_point || maze_args.flag_show_distances ||
    maze_args.flag_show_path || maze_args.flag_colour_distances || maze_args.flag_mark_start_end
}

fn as_coordinate_smallvec(coord: GridCoordinate) -> CoordinateSmallVec {
    [coord].into_iter().cloned().collect::<CoordinateSmallVec>()
}

fn write_text_to_file(data: &str, file_name: &str) -> io::Result<()> {
    let mut f = try!(File::create(file_name));
    try!(f.write_all(data.as_bytes()));
    Ok(())
}

fn exit_with_msg(e: &str) -> ! {
    writeln!(&mut io::stderr(), "{}", e).expect(format!("Failed to print error: {}", e).as_str());
    exit(1);
}
<commit_msg>Lint - unnecessary closure bodies.<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]

extern crate docopt;
extern crate mazes;
extern crate rustc_serialize;

use std::io::prelude::*;
use std::io;
use std::fs::File;
use std::path::Path;
use std::process::exit;
use std::rc::Rc;

use docopt::Docopt;

use mazes::squaregrid::{CoordinateSmallVec, GridCoordinate, GridDisplay, SquareGrid};
use mazes::generators;
use mazes::renderers;
use mazes::pathing;

const USAGE: &'static str = "Mazes

Usage:
    mazes_driver -h | --help
    mazes_driver [--grid-size=<n>]
    mazes_driver render (binary|sidewinder) [text --text-out=<path> (--show-distances|--show-path) (--furthest-end-point --start-point-x=<x> --start-point-y=<y>|--end-point-x=<e1> --end-point-y=<e2> --start-point-x=<x> --start-point-y=<y>) (--start-point-x=<x> --start-point-y=<y>)] [image --image-out=<path> --cell-pixels=<n> --colour-distances --show-path --screen-view --mark-start-end] [--grid-size=<n>]

Options:
    -h --help              Show this screen.
    --grid-size=<n>        The grid size is n * n [default: 20].
    --text-out=<path>      Output file path for a textual rendering of a maze.
    --show-distances       Show the distance from the start point to all other points on the grid. The start point is the longest path start if not specified.
    --show-path            Show the path from the start to end point. Choose the start/end point automatically from the longest path if not specified.
    --furthest-end-point   Chooses an endpoint that is the furthest distance from the start point. The start point is the longest path start if not specified.
    --start-point-x=<x>    x coordinate of the path start
    --start-point-y=<y>    y coordinate of the path start
    --end-point-x=<e1>     x coordinate of the path end
    --end-point-y=<e2>     y coordinate of the path end
    --image-out=<path>     Output file path for an image rendering of a maze.
    --cell-pixels=<n>      Pixel count to render one cell wall in a maze [default: 10] max 255.
    --colour-distances     Indicate the distance from a starting point to any cell by the cell's background colour.
    --screen-view          When rendering to an image and saving to a file, also show the image on the screen.
    --mark-start-end       Draw an 'S' (start) and 'E' (end) to show the path start and end points.
";
#[derive(RustcDecodable, Debug)]
struct MazeArgs {
    flag_grid_size: u32,
    cmd_render: bool,
    cmd_binary: bool,
    cmd_sidewinder: bool,
    cmd_text: bool,
    flag_text_out: String,
    cmd_image: bool,
    flag_image_out: String,
    flag_cell_pixels: u8,
    flag_screen_view: bool,
    flag_colour_distances: bool,
    flag_show_distances: bool,
    flag_mark_start_end: bool,
    flag_show_path: bool,
    flag_furthest_end_point: bool,
    flag_start_point_x: Option<u32>,
    flag_start_point_y: Option<u32>,
    flag_end_point_x: Option<u32>,
    flag_end_point_y: Option<u32>,
}

fn main() {

    let args: MazeArgs = Docopt::new(USAGE)
                             .and_then(|d| d.decode())
                             .unwrap_or_else(|e| e.exit());

    let grid_size = args.flag_grid_size;
    let any_render_option = args.cmd_text || args.cmd_image;

    // Do whatever defaults we want if not given a specific 'render' command
    let do_image_render = !args.cmd_render || args.cmd_image ||
                          (!any_render_option && grid_size >= 25);
    let do_text_render = args.cmd_render &&
                         (args.cmd_text || (!any_render_option && grid_size < 25));

    let mut maze_grid = SquareGrid::<u32>::new(grid_size);

    generate_maze_on_grid(&mut maze_grid, &args);

    let longest_path = longest_path_from_arg_constraints(&args, &maze_grid);

    if do_text_render {

        set_maze_griddisplay(&mut maze_grid, &args, &longest_path);

        if args.flag_text_out.is_empty() {
            println!("{}", maze_grid);
        } else {
            write_text_to_file(&format!("{}", maze_grid), &args.flag_text_out)
                .expect(&format!("Failed to write maze to text file {}", args.flag_text_out));
        }
    }

    if do_image_render {
        let is_image_path_set = !args.flag_image_out.is_empty();
        let out_image_path = if is_image_path_set {
            Some(Path::new(&args.flag_image_out))
        } else {
            None
        };

        let start_opt = get_start_point(&args, &longest_path);
        let end_opt = get_end_point(&args, &longest_path);

        let distances = if args.flag_colour_distances || args.flag_mark_start_end || args.flag_show_path {
            let (start_x, start_y) = start_opt.unwrap();
            Some(pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                    .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate from which to show path distances.")))
        } else {
            None
        };

        let path_opt = if args.flag_show_path {
                let (end_x, end_y) = end_opt.unwrap();
                pathing::shortest_path(&maze_grid, distances.as_ref().unwrap(),
                                       GridCoordinate::new(end_x, end_y))
            }
            else { None };
        let render_options = renderers::RenderOptionsBuilder::new()
                                         .show_on_screen(args.flag_screen_view || !is_image_path_set)
                                         .colour_distances(args.flag_colour_distances)
                                         .mark_start_end(args.flag_mark_start_end)
                                         .start(start_opt.map(GridCoordinate::from))
                                         .end(end_opt.map(GridCoordinate::from))
                                         .show_path(args.flag_show_path)
                                         .distances(distances.as_ref())
                                         .output_file(out_image_path)
                                         .path(path_opt)
                                         .cell_side_pixels_length(args.flag_cell_pixels)
                                         .build();
        renderers::render_square_grid(&maze_grid, &render_options);
    }
}

fn generate_maze_on_grid(mut maze_grid: &mut SquareGrid<u32>, maze_args: &MazeArgs) {

    if maze_args.cmd_render {
        if maze_args.cmd_binary {
            generators::binary_tree(&mut maze_grid);
        }
        if maze_args.cmd_sidewinder {
            generators::sidewinder(&mut maze_grid);
        }
    } else {
        generators::sidewinder(&mut maze_grid);
    }
}

/// Wade through all the maze driver argments and decide how the grid should have cells displayed as text
/// - Nothing in the cells
/// - Start and End point markers if supplied else nothing
/// - Distances from some start cell to all other cells
/// - Shortest path between a start and end point
/// Default to finding the start and end point of the longest path in the maze if required to show a path
/// or asked to find the point furthest away from a start point
/// Use the start of the longest path if asked to show distances to all other cells but no start provided
fn set_maze_griddisplay(maze_grid: &mut SquareGrid<u32>,
                        maze_args: &MazeArgs,
                        longest_path: &[GridCoordinate]) {

    let start_opt = get_start_point(&maze_args, &longest_path);
    let end_opt = get_end_point(&maze_args, &longest_path);

    if maze_args.flag_show_distances || maze_args.flag_show_path {

        let (start_x, start_y) = start_opt.unwrap();
        let distances = Rc::new(pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate from which to show path distances.")));

        if maze_args.flag_show_distances {

            // Ignore any endpoint or furthest point request (docopt cannot nest these mutual exclusions?)
            // Show the distances to everywhere else
            maze_grid.set_grid_display(Some(distances.clone() as Rc<GridDisplay>));

        } else if maze_args.flag_show_path {

            // We need a start and an end
            let (end_x, end_y) = end_opt.unwrap();

            // Given a start and end point - show the shortest path between these two points
            let path_opt = pathing::shortest_path(&maze_grid,
                                                  &distances,
                                                  GridCoordinate::new(end_x, end_y));

            if let Some(path) = path_opt {
                let display_path = Rc::new(pathing::PathDisplay::new(&path));
                maze_grid.set_grid_display(Some(display_path as Rc<GridDisplay>));
            } else {
                // Somehow there is no route, maze generation failed to make a perfect maze
                let start_points = as_coordinate_smallvec(GridCoordinate::new(start_x, start_y));
                let end_points = as_coordinate_smallvec(GridCoordinate::new(end_x, end_y));
                let display_start_end_points =
                    Rc::new(pathing::StartEndPointsDisplay::new(start_points, end_points));
                maze_grid.set_grid_display(Some(display_start_end_points as Rc<GridDisplay>));
            }
        }
    } else {

        // Show the start and end points that exist.
        let start_points = if let Some((start_x, start_y)) = start_opt {
            as_coordinate_smallvec(GridCoordinate::new(start_x, start_y))
        } else {
            CoordinateSmallVec::new()
        };
        let end_points = if let Some((end_x, end_y)) = end_opt {
            as_coordinate_smallvec(GridCoordinate::new(end_x, end_y))
        } else {
            CoordinateSmallVec::new()
        };
        let display_start_end_points = Rc::new(pathing::StartEndPointsDisplay::new(start_points,
                                                                                end_points));
        maze_grid.set_grid_display(Some(display_start_end_points as Rc<GridDisplay>));
    }
}

#[allow(match_same_arms)]
fn longest_path_from_arg_constraints(maze_args: &MazeArgs, maze_grid: &SquareGrid<u32>) -> Vec<GridCoordinate> {

    println!("{:?}", (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                  maze_args.flag_end_point_x, maze_args.flag_end_point_y));

    let single_point: Option<(u32, u32)> = match (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                  maze_args.flag_end_point_x, maze_args.flag_end_point_y) {
        (Some(_), Some(_), Some(_), Some(_)) => None,
        (Some(start_x), Some(start_y), _, _) => Some((start_x, start_y)),
        (_, _, Some(end_x), Some(end_y)) => Some((end_x, end_y)),
        _ => None,
    };

    if let Some((x, y)) = single_point {
        let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(x, y))
                                            .unwrap_or_else(|| exit_with_msg("Provided invalid coordinate."));
        let furthest_points = pathing::furthest_points_on_grid(&maze_grid, &distances);
        let end_coord = furthest_points[0];
        pathing::shortest_path(&maze_grid, &distances, end_coord).unwrap_or_else(Vec::new)
    } else {
        // Fully defined start and end, so we can only find the path for it.
        if let (Some(start_x), Some(start_y), Some(end_x), Some(end_y)) = (maze_args.flag_start_point_x, maze_args.flag_start_point_y,
                                                                           maze_args.flag_end_point_x, maze_args.flag_end_point_y) {

            let distances = pathing::DijkstraDistances::<u32>::new(&maze_grid, GridCoordinate::new(start_x, start_y))
                                            .unwrap_or_else(|| exit_with_msg("Provided invalid start coordinate."));
            let end_coord = GridCoordinate::new(end_x, end_y);
            pathing::shortest_path(&maze_grid, &distances, end_coord).unwrap_or_else(Vec::new)
        } else {
            // No points given, just find the actual longest path
            pathing::dijkstra_longest_path::<_, u32>(&maze_grid).unwrap_or_else(Vec::new)
        }
    }
}

fn get_start_point(maze_args: &MazeArgs, longest_path: &[GridCoordinate]) -> Option<(u32, u32)> {

    if let (Some(start_x), Some(start_y)) = (maze_args.flag_start_point_x,
                                             maze_args.flag_start_point_y) {
        Some((start_x, start_y))

    } else if maze_arg_requires_start_and_end_point(maze_args) {

        // We do not have a start so make one up
        let start = longest_path.first().unwrap();
        Some((start.x, start.y))
    } else {
        None
    }
}
fn get_end_point(maze_args: &MazeArgs, longest_path: &[GridCoordinate]) -> Option<(u32, u32)> {

    if let (Some(end_x), Some(end_y)) = (maze_args.flag_end_point_x, maze_args.flag_end_point_y) {
        Some((end_x, end_y))

    } else if maze_arg_requires_start_and_end_point(maze_args) {

        // We do not have an end but we need to make one up
        let end = longest_path.last().unwrap();
        Some((end.x, end.y))
    } else {
        None
    }
}

fn maze_arg_requires_start_and_end_point(maze_args: &MazeArgs) -> bool {
    maze_args.flag_furthest_end_point || maze_args.flag_show_distances ||
    maze_args.flag_show_path || maze_args.flag_colour_distances || maze_args.flag_mark_start_end
}

fn as_coordinate_smallvec(coord: GridCoordinate) -> CoordinateSmallVec {
    [coord].into_iter().cloned().collect::<CoordinateSmallVec>()
}

fn write_text_to_file(data: &str, file_name: &str) -> io::Result<()> {
    let mut f = try!(File::create(file_name));
    try!(f.write_all(data.as_bytes()));
    Ok(())
}

fn exit_with_msg(e: &str) -> ! {
    writeln!(&mut io::stderr(), "{}", e).expect(format!("Failed to print error: {}", e).as_str());
    exit(1);
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>Add iron hello world<commit_after>extern crate iron;

use iron::prelude::*;
use iron::status;

fn main() {
    fn hello_world(_: &mut Request) -> IronResult<Response> {
        Ok(Response::with((status::Ok, "Hello World!")))
    }

    let _server = Iron::new(hello_world).http("0.0.0.0:3000").unwrap();
    println!("On 3000");
}<|endoftext|>


<commit_before>extern crate hyper;
extern crate rustc_serialize;

use std::io::{self, Read};
use std::str;

use rustc_serialize::json;

fn main() {
    let _l = hyper::Server::new(handle).listen("127.0.0.1:3010");
    println!("Listening on http://127.0.0.1:3010");
}

fn handle(req: hyper::server::Request, mut res: hyper::server::Response<hyper::net::Fresh>) {
    match (req.method, req.uri) {
        (hyper::Get, hyper::uri::RequestUri::AbsolutePath(path)) => {
            let version = match lookup(&path[1..]) {
                Ok(v) => v,
                Err(..) => return not_found(res)
            };
            let badge = format!("https://img.shields.io/badge/crates.io-{}-green.svg", version);
            *res.status_mut() = hyper::status::StatusCode::Found;
            res.headers_mut().set(hyper::header::Location(badge));
            let _ = res.start().and_then(|res| res.end());
        },
        _ => not_found(res)
    };
}

fn not_found(mut res: hyper::server::Response<hyper::net::Fresh>) {
    *res.status_mut() = hyper::NotFound;
    let _ = res.start().and_then(|res| res.end());
}

type LookupResult = Result<String, LookupError>;

enum LookupError {
    NotFound,
    Http(hyper::HttpError),
    Io(io::Error)
}

impl From<hyper::HttpError> for LookupError {
    fn from(e: hyper::HttpError) -> LookupError {
        LookupError::Http(e)
    }
}

impl From<io::Error> for LookupError {
    fn from(e: io::Error) -> LookupError {
        LookupError::Io(e)
    }
}

#[derive(Debug)]
struct LookupCrate {
    version: String
}

impl rustc_serialize::Decodable for LookupCrate {
    fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<LookupCrate, D::Error> {
        Ok(LookupCrate {
            version: try!(d.read_struct("", 1, |d| {
                d.read_struct_field("crate", 1, |d| {
                    d.read_struct("", 1, |d| {
                        d.read_struct_field("max_version", 0, |d| d.read_str())
                    })
                })
            }))
        })
    }
}
fn lookup(krate: &str) -> LookupResult {
    let mut client = hyper::Client::new();
    let url = format!("https://crates.io/api/v1/crates/{}", krate);
    let mut res = try!(client.get(&*url).send());
    if res.status != hyper::Ok {
        return Err(LookupError::NotFound);
    }

    let mut buf = Vec::new();
    try!(res.read_to_end(&mut buf));

    let text = match str::from_utf8(&buf) {
        Ok(text) => text,
        _ => return Err(LookupError::NotFound)
    };

    let map: LookupCrate = match json::decode(text) {
        Ok(map) => map,
        _ => return Err(LookupError::NotFound)
    };

    Ok(map.version)
}
<commit_msg>get port from env<commit_after>extern crate hyper;
extern crate rustc_serialize;

use std::env;
use std::io::{self, Read};
use std::str;

use rustc_serialize::json;

static DEFAULT_PORT: u16 = 8080;

/// Look up our server port number in PORT, for compatibility with Heroku.
fn get_server_port() -> u16 {
    match env::var("PORT") {
        Ok(val) => u16::from_str_radix(&val, 10).unwrap_or(DEFAULT_PORT),
        Err(_) => DEFAULT_PORT
    }
}

fn main() {
    let port = get_server_port();
    let _l = hyper::Server::new(handle).listen(("127.0.0.1", port));
    println!("Listening on http://127.0.0.1:{}", port);
}

fn handle(req: hyper::server::Request, mut res: hyper::server::Response<hyper::net::Fresh>) {
    match (req.method, req.uri) {
        (hyper::Get, hyper::uri::RequestUri::AbsolutePath(path)) => {
            let version = match lookup(&path[1..]) {
                Ok(v) => v,
                Err(..) => return not_found(res)
            };
            let badge = format!("https://img.shields.io/badge/crates.io-{}-green.svg", version);
            *res.status_mut() = hyper::status::StatusCode::Found;
            res.headers_mut().set(hyper::header::Location(badge));
            let _ = res.start().and_then(|res| res.end());
        },
        _ => not_found(res)
    };
}

fn not_found(mut res: hyper::server::Response<hyper::net::Fresh>) {
    *res.status_mut() = hyper::NotFound;
    let _ = res.start().and_then(|res| res.end());
}

type LookupResult = Result<String, LookupError>;

enum LookupError {
    NotFound,
    Http(hyper::HttpError),
    Io(io::Error)
}

impl From<hyper::HttpError> for LookupError {
    fn from(e: hyper::HttpError) -> LookupError {
        LookupError::Http(e)
    }
}

impl From<io::Error> for LookupError {
    fn from(e: io::Error) -> LookupError {
        LookupError::Io(e)
    }
}

#[derive(Debug)]
struct LookupCrate {
    version: String
}

impl rustc_serialize::Decodable for LookupCrate {
    fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<LookupCrate, D::Error> {
        Ok(LookupCrate {
            version: try!(d.read_struct("", 1, |d| {
                d.read_struct_field("crate", 1, |d| {
                    d.read_struct("", 1, |d| {
                        d.read_struct_field("max_version", 0, |d| d.read_str())
                    })
                })
            }))
        })
    }
}
fn lookup(krate: &str) -> LookupResult {
    let mut client = hyper::Client::new();
    let url = format!("https://crates.io/api/v1/crates/{}", krate);
    let mut res = try!(client.get(&*url).send());
    if res.status != hyper::Ok {
        return Err(LookupError::NotFound);
    }

    let mut buf = Vec::new();
    try!(res.read_to_end(&mut buf));

    let text = match str::from_utf8(&buf) {
        Ok(text) => text,
        _ => return Err(LookupError::NotFound)
    };

    let map: LookupCrate = match json::decode(text) {
        Ok(map) => map,
        _ => return Err(LookupError::NotFound)
    };

    Ok(map.version)
}
<|endoftext|>


<commit_before>fn build_prefix_array(haplotypes: &[u8], n_haplo: usize, n_sites: usize) -> Vec<usize> {
    let mut prefix_order: Vec<usize> = vec![0; n_haplo];
    for i in 0..n_haplo {
        prefix_order[i] = i;
    }

    for k in 0..(n_sites-1) {
        let mut allele_0s: Vec<usize> = vec![];
        let mut allele_1s: Vec<usize> = vec![];
        for i in &prefix_order {
            if haplotypes[i*n_sites + k] == 0 {
                allele_0s.push(*i);
            } else {
                allele_1s.push(*i);
            }
        }
        prefix_order[0..allele_0s.len()].clone_from_slice(&allele_0s);
        prefix_order[allele_0s.len()..n_haplo].clone_from_slice(&allele_1s);
    }
    prefix_order
}

fn main() {
    let n_haplo: usize = 8; // M
    let n_sites: usize = 6; // N
    let haplotypes: Vec<u8> = vec![0, 1, 0, 1, 0, 1,
                                   1, 1, 0, 0, 0, 1,
                                   1, 1, 1, 1, 1, 1,
                                   0, 1, 1, 1, 1, 0,
                                   0, 0, 0, 0, 0, 0,
                                   1, 0, 0, 0, 1, 0,
                                   1, 1, 0, 0, 0, 1,
                                   0, 1, 0, 1, 1, 0];
    assert_eq!(n_haplo * n_sites, haplotypes.len());

    let prefix_order = build_prefix_array(&haplotypes, n_haplo, n_sites);
    println!("{:?}", prefix_order);
}

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

    #[test]
    fn test_prefix_array() {
        let n_haplo: usize = 8;
        let n_sites: usize = 6;
        let haplotypes: Vec<u8> = vec![0, 1, 0, 1, 0, 1,
                                       1, 1, 0, 0, 0, 1,
                                       1, 1, 1, 1, 1, 1,
                                       0, 1, 1, 1, 1, 0,
                                       0, 0, 0, 0, 0, 0,
                                       1, 0, 0, 0, 1, 0,
                                       1, 1, 0, 0, 0, 1,
                                       0, 1, 0, 1, 1, 0];
        let expected: Vec<usize> = vec![4, 1, 6, 0, 5, 7, 3, 2];
        assert_eq!(&expected,
                   &build_prefix_array(&haplotypes, n_haplo, n_sites));
    }
}
<commit_msg>Refactoring:<commit_after>/// Returns the next positional prefix array (Durbin's a_{k+1}) from the current one
///
/// # Arguments
///
/// * `pos_prefix_array` - An array slice holding the current positional prefix array (a_k)
/// * `haplotypes` - An array slice holding the haplotypes at the current (k-th) site
fn next_positional_prefix_array(pos_prefix_array: &[usize], haplotypes: &[u8]) -> Vec<usize> {
    let mut allele_0s: Vec<usize> = vec![];
    let mut allele_1s: Vec<usize> = vec![];

    for &i in pos_prefix_array {
        if haplotypes[i] == 0 {
            allele_0s.push(i);
        } else {
            allele_1s.push(i);
        }
    }
    let mut next_pos_prefix_array: Vec<usize> = vec![];
    next_pos_prefix_array.extend(&allele_0s);
    next_pos_prefix_array.extend(&allele_1s);
    next_pos_prefix_array
}

/// Returns the positional prefix array (Durbin's a_k)
///
/// # Arguments
///
/// * `haplotypes` - An array slice in which each row (of length n_haplo)
///                  corresponds to a single site, and contains 0s and 1s
///                  indicating allele
/// * `n_haplo` - The number of haplotypes
/// * `k_site` - The numbered site to build the array for
fn build_positional_prefix_array(haplotypes: &[u8], n_haplo: usize, k_site: usize) -> Vec<usize> {
    let mut pos_prefix_array: Vec<usize> = vec![0; n_haplo];
    for i in 0..n_haplo {
        pos_prefix_array[i] = i;
    }

    for k in 0..(k_site-1) {
        let haplotypes_at_k = &haplotypes[k*n_haplo..(k+1)*n_haplo];
        pos_prefix_array = next_positional_prefix_array(&pos_prefix_array, &haplotypes_at_k);
    }
    pos_prefix_array
}

fn main() {
}

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

    #[test]
    fn test_positional_prefix_array() {
        let n_haplo: usize = 8;
        let n_sites: usize = 6;
        let haplotypes: Vec<u8> = vec![0, 1, 1, 0, 0, 1, 1, 0,
                                       1, 1, 1, 1, 0, 0, 1, 1,
                                       0, 0, 1, 1, 0, 0, 0, 0,
                                       1, 0, 1, 1, 0, 0, 0, 1,
                                       0, 0, 1, 1, 0, 1, 0, 1,
                                       1, 1, 1, 0, 0, 0, 1, 0];
        let expected_1: Vec<usize> = vec![0, 1, 2, 3, 4, 5, 6, 7];
        assert_eq!(&expected_1,
                   &build_positional_prefix_array(&haplotypes, n_haplo, 1));
        let expected_6: Vec<usize> = vec![4, 1, 6, 0, 5, 7, 3, 2];
        assert_eq!(&expected_6,
                   &build_positional_prefix_array(&haplotypes, n_haplo, n_sites));
    }
}
<|endoftext|>


<commit_before>#![feature(duration_span, drain)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate thread_scoped;
extern crate tray_rust;

use std::vec::Vec;
use std::sync::mpsc::{self, Sender, Receiver};
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film;
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// A struct containing results of an image sample where a ray was fired through
/// continuous pixel coordinates [x, y] and color `color` was computed
struct ImageSample {
    x: f32,
    y: f32,
    color: film::Colorf,
}

impl ImageSample {
    pub fn new(x: f32, y: f32, color: film::Colorf) -> ImageSample {
        ImageSample { x: x, y: y, color: color }
    }
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<Vec<ImageSample>>, spp: usize, queue: &sampler::BlockQueue,
               scene: &scene::Scene, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            let mut samples = Vec::with_capacity(sampler.max_spp());
            for s in sample_pos.iter() {
                let mut ray = scene.camera.generate_ray(s);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
            if let Err(e) = tx.send(samples) {
                println!("Worker thread exiting with send error {:?}", e);
                return;
            }
        }
    }
}

/// Spawn `n` worker threads to render the scene in parallel. Returns the receive end
/// of the channel where the threads will write their samples so that the receiver
/// can write these samples to the render target
fn spawn_workers<'a>(n: u32, spp: usize, scene: &'a scene::Scene,
                     queue: &'a sampler::BlockQueue, light_list: &'a Vec<&Emitter>)
                 -> (Receiver<Vec<ImageSample>>, Vec<thread_scoped::JoinGuard<'a, ()>>) {
    let (tx, rx) = mpsc::channel();
    let mut guards = Vec::new();
    for _ in 0..n {
        let t = tx.clone();
        unsafe {
            guards.push(thread_scoped::scoped(move || {
                thread_work(t, spp, queue, scene, light_list);
            }));
        }
    }
    (rx, guards)
}

/// Render the scene in parallel to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let dim = rt.dimensions();
    let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
    let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
        match x {
            &Instance::Emitter(ref e) => Some(e),
            _ => None,
        }
    }).collect();
    assert!(!light_list.is_empty(), "At least one light is required");
    {
        println!("Rendering using {} threads", n);
        let (rx, guards) = spawn_workers(n, spp, &scene, &block_queue, &light_list);
        for mut v in rx.iter() {
            for s in v.drain(..) {
                rt.write(s.x, s.y, &s.color);
            }
        }
        for g in guards {
            g.join();
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    let (scene, spp, (width, height)) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(width, height);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
    println!("Rendering took {:?}", d);

    let img = rt.get_render();
    let out_file = match args.flag_o {
        Some(f) => f,
        None => "out.png".to_string(),
    };

    match image::save_buffer(&Path::new(&out_file), &img[..], width as u32, height as u32, image::RGB(8)) {
        Ok(_) => {},
        Err(e) => println!("Error saving image, {}", e),
    };
}

<commit_msg>Print out render time in seconds, i misread the doc on subsec_nanos<commit_after>#![feature(duration_span, drain)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate thread_scoped;
extern crate tray_rust;

use std::vec::Vec;
use std::sync::mpsc::{self, Sender, Receiver};
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film;
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// A struct containing results of an image sample where a ray was fired through
/// continuous pixel coordinates [x, y] and color `color` was computed
struct ImageSample {
    x: f32,
    y: f32,
    color: film::Colorf,
}

impl ImageSample {
    pub fn new(x: f32, y: f32, color: film::Colorf) -> ImageSample {
        ImageSample { x: x, y: y, color: color }
    }
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(tx: Sender<Vec<ImageSample>>, spp: usize, queue: &sampler::BlockQueue,
               scene: &scene::Scene, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            let mut samples = Vec::with_capacity(sampler.max_spp());
            for s in sample_pos.iter() {
                let mut ray = scene.camera.generate_ray(s);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
            if let Err(e) = tx.send(samples) {
                println!("Worker thread exiting with send error {:?}", e);
                return;
            }
        }
    }
}

/// Spawn `n` worker threads to render the scene in parallel. Returns the receive end
/// of the channel where the threads will write their samples so that the receiver
/// can write these samples to the render target
fn spawn_workers<'a>(n: u32, spp: usize, scene: &'a scene::Scene,
                     queue: &'a sampler::BlockQueue, light_list: &'a Vec<&Emitter>)
                 -> (Receiver<Vec<ImageSample>>, Vec<thread_scoped::JoinGuard<'a, ()>>) {
    let (tx, rx) = mpsc::channel();
    let mut guards = Vec::new();
    for _ in 0..n {
        let t = tx.clone();
        unsafe {
            guards.push(thread_scoped::scoped(move || {
                thread_work(t, spp, queue, scene, light_list);
            }));
        }
    }
    (rx, guards)
}

/// Render the scene in parallel to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let dim = rt.dimensions();
    let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
    let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
        match x {
            &Instance::Emitter(ref e) => Some(e),
            _ => None,
        }
    }).collect();
    assert!(!light_list.is_empty(), "At least one light is required");
    {
        println!("Rendering using {} threads", n);
        let (rx, guards) = spawn_workers(n, spp, &scene, &block_queue, &light_list);
        for mut v in rx.iter() {
            for s in v.drain(..) {
                rt.write(s.x, s.y, &s.color);
            }
        }
        for g in guards {
            g.join();
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    let (scene, spp, (width, height)) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(width, height);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
    let time = d.as_secs() as f64 + (d.subsec_nanos() as f64) / 1_000_000_000.0;
    println!("Rendering took {}s", time);

    let img = rt.get_render();
    let out_file = match args.flag_o {
        Some(f) => f,
        None => "out.png".to_string(),
    };

    match image::save_buffer(&Path::new(&out_file), &img[..], width as u32, height as u32, image::RGB(8)) {
        Ok(_) => {},
        Err(e) => println!("Error saving image, {}", e),
    };
}

<|endoftext|>


<commit_before>extern crate rsdocs2docset;
extern crate html5ever;
#[macro_use]
extern crate quick_error;
extern crate clap;
extern crate url;
extern crate sqlite;

use clap::{Arg, App};
use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;

use rsdocs2docset::dom::{manipulator, parser};

type Result = std::result::Result<(), RsDoc2DocsetError>;

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
        Sqlite(err: sqlite::Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version(include_str!("../VERSION"))
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_docset(args.value_of("indir").unwrap(), args.value_of("name").unwrap()).expect("error creating docset");
    println!("\n{}.docset successfully created!", args.value_of("name").unwrap())
}

fn create_docset(indir: &str, name: &str) -> Result {
    let db_filename = format!("{}.docset/Contents/Resources/docSet.dsidx", name);
    let db_path = Path::new(&db_filename);

    try!(write_file(Path::new(format!("{}.docset/Contents/Info.plist", name).as_str()), format!(include_str!("Info.plist.tmpl"), name = name, identifier = name.replace(" ", "-").to_lowercase()).as_ref()));
    try!(write_file(Path::new(format!("{}.docset/icon.png", name).as_str()), include_bytes!("icon.png")));
    try!(write_file(Path::new(format!("{}.docset/icon@2x.png", name).as_str()), include_bytes!("icon@2x.png")));

    try!(mkdir_parent_p(db_path));
    try!(sqlite::open(db_path).and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")));

    try!(docset_from_rs_doc_tree(&Path::new(indir), format!("{}.docset/Contents/Resources/Documents/", name).as_str(), Path::new(db_path)));

    Ok(())
}

// recursivly creates the parent dir of `path`
fn mkdir_parent_p(path: &Path) -> Result {
    let dir = path.parent().unwrap();

    try!(DirBuilder::new()
         .recursive(true)
         .create(dir));
    Ok(())
}

fn write_file(path: &Path, data: &[u8]) -> Result {
    try!(mkdir_parent_p(path));
    try!(File::create(path).and_then(|mut f| f.write_all(data)));
    Ok(())
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str, db_path: &Path) -> Result {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, &db_path));
                } else {
                    try!(annotate_file(&entry, &out_dir, &db_path));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str, db_path: &Path) -> Result {
    let out_file = Path::new(output_prefix).join(in_file.path());

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(mkdir_parent_p(&out_file));
        try!(fs::copy(in_file.path(), &out_file));
        //println!("{:70} | ", in_file.path().display());
        print!("."); io::stdout().flush().unwrap();
    } else {
        let mut dom = parse_document(RcDom::default(), ParseOpts::default())
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            //println!("{:70} | {}", in_file.path().display(), entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            try!(sqlite::open(db_path).and_then(|c| c.execute(&sql_cmd)))
        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));
        try!(write_file(&out_file, bytes.as_ref()));

        print!("o"); io::stdout().flush().unwrap();
    }

    Ok(())
}
<commit_msg>Some cosmetics<commit_after>#[macro_use] extern crate quick_error;

extern crate clap;
extern crate html5ever;
extern crate rsdocs2docset;
extern crate sqlite;
extern crate url;

use clap::{Arg, App};

use html5ever::driver::{ParseOpts, parse_document};
use html5ever::rcdom::RcDom;
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;

use std::ffi::OsStr;
use std::fs::{self, DirBuilder, DirEntry, File};
use std::io::{self,Write};
use std::path::Path;

use rsdocs2docset::dom::{manipulator, parser};

type Result = std::result::Result<(), RsDoc2DocsetError>;

quick_error! {
    #[derive(Debug)]
    pub enum RsDoc2DocsetError {
        Io(err: std::io::Error) {
            from()
                cause(err)
                description(err.description())
        }
        Utf8(err: std::string::FromUtf8Error) {
            from()
                cause(err)
                description(err.description())
        }
        Sqlite(err: sqlite::Error) {
            from()
                cause(err)
                description(err.description())
        }
    }
}

fn main() {
    let args = App::new("RsDoc2Docset")
        .version(include_str!("../VERSION"))
        .about("A tool that converts rust docs to Dash docset files")
        .arg(Arg::with_name("indir")
             .short("i")
             .long("rsdoc")
             .value_name("INDIR")
             .help("directory that contains rustdoc files")
             .required(true)
             .takes_value(true))
        .arg(Arg::with_name("name")
             .short("n")
             .long("name")
             .value_name("NAME")
             .help("name of the docset")
             .required(true)
             .takes_value(true))
        .get_matches();

    create_docset(args.value_of("indir").unwrap(), args.value_of("name").unwrap()).expect("error creating docset");
    println!("\n{}.docset successfully created!", args.value_of("name").unwrap())
}

fn create_docset(indir: &str, name: &str) -> Result {
    let db_filename = format!("{}.docset/Contents/Resources/docSet.dsidx", name);
    let db_path = Path::new(&db_filename);

    try!(write_file(Path::new(format!("{}.docset/Contents/Info.plist", name).as_str()), format!(include_str!("Info.plist.tmpl"), name = name, identifier = name.replace(" ", "-").to_lowercase()).as_ref()));
    try!(write_file(Path::new(format!("{}.docset/icon.png", name).as_str()), include_bytes!("icon.png")));
    try!(write_file(Path::new(format!("{}.docset/icon@2x.png", name).as_str()), include_bytes!("icon@2x.png")));

    try!(mkdir_parent_p(db_path));
    try!(sqlite::open(db_path).and_then(|c| c.execute("CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT);")));

    try!(docset_from_rs_doc_tree(&Path::new(indir), format!("{}.docset/Contents/Resources/Documents/", name).as_str(), Path::new(db_path)));

    Ok(())
}

// recursivly creates the parent dir of `path`
fn mkdir_parent_p(path: &Path) -> Result {
    let dir = path.parent().unwrap();

    try!(DirBuilder::new()
         .recursive(true)
         .create(dir));
    Ok(())
}

fn write_file(path: &Path, data: &[u8]) -> Result {
    try!(mkdir_parent_p(path));
    try!(File::create(path).and_then(|mut f| f.write_all(data)));
    Ok(())
}

fn docset_from_rs_doc_tree(source_dir: &Path, out_dir: &str, db_path: &Path) -> Result {
        if !source_dir.exists() {
            return Err(io::Error::new(io::ErrorKind::NotFound, format!("{} does not exist", source_dir.to_str().unwrap())).into());
        }

        if source_dir.is_dir() {
            for entry in fs::read_dir(source_dir)? {
                let entry = entry?;
                if entry.path().is_dir() {
                    try!(docset_from_rs_doc_tree(&entry.path(), &out_dir, &db_path));
                } else {
                    try!(annotate_file(&entry, &out_dir, &db_path));
                }
            }
        }
        Ok(())
    }

fn annotate_file(in_file: &DirEntry, output_prefix: &str, db_path: &Path) -> Result {
    let out_file = Path::new(output_prefix).join(in_file.path());

    if in_file.path().extension() != Some(OsStr::new("html")) {
        try!(mkdir_parent_p(&out_file));
        try!(fs::copy(in_file.path(), &out_file));
        //println!("{:70} | ", in_file.path().display());
        print!("."); io::stdout().flush().unwrap();
    } else {
        let mut dom = parse_document(RcDom::default(), ParseOpts::default())
            .from_utf8()
            .read_from( &mut File::open(&in_file.path())? )?;

        let entries = parser::find_entry_elements(&mut dom);
        for entry in entries.iter().filter_map(|x| x.as_ref()) {
            //println!("{:70} | {}", in_file.path().display(), entry);

            let sql_cmd = format!("INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (\"{}\", \"{}\", \"{}#{}\");", entry.entry_name, entry.entry_type, in_file.path().to_str().unwrap(), entry.anchor_name);
            try!(sqlite::open(db_path).and_then(|c| c.execute(&sql_cmd)))
        }
        manipulator::add_dash_links(&mut dom, &entries);

        let mut bytes = vec![];
        try!(serialize(&mut bytes, &dom.document, SerializeOpts::default()));
        try!(write_file(&out_file, bytes.as_ref()));

        print!("o"); io::stdout().flush().unwrap();
    }

    Ok(())
}
<|endoftext|>


<commit_before>#![allow(non_snake_case)]

extern crate getopts;
extern crate jni;
extern crate rustc_serialize;

#[cfg(target_os = "macos")]
extern crate libc;

use getopts::Options;
use jni::JNI;
use jni::classpath::load_static_method;
use jni::consts::*;
use jni::ffi;
use jni::ffi::JNIEnv;
use jni::types as jni_types;
use jni::types::{Jclass, Jint};
use rustc_serialize::json;
use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::{Path, PathBuf};

#[cfg(target_os = "macos")]
use libc::{c_int};
#[cfg(target_os = "macos")]
use std::sync::mpsc::{channel, Receiver, Sender};
#[cfg(target_os = "macos")]
use std::thread;

#[derive(RustcDecodable)]
struct Config {
    jar: String,
    mainClass: String,
    vmArgs: Vec<String>
}

#[cfg(target_os = "macos")]
fn select_root_path(program: &str) {
    let program_path = Path::new(&program).parent().unwrap();
    println!("executable: {}", program_path.display());

    if env::set_current_dir(&program_path).is_err() {
        panic!("Could not change working directory");
    }
}

#[cfg(not(target_os = "macos"))]
#[allow(unused_variables)]
fn select_root_path(program: &str) {
}

#[cfg(target_os = "macos")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("lib");
    path.push("jli");
    path.push("libjli");
    path.set_extension("dylib");
}

#[cfg(target_os = "linux")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("lib");
    path.push("amd64");
    path.push("server");
    path.push("libjvm");
    path.set_extension("so");
}

#[cfg(target_os = "windows")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("bin");
    path.push("server");
    path.push("jvm");
    path.set_extension("dll");
}

fn get_libjvm_path(jre: &Path) -> PathBuf {
    let mut path = PathBuf::new();
    path.push(jre);
    get_libjvm_path_os(&mut path);
    path
}

fn init_jvm_arguments(jni: &mut JNI, config: &Config) {
    let num_args = config.vmArgs.len();

    jni.init_vm_args(num_args);

    for i in 0..num_args {
        let ref vm_arg = config.vmArgs[i];
        jni.push_vm_arg(i, &vm_arg);
    }
}

fn load_jvm(jni: &mut JNI, config: &Config) {
    // create & fill arguments
    init_jvm_arguments(jni, config);

    // load lib, create VM instance
    match jni.create_java_vm() {
        Err(err) => panic!(err),
        Ok(_) => {}
    };

    // attach to current thread
    match ffi::attach_current_thread(jni.get_jvm()) {
        (JNI_OK, _) => {},
        (_, _) => panic!("Could not attach JVM to thread")
    }
    println!("JVM attached to thread ...");
}

fn check_for_exceptions(env: &mut JNIEnv) {
    let throwable = ffi::exception_occured(env);
    if !jni_types::is_null(throwable) {
        ffi::exception_describe(env);
        ffi::exception_clear(env);
        panic!("Exception caught!");
    }
}

fn call_main(env: &mut JNIEnv, path_to_jar: &str, main_class_name: &str, args: &Vec<String>) {

    // do class-loader voodoo

    let (main_class, main_method) = load_static_method(env, path_to_jar, main_class_name);

    match (main_class, main_method) {
        (JNI_NULL, JNI_NULL) => {
            println!("Could not find {}.main()", main_class_name);
            return;
        },
        (_, _) => {}
    };

    // pass program arguments

    let java_lang_String:Jclass = ffi::find_class(env, "java/lang/String");
    check_for_exceptions(env);
    assert!(!jni_types::is_null(java_lang_String));

    let argc = args.len();

    let argv = ffi::new_object_array(env, argc as Jint, java_lang_String, JNI_NULL);
    check_for_exceptions(env);
    assert!(!jni_types::is_null(argv));

    for i in 0..argc {
        println!("Application argument: {}", &args[i]);
        let arg = ffi::new_string_utf(env, &args[i]);
        ffi::set_object_array_element(env, argv, i as Jint, arg);
    }

    // call main()
    ffi::call_static_void_method_a(env, main_class, main_method, &[argv]);

    check_for_exceptions(env);

    println!("Quit from JVM ...");
}

fn read_config(path: &Path) -> Config {
    let mut f = match File::open(path) {
        Ok(f) => f,
        Err(_) => panic!("Could not open {}", path.display())
    };

    let mut content = String::new();

    if f.read_to_string(&mut content).is_err() {
        panic!("Error reading {}", path.display());
    }

    let config:Config = json::decode(&content).unwrap();

    println!("jar: {}", config.jar);
    println!("main class: {}", config.mainClass);

    for arg in config.vmArgs.iter() {
        println!("VM argument: {}", arg);
    }

    config
}

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
    //println!("-- {{args}}\tUnparsed arguments passed through to Java main() method.");
}

fn spawn_vm() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => {
            println!("{} Run {} --help to show options.", f.to_string(), program);
            return;
        }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    select_root_path(&program);

    let root_path = env::current_dir().unwrap();
    println!("working directory: {}", root_path.display());

    let libjvmpath = get_libjvm_path(root_path.join("jre").as_path());
    println!("JRE path: {}", libjvmpath.display());

    // read config JSON
    let config = read_config(root_path.join("config.json").as_path());

    let cp_path = Path::new(&config.jar);
    let class_path = format!("{}", cp_path.display());
    println!("class path: {}", class_path);

    println!("Loading JVM library ...");
    let mut jni:JNI = match JNI::new(&libjvmpath) {
        Err(error) => panic!(error),
        Ok(jni) => jni
    };

    println!("JNI initialized.");

    println!("Creating JVM instance ...");
    load_jvm(&mut jni, &config);

    println!("Invoking {}.main()", config.mainClass);
    let env:&mut JNIEnv = jni.get_env();
    call_main(env, &class_path, &config.mainClass, &matches.free);
}

#[cfg(target_os = "macos")]
#[link(name = "packrnative", kind = "static")]
#[link(name = "CoreFoundation", kind = "framework")]
#[link(name = "CoreServices", kind = "framework")]
extern {
    fn cfRunLoopRun(callback: extern fn(&Receiver<c_int>), signal:&Receiver<c_int>);
    fn cfRunLoopStop();
}

#[cfg(target_os = "macos")]
extern fn run_loop_callback(signal:&Receiver<c_int>) {
    match signal.try_recv() {
        Err(_) => {},
        Ok(_) => unsafe {
            cfRunLoopStop();
        }
    }
}

#[cfg(target_os = "macos")]
fn main() {

    let (tx, rx): (Sender<c_int>, Receiver<c_int>) = channel();
    let proc_tx = tx.clone();

    thread::spawn(move|| {
        spawn_vm();
        proc_tx.send(0).unwrap();
    });

    unsafe {
        cfRunLoopRun(run_loop_callback, &rx);
    }
}

#[cfg(not(target_os = "macos"))]
fn main() {
    spawn_vm();
}
<commit_msg>Modified "--help" output.<commit_after>#![allow(non_snake_case)]

extern crate getopts;
extern crate jni;
extern crate rustc_serialize;

#[cfg(target_os = "macos")]
extern crate libc;

use getopts::Options;
use jni::JNI;
use jni::classpath::load_static_method;
use jni::consts::*;
use jni::ffi;
use jni::ffi::JNIEnv;
use jni::types as jni_types;
use jni::types::{Jclass, Jint};
use rustc_serialize::json;
use std::env;
use std::io::prelude::*;
use std::fs::File;
use std::path::{Path, PathBuf};

#[cfg(target_os = "macos")]
use libc::{c_int};
#[cfg(target_os = "macos")]
use std::sync::mpsc::{channel, Receiver, Sender};
#[cfg(target_os = "macos")]
use std::thread;

#[derive(RustcDecodable)]
struct Config {
    jar: String,
    mainClass: String,
    vmArgs: Vec<String>
}

#[cfg(target_os = "macos")]
fn select_root_path(program: &str) {
    let program_path = Path::new(&program).parent().unwrap();
    println!("executable: {}", program_path.display());

    if env::set_current_dir(&program_path).is_err() {
        panic!("Could not change working directory");
    }
}

#[cfg(not(target_os = "macos"))]
#[allow(unused_variables)]
fn select_root_path(program: &str) {
}

#[cfg(target_os = "macos")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("lib");
    path.push("jli");
    path.push("libjli");
    path.set_extension("dylib");
}

#[cfg(target_os = "linux")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("lib");
    path.push("amd64");
    path.push("server");
    path.push("libjvm");
    path.set_extension("so");
}

#[cfg(target_os = "windows")]
fn get_libjvm_path_os(path: &mut PathBuf) {
    path.push("bin");
    path.push("server");
    path.push("jvm");
    path.set_extension("dll");
}

fn get_libjvm_path(jre: &Path) -> PathBuf {
    let mut path = PathBuf::new();
    path.push(jre);
    get_libjvm_path_os(&mut path);
    path
}

fn init_jvm_arguments(jni: &mut JNI, config: &Config) {
    let num_args = config.vmArgs.len();

    jni.init_vm_args(num_args);

    for i in 0..num_args {
        let ref vm_arg = config.vmArgs[i];
        jni.push_vm_arg(i, &vm_arg);
    }
}

fn load_jvm(jni: &mut JNI, config: &Config) {
    // create & fill arguments
    init_jvm_arguments(jni, config);

    // load lib, create VM instance
    match jni.create_java_vm() {
        Err(err) => panic!(err),
        Ok(_) => {}
    };

    // attach to current thread
    match ffi::attach_current_thread(jni.get_jvm()) {
        (JNI_OK, _) => {},
        (_, _) => panic!("Could not attach JVM to thread")
    }
    println!("JVM attached to thread ...");
}

fn check_for_exceptions(env: &mut JNIEnv) {
    let throwable = ffi::exception_occured(env);
    if !jni_types::is_null(throwable) {
        ffi::exception_describe(env);
        ffi::exception_clear(env);
        panic!("Exception caught!");
    }
}

fn call_main(env: &mut JNIEnv, path_to_jar: &str, main_class_name: &str, args: &Vec<String>) {

    // do class-loader voodoo

    let (main_class, main_method) = load_static_method(env, path_to_jar, main_class_name);

    match (main_class, main_method) {
        (JNI_NULL, JNI_NULL) => {
            println!("Could not find {}.main()", main_class_name);
            return;
        },
        (_, _) => {}
    };

    // pass program arguments

    let java_lang_String:Jclass = ffi::find_class(env, "java/lang/String");
    check_for_exceptions(env);
    assert!(!jni_types::is_null(java_lang_String));

    let argc = args.len();

    let argv = ffi::new_object_array(env, argc as Jint, java_lang_String, JNI_NULL);
    check_for_exceptions(env);
    assert!(!jni_types::is_null(argv));

    for i in 0..argc {
        println!("Application argument: {}", &args[i]);
        let arg = ffi::new_string_utf(env, &args[i]);
        ffi::set_object_array_element(env, argv, i as Jint, arg);
    }

    // call main()
    ffi::call_static_void_method_a(env, main_class, main_method, &[argv]);

    check_for_exceptions(env);

    println!("Quit from JVM ...");
}

fn read_config(path: &Path) -> Config {
    let mut f = match File::open(path) {
        Ok(f) => f,
        Err(_) => panic!("Could not open {}", path.display())
    };

    let mut content = String::new();

    if f.read_to_string(&mut content).is_err() {
        panic!("Error reading {}", path.display());
    }

    let config:Config = json::decode(&content).unwrap();

    println!("jar: {}", config.jar);
    println!("main class: {}", config.mainClass);

    for arg in config.vmArgs.iter() {
        println!("VM argument: {}", arg);
    }

    config
}

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage:\n    {} [options] [--] [<args>...]", program);
    print!("{}", opts.usage(&brief));
    println!("\n    Trailing arguments are passed to Java main() method.");
}

fn spawn_vm() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => {
            println!("{} Run {} --help to show options.", f.to_string(), program);
            return;
        }
    };

    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }

    select_root_path(&program);

    let root_path = env::current_dir().unwrap();
    println!("working directory: {}", root_path.display());

    let libjvmpath = get_libjvm_path(root_path.join("jre").as_path());
    println!("JRE path: {}", libjvmpath.display());

    // read config JSON
    let config = read_config(root_path.join("config.json").as_path());

    let cp_path = Path::new(&config.jar);
    let class_path = format!("{}", cp_path.display());
    println!("class path: {}", class_path);

    println!("Loading JVM library ...");
    let mut jni:JNI = match JNI::new(&libjvmpath) {
        Err(error) => panic!(error),
        Ok(jni) => jni
    };

    println!("JNI initialized.");

    println!("Creating JVM instance ...");
    load_jvm(&mut jni, &config);

    println!("Invoking {}.main()", config.mainClass);
    let env:&mut JNIEnv = jni.get_env();
    call_main(env, &class_path, &config.mainClass, &matches.free);
}

#[cfg(target_os = "macos")]
#[link(name = "packrnative", kind = "static")]
#[link(name = "CoreFoundation", kind = "framework")]
#[link(name = "CoreServices", kind = "framework")]
extern {
    fn cfRunLoopRun(callback: extern fn(&Receiver<c_int>), signal:&Receiver<c_int>);
    fn cfRunLoopStop();
}

#[cfg(target_os = "macos")]
extern fn run_loop_callback(signal:&Receiver<c_int>) {
    match signal.try_recv() {
        Err(_) => {},
        Ok(_) => unsafe {
            cfRunLoopStop();
        }
    }
}

#[cfg(target_os = "macos")]
fn main() {

    let (tx, rx): (Sender<c_int>, Receiver<c_int>) = channel();
    let proc_tx = tx.clone();

    thread::spawn(move|| {
        spawn_vm();
        proc_tx.send(0).unwrap();
    });

    unsafe {
        cfRunLoopRun(run_loop_callback, &rx);
    }
}

#[cfg(not(target_os = "macos"))]
fn main() {
    spawn_vm();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

fn main() {
    let _ = clap::App::new("q")
        .author("Sergey Arkhipov <nineseconds@yandex.ru>")
        .version(&crate_version!()[..])
        .about("q is a gentle way to grep using predefined regexp sets.")
        .after_help("Please find more documentation at https://github.com/9seconds/q.")
        .arg(
            clap::Arg::with_name("same_line")
                .help("Keep matches on the same line")
                .short("l")
                .long("same_line")
        ).arg(
            clap::Arg::with_name("RULES_DIRECTORY")
                .help("Directory where rules could be found. By default it uses $XDG_CONFIG_HOME/q/rules")
                .short("-r")
                .long("rules")
                .takes_value(true)
        ).arg(
            clap::Arg::with_name("RULES")
                .help("Regexp rules to apply to the stdin as a comma-separated list.")
                .index(1)
                .required(true)
        )
        .get_matches();

    println!("Hello world")
}
<commit_msg>More meat<commit_after>#[macro_use]
extern crate clap;

extern crate xdg_basedir;
extern crate regex;

use std::path;
use std::io;
use std::io::BufRead;
use std::fs;

fn get_default_config_directory() -> String {
    let mut config_home_dir = xdg_basedir::get_config_home()
        .ok()
        .expect("Unable to detect default q directory.");

    config_home_dir.push("q");
    config_home_dir.push("rules");

    config_home_dir.to_str().unwrap().to_string()
}

fn parse_rules_filenames(rules: &str, config_dir: &str) -> Vec<path::PathBuf> {
    rules
        .split(",")
        .map(
            |item|
            {
                let mut root_path = path::PathBuf::from(config_dir);
                root_path.push(item);
                root_path
            }
        )
        .collect::<Vec<path::PathBuf>>()
}

fn parse_rules(filenames: &Vec<path::PathBuf>) -> Vec<regex::Regex> {
    let mut rules: Vec<regex::Regex> = Vec::with_capacity(filenames.len());

    for filename in filenames.iter() {
        let path = filename.as_path();
        let file = fs::File::open(path)
            .ok()
            .expect(
                &format!("Cannot open file {:?}.", path)
            );

        for line in io::BufReader::new(file).lines() {
            let content = line
                .ok()
                .expect(
                    &format!("Cannot fetch a line from file {:?}.", path)
                );
            let regexp = regex::Regex::new(&content)
                .ok()
                .expect(
                    &format!("Cannot compile regexp from {}, file {:?}.", content, path)
                );
            rules.push(regexp);
        }
    }

    rules
}

fn main() {
    let options = clap::App::new("q")
        .author("Sergey Arkhipov <nineseconds@yandex.ru>")
        .version(&crate_version!()[..])
        .about("q is a gentle way to grep using predefined regexp sets.")
        .after_help("Please find more documentation at https://github.com/9seconds/q.")
        .arg(
            clap::Arg::with_name("SAME_LINE")
                .help("Keep matches on the same line")
                .short("l")
                .long("same_line")
        ).arg(
            clap::Arg::with_name("RULES_DIRECTORY")
                .help("Directory where rules could be found. By default it uses $XDG_CONFIG_HOME/q/rules")
                .short("-r")
                .long("rules")
                .takes_value(true)
        ).arg(
            clap::Arg::with_name("FILE")
                .help("File to process. Use '-' to read from stdin.")
                .short("-f")
                .long("file")
                .takes_value(true)
        ).arg(
            clap::Arg::with_name("RULES")
                .help("Regexp rules to apply to the stdin as a comma-separated list.")
                .index(1)
                .required(true)
        )
        .get_matches();

    let same_line = options.is_present("SAME_LINE");

    let default_config_directory = get_default_config_directory();
    let rules_directory = options.value_of("RULES_DIRECTORY").unwrap_or(&default_config_directory);

    let filename = options.value_of("FILE").unwrap_or("-");
    let rules_filenames = parse_rules_filenames(options.value_of("RULES").unwrap(), rules_directory);

    let rules = parse_rules(&rules_filenames);

    println!("Options: {}, {}, {}, {:?}", same_line, rules_directory, filename, rules);
}
<|endoftext|>