<commit_before>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alex Lyon <arcterus@mail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) tstr sigstr cmdname setpgid

#[macro_use]
extern crate uucore;

extern crate clap;

use clap::{App, AppSettings, Arg};
use std::io::ErrorKind;
use std::process::{Command, Stdio};
use std::time::Duration;
use uucore::process::ChildExt;
use uucore::signals::signal_by_name_or_value;
use uucore::InvalidEncodingHandling;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION.";

fn get_usage() -> String {
    format!("{0} [OPTION]... [FILE]...", executable!())
}

const ERR_EXIT_STATUS: i32 = 125;

pub mod options {
    pub static FOREGROUND: &str = "foreground";
    pub static KILL_AFTER: &str = "kill-after";
    pub static SIGNAL: &str = "signal";
    pub static VERSION: &str = "version";
    pub static PRESERVE_STATUS: &str = "preserve-status";

    // Positional args.
    pub static DURATION: &str = "duration";
    pub static COMMAND: &str = "command";
    pub static ARGS: &str = "args";
}

struct Config {
    foreground: bool,
    kill_after: Duration,
    signal: usize,
    duration: Duration,
    preserve_status: bool,

    command: String,
    command_args: Vec<String>,
}

impl Config {
    fn from(options: clap::ArgMatches) -> Config {
        let signal = match options.value_of(options::SIGNAL) {
            Some(signal_) => {
                let signal_result = signal_by_name_or_value(&signal_);
                match signal_result {
                    None => {
                        unreachable!("invalid signal '{}'", signal_);
                    }
                    Some(signal_value) => signal_value,
                }
            }
            _ => uucore::signals::signal_by_name_or_value("TERM").unwrap(),
        };

        let kill_after: Duration = match options.value_of(options::KILL_AFTER) {
            Some(time) => uucore::parse_time::from_str(&time).unwrap(),
            None => Duration::new(0, 0),
        };

        let duration: Duration =
            uucore::parse_time::from_str(options.value_of(options::DURATION).unwrap()).unwrap();

        let preserve_status: bool = options.is_present(options::PRESERVE_STATUS);
        let foreground = options.is_present(options::FOREGROUND);

        let command: String = options.value_of(options::COMMAND).unwrap().to_string();

        let command_args: Vec<String> = match options.values_of(options::ARGS) {
            Some(values) => values.map(|x| x.to_owned()).collect(),
            None => vec![],
        };

        Config {
            foreground,
            kill_after,
            signal,
            duration,
            preserve_status,
            command,
            command_args,
        }
    }
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    let usage = get_usage();

    let app = App::new("timeout")
        .version(VERSION)
        .usage(&usage[..])
        .about(ABOUT)
        .arg(
            Arg::with_name(options::FOREGROUND)
                .long(options::FOREGROUND)
                .help("when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out")
        )
        .arg(
            Arg::with_name(options::KILL_AFTER)
                .short("k")
                .takes_value(true))
        .arg(
            Arg::with_name(options::PRESERVE_STATUS)
                .long(options::PRESERVE_STATUS)
                .help("exit with the same status as COMMAND, even when the command times out")
        )
        .arg(
            Arg::with_name(options::SIGNAL)
                .short("s")
                .long(options::SIGNAL)
                .help("specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals")
                .takes_value(true)
        )
        .arg(
            Arg::with_name(options::DURATION)
                .index(1)
                .required(true)
        )
        .arg(
            Arg::with_name(options::COMMAND)
                .index(2)
                .required(true)
        )
        .arg(
            Arg::with_name(options::ARGS).multiple(true)
        )
        .setting(AppSettings::TrailingVarArg);

    let matches = app.get_matches_from(args);

    let config = Config::from(matches);
    timeout(
        &config.command,
        &config.command_args,
        config.duration,
        config.signal,
        config.kill_after,
        config.foreground,
        config.preserve_status,
    )
}

/// TODO: Improve exit codes, and make them consistent with the GNU Coreutil
/// exit codes.

fn timeout(
    cmdname: &str,
    args: &[String],
    duration: Duration,
    signal: usize,
    kill_after: Duration,
    foreground: bool,
    preserve_status: bool,
) -> i32 {
    if !foreground {
        unsafe { libc::setpgid(0, 0) };
    }
    let mut process = match Command::new(cmdname)
        .args(args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn()
    {
        Ok(p) => p,
        Err(err) => {
            show_error!("failed to execute process: {}", err);
            if err.kind() == ErrorKind::NotFound {
                // FIXME: not sure which to use
                return 127;
            } else {
                // FIXME: this may not be 100% correct...
                return 126;
            }
        }
    };
    match process.wait_or_timeout(duration) {
        Ok(Some(status)) => status.code().unwrap_or_else(|| status.signal().unwrap()),
        Ok(None) => {
            return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
            match process.wait_or_timeout(kill_after) {
                Ok(Some(status)) => {
                    if preserve_status {
                        status.code().unwrap_or_else(|| status.signal().unwrap())
                    } else {
                        124
                    }
                }
                Ok(None) => {
                    if kill_after == Duration::new(0, 0) {
                        // XXX: this may not be right
                        return 124;
                    }
                    return_if_err!(
                        ERR_EXIT_STATUS,
                        process
                            .send_signal(uucore::signals::signal_by_name_or_value("KILL").unwrap())
                    );
                    return_if_err!(ERR_EXIT_STATUS, process.wait());
                    137
                }
                Err(_) => 124,
            }
        }
        Err(_) => {
            return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
            ERR_EXIT_STATUS
        }
    }
}
<commit_msg>refactor/timeout ~ polish spelling (comments, names, and exceptions)<commit_after>//  * This file is part of the uutils coreutils package.
//  *
//  * (c) Alex Lyon <arcterus@mail.com>
//  *
//  * For the full copyright and license information, please view the LICENSE
//  * file that was distributed with this source code.

// spell-checker:ignore (ToDO) tstr sigstr cmdname setpgid

#[macro_use]
extern crate uucore;

extern crate clap;

use clap::{App, AppSettings, Arg};
use std::io::ErrorKind;
use std::process::{Command, Stdio};
use std::time::Duration;
use uucore::process::ChildExt;
use uucore::signals::signal_by_name_or_value;
use uucore::InvalidEncodingHandling;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Start COMMAND, and kill it if still running after DURATION.";

fn get_usage() -> String {
    format!("{0} [OPTION]... [FILE]...", executable!())
}

const ERR_EXIT_STATUS: i32 = 125;

pub mod options {
    pub static FOREGROUND: &str = "foreground";
    pub static KILL_AFTER: &str = "kill-after";
    pub static SIGNAL: &str = "signal";
    pub static VERSION: &str = "version";
    pub static PRESERVE_STATUS: &str = "preserve-status";

    // Positional args.
    pub static DURATION: &str = "duration";
    pub static COMMAND: &str = "command";
    pub static ARGS: &str = "args";
}

struct Config {
    foreground: bool,
    kill_after: Duration,
    signal: usize,
    duration: Duration,
    preserve_status: bool,

    command: String,
    command_args: Vec<String>,
}

impl Config {
    fn from(options: clap::ArgMatches) -> Config {
        let signal = match options.value_of(options::SIGNAL) {
            Some(signal_) => {
                let signal_result = signal_by_name_or_value(&signal_);
                match signal_result {
                    None => {
                        unreachable!("invalid signal '{}'", signal_);
                    }
                    Some(signal_value) => signal_value,
                }
            }
            _ => uucore::signals::signal_by_name_or_value("TERM").unwrap(),
        };

        let kill_after: Duration = match options.value_of(options::KILL_AFTER) {
            Some(time) => uucore::parse_time::from_str(&time).unwrap(),
            None => Duration::new(0, 0),
        };

        let duration: Duration =
            uucore::parse_time::from_str(options.value_of(options::DURATION).unwrap()).unwrap();

        let preserve_status: bool = options.is_present(options::PRESERVE_STATUS);
        let foreground = options.is_present(options::FOREGROUND);

        let command: String = options.value_of(options::COMMAND).unwrap().to_string();

        let command_args: Vec<String> = match options.values_of(options::ARGS) {
            Some(values) => values.map(|x| x.to_owned()).collect(),
            None => vec![],
        };

        Config {
            foreground,
            kill_after,
            signal,
            duration,
            preserve_status,
            command,
            command_args,
        }
    }
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    let usage = get_usage();

    let app = App::new("timeout")
        .version(VERSION)
        .usage(&usage[..])
        .about(ABOUT)
        .arg(
            Arg::with_name(options::FOREGROUND)
                .long(options::FOREGROUND)
                .help("when not running timeout directly from a shell prompt, allow COMMAND to read from the TTY and get TTY signals; in this mode, children of COMMAND will not be timed out")
        )
        .arg(
            Arg::with_name(options::KILL_AFTER)
                .short("k")
                .takes_value(true))
        .arg(
            Arg::with_name(options::PRESERVE_STATUS)
                .long(options::PRESERVE_STATUS)
                .help("exit with the same status as COMMAND, even when the command times out")
        )
        .arg(
            Arg::with_name(options::SIGNAL)
                .short("s")
                .long(options::SIGNAL)
                .help("specify the signal to be sent on timeout; SIGNAL may be a name like 'HUP' or a number; see 'kill -l' for a list of signals")
                .takes_value(true)
        )
        .arg(
            Arg::with_name(options::DURATION)
                .index(1)
                .required(true)
        )
        .arg(
            Arg::with_name(options::COMMAND)
                .index(2)
                .required(true)
        )
        .arg(
            Arg::with_name(options::ARGS).multiple(true)
        )
        .setting(AppSettings::TrailingVarArg);

    let matches = app.get_matches_from(args);

    let config = Config::from(matches);
    timeout(
        &config.command,
        &config.command_args,
        config.duration,
        config.signal,
        config.kill_after,
        config.foreground,
        config.preserve_status,
    )
}

/// TODO: Improve exit codes, and make them consistent with the GNU Coreutils exit codes.

fn timeout(
    cmdname: &str,
    args: &[String],
    duration: Duration,
    signal: usize,
    kill_after: Duration,
    foreground: bool,
    preserve_status: bool,
) -> i32 {
    if !foreground {
        unsafe { libc::setpgid(0, 0) };
    }
    let mut process = match Command::new(cmdname)
        .args(args)
        .stdin(Stdio::inherit())
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn()
    {
        Ok(p) => p,
        Err(err) => {
            show_error!("failed to execute process: {}", err);
            if err.kind() == ErrorKind::NotFound {
                // FIXME: not sure which to use
                return 127;
            } else {
                // FIXME: this may not be 100% correct...
                return 126;
            }
        }
    };
    match process.wait_or_timeout(duration) {
        Ok(Some(status)) => status.code().unwrap_or_else(|| status.signal().unwrap()),
        Ok(None) => {
            return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
            match process.wait_or_timeout(kill_after) {
                Ok(Some(status)) => {
                    if preserve_status {
                        status.code().unwrap_or_else(|| status.signal().unwrap())
                    } else {
                        124
                    }
                }
                Ok(None) => {
                    if kill_after == Duration::new(0, 0) {
                        // XXX: this may not be right
                        return 124;
                    }
                    return_if_err!(
                        ERR_EXIT_STATUS,
                        process
                            .send_signal(uucore::signals::signal_by_name_or_value("KILL").unwrap())
                    );
                    return_if_err!(ERR_EXIT_STATUS, process.wait());
                    137
                }
                Err(_) => 124,
            }
        }
        Err(_) => {
            return_if_err!(ERR_EXIT_STATUS, process.send_signal(signal));
            ERR_EXIT_STATUS
        }
    }
}
<|endoftext|>


<commit_before>use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey};
use rand::RngCore;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode, TreeHash};
use test_random_derive::TestRandom;

