<commit_before>extern crate rlp;
extern crate secp256k1;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate clap;
extern crate rand;
extern crate crypto;

use std::io::{ self, Read, Write };
use std::net::{ Ipv4Addr as _Ipv4Addr, AddrParseError };
use std::ops::Deref;
use std::time;
use std::net::UdpSocket;
use std::fs::File;
use std::str::FromStr;
use std::thread;
use std::any::Any;
use std::marker::Send;
use std::sync::Arc;

use rlp::{ Encodable, RlpStream };

use secp256k1::{ Secp256k1, Message };
use secp256k1::key::SecretKey;

use rand::OsRng;

use crypto::sha3::Sha3;
use crypto::digest::Digest;

lazy_static! {
    static ref SECP: Secp256k1 = Secp256k1::new();
}

enum Error {
    IOError(io::Error),
    SECP256K1Error(secp256k1::Error),
    AddrParseError(AddrParseError),
    ThreadError(Box<Any + Send>),
}

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

impl From<secp256k1::Error> for Error {
    fn from(e: secp256k1::Error) -> Self {
        Error::SECP256K1Error(e)
    }
}

impl From<AddrParseError> for Error {
    fn from(e: AddrParseError) -> Self {
        Error::AddrParseError(e)
    }
}

impl From<Box<Any + Send>> for Error {
    fn from(e: Box<Any + Send>) -> Self {
        Error::ThreadError(e)
    }
}

#[derive(Clone, Copy)]
struct Ipv4Addr(_Ipv4Addr);

impl Deref for Ipv4Addr {
    type Target = _Ipv4Addr;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Encodable for Ipv4Addr {
    fn rlp_append(&self, s: &mut RlpStream) {
        self.octets().to_vec().rlp_append(s)
    }
}

//only ipv4 for now:
#[derive(Clone, Copy)]
struct Endpoint {
    address: Ipv4Addr,
    udp_port: u16,
    tcp_port: u16,
}

impl Endpoint {
    fn new(address: Ipv4Addr, udp_port: u16, tcp_port: u16) -> Endpoint {
        Endpoint{ address, udp_port, tcp_port }
    }
}

impl Encodable for Endpoint {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.begin_unbounded_list();
        self.address.rlp_append(s);
        self.udp_port.rlp_append(s);
        self.tcp_port.rlp_append(s);
        s.complete_unbounded_list();
    }
}

struct PingNode {
    from: Endpoint,
    to: Endpoint,
}

impl PingNode {
    fn new(from: Endpoint, to: Endpoint) -> PingNode {
        PingNode{ from, to }
    }
}

impl Encodable for PingNode {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.begin_unbounded_list();
        0x3u8.rlp_append(s);
        self.from.rlp_append(s);
        self.to.rlp_append(s);
        let ts = time::SystemTime::now() + time::Duration::new(60, 0);
        match ts.duration_since(time::UNIX_EPOCH) {
            Ok(t) => (t.as_secs() as u32).rlp_append(s),
            Err(_) => panic!("damn"),
        }
        s.complete_unbounded_list();
    }
}

fn keccak256(data: &[u8]) -> [u8; 256 / 8] {
    let mut sha3 = Sha3::keccak256();
    sha3.input(data);
    let mut out = [0; 256 / 8];
    sha3.result(&mut out);
    out
}

struct PingServer {
    endpoint: Endpoint,
    private_key: SecretKey,
    socket: UdpSocket,
}

impl PingServer {
    fn new(endpoint: Endpoint, private_key_path: &str) -> Result<PingServer, Error> {
        // read private key
        let private_key_raw = {
            let mut f = File::open(private_key_path)?;
            let mut b = vec![];
            f.read_to_end(&mut b)?;
            b
        };
        let private_key = SecretKey::from_slice(&SECP, &private_key_raw)?;

        //setup socket
        println!("listening on {}...", endpoint.udp_port);
        let socket = UdpSocket::bind(("0.0.0.0", endpoint.udp_port))?;

        Ok(PingServer{ endpoint, private_key, socket })
    }

    fn mk_packet(&self, node: PingNode) -> Result<Vec<u8>, Error> {
        let message = [vec![0x01], rlp::encode(&node).to_vec()].concat();
        let message_hash = keccak256(&message);
        let signature = SECP.sign_recoverable(&Message::from_slice(&message_hash)?, &self.private_key)?;
        let (recovery_id, signature_raw) =  signature.serialize_compact(&SECP);
        let payload = [signature_raw.to_vec(), vec![recovery_id.to_i32() as u8], message].concat();
        let payload_hash = keccak256(&payload);
        let packet = [payload_hash.to_vec(), payload].concat();
        Ok(packet)
    }

    fn udp_listen(&self) -> Result<(), Error> {
        loop {
            let mut buf = [0; 1500];
            let (length, addr) = self.socket.recv_from(&mut buf)?;
            println!("{}: {:?}", addr, buf[..length].to_vec());
        }
    }

    fn ping(&self, endpoint: Endpoint) -> Result<(), Error> {
        let ping = PingNode::new(self.endpoint, endpoint);
        let packet = self.mk_packet(ping)?;
        println!("sending ping");
        let _size = self.socket.send_to(&packet, (endpoint.address.0, endpoint.udp_port))?;
        Ok(())
    }
}

fn ma1n() -> Result<(), Error> {
    let matches = clap_app!(ndscrwlr =>
        (version: "0.1")
        (author: "Stefan Nitz <nitz.stefan@googlemail.com>")
        (about: "crawls some nodes")
        (@arg KEYFILE: "The file containing your private key (default: key.priv)")
        (@arg generate: -g --generate ... "Generate a new private key (may overwrite KEYFILE)")
    ).get_matches();

    let private_key_path = matches.value_of("KEYFILE").unwrap_or("key.priv");
    println!("using private key file: {}", private_key_path);
    if matches.is_present("generate") {
        println!("generating new key...");
        let key = SecretKey::new(&SECP, &mut OsRng::new()?);
        let key_raw = &key[..];
        let mut f = File::create(private_key_path)?;
        f.write(key_raw)?;
    }
    let my_address = Ipv4Addr(_Ipv4Addr::from_str("127.0.0.1")?);
    let my_endpoint = Endpoint::new(my_address, 30303, 30303);
    let other_address = Ipv4Addr(_Ipv4Addr::from_str("13.93.211.84")?);
    let other_endpoint = Endpoint::new(other_address, 30303, 30303);
    let server = Arc::new(PingServer::new(my_endpoint, private_key_path)?);
    let thread_server = server.clone();
    let t = thread::spawn(move || thread_server.udp_listen());
    server.ping(other_endpoint)?;
    let _: () = t.join()??;
    Ok(())
}

fn main() {
    match ma1n() {
        Ok(()) => (),
        Err(_) => println!("an error occured and i was too lazy to implement the debug trait on it"),
    }
}
<commit_msg>minor cleanup<commit_after>extern crate rlp;
extern crate secp256k1;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate clap;
extern crate rand;
extern crate crypto;

use std::io::{ self, Read, Write };
use std::net::{ Ipv4Addr, AddrParseError };
use std::ops::Deref;
use std::time;
use std::net::UdpSocket;
use std::fs::File;
use std::str::FromStr;
use std::thread;
use std::any::Any;
use std::marker::Send;
use std::sync::Arc;

use rlp::{ Encodable, RlpStream };

use secp256k1::{ Secp256k1, Message };
use secp256k1::key::SecretKey;

use rand::OsRng;

use crypto::sha3::Sha3;
use crypto::digest::Digest;

lazy_static! {
    static ref SECP: Secp256k1 = Secp256k1::new();
}

enum Error {
    IOError(io::Error),
    SECP256K1Error(secp256k1::Error),
    AddrParseError(AddrParseError),
    ThreadError(Box<Any + Send>),
}

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

impl From<secp256k1::Error> for Error {
    fn from(e: secp256k1::Error) -> Self {
        Error::SECP256K1Error(e)
    }
}

impl From<AddrParseError> for Error {
    fn from(e: AddrParseError) -> Self {
        Error::AddrParseError(e)
    }
}

impl From<Box<Any + Send>> for Error {
    fn from(e: Box<Any + Send>) -> Self {
        Error::ThreadError(e)
    }
}

//only ipv4 for now:
#[derive(Clone, Copy)]
struct Endpoint {
    address: Ipv4Addr,
    udp_port: u16,
    tcp_port: u16,
}

impl Endpoint {
    fn new(address: Ipv4Addr, udp_port: u16, tcp_port: u16) -> Endpoint {
        Endpoint{ address, udp_port, tcp_port }
    }
}

impl Encodable for Endpoint {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.begin_unbounded_list();
        self.address.octets().to_vec().rlp_append(s);
        self.udp_port.rlp_append(s);
        self.tcp_port.rlp_append(s);
        s.complete_unbounded_list();
    }
}

struct PingNode {
    from: Endpoint,
    to: Endpoint,
}

impl PingNode {
    fn new(from: Endpoint, to: Endpoint) -> PingNode {
        PingNode{ from, to }
    }
}

impl Encodable for PingNode {
    fn rlp_append(&self, s: &mut RlpStream) {
        s.begin_unbounded_list();
        0x3u8.rlp_append(s);
        self.from.rlp_append(s);
        self.to.rlp_append(s);
        let ts = time::SystemTime::now() + time::Duration::new(60, 0);
        match ts.duration_since(time::UNIX_EPOCH) {
            Ok(t) => (t.as_secs() as u32).rlp_append(s),
            Err(_) => panic!("damn"),
        }
        s.complete_unbounded_list();
    }
}

