<commit_before>use std::env;
use std::ffi::OsString;
use std::fmt::{self, Display};
use std::fs;
use std::io::{self, BufRead, Write};
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};

use atty::Stream::{Stderr, Stdout};
use prettyprint::{PagingMode, PrettyPrinter, PrettyPrintError};
use quote::quote;
use structopt::clap::AppSettings;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(bin_name = "cargo")]
enum Opts {
    /// Show the result of macro expansion.
    #[structopt(
        name = "expand",
        raw(
            setting = "AppSettings::UnifiedHelpMessage",
            setting = "AppSettings::DeriveDisplayOrder",
            setting = "AppSettings::DontCollapseArgsInUsage"
        )
    )]
    Expand(Args),
}

#[derive(StructOpt, Debug)]
#[structopt(rename_all = "kebab-case")]
struct Args {
    /// Space-separated list of features to activate
    #[structopt(long, value_name = "FEATURES")]
    features: Option<String>,

    /// Activate all available features
    #[structopt(long)]
    all_features: bool,

    /// Do not activate the `default` feature
    #[structopt(long)]
    no_default_features: bool,

    /// Build only this package's library
    #[structopt(long)]
    lib: bool,

    /// Build only the specified binary
    #[structopt(long, value_name = "NAME")]
    bin: Option<String>,

    /// Build only the specified example
    #[structopt(long, value_name = "NAME")]
    example: Option<String>,

    /// Build only the specified test target
    #[structopt(long, value_name = "NAME")]
    test: Option<String>,

    /// Build only the specified bench target
    #[structopt(long, value_name = "NAME")]
    bench: Option<String>,

    /// Target triple which compiles will be for
    #[structopt(long, value_name = "TARGET")]
    target: Option<String>,

    /// Directory for all generated artifacts
    #[structopt(long, value_name = "DIRECTORY", parse(from_os_str))]
    target_dir: Option<PathBuf>,

    /// Path to Cargo.toml
    #[structopt(long, value_name = "PATH", parse(from_os_str))]
    manifest_path: Option<PathBuf>,

    /// Number of parallel jobs, defaults to # of CPUs
    #[structopt(short, long, value_name = "N")]
    jobs: Option<u64>,

    /// Coloring: auto, always, never
    #[structopt(long, value_name = "WHEN")]
    color: Option<String>,

    /// Require Cargo.lock and cache are up to date
    #[structopt(long)]
    frozen: bool,

    /// Require Cargo.lock is up to date
    #[structopt(long)]
    locked: bool,

    /// Unstable (nightly-only) flags to Cargo
    #[structopt(short = "Z", value_name = "FLAG")]
    unstable_flags: Vec<String>,

    /// Do not attempt to run rustfmt
    #[structopt(long)]
    ugly: bool,
}

fn main() {
    let result = cargo_expand_or_run_nightly();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

enum Error {
    Io(io::Error),
    Print(PrettyPrintError),
}

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

impl From<PrettyPrintError> for Error {
    fn from(error: PrettyPrintError) -> Self {
        Error::Print(error)
    }
}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::Io(error) => Display::fmt(error, formatter),
            Error::Print(error) => Display::fmt(error, formatter),
        }
    }
}

type Result<T> = std::result::Result<T, Error>;

fn cargo_expand_or_run_nightly() -> Result<i32> {
    const NO_RUN_NIGHTLY: &str = "CARGO_EXPAND_NO_RUN_NIGHTLY";

    let maybe_nightly = !definitely_not_nightly();
    if maybe_nightly || env::var_os(NO_RUN_NIGHTLY).is_some() {
        return cargo_expand();
    }

    let mut nightly = Command::new("cargo");
    nightly.arg("+nightly");
    nightly.arg("expand");

    let mut args = env::args_os().peekable();
    args.next().unwrap(); // cargo
    if args.peek().map_or(false, |arg| arg == "expand") {
        args.next().unwrap(); // expand
    }
    nightly.args(args);

    // Hopefully prevent infinite re-run loop.
    nightly.env(NO_RUN_NIGHTLY, "");

    let status = nightly.status()?;

    Ok(match status.code() {
        Some(code) => code,
        None => {
            if status.success() {
                0
            } else {
                1
            }
        }
    })
}

fn definitely_not_nightly() -> bool {
    let mut cmd = Command::new(cargo_binary());
    cmd.arg("--version");

    let output = match cmd.output() {
        Ok(output) => output,
        Err(_) => return false,
    };

    let version = match String::from_utf8(output.stdout) {
        Ok(version) => version,
        Err(_) => return false,
    };

    version.starts_with("cargo 1") && !version.contains("nightly")
}

fn cargo_binary() -> OsString {
    env::var_os("CARGO").unwrap_or_else(|| "cargo".to_owned().into())
}