/// Information about a `BeaconChain` validator.
///
/// Spec v0.4.0
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, TreeHash)]
pub struct Validator {
    pub pubkey: PublicKey,
    pub withdrawal_credentials: Hash256,
    pub activation_epoch: Epoch,
    pub exit_epoch: Epoch,
    pub withdrawable_epoch: Epoch,
    pub initiated_exit: bool,
    pub slashed: bool,
}

impl Validator {
    /// Returns `true` if the validator is considered active at some epoch.
    pub fn is_active_at(&self, epoch: Epoch) -> bool {
        self.activation_epoch <= epoch && epoch < self.exit_epoch
    }

    /// Returns `true` if the validator is considered exited at some epoch.
    pub fn is_exited_at(&self, epoch: Epoch) -> bool {
        self.exit_epoch <= epoch
    }

    /// Returns `true` if the validator is able to withdraw at some epoch.
    pub fn is_withdrawable_at(&self, epoch: Epoch) -> bool {
        self.withdrawable_epoch <= epoch
    }
}

impl Default for Validator {
    /// Yields a "default" `Validator`. Primarily used for testing.
    fn default() -> Self {
        Self {
            pubkey: PublicKey::default(),
            withdrawal_credentials: Hash256::default(),
            activation_epoch: Epoch::from(std::u64::MAX),
            exit_epoch: Epoch::from(std::u64::MAX),
            withdrawable_epoch: Epoch::from(std::u64::MAX),
            initiated_exit: false,
            slashed: false,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_utils::{SeedableRng, TestRandom, XorShiftRng};

    #[test]
    fn test_validator_can_be_active() {
        let mut rng = XorShiftRng::from_seed([42; 16]);
        let mut validator = Validator::random_for_test(&mut rng);

        let activation_epoch = u64::random_for_test(&mut rng);
        let exit_epoch = activation_epoch + 234;

        validator.activation_epoch = Epoch::from(activation_epoch);
        validator.exit_epoch = Epoch::from(exit_epoch);

        for slot in (activation_epoch - 100)..(exit_epoch + 100) {
            let slot = Epoch::from(slot);
            if slot < activation_epoch {
                assert!(!validator.is_active_at(slot));
            } else if slot >= exit_epoch {
                assert!(!validator.is_active_at(slot));
            } else {
                assert!(validator.is_active_at(slot));
            }
        }
    }

    ssz_tests!(Validator);
}
<commit_msg>Update `Validator` to 0.5.0, add tests<commit_after>use crate::{test_utils::TestRandom, Epoch, Hash256, PublicKey};
use rand::RngCore;
use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode, TreeHash};
use test_random_derive::TestRandom;

/// Information about a `BeaconChain` validator.
///
/// Spec v0.5.0
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Encode, Decode, TestRandom, TreeHash)]
pub struct Validator {
    pub pubkey: PublicKey,
    pub withdrawal_credentials: Hash256,
    pub activation_epoch: Epoch,
    pub exit_epoch: Epoch,
    pub withdrawable_epoch: Epoch,
    pub initiated_exit: bool,
    pub slashed: bool,
}

impl Validator {
    /// Returns `true` if the validator is considered active at some epoch.
    pub fn is_active_at(&self, epoch: Epoch) -> bool {
        self.activation_epoch <= epoch && epoch < self.exit_epoch
    }

    /// Returns `true` if the validator is considered exited at some epoch.
    pub fn is_exited_at(&self, epoch: Epoch) -> bool {
        self.exit_epoch <= epoch
    }

    /// Returns `true` if the validator is able to withdraw at some epoch.
    pub fn is_withdrawable_at(&self, epoch: Epoch) -> bool {
        self.withdrawable_epoch <= epoch
    }
}

impl Default for Validator {
    /// Yields a "default" `Validator`. Primarily used for testing.
    fn default() -> Self {
        Self {
            pubkey: PublicKey::default(),
            withdrawal_credentials: Hash256::default(),
            activation_epoch: Epoch::from(std::u64::MAX),
            exit_epoch: Epoch::from(std::u64::MAX),
            withdrawable_epoch: Epoch::from(std::u64::MAX),
            initiated_exit: false,
            slashed: false,
        }
    }
}

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

    #[test]
    fn default() {
        let v = Validator::default();

        let epoch = Epoch::new(0);

        assert_eq!(v.is_active_at(epoch), false);
        assert_eq!(v.is_exited_at(epoch), false);
        assert_eq!(v.is_withdrawable_at(epoch), false);
        assert_eq!(v.initiated_exit, false);
        assert_eq!(v.slashed, false);
    }

    #[test]
    fn is_active_at() {
        let epoch = Epoch::new(10);

        let v = Validator {
            activation_epoch: epoch,
            ..Validator::default()
        };

        assert_eq!(v.is_active_at(epoch - 1), false);
        assert_eq!(v.is_active_at(epoch), true);
        assert_eq!(v.is_active_at(epoch + 1), true);
    }

    #[test]
    fn is_exited_at() {
        let epoch = Epoch::new(10);

        let v = Validator {
            exit_epoch: epoch,
            ..Validator::default()
        };

        assert_eq!(v.is_exited_at(epoch - 1), false);
        assert_eq!(v.is_exited_at(epoch), true);
        assert_eq!(v.is_exited_at(epoch + 1), true);
    }

    #[test]
    fn is_withdrawable_at() {
        let epoch = Epoch::new(10);

        let v = Validator {
            withdrawable_epoch: epoch,
            ..Validator::default()
        };

        assert_eq!(v.is_withdrawable_at(epoch - 1), false);
        assert_eq!(v.is_withdrawable_at(epoch), true);
        assert_eq!(v.is_withdrawable_at(epoch + 1), true);
    }

    ssz_tests!(Validator);
}
<|endoftext|>


<commit_before>#[macro_use] extern crate libeuler;
use std::num::Int;
use std::iter::AdditiveIterator;
use std::iter::MultiplicativeIterator;
use libeuler::SieveOfAtkinIterator;