fn keccak256(data: &[u8]) -> [u8; 256 / 8] {
    let mut sha3 = Sha3::keccak256();
    sha3.input(data);
    let mut out = [0; 256 / 8];
    sha3.result(&mut out);
    out
}

struct PingServer {
    endpoint: Endpoint,
    private_key: SecretKey,
    socket: UdpSocket,
}

impl PingServer {
    fn new(endpoint: Endpoint, private_key_path: &str) -> Result<PingServer, Error> {
        // read private key
        let private_key_raw = {
            let mut f = File::open(private_key_path)?;
            let mut b = vec![];
            f.read_to_end(&mut b)?;
            b
        };
        let private_key = SecretKey::from_slice(&SECP, &private_key_raw)?;

        //setup socket
        println!("listening on {}...", endpoint.udp_port);
        let socket = UdpSocket::bind(("0.0.0.0", endpoint.udp_port))?;

        Ok(PingServer{ endpoint, private_key, socket })
    }

    fn mk_packet(&self, node: PingNode) -> Result<Vec<u8>, Error> {
        let message = [vec![0x01], rlp::encode(&node).to_vec()].concat();
        let message_hash = keccak256(&message);
        let signature = SECP.sign_recoverable(&Message::from_slice(&message_hash)?, &self.private_key)?;
        let (recovery_id, signature_raw) =  signature.serialize_compact(&SECP);
        let payload = [signature_raw.to_vec(), vec![recovery_id.to_i32() as u8], message].concat();
        let payload_hash = keccak256(&payload);
        let packet = [payload_hash.to_vec(), payload].concat();
        Ok(packet)
    }

    fn udp_listen(&self) -> Result<(), Error> {
        loop {
            let mut buf = [0; 1500];
            let (length, addr) = self.socket.recv_from(&mut buf)?;
            println!("{}: {:?}", addr, buf[..length].to_vec());
        }
    }

    fn ping(&self, endpoint: Endpoint) -> Result<(), Error> {
        let ping = PingNode::new(self.endpoint, endpoint);
        let packet = self.mk_packet(ping)?;
        println!("sending ping");
        let _size = self.socket.send_to(&packet, (endpoint.address, endpoint.udp_port))?;
        Ok(())
    }
}

fn ma1n() -> Result<(), Error> {
    let matches = clap_app!(ndscrwlr =>
        (version: "0.1")
        (author: "Stefan Nitz <nitz.stefan@googlemail.com>")
        (about: "crawls some nodes")
        (@arg KEYFILE: "The file containing your private key (default: key.priv)")
        (@arg generate: -g --generate ... "Generate a new private key (may overwrite KEYFILE)")
    ).get_matches();

    let private_key_path = matches.value_of("KEYFILE").unwrap_or("key.priv");
    println!("using private key file: {}", private_key_path);
    if matches.is_present("generate") {
        println!("generating new key...");
        let key = SecretKey::new(&SECP, &mut OsRng::new()?);
        let key_raw = &key[..];
        let mut f = File::create(private_key_path)?;
        f.write(key_raw)?;
    }
    let my_address = Ipv4Addr::from_str("127.0.0.1")?;
    let my_endpoint = Endpoint::new(my_address, 30303, 30303);
    let other_address = Ipv4Addr::from_str("13.93.211.84")?;
    let other_endpoint = Endpoint::new(other_address, 30303, 30303);
    let server = Arc::new(PingServer::new(my_endpoint, private_key_path)?);
    let thread_server = server.clone();
    let t = thread::spawn(move || thread_server.udp_listen());
    server.ping(other_endpoint)?;
    let _: () = t.join()??;
    Ok(())
}

fn main() {
    match ma1n() {
        Ok(()) => (),
        Err(_) => println!("an error occured and i was too lazy to implement the debug trait on it"),
    }
}
<|endoftext|>


<commit_before>/// Derives the next positional prefix array and divergence array
/// (Durbin's a_{k+1}[i] and d_{k+1}[i]) from the current ones
///
/// # Arguments
///
/// * `pos_prefix_array` - An array slice holding the positional prefix array (a_k[i])
/// * `div_array` - An array slice holding the divergence array (d_k[i])
/// * `haplotypes` - An array slice holding the haplotypes at the current (k-th) site
fn next_pp_and_div_arrays(pos_prefix_array: &[usize], div_array: &[usize], haplotypes: &[u8], k: usize) -> (Vec<usize>, Vec<usize>) {
    let mut allele_0_pos: Vec<usize> = vec![];
    let mut allele_0_div: Vec<usize> = vec![];
    let mut allele_1_pos: Vec<usize> = vec![];
    let mut allele_1_div: Vec<usize> = vec![];

    let mut div_0_index: usize = k + 1;  // TODO: Naming. longest_common_prefix?
    let mut div_1_index: usize = k + 1;

    for (&haplo_index, &start_of_match) in pos_prefix_array.iter().zip(div_array.iter()) {
        if start_of_match > div_0_index {
            div_0_index = start_of_match;
        }
        if start_of_match > div_1_index {
            div_1_index = start_of_match;
        }
        if haplotypes[haplo_index] == 0 {
            allele_0_pos.push(haplo_index);
            allele_0_div.push(div_0_index);
            div_0_index = 0;
        } else {
            allele_1_pos.push(haplo_index);
            allele_1_div.push(div_1_index);
            div_1_index = 0;
        }
    }
    let mut next_pp_array: Vec<usize> = vec![];
    next_pp_array.extend(allele_0_pos);
    next_pp_array.extend(allele_1_pos);
    let mut next_div_array: Vec<usize> = vec![];
    next_div_array.extend(allele_0_div);
    next_div_array.extend(allele_1_div);
    (next_pp_array, next_div_array)
}

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

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

fn main() {
}

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

    #[test]
    fn test_pp_and_div_arrays() {
        let n_haplo: usize = 8;
        let n_sites: usize = 6;
        let haplotypes: Vec<u8> = vec![0, 1, 1, 0, 0, 1, 1, 0,
                                       1, 1, 1, 1, 0, 0, 1, 1,
                                       0, 0, 1, 1, 0, 0, 0, 0,
                                       1, 0, 1, 1, 0, 0, 0, 1,
                                       0, 0, 1, 1, 0, 1, 0, 1,
                                       1, 1, 1, 0, 0, 0, 1, 0];
        let expected_pp_1: Vec<usize> = (0..8).collect();
        let expected_div_1: Vec<usize> = vec![0; 8];
        let (pp_1, div_1) = build_pp_and_div_arrays(&haplotypes, n_haplo, 1);
        assert_eq!(&expected_pp_1, &pp_1);
        assert_eq!(&expected_div_1, &div_1);
        let expected_pp_6: Vec<usize> = vec![4, 1, 6, 0, 5, 7, 3, 2];
        let expected_div_6: Vec<usize> = vec![5, 2, 0, 4, 5, 4, 3, 1];
        let (pp_6, div_6) = build_pp_and_div_arrays(&haplotypes, n_haplo, n_sites);
        assert_eq!(&expected_pp_6, &pp_6);
        assert_eq!(&expected_div_6, &div_6);
    }
}
<commit_msg>Improve naming<commit_after>/// Derives the next positional prefix array and divergence array
/// (Durbin's a_{k+1}[i] and d_{k+1}[i]) from the current ones
///
/// # Arguments
///
/// * `pos_prefix_array` - An array slice holding the positional prefix array (a_k[i])
/// * `div_array` - An array slice holding the divergence array (d_k[i])
/// * `haplotypes` - An array slice holding the haplotypes at the current (k-th) site
fn next_pp_and_div_arrays(pos_prefix_array: &[usize], div_array: &[usize], haplotypes: &[u8], k: usize) -> (Vec<usize>, Vec<usize>) {
    let mut allele_0_pos: Vec<usize> = vec![];
    let mut allele_0_div: Vec<usize> = vec![];
    let mut allele_1_pos: Vec<usize> = vec![];
    let mut allele_1_div: Vec<usize> = vec![];

    let mut match_0_start: usize = k + 1; // if this stays k+1, no match
    let mut match_1_start: usize = k + 1;

    for (&haplo_index, &start_of_match) in pos_prefix_array.iter().zip(div_array.iter()) {
        if start_of_match > div_0_index {
            match_0_start = start_of_match;
        }
        if start_of_match > div_1_index {
            match_1_start = start_of_match;
        }
        if haplotypes[haplo_index] == 0 {
            allele_0_pos.push(haplo_index);
            allele_0_div.push(match_0_start);
            match_0_start = 0;
        } else {
            allele_1_pos.push(haplo_index);
            allele_1_div.push(match_1_start);
            match_1_start = 0;
        }
    }
    let mut next_pp_array: Vec<usize> = vec![];
    next_pp_array.extend(allele_0_pos);
    next_pp_array.extend(allele_1_pos);
    let mut next_div_array: Vec<usize> = vec![];
    next_div_array.extend(allele_0_div);
    next_div_array.extend(allele_1_div);
    (next_pp_array, next_div_array)
}

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

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

