<commit_before> #![feature(stmt_expr_attributes)]
extern crate x86;
extern crate perfcnt;
extern crate rustc_serialize;
extern crate docopt;
extern crate rand;
extern crate libc;
extern crate time;
extern crate ansi_term;
extern crate pbr;
extern crate csv;
extern crate hwloc;
extern crate num_cpus;
extern crate wait_timeout;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate futures_cpupool;

#[macro_use]
extern crate lazy_static;
extern crate influent;

use ansi_term::Colour::{Green, Yellow};
use std::time::Duration;
use std::collections::HashMap;
use annealing::problem::Problem;
use annealing::solver::seqsea::Seqsea;
use annealing::solver::Solver;
use annealing::solver::common::MrResult;

use std::sync::{Arc, Mutex, Condvar};
use std::sync::RwLock;

use docopt::Docopt;
use std::process::Command;
use std::thread;

mod perf_counters;
mod states_gen;
mod annealing;
mod energy_eval;
mod meter_proxy;
mod results_emitter;

type State = HashMap<String, usize>;

#[derive(Debug, Clone,RustcDecodable)]
pub enum CoolingSchedule {
    linear,
    exponential,
    basic_exp_cooling,
}

#[derive(Debug, Clone,RustcDecodable)]
pub enum SolverVersion {
    seqsea,
    spis,
    mips,
    prsa,
}

#[derive(Debug, Clone, Copy, RustcDecodable)]
pub enum EnergyType {
    throughput,
    latency,
}

#[derive(Debug, Clone,RustcDecodable)]
pub enum ExecutionType {
    sequential,
    parallel,
}

// The Docopt usage string.
const USAGE: &'static str =
    "
Usage:   annealing-tuner [-t] --targ=<targetPath> --args2targ=<args> [-b] \
     --bench=<benchmarkPath> --args2bench=<args> [-ms] --maxSteps=<maxSteps> [-ni] \
     --numIter=<numIter> [-tp] [--maxTemp=<maxTemperature>] [-mt] [--minTemp=<minTemperature>] \
     [-e] --energy=<energy> [-c] --cooling=<cooling> --version=<version>

Options:
    -t,    \
     --targ=<args>     	Target Path.
    --args2targ=<args>          Arguments for Target \
     (Specify Host and Port!).
    -b,    --bench=<args>     	Benchmark Path.
    \
     --args2bench=<args>         Arguments for Benchmark
    -ms,   --maxSteps=<args>    Max \
     Steps of Annealing.
    -ni,   --numIter=<args>     Number of Iterations for each stage of \
     exploration
    -tp,   --maxTemp=<args>     (Optional) Max Temperature.
    -mt,   \
     --minTemp=<args>     (Optional) Min Temperature.
    -e,	   --energy=<args>      Energy to \
     eval (latency or throughput)
    -c,    --cooling=<args>     Cooling Schedule (linear, \
     exponential, basic_exp_cooling)
    -v,	   --version=<args>     Type of solver to use \
     (seqsea, spis, mips, prsa)
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_targ: String,
    flag_bench: String,
    flag_maxSteps: usize,
    flag_numIter: u8,
    flag_maxTemp: Option<f64>,
    flag_minTemp: Option<f64>,
    flag_energy: EnergyType,
    flag_cooling: CoolingSchedule,
    flag_version: SolverVersion,
    flag_args2targ: String,
    flag_args2bench: String,
}