/// In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
///
///            08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
///            49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
///            81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
///            52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
///            22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
///            24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
///            32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
///            67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
///            24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
///            21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
///            78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
///            16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
///            86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
///            19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
///            04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
///            88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
///            04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
///            20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
///            20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
///            01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
///
/// The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
///
/// What is the greatest product of four adjacent numbers in the same direction (up, down, left,
/// right, or diagonally) in the 20×20 grid?
fn main() {
    let grid = [
        [ 08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08 ],
        [ 49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00 ],
        [ 81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65 ],
        [ 52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91 ],
        [ 22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80 ],
        [ 24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50 ],
        [ 32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70 ],
        [ 67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21 ],
        [ 24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72 ],
        [ 21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95 ],
        [ 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92 ],
        [ 16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57 ],
        [ 86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58 ],
        [ 19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40 ],
        [ 04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66 ],
        [ 88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69 ],
        [ 04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36 ],
        [ 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16 ],
        [ 20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54 ],
        [ 01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48 ],
    ];

    enum GridIterDirection {
        Right,
        Down,
        DiagonalRight,
        DiagonalLeft
    }

    struct GridIter {
        direction: Option<GridIterDirection>,
        x: usize,
        y: usize,
        grid: [[i32; 20]; 20]
    }

    impl GridIter {
        fn new(grid: [[i32; 20]; 20]) -> GridIter {
            GridIter {
                direction: Some(GridIterDirection::Right),
                x: 0,
                y: 0,
                grid: grid
            }
        }
    }
    impl Iterator for GridIter {
        type Item = Vec<i32>;

        fn next(&mut self) -> Option<Vec<i32>> {
            if self.direction.is_none() {
                return None;
            }

            println!("({}, {}) {}", self.x, self.y, match self.direction {
                Some(GridIterDirection::Right) => "Right",
                Some(GridIterDirection::DiagonalRight) => "DiagonalRight",
                Some(GridIterDirection::DiagonalLeft) => "DiagonalLeft",
                Some(GridIterDirection::Down) => "Down",
                None => unreachable!()
            });

            let mut retval = Vec::new();
            for i in 0..4 {
                retval.push(match self.direction {
                    Some(GridIterDirection::Right) => self.grid[self.y][self.x + i],
                    Some(GridIterDirection::DiagonalRight) => self.grid[self.y + i][self.x + i],
                    Some(GridIterDirection::DiagonalLeft) => self.grid[self.y + i][self.x - i],
                    Some(GridIterDirection::Down) => self.grid[self.y + i][self.x],
                    None => unreachable!()
                });
            }

            loop {
                self.direction = match self.direction {
                    Some(GridIterDirection::Right) => Some(GridIterDirection::DiagonalLeft),
                    Some(GridIterDirection::DiagonalLeft) => Some(GridIterDirection::DiagonalRight),
                    Some(GridIterDirection::DiagonalRight) => Some(GridIterDirection::Down),
                    Some(GridIterDirection::Down) => {
                        self.x += 1;
                        if self.x >= self.grid[0].len() {
                            self.x = 0;
                            self.y += 1;
                            if self.y >= self.grid.len() {
                                None
                            } else {
                                Some(GridIterDirection::Right)
                            }
                        } else {
                            Some(GridIterDirection::Right)
                        }
                    },
                    None => unreachable!()
                };

                match self.direction {
                    Some(GridIterDirection::Right) => {
                        if self.x + 3 < self.grid[0].len() {
                            break;
                        }
                    },
                    Some(GridIterDirection::DiagonalRight) => {
                        if self.x + 3 < self.grid[0].len() && self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    Some(GridIterDirection::DiagonalLeft) => {
                        if (self.x as isize)- 3 >= 0 && self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    Some(GridIterDirection::Down) => {
                        if self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    None => break
                }
            }

            return Some(retval);
        }
    }

    solutions!{
        inputs: (ceiling: u64 = 2_000_000)

        sol naive {
            GridIter::new(grid).map(|v| {
                let ret = v.iter().map(|&x| x).product();
                println!("getting product of {:?} -> {}", v, ret);
                ret
            }).max()
        }
    };
}
<commit_msg>Clean up solution 11<commit_after>#[macro_use] extern crate libeuler;
use std::num::Int;
use std::iter::AdditiveIterator;
use std::iter::MultiplicativeIterator;
use libeuler::SieveOfAtkinIterator;

/// In the 20×20 grid below, four numbers along a diagonal line have been marked in red.
///
///            08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
///            49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
///            81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
///            52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
///            22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
///            24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
///            32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
///            67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
///            24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
///            21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
///            78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
///            16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
///            86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
///            19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
///            04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
///            88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
///            04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
///            20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
///            20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
///            01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48
///
/// The product of these numbers is 26 × 63 × 78 × 14 = 1788696.
///
/// What is the greatest product of four adjacent numbers in the same direction (up, down, left,
/// right, or diagonally) in the 20×20 grid?

enum GridDirection {
    Right,
    Down,
    DiagonalRight,
    DiagonalLeft
}
use self::GridDirection::*;

fn main() {
    let grid = [
        [ 08, 02, 22, 97, 38, 15, 00, 40, 00, 75, 04, 05, 07, 78, 52, 12, 50, 77, 91, 08 ],
        [ 49, 49, 99, 40, 17, 81, 18, 57, 60, 87, 17, 40, 98, 43, 69, 48, 04, 56, 62, 00 ],
        [ 81, 49, 31, 73, 55, 79, 14, 29, 93, 71, 40, 67, 53, 88, 30, 03, 49, 13, 36, 65 ],
        [ 52, 70, 95, 23, 04, 60, 11, 42, 69, 24, 68, 56, 01, 32, 56, 71, 37, 02, 36, 91 ],
        [ 22, 31, 16, 71, 51, 67, 63, 89, 41, 92, 36, 54, 22, 40, 40, 28, 66, 33, 13, 80 ],
        [ 24, 47, 32, 60, 99, 03, 45, 02, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50 ],
        [ 32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70 ],
        [ 67, 26, 20, 68, 02, 62, 12, 20, 95, 63, 94, 39, 63, 08, 40, 91, 66, 49, 94, 21 ],
        [ 24, 55, 58, 05, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72 ],
        [ 21, 36, 23, 09, 75, 00, 76, 44, 20, 45, 35, 14, 00, 61, 33, 97, 34, 31, 33, 95 ],
        [ 78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 03, 80, 04, 62, 16, 14, 09, 53, 56, 92 ],
        [ 16, 39, 05, 42, 96, 35, 31, 47, 55, 58, 88, 24, 00, 17, 54, 24, 36, 29, 85, 57 ],
        [ 86, 56, 00, 48, 35, 71, 89, 07, 05, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58 ],
        [ 19, 80, 81, 68, 05, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 04, 89, 55, 40 ],
        [ 04, 52, 08, 83, 97, 35, 99, 16, 07, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66 ],
        [ 88, 36, 68, 87, 57, 62, 20, 72, 03, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69 ],
        [ 04, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 08, 46, 29, 32, 40, 62, 76, 36 ],
        [ 20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 04, 36, 16 ],
        [ 20, 73, 35, 29, 78, 31, 90, 01, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 05, 54 ],
        [ 01, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 01, 89, 19, 67, 48 ],
    ];

    struct GridIter {
        direction: Option<GridDirection>,
        x: usize,
        y: usize,
        grid: [[i32; 20]; 20]
    }

    impl GridIter {
        fn new(grid: [[i32; 20]; 20]) -> GridIter {
            GridIter {
                direction: Some(Right),
                x: 0,
                y: 0,
                grid: grid
            }
        }
    }

    impl Iterator for GridIter {
        type Item = Vec<i32>;

        fn next(&mut self) -> Option<Vec<i32>> {
            if self.direction.is_none() {
                return None;
            }

            let mut retval = Vec::new();
            for i in 0..4 {
                retval.push(match *self.direction.as_ref().unwrap() {
                    Right => self.grid[self.y][self.x + i],
                    DiagonalRight => self.grid[self.y + i][self.x + i],
                    DiagonalLeft => self.grid[self.y + i][self.x - i],
                    Down => self.grid[self.y + i][self.x],
                });
            }

            loop {
                self.direction = match *self.direction.as_ref().unwrap() {
                    Right => Some(DiagonalLeft),
                    DiagonalLeft => Some(DiagonalRight),
                    DiagonalRight => Some(Down),
                    Down => {
                        self.x += 1;
                        if self.x >= self.grid[0].len() {
                            self.x = 0;
                            self.y += 1;
                            if self.y >= self.grid.len() {
                                None
                            } else {
                                Some(Right)
                            }
                        } else {
                            Some(Right)
                        }
                    },
                };

                match self.direction {
                    Some(Right) => {
                        if self.x + 3 < self.grid[0].len() {
                            break;
                        }
                    },
                    Some(DiagonalRight) => {
                        if self.x + 3 < self.grid[0].len() && self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    Some(DiagonalLeft) => {
                        if (self.x as isize)- 3 >= 0 && self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    Some(Down) => {
                        if self.y + 3 < self.grid.len() {
                            break;
                        }
                    },
                    None => break
                }
            }

            return Some(retval);
        }
    }

    solutions!{
        inputs: (ceiling: u64 = 2_000_000)

        sol naive {
            GridIter::new(grid).map(|v| v.iter().fold(1, |a, &x| a * x)).max()
        }
    };
}
<|endoftext|>


<commit_before>use ast::{self, Name};
use attr::{self, AttrMetaMethods, HasAttrs};
use codemap::{ExpnInfo, MacroAttribute, NameAndSpan};
use ext::base::*;
use ext::build::AstBuilder;
use ext::expand::{MacroExpander, expand_multi_modified};
use parse::token::intern;
use util::small_vector::SmallVector;

pub fn expand_annotatable(
    mut item: Annotatable,
    fld: &mut MacroExpander,
) -> SmallVector<Annotatable> {
    let mut out_items = SmallVector::zero();
    let mut new_attrs = Vec::new();

    item = expand_1(item, fld, &mut out_items, &mut new_attrs);

    item = item.fold_attrs(new_attrs);
    let expanded = expand_multi_modified(item, fld);
    out_items.push_all(expanded);

    out_items
}

// Responsible for expanding `cfg_attr` and delegating to expand_2.
//
// The expansion turns this:
//
//     #[cfg_attr(COND1, SPEC1)]
//     #[cfg_attr(COND2, SPEC2)]
//     struct Item { ... }
//
// into this:
//
//     #[cfg(COND1)]
//     impl Trait for Item { ... }
//     #[cfg_attr(COND2, SPEC3)]
//     struct Item { ... }
//
// In the example, SPEC1 was handled by expand_2 to create the impl, and the
// handling of SPEC2 resulted in a new attribute SPEC3 which remains
// conditional.
fn expand_1(
    mut item: Annotatable,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    new_attrs: &mut Vec<ast::Attribute>,
) -> Annotatable {
    while !item.attrs().is_empty() {
        // Pop the first attribute.
        let mut attr = None;
        item = item.map_attrs(|mut attrs| {
            attr = Some(attrs.remove(0));
            attrs
        });
        let attr = attr.unwrap();

        match attr.node.value.node {
            // #[cfg_attr(COND, SPEC)]
            ast::MetaItemKind::List(ref word, ref vec)
                if word == "cfg_attr" && vec.len() == 2 =>
            {
                // #[cfg(COND)]
                let cond = fld.cx.attribute(
                    attr.span,
                    fld.cx.meta_list(
                        attr.node.value.span,
                        intern("cfg").as_str(),
                        vec[..1].to_vec()));
                // #[SPEC]
                let spec = fld.cx.attribute(
                    attr.span,
                    vec[1].clone());
                let mut items = SmallVector::zero();
                let mut attrs = Vec::new();
                item = expand_2(item, &spec, fld, &mut items, &mut attrs);
                for new_item in items {
                    let new_item = new_item.map_attrs(|mut attrs| {
                        attrs.push(cond.clone());
                        attrs
                    });
                    out_items.push(new_item);
                }
                for new_attr in attrs {
                    // #[cfg_attr(COND, NEW_SPEC)]
                    let new_attr = fld.cx.attribute(
                        attr.span,
                        fld.cx.meta_list(
                            attr.node.value.span,
                            word.clone(),
                            vec![vec[0].clone(), new_attr.node.value]));
                    new_attrs.push(new_attr);
                }
            }
            _ => {
                item = expand_2(item, &attr, fld, out_items, new_attrs);
            }
        }
    }
    item
}

// Responsible for expanding `derive` and delegating to expand_3.
//
// The expansion turns this:
//
//     #[derive(Serialize, Clone)]
//     #[other_attr]
//     struct Item { ... }
//
// into this:
//
//     impl Serialize for Item { ... }
//     #[derive(Clone)]
//     #[other_attr]
//     struct Item { ... }
//
// In the example, `derive_Serialize` was handled by expand_3 to create the impl
// but `derive_Clone` and `other_attr` were not handled. Attributes that are not
// handled by expand_3 are preserved.
fn expand_2(
    mut item: Annotatable,
    attr: &ast::Attribute,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    new_attrs: &mut Vec<ast::Attribute>,
) -> Annotatable {
    let mname = intern(&attr.name());
    let mitem = &attr.node.value;
    if mname.as_str() == "derive" {
        let traits = mitem.meta_item_list().unwrap_or(&[]);
        if traits.is_empty() {
            fld.cx.span_warn(mitem.span, "empty trait list in `derive`");
        }
        let mut not_handled = Vec::new();
        for titem in traits.iter().rev() {
            let tname = match titem.node {
                ast::MetaItemKind::Word(ref tname) => tname,
                _ => {
                    fld.cx.span_err(titem.span, "malformed `derive` entry");
                    continue;
                }
            };
            let tname = intern(&format!("derive_{}", tname));
            // #[derive_Trait]
            let derive = fld.cx.attribute(
                attr.span,
                fld.cx.meta_word(titem.span, tname.as_str()));
            let (handled, out) = expand_3(item, &derive, fld, out_items, tname);
            if !handled {
                not_handled.push((*titem).clone());
            }
            item = out;
        }
        if !not_handled.is_empty() {
            // #[derive(Trait, ...)]
            let derive = fld.cx.attribute(
                attr.span,
                fld.cx.meta_list(mitem.span, mname.as_str(), not_handled));
            new_attrs.push(derive);
        }
        item
    } else {
        let (handled, out) = expand_3(item, attr, fld, out_items, mname);
        if !handled {
            new_attrs.push((*attr).clone());
        }
        out
    }
}

// Responsible for expanding attributes that match a MultiDecorator or
// MultiModifier registered in the syntax_env. Returns whether the given
// attribute was handled, along with the item to continue processing.
//
// Syntex supports only a special case of MultiModifier - those that produce
// exactly one output. If a MultiModifier produces zero or more than one output
// this function panics. The problematic case we cannot support is:
//
//     #[decorator] // not registered with Syntex
//     #[modifier] // registered
//     struct A;
fn expand_3(
    item: Annotatable,
    attr: &ast::Attribute,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    mname: Name,
) -> (bool, Annotatable) {
    match fld.cx.syntax_env.find(mname) {
        Some(rc) => match *rc {
            MultiDecorator(ref mac) => {
                attr::mark_used(&attr);
                fld.cx.bt_push(ExpnInfo {
                    call_site: attr.span,
                    callee: NameAndSpan {
                        format: MacroAttribute(mname),
                        span: Some(attr.span),
                        // attributes can do whatever they like, for now.
                        allow_internal_unstable: true,
                    }
                });

                let mut modified = Vec::new();
                mac.expand(fld.cx, attr.span, &attr.node.value, &item,
                        &mut |item| modified.push(item));

                fld.cx.bt_pop();
                out_items.extend(modified.into_iter()
                    .flat_map(|ann| expand_annotatable(ann, fld).into_iter()));
                (true, item)
            }
            MultiModifier(ref mac) => {
                attr::mark_used(&attr);
                fld.cx.bt_push(ExpnInfo {
                    call_site: attr.span,
                    callee: NameAndSpan {
                        format: MacroAttribute(mname),
                        span: Some(attr.span),
                        // attributes can do whatever they like, for now.
                        allow_internal_unstable: true,
                    }
                });

                let mut modified = mac.expand(fld.cx,
                                              attr.span,
                                              &attr.node.value,
                                              item);
                if modified.len() != 1 {
                    panic!("expected 1 output from `#[{}]` but got {}",
                           mname, modified.len());
                }
                let modified = modified.pop().unwrap();

                fld.cx.bt_pop();

                let mut expanded = expand_annotatable(modified, fld);
                if expanded.is_empty() {
                    panic!("expected 1 output from `#[{}]` but got {}",
                           mname, expanded.len());
                }
                let last = expanded.pop().unwrap();

                out_items.extend(expanded);
                (true, last)
            }
            _ => (false, item),
        },
        _ => (false, item),
    }
}
<commit_msg>Fix message from modifier failure cases<commit_after>use ast::{self, Name};
use attr::{self, AttrMetaMethods, HasAttrs};
use codemap::{ExpnInfo, MacroAttribute, NameAndSpan};
use ext::base::*;
use ext::build::AstBuilder;
use ext::expand::{MacroExpander, expand_multi_modified};
use parse::token::intern;
use util::small_vector::SmallVector;

pub fn expand_annotatable(
    mut item: Annotatable,
    fld: &mut MacroExpander,
) -> SmallVector<Annotatable> {
    let mut out_items = SmallVector::zero();
    let mut new_attrs = Vec::new();

    item = expand_1(item, fld, &mut out_items, &mut new_attrs);

    item = item.fold_attrs(new_attrs);
    let expanded = expand_multi_modified(item, fld);
    out_items.push_all(expanded);

    out_items
}

// Responsible for expanding `cfg_attr` and delegating to expand_2.
//
// The expansion turns this:
//
//     #[cfg_attr(COND1, SPEC1)]
//     #[cfg_attr(COND2, SPEC2)]
//     struct Item { ... }
//
// into this:
//
//     #[cfg(COND1)]
//     impl Trait for Item { ... }
//     #[cfg_attr(COND2, SPEC3)]
//     struct Item { ... }
//
// In the example, SPEC1 was handled by expand_2 to create the impl, and the
// handling of SPEC2 resulted in a new attribute SPEC3 which remains
// conditional.
fn expand_1(
    mut item: Annotatable,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    new_attrs: &mut Vec<ast::Attribute>,
) -> Annotatable {
    while !item.attrs().is_empty() {
        // Pop the first attribute.
        let mut attr = None;
        item = item.map_attrs(|mut attrs| {
            attr = Some(attrs.remove(0));
            attrs
        });
        let attr = attr.unwrap();

        match attr.node.value.node {
            // #[cfg_attr(COND, SPEC)]
            ast::MetaItemKind::List(ref word, ref vec)
                if word == "cfg_attr" && vec.len() == 2 =>
            {
                // #[cfg(COND)]
                let cond = fld.cx.attribute(
                    attr.span,
                    fld.cx.meta_list(
                        attr.node.value.span,
                        intern("cfg").as_str(),
                        vec[..1].to_vec()));
                // #[SPEC]
                let spec = fld.cx.attribute(
                    attr.span,
                    vec[1].clone());
                let mut items = SmallVector::zero();
                let mut attrs = Vec::new();
                item = expand_2(item, &spec, fld, &mut items, &mut attrs);
                for new_item in items {
                    let new_item = new_item.map_attrs(|mut attrs| {
                        attrs.push(cond.clone());
                        attrs
                    });
                    out_items.push(new_item);
                }
                for new_attr in attrs {
                    // #[cfg_attr(COND, NEW_SPEC)]
                    let new_attr = fld.cx.attribute(
                        attr.span,
                        fld.cx.meta_list(
                            attr.node.value.span,
                            word.clone(),
                            vec![vec[0].clone(), new_attr.node.value]));
                    new_attrs.push(new_attr);
                }
            }
            _ => {
                item = expand_2(item, &attr, fld, out_items, new_attrs);
            }
        }
    }
    item
}

// Responsible for expanding `derive` and delegating to expand_3.
//
// The expansion turns this:
//
//     #[derive(Serialize, Clone)]
//     #[other_attr]
//     struct Item { ... }
//
// into this:
//
//     impl Serialize for Item { ... }
//     #[derive(Clone)]
//     #[other_attr]
//     struct Item { ... }
//
// In the example, `derive_Serialize` was handled by expand_3 to create the impl
// but `derive_Clone` and `other_attr` were not handled. Attributes that are not
// handled by expand_3 are preserved.
fn expand_2(
    mut item: Annotatable,
    attr: &ast::Attribute,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    new_attrs: &mut Vec<ast::Attribute>,
) -> Annotatable {
    let mname = intern(&attr.name());
    let mitem = &attr.node.value;
    if mname.as_str() == "derive" {
        let traits = mitem.meta_item_list().unwrap_or(&[]);
        if traits.is_empty() {
            fld.cx.span_warn(mitem.span, "empty trait list in `derive`");
        }
        let mut not_handled = Vec::new();
        for titem in traits.iter().rev() {
            let tname = match titem.node {
                ast::MetaItemKind::Word(ref tname) => tname,
                _ => {
                    fld.cx.span_err(titem.span, "malformed `derive` entry");
                    continue;
                }
            };
            let tname = intern(&format!("derive_{}", tname));
            // #[derive_Trait]
            let derive = fld.cx.attribute(
                attr.span,
                fld.cx.meta_word(titem.span, tname.as_str()));
            let (handled, out) = expand_3(item, &derive, fld, out_items, tname);
            if !handled {
                not_handled.push((*titem).clone());
            }
            item = out;
        }
        if !not_handled.is_empty() {
            // #[derive(Trait, ...)]
            let derive = fld.cx.attribute(
                attr.span,
                fld.cx.meta_list(mitem.span, mname.as_str(), not_handled));
            new_attrs.push(derive);
        }
        item
    } else {
        let (handled, out) = expand_3(item, attr, fld, out_items, mname);
        if !handled {
            new_attrs.push((*attr).clone());
        }
        out
    }
}

// Responsible for expanding attributes that match a MultiDecorator or
// MultiModifier registered in the syntax_env. Returns whether the given
// attribute was handled, along with the item to continue processing.
//
// Syntex supports only a special case of MultiModifier - those that produce
// exactly one output. If a MultiModifier produces zero or more than one output
// this function panics. The problematic case we cannot support is:
//
//     #[decorator] // not registered with Syntex
//     #[modifier] // registered
//     struct A;
fn expand_3(
    item: Annotatable,
    attr: &ast::Attribute,
    fld: &mut MacroExpander,
    out_items: &mut SmallVector<Annotatable>,
    mname: Name,
) -> (bool, Annotatable) {
    match fld.cx.syntax_env.find(mname) {
        Some(rc) => match *rc {
            MultiDecorator(ref mac) => {
                attr::mark_used(&attr);
                fld.cx.bt_push(ExpnInfo {
                    call_site: attr.span,
                    callee: NameAndSpan {
                        format: MacroAttribute(mname),
                        span: Some(attr.span),
                        // attributes can do whatever they like, for now.
                        allow_internal_unstable: true,
                    }
                });

                let mut modified = Vec::new();
                mac.expand(fld.cx, attr.span, &attr.node.value, &item,
                        &mut |item| modified.push(item));

                fld.cx.bt_pop();
                out_items.extend(modified.into_iter()
                    .flat_map(|ann| expand_annotatable(ann, fld).into_iter()));
                (true, item)
            }
            MultiModifier(ref mac) => {
                attr::mark_used(&attr);
                fld.cx.bt_push(ExpnInfo {
                    call_site: attr.span,
                    callee: NameAndSpan {
                        format: MacroAttribute(mname),
                        span: Some(attr.span),
                        // attributes can do whatever they like, for now.
                        allow_internal_unstable: true,
                    }
                });

                let mut modified = mac.expand(fld.cx,
                                              attr.span,
                                              &attr.node.value,
                                              item);
                if modified.len() != 1 {
                    panic!("syntex limitation: expected 1 output from `#[{}]` but got {}",
                           mname, modified.len());
                }
                let modified = modified.pop().unwrap();

                fld.cx.bt_pop();

                let mut expanded = expand_annotatable(modified, fld);
                if expanded.is_empty() {
                    panic!("syntex limitation: output of `#[{}]` must not expand further",
                           mname);
                }
                let last = expanded.pop().unwrap();

                out_items.extend(expanded);
                (true, last)
            }
            _ => (false, item),
        },
        _ => (false, item),
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-aarch64
#![feature(libc)]

extern crate libc;

use std::mem;
use std::thread;

#[link(name = "rust_test_helpers")]
extern {
    fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
                     data: libc::uintptr_t) -> libc::uintptr_t;
}

pub fn main() {
    unsafe {
        thread::spawn(move|| {
            let i = 100;
            rust_dbg_call(callback, mem::transmute(&i));
        }).join();
    }
}

extern fn callback(data: libc::uintptr_t) {
    unsafe {
        let data: *const isize = mem::transmute(data);
        assert_eq!(*data, 100);
    }
}
<commit_msg>Fix (and extend) src/test/run-pass/foreign-call-no-runtime.rs<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ignore-aarch64
#![feature(libc)]

extern crate libc;

use std::mem;
use std::thread;

#[link(name = "rust_test_helpers")]
extern {
    fn rust_dbg_call(cb: extern "C" fn(libc::uintptr_t),
                     data: libc::uintptr_t) -> libc::uintptr_t;
}

pub fn main() {
    unsafe {
        thread::spawn(move|| {
            let i: isize = 100;
            rust_dbg_call(callback_isize, mem::transmute(&i));
        }).join().unwrap();

        thread::spawn(move|| {
            let i: i32 = 100;
            rust_dbg_call(callback_i32, mem::transmute(&i));
        }).join().unwrap();

        thread::spawn(move|| {
            let i: i64 = 100;
            rust_dbg_call(callback_i64, mem::transmute(&i));
        }).join().unwrap();
    }
}

extern fn callback_isize(data: libc::uintptr_t) {
    unsafe {
        let data: *const isize = mem::transmute(data);
        assert_eq!(*data, 100);
    }
}

extern fn callback_i64(data: libc::uintptr_t) {
    unsafe {
        let data: *const i64 = mem::transmute(data);
        assert_eq!(*data, 100);
    }
}

extern fn callback_i32(data: libc::uintptr_t) {
    unsafe {
        let data: *const i32 = mem::transmute(data);
        assert_eq!(*data, 100);
    }
}
<|endoftext|>


<commit_before>extern crate fast_sweeping;
extern crate gnuplot;

use gnuplot::{Figure, Caption, Color, Fix, AxesCommon, PlotOption, DashType, Coordinate, TextColor};
use fast_sweeping::*;

fn main() {
    let n = 16;
    let mut u = vec![0.; (n + 1) * (n + 1)];

    let h = 1f64 / n as f64;
    let t_max = 256;
    let dt = h * h / 2.;
    let k = 16;
    let tau = dt / k as f64;

    let r = 0.3;

    // init with circle
    for i in 0..(n+1) {
        for j in 0..(n+1) {
            let x = i as f64 * h - 0.5;
            let y = j as f64 * h - 0.5;
            u[i + j * (n + 1)] = (x * x + y * y).sqrt() - r;
        }
    }

    // initial data
    let orig = u.clone();
    let mut d_prev: Option<Vec<_>> = None;

    for t in 0..t_max {
        // compute distance function
        let mut d = vec![0f64; (n + 1) * (n + 1)];

            init_dist(&mut d, &u, (n+1, n+1));
            fast_sweep_dist(&mut d, (n+1, n+1));

            // create distance
            for i in 0..d.len() {
                d[i] *= h;
                if u[i] < 0. {
                    d[i] = -d[i];
                }
            }

            match d_prev {
                Some(dp) => {
                    for i in 0..u.len() {
                        u[i] = 2. * d[i] - dp[i];
                    }
                },
                None => u.clone_from(&d)
            }

        // solve wave equation for k timesteps
        for _ in 0..k {
            let mut v = u.clone();
            for j in 0..(n+1) {
                for i in 0..(n+1) {
                    let s = j * (n + 1) + i;
                    let uc = u[s];
                    let ul = if i == 0 { uc } else { u[s - 1] };
                    let ur = if i == n { uc } else { u[s + 1] };
                    let ut = if j == 0 { uc } else { u[s - n - 1] };
                    let ub = if j == n { uc } else { u[s + n + 1] };
                    v[s] = uc + (tau / h * h) * (ul + ur + ut + ub - 4. * uc);
                }
            }
            u.clone_from(&v);
        }

        d_prev = Some(d);
    }

    let mut fg = Figure::new();

    fg.axes3d()
        .set_view_map()
        .surface(&u, n+1, n+1, None, &[])
        // .surface(&d, n+1, n+1, None, &[])
        // .surface(&u, n+1, n+1, None, &[])
        ;
    fg.show();
}
<commit_msg>Possibly working accelerated mean curvature flow<commit_after>extern crate fast_sweeping;
extern crate gnuplot;

use gnuplot::{Figure, Caption, Color, Fix, AxesCommon, PlotOption, DashType, Coordinate, TextColor,
            ContourStyle, AutoOption};
use fast_sweeping::*;

fn main() {
    let n = 64;
    let mut u = vec![0.; (n + 1) * (n + 1)];

    let h = 1f64 / n as f64;
    let t_max = 14;
    // let dt = h / 2.;
    let k = 128;
    let tau = h;

    let r = 0.3;

    // init with circle
    for i in 0..(n+1) {
        for j in 0..(n+1) {
            let x = i as f64 * h - 0.5;
            let y = j as f64 * h - 0.5;
            u[i + j * (n + 1)] = (x * x + y * y).sqrt() - r;
        }
    }

    // initial data
    let orig = u.clone();
    let mut d_prev: Option<Vec<_>> = None;

    for t in 0..t_max {
        // compute distance function
        let mut d = vec![0f64; (n + 1) * (n + 1)];

            init_dist(&mut d, &u, (n+1, n+1));
            fast_sweep_dist(&mut d, (n+1, n+1));

            // create distance
            for i in 0..d.len() {
                d[i] *= h;
                if u[i] < 0. {
                    d[i] = -d[i];
                }
            }

            match d_prev {
                Some(dp) => {
                    for i in 0..u.len() {
                        u[i] = 2. * d[i] - dp[i];
                    }
                },
                None => u.clone_from(&d)
            }

        // solve wave equation for k timesteps
        let mut w = u.clone();
        for _ in 0..k {
            let mut v = u.clone();
            for j in 0..(n+1) {
                for i in 0..(n+1) {
                    let s = j * (n + 1) + i;
                    let uc = u[s];
                    let ul = if i == 0 { uc } else { u[s - 1] };
                    let ur = if i == n { uc } else { u[s + 1] };
                    let ut = if j == 0 { uc } else { u[s - n - 1] };
                    let ub = if j == n { uc } else { u[s + n + 1] };
                    v[s] = 2. * uc - w[s] + (tau * tau / h * h) * (ul + ur + ut + ub - 4. * uc);
                }
            }
            w.clone_from(&u);
            u.clone_from(&v);
        }

        d_prev = Some(d);
    }

    let mut fg = Figure::new();

    fg.axes3d()
        .set_aspect_ratio(AutoOption::Fix(1.))
        .set_view_map()
        .show_contours_custom(true, true, ContourStyle::Linear, AutoOption::Auto, &[0.])
        .surface(&u, n+1, n+1, None, &[])
        // .surface(&d, n+1, n+1, None, &[])
        // .surface(&u, n+1, n+1, None, &[])
        ;
    fg.show();
}
<|endoftext|>


<commit_before><commit_msg>Convert GameMap functions into methods.<commit_after><|endoftext|>


<commit_before><commit_msg>clippy lint<commit_after><|endoftext|>


<commit_before><commit_msg>Make lang detection more flexible<commit_after><|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]

include!("bindings.rs");

use std::os::raw::c_char;
use std::io::Write;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::IntoRawFd;

extern crate libc;

#[derive(PartialEq)]
enum PrintState {
    OUT,
    IN,
    DISPLAY
}

fn print_ptr_rec<W: Write>(port: &mut W, p: ptr, state: PrintState) {
    let x = p as u32;
    if  (x & fx_mask) == fx_tag {
        write!(port, "{}", (x as i32) >> fx_shift);
    } else if x == bool_f {
        write!(port, "#f");
    } else if x == bool_t {
        write!(port, "#t");
    } else if x == list_nil {
        write!(port, "()");
    } else if x == eof_obj {
        write!(port, "#!eof");
    } else if (x & char_mask) == char_tag {
        let c = std::char::from_u32(x >> char_shift).
            expect("a char");
        if state == PrintState::DISPLAY {
            write!(port, "{}", c);
        } else {
            if      c == '\t' { write!(port, "#\\tab"); }
            else if c == '\n' { write!(port, "#\\newline"); }
            else if c == '\r' { write!(port, "#\\return"); }
            else if c == ' '  { write!(port, "#\\space"); }
            else              { write!(port, "#\\{}", c); }
        }
    } else if (x & obj_mask) == pair_tag {
        if state == PrintState::OUT { write!(port, "("); }
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let car = cell.car;
        print_ptr_rec(port, car, PrintState::OUT);
        let cdr = cell.cdr;
        if cdr != list_nil {
            if (cdr & obj_mask) != pair_tag {
                write!(port, " . ");
                print_ptr_rec(port, cdr, PrintState::OUT);
            } else {
                write!(port, " ");
                print_ptr_rec(port, cdr, PrintState::IN);
            }
        }
        if state == PrintState::OUT { write!(port, ")"); }
    } else if (x & obj_mask) == vector_tag {
        write!(port, "#(");
        unsafe {
        let p = &*((x-vector_tag) as *const vector);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            if i > 0 { write!(port, " "); }
            print_ptr_rec(port,
                *((p.buf.as_ptr()).offset(i as isize)),
                PrintState::OUT)
        }}
        write!(port, ")");
    } else if (x & obj_mask) == string_tag {
        if state == PrintState::OUT { write!(port, "\""); }
        unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            let c = std::char::from_u32(*((p.buf.as_ptr()).offset(i as isize)) as u32)
                .expect("char");
            if c == '"'       { write!(port, "\\\""); }
            else if c == '\\' { write!(port, "\\\\"); }
            else              { write!(port, "{}", c); }
        }}
        if state == PrintState::OUT { write!(port, "\""); }
    } else if (x & obj_mask) == symbol_tag {
        print_ptr_rec(port, (x - symbol_tag) | string_tag, PrintState::IN);
    } else if (x & obj_mask) == closure_tag {
        write!(port, "#<procedure>");
    } else {
        write!(port, "#<unknown 0x{:x}>", x);
    }
}
fn print_ptr(x: ptr) {
    print_ptr_rec(&mut std::io::stdout(), x, PrintState::OUT);
    println!("");
}

fn eprint_ptr(msg: ptr, state: PrintState) {
    print_ptr_rec(&mut std::io::stderr(), msg, PrintState::IN);
}

#[no_mangle]
pub extern "C" fn ik_log(msg: ptr) -> ptr {
    eprint!("log: ");
    eprint_ptr(msg, PrintState::IN);
    eprintln!("");
    0
}
#[no_mangle]
pub extern "C" fn ik_error(x: ptr) {
    eprint!("Exception");
    if (x & obj_mask) == pair_tag {
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let caller = cell.car;
        let msg = cell.cdr;
        if caller != bool_f {
            eprint!(" in ");
            eprint_ptr(caller, PrintState::OUT);
        }
        eprint!(": ");
        eprint_ptr(msg, PrintState::IN);
    }
    eprintln!("");
    std::process::exit(0);
}

fn unshift(x: ptr) -> i32 {
    (x as i32) >> fx_shift
}
fn shift(x: i32) -> ptr {
    (x << fx_shift) as u32
}
fn string_data(x: ptr) -> *mut c_char {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        p.buf.as_ptr() as *mut c_char
    }
}
fn cp_str_data(x: ptr, buf: *mut c_char, buf_length: u32) {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = unshift(p.length) as u32;
        let m = std::cmp::min(n, buf_length-1);
        for i in 0..m {
            *(buf.offset(i as isize)) = *(p.buf.as_ptr().offset(i as isize));
        }
        *(buf.offset(m as isize)) = 0;
    }
}
#[no_mangle]
pub extern "C" fn s_write(fd: ptr, str: ptr, len: ptr) -> ptr {
    let bytes = unsafe { libc::write(unshift(fd), string_data(str) as *const libc::c_void, unshift(len) as usize)};
    shift(bytes as i32)
}
#[no_mangle]
pub extern "C" fn s_open_write(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 10] = [0 as c_char; 10];
    cp_str_data(fname, c_fname.as_mut_ptr(), 10);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC, 0640) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_fflush(fd: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn scheme_write(fd: ptr, x: ptr, opt: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let state = unshift(opt);
    let state =
        if state == 0 { PrintState::OUT }
    else if state == 1 { PrintState::IN }
    else { PrintState :: DISPLAY };
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    print_ptr_rec(&mut w, x, state);
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn s_open_read(fname: ptr) -> ptr {
    let mut c_fname: [c_char; 10] = [0; 10];
    cp_str_data(fname, c_fname.as_mut_ptr(), 10);
    let fd = unsafe { libc::open(c_fname.as_mut_ptr(), libc::O_RDONLY) };
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_read_char(fd: ptr) -> ptr {
    let mut ca: [u32; 1] = [0;1];
    let ufd = unshift(fd);
    if unsafe { libc::read(ufd, ca.as_mut_ptr() as *mut libc::c_void, 1) } < 1 {
        eof_obj
    } else {
        (ca[0] << char_shift) | char_tag
    }
}
#[no_mangle]
pub extern "C" fn s_close(fd: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let w = unsafe { std::fs::File::from_raw_fd(ufd) };
    std::mem::drop(w);
    shift(0)
}

#[no_mangle]
pub extern "C" fn heap_alloc(mem: *mut memory, stack: *mut c_char, size: usize) -> *mut c_char {
    let heap_next = unsafe { (*mem).heap_next };
    let heap_new = unsafe { heap_next.offset(size as isize) };
    if heap_new >= unsafe { (*mem).heap_top } {
        eprintln!("Exception: overflow");
        std::process::exit(0);
    }
    unsafe {(*mem).heap_next = heap_new};
    return heap_next;
}

fn allocate_protected_space(size: usize) -> *mut c_char {
    let mut v = Vec::with_capacity(size);
    let ptr = v.as_mut_ptr();
    std::mem::forget(v);
    ptr
}

fn deallocate_protected_space(p: *mut c_char, size: usize) {
    unsafe { std::mem::drop(Vec::from_raw_parts(p, 0, size)) };
}

fn main() {
    let stack_size = 16 * 4096;
    let heap_size = 4 * 16 * 4096;
    let global_size = 16 * 4096;
    let scratch_size = 16 * 4096;

    let stack_top = allocate_protected_space(stack_size);
    let stack_base = unsafe { stack_top.offset(stack_size as isize) };

    let heap = allocate_protected_space(heap_size);
    let global = allocate_protected_space(global_size);
    let scratch = allocate_protected_space(scratch_size);

    let uninit = 0 as (*mut std::os::raw::c_void);

    let mut ctxt = context {
        eax : uninit,
        ebx : uninit,
        ecx : uninit,
        edx : uninit,
        esi : uninit,
        edi : uninit,
        ebp : uninit,
        esp : uninit,
    };

    let heap_top = unsafe { heap.offset((heap_size as isize)/2) };
    let mut mem = memory {
        heap_next : heap,
        global_next : global,
        heap_base : heap,
        heap_top : heap_top,
        heap_base_alt : heap_top,
        heap_top_alt : unsafe { heap.offset(heap_size as isize) },
        global_base : global,
        stack_base : stack_base,
        scratch_base : scratch,
        edi : 0
    };

    let r = unsafe {
        scheme_entry(&mut ctxt, stack_base, &mut mem)
    };
    print_ptr(r);

    deallocate_protected_space(stack_top, stack_size);
    deallocate_protected_space(heap, stack_size);
}
<commit_msg>more avoiding uses of libc<commit_after>#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_must_use)]
#![allow(unused_imports)]

include!("bindings.rs");

use std::os::raw::c_char;
use std::io::Write;
use std::os::unix::io::FromRawFd;
use std::os::unix::io::IntoRawFd;
use std::convert::From;
extern crate libc;

#[derive(PartialEq)]
enum PrintState {
    OUT,
    IN,
    DISPLAY
}

fn print_ptr_rec<W: Write>(port: &mut W, p: ptr, state: PrintState) {
    let x = p as u32;
    if  (x & fx_mask) == fx_tag {
        write!(port, "{}", (x as i32) >> fx_shift);
    } else if x == bool_f {
        write!(port, "#f");
    } else if x == bool_t {
        write!(port, "#t");
    } else if x == list_nil {
        write!(port, "()");
    } else if x == eof_obj {
        write!(port, "#!eof");
    } else if (x & char_mask) == char_tag {
        let c = std::char::from_u32(x >> char_shift).
            expect("a char");
        if state == PrintState::DISPLAY {
            write!(port, "{}", c);
        } else {
            if      c == '\t' { write!(port, "#\\tab"); }
            else if c == '\n' { write!(port, "#\\newline"); }
            else if c == '\r' { write!(port, "#\\return"); }
            else if c == ' '  { write!(port, "#\\space"); }
            else              { write!(port, "#\\{}", c); }
        }
    } else if (x & obj_mask) == pair_tag {
        if state == PrintState::OUT { write!(port, "("); }
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let car = cell.car;
        print_ptr_rec(port, car, PrintState::OUT);
        let cdr = cell.cdr;
        if cdr != list_nil {
            if (cdr & obj_mask) != pair_tag {
                write!(port, " . ");
                print_ptr_rec(port, cdr, PrintState::OUT);
            } else {
                write!(port, " ");
                print_ptr_rec(port, cdr, PrintState::IN);
            }
        }
        if state == PrintState::OUT { write!(port, ")"); }
    } else if (x & obj_mask) == vector_tag {
        write!(port, "#(");
        unsafe {
        let p = &*((x-vector_tag) as *const vector);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            if i > 0 { write!(port, " "); }
            print_ptr_rec(port,
                *((p.buf.as_ptr()).offset(i as isize)),
                PrintState::OUT)
        }}
        write!(port, ")");
    } else if (x & obj_mask) == string_tag {
        if state == PrintState::OUT { write!(port, "\""); }
        unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = (p.length as i32) >> fx_shift;
        for i in 0..n {
            let c = std::char::from_u32(*((p.buf.as_ptr()).offset(i as isize)) as u32)
                .expect("char");
            if c == '"'       { write!(port, "\\\""); }
            else if c == '\\' { write!(port, "\\\\"); }
            else              { write!(port, "{}", c); }
        }}
        if state == PrintState::OUT { write!(port, "\""); }
    } else if (x & obj_mask) == symbol_tag {
        print_ptr_rec(port, (x - symbol_tag) | string_tag, PrintState::IN);
    } else if (x & obj_mask) == closure_tag {
        write!(port, "#<procedure>");
    } else {
        write!(port, "#<unknown 0x{:x}>", x);
    }
}
fn print_ptr(x: ptr) {
    print_ptr_rec(&mut std::io::stdout(), x, PrintState::OUT);
    println!("");
}

fn eprint_ptr(msg: ptr, state: PrintState) {
    print_ptr_rec(&mut std::io::stderr(), msg, PrintState::IN);
}

#[no_mangle]
pub extern "C" fn ik_log(msg: ptr) -> ptr {
    eprint!("log: ");
    eprint_ptr(msg, PrintState::IN);
    eprintln!("");
    0
}
#[no_mangle]
pub extern "C" fn ik_error(x: ptr) {
    eprint!("Exception");
    if (x & obj_mask) == pair_tag {
        let cell = unsafe { *((x-pair_tag) as *const cell) };
        let caller = cell.car;
        let msg = cell.cdr;
        if caller != bool_f {
            eprint!(" in ");
            eprint_ptr(caller, PrintState::OUT);
        }
        eprint!(": ");
        eprint_ptr(msg, PrintState::IN);
    }
    eprintln!("");
    std::process::exit(0);
}

fn unshift(x: ptr) -> i32 {
    (x as i32) >> fx_shift
}
fn shift(x: i32) -> ptr {
    (x << fx_shift) as u32
}
fn string_data(x: ptr) -> *mut c_char {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        p.buf.as_ptr() as *mut c_char
    }
}
fn ptr_string_to_str(x: ptr) -> String {
    unsafe {
        let p = &*((x-string_tag) as *const string);
        let n = unshift(p.length) as usize;
        let mut v = Vec::with_capacity(n);
        for i in 0..n {
            v.push(*(p.buf.as_ptr().offset(i as isize)) as u8);
        }
        std::ffi::CString::from_vec_unchecked(v).into_string().expect("string")
    }
}
#[no_mangle]
pub extern "C" fn s_write(fd: ptr, str: ptr, len: ptr) -> ptr {
    let bytes = unsafe { libc::write(unshift(fd), string_data(str) as *const libc::c_void, unshift(len) as usize)};
    shift(bytes as i32)
}
#[no_mangle]
pub extern "C" fn s_open_write(fname: ptr) -> ptr {
    let s_fname = ptr_string_to_str(fname);
    let port = std::fs::File::create(s_fname).expect("created");
    let fd = port.into_raw_fd();
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_fflush(fd: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn scheme_write(fd: ptr, x: ptr, opt: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let state = unshift(opt);
    let state =
        if state == 0 { PrintState::OUT }
    else if state == 1 { PrintState::IN }
    else { PrintState :: DISPLAY };
    let mut w = unsafe { std::fs::File::from_raw_fd(ufd) };
    print_ptr_rec(&mut w, x, state);
    w.flush();
    w.into_raw_fd();
    0
}
#[no_mangle]
pub extern "C" fn s_open_read(fname: ptr) -> ptr {
    let s_fname = ptr_string_to_str(fname);
    let port = std::fs::File::open(s_fname).expect("opened");
    let fd = port.into_raw_fd();
    shift(fd)
}
#[no_mangle]
pub extern "C" fn s_read_char(fd: ptr) -> ptr {
    let mut ca: [u32; 1] = [0;1];
    let ufd = unshift(fd);
    if unsafe { libc::read(ufd, ca.as_mut_ptr() as *mut libc::c_void, 1) } < 1 {
        eof_obj
    } else {
        (ca[0] << char_shift) | char_tag
    }
}
#[no_mangle]
pub extern "C" fn s_close(fd: ptr) -> ptr {
    let ufd = unshift(fd) as i32;
    let w = unsafe { std::fs::File::from_raw_fd(ufd) };
    std::mem::drop(w);
    shift(0)
}

#[no_mangle]
pub extern "C" fn heap_alloc(mem: *mut memory, stack: *mut c_char, size: usize) -> *mut c_char {
    let heap_next = unsafe { (*mem).heap_next };
    let heap_new = unsafe { heap_next.offset(size as isize) };
    if heap_new >= unsafe { (*mem).heap_top } {
        eprintln!("Exception: overflow");
        std::process::exit(0);
    }
    unsafe {(*mem).heap_next = heap_new};
    return heap_next;
}

fn allocate_protected_space(size: usize) -> *mut c_char {
    let mut v = Vec::with_capacity(size);
    let ptr = v.as_mut_ptr();
    std::mem::forget(v);
    ptr
}

fn deallocate_protected_space(p: *mut c_char, size: usize) {
    unsafe { std::mem::drop(Vec::from_raw_parts(p, 0, size)) };
}

fn main() {
    let stack_size = 16 * 4096;
    let heap_size = 4 * 16 * 4096;
    let global_size = 16 * 4096;
    let scratch_size = 16 * 4096;

    let stack_top = allocate_protected_space(stack_size);
    let stack_base = unsafe { stack_top.offset(stack_size as isize) };

    let heap = allocate_protected_space(heap_size);
    let global = allocate_protected_space(global_size);
    let scratch = allocate_protected_space(scratch_size);

    let uninit = 0 as (*mut std::os::raw::c_void);

    let mut ctxt = context {
        eax : uninit,
        ebx : uninit,
        ecx : uninit,
        edx : uninit,
        esi : uninit,
        edi : uninit,
        ebp : uninit,
        esp : uninit,
    };

    let heap_top = unsafe { heap.offset((heap_size as isize)/2) };
    let mut mem = memory {
        heap_next : heap,
        global_next : global,
        heap_base : heap,
        heap_top : heap_top,
        heap_base_alt : heap_top,
        heap_top_alt : unsafe { heap.offset(heap_size as isize) },
        global_base : global,
        stack_base : stack_base,
        scratch_base : scratch,
        edi : 0
    };

    let r = unsafe {
        scheme_entry(&mut ctxt, stack_base, &mut mem)
    };
    print_ptr(r);

    deallocate_protected_space(stack_top, stack_size);
    deallocate_protected_space(heap, stack_size);
}
<|endoftext|>


<commit_before><commit_msg>no Box required here<commit_after><|endoftext|>


<commit_before><commit_msg>minor change to the test case<commit_after><|endoftext|>


<commit_before>use super::scheduler_future::*;

use futures::prelude::*;
use futures::task;
use futures::task::{Poll};
use futures::channel::oneshot;

use std::mem;
use std::pin::*;

///
/// The state of a SyncFuture operation
///
enum SyncFutureState<TFn, TFuture>
where TFuture: Future {
    /// Waiting for the queue to start running the future
    WaitingForQueue(oneshot::Receiver<()>, TFn),

    /// Evaluating an active future for its result
    WaitingForFuture(TFuture),

    /// The sync future has completed and now we're waiting for the scheduler to complete
    WaitingForScheduler(Box<TFuture::Output>),

    /// Finished evaluating
    Completed
}

///
/// Represents a future that runs synchronously with a queue
///
/// The future is only run in an exclusive time slot within the queue - this property is used to guarantee the
/// safety of `Desync::future_sync`, which provides exclusive access to the data store while the future is running.
/// The queue is allowed to continue once the returned future has completed.
///
pub struct SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    /// The state of this future
    state: SyncFutureState<TFn, TFuture>,

    /// Tracks this future on the scheduler (this allows polling this future to invoke desync's thread-stealing semantics instead of leaving the queue scheduling to a separate thread)
    scheduler_future: SchedulerFuture<()>,

    /// Signals when the future has finished running (None if this future is completed)
    task_finished: Option<oneshot::Sender<()>>
}

impl<TFn, TFuture> SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    ///
    /// Creates a new SyncFuture
    ///
    pub fn new(create_future: TFn, scheduler_future: SchedulerFuture<()>, queue_ready: oneshot::Receiver<()>, task_finished: oneshot::Sender<()>) -> SyncFuture<TFn, TFuture> {
        SyncFuture {
            state:              SyncFutureState::WaitingForQueue(queue_ready, create_future),
            scheduler_future:   scheduler_future,
            task_finished:      Some(task_finished)
        }
    }
}