fn cargo_expand() -> Result<i32> {
    let Opts::Expand(args) = Opts::from_args();

    let mut builder = tempfile::Builder::new();
    builder.prefix("cargo-expand");
    let outdir = builder.tempdir().expect("failed to create tmp file");
    let outfile_path = outdir.path().join("expanded");

    // Run cargo
    let mut cmd = Command::new(cargo_binary());
    apply_args(&mut cmd, &args, &outfile_path);
    let code = filter_err(&mut cmd, ignore_cargo_err)?;

    let mut content = fs::read_to_string(&outfile_path)?;
    if content.is_empty() {
        let _ = writeln!(
            &mut io::stderr(),
            "ERROR: rustc produced no expanded output"
        );
        return Ok(if code == 0 { 1 } else { code });
    }

    // Run rustfmt
    let which_rustfmt = match args.ugly {
        false => which("rustfmt"),
        true => None,
    };
    if let Some(fmt) = which_rustfmt {
        // Discard comments, which are misplaced by the compiler
        if let Ok(syntax_tree) = syn::parse_file(&content) {
            content = quote!(#syntax_tree).to_string();
            fs::write(&outfile_path, content)?;
        }

        // Ignore any errors.
        let _status = Command::new(fmt)
            .arg(&outfile_path)
            .stderr(Stdio::null())
            .status();

        content = fs::read_to_string(&outfile_path)?;
    }

    // Run pretty printer
    let do_color = match args.color.as_ref().map(String::as_str) {
        Some("always") => true,
        Some("never") => false,
        None | Some("auto") | Some(_) => atty::is(Stdout),
    };
    if do_color {
        if content.ends_with('\n') {
            // Pretty printer seems to print an extra trailing newline.
            content.truncate(content.len() - 1);
        }
        let printer = PrettyPrinter::default()
            .header(false)
            .grid(false)
            .line_numbers(false)
            .language("rust")
            .paging_mode(PagingMode::Never)
            .build()
            .unwrap();

        // Ignore any errors.
        let _ = printer.string(content);
    } else {
        let _ = write!(&mut io::stdout(), "{}", content);
    }

    Ok(0)
}

// Based on https://github.com/rsolomo/cargo-check
fn apply_args(cmd: &mut Command, args: &Args, outfile: &Path) {
    cmd.arg("rustc");
    cmd.arg("--profile=check");

    if let Some(features) = &args.features {
        cmd.arg("--features");
        cmd.arg(features);
    }

    if args.all_features {
        cmd.arg("--all-features");
    }

    if args.no_default_features {
        cmd.arg("--no-default-features");
    }

    if args.lib {
        cmd.arg("--lib");
    }

    if let Some(bin) = &args.bin {
        cmd.arg("--bin");
        cmd.arg(bin);
    }

    if let Some(example) = &args.example {
        cmd.arg("--example");
        cmd.arg(example);
    }

    if let Some(test) = &args.test {
        cmd.arg("--test");
        cmd.arg(test);
    }

    if let Some(bench) = &args.bench {
        cmd.arg("--bench");
        cmd.arg(bench);
    }

    if let Some(target) = &args.target {
        cmd.arg("--target");
        cmd.arg(target);
    }

    if let Some(target_dir) = &args.target_dir {
        cmd.arg("--target-dir");
        cmd.arg(target_dir);
    }

    if let Some(manifest_path) = &args.manifest_path {
        cmd.arg("--manifest-path");
        cmd.arg(manifest_path);
    }

    if let Some(jobs) = args.jobs {
        cmd.arg("--jobs");
        cmd.arg(jobs.to_string());
    }

    cmd.arg("--color");
    if let Some(color) = &args.color {
        cmd.arg(color);
    } else {
        cmd.arg(if atty::is(Stderr) { "always" } else { "never" });
    }

    if args.frozen {
        cmd.arg("--frozen");
    }

    if args.locked {
        cmd.arg("--locked");
    }

    for unstable_flag in &args.unstable_flags {
        cmd.arg("-Z");
        cmd.arg(unstable_flag);
    }

    cmd.arg("--");
    cmd.arg("-o");
    cmd.arg(outfile);
    cmd.arg("-Zunstable-options");
    cmd.arg("--pretty=expanded");
}

fn which(cmd: &str) -> Option<OsString> {
    if env::args_os().any(|arg| arg == *"--help") {
        return None;
    }

    if let Some(which) = env::var_os(&cmd.to_uppercase()) {
        return if which.is_empty() { None } else { Some(which) };
    }

    let spawn = Command::new(cmd)
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn();
    let mut child = match spawn {
        Ok(child) => child,
        Err(_) => {
            return None;
        }
    };

    let exit = match child.wait() {
        Ok(exit) => exit,
        Err(_) => {
            return None;
        }
    };

    if exit.success() {
        Some(cmd.into())
    } else {
        None
    }
}

fn filter_err(cmd: &mut Command, ignore: fn(&str) -> bool) -> io::Result<i32> {
    let mut child = cmd.stderr(Stdio::piped()).spawn()?;
    let mut stderr = io::BufReader::new(child.stderr.take().unwrap());
    let mut line = String::new();
    while let Ok(n) = stderr.read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    let code = child.wait()?.code().unwrap_or(1);
    Ok(code)
}

fn ignore_cargo_err(line: &str) -> bool {
    if line.trim().is_empty() {
        return true;
    }

    let blacklist = [
        "ignoring specified output filename because multiple outputs were \
         requested",
        "ignoring specified output filename for 'link' output because multiple \
         outputs were requested",
        "ignoring --out-dir flag due to -o flag",
        "ignoring -C extra-filename flag due to -o flag",
        "due to multiple output types requested, the explicitly specified \
         output file name will be adapted for each output type",
    ];
    for s in &blacklist {
        if line.contains(s) {
            return true;
        }
    }

    false
}
<commit_msg>Work around issue parsing $crate<commit_after>use std::env;
use std::ffi::OsString;
use std::fmt::{self, Display};
use std::fs;
use std::io::{self, BufRead, Write};
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};

use atty::Stream::{Stderr, Stdout};
use prettyprint::{PagingMode, PrettyPrinter, PrettyPrintError};
use quote::quote;
use structopt::clap::AppSettings;
use structopt::StructOpt;

#[derive(StructOpt)]
#[structopt(bin_name = "cargo")]
enum Opts {
    /// Show the result of macro expansion.
    #[structopt(
        name = "expand",
        raw(
            setting = "AppSettings::UnifiedHelpMessage",
            setting = "AppSettings::DeriveDisplayOrder",
            setting = "AppSettings::DontCollapseArgsInUsage"
        )
    )]
    Expand(Args),
}

#[derive(StructOpt, Debug)]
#[structopt(rename_all = "kebab-case")]
struct Args {
    /// Space-separated list of features to activate
    #[structopt(long, value_name = "FEATURES")]
    features: Option<String>,

    /// Activate all available features
    #[structopt(long)]
    all_features: bool,

    /// Do not activate the `default` feature
    #[structopt(long)]
    no_default_features: bool,

    /// Build only this package's library
    #[structopt(long)]
    lib: bool,

    /// Build only the specified binary
    #[structopt(long, value_name = "NAME")]
    bin: Option<String>,

    /// Build only the specified example
    #[structopt(long, value_name = "NAME")]
    example: Option<String>,

    /// Build only the specified test target
    #[structopt(long, value_name = "NAME")]
    test: Option<String>,

    /// Build only the specified bench target
    #[structopt(long, value_name = "NAME")]
    bench: Option<String>,

    /// Target triple which compiles will be for
    #[structopt(long, value_name = "TARGET")]
    target: Option<String>,

    /// Directory for all generated artifacts
    #[structopt(long, value_name = "DIRECTORY", parse(from_os_str))]
    target_dir: Option<PathBuf>,

    /// Path to Cargo.toml
    #[structopt(long, value_name = "PATH", parse(from_os_str))]
    manifest_path: Option<PathBuf>,

    /// Number of parallel jobs, defaults to # of CPUs
    #[structopt(short, long, value_name = "N")]
    jobs: Option<u64>,

    /// Coloring: auto, always, never
    #[structopt(long, value_name = "WHEN")]
    color: Option<String>,

    /// Require Cargo.lock and cache are up to date
    #[structopt(long)]
    frozen: bool,

    /// Require Cargo.lock is up to date
    #[structopt(long)]
    locked: bool,

    /// Unstable (nightly-only) flags to Cargo
    #[structopt(short = "Z", value_name = "FLAG")]
    unstable_flags: Vec<String>,

    /// Do not attempt to run rustfmt
    #[structopt(long)]
    ugly: bool,
}

fn main() {
    let result = cargo_expand_or_run_nightly();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

enum Error {
    Io(io::Error),
    Print(PrettyPrintError),
}

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

impl From<PrettyPrintError> for Error {
    fn from(error: PrettyPrintError) -> Self {
        Error::Print(error)
    }
}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Error::Io(error) => Display::fmt(error, formatter),
            Error::Print(error) => Display::fmt(error, formatter),
        }
    }
}