/**
The Annealing Tuner is a tool able to needs in input:

	- The target app
	- The benchmark app
	- An initial default parameter configuration
	- The iteration number r for random selection of initial parameter configuration
	- Fixed number s of random moves for perturbation
**/
/**
Annealing Tuner Entry Point
**/
fn main() {

    /// Collect command line arguments
    ///
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);

    /// Create ParamsConfigurator useful to manage the parameters (or states)
    /// that the simulated annealing algorithm will explore. ParamsConfigurator set initial default parameters
    /// defined in the initial-params.txt input file
    ///
    let params_config = states_gen::ParamsConfigurator {
        param_file_path: "params.conf".to_string(),
        ..states_gen::ParamsConfigurator::default()
    };

    /// Instantiate the EnergyEval struct needed for start/stop the Target and the Benchmark applications
    /// and then evaluate the energy selected by the user
    ///
    let energy_eval = energy_eval::EnergyEval {
        target_path: args.flag_targ,
        bench_path: args.flag_bench,
        target_args: args.flag_args2targ,
        bench_args: args.flag_args2bench,
        num_iter: args.flag_numIter,
    };

    /// Configure the Simulated Annealing problem with the ParamsConfigurator and EnergyEval instances.
    /// Finally,the solver is started
    ///
    let mut problem = Problem {
        params_configurator: params_config,
        energy_evaluator: energy_eval,
    };

    /// Based on the user choice define what type of energy evaluate. Based on this, the Solver will perform
    /// either a maximization problem or a minimization problem
    ///
    let energy_type = match args.flag_energy {
        EnergyType::latency => EnergyType::latency,
        EnergyType::throughput => EnergyType::throughput,
    };

    /// An important aspect of the simulated anneling is how the temperature decrease.
    /// Therefore, the user can choice three types of decreasing function (exp, lin, adapt)
    ///
    let cooling_schedule = match args.flag_cooling {
        CoolingSchedule::exponential => CoolingSchedule::exponential,
        CoolingSchedule::linear => CoolingSchedule::linear,
        CoolingSchedule::basic_exp_cooling => CoolingSchedule::basic_exp_cooling,
    };

    let (t_min, t_max) = eval_temperature(args.flag_minTemp,
                                          args.flag_maxTemp,
                                          energy_type.clone(),
                                          &mut problem);

    let mr_result: MrResult = match args.flag_version {
        SolverVersion::seqsea => {
            let mut solver = annealing::solver::seqsea::Seqsea {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::spis => {
            let mut solver = annealing::solver::spis::Spis {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::mips => {
            let mut solver = annealing::solver::mips::Mips {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::prsa => {
            let mut solver = annealing::solver::prsa::Prsa {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                population_size: 10,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
    };

    println!("{}",Yellow.paint("\n-----------------------------------------------------------------------------------------------------------------------------------------------"));
    println!("{} {:?}",
             Yellow.paint("The Best Configuration found is: "),
             mr_result.state);
    println!("{} {:?}", Yellow.paint("Energy: "), mr_result.energy);
    println!("{}",Yellow.paint("-----------------------------------------------------------------------------------------------------------------------------------------------"));

}

/// Check if the temperature is given by the user or if Tmin and Tmax need to be evaluated
fn eval_temperature(t_min: Option<f64>,
                    t_max: Option<f64>,
                    nrg_type: EnergyType,
                    problem: &mut Problem)
                    -> (f64, f64) {
    let num_exec = 20;
    let ngr_type_c = nrg_type.clone();

    let min_temp = match t_min {
        Some(val) => val,
        None => 1.0,
    };

    let max_temp = match t_max {
        Some(val) => val,
        None => {
            let mut energies = Vec::with_capacity(num_exec);
            /// Search for Tmax: a temperature that gives 98% acceptance
            /// Tmin: equal to 1.
            println!("{} Temperature not provided. Starting its Evaluation",
                     Green.paint("[TUNER]"));
            let mut state = problem.initial_state();
            match problem.energy(&state, nrg_type.clone(), 0) {
                Some(nrg) => energies.push(nrg),
                None => panic!("The initial configuration does not allow to calculate the energy"),
            };

            for i in 0..num_exec {

                let next_state = problem.rand_state();
                match problem.energy(&next_state, ngr_type_c, 0) {
                    Some(new_energy) => {
                        energies.push(new_energy);
                    }
                    None => {
                        println!("{} The current configuration parameters cannot be evaluated. \
                                  Skip!",
                                 Green.paint("[TUNER]"));
                    }
                };
            }

            let desired_prob: f64 = 0.98;
            (energies.iter().cloned().fold(0. / 0., f64::max) -
             energies.iter().cloned().fold(0. / 0., f64::min)) / desired_prob.ln()
        }
    };

    return (min_temp, max_temp);
}
<commit_msg>Added<commit_after> #![feature(stmt_expr_attributes)]
extern crate x86;
extern crate perfcnt;
extern crate rustc_serialize;
extern crate docopt;
extern crate rand;
extern crate libc;
extern crate time;
extern crate ansi_term;
extern crate pbr;
extern crate csv;
extern crate hwloc;
extern crate num_cpus;
extern crate wait_timeout;
#[macro_use]
extern crate futures;
#[macro_use]
extern crate tokio_core;
extern crate futures_cpupool;

#[macro_use]
extern crate lazy_static;
extern crate influent;

use ansi_term::Colour::{Green, Yellow};
use std::time::Duration;
use std::collections::HashMap;
use annealing::problem::Problem;
use annealing::solver::seqsea::Seqsea;
use annealing::solver::Solver;
use annealing::solver::common::MrResult;

use std::sync::{Arc, Mutex, Condvar};
use std::sync::RwLock;

use docopt::Docopt;
use std::process::Command;
use std::thread;

mod perf_counters;
mod states_gen;
mod annealing;
mod energy_eval;
mod meter_proxy;
mod results_emitter;

type State = HashMap<String, usize>;

#[derive(Debug, Clone,RustcDecodable)]
pub enum CoolingSchedule {
    linear,
    exponential,
    basic_exp_cooling,
}

#[derive(Debug, Clone,RustcDecodable)]
pub enum SolverVersion {
    seqsea,
    spis,
    mips,
    prsa,
}

#[derive(Debug, Clone, Copy, RustcDecodable)]
pub enum EnergyType {
    throughput,
    latency,
}

#[derive(Debug, Clone,RustcDecodable)]
pub enum ExecutionType {
    sequential,
    parallel,
}

//The Docopt usage string.
const USAGE: &'static str = "
Usage:   annealing-tuner [-t] --targ=<targetPath> --args2targ=<args> [-b] --bench=<benchmarkPath> --args2bench=<args> [-ms] --maxSteps=<maxSteps> [-ni] --numIter=<numIter> [-tp] [--maxTemp=<maxTemperature>] [-mt] [--minTemp=<minTemperature>] [-e] --energy=<energy> [-c] --cooling=<cooling> --version=<version>

Options:
    -t,    --targ=<args>     	Target Path.
    --args2targ=<args>          Arguments for Target (Specify Host and Port!).
    -b,    --bench=<args>     	Benchmark Path.
    --args2bench=<args>         Arguments for Benchmark
    -ms,   --maxSteps=<args>    Max Steps of Annealing.
    -ni,   --numIter=<args>     Number of Iterations for each stage of exploration
    -tp,   --maxTemp=<args>     (Optional) Max Temperature.
    -mt,   --minTemp=<args>     (Optional) Min Temperature.
    -e,	   --energy=<args>      Energy to eval (latency or throughput)
    -c,    --cooling=<args>     Cooling Schedule (linear, exponential, basic_exp_cooling)
    -v,	   --version=<args>     Type of solver to use (seqsea, spis, mips, prsa)
";

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_targ: String,
    flag_bench: String,
    flag_maxSteps: usize,
    flag_numIter: u8,
    flag_maxTemp: Option<f64>,
    flag_minTemp: Option<f64>,
    flag_energy: EnergyType,
    flag_cooling: CoolingSchedule,
    flag_version: SolverVersion,
    flag_args2targ: String,
    flag_args2bench: String,
}

/**
The Annealing Tuner is a tool able to needs in input:

	- The target app
	- The benchmark app
	- An initial default parameter configuration
	- The iteration number r for random selection of initial parameter configuration
	- Fixed number s of random moves for perturbation
**/
/**
Annealing Tuner Entry Point
**/
fn main() {

    /// Collect command line arguments
    ///
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());
    println!("{:?}", args);

    /// Create ParamsConfigurator useful to manage the parameters (or states)
    /// that the simulated annealing algorithm will explore. ParamsConfigurator set initial default parameters
    /// defined in the initial-params.txt input file
    ///
    let params_config = states_gen::ParamsConfigurator {
        param_file_path: "params.conf".to_string(),
        ..states_gen::ParamsConfigurator::default()
    };

    /// Instantiate the EnergyEval struct needed for start/stop the Target and the Benchmark applications
    /// and then evaluate the energy selected by the user
    ///
    let energy_eval = energy_eval::EnergyEval {
        target_path: args.flag_targ,
        bench_path: args.flag_bench,
        target_args: args.flag_args2targ,
        bench_args: args.flag_args2bench,
        num_iter: args.flag_numIter,
    };

    /// Configure the Simulated Annealing problem with the ParamsConfigurator and EnergyEval instances.
    /// Finally,the solver is started
    ///
    let mut problem = Problem {
        params_configurator: params_config,
        energy_evaluator: energy_eval,
    };

    /// Based on the user choice define what type of energy evaluate. Based on this, the Solver will perform
    /// either a maximization problem or a minimization problem
    ///
    let energy_type = match args.flag_energy {
        EnergyType::latency => EnergyType::latency,
        EnergyType::throughput => EnergyType::throughput,
    };

    /// An important aspect of the simulated anneling is how the temperature decrease.
    /// Therefore, the user can choice three types of decreasing function (exp, lin, adapt)
    ///
    let cooling_schedule = match args.flag_cooling {
        CoolingSchedule::exponential => CoolingSchedule::exponential,
        CoolingSchedule::linear => CoolingSchedule::linear,
        CoolingSchedule::basic_exp_cooling => CoolingSchedule::basic_exp_cooling,
    };

    let (t_min, t_max) = eval_temperature(args.flag_minTemp,
                                          args.flag_maxTemp,
                                          energy_type.clone(),
                                          &mut problem);

    let mr_result: MrResult = match args.flag_version {
        SolverVersion::seqsea => {
            let mut solver = annealing::solver::seqsea::Seqsea {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::spis => {
            let mut solver = annealing::solver::spis::Spis {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::mips => {
            let mut solver = annealing::solver::mips::Mips {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
        SolverVersion::prsa => {
            let mut solver = annealing::solver::prsa::Prsa {
                min_temp: t_min,
                max_temp: t_max,
                max_steps: args.flag_maxSteps,
                population_size: 10,
                energy_type: energy_type,
                cooling_schedule: cooling_schedule.clone(),
            };

            solver.solve(&mut problem)
        }
    };

    println!("{}",Yellow.paint("\n-----------------------------------------------------------------------------------------------------------------------------------------------"));
    println!("{} {:?}",
             Yellow.paint("The Best Configuration found is: "),
             mr_result.state);
    println!("{} {:?}", Yellow.paint("Energy: "), mr_result.energy);
    println!("{}",Yellow.paint("-----------------------------------------------------------------------------------------------------------------------------------------------"));

}

/// Check if the temperature is given by the user or if Tmin and Tmax need to be evaluated
fn eval_temperature(t_min: Option<f64>,
                    t_max: Option<f64>,
                    nrg_type: EnergyType,
                    problem: &mut Problem)
                    -> (f64, f64) {
    let num_exec = 20;
    let ngr_type_c = nrg_type.clone();

    let min_temp = match t_min {
        Some(val) => val,
        None => 1.0,
    };

    let max_temp = match t_max {
        Some(val) => val,
        None => {
            let mut energies = Vec::with_capacity(num_exec);
            /// Search for Tmax: a temperature that gives 98% acceptance
            /// Tmin: equal to 1.
            println!("{} Temperature not provided. Starting its Evaluation",
                     Green.paint("[TUNER]"));
            let mut state = problem.initial_state();
            match problem.energy(&state, nrg_type.clone(), 0) {
                Some(nrg) => energies.push(nrg),
                None => panic!("The initial configuration does not allow to calculate the energy"),
            };

            for i in 0..num_exec {

                let next_state = problem.rand_state();
                match problem.energy(&next_state, ngr_type_c, 0) {
                    Some(new_energy) => {
                        energies.push(new_energy);
                    }
                    None => {
                        println!("{} The current configuration parameters cannot be evaluated. \
                                  Skip!",
                                 Green.paint("[TUNER]"));
                    }
                };
            }

            let desired_prob: f64 = 0.98;
            (energies.iter().cloned().fold(0. / 0., f64::max) -
             energies.iter().cloned().fold(0. / 0., f64::min)) / desired_prob.ln()
        }
    };

    return (min_temp, max_temp);
}
<|endoftext|>


<commit_before>use std::thread;
use std::net;

fn socket(listen_on: net::SocketAddr) -> net::UdpSocket {
    let attempt = net::UdpSocket::bind(listen_on);
    let mut socket;
    match attempt {
        Ok(sock) => {
            println!("Bound socket to {}", listen_on);
            socket = sock;
        },
    Err(err) => panic!("Could not bind: {}", err)
    }
    socket
}

fn read_message(socket: net::UdpSocket) -> Vec<u8> {
    let mut buf: [u8; 1] = [0; 1];
    println!("Reading data");
    let result = socket.recv_from(&mut buf);
    drop(socket);
    let mut data;
    match result {
        Ok((amt, src)) => {
        println!("Received data from {}", src);
        data = Vec::from(&buf[0..amt]);
        },
    Err(err) => panic!("Read error: {}", err)
    }
    data
}

pub fn send_message(send_addr: net::SocketAddr, target: net::SocketAddr, data: Vec<u8>) {
    let socket = socket(send_addr);
    println!("Sending data");
    let result = socket.send_to(&data, target);
    drop(socket);
    match result {
        Ok(amt) => println!("Sent {} bytes", amt),
        Err(err) => panic!("Write error: {}", err)
    }
}

pub fn listen(listen_on: net::SocketAddr) -> thread::JoinHandle<Vec<u8>> {
    let socket = socket(listen_on);
    let handle = thread::spawn(move || {
        read_message(socket)
    });
    handle
}

#[cfg(test)]
mod test {
    use std::net;
    use std::thread;
    use super::*;

    #[test]
    fn test_udp() {
        println!("UDP");
        let ip = net::Ipv4Addr::new(127, 0, 0, 1);
        let listen_addr = net::SocketAddrV4::new(ip, 8888);
        let send_addr = net::SocketAddrV4::new(ip, 8889);
        let future = listen(net::SocketAddr::V4(listen_addr));
        let message: Vec<u8> = vec![10];
        // give the thread 3s to open the socket
        thread::sleep_ms(3000);
        send_message(
            net::SocketAddr::V4(send_addr),
            net::SocketAddr::V4(listen_addr),
            message);
        println!("Waiting");
        let received = future.join().unwrap();
        println!("Got {} bytes", received.len());
        assert_eq!(1, received.len());
        assert_eq!(10, received[0]);
    }
}

fn main() {
    let ip = net::Ipv4Addr::new(127, 0, 0, 1);
    let listen_addr = net::SocketAddrV4::new(ip, 1738);
    let send_addr = net::SocketAddrV4::new(ip, 0);
    let s = "red".to_string();
    let mut message: Vec<u8> = Vec::new();
    message.extend(s.as_bytes().iter().cloned());
    send_message(
        net::SocketAddr::V4(send_addr),
        net::SocketAddr::V4(listen_addr),
        message);
}
<commit_msg>First pass at working program<commit_after>use std::thread;
use std::net;
use std::env;

fn socket(listen_on: net::SocketAddr) -> net::UdpSocket {
    let attempt = net::UdpSocket::bind(listen_on);
    let mut socket;
    match attempt {
        Ok(sock) => {
            socket = sock;
        },
    Err(err) => panic!("Could not bind: {}", err)
    }
    socket
}

fn read_message(socket: net::UdpSocket) -> Vec<u8> {
    let mut buf: [u8; 1] = [0; 1];
    let result = socket.recv_from(&mut buf);
    drop(socket);
    let mut data;
    match result {
        Ok((amt, src)) => {
        data = Vec::from(&buf[0..amt]);
        },
    Err(err) => panic!("Read error: {}", err)
    }
    data
}

pub fn send_message(send_addr: net::SocketAddr, target: net::SocketAddr, data: Vec<u8>) {
    let socket = socket(send_addr);
    let result = socket.send_to(&data, target);
    drop(socket);
    // match result {
    //     Ok(amt) => println!("Sent {} bytes", amt),
    //     Err(err) => panic!("Write error: {}", err)
    // }
}

pub fn listen(listen_on: net::SocketAddr) -> thread::JoinHandle<Vec<u8>> {
    let socket = socket(listen_on);
    let handle = thread::spawn(move || {
        read_message(socket)
    });
    handle
}

#[cfg(test)]
mod test {
    use std::net;
    use std::thread;
    use super::*;

    #[test]
    fn test_udp() {
        println!("UDP");
        let ip = net::Ipv4Addr::new(127, 0, 0, 1);
        let listen_addr = net::SocketAddrV4::new(ip, 8888);
        let send_addr = net::SocketAddrV4::new(ip, 8889);
        let future = listen(net::SocketAddr::V4(listen_addr));
        let message: Vec<u8> = vec![10];
        // give the thread 3s to open the socket
        thread::sleep_ms(3000);
        send_message(
            net::SocketAddr::V4(send_addr),
            net::SocketAddr::V4(listen_addr),
            message);
        println!("Waiting");
        let received = future.join().unwrap();
        println!("Got {} bytes", received.len());
        assert_eq!(1, received.len());
        assert_eq!(10, received[0]);
    }
}

fn main() {
    // get command-line input

    // this waits on a prompt, so
    // http://stackoverflow.com/a/27973038/416626
    // use std::io;
    // use std::io::prelude::*;
    // let stdin = io::stdin();
    // let inp = stdin
    //     .lock()
    //     .lines()
    //     .next()
    //     .unwrap()
    //     .unwrap()
    //     .trim()
    //     .to_string();

    // Strings do not live for the entire life of your program
    // http://stackoverflow.com/a/23977218/416626
    let args: Vec<String> = env::args().collect();
    let arg = args[1].clone();
    let intermediate: &str = &*arg;

    // match input or bail out horribly
    let to_send = match intermediate {
        "white" => "white".to_string(),
        "red" => "red".to_string(),
        "orange" => "orange".to_string(),
        "yellow" => "yellow".to_string(),
        "green" => "green".to_string(),
        "cyan" => "cyan".to_string(),
        "blue" => "blue".to_string(),
        "purple" => "purple".to_string(),
        "black" => "black".to_string(),
        "?" => "question".to_string(),
        "!" => "exclamation".to_string(),
        "quit" => "quit".to_string(),
        _ => panic!("Unknown option!")
    };

    let mut message: Vec<u8> = Vec::new();
    message.extend(to_send.as_bytes().iter().cloned());
    let ip = net::Ipv4Addr::new(127, 0, 0, 1);
    let listen_addr = net::SocketAddrV4::new(ip, 1738);
    let send_addr = net::SocketAddrV4::new(ip, 0);
    send_message(
        net::SocketAddr::V4(send_addr),
        net::SocketAddr::V4(listen_addr),
        message);
}
<|endoftext|>


<commit_before>// #![deny(warnings)]

extern crate clap;
extern crate fern;
extern crate rustc_version;
extern crate tempdir;

#[macro_use]
extern crate log;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use std::process::{Command, Stdio};

use clap::{App, AppSettings, Arg, SubCommand};

// TODO proper error reporting
macro_rules! try {
    ($e:expr) => {
        $e.unwrap_or_else(|_| panic!(stringify!($e)))
    }
}

struct Context<'a> {
    commit_hash: &'a str,
    host: &'a str,
    out_dir: &'a Path,
    release: bool,
    target: &'a str,
}

fn main() {
    let rustc_version::VersionMeta { ref host, ref commit_hash, .. } =
        rustc_version::version_meta();
    let commit_hash = commit_hash.as_ref().unwrap();

    let ref matches = App::new("cargo-sysroot")
                          .bin_name("cargo")
                          .settings(&[AppSettings::SubcommandRequired])
                          .subcommand(SubCommand::with_name("sysroot")
                                          .about("Builds a sysroot with cross compiled standard \
                                                  crates")
                                          .arg(Arg::with_name("triple")
                                                   .help("Target triple to compile for")
                                                   .long("target")
                                                   .required(true)
                                                   .takes_value(true))
                                          .arg(Arg::with_name("release")
                                                   .help("Build artifacts in release mode, \
                                                          with optimizations")
                                                   .long("release"))
                                          .arg(Arg::with_name("out_dir")
                                                   .help("Output directory")
                                                   .required(true))
                                          .author("Jorge Aparicio <japaricious@gmail.com>"))
                          .version(env!("CARGO_PKG_VERSION"))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("sysroot") {
        if let (Some(target), Some(out_dir)) = (matches.value_of("triple"),
                                                matches.value_of("out_dir")) {
            if host == target {
                panic!("`cargo sysroot` for host has not been implement yet");
            }

            let ref ctx = Context {
                commit_hash: commit_hash,
                host: host,
                out_dir: Path::new(out_dir),
                release: matches.is_present("release"),
                target: target,
            };

            init_logger();
            fetch_source(ctx);
            symlink_host_crates(ctx);
            build_target_crates(ctx);
        }
    }
}

fn init_logger() {
    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, _| format!("{}: {}", level, msg)),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Trace,
    };

    try!(fern::init_global_logger(config, log::LogLevelFilter::Trace));
}

fn fetch_source(ctx: &Context) {
    let hash = ctx.commit_hash;
    let ref src_dir = ctx.out_dir.join("src");
    let ref hash_file = src_dir.join(".commit-hash");

    if hash_file.exists() {
        let ref mut old_hash = String::with_capacity(hash.len());
        try!(try!(File::open(hash_file)).read_to_string(old_hash));

        if old_hash == hash {
            info!("source up to date");
            return;
        }
    }

    if src_dir.exists() {
        info!("purging the src directory");
        try!(fs::remove_dir_all(src_dir));
    }

    try!(fs::create_dir_all(src_dir));

    info!("fetching source tarball");
    let ref curl = try!(Command::new("curl")
                            .arg("-L")
                            .arg(format!("https://github.com/rust-lang/rust/tarball/{}", hash))
                            .output());

    assert!(curl.status.success());

    info!("unpacking source tarball");
    let short_hash = &hash[..7];
    let ref mut tar = try!(Command::new("tar")
                               .args(&["-xz", "--strip-components", "2", "-C"])
                               .arg(src_dir)
                               .arg(format!("rust-lang-rust-{}/src", short_hash))
                               .stdin(Stdio::piped())
                               .spawn());
    try!(tar.stdin.as_mut().unwrap().write_all(&curl.stdout));

    info!("creating .commit-hash file");
    try!(try!(File::create(hash_file)).write_all(hash.as_bytes()));
}

fn symlink_host_crates(ctx: &Context) {
    info!("symlinking host crates");

    let sys_root = try!(String::from_utf8(try!(Command::new("rustc")
                                                   .args(&["--print", "sysroot"])
                                                   .output())
                                              .stdout));
    let ref src = Path::new(sys_root.trim_right()).join(format!("lib/rustlib/{}", ctx.host));
    let ref rustlib_dir = ctx.out_dir.join("lib/rustlib");
    let ref dst = rustlib_dir.join(ctx.host);

    try!(fs::create_dir_all(rustlib_dir));

    if dst.exists() {
        try!(fs::remove_file(dst));
    }

    match () {
        #[cfg(unix)]
        () => {
            use std::os::unix::fs;

            try!(fs::symlink(src, dst))
        }
        #[cfg(windows)]
        () => {
            use std::os::windaws::fs;

            try!(fs::symlink_dir(src, dst))
        }
    }
}

// XXX we only build the core crate for now
// TODO build the rest of crates
fn build_target_crates(ctx: &Context) {
    const CARGO_TOML: &'static str = r#"[package]
authors = ["The Rust Project Developers"]
name = "core"
version = "0.0.0"

[lib]
name = "core"
path = "lib.rs""#;

    let ref src_dir = ctx.out_dir.join("src/libcore");

    try!(try!(File::create(src_dir.join("Cargo.toml"))).write_all(CARGO_TOML.as_bytes()));

    let ref temp_dir = try!(tempdir::TempDir::new("core"));
    let temp_dir = temp_dir.path();

    info!("building the core crate");
    assert!(try!(Command::new("cargo")
                     .args(&["build", "--target"])
                     .arg(ctx.target)
                     .arg(if ctx.release {
                         "--release"
                     } else {
                         // XXX dummy value
                         "--lib"
                     })
                     .current_dir(src_dir)
                     .env("CARGO_TARGET_DIR", temp_dir)
                     .status())
                .success());

    info!("copy the core crate to the sysroot");
    let ref libdir = ctx.out_dir.join(format!("lib/rustlib/{}/lib", ctx.target));
    try!(fs::create_dir_all(libdir));

    let ref src = temp_dir.join(format!("{}/{}/libcore.rlib",
                                        ctx.target,
                                        if ctx.release {
                                            "release"
                                        } else {
                                            "debug"
                                        }));
    let ref dst = libdir.join("libcore.rlib");
    try!(fs::copy(src, dst));
}
<commit_msg>refactor: deny warnings<commit_after>#![deny(warnings)]

extern crate clap;
extern crate fern;
extern crate rustc_version;
extern crate tempdir;

#[macro_use]
extern crate log;

use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::Path;
use std::process::{Command, Stdio};

use clap::{App, AppSettings, Arg, SubCommand};

// TODO proper error reporting
macro_rules! try {
    ($e:expr) => {
        $e.unwrap_or_else(|_| panic!(stringify!($e)))
    }
}

struct Context<'a> {
    commit_hash: &'a str,
    host: &'a str,
    out_dir: &'a Path,
    release: bool,
    target: &'a str,
}

fn main() {
    let rustc_version::VersionMeta { ref host, ref commit_hash, .. } =
        rustc_version::version_meta();
    let commit_hash = commit_hash.as_ref().unwrap();

    let ref matches = App::new("cargo-sysroot")
                          .bin_name("cargo")
                          .settings(&[AppSettings::SubcommandRequired])
                          .subcommand(SubCommand::with_name("sysroot")
                                          .about("Builds a sysroot with cross compiled standard \
                                                  crates")
                                          .arg(Arg::with_name("triple")
                                                   .help("Target triple to compile for")
                                                   .long("target")
                                                   .required(true)
                                                   .takes_value(true))
                                          .arg(Arg::with_name("release")
                                                   .help("Build artifacts in release mode, \
                                                          with optimizations")
                                                   .long("release"))
                                          .arg(Arg::with_name("out_dir")
                                                   .help("Output directory")
                                                   .required(true))
                                          .author("Jorge Aparicio <japaricious@gmail.com>"))
                          .version(env!("CARGO_PKG_VERSION"))
                          .get_matches();

    if let Some(matches) = matches.subcommand_matches("sysroot") {
        if let (Some(target), Some(out_dir)) = (matches.value_of("triple"),
                                                matches.value_of("out_dir")) {
            if host == target {
                panic!("`cargo sysroot` for host has not been implement yet");
            }

            let ref ctx = Context {
                commit_hash: commit_hash,
                host: host,
                out_dir: Path::new(out_dir),
                release: matches.is_present("release"),
                target: target,
            };

            init_logger();
            fetch_source(ctx);
            symlink_host_crates(ctx);
            build_target_crates(ctx);
        }
    }
}

fn init_logger() {
    let config = fern::DispatchConfig {
        format: Box::new(|msg, level, _| format!("{}: {}", level, msg)),
        output: vec![fern::OutputConfig::stderr()],
        level: log::LogLevelFilter::Trace,
    };

    try!(fern::init_global_logger(config, log::LogLevelFilter::Trace));
}

fn fetch_source(ctx: &Context) {
    let hash = ctx.commit_hash;
    let ref src_dir = ctx.out_dir.join("src");
    let ref hash_file = src_dir.join(".commit-hash");

    if hash_file.exists() {
        let ref mut old_hash = String::with_capacity(hash.len());
        try!(try!(File::open(hash_file)).read_to_string(old_hash));

        if old_hash == hash {
            info!("source up to date");
            return;
        }
    }

    if src_dir.exists() {
        info!("purging the src directory");
        try!(fs::remove_dir_all(src_dir));
    }

    try!(fs::create_dir_all(src_dir));

    info!("fetching source tarball");
    let ref curl = try!(Command::new("curl")
                            .arg("-L")
                            .arg(format!("https://github.com/rust-lang/rust/tarball/{}", hash))
                            .output());

    assert!(curl.status.success());

    info!("unpacking source tarball");
    let short_hash = &hash[..7];
    let ref mut tar = try!(Command::new("tar")
                               .args(&["-xz", "--strip-components", "2", "-C"])
                               .arg(src_dir)
                               .arg(format!("rust-lang-rust-{}/src", short_hash))
                               .stdin(Stdio::piped())
                               .spawn());
    try!(tar.stdin.as_mut().unwrap().write_all(&curl.stdout));

    info!("creating .commit-hash file");
    try!(try!(File::create(hash_file)).write_all(hash.as_bytes()));
}

fn symlink_host_crates(ctx: &Context) {
    info!("symlinking host crates");

    let sys_root = try!(String::from_utf8(try!(Command::new("rustc")
                                                   .args(&["--print", "sysroot"])
                                                   .output())
                                              .stdout));
    let ref src = Path::new(sys_root.trim_right()).join(format!("lib/rustlib/{}", ctx.host));
    let ref rustlib_dir = ctx.out_dir.join("lib/rustlib");
    let ref dst = rustlib_dir.join(ctx.host);

    try!(fs::create_dir_all(rustlib_dir));

    if dst.exists() {
        try!(fs::remove_file(dst));
    }

    match () {
        #[cfg(unix)]
        () => {
            use std::os::unix::fs;

            try!(fs::symlink(src, dst))
        }
        #[cfg(windows)]
        () => {
            use std::os::windaws::fs;

            try!(fs::symlink_dir(src, dst))
        }
    }
}

// XXX we only build the core crate for now
// TODO build the rest of crates
fn build_target_crates(ctx: &Context) {
    const CARGO_TOML: &'static str = r#"[package]
authors = ["The Rust Project Developers"]
name = "core"
version = "0.0.0"

[lib]
name = "core"
path = "lib.rs""#;

    let ref src_dir = ctx.out_dir.join("src/libcore");

    try!(try!(File::create(src_dir.join("Cargo.toml"))).write_all(CARGO_TOML.as_bytes()));

    let ref temp_dir = try!(tempdir::TempDir::new("core"));
    let temp_dir = temp_dir.path();

    info!("building the core crate");
    assert!(try!(Command::new("cargo")
                     .args(&["build", "--target"])
                     .arg(ctx.target)
                     .arg(if ctx.release {
                         "--release"
                     } else {
                         // XXX dummy value
                         "--lib"
                     })
                     .current_dir(src_dir)
                     .env("CARGO_TARGET_DIR", temp_dir)
                     .status())
                .success());

    info!("copy the core crate to the sysroot");
    let ref libdir = ctx.out_dir.join(format!("lib/rustlib/{}/lib", ctx.target));
    try!(fs::create_dir_all(libdir));

    let ref src = temp_dir.join(format!("{}/{}/libcore.rlib",
                                        ctx.target,
                                        if ctx.release {
                                            "release"
                                        } else {
                                            "debug"
                                        }));
    let ref dst = libdir.join("libcore.rlib");
    try!(fs::copy(src, dst));
}
<|endoftext|>


<commit_before>#![feature(plugin)]
#![plugin(docopt_macros)]

#[macro_use]
extern crate docopt;
extern crate env_logger;
extern crate rustc_serialize;
extern crate website;

const DEFAULT_PORT: u16 = 9000;

docopt!(Args derive Debug, r"
My personal website.

Usage:
    website [<port>]
", arg_port: Option<u16>);

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

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    website::listen(("localhost", args.arg_port.unwrap_or(DEFAULT_PORT)))
}
<commit_msg>feat(log): set default log output level to "info"<commit_after>#![feature(plugin)]
#![plugin(docopt_macros)]

#[macro_use]
extern crate docopt;
extern crate env_logger;
extern crate log;
extern crate rustc_serialize;
extern crate website;

use env_logger::LogBuilder;
use log::LogLevelFilter;

const DEFAULT_PORT: u16 = 9000;

docopt!(Args derive Debug, r"
My personal website.

Usage:
    website [<port>]
", arg_port: Option<u16>);

fn main() {
    LogBuilder::new().filter(None, LogLevelFilter::Info).init().unwrap();

    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    website::listen(("localhost", args.arg_port.unwrap_or(DEFAULT_PORT)))
}
<|endoftext|>


<commit_before>enum Tetromino {
    I,
    O,
    T,
    J,
    L,
    S,
    Z,
}

struct Block {
    shape: Tetromino,
    anchor: (i32, i32),
}

impl Block {
    fn new(tetris: Tetromino) -> Block {
        Block {
            shape: tetris,
            anchor: (-1, -1),
        }
    }
}

struct Board {
    filled: bool,
}

impl Board {
    fn new(width: i32, height: i32) -> Vec<Vec<Board>> {

        let mut board: Vec<Vec<Board>> = Vec::new();
        for w in 0..width {

            let mut innerBoard: Vec<Board> = Vec::new();
            for h in 0..height {
                innerBoard.push(Board { filled: false });
            }

            board.push(innerBoard);
        }

        return board;
    }
}

fn main() {
    println!("Hello, world!");
    let width = 7;
    let height = 4;

    let mut board = Board::new(width, height);
    let mut blocks: Vec<Block> = vec![
        Block::new(Tetromino::I),
        Block::new(Tetromino::I),
        Block::new(Tetromino::T),
        Block::new(Tetromino::T),
        Block::new(Tetromino::S),
        Block::new(Tetromino::Z),
        Block::new(Tetromino::L)
    ];

    let x = &blocks[6];

    match x.shape {
        Tetromino::I => println!("I shape"),
        Tetromino::O => println!("O shape"),
        Tetromino::T => println!("T shape"),
        Tetromino::J => println!("J shape"),
        Tetromino::L => println!("L shape"),
        Tetromino::S => println!("S shape"),
        Tetromino::Z => println!("Z shape"),
    }
}

<commit_msg>prints board to console<commit_after>enum Tetromino {
    I,
    O,
    T,
    J,
    L,
    S,
    Z,
}

struct Block {
    shape: Tetromino,
    anchor: (i32, i32),
}

impl Block {
    fn new(tetris: Tetromino) -> Block {
        Block {
            shape: tetris,
            anchor: (-1, -1),
        }
    }
}

struct Board {
    filled: bool,
}

impl Board {
    fn new(row: i32, col: i32) -> Vec<Vec<Board>> {

        let mut board: Vec<Vec<Board>> = Vec::new();
        for w in 0..row {

            let mut innerBoard: Vec<Board> = Vec::new();
            for h in 0..col {
                innerBoard.push(Board { filled: false });
            }

            board.push(innerBoard);
        }

        return board;
    }

}

fn main() {
    // TODO: make it a dynamic board
    let R = 4;
    let C = 7;

    let mut board = Board::new(R, C);

    // TODO: put in a printing function
    for row in board {
        for col in row {
            match col.filled {
                true => print!("[X]"),
                false => print!("[ ]")
            }
        }
        println!("");
    }

    // Test data
    let mut blocks: Vec<Block> = vec![
        Block::new(Tetromino::I),
        Block::new(Tetromino::I),
        Block::new(Tetromino::T),
        Block::new(Tetromino::T),
        Block::new(Tetromino::S),
        Block::new(Tetromino::Z),
        Block::new(Tetromino::L)
    ];

    let x = &blocks[6];

    // test matching
    match x {
        &Block { shape: Tetromino::I, .. } => println!("I shape"),
        &Block { shape: Tetromino::O, .. } => println!("O shape"),
        &Block { shape: Tetromino::T, .. } => println!("T shape"),
        &Block { shape: Tetromino::J, .. } => println!("J shape"),
        &Block { shape: Tetromino::L, .. } => println!("L shape"),
        &Block { shape: Tetromino::S, .. } => println!("S shape"),
        &Block { shape: Tetromino::Z, .. } => println!("Z shape"),
    }
}

<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
extern crate leveldb;
extern crate glob;
extern crate rustc_serialize;

use rustc_serialize::json::Json;
use glob::glob;
use clap::App;
use leveldb::database::Database;
use leveldb::kv::KV;
use leveldb::options::{Options, WriteOptions};
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;

fn main() {
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();

    let dbpath = match matches.value_of("dbpath") {
        Some(userpath) => PathBuf::new().join(userpath),
        _ => std::env::temp_dir().join("ldp-coldstorage")
    };

    let srcpattern = matches.value_of("srcpattern").unwrap_or("*");
    let srcpath = match matches.value_of("srcpath") {
        Some(userpath) => PathBuf::new().join(userpath).join(srcpattern),
        _ => std::env::current_dir().unwrap().join(srcpattern)
    };
    println!("Using source pattern: {}", srcpath.display());

    let mut options = Options::new();
    options.create_if_missing = true;
    let db: Database<i32> = match Database::open(dbpath.as_path(), options) {
        Ok(db) => db,
        Err(e) => panic!("failed to open database: {:?}", e)
    };
    println!("Using database path: {}", dbpath.display());

    for entry in glob(srcpath.to_str().unwrap()).expect("Failed to read glob pattern") {
        match entry {
            Ok(path) => {
                if path.is_dir() == false {
                    let mut f = File::open(path.to_str().unwrap()).unwrap();
                    let mut file = BufReader::new(&f);
                    for line in file.lines() {
                        let l = line.unwrap();
                        match Json::from_str(l.trim()) {
                            Ok(jdata) => println!("ok => {}", l),
                            _ => println!("failed => {}", l)
                        }
                    };
                }
            },
            Err(e) => println!("{:?}", e),
        }
    }
}
<commit_msg>devel: line number<commit_after>#[macro_use]
extern crate clap;
extern crate leveldb;
extern crate glob;
extern crate rustc_serialize;

use rustc_serialize::json::Json;
use glob::glob;
use clap::App;
use leveldb::database::Database;
use leveldb::kv::KV;
use leveldb::options::{Options, WriteOptions};
use std::path::{Path, PathBuf};
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;

fn main() {
    let yaml = load_yaml!("cli.yml");
    let matches = App::from_yaml(yaml).get_matches();

    let dbpath = match matches.value_of("dbpath") {
        Some(userpath) => PathBuf::new().join(userpath),
        _ => std::env::temp_dir().join("ldp-coldstorage")
    };

    let srcpattern = matches.value_of("srcpattern").unwrap_or("*");
    let srcpath = match matches.value_of("srcpath") {
        Some(userpath) => PathBuf::new().join(userpath).join(srcpattern),
        _ => std::env::current_dir().unwrap().join(srcpattern)
    };
    println!("Using source pattern: {}", srcpath.display());

    let mut options = Options::new();
    options.create_if_missing = true;
    let db: Database<i32> = match Database::open(dbpath.as_path(), options) {
        Ok(db) => db,
        Err(e) => panic!("failed to open database: {:?}", e)
    };
    println!("Using database path: {}", dbpath.display());

    for entry in glob(srcpath.to_str().unwrap()).expect("Failed to read glob pattern") {
        match entry {
            Ok(path) => {
                if path.is_dir() == false {
                    let mut f = File::open(path.to_str().unwrap()).unwrap();
                    let mut file = BufReader::new(&f);
                    for (lineno, data) in file.lines().enumerate() {
                        let l = data.unwrap();
                        match Json::from_str(l.trim()) {
                            Ok(jdata) => println!("ok => {} - {}", lineno, l),
                            _ => println!("failed => {} - {}", lineno, l)
                        }
                    };
                }
            },
            Err(e) => println!("{:?}", e),
        }
    }
}
<|endoftext|>


<commit_before>#![feature(phase)]
#[phase(plugin, link)] extern crate log;

const U4_LOW:  u8 = 0b00001111;
const U4_HIGH: u8 = 0b11110000;

enum CpuState {
	Continue,
	Halt,
}

/// The P150 virtual machine
struct P150Cpu {
	ip:  u8,
	ir: u16,

	reg: [u8, ..16],
	mem: [u8, ..256],
}

impl P150Cpu {
	/// Initializes the P150 CPU
	///
	/// NOTE: This implementation 0s memory; but this is not guaranteed
	/// by the machine specification.
	///
	/// Programs must start at memory address 0x00
	fn new() -> P150Cpu {
		P150Cpu {
			ip:  0x00,
			ir:  0x0000,

			reg: [0u8, ..16],
			mem: [0u8, ..256],
		}
	}

	/// Prints the current machine state to the console window
	/// This includes the IP, IR, and all registers.
	/// (Registers will be formatted as 2s complement numbers.)
	fn dump(&self) {
		println!("IP: 0x{:02X}, IR: 0x{:04X}", self.ip, self.ir);

		println!("Registers")
		for (addr, cell) in self.reg.iter().enumerate() {
			println!("{}: {}", addr, cell)
		}
	}

	/// Read an array of instructions into memory
	/// This reads two bytes at a time from the `memory` array
	/// and loads them into the P150s RAM bank, starting from address 0.
	fn init_mem(&mut self, memory: &[u16]) {
		let mut next_cell = 0x00;

		for op in memory.iter() {
			let byte_1 = (*op >> 8) as u8;
			let byte_2 = *op as u8;

			self.mem[next_cell]     = byte_1;
			self.mem[next_cell + 1] = byte_2;
			next_cell += 2
		}
	}

	/// Runs the entire fetch, execute, decode cycle against the current IP
	fn tick(&mut self) -> CpuState {
		self.fetch();

		// decode
		let op = (self.ir >> 12) as u8;
		match op {
			0x0   => { // ADDB
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);   // first input: lower nibble of first byte
				let rloc_i1 = h_nibble(self.ir as u8);          // second input: upper nibble of second byte
				let rloc_o0 = l_nibble(self.ir as u8);          // output: lower nibble of second byte

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] + self.reg[rloc_i1 as uint];
				Continue
			},

			0x3   => { // AND
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] & self.reg[rloc_i1 as uint];
				Continue
			},

			0x4   => { // OR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] | self.reg[rloc_i1 as uint];
				Continue
			},

			0x5   => { // XOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] ^ self.reg[rloc_i1 as uint];
				Continue
			},

			0x6   => { // MLOAD
				let rloc_o0 = l_nibble((self.ir >> 8) as u8);
				let mloc_i0 = self.ir as u8;

				self.reg[rloc_o0 as uint] = self.mem[mloc_i0 as uint];
				Continue
			},

			0x7   => { // MSTOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let mloc_o0 = self.ir as u8;

				self.mem[mloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x9   => { // RSET
				let rloc = ((self.ir >> 8) as u8) & U4_LOW;  // lower nibble of first byte
				let rval = self.ir as u8;                    // value is entire second byte
				self.reg[rloc as uint] = rval;               // store value in register

				Continue
			},

			0xB   => { Halt },
			_     => { debug!("read unhandled opcode: {}", op); Halt },
		}
	}

	/// Load the instruction at `IP` and advance the pointer by two bytes.
	/// The instruction is packed into a single `u16` and stored in the instruction register.
	fn fetch(&mut self) {
		// load PC -> IR
		let byte_1 = self.mem[(self.ip+0) as uint];
		let byte_2 = self.mem[(self.ip+1) as uint];

		self.ir  = (byte_1 as u16 << 8) | (byte_2 as u16);
		self.ip += 2;

		debug!("IR set to 0x{:04X} ({:02X},{:02X})", self.ir, byte_1, byte_2)
	}
}

/// Take the lower nibble of a byte
fn l_nibble(byte: u8) -> u8 {
	(byte & U4_LOW)
}

/// Take the upper nibble of a byte and shift it
/// towards the least significant bits.
fn h_nibble(byte: u8) -> u8 {
	(byte & U4_HIGH) >> 4
}

fn main() {
	let mut cpu = P150Cpu::new();
	let program = [0x911E, 0x920C, 0x0123, 0x73F0, 0x61F0, 0x0123, 0x73F1, 0xB000];
	cpu.init_mem(program);

	// 0x911E => 0x9 (rset), 0x1 (reg), 0x1E (val: 30)
	// 0x920C => 0x9 (rset), 0x2 (reg), 0x0C (val: 12)
	// 0x0123 => 0x0 (addb), 0x1 (in1), 0x2 (in2), 0x3 (out1)
	// 0x73F0 => 0x7 (msto), 0x3 (reg), 0xF0 (mem)
	// 0x61F0 => 0x7 (mlod), 0x1 (reg), 0xF0 (mem)
	// 0x0123 => 0x0 (addb), 0x1 (in1), 0x2 (in2), 0x3 (out1)
	// 0x73F1 => 0x7 (msto), 0x3 (reg), 0xF1 (mem)

	loop {
		match cpu.tick() {
			Continue => { continue; },
			Halt => { println!("CPU halted."); cpu.dump(); break; },
		}
	}
}

<commit_msg>Add jump and register moving.<commit_after>#![feature(phase)]
#[phase(plugin, link)] extern crate log;

const U4_LOW:  u8 = 0b00001111;
const U4_HIGH: u8 = 0b11110000;

enum CpuState {
	Continue,
	Halt,
}

/// The P150 virtual machine
struct P150Cpu {
	ip:  u8,
	ir: u16,

	reg: [u8, ..16],
	mem: [u8, ..256],
}

impl P150Cpu {
	/// Initializes the P150 CPU
	///
	/// NOTE: This implementation 0s memory; but this is not guaranteed
	/// by the machine specification.
	///
	/// Programs must start at memory address 0x00
	fn new() -> P150Cpu {
		P150Cpu {
			ip:  0x00,
			ir:  0x0000,

			reg: [0u8, ..16],
			mem: [0u8, ..256],
		}
	}

	/// Prints the current machine state to the console window
	/// This includes the IP, IR, and all registers.
	/// (Registers will be formatted as 2s complement numbers.)
	fn dump(&self) {
		println!("IP: 0x{:02X}, IR: 0x{:04X}", self.ip, self.ir);

		println!("Registers")
		for (addr, cell) in self.reg.iter().enumerate() {
			println!("{}: {}", addr, cell)
		}
	}

	/// Read an array of instructions into memory
	/// This reads two bytes at a time from the `memory` array
	/// and loads them into the P150s RAM bank, starting from address 0.
	fn init_mem(&mut self, memory: &[u16]) {
		let mut next_cell = 0x00;

		for op in memory.iter() {
			let byte_1 = (*op >> 8) as u8;
			let byte_2 = *op as u8;

			self.mem[next_cell]     = byte_1;
			self.mem[next_cell + 1] = byte_2;
			next_cell += 2
		}
	}

	/// Runs the entire fetch, execute, decode cycle against the current IP
	fn tick(&mut self) -> CpuState {
		self.fetch();

		// decode
		let op = (self.ir >> 12) as u8;
		match op {
			0x0   => { // ADDB
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);   // first input: lower nibble of first byte
				let rloc_i1 = h_nibble(self.ir as u8);          // second input: upper nibble of second byte
				let rloc_o0 = l_nibble(self.ir as u8);          // output: lower nibble of second byte

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] + self.reg[rloc_i1 as uint];
				Continue
			},

			0x3   => { // AND
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] & self.reg[rloc_i1 as uint];
				Continue
			},

			0x4   => { // OR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] | self.reg[rloc_i1 as uint];
				Continue
			},

			0x5   => { // XOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_i1 = h_nibble(self.ir as u8);
				let rloc_o0 = l_nibble(self.ir as u8);

				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint] ^ self.reg[rloc_i1 as uint];
				Continue
			},

			0x6   => { // MLOAD
				let rloc_o0 = l_nibble((self.ir >> 8) as u8);
				let mloc_i0 = self.ir as u8;

				self.reg[rloc_o0 as uint] = self.mem[mloc_i0 as uint];
				Continue
			},

			0x7   => { // MSTOR
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let mloc_o0 = self.ir as u8;

				self.mem[mloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x8   => { // RMOV
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let rloc_o0 = h_nibble(self.ir as u8);

				debug!("moving from {:02X} to {:02X}", rloc_i0, rloc_o0)
				self.reg[rloc_o0 as uint] = self.reg[rloc_i0 as uint];
				Continue
			},

			0x9   => { // RSET
				let rloc = ((self.ir >> 8) as u8) & U4_LOW;  // lower nibble of first byte
				let rval = self.ir as u8;                    // value is entire second byte

				self.reg[rloc as uint] = rval;               // store value in register
				Continue
			},

			0xA   => { // JMPEQ
				let rloc_i0 = l_nibble((self.ir >> 8) as u8);
				let next_ip = self.ir as u8;

				if self.reg[rloc_i0 as uint] == self.reg[0] { self.ip = next_ip }
				Continue
			},

			0xB   => { Halt },
			_     => { debug!("halt, cpu on fire: {}", op); Halt },
		}
	}

	/// Load the instruction at `IP` and advance the pointer by two bytes.
	/// The instruction is packed into a single `u16` and stored in the instruction register.
	fn fetch(&mut self) {
		// load PC -> IR
		let byte_1 = self.mem[(self.ip+0) as uint];
		let byte_2 = self.mem[(self.ip+1) as uint];

		self.ir  = (byte_1 as u16 << 8) | (byte_2 as u16);
		self.ip += 2;

		debug!("IR set to 0x{:04X} ({:02X},{:02X})", self.ir, byte_1, byte_2)
	}
}

/// Take the lower nibble of a byte
fn l_nibble(byte: u8) -> u8 {
	(byte & U4_LOW)
}

/// Take the upper nibble of a byte and shift it
/// towards the least significant bits.
fn h_nibble(byte: u8) -> u8 {
	(byte & U4_HIGH) >> 4
}

fn main() {
	let mut cpu = P150Cpu::new();
	let program = [0x902A, 0x911E, 0x920C, 0x0123, 0x8310, 0xA106, 0xB000];
	cpu.init_mem(program);

	loop {
		match cpu.tick() {
			Continue => { continue; },
			Halt => { println!("CPU halted."); cpu.dump(); break; },
		}
	}
}

<|endoftext|>


<commit_before>extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType};
use docopt::Docopt;
use std::old_io as io;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit [options] <repo> [<branch>]

Options:
    -f, --flag  Flags a flag, note the multiple spaces!
";

#[derive(RustcDecodable, Show)]
struct Args {
    arg_repo: String,
    arg_branch: Option<String>,
    flag_flag: bool,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Could not discover a repository.");
    let branch = match args.arg_branch {
        Some(branch) => repo.find_branch(&branch[], BranchType::Local),
        None => choose_branch(&repo),
    }.ok().expect("Could not get branch.");
    println!("Repo: {:?}, Branch: {:?}", path, branch.name()
        .ok().expect("Branch name was not valid UTF-8"));
}

fn choose_branch(repo: &Repository) -> Result<Branch, git2::Error> {
    println!("Please choose a branch:");
    let mut branches = repo.branches(Some(BranchType::Local))
        .ok().expect("Could find any branches.");
    for (branch, _) in branches {
        let name = branch.name()
            .ok().expect("Could not get branch name.")
            .expect("Branch name was not valid UTF-8");
        println!("{}", name);
    }
    io::stdout().write_str(&"Choose your branch: "[]);
    let chosen = io::stdin().lock().read_line()
        .ok().expect("Could not read from stdin");
    repo.find_branch(&chosen.trim()[], BranchType::Local)
}

<commit_msg>Get the references.<commit_after>extern crate git2;
extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;

use git2::{Repository, Branch, BranchType};
use docopt::Docopt;
use std::old_io as io;

// Write the Docopt usage string.
static USAGE: &'static str = "
Usage: transit [options] <repo> [<branch>]

Options:
    -f, --flag  Flags a flag, note the multiple spaces!
";

#[derive(RustcDecodable, Show)]
struct Args {
    arg_repo: String,
    arg_branch: Option<String>,
    flag_flag: bool,
}

fn main() {
    // Parse the args above or die.
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    let path = Path::new(args.arg_repo);
    let repo = Repository::discover(&path)
        .ok().expect("Could not discover a repository.");

    // Which branch?
    let branch = match args.arg_branch {
        Some(branch) => repo.find_branch(&branch[], BranchType::Local),
        None => choose_branch(&repo),
    }.ok().expect("Could not get branch.");

    // Mostly debugging.
    println!("Repo: {:?}, Branch: {:?}", path, branch.name()
       .ok().expect("Couldn't get branch name.")
       .expect("Branch name is not UTF-8."));

    // Get the reference of the branch.
    let reference = branch.into_reference();
    let oid = reference.target()
        .expect("Could not get target.");
    println!("Target Commit: {:?}", oid);
}

fn choose_branch(repo: &Repository) -> Result<Branch, git2::Error> {
    println!("Please choose a branch:");
    let mut branches = repo.branches(Some(BranchType::Local))
        .ok().expect("Could find any branches.");
    for (branch, _) in branches {
        let name = branch.name()
            .ok().expect("Could not get branch name.")
            .expect("Branch name was not valid UTF-8");
        println!("{}", name);
    }
    io::stdout().write_str(&"Choose your branch: "[]);
    let chosen = io::stdin().lock().read_line()
        .ok().expect("Could not read from stdin");
    repo.find_branch(&chosen.trim()[], BranchType::Local)
}
<|endoftext|>


<commit_before>// TODO
// when sending too much data, size gets printed. it is not beeing sent a u8, it is being sent as a string i think
// add nickname
// modularize
// print list of peers (exclude myself or print myself and state it is me)
// add /help
//     Help:          -h --help
//    Host IP:       -H --host {host IP}
//    Broadcast IP:  -B --broadcast {broadcast IP}
//    RPC Port:      -P --port {port}
// add encryption
// add rooms, by default join lobby

use std::net::UdpSocket;
use std::io;
use std::io::Write;
use std::thread;
use std::time::Duration;
use std::process;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::time::SystemTime;

fn main () {
    let peers = Arc::new(Mutex::new(HashMap::new()));

    let peers_sender = peers.clone();
    let sender = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");

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

        loop {
            let mut input = String::new();
            match io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input.pop();

                    process(&socket, input);
                    io::stdout().flush().unwrap();
                   // println!("peers {:?}", *peers_sender.lock().unwrap()); //TODO move this to the process of the sender when writting /peers
                }
                Err(error) =>
                    println!("error: {}", error),
            }
        }
    });

    let prober = thread::spawn(|| {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");
        loop {
            let message = format!("P");
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
            thread::sleep(Duration::from_millis(5000)); //TODO put in seconds
        }
    });

    let peers_rec = peers.clone();
    let receiver = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:4041").expect("couldn't bind to address");

        loop {
            let mut buffer = [0; 512];
            let (received_bytes, source) = socket.recv_from(&mut buffer)
                .expect("Didn't receive data");

            match std::str::from_utf8(&buffer[0..1]).unwrap() {
                "M" => {
                    println!("{}", std::str::from_utf8(&buffer[2..received_bytes]).unwrap());
                    io::stdout().flush().unwrap();
                    print!("> ");
                    io::stdout().flush().unwrap();
                }

                "P" => {
                    //println!("probe with source {}", source);
                    peers_rec.lock().unwrap().insert(source, SystemTime::now()); //TODO insert only seconds and IP
                    // clean hosts that have not received content for more than x seconds
                }

                _ =>  {
                }
            }

        }
    });

    receiver.join().unwrap();
    sender.join().unwrap();
    prober.join().unwrap();
}