fn main() {
}

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

    #[test]
    fn test_pp_and_div_arrays() {
        let n_haplo: usize = 8;
        let n_sites: usize = 6;
        let haplotypes: Vec<u8> = vec![0, 1, 1, 0, 0, 1, 1, 0,
                                       1, 1, 1, 1, 0, 0, 1, 1,
                                       0, 0, 1, 1, 0, 0, 0, 0,
                                       1, 0, 1, 1, 0, 0, 0, 1,
                                       0, 0, 1, 1, 0, 1, 0, 1,
                                       1, 1, 1, 0, 0, 0, 1, 0];
        let expected_pp_1: Vec<usize> = (0..8).collect();
        let expected_div_1: Vec<usize> = vec![0; 8];
        let (pp_1, div_1) = build_pp_and_div_arrays(&haplotypes, n_haplo, 1);
        assert_eq!(&expected_pp_1, &pp_1);
        assert_eq!(&expected_div_1, &div_1);
        let expected_pp_6: Vec<usize> = vec![4, 1, 6, 0, 5, 7, 3, 2];
        let expected_div_6: Vec<usize> = vec![5, 2, 0, 4, 5, 4, 3, 1];
        let (pp_6, div_6) = build_pp_and_div_arrays(&haplotypes, n_haplo, n_sites);
        assert_eq!(&expected_pp_6, &pp_6);
        assert_eq!(&expected_div_6, &div_6);
    }
}
<|endoftext|>


<commit_before>extern crate docopt;
extern crate rustc_serialize;

use std::process;
use std::io::prelude::*;
use std::io::Error;
use std::fs::File;
use std::time::{ Instant, Duration };
use docopt::Docopt;

pub mod error;
pub mod lexicon;
pub mod tokenizer;
pub mod parser;
pub mod grammar;
pub mod transformer;
pub mod codegen;

fn print_ms(label: &str, duration: &Duration) {
    let delta = ((duration.as_secs() as f64) * 1000.0) +
                (duration.subsec_nanos() as f64) / 1_000_000.0;

    println!("{} {}ms", label, delta);
}

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USAGE: &'static str = "
honeybadger

Usage:
  badger [options]
  badger --version

Options:
  -h --help                    Show this screen.
  --version                    Show version.
  -e SCRIPT, --string=SCRIPT   Specifies an input string.
  -f FILE, --file=FILE         Specifies the input file.
  -o FILE, --output=FILE       Specifies the output file.
  --pretty                     Don't minify the output.
  --ast                        Print out the Abstract Syntax Tree of the input.
";

fn read_file(path: &str) -> Result<String, Error> {
    let mut f = try!(File::open(path));
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(err)
    }
}

fn write_file(filename: &str, program: String) -> Result<(), Error> {
    let mut f = try!(File::create(filename));
    match f.write_all(&program.into_bytes()[..]) {
        Ok(_) => Ok(()),
        Err(err) => Err(err)
    }
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_file: Option<String>,
    flag_output: Option<String>,
    flag_version: bool,
    flag_ast: bool,
    flag_pretty: bool,
    flag_string: Option<String>,
}

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

    if args.flag_version {
        println!("v{}", VERSION);
        process::exit(0);
    }

    if args.flag_string.is_none() && args.flag_file.is_none() {
        println!("{}", USAGE);
        process::exit(0);
    }

    let input = match args.flag_string {
        Some(source) => source,
        None => {
                match read_file(&args.flag_file.unwrap()) {
                    Ok(file) => file,
                    Err(err) => {
                        println!("ERR Couldn't read file: {:?}", err);
                        process::exit(1)
                    }
                }
        }
    };

    let start = Instant::now();
    let mut ast = parser::parse(input);
    let parse_duration = Instant::now().duration_since(start);

    if args.flag_ast {
        println!("{:#?}", ast);
        print_ms("Parsing", &parse_duration);
        process::exit(0);
    }

    let start = Instant::now();
    transformer::transform(&mut ast, transformer::Settings::target_es5());
    let transform_duration = Instant::now().duration_since(start);

    let start = Instant::now();
    let program = codegen::generate_code(ast, !args.flag_pretty);
    let codegen_duration = Instant::now().duration_since(start);

    if args.flag_output.is_none() {
        println!("{}", program);
        print_ms("Parsing        ", &parse_duration);
        print_ms("Transformation ", &transform_duration);
        print_ms("Code generation", &codegen_duration);

        process::exit(0);
    }

    match write_file(&args.flag_output.unwrap(), program) {
        Ok(()) => {
            print_ms("Parsing        ", &parse_duration);
            print_ms("Transformation ", &transform_duration);
            print_ms("Code generation", &codegen_duration);
        },
        Err(err) => {
            println!("ERR Writing out.js {}", err);
            process::exit(1);
        }
    }
}
<commit_msg>Some cleanup<commit_after>extern crate docopt;
extern crate rustc_serialize;

use std::process;
use std::io::prelude::*;
use std::io::Error;
use std::fs::File;
use std::time::{ Instant, Duration };
use docopt::Docopt;

pub mod error;
pub mod lexicon;
pub mod tokenizer;
pub mod parser;
pub mod grammar;
pub mod transformer;
pub mod codegen;

fn print_ms(label: &str, duration: &Duration) {
    let delta = ((duration.as_secs() as f64) * 1000.0) +
                (duration.subsec_nanos() as f64) / 1_000_000.0;

    println!("{} {}ms", label, delta);
}

const VERSION: &'static str = env!("CARGO_PKG_VERSION");
const USAGE: &'static str = "
honeybadger

Usage:
  badger [options]
  badger --version

Options:
  -h --help                    Show this screen.
  --version                    Show version.
  -e SCRIPT, --string=SCRIPT   Specifies an input string.
  -f FILE, --file=FILE         Specifies the input file.
  -o FILE, --output=FILE       Specifies the output file.
  --pretty                     Don't minify the output.
  --ast                        Print out the Abstract Syntax Tree of the input.
";

fn read_file(path: &str) -> Result<String, Error> {
    let mut f = try!(File::open(path));
    let mut s = String::new();
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(err) => Err(err)
    }
}

fn write_file(filename: &str, program: String) -> Result<(), Error> {
    let mut f = try!(File::create(filename));
    match f.write_all(&program.into_bytes()[..]) {
        Ok(_) => Ok(()),
        Err(err) => Err(err)
    }
}

#[derive(Debug, RustcDecodable)]
struct Args {
    flag_file: Option<String>,
    flag_output: Option<String>,
    flag_version: bool,
    flag_ast: bool,
    flag_pretty: bool,
    flag_string: Option<String>,
}

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

    if args.flag_version {
        println!("v{}", VERSION);
        process::exit(0);
    }

    let source = match args.flag_string {
        Some(source) => source,
        None => {
            match args.flag_file {
                Some(path) => {
                    read_file(&path).unwrap_or_else(|err| {
                        println!("ERR Couldn't read file: {:?}", err);
                        process::exit(1);
                    })
                },
                None => {
                    println!("{}", USAGE);
                    process::exit(0);
                }
            }
        }
    };

    let start = Instant::now();
    let mut ast = parser::parse(source);
    let parse_duration = Instant::now().duration_since(start);

    if args.flag_ast {
        println!("{:#?}", ast);
        print_ms("Parsing", &parse_duration);
        process::exit(0);
    }

    let start = Instant::now();
    transformer::transform(&mut ast, transformer::Settings::target_es5());
    let transform_duration = Instant::now().duration_since(start);

    let start = Instant::now();
    let program = codegen::generate_code(ast, !args.flag_pretty);
    let codegen_duration = Instant::now().duration_since(start);

    if args.flag_output.is_none() {
        println!("{}", program);
        print_ms("Parsing        ", &parse_duration);
        print_ms("Transformation ", &transform_duration);
        print_ms("Code generation", &codegen_duration);

        process::exit(0);
    }

    match write_file(&args.flag_output.unwrap(), program) {
        Ok(()) => {
            print_ms("Parsing        ", &parse_duration);
            print_ms("Transformation ", &transform_duration);
            print_ms("Code generation", &codegen_duration);
        },
        Err(err) => {
            println!("ERR Writing out.js {}", err);
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>extern crate notify;

use notify::{RecommendedWatcher, Watcher};
use std::sync::mpsc::channel;
use std::env;

fn main() {
  // Create a channel to receive the events.
  let (tx, rx) = channel();

  // Automatically select the best implementation for your platform.
  // You can also access each implementation directly e.g. INotifyWatcher.
  let mut watcher: RecommendedWatcher = Watcher::new(tx).unwrap();

  let current_path = env::current_dir().unwrap();

  watcher.watch(current_path.as_path()).unwrap();

  loop {
    match rx.recv() {
      _ => println!("Recv.")
    }
  }
}
<commit_msg>rsnotify loop working<commit_after>extern crate notify;

use notify::{RecommendedWatcher, Watcher};
use std::sync::mpsc::channel;
use std::env;

fn main() {
  // Create a channel to receive the events.
  let (tx, rx) = channel();

  // Automatically select the best implementation for your platform.
  // You can also access each implementation directly e.g. INotifyWatcher.
  let mut watcher: RecommendedWatcher = Watcher::new(tx).unwrap();

  let current_path = env::current_dir().unwrap();

  watcher.watch(current_path.as_path()).unwrap();

  loop {
    match rx.recv() {
      Ok(event) => {
        println!("Recv {:?}", event);
        if let Some(path) = event.path {
            if let Ok(op) = event.op {
                println!("path: {:?}, op: {:?}", path, op);
            }
        }
      },
      Err(error) =>
        println!("Error: {}", error)
    }
  }
}
<|endoftext|>


<commit_before>#![recursion_limit = "256"]

extern crate ape;
extern crate app_dirs;
extern crate base64;
extern crate core;
extern crate crypto;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate md5;
extern crate metaflac;
extern crate mount;
extern crate mp3_duration;
extern crate params;
extern crate rand;
extern crate regex;
extern crate reqwest;
extern crate ring;
extern crate router;
extern crate rustfm_scrobble;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_xml_rs;
extern crate staticfile;
extern crate toml;
extern crate typemap;
extern crate url;
#[macro_use]
extern crate log;
extern crate simplelog;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;

#[cfg(unix)]
extern crate unix_daemonize;

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

use core::ops::Deref;
use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
#[cfg(unix)]
use simplelog::SimpleLogger;
use simplelog::{Level, LevelFilter, TermLogger};
use staticfile::Static;
use std::path::Path;
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};

mod api;
mod config;
mod db;
mod ddns;
mod errors;
mod index;
mod lastfm;
mod metadata;
mod playlist;
mod serve;
mod thumbnails;
mod ui;
mod user;
mod utils;
mod vfs;

static LOG_CONFIG: simplelog::Config = simplelog::Config {
	time: Some(Level::Error),
	level: Some(Level::Error),
	target: Some(Level::Error),
	location: Some(Level::Error),
	time_format: None,
};

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[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) {
			bail!("Error starting terminal logger: {}", e);
		};
	} else {
		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 let Err(e) = TermLogger::init(log_level, LOG_CONFIG) {
		bail!("Error starting terminal logger: {}", e);
	};
	Ok(())
}