type Result<T> = std::result::Result<T, Error>;

fn cargo_expand_or_run_nightly() -> Result<i32> {
    const NO_RUN_NIGHTLY: &str = "CARGO_EXPAND_NO_RUN_NIGHTLY";

    let maybe_nightly = !definitely_not_nightly();
    if maybe_nightly || env::var_os(NO_RUN_NIGHTLY).is_some() {
        return cargo_expand();
    }

    let mut nightly = Command::new("cargo");
    nightly.arg("+nightly");
    nightly.arg("expand");

    let mut args = env::args_os().peekable();
    args.next().unwrap(); // cargo
    if args.peek().map_or(false, |arg| arg == "expand") {
        args.next().unwrap(); // expand
    }
    nightly.args(args);

    // Hopefully prevent infinite re-run loop.
    nightly.env(NO_RUN_NIGHTLY, "");

    let status = nightly.status()?;

    Ok(match status.code() {
        Some(code) => code,
        None => {
            if status.success() {
                0
            } else {
                1
            }
        }
    })
}

fn definitely_not_nightly() -> bool {
    let mut cmd = Command::new(cargo_binary());
    cmd.arg("--version");

    let output = match cmd.output() {
        Ok(output) => output,
        Err(_) => return false,
    };

    let version = match String::from_utf8(output.stdout) {
        Ok(version) => version,
        Err(_) => return false,
    };

    version.starts_with("cargo 1") && !version.contains("nightly")
}

fn cargo_binary() -> OsString {
    env::var_os("CARGO").unwrap_or_else(|| "cargo".to_owned().into())
}