fn process(socket: &UdpSocket, input: String) {
    match input.as_ref() {
        "" => {

        },

        "/quit" => {
            process::exit(0x0f00);
        },

        "/peers" => {
            //TODO print list of
        },

        "/rooms" => {
        },

        "/help" => {
        },

        _ => {
            let size = input.len();
            let message = format!("M{}{}", size, input);
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
        }
    }
    ()
}
<commit_msg>Add source<commit_after>// TODO
// when sending too much data, size gets printed. it is not beeing sent a u8, it is being sent as a string i think
// add nickname
// modularize
// print list of peers (exclude myself or print myself and state it is me)
// add /help
//     Help:          -h --help
//    Host IP:       -H --host {host IP}
//    Broadcast IP:  -B --broadcast {broadcast IP}
//    RPC Port:      -P --port {port}
// add encryption
// add rooms, by default join lobby

use std::net::UdpSocket;
use std::io;
use std::io::Write;
use std::thread;
use std::time::Duration;
use std::process;
use std::sync::{Arc, Mutex};
use std::collections::HashMap;
use std::time::SystemTime;

fn main () {
    let peers = Arc::new(Mutex::new(HashMap::new()));

    let peers_sender = peers.clone();
    let sender = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");

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

        loop {
            let mut input = String::new();
            match io::stdin().read_line(&mut input) {
                Ok(_) => {
                    input.pop();

                    process(&socket, input);
                    io::stdout().flush().unwrap();
                   // println!("peers {:?}", *peers_sender.lock().unwrap()); //TODO move this to the process of the sender when writting /peers
                }
                Err(error) =>
                    println!("error: {}", error),
            }
        }
    });

    let prober = thread::spawn(|| {
        let socket = UdpSocket::bind("0.0.0.0:0").expect("couldn't bind to address");
        socket.set_broadcast(true).expect("set_broadcast call failed");
        loop {
            let message = format!("P");
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
            thread::sleep(Duration::from_millis(5000)); //TODO put in seconds
        }
    });

    let peers_rec = peers.clone();
    let receiver = thread::spawn(move || {
        let socket = UdpSocket::bind("0.0.0.0:4041").expect("couldn't bind to address");

        loop {
            let mut buffer = [0; 512];
            let (received_bytes, source) = socket.recv_from(&mut buffer)
                .expect("Didn't receive data");

            match std::str::from_utf8(&buffer[0..1]).unwrap() {
                "M" => {
                    println!("{}: {}", source, std::str::from_utf8(&buffer[2..received_bytes]).unwrap());
                    io::stdout().flush().unwrap();
                    print!("> ");
                    io::stdout().flush().unwrap();
                }

                "P" => {
                    //println!("probe with source {}", source);
                    peers_rec.lock().unwrap().insert(source, SystemTime::now()); //TODO insert only seconds and IP
                    // clean hosts that have not received content for more than x seconds
                }

                _ =>  {
                }
            }

        }
    });

    receiver.join().unwrap();
    sender.join().unwrap();
    prober.join().unwrap();
}