fn run() -> 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(
		"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
	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)?;
		config::overwrite(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;

	// Init index
	let (index_sender, index_receiver) = channel();
	let index_sender = Arc::new(Mutex::new(index_sender));
	let db_ref = db.clone();
	std::thread::spawn(move || {
		let db = db_ref.deref();
		index::update_loop(db, &index_receiver);
	});

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

	// Mount API
	let prefix_url = config.prefix_url.unwrap_or_else(|| "".to_string());
	let api_url = format!("{}/api", &prefix_url);
	info!("Mounting API on {}", api_url);
	let mut mount = Mount::new();
	let handler = api::get_handler(&db.clone(), &index_sender)?;
	mount.mount(&api_url, handler);

	// Mount static files
	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 static_url = format!("/{}", &prefix_url);
	info!("Mounting static files on {}", static_url);
	mount.mount(&static_url, Static::new(web_dir_path));

	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or_else(|| "5050".to_owned())
		.parse()
		.or(Err("invalid port number"))?;

	let mut server = match Iron::new(mount).http(("0.0.0.0", port)) {
		Ok(s) => s,
		Err(e) => bail!("Error starting up server: {}", e),
	};

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

	// Run UI
	ui::run();

	info!("Shutting down server");
	if let Err(e) = server.close() {
		bail!("Error shutting down server: {}", e);
	}

	Ok(())
}
<commit_msg>Fixed init error on Windows<commit_after>#![recursion_limit = "256"]

extern crate ape;
extern crate app_dirs;
extern crate base64;
extern crate core;
extern crate crypto;
#[macro_use]
extern crate diesel;
#[macro_use]
extern crate diesel_migrations;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate md5;
extern crate metaflac;
extern crate mount;
extern crate mp3_duration;
extern crate params;
extern crate rand;
extern crate regex;
extern crate reqwest;
extern crate ring;
extern crate router;
extern crate rustfm_scrobble;
extern crate secure_session;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate serde_xml_rs;
extern crate staticfile;
extern crate toml;
extern crate typemap;
extern crate url;
#[macro_use]
extern crate log;
extern crate simplelog;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;

#[cfg(unix)]
extern crate unix_daemonize;

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

use core::ops::Deref;
use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use simplelog::{Level, LevelFilter, SimpleLogger, TermLogger};
use staticfile::Static;
use std::path::Path;
use std::sync::mpsc::channel;
use std::sync::{Arc, Mutex};

mod api;
mod config;
mod db;
mod ddns;
mod errors;
mod index;
mod lastfm;
mod metadata;
mod playlist;
mod serve;
mod thumbnails;
mod ui;
mod user;
mod utils;
mod vfs;

static LOG_CONFIG: simplelog::Config = simplelog::Config {
	time: Some(Level::Error),
	level: Some(Level::Error),
	target: Some(Level::Error),
	location: Some(Level::Error),
	time_format: None,
};

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

#[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) {
			bail!("Error starting terminal logger: {}", e);
		};
	} else {
		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 let Err(_) = TermLogger::init(log_level, LOG_CONFIG) {
		if let Err(e) = SimpleLogger::init(log_level, LOG_CONFIG) {
			bail!("Error starting simple logger: {}", e);
		}
	};
	Ok(())
}

fn run() -> 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(
		"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
	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)?;
		config::overwrite(db.deref(), &config)?;
	}
	let config = config::read(db.deref())?;

	// Init index
	let (index_sender, index_receiver) = channel();
	let index_sender = Arc::new(Mutex::new(index_sender));
	let db_ref = db.clone();
	std::thread::spawn(move || {
		let db = db_ref.deref();
		index::update_loop(db, &index_receiver);
	});

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

	// Mount API
	let prefix_url = config.prefix_url.unwrap_or_else(|| "".to_string());
	let api_url = format!("{}/api", &prefix_url);
	info!("Mounting API on {}", api_url);
	let mut mount = Mount::new();
	let handler = api::get_handler(&db.clone(), &index_sender)?;
	mount.mount(&api_url, handler);

	// Mount static files
	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 static_url = format!("/{}", &prefix_url);
	info!("Mounting static files on {}", static_url);
	mount.mount(&static_url, Static::new(web_dir_path));

	info!("Starting up server");
	let port: u16 = matches
		.opt_str("p")
		.unwrap_or_else(|| "5050".to_owned())
		.parse()
		.or(Err("invalid port number"))?;

	let mut server = match Iron::new(mount).http(("0.0.0.0", port)) {
		Ok(s) => s,
		Err(e) => bail!("Error starting up server: {}", e),
	};

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

	// Run UI
	ui::run();

	info!("Shutting down server");
	if let Err(e) = server.close() {
		bail!("Error shutting down server: {}", e);
	}

	Ok(())
}
<|endoftext|>


<commit_before>#![feature(plugin, custom_derive, decl_macro)]
#![plugin(rocket_codegen)]
extern crate ip_manager;
extern crate rocket;
extern crate rocket_contrib;
extern crate toml;

use std::fs;
use std::io::Read;
use std::sync::{Arc, Mutex};
use rocket::request::LenientForm;
use ip_manager::{ip, settings, slash_command};

enum Command {
    Add,
    Get,
    Edit,
    Issue,
    Help,
}

impl std::fmt::Display for Command {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                &Command::Add => "Add",
                &Command::Get => "Get",
                &Command::Edit => "Edit",
                &Command::Issue => "Issue",
                &Command::Help => "Help",
            }
        )
    }
}

fn main() {
    try_main().unwrap();
}

fn try_main() -> Result<(), Box<std::error::Error>> {
    let ip_list = Arc::new(Mutex::new(ip::List::default()));
    let settings = Arc::new(Mutex::new(settings::Settings::new()?));

    let dir_entries: fs::ReadDir = fs::read_dir("data")?;
    let files: Vec<fs::DirEntry> = dir_entries.map(|e| e.unwrap()).collect();
    {
        let mut ips = ip_list.lock().unwrap();
        files
            .into_iter()
            .map(|f| {
                let mut file = fs::File::open(f.path()).unwrap();
                let mut content: String = String::new();
                file.read_to_string(&mut content).unwrap();
                toml::from_str(&content).unwrap()
            })
            .for_each(|e| ips.add(e));
    }

    rocket::ignite()
        .manage(ip_list)
        .manage(settings)
        .mount("/ip-manager", routes![command_request])
        .launch();
    Ok(())
}

#[post("/command", data = "<form>")]
fn command_request(form: LenientForm<slash_command::Request>) -> String {
    let data = form.into_inner();
    let command = parse_command(&data.text);
    println!("{}", command);
    "foo".to_owned()
}

fn parse_command(content: &str) -> Command {
    match content.split(' ').nth(0) {
        Some(s) => match &s.to_lowercase()[..] {
            "add" => Command::Add,
            "get" => Command::Get,
            "edit" => Command::Edit,
            "issue" => Command::Issue,
            _ => Command::Help,
        },
        None => Command::Help,
    }
}
<commit_msg>divide commands into functions<commit_after>#![feature(plugin, custom_derive, decl_macro)]
#![plugin(rocket_codegen)]
extern crate ip_manager;
extern crate rocket;
extern crate rocket_contrib;
extern crate toml;

use std::fs;
use std::io::Read;
use std::sync::{Arc, Mutex};
use rocket::request::LenientForm;
use rocket::State;
use ip_manager::{ip, settings, slash_command};

enum Command {
    Add,
    Get,
    Edit,
    Issue,
    Help,
}

impl std::fmt::Display for Command {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        use Command::*;
        write!(
            f,
            "{}",
            match self {
                &Add => "Add",
                &Get => "Get",
                &Edit => "Edit",
                &Issue => "Issue",
                &Help => "Help",
            }
        )
    }
}

fn main() {
    try_main().unwrap();
}