fn cargo_expand() -> Result<i32> {
    let Opts::Expand(args) = Opts::from_args();

    let mut builder = tempfile::Builder::new();
    builder.prefix("cargo-expand");
    let outdir = builder.tempdir().expect("failed to create tmp file");
    let outfile_path = outdir.path().join("expanded");

    // Run cargo
    let mut cmd = Command::new(cargo_binary());
    apply_args(&mut cmd, &args, &outfile_path);
    let code = filter_err(&mut cmd, ignore_cargo_err)?;

    let mut content = fs::read_to_string(&outfile_path)?;
    if content.is_empty() {
        let _ = writeln!(
            &mut io::stderr(),
            "ERROR: rustc produced no expanded output"
        );
        return Ok(if code == 0 { 1 } else { code });
    }

    // Run rustfmt
    let which_rustfmt = match args.ugly {
        false => which("rustfmt"),
        true => None,
    };
    if let Some(fmt) = which_rustfmt {
        // Work around rustfmt not being able to parse paths containing $crate.
        // This placeholder should be the same width as $crate to preserve
        // alignments.
        const DOLLAR_CRATE_PLACEHOLDER: &str = "Ξcrate";
        content = content.replace("$crate", DOLLAR_CRATE_PLACEHOLDER);

        // Discard comments, which are misplaced by the compiler
        if let Ok(syntax_tree) = syn::parse_file(&content) {
            content = quote!(#syntax_tree).to_string();
        }
        fs::write(&outfile_path, content)?;

        // Ignore any errors.
        let _status = Command::new(fmt)
            .arg(&outfile_path)
            .stderr(Stdio::null())
            .status();

        content = fs::read_to_string(&outfile_path)?;
        content = content.replace(DOLLAR_CRATE_PLACEHOLDER, "$crate");
    }

    // Run pretty printer
    let do_color = match args.color.as_ref().map(String::as_str) {
        Some("always") => true,
        Some("never") => false,
        None | Some("auto") | Some(_) => atty::is(Stdout),
    };
    if do_color {
        if content.ends_with('\n') {
            // Pretty printer seems to print an extra trailing newline.
            content.truncate(content.len() - 1);
        }
        let printer = PrettyPrinter::default()
            .header(false)
            .grid(false)
            .line_numbers(false)
            .language("rust")
            .paging_mode(PagingMode::Never)
            .build()
            .unwrap();

        // Ignore any errors.
        let _ = printer.string(content);
    } else {
        let _ = write!(&mut io::stdout(), "{}", content);
    }

    Ok(0)
}

// Based on https://github.com/rsolomo/cargo-check
fn apply_args(cmd: &mut Command, args: &Args, outfile: &Path) {
    cmd.arg("rustc");
    cmd.arg("--profile=check");

    if let Some(features) = &args.features {
        cmd.arg("--features");
        cmd.arg(features);
    }

    if args.all_features {
        cmd.arg("--all-features");
    }

    if args.no_default_features {
        cmd.arg("--no-default-features");
    }

    if args.lib {
        cmd.arg("--lib");
    }

    if let Some(bin) = &args.bin {
        cmd.arg("--bin");
        cmd.arg(bin);
    }

    if let Some(example) = &args.example {
        cmd.arg("--example");
        cmd.arg(example);
    }

    if let Some(test) = &args.test {
        cmd.arg("--test");
        cmd.arg(test);
    }

    if let Some(bench) = &args.bench {
        cmd.arg("--bench");
        cmd.arg(bench);
    }

    if let Some(target) = &args.target {
        cmd.arg("--target");
        cmd.arg(target);
    }

    if let Some(target_dir) = &args.target_dir {
        cmd.arg("--target-dir");
        cmd.arg(target_dir);
    }

    if let Some(manifest_path) = &args.manifest_path {
        cmd.arg("--manifest-path");
        cmd.arg(manifest_path);
    }

    if let Some(jobs) = args.jobs {
        cmd.arg("--jobs");
        cmd.arg(jobs.to_string());
    }

    cmd.arg("--color");
    if let Some(color) = &args.color {
        cmd.arg(color);
    } else {
        cmd.arg(if atty::is(Stderr) { "always" } else { "never" });
    }

    if args.frozen {
        cmd.arg("--frozen");
    }

    if args.locked {
        cmd.arg("--locked");
    }

    for unstable_flag in &args.unstable_flags {
        cmd.arg("-Z");
        cmd.arg(unstable_flag);
    }

    cmd.arg("--");
    cmd.arg("-o");
    cmd.arg(outfile);
    cmd.arg("-Zunstable-options");
    cmd.arg("--pretty=expanded");
}

fn which(cmd: &str) -> Option<OsString> {
    if env::args_os().any(|arg| arg == *"--help") {
        return None;
    }

    if let Some(which) = env::var_os(&cmd.to_uppercase()) {
        return if which.is_empty() { None } else { Some(which) };
    }

    let spawn = Command::new(cmd)
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .spawn();
    let mut child = match spawn {
        Ok(child) => child,
        Err(_) => {
            return None;
        }
    };

    let exit = match child.wait() {
        Ok(exit) => exit,
        Err(_) => {
            return None;
        }
    };

    if exit.success() {
        Some(cmd.into())
    } else {
        None
    }
}

fn filter_err(cmd: &mut Command, ignore: fn(&str) -> bool) -> io::Result<i32> {
    let mut child = cmd.stderr(Stdio::piped()).spawn()?;
    let mut stderr = io::BufReader::new(child.stderr.take().unwrap());
    let mut line = String::new();
    while let Ok(n) = stderr.read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    let code = child.wait()?.code().unwrap_or(1);
    Ok(code)
}

fn ignore_cargo_err(line: &str) -> bool {
    if line.trim().is_empty() {
        return true;
    }

    let blacklist = [
        "ignoring specified output filename because multiple outputs were \
         requested",
        "ignoring specified output filename for 'link' output because multiple \
         outputs were requested",
        "ignoring --out-dir flag due to -o flag",
        "ignoring -C extra-filename flag due to -o flag",
        "due to multiple output types requested, the explicitly specified \
         output file name will be adapted for each output type",
    ];
    for s in &blacklist {
        if line.contains(s) {
            return true;
        }
    }

    false
}
<|endoftext|>


<commit_before>#[macro_use] extern crate enum_primitive;
extern crate num;
#[macro_use] extern crate bitflags;

mod cpu;
mod memory;
mod instructions;

use std::env;
use std::fs;
use std::io::Read;
use std::path::Path;

fn read_bin<P: AsRef<Path>>(path: P) -> Vec<u8> {
    let mut file = fs::File::open(path).unwrap();
    let mut file_buf = Vec::new();
    file.read_to_end(&mut file_buf).unwrap();
    file_buf
}

fn main() {
    let rom0_file_name = env::args().nth(1).unwrap();
    let rom1_file_name = env::args().nth(2).unwrap();

    let rom0 = read_bin(rom0_file_name);
    let rom1 = read_bin(rom1_file_name);

    let mut memory = memory::Memory::new(rom0, rom1);

    let mut cpu = cpu::Cpu::new(memory);

    cpu.run();
}
<commit_msg>Remove useless mut qualifier<commit_after>#[macro_use] extern crate enum_primitive;
extern crate num;
#[macro_use] extern crate bitflags;

mod cpu;
mod memory;
mod instructions;

use std::env;
use std::fs;
use std::io::Read;
use std::path::Path;

fn read_bin<P: AsRef<Path>>(path: P) -> Vec<u8> {
    let mut file = fs::File::open(path).unwrap();
    let mut file_buf = Vec::new();
    file.read_to_end(&mut file_buf).unwrap();
    file_buf
}

fn main() {
    let rom0_file_name = env::args().nth(1).unwrap();
    let rom1_file_name = env::args().nth(2).unwrap();

    let rom0 = read_bin(rom0_file_name);
    let rom1 = read_bin(rom1_file_name);

    let memory = memory::Memory::new(rom0, rom1);

    let mut cpu = cpu::Cpu::new(memory);

    cpu.run();
}
<|endoftext|>


<commit_before>#![feature(globs)]

extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate "rustc-serialize" as rustc_serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

fn main() {
    // create data dir
    let home_dir = ::utils::get_home_dir();
    let data_dir = home_dir.join(::utils::DATA_DIR);
    if !data_dir.exists() {
        match fs::mkdir(&data_dir, ::std::io::USER_DIR) {
            Ok(_) => {
                for res in ::utils::DATA_CONTENT.iter() {
                    let res_path = data_dir.join_many(res.path);
                    ::std::io::fs::mkdir_recursive(&res_path.dir_path(), ::std::io::USER_DIR).ok();
                    ::std::io::File::create(&res_path).write(res.data.as_bytes()).ok();
                }
                println!("Created data dir at {}", data_dir.as_str().unwrap());
            },
            Err(e) => { println!("Error creating data dir: {}", e) }
        }
    }

    // set $VIM to the data dir if it isn't already set
    if ::std::os::getenv("VIM").is_none() {
        ::std::os::setenv("VIM", data_dir.as_str().unwrap());
    }

    // create config file
    let config_file = home_dir.join(::utils::CONFIG_FILE);
    if !config_file.exists() {
        match ::std::io::File::create(&config_file).write(::utils::CONFIG_CONTENT.as_bytes()) {
            Ok(_) => { println!("Created config file at {}", config_file.as_str().unwrap()) },
            Err(e) => { println!("Error creating config file: {}", e) }
        }
    }

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int, ..2] = [0, ..2];
    let mut gui_from_nvim : [ffi::c_int, ..2] = [0, ..2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        ::std::thread::Thread::spawn(move || {
            // send attach_ui message
            {
                let mut arr = neovim::Array::new();
                arr.add_integer(80);
                arr.add_integer(24);
                let msg = neovim::serialize_request(1, "attach_ui", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
            }

            // listen for messages
            let mut buf : [ffi::c_uchar, ..100] = [0, ..100];
            unsafe {
                loop {
                    let n = ffi::read(gui_from_nvim[0], buf.as_mut_ptr() as *mut ffi::c_void, 100);
                    if n < 0 {
                        break;
                    } else if n > 0 {
                        let msg = ::std::string::String::from_raw_buf_len(buf.as_ptr(), n as uint);
                        println!("Received: {}", msg);
                    }
                }
            }
        }).detach();

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // start nvim
        let mut args = ::std::os::args().clone();
        args.push_all(&["-u".to_string(), config_file.as_str().unwrap().to_string()]);
        neovim::run_with_fds(args, nvim_from_gui[0], gui_from_nvim[1]);
    }
}
<commit_msg>Deserialize responses<commit_after>#![feature(globs)]

extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate "rustc-serialize" as rustc_serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

fn main() {
    // create data dir
    let home_dir = ::utils::get_home_dir();
    let data_dir = home_dir.join(::utils::DATA_DIR);
    if !data_dir.exists() {
        match fs::mkdir(&data_dir, ::std::io::USER_DIR) {
            Ok(_) => {
                for res in ::utils::DATA_CONTENT.iter() {
                    let res_path = data_dir.join_many(res.path);
                    ::std::io::fs::mkdir_recursive(&res_path.dir_path(), ::std::io::USER_DIR).ok();
                    ::std::io::File::create(&res_path).write(res.data.as_bytes()).ok();
                }
                println!("Created data dir at {}", data_dir.as_str().unwrap());
            },
            Err(e) => { println!("Error creating data dir: {}", e) }
        }
    }

    // set $VIM to the data dir if it isn't already set
    if ::std::os::getenv("VIM").is_none() {
        ::std::os::setenv("VIM", data_dir.as_str().unwrap());
    }

    // create config file
    let config_file = home_dir.join(::utils::CONFIG_FILE);
    if !config_file.exists() {
        match ::std::io::File::create(&config_file).write(::utils::CONFIG_CONTENT.as_bytes()) {
            Ok(_) => { println!("Created config file at {}", config_file.as_str().unwrap()) },
            Err(e) => { println!("Error creating config file: {}", e) }
        }
    }

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int, ..2] = [0, ..2];
    let mut gui_from_nvim : [ffi::c_int, ..2] = [0, ..2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        ::std::thread::Thread::spawn(move || {
            // send attach_ui message
            {
                let mut arr = neovim::Array::new();
                arr.add_integer(80);
                arr.add_integer(24);
                let msg = neovim::serialize_message(1, "attach_ui", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
            }

            // listen for messages
            let mut buf : [ffi::c_uchar, ..100] = [0, ..100];
            unsafe {
                loop {
                    let n = ffi::read(gui_from_nvim[0], buf.as_mut_ptr() as *mut ffi::c_void, 100);
                    if n < 0 {
                        break;
                    } else if n > 0 {
                        let msg = ::std::string::String::from_raw_buf_len(buf.as_ptr(), n as uint);
                        let arr = neovim::deserialize_message(&msg);
                        println!("Received array of length: {}", arr.len());
                    }
                }
            }
        }).detach();

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // start nvim
        let mut args = ::std::os::args().clone();
        args.push_all(&["-u".to_string(), config_file.as_str().unwrap().to_string()]);
        neovim::run_with_fds(args, nvim_from_gui[0], gui_from_nvim[1]);
    }
}
<|endoftext|>


<commit_before>// Genetic Algorithm for convergence to a given string
// Author: Duncan Dean
extern crate rand;
use rand::Rng;

fn rand_string(size: u32) -> String {
    let mut rand_string = String::with_capacity(size as usize);
    for _ in 0..size {
        rand_string = rand_string + &(rand::thread_rng().gen_range(32, 123) as u8 as char).to_string();
    }
    rand_string
}

fn crossover(chrome1: Chromosome, chrome2: Chromosome, cross_prob: f32, solution: &str) -> Chromosome {
    if rand::thread_rng().gen_range::<f32>(0.0, 1.0) <= cross_prob {
        let code_len = chrome1.code.len();
        let rand_index = rand::thread_rng().gen_range(0, code_len);
        let first_half = &chrome1.code[0..rand_index];
        let second_half = &chrome2.code[rand_index..code_len];
        let new_code = first_half.to_string() + second_half;
        Chromosome {
            code: new_code.to_string(),
            cost_score: cost_function(&new_code, solution),
            solution: solution.to_string(),
        }
    } else if chrome1.cost_score < chrome2.cost_score {
        chrome1.clone()
    } else {
        chrome2.clone()
    }
}

fn cost_function(code: &str, solution: &str) -> u32 {
    let chars: Vec<char> = solution.to_string().chars().collect();
    let code_chars: Vec<char> = code.to_string().chars().collect();
    let mut cost: u32 = 0;
    for i in 0..chars.len() {
        cost += ((chars[i] as u8 as i32) - (code_chars[i] as u8 as i32)).abs() as u32;
    }
    cost
}

#[derive(Clone)]
struct Chromosome {
    code: String,
    cost_score: u32,
    solution: String,
}

impl Chromosome {
    fn new(solution: String) -> Chromosome {
        let random_string = &rand_string(solution.len() as u32);
        Chromosome {
            code: random_string.to_string(),
            cost_score: cost_function(random_string, &solution),
            solution: solution,
        }
    }

    fn mutate(&mut self, mut_prob:f64) -> Chromosome {
        if rand::thread_rng().gen_range::<f64>(0.0, 1.0) <= mut_prob {
            let rand_index = rand::thread_rng().gen_range(0, self.code.len());
            let mut new_code_vec: Vec<char> = self.code.chars().collect();
            new_code_vec[rand_index] = rand::thread_rng().gen_range(32, 123) as u8 as char;
            self.code = new_code_vec.iter().fold("".to_string(), |acc, s| acc + &s.to_string());
            self.cost_score = cost_function(&self.code, &self.solution);
            self.clone()

        } else {
            self.clone()
        }

    }

}

fn main() {
    let solution = "The quick brown fox jumps over the lazy dog.".to_string();
    let pop_size = 30; // Must be greater than 1
    let max_pop = pop_size * 5;
    let mut_prob = 0.4;
    let kill_constant = 0.45;
    let cross_prob = 0.6;
    let mut population = Vec::new();

    // Initialize population
    for i in 0..pop_size {
        population.push(Chromosome::new(solution.to_string()));
        println!("{}, cost: {}", population[i].code, population[i].cost_score);
    }

    population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
    let mut winner: Chromosome = population[0].clone();
    // Step generation
    let mut j = 1;
    while  winner.cost_score != 0 {

        // Mutations
        for i in 0..population.len() {
            population[i] = population[i].mutate(mut_prob);
        }

        // Kill the weaklings
        population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
        for _ in 0..((( population.len() as f32)*kill_constant) as u32) {
            population.pop();
        }

        // Crossovers
        if population.len() < max_pop {
            for i in 0..(population.len() - 2) {
                let chrome1 = population[i].clone();
                let chrome2 = population[i+1].clone();
                population.push(crossover(chrome1, chrome2, cross_prob, &solution));
            }
        }

        population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
        winner = population[0].clone();
        println!("\nGeneration: {}\nString: {}\nCost: {}\n", j, winner.code, winner.cost_score);

        j += 1;

    }

}
<commit_msg>Simplified the rand_string and Chromosome::new functions<commit_after>// Genetic Algorithm for convergence to a given string
// Author: Duncan Dean
extern crate rand;
use rand::Rng;

fn rand_string(size: usize) -> String {
    return rand::thread_rng().gen_ascii_chars().take(size).collect();
}

fn crossover(chrome1: Chromosome, chrome2: Chromosome, cross_prob: f32, solution: &str) -> Chromosome {
    if rand::thread_rng().gen_range::<f32>(0.0, 1.0) <= cross_prob {
        let code_len = chrome1.code.len();
        let rand_index = rand::thread_rng().gen_range(0, code_len);
        let first_half = &chrome1.code[0..rand_index];
        let second_half = &chrome2.code[rand_index..code_len];
        let new_code = first_half.to_string() + second_half;
        Chromosome {
            code: new_code.to_string(),
            cost_score: cost_function(&new_code, solution),
            solution: solution.to_string(),
        }
    } else if chrome1.cost_score < chrome2.cost_score {
        chrome1.clone()
    } else {
        chrome2.clone()
    }
}

fn cost_function(code: &str, solution: &str) -> u32 {
    let chars: Vec<char> = solution.to_string().chars().collect();
    let code_chars: Vec<char> = code.to_string().chars().collect();
    let mut cost: u32 = 0;
    for i in 0..chars.len() {
        cost += ((chars[i] as u8 as i32) - (code_chars[i] as u8 as i32)).abs() as u32;
    }
    cost
}

#[derive(Clone)]
struct Chromosome {
    code: String,
    cost_score: u32,
    solution: String,
}

impl Chromosome {
    fn new(solution: String) -> Chromosome {
        let random_string = rand_string(solution.len());
        Chromosome {
            code: random_string.clone(),
            cost_score: cost_function(&random_string, &solution),
            solution: solution,
        }
    }

    fn mutate(&mut self, mut_prob:f64) -> Chromosome {
        if rand::thread_rng().gen_range::<f64>(0.0, 1.0) <= mut_prob {
            let rand_index = rand::thread_rng().gen_range(0, self.code.len());
            let mut new_code_vec: Vec<char> = self.code.chars().collect();
            new_code_vec[rand_index] = rand::thread_rng().gen_range(32, 123) as u8 as char;
            self.code = new_code_vec.iter().fold("".to_string(), |acc, s| acc + &s.to_string());
            self.cost_score = cost_function(&self.code, &self.solution);
            self.clone()

        } else {
            self.clone()
        }

    }

}

fn main() {
    let solution = "The quick brown fox jumps over the lazy dog.".to_string();
    let pop_size = 30; // Must be greater than 1
    let max_pop = pop_size * 5;
    let mut_prob = 0.4;
    let kill_constant = 0.45;
    let cross_prob = 0.6;
    let mut population = Vec::new();

    // Initialize population
    for i in 0..pop_size {
        population.push(Chromosome::new(solution.to_string()));
        println!("{}, cost: {}", population[i].code, population[i].cost_score);
    }

    population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
    let mut winner: Chromosome = population[0].clone();
    // Step generation
    let mut j = 1;
    while  winner.cost_score != 0 {

        // Mutations
        for i in 0..population.len() {
            population[i] = population[i].mutate(mut_prob);
        }

        // Kill the weaklings
        population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
        for _ in 0..((( population.len() as f32)*kill_constant) as u32) {
            population.pop();
        }

        // Crossovers
        if population.len() < max_pop {
            for i in 0..(population.len() - 2) {
                let chrome1 = population[i].clone();
                let chrome2 = population[i+1].clone();
                population.push(crossover(chrome1, chrome2, cross_prob, &solution));
            }
        }

        population.sort_by(|ref a, ref b| a.cost_score.cmp(&b.cost_score));
        winner = population[0].clone();
        println!("\nGeneration: {}\nString: {}\nCost: {}\n", j, winner.code, winner.cost_score);

        j += 1;

    }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate toml;

use std::collections::BTreeMap;

use std::env;
use std::fs::File;
use std::io::prelude::*;

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String,String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?
        .read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or(Box::new(std::io::Error::last_os_error()))
}

fn main() {
    let program_name = std::env::args().nth(0).unwrap_or("resh".to_string());

    let command_alias = match std::env::args().nth(1) {
        Some(alias) => alias,
        None => { die!("Usage: {} <command alias>", program_name) }
    };

    let config_file = env::var("RESH_CONFIG")
        .unwrap_or_else(|_| {"/etc/resh.toml".to_string()});

    let config: Config = read_config(&config_file).
        unwrap_or_else(|e| { die!("Failed to read {}: {}", config_file, e); });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => { die!("Undefined command alias: {}", command_alias) },
    };

    let exitcode = run_command(&full_command)
        .unwrap_or(1);

    std::process::exit(exitcode);
}
<commit_msg>Refactor<commit_after>#[macro_use]
extern crate serde_derive;
extern crate toml;