fn process(socket: &UdpSocket, input: String) {
    match input.as_ref() {
        "" => {

        },

        "/quit" => {
            process::exit(0x0f00);
        },

        "/peers" => {
            //TODO print list of
        },

        "/rooms" => {
        },

        "/help" => {
        },

        _ => {
            let size = input.len();
            let message = format!("M{}{}", size, input);
            socket.send_to(&message.into_bytes(), "255.255.255.255:4041").expect("couldn't send data");
        }
    }
    ()
}
<|endoftext|>


<commit_before>#![recursion_limit = "256"]
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
#[cfg(feature = "profile-index")]
#[macro_use]
extern crate flamer;

#[cfg(unix)]
use log::error;
#[cfg(unix)]
use sd_notify::{self, NotifyState};
#[cfg(unix)]
use std::fs::File;
#[cfg(unix)]
use std::io::prelude::*;
#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};

use anyhow::*;
use core::ops::Deref;
use getopts::Options;
use log::info;
use simplelog::{LevelFilter, SimpleLogger, TermLogger, TerminalMode};
use std::path::Path;
use std::sync::Arc;

mod api;
#[cfg(test)]
mod api_tests;
mod config;
mod db;
mod ddns;
mod index;
mod lastfm;
mod metadata;
mod playlist;
mod serve;
mod server;
mod swagger;
#[cfg(test)]
mod test;
mod thumbnails;
mod ui;
mod user;
mod utils;
mod vfs;
mod web;