impl<TFn, TFuture> Future for SyncFuture<TFn, TFuture>
where   TFn:                Unpin+Send+FnOnce() -> TFuture,
        TFuture:            Unpin+Send+Future,
        TFuture::Output:    Send {
    type Output = Result<TFuture::Output, oneshot::Canceled>;

    fn poll(mut self: Pin<&mut Self>, context: &mut task::Context) -> Poll<Self::Output> {
        use self::SyncFutureState::*;

        // Rust doesn't seem to have a way to let us update the state in-place, so we need to swap out the old state and swap in the new state
        let result;
        let mut state = Completed;
        mem::swap(&mut state, &mut self.state);

        // Update the state now we own it
        state = match state {
            WaitingForQueue(mut recv, create_future) => {
                // Check the scheduler future (give it a chance to steal the thread)
                if let Poll::Ready(Err(_)) = self.scheduler_future.poll_unpin(context) {
                    // The queue will never get to the point of polling this future
                    result = Poll::Ready(Err(oneshot::Canceled));
                    self.task_finished.take().map(|finished| finished.send(()));
                    Completed
                } else {
                    // Poll the receiver
                    match recv.poll_unpin(context) {
                        Poll::Ready(Ok(())) => {
                            // Start the future
                            let mut future = create_future();

                            // Poll it immediately to determine its status
                            if let Poll::Ready(future_result) = future.poll_unpin(context) {
                                // Future has completed
                                result = Poll::Pending;
                                self.task_finished.take().map(|finished| finished.send(()));
                                WaitingForScheduler(Box::new(future_result))
                            } else {
                                // Future is still running
                                result = Poll::Pending;
                                WaitingForFuture(future)
                            }
                        }

                        Poll::Ready(Err(_)) => {
                            // Future never became ready
                            result = Poll::Ready(Err(oneshot::Canceled));
                            Completed
                        }

                        Poll::Pending => {
                            // Waiting for the queue to start this future
                            result = Poll::Pending;
                            WaitingForQueue(recv, create_future)
                        }
                    }
                }
            }

            WaitingForFuture(mut future) => {
                if let Poll::Ready(future_result) = future.poll_unpin(context) {
                    // Future has completed
                    result = Poll::Pending;
                    self.task_finished.take().map(|finished| finished.send(()));
                    WaitingForScheduler(Box::new(future_result))
                } else {
                    // Future is still running
                    result = Poll::Pending;
                    WaitingForFuture(future)
                }
            }

            WaitingForScheduler(future_result) => {
                // Poll until the scheduler has finished running the task entirely (can deadlock while draining if we don't)
                if let Poll::Ready(_) = self.scheduler_future.poll_unpin(context) {
                    result = Poll::Ready(Ok(*future_result));
                    Completed
                } else {
                    result = Poll::Pending;
                    WaitingForScheduler(future_result)
                }
            }

            Completed => {
                // Polling after the result has been returned
                result = Poll::Ready(Err(oneshot::Canceled));
                Completed
            }
        };

        // Swap the state back into the structure
        self.state = state;

        result
    }
}
<commit_msg>Retry when changing to 'WaitingForScheduler' mode<commit_after>use super::scheduler_future::*;