fn try_main() -> Result<(), Box<std::error::Error>> {
    let ip_list = Arc::new(Mutex::new(ip::List::default()));
    let settings = Arc::new(Mutex::new(settings::Settings::new()?));

    let dir_entries: fs::ReadDir = fs::read_dir("data")?;
    let files: Vec<fs::DirEntry> = dir_entries.map(|e| e.unwrap()).collect();
    {
        let mut ips = ip_list.lock().unwrap();
        files
            .into_iter()
            .map(|f| {
                let mut file = fs::File::open(f.path()).unwrap();
                let mut content: String = String::new();
                file.read_to_string(&mut content).unwrap();
                toml::from_str(&content).unwrap()
            })
            .for_each(|e| ips.add(e));
    }

    rocket::ignite()
        .manage(ip_list)
        .manage(settings)
        .mount("/ip-manager", routes![command_request])
        .launch();
    Ok(())
}

#[post("/command", data = "<form>")]
fn command_request(
    form: LenientForm<slash_command::Request>,
    ips: State<Arc<Mutex<ip::List>>>,
    settings: State<Arc<Mutex<settings::Settings>>>,
) -> String {
    let data = form.into_inner();
    let s = &*settings.lock().unwrap();
    if s.token != data.token {
        return "".to_owned();
    }

    let command = parse_command(&data.text);
    let i = &*ips.lock().unwrap();
    do_command(command, i, &data.text)
}

fn parse_command(content: &str) -> Command {
    use Command::*;
    match content.split(' ').nth(0) {
        Some(s) => match &s.to_lowercase()[..] {
            "add" => Add,
            "get" => Get,
            "edit" => Edit,
            "issue" => Issue,
            _ => Help,
        },
        None => Help,
    }
}

fn do_command(command: Command, ips: &ip::List, content: &str) -> String {
    use Command::*;
    match command {
        Add => add(ips, content),
        Get => get(ips, content),
        Edit => edit(ips, content),
        Issue => issue(ips, content),
        Help => help(ips, content),
    }
}

fn add(ips: &ip::List, content: &str) -> String {
    "add".to_owned()
}

fn get(ips: &ip::List, content: &str) -> String {
    "get".to_owned()
}

fn edit(ips: &ip::List, content: &str) -> String {
    "edit".to_owned()
}

fn issue(ips: &ip::List, content: &str) -> String {
    "issue".to_owned()
}

fn help(ips: &ip::List, content: &str) -> String {
    "help".to_owned()
}
<|endoftext|>


<commit_before>use num::BigUint;
use num::traits::{Zero, One, FromPrimitive};
use digit_slice::{DigitSlice, FromDigits};
use {Shape, Noun, NockError, NockResult};

/// Evaluate the nock `*[subject formula]`
pub fn nock_on(mut subject: Noun, mut formula: Noun) -> NockResult {
    loop {
        if let Shape::Cell(ops, tail) = formula.clone().get() {
            match ops.as_u32() {
                // Axis
                Some(0) => {
                    match tail.get() {
                        Shape::Atom(ref x) => return axis(x, &subject),
                        _ => return Err(NockError),
                    }
                }

                // Just
                Some(1) => return Ok(tail.clone()),

                // Fire
                Some(2) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            let q = try!(nock_on(subject, (*c).clone()));
                            subject = p;
                            formula = q;
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Depth
                Some(3) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Cell(_, _) => Ok(Noun::from(0u32)),
                        _ => Ok(Noun::from(1u32)),
                    };
                }

                // Bump
                Some(4) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Atom(ref x) => {
                            // TODO: Non-bignum optimization
                            Ok(Noun::from(BigUint::from_digits(x).unwrap() +
                                          BigUint::one()))
                        }
                        _ => Err(NockError),
                    };
                }

                // Same
                Some(5) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Cell(ref a, ref b) => {
                            if a == b {
                                // Yes.
                                return Ok(Noun::from(0u32));
                            } else {
                                // No.
                                return Ok(Noun::from(1u32));
                            }
                        }
                        _ => return Err(NockError),
                    };
                }

                // If
                Some(6) => {
                    if let Some((b, c, d)) = tail.get_122() {
                        let p = try!(nock_on(subject.clone(), (*b).clone()));
                        match p.get() {
                            Shape::Atom(ref x) => {
                                if x == &0u32.as_digits() {
                                    formula = (*c).clone();
                                } else if x == &1u32.as_digits() {
                                    formula = (*d).clone();
                                } else {
                                    return Err(NockError);
                                }
                            }
                            _ => return Err(NockError),
                        }
                        continue;
                    } else {
                        return Err(NockError);
                    }
                }

                // Compose
                Some(7) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            subject = p;
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Push
                Some(8) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            subject = Noun::cell(p, subject);
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Call
                Some(9) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            subject = try!(nock_on(subject.clone(),
                                                   (*c).clone()));
                            formula = try!(nock_on(subject.clone(),
                                             Noun::cell(Noun::from(0u32),
                                                        (*b).clone())));
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Hint
                Some(10) => {
                    match tail.get() {
                        Shape::Cell(ref _b, ref c) => {
                            // Throw away b.

                            // TODO: Check if b is a cell and fail if it would
                            // crash.
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Unhandled opcode
                Some(_) => {
                    return Err(NockError);
                }

                None => {
                    if let Shape::Cell(_, _) = ops.get() {
                        // Autocons
                        let a = try!(nock_on(subject.clone(), ops.clone()));
                        let b = try!(nock_on(subject, tail.clone()));
                        return Ok(Noun::cell(a, b));
                    } else {
                        return Err(NockError);
                    }
                }
            }
        } else {
            return Err(NockError);
        }
    }
}

fn axis(atom: &[u8], subject: &Noun) -> NockResult {
    // TODO: Optimize for small atoms.
    fn fas(x: BigUint, n: &Noun) -> NockResult {
        let two = BigUint::from_u32(2).unwrap();
        let three = BigUint::from_u32(3).unwrap();
        if x == BigUint::zero() {
            return Err(NockError);
        }
        if x == BigUint::one() {
            return Ok(n.clone());
        }
        if let Shape::Cell(ref a, ref b) = n.get() {
            if x == two {
                return Ok((*a).clone());
            } else if x == three {
                return Ok((*b).clone());
            } else {
                let half = x.clone() >> 1;
                let p = try!(fas(half, n));

                if x % two.clone() == BigUint::zero() {
                    fas(two, &p)
                } else {
                    fas(three, &p)
                }
            }
        } else {
            return Err(NockError);
        }
    }

    fas(BigUint::from_digits(atom).unwrap(), subject)
}
<commit_msg>Naming<commit_after>use num::BigUint;
use num::traits::{Zero, One, FromPrimitive};
use digit_slice::{DigitSlice, FromDigits};
use {Shape, Noun, NockError, NockResult};

/// Evaluate the nock `*[subject formula]`
pub fn nock_on(mut subject: Noun, mut formula: Noun) -> NockResult {
    loop {
        if let Shape::Cell(ops, tail) = formula.clone().get() {
            match ops.as_u32() {
                // Axis
                Some(0) => {
                    match tail.get() {
                        Shape::Atom(ref x) => return axis(x, &subject),
                        _ => return Err(NockError),
                    }
                }

                // Just
                Some(1) => return Ok(tail.clone()),

                // Fire
                Some(2) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            let q = try!(nock_on(subject, (*c).clone()));
                            subject = p;
                            formula = q;
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Depth
                Some(3) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Cell(_, _) => Ok(Noun::from(0u32)),
                        _ => Ok(Noun::from(1u32)),
                    };
                }

                // Bump
                Some(4) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Atom(ref x) => {
                            // TODO: Non-bignum optimization
                            Ok(Noun::from(BigUint::from_digits(x).unwrap() +
                                          BigUint::one()))
                        }
                        _ => Err(NockError),
                    };
                }

                // Same
                Some(5) => {
                    let p = try!(nock_on(subject.clone(), (*tail).clone()));
                    return match p.get() {
                        Shape::Cell(ref a, ref b) => {
                            if a == b {
                                // Yes.
                                return Ok(Noun::from(0u32));
                            } else {
                                // No.
                                return Ok(Noun::from(1u32));
                            }
                        }
                        _ => return Err(NockError),
                    };
                }

                // If
                Some(6) => {
                    if let Some((b, c, d)) = tail.get_122() {
                        let p = try!(nock_on(subject.clone(), (*b).clone()));
                        match p.get() {
                            Shape::Atom(ref x) => {
                                if x == &0u32.as_digits() {
                                    formula = (*c).clone();
                                } else if x == &1u32.as_digits() {
                                    formula = (*d).clone();
                                } else {
                                    return Err(NockError);
                                }
                            }
                            _ => return Err(NockError),
                        }
                        continue;
                    } else {
                        return Err(NockError);
                    }
                }

                // Compose
                Some(7) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            subject = p;
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Push
                Some(8) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            let p = try!(nock_on(subject.clone(),
                                                 (*b).clone()));
                            subject = Noun::cell(p, subject);
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Call
                Some(9) => {
                    match tail.get() {
                        Shape::Cell(ref b, ref c) => {
                            subject = try!(nock_on(subject.clone(),
                                                   (*c).clone()));
                            formula = try!(nock_on(subject.clone(),
                                             Noun::cell(Noun::from(0u32),
                                                        (*b).clone())));
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Hint
                Some(10) => {
                    match tail.get() {
                        Shape::Cell(ref hint, ref c) => {
                            // Throw away hint.

                            // TODO: Check if hint is a cell and fail if it would
                            // crash.
                            formula = (*c).clone();
                            continue;
                        }
                        _ => return Err(NockError),
                    }
                }

                // Unhandled opcode
                Some(_) => {
                    return Err(NockError);
                }

                None => {
                    if let Shape::Cell(_, _) = ops.get() {
                        // Autocons
                        let a = try!(nock_on(subject.clone(), ops.clone()));
                        let b = try!(nock_on(subject, tail.clone()));
                        return Ok(Noun::cell(a, b));
                    } else {
                        return Err(NockError);
                    }
                }
            }
        } else {
            return Err(NockError);
        }
    }
}