fn log_config() -> simplelog::Config {
	simplelog::ConfigBuilder::new()
		.set_location_level(LevelFilter::Error)
		.build()
}

#[cfg(unix)]
fn daemonize(options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		return Ok(());
	}
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	let pid = match daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir) {
		Ok(p) => p,
		Err(_) => bail!(ErrorKind::DaemonError),
	};
	let mut pid_path = utils::get_data_root()?;
	pid_path.push("polaris.pid");
	let mut file = File::create(pid_path)?;
	file.write_all(pid.to_string().as_bytes())?;
	Ok(())
}

#[cfg(unix)]
fn init_log(log_level: LevelFilter, options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		if let Err(e) = TermLogger::init(log_level, log_config(), TerminalMode::Stdout) {
			println!("Error starting terminal logger: {}", e);
		} else {
			return Ok(());
		}
	}

	if let Err(e) = SimpleLogger::init(log_level, log_config()) {
		bail!("Error starting simple logger: {}", e);
	}
	Ok(())
}

#[cfg(windows)]
fn init_log(log_level: LevelFilter, _: &getopts::Matches) -> Result<()> {
	if TermLogger::init(log_level, log_config(), TerminalMode::Stdout).is_err() {
		if let Err(e) = SimpleLogger::init(log_level, log_config()) {
			bail!("Error starting simple logger: {}", e);
		}
	};
	Ok(())
}