use futures::prelude::*;
use futures::task;
use futures::task::{Poll};
use futures::channel::oneshot;

use std::mem;
use std::pin::*;

///
/// The state of a SyncFuture operation
///
enum SyncFutureState<TFn, TFuture>
where TFuture: Future {
    /// Waiting for the queue to start running the future
    WaitingForQueue(oneshot::Receiver<()>, TFn),

    /// Evaluating an active future for its result
    WaitingForFuture(TFuture),

    /// The sync future has completed and now we're waiting for the scheduler to complete
    WaitingForScheduler(Box<TFuture::Output>),

    /// Finished evaluating
    Completed
}

///
/// Represents a future that runs synchronously with a queue
///
/// The future is only run in an exclusive time slot within the queue - this property is used to guarantee the
/// safety of `Desync::future_sync`, which provides exclusive access to the data store while the future is running.
/// The queue is allowed to continue once the returned future has completed.
///
pub struct SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    /// The state of this future
    state: SyncFutureState<TFn, TFuture>,

    /// Tracks this future on the scheduler (this allows polling this future to invoke desync's thread-stealing semantics instead of leaving the queue scheduling to a separate thread)
    scheduler_future: SchedulerFuture<()>,

    /// Signals when the future has finished running (None if this future is completed)
    task_finished: Option<oneshot::Sender<()>>
}