use std::io::prelude::*;
use std::fs::File;
use std::collections::BTreeMap;

macro_rules! die(
    ($($arg:tt)*) => { {
        writeln!(std::io::stderr(), $($arg)*)
            .expect("Failed to print to stderr");
        std::process::exit(1);
    } }
);

#[derive(Deserialize)]
struct Config {
    commands: BTreeMap<String,String>,
}

fn read_config<P: AsRef<std::path::Path>>(path: P) -> Result<Config, Box<std::error::Error>> {
    let mut contents = String::new();

    File::open(path)?
        .read_to_string(&mut contents)?;

    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

fn run_command(command: &str) -> Result<i32, Box<std::error::Error>> {
    let mut child = std::process::Command::new("/bin/sh")
        .arg("-c")
        .arg(command)
        .spawn()?;

    child
        .wait()?
        .code()
        .ok_or_else(|| std::io::Error::last_os_error().into())
}

fn main() {
    let program_name = std::env::args().nth(0)
        .unwrap_or_else(|| "resh".to_string());

    let command_alias = match std::env::args().nth(1) {
        Some(alias) => alias,
        None => { die!("Usage: {} <command alias>", program_name) }
    };

    let config_file = std::env::var("RESH_CONFIG")
        .unwrap_or_else(|_| {"/etc/resh.toml".to_string()});

    let config: Config = read_config(&config_file).
        unwrap_or_else(|e| { die!("Failed to read {}: {}", config_file, e); });

    let full_command = match config.commands.get(&command_alias) {
        Some(cmd) => cmd,
        None => { die!("Undefined command alias: {}", command_alias) },
    };

    let exitcode = run_command(full_command)
        .unwrap_or(1);

    std::process::exit(exitcode);
}
<|endoftext|>


<commit_before>extern crate regex;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;
extern crate url;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use irc::client::server::NetIrcServer;
use xdg_basedir::*;
use std::io::Read;
use url::Url;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    let urlregex = Regex::new(r"https?://\S+\.[:alpha:]{2,}\S+").unwrap();

    if let Some(x) = urlregex.captures(post) {
        if let Ok(parsedurl) = Url::parse(x.at(0).unwrap()) {
            if parsedurl.domain().unwrap().ends_with("github.com") {
                let urlpath = parsedurl.path().unwrap();
                if (urlpath.len() == 4) &&
                    ((urlpath[2] == "issues") || urlpath[2] == "pull") {
                        return github::get_display_text(&urlpath[0],
                                                        &urlpath[1],
                                                        &urlpath[3],
                                                        false).ok();
                    }
            }
        }
        if let Ok(mut resp) = client.get(x.at(0).unwrap()).send() {
            let mut body = String::new();
            resp.read_to_string(&mut body).unwrap();
            let titleregex = Regex::new(r"<title>(.+)</title>").unwrap();
            if let Some(cap) = titleregex.captures(&body) {
                return Some(format!("Title: {}", cap.at(1).unwrap()));
            }
        }
    }

    let issueregex = Regex::new(r"([^ ()]+)/([^ ()]+)#(\d+)").unwrap();

    if let Some(cap) = issueregex.captures(post) {
        let user = cap.at(1).unwrap();
        let repo = cap.at(2).unwrap();
        let number = cap.at(3).unwrap();
        return github::get_display_text(user, repo, number, true).ok();
    }
    None
}