#[cfg(unix)]
fn notify_ready() {
	if let Ok(true) = sd_notify::booted() {
		if let Err(e) = sd_notify::notify(true, &[NotifyState::Ready]) {
			error!("Unable to send ready notification: {}", e);
		}
	}
}

#[cfg(not(unix))]
fn notify_ready() {}

fn main() -> Result<()> {
	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("p", "port", "set polaris to run on a custom port", "PORT");
	options.optopt("d", "database", "set the path to index database", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	options.optopt("s", "swagger", "set the path to swagger files", "DIRECTORY");
	options.optopt(
		"l",
		"log",
		"set the log level to a value between 0 (off) and 3 (debug)",
		"LEVEL",
	);

	#[cfg(unix)]
	options.optflag(
		"f",
		"foreground",
		"run polaris in the foreground instead of daemonizing",
	);

	options.optflag("h", "help", "print this help menu");

	let matches = options.parse(&args[1..])?;

	if matches.opt_present("h") {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options.usage(&brief));
		return Ok(());
	}

	let log_level = match matches.opt_str("l").as_ref().map(String::as_ref) {
		Some("0") => LevelFilter::Off,
		Some("1") => LevelFilter::Error,
		Some("2") => LevelFilter::Info,
		Some("3") => LevelFilter::Debug,
		_ => LevelFilter::Info,
	};

	init_log(log_level, &matches)?;

	#[cfg(unix)]
	daemonize(&matches)?;

	// Init DB
	info!("Starting up database");
	let db_path = matches.opt_str("d");
	let mut default_db_path = utils::get_data_root()?;
	default_db_path.push("db.sqlite");
	let db_path = db_path
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_db_path);
	let db = Arc::new(db::DB::new(&db_path)?);

	// Parse config
	info!("Parsing configuration");
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|p| Path::new(p.as_str()).to_path_buf());
	if let Some(path) = config_file_path {
		let config = config::parse_toml_file(&path)?;
		info!("Applying configuration");
		config::amend(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;
	let auth_secret = config::get_auth_secret(db.deref())?;

	// Init index
	info!("Initializing index");
	let command_sender = index::init(db.clone());

	// Trigger auto-indexing
	let db_auto_index = db.clone();
	let command_sender_auto_index = command_sender.clone();
	std::thread::spawn(move || {
		index::self_trigger(db_auto_index.deref(), &command_sender_auto_index);
	});

	// API mount target
	let prefix_url = config.prefix_url.unwrap_or_else(|| "".to_string());
	let api_url = format!("/{}api", &prefix_url);
	info!("Mounting API on {}", api_url);

	// Web client mount target
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);
	info!("Static files location is {}", web_dir_path.display());
	let web_url = format!("/{}", &prefix_url);
	info!("Mounting web client files on {}", web_url);

	// Swagger files mount target
	let swagger_dir_name = matches.opt_str("s");
	let mut default_swagger_dir = utils::get_data_root()?;
	default_swagger_dir.push("swagger");
	let swagger_dir_path = swagger_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_swagger_dir);
	info!("Swagger files location is {}", swagger_dir_path.display());
	let swagger_url = format!("/{}swagger", &prefix_url);
	info!("Mounting swagger files on {}", swagger_url);

	// Start server
	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or_else(|| "5050".to_owned())
		.parse()
		.with_context(|| "Invalid port number")?;

	let server = server::get_server(
		port,
		Some(auth_secret.as_slice()),
		&api_url,
		&web_url,
		&web_dir_path,
		&swagger_url,
		&swagger_dir_path,
		db.clone(),
		command_sender,
	)?;
	std::thread::spawn(move || {
		server.launch();
	});

	// Start DDNS updates
	let db_ddns = db.clone();
	std::thread::spawn(move || {
		ddns::run(db_ddns.deref());
	});

	// Send readiness notification
	notify_ready();

	// Run UI
	ui::run();

	info!("Shutting down server");
	Ok(())
}
<commit_msg>Fixed straggler error<commit_after>#![recursion_limit = "256"]
#![feature(proc_macro_hygiene, decl_macro)]

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
#[cfg(feature = "profile-index")]
#[macro_use]
extern crate flamer;