fn axis(atom: &[u8], subject: &Noun) -> NockResult {
    // TODO: Optimize for small atoms.
    fn fas(x: BigUint, n: &Noun) -> NockResult {
        let two = BigUint::from_u32(2).unwrap();
        let three = BigUint::from_u32(3).unwrap();
        if x == BigUint::zero() {
            return Err(NockError);
        }
        if x == BigUint::one() {
            return Ok(n.clone());
        }
        if let Shape::Cell(ref a, ref b) = n.get() {
            if x == two {
                return Ok((*a).clone());
            } else if x == three {
                return Ok((*b).clone());
            } else {
                let half = x.clone() >> 1;
                let p = try!(fas(half, n));

                if x % two.clone() == BigUint::zero() {
                    fas(two, &p)
                } else {
                    fas(three, &p)
                }
            }
        } else {
            return Err(NockError);
        }
    }

    fas(BigUint::from_digits(atom).unwrap(), subject)
}
<|endoftext|>


<commit_before>// Copyright 2013 The rust-pcre authors.
//
// 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.

#[link(name = "pcre", vers = "0.1")];
#[crate_type = "lib"];

use std::libc::{c_int, c_uchar, c_void};
use std::option::{None, Option, Some};
use std::ptr::{is_not_null, null};
use std::vec::{from_elem};
use std::vec::raw::{to_mut_ptr};

pub type options = c_int;

pub static PCRE_CASELESS: options = 0x00000001;
pub static PCRE_MULTILINE: options = 0x00000002;
pub static PCRE_DOTALL: options = 0x00000004;
pub static PCRE_EXTENDED: options = 0x00000008;
pub static PCRE_ANCHORED: options = 0x00000010;
pub static PCRE_DOLLAR_ENDONLY: options = 0x00000020;
pub static PCRE_EXTRA: options = 0x00000040;
pub static PCRE_NOTBOL: options = 0x00000080;
pub static PCRE_NOTEOL: options = 0x00000100;
pub static PCRE_UNGREEDY: options = 0x00000200;
pub static PCRE_NOTEMPTY: options = 0x00000400;
pub static PCRE_UTF8: options = 0x00000800;
pub static PCRE_UTF16: options = 0x00000800;
pub static PCRE_UTF32: options = 0x00000800;
pub static PCRE_NO_AUTO_CAPTURE: options = 0x00001000;
pub static PCRE_NO_UTF8_CHECK: options = 0x00002000;
pub static PCRE_NO_UTF16_CHECK: options = 0x00002000;
pub static PCRE_NO_UTF32_CHECK: options = 0x00002000;
pub static PCRE_AUTO_CALLOUT: options = 0x00004000;
pub static PCRE_PARTIAL_SOFT: options = 0x00008000;
pub static PCRE_PARTIAL: options = 0x00008000;
pub static PCRE_NEVER_UTF: options = 0x00010000;
pub static PCRE_DFA_SHORTEST: options = 0x00010000;
pub static PCRE_DFA_RESTART: options = 0x00020000;
pub static PCRE_FIRSTLINE: options = 0x00040000;
pub static PCRE_DUPNAMES: options = 0x00080000;
pub static PCRE_NEWLINE_CR: options = 0x00100000;
pub static PCRE_NEWLINE_LF: options = 0x00200000;
pub static PCRE_NEWLINE_CRLF: options = 0x00300000;
pub static PCRE_NEWLINE_ANY: options = 0x00400000;
pub static PCRE_NEWLINE_ANYCRLF: options = 0x00500000;
pub static PCRE_BSR_ANYCRLF: options = 0x00800000;
pub static PCRE_BSR_UNICODE: options = 0x01000000;
pub static PCRE_JAVASCRIPT_COMPAT: options = 0x02000000;
pub static PCRE_NO_START_OPTIMIZE: options = 0x04000000;
pub static PCRE_NO_START_OPTIMISE: options = 0x04000000;
pub static PCRE_PARTIAL_HARD: options = 0x08000000;
pub static PCRE_NOTEMPTY_ATSTART: options = 0x10000000;
pub static PCRE_UCP: options = 0x20000000;

mod detail {

    use std::c_str::*;
    use std::libc::*;
    use std::ptr::*;

    pub type fullinfo_field = c_int;
    pub type pcre = c_void;
    pub type pcre_error = c_int;
    pub type pcre_extra = c_void;

    pub static PCRE_ERROR_NOMATCH: pcre_error = -1;
    pub static PCRE_ERROR_NULL: pcre_error = -2;

    pub static PCRE_INFO_CAPTURECOUNT: fullinfo_field = 2;

    mod native {

        use std::libc::*;

        #[link_args = "-lpcre.1"]
        extern {
            static pcre_free: extern "C" fn(ptr: *c_void);

            fn pcre_compile(pattern: *c_char, options: ::options, errptr: *mut *c_char, erroffset: *mut c_int, tableptr: *c_uchar) -> *::detail::pcre;
            fn pcre_exec(code: *::detail::pcre, extra: *::detail::pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: ::options, ovector: *mut c_int, ovecsize: c_int) -> ::detail::pcre_error;
            fn pcre_free_study(extra: *::detail::pcre_extra);
            fn pcre_fullinfo(code: *::detail::pcre, extra: *::detail::pcre_extra, what: ::detail::fullinfo_field, where: *mut c_void) -> c_int;
        }

    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_compile(pattern: *c_char, options: ::options, tableptr: *c_uchar) -> *pcre {
        assert!(is_not_null(pattern));
        let mut err: *c_char = null();
        let mut erroffset: c_int = 0;
        let code = unsafe { native::pcre_compile(pattern, options, &mut err, &mut erroffset, tableptr) };

        if is_null(code) {
            // "Otherwise, if  compilation  of  a  pattern fails, pcre_compile() returns
            // NULL, and sets the variable pointed to by errptr to point to a textual
            // error message. This is a static string that is part of the library. You
            // must not try to free it."
            // http://pcre.org/pcre.txt
            unsafe {
                let err_cstring = CString::new(err, false);
                error!("pcre_compile() failed at offset %u: %s", erroffset as uint, err_cstring.as_str().unwrap());
            }
            fail!("pcre_compile");
        }
        assert!(is_not_null(code) && erroffset == 0);

        code
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_exec(code: *pcre, extra: *pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: ::options, ovector: *mut c_int, ovecsize: c_int) -> bool {
        assert!(is_not_null(code));
        assert!(ovecsize >= 0 && ovecsize % 3 == 0);
        let rc = unsafe { native::pcre_exec(code, extra, subject, length, startoffset, options, ovector, ovecsize) };
        if rc == PCRE_ERROR_NOMATCH {
            return false;
        } else if rc < 0 && rc != PCRE_ERROR_NULL {
            fail!("pcre_exec");
        }

        true
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_free(ptr: *c_void) {
        native::pcre_free(ptr);
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_free_study(extra: *pcre_extra) {
        unsafe { native::pcre_free_study(extra); }
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_fullinfo(code: *pcre, extra: *pcre_extra, what: fullinfo_field, where: *mut c_void) {
        assert!(is_not_null(code));
        let rc = unsafe { native::pcre_fullinfo(code, extra, what, where) };
        if rc < 0 && rc != PCRE_ERROR_NULL {
            fail!("pcre_fullinfo");
        }
    }

} // End `mod detail`.

pub struct Pcre {

    priv code: *detail::pcre,

    priv extra: *detail::pcre_extra,

    capture_count: uint

}

pub struct Match<'self> {

    priv subject: &'self str,

    priv ovector: ~[c_int]

}

impl Pcre {
    fn compile(pattern: &str) -> Pcre {
        Pcre::compile_with_options(pattern, 0)
    }

    fn compile_with_options(pattern: &str, options: options) -> Pcre {
        do pattern.with_c_str |pattern_c_str| {
            // Use the default character tables.
            let tableptr: *c_uchar = null();
            let code = detail::pcre_compile(pattern_c_str, options, tableptr);
            assert!(is_not_null(code));

            let extra: *detail::pcre_extra = null();

            let mut capture_count: c_int = 0;
            detail::pcre_fullinfo(code, extra, detail::PCRE_INFO_CAPTURECOUNT, &mut capture_count as *mut c_int as *mut c_void);

            Pcre {
                code: code,
                extra: extra,
                capture_count: capture_count as uint
            }
        }
    }

    fn exec<'a>(&self, subject: &'a str) -> Option<Match<'a>> {
        self.exec_from(subject, 0)
    }

    fn exec_from<'a>(&self, subject: &'a str, startoffset: uint) -> Option<Match<'a>> {
        self.exec_from_with_options(subject, startoffset, 0)
    }