fn handle_message(server: &NetIrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => server.send_join(parameter).unwrap(),
            "part" => server.send(
                Command::PART(parameter.to_string(), None)
                ).unwrap(),
            "quit" => server.send_quit("").unwrap(),
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_privmsg(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.into_string());
        if message.command == "PRIVMSG" {
            let from = message.get_source_nickname().unwrap().to_owned();
            let to = &message.args[0];
            let content = message.suffix.unwrap();
            handle_message(&server, &from, to, &content);
        }
    }
}
<commit_msg>Remove some unnecessary parentheses<commit_after>extern crate regex;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;
extern crate url;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use irc::client::server::NetIrcServer;
use xdg_basedir::*;
use std::io::Read;
use url::Url;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    let urlregex = Regex::new(r"https?://\S+\.[:alpha:]{2,}\S+").unwrap();

    if let Some(x) = urlregex.captures(post) {
        if let Ok(parsedurl) = Url::parse(x.at(0).unwrap()) {
            if parsedurl.domain().unwrap().ends_with("github.com") {
                let urlpath = parsedurl.path().unwrap();
                if urlpath.len() == 4 &&
                    (urlpath[2] == "issues" || urlpath[2] == "pull") {
                        return github::get_display_text(&urlpath[0],
                                                        &urlpath[1],
                                                        &urlpath[3],
                                                        false).ok();
                    }
            }
        }
        if let Ok(mut resp) = client.get(x.at(0).unwrap()).send() {
            let mut body = String::new();
            resp.read_to_string(&mut body).unwrap();
            let titleregex = Regex::new(r"<title>(.+)</title>").unwrap();
            if let Some(cap) = titleregex.captures(&body) {
                return Some(format!("Title: {}", cap.at(1).unwrap()));
            }
        }
    }

    let issueregex = Regex::new(r"([^ ()]+)/([^ ()]+)#(\d+)").unwrap();

    if let Some(cap) = issueregex.captures(post) {
        let user = cap.at(1).unwrap();
        let repo = cap.at(2).unwrap();
        let number = cap.at(3).unwrap();
        return github::get_display_text(user, repo, number, true).ok();
    }
    None
}