#[cfg(unix)]
use log::error;
#[cfg(unix)]
use sd_notify::{self, NotifyState};
#[cfg(unix)]
use std::fs::File;
#[cfg(unix)]
use std::io::prelude::*;
#[cfg(unix)]
use unix_daemonize::{daemonize_redirect, ChdirMode};

use anyhow::*;
use core::ops::Deref;
use getopts::Options;
use log::info;
use simplelog::{LevelFilter, SimpleLogger, TermLogger, TerminalMode};
use std::path::Path;
use std::sync::Arc;

mod api;
#[cfg(test)]
mod api_tests;
mod config;
mod db;
mod ddns;
mod index;
mod lastfm;
mod metadata;
mod playlist;
mod serve;
mod server;
mod swagger;
#[cfg(test)]
mod test;
mod thumbnails;
mod ui;
mod user;
mod utils;
mod vfs;
mod web;

fn log_config() -> simplelog::Config {
	simplelog::ConfigBuilder::new()
		.set_location_level(LevelFilter::Error)
		.build()
}

#[cfg(unix)]
fn daemonize(options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		return Ok(());
	}
	let mut log_file = utils::get_data_root()?;
	log_file.push("polaris.log");
	let pid = daemonize_redirect(Some(&log_file), Some(&log_file), ChdirMode::NoChdir)?;
	let mut pid_path = utils::get_data_root()?;
	pid_path.push("polaris.pid");
	let mut file = File::create(pid_path)?;
	file.write_all(pid.to_string().as_bytes())?;
	Ok(())
}