    fn exec_from_with_options<'a>(&self, subject: &'a str, startoffset: uint, options: options) -> Option<Match<'a>> {
        let ovecsize = (self.capture_count + 1) * 3;
        let mut ovector: ~[c_int] = from_elem(ovecsize, 0 as c_int);

        unsafe {
            do subject.with_c_str_unchecked |subject_c_str| -> Option<Match<'a>> {
                if detail::pcre_exec(self.code, self.extra, subject_c_str, subject.len() as c_int, startoffset as c_int, options, to_mut_ptr(ovector), ovecsize as c_int) {
                    Some(Match {
                        subject: subject,
                        // TODO: Is it possible to avoid to_owned()?
                        // Probably need multiple lifetime parameters:
                        // https://mail.mozilla.org/pipermail/rust-dev/2013-September/005829.html
                        ovector: ovector.slice_to((self.capture_count + 1) * 2).to_owned()
                    })
                } else {
                    None
                }
            }
        }
    }
}

impl Drop for Pcre {
    fn drop(&mut self) {
        detail::pcre_free_study(self.extra);
        self.extra = null();
        detail::pcre_free(self.code);
        self.code = null();
    }
}

impl<'self> Match<'self> {

    fn group_start(&self, n: uint) -> uint {
        self.ovector[(n * 2) as uint] as uint
    }

    fn group_end(&self, n: uint) -> uint {
        self.ovector[(n * 2 + 1) as uint] as uint
    }

    fn group_len(&self, n: uint) -> uint {
        let group_offsets = self.ovector.slice_from((n * 2) as uint);
        (group_offsets[1] - group_offsets[0]) as uint
    }

    fn group(&self, n: uint) -> &'self str {
        let group_offsets = self.ovector.slice_from((n * 2) as uint);
        let start = group_offsets[0];
        let end = group_offsets[1];
        self.subject.slice(start as uint, end as uint)
    }

}

#[cfg(test)]
mod tests {

    #[test]
    #[should_fail]
    fn test_compile_nul() {
        // Nul bytes are not allowed in the pattern string.
        ::Pcre::compile("\0abc");
    }

    #[test]
    #[should_fail]
    fn test_compile_bad_pattern() {
        ::Pcre::compile("[");
    }

    #[test]
    fn test_compile_capture_count() {
        let re = ::Pcre::compile("(?:abc)(def)");
        assert_eq!(re.capture_count, 1u);
    }

    #[test]
    fn test_exec_basic() {
        let re = ::Pcre::compile("^...$");
        assert_eq!(re.capture_count, 0u);
        let m = re.exec("abc").unwrap();
        assert_eq!(m.group(0), "abc");
    }

    #[test]
    fn test_exec_no_match() {
        let re = ::Pcre::compile("abc");
        assert!(re.exec("def").is_none());
    }

    #[test]
    fn test_exec_nul_byte() {
        // Nul bytes *are* allowed in subject strings, however.
        let re = ::Pcre::compile("abc\\0def");
        let m = re.exec("abc\0def").unwrap();
        assert_eq!(m.group(0), "abc\0def");
    }

    #[test]
    fn test_exec_from_basic() {
        let re = ::Pcre::compile("abc");
        let subject = "abcabc";
        let m1 = re.exec_from(subject, 1u).unwrap();
        assert_eq!(m1.group_start(0u), 3u);
        assert_eq!(m1.group_end(0u), 6u);
        assert_eq!(m1.group_len(0u), 3u);
        let m2 = re.exec(subject).unwrap();
        assert_eq!(m2.group_start(0u), 0u);
    }
}
<commit_msg>Clean up imports<commit_after>// Copyright 2013 The rust-pcre authors.
//
// 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.

#[link(name = "pcre", vers = "0.1")];
#[crate_type = "lib"];

use std::libc::{c_int, c_uchar, c_void};
use std::option::{Option};
use std::ptr;
use std::vec;

pub type options = c_int;

pub static PCRE_CASELESS: options = 0x00000001;
pub static PCRE_MULTILINE: options = 0x00000002;
pub static PCRE_DOTALL: options = 0x00000004;
pub static PCRE_EXTENDED: options = 0x00000008;
pub static PCRE_ANCHORED: options = 0x00000010;
pub static PCRE_DOLLAR_ENDONLY: options = 0x00000020;
pub static PCRE_EXTRA: options = 0x00000040;
pub static PCRE_NOTBOL: options = 0x00000080;
pub static PCRE_NOTEOL: options = 0x00000100;
pub static PCRE_UNGREEDY: options = 0x00000200;
pub static PCRE_NOTEMPTY: options = 0x00000400;
pub static PCRE_UTF8: options = 0x00000800;
pub static PCRE_UTF16: options = 0x00000800;
pub static PCRE_UTF32: options = 0x00000800;
pub static PCRE_NO_AUTO_CAPTURE: options = 0x00001000;
pub static PCRE_NO_UTF8_CHECK: options = 0x00002000;
pub static PCRE_NO_UTF16_CHECK: options = 0x00002000;
pub static PCRE_NO_UTF32_CHECK: options = 0x00002000;
pub static PCRE_AUTO_CALLOUT: options = 0x00004000;
pub static PCRE_PARTIAL_SOFT: options = 0x00008000;
pub static PCRE_PARTIAL: options = 0x00008000;
pub static PCRE_NEVER_UTF: options = 0x00010000;
pub static PCRE_DFA_SHORTEST: options = 0x00010000;
pub static PCRE_DFA_RESTART: options = 0x00020000;
pub static PCRE_FIRSTLINE: options = 0x00040000;
pub static PCRE_DUPNAMES: options = 0x00080000;
pub static PCRE_NEWLINE_CR: options = 0x00100000;
pub static PCRE_NEWLINE_LF: options = 0x00200000;
pub static PCRE_NEWLINE_CRLF: options = 0x00300000;
pub static PCRE_NEWLINE_ANY: options = 0x00400000;
pub static PCRE_NEWLINE_ANYCRLF: options = 0x00500000;
pub static PCRE_BSR_ANYCRLF: options = 0x00800000;
pub static PCRE_BSR_UNICODE: options = 0x01000000;
pub static PCRE_JAVASCRIPT_COMPAT: options = 0x02000000;
pub static PCRE_NO_START_OPTIMIZE: options = 0x04000000;
pub static PCRE_NO_START_OPTIMISE: options = 0x04000000;
pub static PCRE_PARTIAL_HARD: options = 0x08000000;
pub static PCRE_NOTEMPTY_ATSTART: options = 0x10000000;
pub static PCRE_UCP: options = 0x20000000;

mod detail {

    use std::c_str::*;
    use std::libc::*;
    use std::ptr;

    pub type fullinfo_field = c_int;
    pub type pcre = c_void;
    pub type pcre_error = c_int;
    pub type pcre_extra = c_void;

    pub static PCRE_ERROR_NOMATCH: pcre_error = -1;
    pub static PCRE_ERROR_NULL: pcre_error = -2;

    pub static PCRE_INFO_CAPTURECOUNT: fullinfo_field = 2;

    mod native {

        use std::libc::*;

        #[link_args = "-lpcre.1"]
        extern {
            static pcre_free: extern "C" fn(ptr: *c_void);

            fn pcre_compile(pattern: *c_char, options: ::options, errptr: *mut *c_char, erroffset: *mut c_int, tableptr: *c_uchar) -> *::detail::pcre;
            fn pcre_exec(code: *::detail::pcre, extra: *::detail::pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: ::options, ovector: *mut c_int, ovecsize: c_int) -> ::detail::pcre_error;
            fn pcre_free_study(extra: *::detail::pcre_extra);
            fn pcre_fullinfo(code: *::detail::pcre, extra: *::detail::pcre_extra, what: ::detail::fullinfo_field, where: *mut c_void) -> c_int;
        }

    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_compile(pattern: *c_char, options: ::options, tableptr: *c_uchar) -> *pcre {
        assert!(ptr::is_not_null(pattern));
        let mut err: *c_char = ptr::null();
        let mut erroffset: c_int = 0;
        let code = unsafe { native::pcre_compile(pattern, options, &mut err, &mut erroffset, tableptr) };

        if ptr::is_null(code) {
            // "Otherwise, if  compilation  of  a  pattern fails, pcre_compile() returns
            // NULL, and sets the variable pointed to by errptr to point to a textual
            // error message. This is a static string that is part of the library. You
            // must not try to free it."
            // http://pcre.org/pcre.txt
            unsafe {
                let err_cstring = CString::new(err, false);
                error!("pcre_compile() failed at offset %u: %s", erroffset as uint, err_cstring.as_str().unwrap());
            }
            fail!("pcre_compile");
        }
        assert!(ptr::is_not_null(code) && erroffset == 0);

        code
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_exec(code: *pcre, extra: *pcre_extra, subject: *c_char, length: c_int, startoffset: c_int, options: ::options, ovector: *mut c_int, ovecsize: c_int) -> bool {
        assert!(ptr::is_not_null(code));
        assert!(ovecsize >= 0 && ovecsize % 3 == 0);
        let rc = unsafe { native::pcre_exec(code, extra, subject, length, startoffset, options, ovector, ovecsize) };
        if rc == PCRE_ERROR_NOMATCH {
            return false;
        } else if rc < 0 && rc != PCRE_ERROR_NULL {
            fail!("pcre_exec");
        }

        true
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_free(ptr: *c_void) {
        native::pcre_free(ptr);
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_free_study(extra: *pcre_extra) {
        unsafe { native::pcre_free_study(extra); }
    }

    #[fixed_stack_segment]
    #[inline(never)]
    pub fn pcre_fullinfo(code: *pcre, extra: *pcre_extra, what: fullinfo_field, where: *mut c_void) {
        assert!(ptr::is_not_null(code));
        let rc = unsafe { native::pcre_fullinfo(code, extra, what, where) };
        if rc < 0 && rc != PCRE_ERROR_NULL {
            fail!("pcre_fullinfo");
        }
    }

} // End `mod detail`.

pub struct Pcre {

    priv code: *detail::pcre,

    priv extra: *detail::pcre_extra,

    capture_count: uint

}

pub struct Match<'self> {

    priv subject: &'self str,

    priv ovector: ~[c_int]

}

impl Pcre {
    fn compile(pattern: &str) -> Pcre {
        Pcre::compile_with_options(pattern, 0)
    }

    fn compile_with_options(pattern: &str, options: options) -> Pcre {
        do pattern.with_c_str |pattern_c_str| {
            // Use the default character tables.
            let tableptr: *c_uchar = ptr::null();
            let code = detail::pcre_compile(pattern_c_str, options, tableptr);
            assert!(ptr::is_not_null(code));

            let extra: *detail::pcre_extra = ptr::null();

            let mut capture_count: c_int = 0;
            detail::pcre_fullinfo(code, extra, detail::PCRE_INFO_CAPTURECOUNT, &mut capture_count as *mut c_int as *mut c_void);

            Pcre {
                code: code,
                extra: extra,
                capture_count: capture_count as uint
            }
        }
    }

    fn exec<'a>(&self, subject: &'a str) -> Option<Match<'a>> {
        self.exec_from(subject, 0)
    }