fn handle_message(server: &NetIrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => server.send_join(parameter).unwrap(),
            "part" => server.send(
                Command::PART(parameter.to_string(), None)
                ).unwrap(),
            "quit" => server.send_quit("").unwrap(),
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_privmsg(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.into_string());
        if message.command == "PRIVMSG" {
            let from = message.get_source_nickname().unwrap().to_owned();
            let to = &message.args[0];
            let content = message.suffix.unwrap();
            handle_message(&server, &from, to, &content);
        }
    }
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate izzet;
extern crate toml;

use getopts::{Matches, Options};
use izzet::error::{Error, Result};
use izzet::{gen, post, server};
use izzet::config::Config;
use std::env;
use std::fs::DirBuilder;
use std::path::PathBuf;
use std::process;
use std::io::Write;

const PROG_NAME: &str = env!("CARGO_PKG_NAME");

fn create_site(m: &Matches) -> Result<()> {
    let dir = m.free.get(1)
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir()?);

    if !PathBuf::from(&dir).exists() {
        DirBuilder::new()
            .recursive(false)
            .create(&dir)
            .map_err(|e| format!("fail to create {:?}: {}", &dir, e))?;
    }

    let opener = izzet::get_opener(m.opt_present("force"));

    // create a default configuration file
    let config: Config = Config::default();
    let config = toml::to_string(&config)?;
    opener.open(dir.join(izzet::CONFIG_FILE))
          .and_then(|mut f| f.write(config.as_bytes()))
          .map_err(|e| format!("fail to create {}: {}", izzet::CONFIG_FILE, e))?;

    // create other files
    // XXX may need to do more things here later
    for filename in izzet::SITE_FILES {
        opener.open(dir.join(filename))
              .map_err(|e| format!("fail to create {}: {}", filename, e))?;
    }

    // create directories
    for dirname in izzet::SITE_DIRS {
        DirBuilder::new()
            .recursive(m.opt_present("force"))
            .create(dir.join(dirname))
            .map_err(|e| format!("fail to create {}: {}", dirname, e))?;
    }

    // create default templates
    for &(filename, html) in izzet::SITE_TEMPLATES {
        let mut file = opener.open(dir.join(izzet::THEME_DIR)
                                      .join(filename))
                             .map_err(|e| format!("fail to create {}: {}", filename, e))?;
        file.write(html)?;
    }

    Ok(())
}

fn usage(opts: &Options) {
    println!("{}", opts.usage(&format!("Usage: {} <options> <args>", PROG_NAME)));
}

fn run(m: Matches, action: &str) -> Result<()> {
    // Note that now we have no configuration file yet
    if action == "new" {
        create_site(&m)?;
        return Ok(());
    }

    // Load config file as a basis which may be overwritten
    // later by the command-line options.
    let mut config = Config::from_file(m.opt_str("config")
                                        .map(|p| PathBuf::from(p))
                                        .unwrap_or(env::current_dir()?)
                                        .join(izzet::CONFIG_FILE))?;

    config.force = Some(m.opt_present("force"));
    if let None = config.title {
        config.title = Some("Default title".to_string());
    }

    match action {
        "article" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the article".to_string()))?;
            post::create_post(link.to_string(), config, true)?;
        },

        "page" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the page".to_string()))?;
            post::create_post(link.clone(), config, false)?;
        },

        "gen" => {
            config.in_dir = m.opt_str("input");
            config.out_dir = m.opt_str("output");
            gen::generate(config)?;
        },

        "server" => {
            let dir = m.free.get(1)
                .map(PathBuf::from)
                .unwrap_or(env::current_dir()?);
            config.port = m.opt_str("listen")
                .and_then(|s| s.parse::<u16>().ok());
            server::forever(dir, config)?;
        },

        _ => {
            eprintln!("unknown action {}", action);
            process::exit(1);
        }
    }

    Ok(())
}