impl<TFn, TFuture> SyncFuture<TFn, TFuture>
where   TFn:                Send+FnOnce() -> TFuture,
        TFuture:            Send+Future,
        TFuture::Output:    Send {
    ///
    /// Creates a new SyncFuture
    ///
    pub fn new(create_future: TFn, scheduler_future: SchedulerFuture<()>, queue_ready: oneshot::Receiver<()>, task_finished: oneshot::Sender<()>) -> SyncFuture<TFn, TFuture> {
        SyncFuture {
            state:              SyncFutureState::WaitingForQueue(queue_ready, create_future),
            scheduler_future:   scheduler_future,
            task_finished:      Some(task_finished)
        }
    }
}

impl<TFn, TFuture> Future for SyncFuture<TFn, TFuture>
where   TFn:                Unpin+Send+FnOnce() -> TFuture,
        TFuture:            Unpin+Send+Future,
        TFuture::Output:    Send {
    type Output = Result<TFuture::Output, oneshot::Canceled>;

    fn poll(mut self: Pin<&mut Self>, context: &mut task::Context) -> Poll<Self::Output> {
        use self::SyncFutureState::*;

        // Rust doesn't seem to have a way to let us update the state in-place, so we need to swap out the old state and swap in the new state
        let mut result;
        let mut state = Completed;
        mem::swap(&mut state, &mut self.state);

        // Update the state now we own it
        loop {
            // Set to true if a 'pending' result should trigger another state update (eg, if we start a new future, we should poll it)
            let mut retry = false;

            state = match state {
                WaitingForQueue(mut recv, create_future) => {
                    // Check the scheduler future (give it a chance to steal the thread)
                    if let Poll::Ready(Err(_)) = self.scheduler_future.poll_unpin(context) {
                        // The queue will never get to the point of polling this future
                        result = Poll::Ready(Err(oneshot::Canceled));
                        self.task_finished.take().map(|finished| finished.send(()));
                        Completed
                    } else {
                        // Poll the receiver
                        match recv.poll_unpin(context) {
                            Poll::Ready(Ok(())) => {
                                // Start the future
                                let mut future = create_future();

                                // Poll it immediately to determine its status
                                if let Poll::Ready(future_result) = future.poll_unpin(context) {
                                    // Future has completed
                                    result = Poll::Pending;
                                    self.task_finished.take().map(|finished| finished.send(()));

                                    retry = true;
                                    WaitingForScheduler(Box::new(future_result))
                                } else {
                                    // Future is still running
                                    result = Poll::Pending;
                                    WaitingForFuture(future)
                                }
                            }

                            Poll::Ready(Err(_)) => {
                                // Future never became ready
                                result = Poll::Ready(Err(oneshot::Canceled));
                                Completed
                            }

                            Poll::Pending => {
                                // Waiting for the queue to start this future
                                result = Poll::Pending;
                                WaitingForQueue(recv, create_future)
                            }
                        }
                    }
                }

                WaitingForFuture(mut future) => {
                    if let Poll::Ready(future_result) = future.poll_unpin(context) {
                        // Future has completed
                        result = Poll::Pending;
                        self.task_finished.take().map(|finished| finished.send(()));

                        retry = true;
                        WaitingForScheduler(Box::new(future_result))
                    } else {
                        // Future is still running
                        result = Poll::Pending;
                        WaitingForFuture(future)
                    }
                }

                WaitingForScheduler(future_result) => {
                    // Poll until the scheduler has finished running the task entirely (can deadlock while draining if we don't)
                    if let Poll::Ready(_) = self.scheduler_future.poll_unpin(context) {
                        result = Poll::Ready(Ok(*future_result));
                        Completed
                    } else {
                        result = Poll::Pending;
                        WaitingForScheduler(future_result)
                    }
                }

                Completed => {
                    // Polling after the result has been returned
                    result = Poll::Ready(Err(oneshot::Canceled));
                    Completed
                }
            };

            // Finish once retry is left at false
            if !retry {
                break;
            }
        }

        // Swap the state back into the structure
        self.state = state;

        result
    }
}
<|endoftext|>


<commit_before>/*
pub fn serialize<'a, T: Encodable<Encoder<'a>, IoError>>(to_encode_object: &T) -> ~str {
    Encoder::str_encode(to_encode_object)
}
 */

/*
 * Contains all the information on what peers we have, and manages Schooner's interactions
 * with them.
 */
struct NetListener {
    peers: Vec<NetPeer>
}

impl NetListener {
    fn spawn_listener(from_peers_send: Sender<RaftCmd>) {

    }
}
<commit_msg>kill messages.rs<commit_after><|endoftext|>