    fn exec_from<'a>(&self, subject: &'a str, startoffset: uint) -> Option<Match<'a>> {
        self.exec_from_with_options(subject, startoffset, 0)
    }

    fn exec_from_with_options<'a>(&self, subject: &'a str, startoffset: uint, options: options) -> Option<Match<'a>> {
        let ovecsize = (self.capture_count + 1) * 3;
        let mut ovector: ~[c_int] = vec::from_elem(ovecsize, 0 as c_int);

        unsafe {
            do subject.with_c_str_unchecked |subject_c_str| -> Option<Match<'a>> {
                if detail::pcre_exec(self.code, self.extra, subject_c_str, subject.len() as c_int, startoffset as c_int, options, vec::raw::to_mut_ptr(ovector), ovecsize as c_int) {
                    Some(Match {
                        subject: subject,
                        // TODO: Is it possible to avoid to_owned()?
                        // Probably need multiple lifetime parameters:
                        // https://mail.mozilla.org/pipermail/rust-dev/2013-September/005829.html
                        ovector: ovector.slice_to((self.capture_count + 1) * 2).to_owned()
                    })
                } else {
                    None
                }
            }
        }
    }
}

impl Drop for Pcre {
    fn drop(&mut self) {
        detail::pcre_free_study(self.extra);
        self.extra = ptr::null();
        detail::pcre_free(self.code);
        self.code = ptr::null();
    }
}

impl<'self> Match<'self> {

    fn group_start(&self, n: uint) -> uint {
        self.ovector[(n * 2) as uint] as uint
    }

    fn group_end(&self, n: uint) -> uint {
        self.ovector[(n * 2 + 1) as uint] as uint
    }

    fn group_len(&self, n: uint) -> uint {
        let group_offsets = self.ovector.slice_from((n * 2) as uint);
        (group_offsets[1] - group_offsets[0]) as uint
    }

    fn group(&self, n: uint) -> &'self str {
        let group_offsets = self.ovector.slice_from((n * 2) as uint);
        let start = group_offsets[0];
        let end = group_offsets[1];
        self.subject.slice(start as uint, end as uint)
    }

}

#[cfg(test)]
mod tests {

    #[test]
    #[should_fail]
    fn test_compile_nul() {
        // Nul bytes are not allowed in the pattern string.
        ::Pcre::compile("\0abc");
    }

    #[test]
    #[should_fail]
    fn test_compile_bad_pattern() {
        ::Pcre::compile("[");
    }

    #[test]
    fn test_compile_capture_count() {
        let re = ::Pcre::compile("(?:abc)(def)");
        assert_eq!(re.capture_count, 1u);
    }

    #[test]
    fn test_exec_basic() {
        let re = ::Pcre::compile("^...$");
        assert_eq!(re.capture_count, 0u);
        let m = re.exec("abc").unwrap();
        assert_eq!(m.group(0), "abc");
    }

    #[test]
    fn test_exec_no_match() {
        let re = ::Pcre::compile("abc");
        assert!(re.exec("def").is_none());
    }

    #[test]
    fn test_exec_nul_byte() {
        // Nul bytes *are* allowed in subject strings, however.
        let re = ::Pcre::compile("abc\\0def");
        let m = re.exec("abc\0def").unwrap();
        assert_eq!(m.group(0), "abc\0def");
    }

    #[test]
    fn test_exec_from_basic() {
        let re = ::Pcre::compile("abc");
        let subject = "abcabc";
        let m1 = re.exec_from(subject, 1u).unwrap();
        assert_eq!(m1.group_start(0u), 3u);
        assert_eq!(m1.group_end(0u), 6u);
        assert_eq!(m1.group_len(0u), 3u);
        let m2 = re.exec(subject).unwrap();
        assert_eq!(m2.group_start(0u), 0u);
    }
}
<|endoftext|>


<commit_before>//! Implements polynomial operations in GF(2^8).

use std::rand;
use gf256::*;

/// Evaluate a polynomial, returning the Y value for the given X value.
pub fn eval(p: &Vec<u8>, x: u8) -> u8 {
    let mut res: u8 = 0;
    for v in p.iter().rev() {
        res = mul(res, x) ^ *v;
    }
    return res
}

/// Generates a random polynomial of the Nth degree with an X-intercept with the
/// given value.
pub fn generate<T: rand::Rng>(n: u8, x: u8, rng: &mut T) -> Vec<u8> {
    let mut p: Vec<u8> = rng.gen_iter::<u8>().take(n as usize - 2).collect();
    p.push(rng.gen_range(1, 255));
    p.insert(0, x);
    return p;
}

/// Interpolates a vector of (X, Y) points, returning the Y value for the given
/// X value.
pub fn interpolate<'a>(points: &'a Vec<(u8, u8)>, x: u8) -> u8 {
    let mut value: u8 = 0;
    for (i, &(ax, ay)) in points.iter().enumerate() {
        let mut weight: u8 = 1;
        for (j, &(bx, _)) in points.iter().enumerate() {
            if i != j {
                let top = x ^ bx;
                let bottom = ax ^ bx;
                let factor = div(top, bottom);
                weight = mul(weight, factor);
            }
        }
        value ^= mul(weight, ay)
    }
    return value
}

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

    #[test]
    fn test_eval() {
        let p = vec![1, 0, 2, 3];
        assert_eq!(eval(&p, 2), 17);
    }

    #[test]
    fn test_generate() {
        let mut rng = rand::ChaChaRng::new_unseeded();
        assert_eq!(vec![50u8, 118u8, 160u8, 64u8, 84u8], generate(5, 50, &mut rng))
    }

    #[test]
    fn test_interpolate() {
        let y = interpolate(&vec![(1,1), (2,2), (3,3)], 0);
        assert_eq!(y, 0);
    }
}
<commit_msg>Tidy up eval using fold.<commit_after>//! Implements polynomial operations in GF(2^8).

use std::rand;
use gf256::*;

/// Evaluate a polynomial, returning the Y value for the given X value.
pub fn eval(p: &Vec<u8>, x: u8) -> u8 {
    p.iter().rev().fold(0u8, |res, &v| mul(res, x) ^ v)
}

/// Generates a random polynomial of the Nth degree with an X-intercept with the
/// given value.
pub fn generate<T: rand::Rng>(n: u8, x: u8, rng: &mut T) -> Vec<u8> {
    let mut p: Vec<u8> = rng.gen_iter::<u8>().take(n as usize - 2).collect();
    p.push(rng.gen_range(1, 255));
    p.insert(0, x);
    return p;
}

/// Interpolates a vector of (X, Y) points, returning the Y value for the given
/// X value.
pub fn interpolate<'a>(points: &'a Vec<(u8, u8)>, x: u8) -> u8 {
    let mut value: u8 = 0;
    for (i, &(ax, ay)) in points.iter().enumerate() {
        let mut weight: u8 = 1;
        for (j, &(bx, _)) in points.iter().enumerate() {
            if i != j {
                let top = x ^ bx;
                let bottom = ax ^ bx;
                let factor = div(top, bottom);
                weight = mul(weight, factor);
            }
        }
        value ^= mul(weight, ay)
    }
    return value
}

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

    #[test]
    fn test_eval() {
        let p = vec![1, 0, 2, 3];
        assert_eq!(eval(&p, 2), 17);
    }

    #[test]
    fn test_generate() {
        let mut rng = rand::ChaChaRng::new_unseeded();
        assert_eq!(vec![50u8, 118u8, 160u8, 64u8, 84u8], generate(5, 50, &mut rng))
    }

    #[test]
    fn test_interpolate() {
        let y = interpolate(&vec![(1,1), (2,2), (3,3)], 0);
        assert_eq!(y, 0);
    }
}
<|endoftext|>