fn main() {
    let mut opts = Options::new();

    // One of these flags should be specified
    opts.optflag("n", "new", "Initialize an empty site at the given location.");
    opts.optflag("a", "article", "Create an article with the given permalink.");
    opts.optflag("p", "page", "Create a page with the given permalink.");
    opts.optflag("g", "gen", "Generate site, can be used along with -i and -o \
                              to specify the input and output location.");
    opts.optflag("s", "server", "Start a local server to preview the generated site \
                                 specified by a directory.");
    opts.optflag("f", "force", "Overwrite existing files when creating articles, \
                                generating site output files, etc.");

    opts.optopt("c", "config", "Search for configuration file at the specified \
                                directory. By default the configuration file will be \
                                looked for under the current directory.", "CONFIG");
    opts.optopt("i", "input", "Input site directory. Read input files from current \
                              directory by default.", "INPUT");
    opts.optopt("o", "output", "Output site directory. Write to current directory \
                               by default.", "OUTPUT");
    opts.optopt("l", "listen", "Port on which the local server will listen.", "PORT");

    opts.optflag("h", "help", "Show this help message.");
    opts.optflag("V", "version", "Display version information.");

    let matches = match opts.parse(env::args()) {
        Ok(m) => m,
        Err(e) => {
            eprintln!("{}\ntry `{1} -h` or `{1} --help` to see the help.", e, PROG_NAME);
            process::exit(1);
        },
    };

    if matches.opt_present("help") {
        usage(&opts);
        return;
    }

    if matches.opt_present("version") {
        println!("{} {}", PROG_NAME, env!("CARGO_PKG_VERSION"));
        return;
    }

    let mutex_opts = ["new", "article", "gen", "page", "server"];
    let action = mutex_opts
        .iter()
        .filter(|o| matches.opt_present(o))
        .collect::<Vec<_>>();

    match action.len() {
        0 => {
            println!("nothing to do");
            return;
        },
        1 => {
            if let Err(e) = run(matches, action.first().unwrap()) {
                eprintln!("{}", e);
                process::exit(1);
            }
        },
        _ => {
            eprintln!("only one of `-n', `-a', `-p', `-s' and `-g' could be specified");
            process::exit(1);
        }
    }
}
<commit_msg>Only set -f flag when it's given on command line<commit_after>extern crate getopts;
extern crate izzet;
extern crate toml;

use getopts::{Matches, Options};
use izzet::error::{Error, Result};
use izzet::{gen, post, server};
use izzet::config::Config;
use std::env;
use std::fs::DirBuilder;
use std::path::PathBuf;
use std::process;
use std::io::Write;

const PROG_NAME: &str = env!("CARGO_PKG_NAME");

fn create_site(m: &Matches) -> Result<()> {
    let dir = m.free.get(1)
        .map(|s| PathBuf::from(s))
        .unwrap_or(env::current_dir()?);

    if !PathBuf::from(&dir).exists() {
        DirBuilder::new()
            .recursive(false)
            .create(&dir)
            .map_err(|e| format!("fail to create {:?}: {}", &dir, e))?;
    }

    let opener = izzet::get_opener(m.opt_present("force"));

    // create a default configuration file
    let config: Config = Config::default();
    let config = toml::to_string(&config)?;
    opener.open(dir.join(izzet::CONFIG_FILE))
          .and_then(|mut f| f.write(config.as_bytes()))
          .map_err(|e| format!("fail to create {}: {}", izzet::CONFIG_FILE, e))?;

    // create other files
    // XXX may need to do more things here later
    for filename in izzet::SITE_FILES {
        opener.open(dir.join(filename))
              .map_err(|e| format!("fail to create {}: {}", filename, e))?;
    }

    // create directories
    for dirname in izzet::SITE_DIRS {
        DirBuilder::new()
            .recursive(m.opt_present("force"))
            .create(dir.join(dirname))
            .map_err(|e| format!("fail to create {}: {}", dirname, e))?;
    }

    // create default templates
    for &(filename, html) in izzet::SITE_TEMPLATES {
        let mut file = opener.open(dir.join(izzet::THEME_DIR)
                                      .join(filename))
                             .map_err(|e| format!("fail to create {}: {}", filename, e))?;
        file.write(html)?;
    }

    Ok(())
}

fn usage(opts: &Options) {
    println!("{}", opts.usage(&format!("Usage: {} <options> <args>", PROG_NAME)));
}

fn run(m: Matches, action: &str) -> Result<()> {
    // Note that now we have no configuration file yet
    if action == "new" {
        create_site(&m)?;
        return Ok(());
    }

    // Load config file as a basis which may be overwritten
    // later by the command-line options.
    let mut config = Config::from_file(m.opt_str("config")
                                        .map(|p| PathBuf::from(p))
                                        .unwrap_or(env::current_dir()?)
                                        .join(izzet::CONFIG_FILE))?;

    if m.opt_present("force") {
        config.force = Some(true)
    }
    if let None = config.title {
        config.title = Some("Default title".to_string());
    }

    match action {
        "article" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the article".to_string()))?;
            post::create_post(link.to_string(), config, true)?;
        },

        "page" => {
            let link = m.free.get(1)
                .ok_or(Error::new("need the link of the page".to_string()))?;
            post::create_post(link.clone(), config, false)?;
        },

        "gen" => {
            config.in_dir = m.opt_str("input");
            config.out_dir = m.opt_str("output");
            gen::generate(config)?;
        },

        "server" => {
            let dir = m.free.get(1)
                .map(PathBuf::from)
                .unwrap_or(env::current_dir()?);
            config.port = m.opt_str("listen")
                .and_then(|s| s.parse::<u16>().ok());
            server::forever(dir, config)?;
        },

        _ => {
            eprintln!("unknown action {}", action);
            process::exit(1);
        }
    }

    Ok(())
}

fn main() {
    let mut opts = Options::new();

    // One of these flags should be specified
    opts.optflag("n", "new", "Initialize an empty site at the given location.");
    opts.optflag("a", "article", "Create an article with the given permalink.");
    opts.optflag("p", "page", "Create a page with the given permalink.");
    opts.optflag("g", "gen", "Generate site, can be used along with -i and -o \
                              to specify the input and output location.");
    opts.optflag("s", "server", "Start a local server to preview the generated site \
                                 specified by a directory.");
    opts.optflag("f", "force", "Overwrite existing files when creating articles, \
                                generating site output files, etc.");

    opts.optopt("c", "config", "Search for configuration file at the specified \
                                directory. By default the configuration file will be \
                                looked for under the current directory.", "CONFIG");
    opts.optopt("i", "input", "Input site directory. Read input files from current \
                              directory by default.", "INPUT");
    opts.optopt("o", "output", "Output site directory. Write to current directory \
                               by default.", "OUTPUT");
    opts.optopt("l", "listen", "Port on which the local server will listen.", "PORT");

    opts.optflag("h", "help", "Show this help message.");
    opts.optflag("V", "version", "Display version information.");

    let matches = match opts.parse(env::args()) {
        Ok(m) => m,
        Err(e) => {
            eprintln!("{}\ntry `{1} -h` or `{1} --help` to see the help.", e, PROG_NAME);
            process::exit(1);
        },
    };

    if matches.opt_present("help") {
        usage(&opts);
        return;
    }

    if matches.opt_present("version") {
        println!("{} {}", PROG_NAME, env!("CARGO_PKG_VERSION"));
        return;
    }

    let mutex_opts = ["new", "article", "gen", "page", "server"];
    let action = mutex_opts
        .iter()
        .filter(|o| matches.opt_present(o))
        .collect::<Vec<_>>();

    match action.len() {
        0 => {
            println!("nothing to do");
            return;
        },
        1 => {
            if let Err(e) = run(matches, action.first().unwrap()) {
                eprintln!("{}", e);
                process::exit(1);
            }
        },
        _ => {
            eprintln!("only one of `-n', `-a', `-p', `-s' and `-g' could be specified");
            process::exit(1);
        }
    }
}
<|endoftext|>