#[cfg(unix)]
fn init_log(log_level: LevelFilter, options: &getopts::Matches) -> Result<()> {
	if options.opt_present("f") {
		if let Err(e) = TermLogger::init(log_level, log_config(), TerminalMode::Stdout) {
			println!("Error starting terminal logger: {}", e);
		} else {
			return Ok(());
		}
	}

	if let Err(e) = SimpleLogger::init(log_level, log_config()) {
		bail!("Error starting simple logger: {}", e);
	}
	Ok(())
}

#[cfg(windows)]
fn init_log(log_level: LevelFilter, _: &getopts::Matches) -> Result<()> {
	if TermLogger::init(log_level, log_config(), TerminalMode::Stdout).is_err() {
		if let Err(e) = SimpleLogger::init(log_level, log_config()) {
			bail!("Error starting simple logger: {}", e);
		}
	};
	Ok(())
}

#[cfg(unix)]
fn notify_ready() {
	if let Ok(true) = sd_notify::booted() {
		if let Err(e) = sd_notify::notify(true, &[NotifyState::Ready]) {
			error!("Unable to send ready notification: {}", e);
		}
	}
}

#[cfg(not(unix))]
fn notify_ready() {}

fn main() -> Result<()> {
	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("p", "port", "set polaris to run on a custom port", "PORT");
	options.optopt("d", "database", "set the path to index database", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	options.optopt("s", "swagger", "set the path to swagger files", "DIRECTORY");
	options.optopt(
		"l",
		"log",
		"set the log level to a value between 0 (off) and 3 (debug)",
		"LEVEL",
	);

	#[cfg(unix)]
	options.optflag(
		"f",
		"foreground",
		"run polaris in the foreground instead of daemonizing",
	);

	options.optflag("h", "help", "print this help menu");

	let matches = options.parse(&args[1..])?;

	if matches.opt_present("h") {
		let program = args[0].clone();
		let brief = format!("Usage: {} [options]", program);
		print!("{}", options.usage(&brief));
		return Ok(());
	}

	let log_level = match matches.opt_str("l").as_ref().map(String::as_ref) {
		Some("0") => LevelFilter::Off,
		Some("1") => LevelFilter::Error,
		Some("2") => LevelFilter::Info,
		Some("3") => LevelFilter::Debug,
		_ => LevelFilter::Info,
	};

	init_log(log_level, &matches)?;

	#[cfg(unix)]
	daemonize(&matches)?;

	// Init DB
	info!("Starting up database");
	let db_path = matches.opt_str("d");
	let mut default_db_path = utils::get_data_root()?;
	default_db_path.push("db.sqlite");
	let db_path = db_path
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_db_path);
	let db = Arc::new(db::DB::new(&db_path)?);

	// Parse config
	info!("Parsing configuration");
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|p| Path::new(p.as_str()).to_path_buf());
	if let Some(path) = config_file_path {
		let config = config::parse_toml_file(&path)?;
		info!("Applying configuration");
		config::amend(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;
	let auth_secret = config::get_auth_secret(db.deref())?;

	// Init index
	info!("Initializing index");
	let command_sender = index::init(db.clone());

	// Trigger auto-indexing
	let db_auto_index = db.clone();
	let command_sender_auto_index = command_sender.clone();
	std::thread::spawn(move || {
		index::self_trigger(db_auto_index.deref(), &command_sender_auto_index);
	});

	// API mount target
	let prefix_url = config.prefix_url.unwrap_or_else(|| "".to_string());
	let api_url = format!("/{}api", &prefix_url);
	info!("Mounting API on {}", api_url);

	// Web client mount target
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);
	info!("Static files location is {}", web_dir_path.display());
	let web_url = format!("/{}", &prefix_url);
	info!("Mounting web client files on {}", web_url);

	// Swagger files mount target
	let swagger_dir_name = matches.opt_str("s");
	let mut default_swagger_dir = utils::get_data_root()?;
	default_swagger_dir.push("swagger");
	let swagger_dir_path = swagger_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_swagger_dir);
	info!("Swagger files location is {}", swagger_dir_path.display());
	let swagger_url = format!("/{}swagger", &prefix_url);
	info!("Mounting swagger files on {}", swagger_url);

	// Start server
	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or_else(|| "5050".to_owned())
		.parse()
		.with_context(|| "Invalid port number")?;

	let server = server::get_server(
		port,
		Some(auth_secret.as_slice()),
		&api_url,
		&web_url,
		&web_dir_path,
		&swagger_url,
		&swagger_dir_path,
		db.clone(),
		command_sender,
	)?;
	std::thread::spawn(move || {
		server.launch();
	});

	// Start DDNS updates
	let db_ddns = db.clone();
	std::thread::spawn(move || {
		ddns::run(db_ddns.deref());
	});

	// Send readiness notification
	notify_ready();

	// Run UI
	ui::run();

	info!("Shutting down server");
	Ok(())
}
<|endoftext|>


<commit_before>// see 'rustc -W help'
#![warn(missing_docs, unused_extern_crates, unused_results)]

//! An IRC bot that posts comments to github when W3C-style IRC minuting is
//! combined with "Github topic:" or "Github issue:" lines that give the
//! github issue to comment in.

extern crate env_logger;
extern crate irc;
#[macro_use]
extern crate lazy_static;
extern crate tokio_core;
extern crate wgmeeting_github_ircbot;

use irc::client::prelude::{Client, ClientExt, Config, Future, IrcClient, Stream};
use irc::client::PackedIrcClient;
use std::collections::HashMap;
use std::env;
use std::ffi::OsString;
use std::fs::File;
use std::io::Read;
use tokio_core::reactor::Core;
use wgmeeting_github_ircbot::*;

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

    lazy_static! {
        static ref ARGS: Vec<OsString> = {
            let args = env::args_os().skip(1).collect::<Vec<_>>();
            if args.len() != 2 {
                eprintln!("syntax: {} <config file> <github access token file>\n",
                    env::args_os().nth(0)
                        .map(|osstring| osstring.into_string().unwrap_or(String::from("")))
                        .unwrap_or(String::from("")));
                ::std::process::exit(1);
            }
            args
        };
        static ref CONFIG: Config = {
            Config::load(ARGS[0].clone()).expect("couldn't load configuration file")
        };
        static ref GITHUB_ACCESS_TOKEN: String = {
            let mut f = File::open(ARGS[1].clone())
                .expect("github access token file (second argument) not found");
            let mut token = String::new();
            let _numbytes =
                f.read_to_string(&mut token).expect("couldn't read github access token file");
            token
        };
        static ref OPTIONS: HashMap<String, String> = {
            let mut options =
                CONFIG.options.as_ref().expect("No options property within configuration?").clone();
            // Store the access token with the options, even though we read it from a different
            // place.
            let _oldval =
                options.insert("github_access_token".to_string(), GITHUB_ACCESS_TOKEN.to_string());
            options
        };
    }

    // FIXME: Add a way to ask the bot to reboot itself?

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let mut irc_state = IRCState::new(GithubType::RealGithubConnection, &handle);

    let irc_client_future = IrcClient::new_future(handle, &CONFIG).expect(
        "Couldn't initialize server \
         with given configuration file",
    );

    let PackedIrcClient(irc, irc_outgoing_future) = core.run(irc_client_future).unwrap();

    irc.identify().unwrap();

    let ircstream = irc.stream().for_each(|message| {
        process_irc_message(&irc, &mut irc_state, &OPTIONS, message);
        Ok(())
    });

    let _ = core.run(ircstream.join(irc_outgoing_future)).unwrap();
}
<commit_msg>Simplify reading configuration.<commit_after>// see 'rustc -W help'
#![warn(missing_docs, unused_extern_crates, unused_results)]

//! An IRC bot that posts comments to github when W3C-style IRC minuting is
//! combined with "Github topic:" or "Github issue:" lines that give the
//! github issue to comment in.

extern crate env_logger;
extern crate irc;
extern crate tokio_core;
extern crate wgmeeting_github_ircbot;

use irc::client::prelude::{Client, ClientExt, Config, Future, IrcClient, Stream};
use irc::client::PackedIrcClient;
use std::env;
use std::fs;
use tokio_core::reactor::Core;
use wgmeeting_github_ircbot::*;

fn read_config() -> Config {
    let mut args = env::args_os();
    if args.len() != 3 {
        eprintln!(
            "syntax: {} <config file> <github access token file>\n",
            env::args().next().unwrap()
        );
        ::std::process::exit(1);
    }
    let (_, config_file, token_file) = (
        args.next().unwrap(),
        args.next().unwrap(),
        args.next().unwrap(),
    );

    let mut config = Config::load(config_file)
        .expect("couldn't load configuration file");
    let token = fs::read_to_string(token_file)
        .expect("couldn't read github access token file");
    let _ = config
        .options
        .as_mut()
        .unwrap()
        .insert("github_access_token".to_string(), token);
    config
}

fn main() {
    env_logger::init();
    let config: &'static Config = Box::leak(Box::new(read_config()));

    // FIXME: Add a way to ask the bot to reboot itself?

    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let mut irc_state = IRCState::new(GithubType::RealGithubConnection, &handle);

    let irc_client_future = IrcClient::new_future(handle, config).expect(
        "Couldn't initialize server \
         with given configuration file",
    );

    let PackedIrcClient(irc, irc_outgoing_future) = core.run(irc_client_future).unwrap();

    irc.identify().unwrap();

    let ircstream = irc.stream().for_each(|message| {
        let options = config.options.as_ref().unwrap();
        process_irc_message(&irc, &mut irc_state, options, message);
        Ok(())
    });

    let _ = core.run(ircstream.join(irc_outgoing_future)).unwrap();
}
<|endoftext|>