<commit_before>use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::io::Lines;
use std::collections::HashMap;

use CommandType::{ACommand, CCommand, LCommand};

enum CommandType {
	ACommand,
	CCommand,
	LCommand,
}

struct Parser {
	input_lines: Lines<BufReader<File>>,
	current_command: String,
}

impl Parser {
	/// Opens the input file/stream and gets ready to parse it.
	fn new(filename: &str) -> Parser {
		let path = Path::new(filename);
		let file = match File::open(&path) {
			Err(why) => panic!("couldn't open {}: {}", path.display(), Error::description(&why)),
			Ok(file) => file,
		};

		let lines = BufReader::new(file).lines(); // iterator
		Parser {
			input_lines: lines,
			current_command: String::new(),
		}
	}

	/// Contains the main program logc
	///
	/// TODO Consider moving it to a separte stand alone module.
	///
	///		Are there any more commands in the input?
	///			Reads the next command from the input and makes it the current command
	fn parse(&mut self) {
		loop {
			match self.input_lines.next() {
				Some(line) => {
					let content = line.unwrap().trim().to_string();

					// ignore line comments and empty lines
					if content.starts_with("//") || content == "\n" || content == "" {
						continue
					}

					// remove inline commnents
					let mut content_without_inline = String::new();
					if content.contains("//") {
						let v: Vec<&str> = content.split("//").collect();
						content_without_inline = v[0].trim().to_string();
					}

					// decide whether to use content_with_inline or content
					if content_without_inline != String::new() {
						self.current_command = content_without_inline;
					} else {
						self.current_command = content;
					}

					match self.command_type() {
						ACommand => {
							println!("ACommand: {0}", self.current_command);
							println!("\tsymbol: {0}", self.symbol());
						},
						CCommand => {
							println!("CCommand: {0}", self.current_command);
							println!("\tdest: {0}", self.dest());
							println!("\tcomp: {0}", self.comp());
							println!("\tjump: {0}", self.jump());
						},
						LCommand => {
							println!("LCommand: {0}", self.current_command);
							println!("\tsymbol: {0}", self.symbol());
						},
					}
				},
				None => break,
			}
		}
	}

	/// Returns the type of the current command.
	///
	/// * ACommand: For @xxx where xxx is either a symbol or a decimal number
	/// * CCommand: For dest=comp;jump
	/// * LCommand: Pseudo-Command. For (xxx) where xxx is a symbol
	fn command_type(&self) -> CommandType {
		if self.current_command.starts_with("@") {
			return ACommand
		} else if self.current_command.starts_with("(") {
			return LCommand
		}
		CCommand
	}

	/// Returns the symbol or decimal xxx of the current command @xxx or (xxx).
	///
	/// Should be called only when command_type() is ACommand or LCommand.
	fn symbol(&self) -> String {
		let pattern: &[_] = &['(', ')', '@'];
		self.current_command.trim_matches(pattern).to_string()
	}

	/// Returns the dest mnemonic in the current CCommand. dest=comp;jump
	///
	///(8 posibilities.)
	/// Should only be called when cammand_type() is CCommand.
	fn dest(&self) -> String {
		// dest or jump field may be empy
		// if dest is empty, the '=' is omitted.
		// if jump is empty, the ';' is omitted.
		match self.current_command.contains('=') {
			true => {
				let v: Vec<&str> = self.current_command.split('=').collect();
				return v[0].to_string()
			},
			false => "null".to_string(),
		}
	}

	// /// Returns the comp mnemonic in the current CCommand. dest=comp;jump
	// ///
	// /// 28 possibilities.
	// /// Should only be called when cammand_type() is CCommand.
	fn comp(&self) -> String {
		match self.current_command.contains('=') {
			true => {
				match self.current_command.contains(';') {
					true => { // dest=comp;jump
						let v: Vec<&str> = self.current_command.split(|c: char| c == ';' || c == '=' ).collect();
						v[1].to_string()
					},
					false => { // dest=comp
						let v: Vec<&str> = self.current_command.split('=').collect();
						v[1].to_string()
					}
				}
			},
			false => {
				match self.current_command.contains(';') {
					true => { // comp;jump
						let v: Vec<&str> = self.current_command.split(';').collect();
						v[0].to_string()
					},
					false => { // comp
						self.current_command.clone()
					},
				}
			}
		}
	}

	/// Returns the jump mnemonic in the current CCommand. dest=com;jump
	///
	/// 8-possibilities.
	/// Should only be called when cammand_type() is CCommand.
	fn jump(&self) -> String {
		match self.current_command.contains(';') {
			true => {
				let v: Vec<&str> = self.current_command.split(';').collect();
				return v[1].to_string()
			},
			false => "null".to_string(),
		}
	}
}

/// Translate Hack assembly language mnemonic into binary codes
struct Code;

impl Code {
	fn new() -> Code {
		Code
	}

	/// Returns the binary code of the dest mnemonic
	///
	/// returns 3 bits
	fn dest(mnemonic: &str) -> u8 {
		match mnemonic {
			"null" 	=> 0x00,
			"M"		=> 0x01,
			"D"		=> 0x02,
			"MD"	=> 0x03,
			"A"		=> 0x04,
			"AM"	=> 0x05,
			"AD"	=> 0x06,
			"AMD"	=> 0x07,
			_		=> 0x08,
		}
	}

	/// Returns the binary code of the comp mnemonic
	///
	/// returns 7 bits
	// fn comp(mnemonic: &str) -> u8 {

	// }

	/// Returns the binary code of the jump mnemonic
	///
	/// returns 3 bits
	fn jump(mnemonic: &str) -> u16 {
		match mnemonic {
			"null" 	=> 0x00,
			"JGT"	=> 0x01,
			"JEQ"	=> 0x02,
			"JGE"	=> 0x03,
			"JLT"	=> 0x04,
			"JNE"	=> 0x05,
			"JLE"	=> 0x06,
			"JMP"	=> 0x07,
			_		=> 0x08,
		}
	}
}

/// Change the bits at indexes in index to values in dest
///
/// Takes a hashmap such as bit_index -> bit_value
fn set_bits(mut word:i16, index_bitvalue: HashMap<i16, i16>) -> i16 {
	for index in index_bitvalue.keys() {
		let bit_value: i16 = match index_bitvalue.get(index) {
			Some(value) => value.clone(),
			None => 0,
		};
		word ^= (-bit_value ^ word) & (1i16 << index);
	}
	word
}

/// CInstruction bitfield
struct CInstruction {
	a: u8,
	c1: u8,
	c2: u8,
	c3: u8,
	c4: u8,
	c5: u8,
	c6: u8,
	d1: u8,
	d2: u8,
	d3: u8,
	j1: u8,
	j2: u8,
	j3: u8,
}

impl CInstruction {
	fn new() -> CInstruction {
		CInstruction {
			a: 0,
			c1: 0,
			c2: 0,
			c3: 0,
			c4: 0,
			c5: 0,
			c6: 0,
			d1: 0,
			d2: 0,
			d3: 0,
			j1: 0,
			j2: 0,
			j3: 0,
		}
	}
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 2 {
		println!("HACK Assembler. Translates assembly (mnemonic) into binary
			machine code.\n\nUsage:\n\tassembler [PATH_TO_ASM_FILE]");
		return;
	}
	let path_to_asm = &args[1];
	let mut parser = Parser::new(path_to_asm);
	parser.parse();
}
<commit_msg>Check point<commit_after>use std::path::Path;
use std::fs::File;
use std::error::Error;
use std::env;
use std::io::BufReader;
use std::io::BufRead;
use std::io::Lines;
use std::collections::HashMap;

use CommandType::{ACommand, CCommand, LCommand};

enum CommandType {
	ACommand,
	CCommand,
	LCommand,
}

struct Parser {
	input_lines: Lines<BufReader<File>>,
	current_command: String,
}

impl Parser {
	/// Opens the input file/stream and gets ready to parse it.
	fn new(filename: &str) -> Parser {
		let path = Path::new(filename);
		let file = match File::open(&path) {
			Err(why) => panic!("couldn't open {}: {}", path.display(), Error::description(&why)),
			Ok(file) => file,
		};

		let lines = BufReader::new(file).lines(); // iterator
		Parser {
			input_lines: lines,
			current_command: String::new(),
		}
	}

	/// Contains the main program logc
	///
	/// TODO Consider moving it to a separte stand alone module.
	///
	///		Are there any more commands in the input?
	///			Reads the next command from the input and makes it the current command
	fn parse(&mut self) {
		loop {
			match self.input_lines.next() {
				Some(line) => {
					let content = line.unwrap().trim().to_string();

					// ignore line comments and empty lines
					if content.starts_with("//") || content == "\n" || content == "" {
						continue
					}

					// remove inline commnents
					let mut content_without_inline = String::new();
					if content.contains("//") {
						let v: Vec<&str> = content.split("//").collect();
						content_without_inline = v[0].trim().to_string();
					}

					// decide whether to use content_with_inline or content
					if content_without_inline != String::new() {
						self.current_command = content_without_inline;
					} else {
						self.current_command = content;
					}

					match self.command_type() {
						ACommand => {
							println!("ACommand: {0}", self.current_command);
							println!("\tsymbol: {0}", self.symbol());
						},
						CCommand => {
							println!("CCommand: {0}", self.current_command);
							println!("\tdest: {0}", self.dest());
							println!("\tcomp: {0}", self.comp());
							println!("\tjump: {0}", self.jump());
						},
						LCommand => {
							println!("LCommand: {0}", self.current_command);
							println!("\tsymbol: {0}", self.symbol());
						},
					}
				},
				None => break,
			}
		}
	}

	/// Returns the type of the current command.
	///
	/// * ACommand: For @xxx where xxx is either a symbol or a decimal number
	/// * CCommand: For dest=comp;jump
	/// * LCommand: Pseudo-Command. For (xxx) where xxx is a symbol
	fn command_type(&self) -> CommandType {
		if self.current_command.starts_with("@") {
			return ACommand
		} else if self.current_command.starts_with("(") {
			return LCommand
		}
		CCommand
	}

	/// Returns the symbol or decimal xxx of the current command @xxx or (xxx).
	///
	/// Should be called only when command_type() is ACommand or LCommand.
	fn symbol(&self) -> String {
		let pattern: &[_] = &['(', ')', '@'];
		self.current_command.trim_matches(pattern).to_string()
	}

	/// Returns the dest mnemonic in the current CCommand. dest=comp;jump
	///
	///(8 posibilities.)
	/// Should only be called when cammand_type() is CCommand.
	fn dest(&self) -> String {
		// dest or jump field may be empy
		// if dest is empty, the '=' is omitted.
		// if jump is empty, the ';' is omitted.
		match self.current_command.contains('=') {
			true => {
				let v: Vec<&str> = self.current_command.split('=').collect();
				return v[0].to_string()
			},
			false => "null".to_string(),
		}
	}

	// /// Returns the comp mnemonic in the current CCommand. dest=comp;jump
	// ///
	// /// 28 possibilities.
	// /// Should only be called when cammand_type() is CCommand.
	fn comp(&self) -> String {
		match self.current_command.contains('=') {
			true => {
				match self.current_command.contains(';') {
					true => { // dest=comp;jump
						let v: Vec<&str> = self.current_command.split(|c: char| c == ';' || c == '=' ).collect();
						v[1].to_string()
					},
					false => { // dest=comp
						let v: Vec<&str> = self.current_command.split('=').collect();
						v[1].to_string()
					}
				}
			},
			false => {
				match self.current_command.contains(';') {
					true => { // comp;jump
						let v: Vec<&str> = self.current_command.split(';').collect();
						v[0].to_string()
					},
					false => { // comp
						self.current_command.clone()
					},
				}
			}
		}
	}

	/// Returns the jump mnemonic in the current CCommand. dest=com;jump
	///
	/// 8-possibilities.
	/// Should only be called when cammand_type() is CCommand.
	fn jump(&self) -> String {
		match self.current_command.contains(';') {
			true => {
				let v: Vec<&str> = self.current_command.split(';').collect();
				return v[1].to_string()
			},
			false => "null".to_string(),
		}
	}
}

/// Translate Hack assembly language mnemonic into binary codes
struct Code;

impl Code {
	fn new() -> Code {
		Code
	}

	/// Returns the binary code of the dest mnemonic
	///
	/// returns 3 bits
	fn dest(mnemonic: &str) -> u8 {
		match mnemonic {
			"null" 	=> 0x00,
			"M"		=> 0x01,
			"D"		=> 0x02,
			"MD"	=> 0x03,
			"A"		=> 0x04,
			"AM"	=> 0x05,
			"AD"	=> 0x06,
			"AMD"	=> 0x07,
			_		=> 0x08,
		}
	}

	/// Returns the binary code of the comp mnemonic
	///
	/// returns 7 bits
	// fn comp(mnemonic: &str) -> u8 {

	// }

	/// Returns the binary code of the jump mnemonic
	///
	/// returns 3 bits
	fn jump(mnemonic: &str) -> CInstruction {
		let mut c_instr = CInstruction::new();
		match mnemonic {
			"null" 	=> ,
			"JGT"	=> {
				c_instr.j3 = 1;
			},
			"JEQ"	=> {
				c_instr.j2 = 1;
			},
			"JGE"	=> {
				c_instr.j3 = 1;
				c_instr.j2 = 1;
			},
			"JLT"	=> {
				c_instr.j1 = 1;
			},
			"JNE"	=> {
				c_instr.j1 = 1;
				c_instr.j3 = 1;
			},
			"JLE"	=> {
				c_instr.j1 = 1;
				c_instr.j2 = 1;
			},
			"JMP"	=> {
				c_instr.j1 = 1;
				c_instr.j2 = 1;
				c_instr.j3 = 1;
			},
			_		=> ,
		}
		c_instr
	}
}

/// Change the bits at indexes in index to values in dest
///
/// Takes a hashmap such as bit_index -> bit_value
fn set_bits(mut word:i16, index_bitvalue: HashMap<i16, i16>) -> i16 {
	for index in index_bitvalue.keys() {
		let bit_value: i16 = match index_bitvalue.get(index) {
			Some(value) => value.clone(),
			None => 0,
		};
		word ^= (-bit_value ^ word) & (1i16 << index);
	}
	word
}

/// CInstruction bitfield
struct CInstruction {
	a: u8,
	c1: u8,
	c2: u8,
	c3: u8,
	c4: u8,
	c5: u8,
	c6: u8,
	d1: u8,
	d2: u8,
	d3: u8,
	j1: u8,
	j2: u8,
	j3: u8,
}

impl CInstruction {
	fn new() -> CInstruction {
		CInstruction {
			a: 0,
			c1: 0,
			c2: 0,
			c3: 0,
			c4: 0,
			c5: 0,
			c6: 0,
			d1: 0,
			d2: 0,
			d3: 0,
			j1: 0,
			j2: 0,
			j3: 0,
		}
	}
}

fn main() {
	let args: Vec<String> = env::args().collect();
	if args.len() != 2 {
		println!("HACK Assembler. Translates assembly (mnemonic) into binary
			machine code.\n\nUsage:\n\tassembler [PATH_TO_ASM_FILE]");
		return;
	}
	let path_to_asm = &args[1];
	let mut parser = Parser::new(path_to_asm);
	parser.parse();
}
<|endoftext|>


<commit_before>extern crate ramp;
extern crate bufstream;
extern crate regex;

use std::sync::mpsc::channel;
use std::thread;
use std::sync::{RwLock, Arc};
use std::net::{TcpListener, TcpStream};
use std::io::{Read, BufRead, Write};
use regex::Regex;

#[macro_use]
extern crate log;
extern crate env_logger;

use bufstream::BufStream;

use ramp::Database;

type DB = Arc<RwLock<Database>>;

//
// impl RampServer {
//     fn new() -> RampServer {
//         // create a new Database, wrap in RwLock and Arc
//         let db = RwLock::new(Database::new());
//         RampServer{db:db}
//     }
// }
//
// impl ramp_interface::Server for RampServer {
//     fn prepare(&mut self, mut context: ramp_interface::PrepareContext) {
//         println!("Preparing");
//         {
//             let (params, mut results) = context.get();
//             let key = params.get_key().unwrap();
//             let value = params.get_value().unwrap();
//
//             let deps = {
//                 let target = params.get_dependencies().unwrap();
//                 let size = target.len();
//                 let mut entries = Vec::with_capacity(size as usize);
//                 for i in 0..size {
//                     entries.push(target.get(i).unwrap().to_string());
//                 }
//                 entries
//             };
//
//             // let deps = params.get_dependencies().unwrap();
//             let timestamp = params.get_timestamp();
//
//             println!("Acquiring write lock");
//             let mut db = self.db.write().unwrap(); // hold lock till prepare is done
//             db.prepare(key.to_string(), value.to_string(), deps, timestamp);
//         }
//
//         context.done();
//         println!("Prepared");
//     }
//
//     fn commit(&mut self, mut context: ramp_interface::CommitContext) {
//         println!("Committing");
//         {
//             let (params, mut results) = context.get();
//             let ts = params.get_timestamp();
//
//             println!("Acquiring write lock");
//             let mut db = self.db.write().unwrap();
//             println!("Write lock acquired");
//             db.commit(ts);
//
//         }
//
//         context.done();
//     }
//
//     fn get(&mut self, mut context: ramp_interface::GetContext) {
//         {
//             let (params, mut results) = context.get();
//             let key = params.get_key().unwrap();
//
//             let mut db = self.db.write().unwrap();
//             let version = db.get(key.to_string());
//
//             match version {
//                 Some(v) => {
//                     println!("Found version {} {}", v.timestamp, &v.value);
//                     let mut r = results.init_result();
//                     let mut ver = r.init_version();
//                     ver.set_value(&v.value);
//                     ver.set_timestamp(v.timestamp);
//
//                     let len = v.dependencies.len() as u32;
//                     let mut deps = ver.init_dependencies(len);
//
//                     println!("{} dependencies: {:?}", len, v.dependencies);
//                     for i in 0..len {
//                         println!("Setting dependency {}",i);
//                         deps.set(i as u32, &v.dependencies.get(i as usize).unwrap());
//                     }
//                     println!("Deps set for get return");
//                 },
//                 None => {
//                     let mut r = results.init_result();
//                     r.set_none(());
//                 }
//             };
//
//         }
//         context.done();
//     }
//
//     fn get_version(&mut self, mut context: ramp_interface::GetVersionContext) {
//         {
//             println!("Getting specific version");
//             let (params, mut results) = context.get();
//             let key = params.get_key().unwrap();
//             let timestamp = params.get_timestamp();
//
//             let mut db = self.db.write().unwrap();
//             let version = db.get_version(key.to_string(), timestamp);
//
//             match version {
//                 Some(v) => {
//                     let mut r = results.init_result();
//                     let mut ver = r.init_version();
//                     ver.set_value(&v.value);
//                     ver.set_timestamp(v.timestamp);
//
//                     let len = v.dependencies.len() as u32;
//                     let mut deps = ver.init_dependencies(len);
//                     for i in 0..len {
//                         deps.set(i as u32, &v.dependencies.get(i as usize).unwrap());
//                     }
//                 },
//                 None => {
//                     // let mut r = results.init_result();
//                     // r.set_none(());
//                 }
//             };
//         }
//
//         context.done();
//     }
// }

fn main() {
    /*
    Logger notes:
    RUST_LOG=error ./main
    RUST_LOG=info
    http://rust-lang.github.io/log/env_logger/
    */

    info!("Starting up RAMP socket server!");
    let db = Arc::new(RwLock::new(Database::new()));
    let listener = TcpListener::bind("127.0.0.1:6000").unwrap();

    info!("Socket bound");

    for stream in listener.incoming() {
        // info!("connection established, spawning new thread");
        let db2 = db.clone();
        match stream {
            Ok(stream) => {
                thread::spawn(move || {
                    handle_client(stream, db2)
                    });
            },
            Err(e) => {}
        }
    }

    info!("Goodbye forever.");
}

fn handle_client(mut stream: TcpStream, mut db: DB ) {
    info!("Starting new client thread, creating regexes");

    let prepare = Regex::new(r"prepare\s+([:alpha:]+)\s+([:alpha:]+)\s+(\d+)\s?([a-z,]*)").unwrap();

    let mut buf = BufStream::new(stream.try_clone().unwrap());

    let mut buffer = String::new();
    for line in buf.lines() {
        let l = line.unwrap();
        println!("Line: {}", l);

        if prepare.is_match(&l) {
            println!("prepare statement");
            let cap = prepare.captures(&l).unwrap();
            let key = cap.at(1).unwrap();
            let value = cap.at(2).unwrap();
            let timestamp = cap.at(3).unwrap().parse::<i64>().unwrap();

            println!("Key, value, timestamp, deps: {} : {} : {} : {}",
                     key, value, timestamp, cap.at(4).unwrap());

            let deps : Vec<String> = cap.at(4).unwrap()
                                    .split(",").map(|x| x.to_string())
                                    .collect();

            println!("depencencies: {:?}", deps );

            {
                let mut writer = (*db).write().unwrap();
                writer.prepare(key.to_string(),
                           value.to_string(),
                           deps,
                           timestamp);
            }
            stream.write("PREPARED\n".as_bytes());
            continue;
        }
    }
}
<commit_msg>commit code works<commit_after>extern crate ramp;
extern crate bufstream;
extern crate regex;

use std::sync::mpsc::channel;
use std::thread;
use std::sync::{RwLock, Arc};
use std::net::{TcpListener, TcpStream};
use std::io::{Read, BufRead, Write};
use regex::Regex;

#[macro_use]
extern crate log;
extern crate env_logger;

use bufstream::BufStream;

use ramp::Database;

type DB = Arc<RwLock<Database>>;

fn main() {
    /*
    Logger notes:
    RUST_LOG=error ./main
    RUST_LOG=info
    http://rust-lang.github.io/log/env_logger/
    */

    info!("Starting up RAMP socket server!");
    let db = Arc::new(RwLock::new(Database::new()));
    let listener = TcpListener::bind("127.0.0.1:6000").unwrap();

    info!("Socket bound");

    for stream in listener.incoming() {
        // info!("connection established, spawning new thread");
        let db2 = db.clone();
        match stream {
            Ok(stream) => {
                thread::spawn(move || {
                    handle_client(stream, db2)
                    });
            },
            Err(e) => {}
        }
    }

    info!("Goodbye forever.");
}

fn handle_client(mut stream: TcpStream, mut db: DB ) {
    info!("Starting new client thread, creating regexes");

    let prepare = Regex::new(r"prepare\s+([:alpha:]+)\s+([:alpha:]+)\s+(\d+)\s?([a-z,]*)").unwrap();
    let commit = Regex::new(r"commit (\d+)").unwrap();

    let mut buf = BufStream::new(stream.try_clone().unwrap());

    let mut buffer = String::new();
    for line in buf.lines() {
        let l = line.unwrap();
        println!("Line: {}", l);

        if prepare.is_match(&l) {
            println!("prepare statement");
            let cap = prepare.captures(&l).unwrap();
            let key = cap.at(1).unwrap();
            let value = cap.at(2).unwrap();
            let timestamp = cap.at(3).unwrap().parse::<i64>().unwrap();

            println!("Key, value, timestamp, deps: {} : {} : {} : {}",
                     key, value, timestamp, cap.at(4).unwrap());

            let deps : Vec<String> = cap.at(4).unwrap()
                                    .split(",").map(|x| x.to_string())
                                    .collect();

            println!("depencencies: {:?}", deps );

            {
                let mut writer = (*db).write().unwrap();
                writer.prepare(key.to_string(),
                           value.to_string(),
                           deps,
                           timestamp);
            }
            stream.write("PREPARED\n".as_bytes());
            continue;
        } else if commit.is_match(&l) {
            let cap = commit.captures(&l).unwrap();
            let timestamp = cap.at(1).unwrap().parse::<i64>().unwrap();
            {
                let mut writer = (*db).write().unwrap();
                writer.commit(timestamp);
            }
            stream.write("COMMITTED\n".as_bytes());
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate serde;
#[macro_use] extern crate serde_json;
#[macro_use] extern crate glob;
#[macro_use] extern crate uuid;
#[macro_use] extern crate regex;
#[macro_use] extern crate prettytable;
extern crate url;
extern crate config;

use std::process::exit;

use cli::CliConfig;
use configuration::Configuration;
use runtime::{ImagLogger, Runtime};
use clap::App;
use module::Module;

mod cli;
mod configuration;
mod runtime;
mod module;
mod storage;
mod ui;
mod util;

use module::bm::BM;

fn main() {
    let yaml = load_yaml!("../etc/cli.yml");
    let app = App::from_yaml(yaml);
    let config = CliConfig::new(app);
    let configuration = Configuration::new(&config);

    let logger = ImagLogger::init(&configuration, &config);
    debug!("Logger created!");

    debug!("CliConfig    : {:?}", &config);
    debug!("Configuration: {:?}", &configuration);

    let rt = Runtime::new(configuration, config);

    debug!("Runtime      : {:?}", &rt);

    if let Some(matches) = rt.config.cli_matches.subcommand_matches("bm") {
        let res = BM::new(&rt).exec(matches);
        info!("BM exited with {}", res);
    } else {
        info!("No commandline call...")
    }

    info!("Hello, world!");
}
<commit_msg>Use modules publicly, so "cargo doc" generates documentation<commit_after>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
#[macro_use] extern crate serde;
#[macro_use] extern crate serde_json;
#[macro_use] extern crate glob;
#[macro_use] extern crate uuid;
#[macro_use] extern crate regex;
#[macro_use] extern crate prettytable;
extern crate url;
extern crate config;

use std::process::exit;

pub use cli::CliConfig;
pub use configuration::Configuration;
pub use runtime::{ImagLogger, Runtime};
pub use clap::App;
pub use module::Module;

pub mod cli;
pub mod configuration;
pub mod runtime;
pub mod module;
pub mod storage;
pub mod ui;
pub mod util;

pub use module::bm::BM;

fn main() {
    let yaml = load_yaml!("../etc/cli.yml");
    let app = App::from_yaml(yaml);
    let config = CliConfig::new(app);
    let configuration = Configuration::new(&config);

    let logger = ImagLogger::init(&configuration, &config);
    debug!("Logger created!");

    debug!("CliConfig    : {:?}", &config);
    debug!("Configuration: {:?}", &configuration);

    let rt = Runtime::new(configuration, config);

    debug!("Runtime      : {:?}", &rt);

    if let Some(matches) = rt.config.cli_matches.subcommand_matches("bm") {
        let res = BM::new(&rt).exec(matches);
        info!("BM exited with {}", res);
    } else {
        info!("No commandline call...")
    }

    info!("Hello, world!");
}
<|endoftext|>


<commit_before>// TODO: many items from tokio-core::io have been deprecated in favour of tokio-io
#![allow(deprecated)]

#[macro_use] extern crate log;
#[cfg(debug_assertions)]
extern crate env_logger;
extern crate futures;
extern crate getopts;
extern crate librespot;
extern crate tokio_core;
extern crate tokio_signal;

#[cfg(debug_assertions)]
use env_logger::LogBuilder;
use futures::{Future, Async, Poll, Stream};
#[cfg(debug_assertions)]
use std::env;
use std::io::{self, stderr, Write};
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
use tokio_core::reactor::{Handle, Core};
use tokio_core::io::IoStream;
use std::mem;

use librespot::spirc::{Spirc, SpircTask};
use librespot::authentication::{get_credentials, Credentials};
use librespot::authentication::discovery::{discovery, DiscoveryStream};
use librespot::audio_backend;
use librespot::cache::Cache;
use librespot::player::Player;
use librespot::session::{Bitrate, Config, Session};
use librespot::mixer::{self, Mixer};
use librespot::util::SpotifyId;

use librespot::version;

fn usage(program: &str, opts: &getopts::Options) -> String {
    let brief = format!("Usage: {} [options]", program);
    opts.usage(&brief)
}

#[cfg(debug_assertions)]
fn setup_logging(verbose: bool) {
    let mut builder = LogBuilder::new();
    match env::var("RUST_LOG") {
        Ok(config) => {
            builder.parse(&config);
            builder.init().unwrap();

            if verbose {
                warn!("`--verbose` flag overidden by `RUST_LOG` environment variable");
            }
        }
        Err(_) => {
            if verbose {
                builder.parse("mdns=info,librespot=trace");
            } else {
                builder.parse("mdns=error,librespot=warn");
            }
            builder.init().unwrap();
        }
    }
}

#[derive(Clone)]
struct Setup {
    mixer: fn() -> Box<Mixer>,

	name: String,
    cache: Option<Cache>,
    config: Config,
    credentials: Option<Credentials>,
    enable_discovery: bool,

    single_track: Option<String>,
    start_position: u32,
}

fn setup(args: &[String]) -> Setup {
    let mut opts = getopts::Options::new();
    opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
        .reqopt("n", "name", "Device name", "NAME")
        .optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE")
        .optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM")
        .optopt("", "onstop", "Run PROGRAM when playback has ended.", "PROGRAM")
        .optopt("", "single-track", "Play a single track ID and exit.", "ID")
        .optopt("", "start-position", "Position (in ms) where playback should be started. Only valid with the --single-track option.", "STARTPOSITION")
        .optopt("u", "username", "Username to sign in with", "USERNAME")
        .optopt("p", "password", "Password", "PASSWORD")
        .optflag("", "disable-discovery", "Disable discovery mode")
        .optopt("", "mixer", "Mixer to use", "MIXER");

	#[cfg(debug_assertions)]
    opts.optflag("v", "verbose", "Enable verbose output");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            writeln!(stderr(), "error: {}\n{}", f.to_string(), usage(&args[0], &opts)).unwrap();
            exit(1);
        }
    };

	#[cfg(debug_assertions)]
	{
	    let verbose = matches.opt_present("verbose");
	    setup_logging(verbose);
	}

    info!("librespot {} ({}). Built on {}.",
             version::short_sha(),
             version::commit_date(),
             version::short_now());

    let mixer_name = matches.opt_str("mixer");
    let mixer = mixer::find(mixer_name.as_ref())
        .expect("Invalid mixer");

    let bitrate = matches.opt_str("b").as_ref()
        .map(|bitrate| Bitrate::from_str(bitrate).expect("Invalid bitrate"))
        .unwrap_or(Bitrate::Bitrate160);

    let name = matches.opt_str("name").unwrap();
    let device_id = librespot::session::device_id(&name);

    let cache = matches.opt_str("c").map(|cache_location| {
        Cache::new(PathBuf::from(cache_location))
    });

    let cached_credentials = cache.as_ref().and_then(Cache::credentials);

    let credentials = get_credentials(matches.opt_str("username"),
                                      matches.opt_str("password"),
                                      cached_credentials);

    let enable_discovery = !matches.opt_present("disable-discovery");

    let start_position = matches.opt_str("start-position")
    	.unwrap_or("0".to_string())
    	.parse().unwrap_or(0);

    let config = Config {
        user_agent: version::version_string(),
        device_id: device_id,
        bitrate: bitrate,
        onstart: matches.opt_str("onstart"),
        onstop: matches.opt_str("onstop"),
    };

    Setup {
		name: name,
        cache: cache,
        config: config,
        credentials: credentials,
        enable_discovery: enable_discovery,
        mixer: mixer,

        single_track: matches.opt_str("single-track"),
        start_position: start_position * 1000,
    }
}

struct Main {
	name: String,
    cache: Option<Cache>,
    config: Config,
    mixer: fn() -> Box<Mixer>,
    handle: Handle,

    discovery: Option<DiscoveryStream>,
    signal: IoStream<()>,

    spirc: Option<Spirc>,
    spirc_task: Option<SpircTask>,
    connect: Box<Future<Item=Session, Error=io::Error>>,

    player: Option<Player>,

    shutdown: bool,
}

impl Main {
    fn new(handle: Handle,
           name: String,
           config: Config,
           cache: Option<Cache>,
           mixer: fn() -> Box<Mixer>,
    ) -> Main
    {
        Main {
            handle: handle.clone(),
            name: name,
            cache: cache,
            config: config,
            mixer: mixer,

            connect: Box::new(futures::future::empty()),
            discovery: None,
            spirc: None,
            spirc_task: None,

            player: None,

            shutdown: false,
            signal: tokio_signal::ctrl_c(&handle).flatten_stream().boxed(),
        }
    }

    fn discovery(&mut self) {
        let device_id = self.config.device_id.clone();
        let name = self.name.clone();

        self.discovery = Some(discovery(&self.handle, name, device_id).unwrap());
    }

    fn credentials(&mut self, credentials: Credentials) {
        let config = self.config.clone();
        let handle = self.handle.clone();

        let connection = Session::connect(config, credentials, self.cache.clone(), handle);

        self.connect = connection;
        self.spirc = None;
        let task = mem::replace(&mut self.spirc_task, None);
        if let Some(task) = task {
            self.handle.spawn(task);
        }
    }
}

impl Future for Main {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        loop {
            let mut progress = false;

            if let Some(Async::Ready(Some(creds))) = self.discovery.as_mut().map(|d| d.poll().unwrap()) {
                if let Some(ref spirc) = self.spirc {
                    spirc.shutdown();
                }
                self.credentials(creds);

                progress = true;
            }

            if let Async::Ready(session) = self.connect.poll().unwrap() {
                self.connect = Box::new(futures::future::empty());
                let mixer = (self.mixer)();

                let audio_filter = mixer.get_audio_filter();
				let backend = audio_backend::find(None).unwrap();
                let player = Player::new(session.clone(), audio_filter, move || {
                    (backend)(None)
                });

                self.player = Some(player.clone());

                let (spirc, spirc_task) = Spirc::new(self.name.clone(), session, player, mixer);
                self.spirc = Some(spirc);
                self.spirc_task = Some(spirc_task);

                progress = true;
            }

            if let Async::Ready(Some(())) = self.signal.poll().unwrap() {
                if !self.shutdown {
                    if let Some(ref spirc) = self.spirc {
                        spirc.shutdown();
                    }
                    self.shutdown = true;
                } else {
                    return Ok(Async::Ready(()));
                }

                progress = true;
            }

            if let Some(ref mut spirc_task) = self.spirc_task {
                if let Async::Ready(()) = spirc_task.poll().unwrap() {
                    if self.shutdown {
                        return Ok(Async::Ready(()));
                    } else {
                        panic!("Spirc shut down unexpectedly");
                    }
                }
            }

            if !progress {
                return Ok(Async::NotReady);
            }
        }
    }
}

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let args: Vec<String> = std::env::args().collect();
    let Setup { name, config, cache, enable_discovery, credentials, mixer, single_track, start_position } = setup(&args);

	if let Some(ref track_id) = single_track {
		match credentials {
			Some(credentials) => {
				let backend = audio_backend::find(None).unwrap();

				let track = SpotifyId::from_base62(
									track_id.replace("spotty://", "")
									.replace("spotify://", "")
									.replace("track:", "")
									.as_str());

				let session = core.run(Session::connect(config, credentials, None, handle)).unwrap();

				let player = Player::new(session.clone(), None, move || (backend)(None));

				core.run(player.load(track, true, start_position)).unwrap();
			}
			None => {
				println!("Missing credentials");
			}
	    }
	}
	else {
		let mut task = Main::new(handle, name, config, cache, mixer);
		if enable_discovery {
			task.discovery();
		}
		if let Some(credentials) = credentials {
			task.credentials(credentials);
		}

		core.run(task).unwrap()
    }
}

<commit_msg>Add option to authenticate given username/password and store credentials in cache<commit_after>// TODO: many items from tokio-core::io have been deprecated in favour of tokio-io
#![allow(deprecated)]

#[macro_use] extern crate log;
#[cfg(debug_assertions)]
extern crate env_logger;
extern crate futures;
extern crate getopts;
extern crate librespot;
extern crate tokio_core;
extern crate tokio_signal;

#[cfg(debug_assertions)]
use env_logger::LogBuilder;
use futures::{Future, Async, Poll, Stream};
#[cfg(debug_assertions)]
use std::env;
use std::io::{self, stderr, Write};
use std::path::PathBuf;
use std::process::exit;
use std::str::FromStr;
use tokio_core::reactor::{Handle, Core};
use tokio_core::io::IoStream;
use std::mem;

use librespot::spirc::{Spirc, SpircTask};
use librespot::authentication::{get_credentials, Credentials};
use librespot::authentication::discovery::{discovery, DiscoveryStream};
use librespot::audio_backend;
use librespot::cache::Cache;
use librespot::player::Player;
use librespot::session::{Bitrate, Config, Session};
use librespot::mixer::{self, Mixer};
use librespot::util::SpotifyId;

use librespot::version;

fn usage(program: &str, opts: &getopts::Options) -> String {
    let brief = format!("Usage: {} [options]", program);
    opts.usage(&brief)
}

#[cfg(debug_assertions)]
fn setup_logging(verbose: bool) {
    let mut builder = LogBuilder::new();
    match env::var("RUST_LOG") {
        Ok(config) => {
            builder.parse(&config);
            builder.init().unwrap();

            if verbose {
                warn!("`--verbose` flag overidden by `RUST_LOG` environment variable");
            }
        }
        Err(_) => {
            if verbose {
                builder.parse("mdns=info,librespot=trace");
            } else {
                builder.parse("mdns=error,librespot=warn");
            }
            builder.init().unwrap();
        }
    }
}

#[derive(Clone)]
struct Setup {
    mixer: fn() -> Box<Mixer>,

	name: String,
    cache: Option<Cache>,
    config: Config,
    credentials: Option<Credentials>,
    authenticate: bool,
    enable_discovery: bool,

    single_track: Option<String>,
    start_position: u32,
}

fn setup(args: &[String]) -> Setup {
    let mut opts = getopts::Options::new();
    opts.optopt("c", "cache", "Path to a directory where files will be cached.", "CACHE")
        .reqopt("n", "name", "Device name", "NAME")
        .optopt("b", "bitrate", "Bitrate (96, 160 or 320). Defaults to 160", "BITRATE")
        .optopt("", "onstart", "Run PROGRAM when playback is about to begin.", "PROGRAM")
        .optopt("", "onstop", "Run PROGRAM when playback has ended.", "PROGRAM")
        .optopt("", "single-track", "Play a single track ID and exit.", "ID")
        .optopt("", "start-position", "Position (in ms) where playback should be started. Only valid with the --single-track option.", "STARTPOSITION")
        .optopt("u", "username", "Username to sign in with", "USERNAME")
        .optopt("p", "password", "Password", "PASSWORD")
        .optflag("a", "authenticate", "Authenticate given username and password. Make sure you define a cache folder to store credentials.")
        .optflag("", "disable-discovery", "Disable discovery mode")
        .optopt("", "mixer", "Mixer to use", "MIXER");

	#[cfg(debug_assertions)]
    opts.optflag("v", "verbose", "Enable verbose output");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => {
            writeln!(stderr(), "error: {}\n{}", f.to_string(), usage(&args[0], &opts)).unwrap();
            exit(1);
        }
    };

	#[cfg(debug_assertions)]
	{
	    let verbose = matches.opt_present("verbose");
	    setup_logging(verbose);
	}

    info!("librespot {} ({}). Built on {}.",
             version::short_sha(),
             version::commit_date(),
             version::short_now());

    let mixer_name = matches.opt_str("mixer");
    let mixer = mixer::find(mixer_name.as_ref())
        .expect("Invalid mixer");

    let bitrate = matches.opt_str("b").as_ref()
        .map(|bitrate| Bitrate::from_str(bitrate).expect("Invalid bitrate"))
        .unwrap_or(Bitrate::Bitrate160);

    let name = matches.opt_str("name").unwrap();
    let device_id = librespot::session::device_id(&name);

    let cache = matches.opt_str("c").map(|cache_location| {
        Cache::new(PathBuf::from(cache_location))
    });

    let cached_credentials = cache.as_ref().and_then(Cache::credentials);

    let credentials = get_credentials(matches.opt_str("username"),
                                      matches.opt_str("password"),
                                      cached_credentials);

    let authenticate = matches.opt_present("authenticate");

    let enable_discovery = !matches.opt_present("disable-discovery");

    let start_position = matches.opt_str("start-position")
    	.unwrap_or("0".to_string())
    	.parse().unwrap_or(0);

    let config = Config {
        user_agent: version::version_string(),
        device_id: device_id,
        bitrate: bitrate,
        onstart: matches.opt_str("onstart"),
        onstop: matches.opt_str("onstop"),
    };

    Setup {
		name: name,
        cache: cache,
        config: config,
        credentials: credentials,
        authenticate: authenticate,
        enable_discovery: enable_discovery,
        mixer: mixer,

        single_track: matches.opt_str("single-track"),
        start_position: start_position * 1000,
    }
}

struct Main {
	name: String,
    cache: Option<Cache>,
    config: Config,
    mixer: fn() -> Box<Mixer>,
    handle: Handle,

    discovery: Option<DiscoveryStream>,
    signal: IoStream<()>,

    spirc: Option<Spirc>,
    spirc_task: Option<SpircTask>,
    connect: Box<Future<Item=Session, Error=io::Error>>,

    player: Option<Player>,

    shutdown: bool,
}

impl Main {
    fn new(handle: Handle,
           name: String,
           config: Config,
           cache: Option<Cache>,
           mixer: fn() -> Box<Mixer>,
    ) -> Main
    {
        Main {
            handle: handle.clone(),
            name: name,
            cache: cache,
            config: config,
            mixer: mixer,

            connect: Box::new(futures::future::empty()),
            discovery: None,
            spirc: None,
            spirc_task: None,

            player: None,

            shutdown: false,
            signal: tokio_signal::ctrl_c(&handle).flatten_stream().boxed(),
        }
    }

    fn discovery(&mut self) {
        let device_id = self.config.device_id.clone();
        let name = self.name.clone();

        self.discovery = Some(discovery(&self.handle, name, device_id).unwrap());
    }

    fn credentials(&mut self, credentials: Credentials) {
        let config = self.config.clone();
        let handle = self.handle.clone();

        let connection = Session::connect(config, credentials, self.cache.clone(), handle);

        self.connect = connection;
        self.spirc = None;
        let task = mem::replace(&mut self.spirc_task, None);
        if let Some(task) = task {
            self.handle.spawn(task);
        }
    }
}

impl Future for Main {
    type Item = ();
    type Error = ();

    fn poll(&mut self) -> Poll<(), ()> {
        loop {
            let mut progress = false;

            if let Some(Async::Ready(Some(creds))) = self.discovery.as_mut().map(|d| d.poll().unwrap()) {
                if let Some(ref spirc) = self.spirc {
                    spirc.shutdown();
                }
                self.credentials(creds);

                progress = true;
            }

            if let Async::Ready(session) = self.connect.poll().unwrap() {
                self.connect = Box::new(futures::future::empty());
                let mixer = (self.mixer)();

                let audio_filter = mixer.get_audio_filter();
				let backend = audio_backend::find(None).unwrap();
                let player = Player::new(session.clone(), audio_filter, move || {
                    (backend)(None)
                });

                self.player = Some(player.clone());

                let (spirc, spirc_task) = Spirc::new(self.name.clone(), session, player, mixer);
                self.spirc = Some(spirc);
                self.spirc_task = Some(spirc_task);

                progress = true;
            }

            if let Async::Ready(Some(())) = self.signal.poll().unwrap() {
                if !self.shutdown {
                    if let Some(ref spirc) = self.spirc {
                        spirc.shutdown();
                    }
                    self.shutdown = true;
                } else {
                    return Ok(Async::Ready(()));
                }

                progress = true;
            }

            if let Some(ref mut spirc_task) = self.spirc_task {
                if let Async::Ready(()) = spirc_task.poll().unwrap() {
                    if self.shutdown {
                        return Ok(Async::Ready(()));
                    } else {
                        panic!("Spirc shut down unexpectedly");
                    }
                }
            }

            if !progress {
                return Ok(Async::NotReady);
            }
        }
    }
}

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();

    let args: Vec<String> = std::env::args().collect();
    let Setup { name, config, cache, enable_discovery, credentials, authenticate, mixer, single_track, start_position } = setup(&args);

	if let Some(ref track_id) = single_track {
		match credentials {
			Some(credentials) => {
				let backend = audio_backend::find(None).unwrap();

				let track = SpotifyId::from_base62(
									track_id.replace("spotty://", "")
									.replace("spotify://", "")
									.replace("track:", "")
									.as_str());

				let session = core.run(Session::connect(config, credentials, None, handle)).unwrap();

				let player = Player::new(session.clone(), None, move || (backend)(None));

				core.run(player.load(track, true, start_position)).unwrap();
			}
			None => {
				println!("Missing credentials");
			}
	    }
	}
	else if authenticate {
        core.run(Session::connect(config, credentials.unwrap(), cache.clone(), handle)).unwrap();
		println!("Credentials stored?");
	}
	else {
		let mut task = Main::new(handle, name, config, cache, mixer);
		if enable_discovery {
			task.discovery();
		}
		if let Some(credentials) = credentials {
			task.credentials(credentials);
		}

		core.run(task).unwrap()
    }
}

<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;

mod memory;
mod helpers;
mod temperature;
mod load;

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");

    let router = env::var("BIND_STR").map_err(|e| e.to_string())
        .and_then(|s| SocketAddr::from_str(s.as_str()).map_err(|e| e.to_string()))
        .and_then(|s| Iron::new(router).http(s).map_err(|e| e.to_string()));

    match router {
        Err(err) => println!("Error: {}", err),
        Ok(_) => { /* Router unwrapped */ }
    }
}
<commit_msg>Added default site with not found message<commit_after>extern crate iron;
extern crate router;
extern crate rustc_serialize;

use router::Router;
use iron::prelude::*;
use iron::status::Status;
use rustc_serialize::json;
use std::env;
use std::net::SocketAddr;
use std::str::FromStr;

mod memory;
mod helpers;
mod temperature;
mod load;

fn main() {
    let mut router = Router::new();
    router.get("/temperature", |_: &mut Request| -> IronResult<Response> {
        let temp = temperature::temperature();
        match temp {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "temperature");

    router.get("/memory", |_: &mut Request| -> IronResult<Response> {
        let mem = memory::read_usage();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "memory");

    router.get("/load", |_: &mut Request| -> IronResult<Response> {
        let mem = load::load();
        match mem {
            Err(err) => Ok(Response::with((Status::InternalServerError, err))),
            Ok(val) => Ok(Response::with((Status::Ok, json::encode(&val).unwrap())))
        }
    }, "load");

    router.any("/*", |_: &mut Request| -> IronResult<Response> {
        Ok(Response::with((Status::NotFound, "Page not found")))
    }, "default");

    let router = env::var("BIND_STR").map_err(|e| e.to_string())
        .and_then(|s| SocketAddr::from_str(s.as_str()).map_err(|e| e.to_string()))
        .and_then(|s| Iron::new(router).http(s).map_err(|e| e.to_string()));

    match router {
        Err(err) => println!("Error: {}", err),
        Ok(_) => { /* Router unwrapped */ }
    }
}
<|endoftext|>


<commit_before>extern crate "dbus-rs" as dbus;

use std::os::args;
use dbus::{Connection, BusType, Message, MessageItem};

static DEST: &'static str = "org.kde.kdeconnect";
static PATH: &'static str = "/modules/kdeconnect";

fn get_ids(c: &Connection) -> Result<Vec<String>, &'static str> {
    let mut m = Message::new_method_call(DEST
                                         , PATH
                                         , (DEST.to_string() + ".daemon").as_slice()
                                         , "devices").unwrap();
    m.append_items(&[MessageItem::Bool(true)]); // onlyReachable
    m = c.send_with_reply_and_block(m, 1000).unwrap();
    let items = m.get_items();
    match items[0] {
        MessageItem::Array(_, 0) => Err("No reachable devices"),
        MessageItem::Array(ref a, _) => Ok(a.clone().into_iter().map(|e| match e {
            MessageItem::Str(s) => s,
            _ => unreachable!(),
        }).collect()),
        _ => unreachable!(),
    }
}

fn share_url(c: &Connection, id: &String, url: &String) {
    let mut m = Message::new_method_call(DEST
                                         , (PATH.to_string() + "/devices/" + id.as_slice() + "/share").as_slice()
                                         , (DEST.to_string() + ".device.share").as_slice()
                                         , "shareUrl").unwrap();
    m.append_items(&[MessageItem::Str(url.clone())]);
    c.send_with_reply_and_block(m, 1000).unwrap();
}

fn main() {
    let mut urls = args();
    urls.remove(0);

    let ref c = Connection::get_private(BusType::Session).unwrap();
    let ids = get_ids(c).unwrap();
    for url in urls.iter() {
        for id in ids.iter() {
            share_url(c, id, url);
        }
    }
}
<commit_msg>connect strings instead of adding them<commit_after>extern crate "dbus-rs" as dbus;

use std::os::args;
use dbus::{Connection, BusType, Message, MessageItem};

static DEST: &'static str = "org.kde.kdeconnect";
static PATH: &'static str = "/modules/kdeconnect";

fn get_ids(c: &Connection) -> Result<Vec<String>, &'static str> {
    let mut m = Message::new_method_call(DEST
                                         , PATH
                                         , [DEST, "daemon"].connect(".").as_slice()
                                         , "devices").unwrap();
    m.append_items(&[MessageItem::Bool(true)]); // onlyReachable
    m = c.send_with_reply_and_block(m, 1000).unwrap();
    let items = m.get_items();
    match items[0] {
        MessageItem::Array(_, 0) => Err("No reachable devices"),
        MessageItem::Array(ref a, _) => Ok(a.clone().into_iter().map(|e| match e {
            MessageItem::Str(s) => s,
            _ => unreachable!(),
        }).collect()),
        _ => unreachable!(),
    }
}

fn share_url(c: &Connection, id: &String, url: &String) {
    let mut m = Message::new_method_call(DEST
                                         , [PATH, "devices", id.as_slice(), "share"].connect("/").as_slice()
                                         , [DEST, "device.share"].connect(".").as_slice()
                                         , "shareUrl").unwrap();
    m.append_items(&[MessageItem::Str(url.clone())]);
    c.send_with_reply_and_block(m, 1000).unwrap();
}

fn main() {
    let mut urls = args();
    urls.remove(0);

    let ref c = Connection::get_private(BusType::Session).unwrap();
    let ids = get_ids(c).unwrap();
    for url in urls.iter() {
        for id in ids.iter() {
            share_url(c, id, url);
        }
    }
}
<|endoftext|>


<commit_before>extern crate env_logger;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;

mod future;
mod utils;

use std::net::{SocketAddr, SocketAddrV4, IpAddr};

use mioco::udp::UdpSocket;
use mioco::mio::Ipv4Addr;
use mioco::timer::Timer;
use mioco::sync::mpsc::{Sender, channel};
use trust_dns::op::{Message, MessageType, ResponseCode, Query, OpCode};

use utils::{Result, Error, CloneExt, MessageExt};
use future::Future;

const QUERY_TIMEOUT: i64 = 5000;

fn query(q: Query, server: Ipv4Addr) -> Result<Message> {
    let mut msg : Message = Message::new();
    msg.message_type(MessageType::Query);
    msg.id(rand::random());
    msg.op_code(OpCode::Query);
    msg.recursion_desired(true);
    debug!("Q[{}][{}] {} {:?} {:?}",
           server, msg.get_id(), q.get_name(), q.get_query_type(), q.get_query_class());
    msg.add_query(q);
    let msg_data = try!(msg.to_bytes());
    let mut sock = try!(UdpSocket::v4());
    let target = SocketAddr::new(IpAddr::V4(server), 53);
    try!(sock.send(&msg_data, &target));
    let mut timer = Timer::new();
    timer.set_timeout(QUERY_TIMEOUT);
    let mut buf = [0u8; 1024 * 16];
    loop {
        select! {
            r:sock => { /* Fall below */ },
            r:timer => {
                return Err(std::io::ErrorKind::TimedOut.into());
            },
        };
        let result = try!(sock.try_recv(&mut buf));
        if result.is_none() {
            continue;
        }
        let (len, addr) = result.unwrap();
        if addr != target {
            warn!("Q[{}][{}] Response from unexpected server: {}",
                  server, msg.get_id(), addr);
            continue
        }
        let resp = try!(Message::from_bytes(&buf[0..len]));
        if ! resp.is_resp_for(&msg) {
            warn!("Q[{}][{}] Invalid response: {:?}",
                  server, msg.get_id(), resp);
            continue
        }
        // TODO: Validate response, handle truncated message
        debug!("A[{}][{}] {:?} {} answer(s)",
           server, resp.get_id(), resp.get_response_code(), resp.get_answers().len());
        return Ok(resp);
    };
}
fn query_multiple(q: &Query, servers: &[Ipv4Addr]) -> Result<Message> {
    let mut futures = servers.iter()
        .cloned()
        .map(move |server| {
            let qc = q.clone();
            Future::from_fn(move || query(qc, server))
        })
        .collect::<Vec<Future<Result<Message>>>>();
    loop {
        let result_index = Future::wait_any(&mut futures);
        let result = futures.remove(result_index).consume();
        let mut should_return = futures.len() == 0;
        match result {
            Ok(ref msg) => {
                match msg.get_response_code() {
                    ResponseCode::ServFail |
                    ResponseCode::NotImp |
                    ResponseCode::Refused => {
                        // Fall below to wait for remaining servers, if any
                    },
                    _ => { should_return = true; },
                }
            },
            Err(Error::Io(ref err)) if err.kind() == std::io::ErrorKind::TimedOut => {
                debug!("{:?} timed out", q);
            },
            Err(ref err) => {
                debug!("{:?} returned error {:?}", q, err);
            },
        };
        if should_return {
            return result;
        }
    }
}

fn handle_request(msg: Message) -> Message {
    let mut ret : Message = msg.new_resp();
    ret.recursion_available(true);
    if msg.get_queries().len() != 1 {
        // For simplicity, only support one question
        ret.response_code(ResponseCode::Refused);
        return ret;
    }
    // TODO: EDNS?
    match query_multiple(&msg.get_queries()[0], &[Ipv4Addr::new(1, 8, 8, 8), Ipv4Addr::new(1, 8, 4, 4)]) {
        Ok(resp) => { ret.copy_resp_from(&resp); },
        Err(_)   => { ret.response_code(ResponseCode::ServFail); },
    };
    ret
}
fn handle_request_async(msg: Message, addr: SocketAddr, sender: Sender<(Message, SocketAddr)>) {
    mioco::spawn(move || {
        sender.send((handle_request(msg), addr)).unwrap();
    });
}

fn main() {
    env_logger::init().unwrap();
    println!("Hello, world!");

    mioco::start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));

        mioco::spawn(move || -> Result<()> {
            let mut sock : UdpSocket = UdpSocket::v4().unwrap();
            sock.bind(&addr).unwrap();

            let (sender, receiver) = channel::<(Message, SocketAddr)>();
            {
                let mut sock_resp = sock.try_clone().unwrap();
                mioco::spawn(move || {
                    loop {
                        let (msg, addr) = receiver.recv().unwrap();
                        let bytes = msg.to_bytes().unwrap();
                        sock_resp.send(&bytes, &addr).unwrap();
                    }
                });
            }

            loop {
                let (msg, addr) = try!(Message::from_udp(&mut sock));
                handle_request_async(msg, addr, sender.clone());
            }
        });
    }).unwrap();
}
<commit_msg>Do not panic when failing to reply<commit_after>extern crate env_logger;
#[macro_use] extern crate mioco;
extern crate trust_dns;
extern crate rand;
#[macro_use] extern crate quick_error;
#[macro_use] extern crate log;

mod future;
mod utils;

use std::net::{SocketAddr, SocketAddrV4, IpAddr};

use mioco::udp::UdpSocket;
use mioco::mio::Ipv4Addr;
use mioco::timer::Timer;
use mioco::sync::mpsc::{Sender, channel};
use trust_dns::op::{Message, MessageType, ResponseCode, Query, OpCode};

use utils::{Result, Error, CloneExt, MessageExt};
use future::Future;

const QUERY_TIMEOUT: i64 = 5000;

fn query(q: Query, server: Ipv4Addr) -> Result<Message> {
    let mut msg : Message = Message::new();
    msg.message_type(MessageType::Query);
    msg.id(rand::random());
    msg.op_code(OpCode::Query);
    msg.recursion_desired(true);
    debug!("Q[{}][{}] {} {:?} {:?}",
           server, msg.get_id(), q.get_name(), q.get_query_type(), q.get_query_class());
    msg.add_query(q);
    let msg_data = try!(msg.to_bytes());
    let mut sock = try!(UdpSocket::v4());
    let target = SocketAddr::new(IpAddr::V4(server), 53);
    try!(sock.send(&msg_data, &target));
    let mut timer = Timer::new();
    timer.set_timeout(QUERY_TIMEOUT);
    let mut buf = [0u8; 1024 * 16];
    loop {
        select! {
            r:sock => { /* Fall below */ },
            r:timer => {
                return Err(std::io::ErrorKind::TimedOut.into());
            },
        };
        let result = try!(sock.try_recv(&mut buf));
        if result.is_none() {
            continue;
        }
        let (len, addr) = result.unwrap();
        if addr != target {
            warn!("Q[{}][{}] Response from unexpected server: {}",
                  server, msg.get_id(), addr);
            continue
        }
        let resp = try!(Message::from_bytes(&buf[0..len]));
        if ! resp.is_resp_for(&msg) {
            warn!("Q[{}][{}] Invalid response: {:?}",
                  server, msg.get_id(), resp);
            continue
        }
        // TODO: Validate response, handle truncated message
        debug!("A[{}][{}] {:?} {} answer(s)",
           server, resp.get_id(), resp.get_response_code(), resp.get_answers().len());
        return Ok(resp);
    };
}
fn query_multiple(q: &Query, servers: &[Ipv4Addr]) -> Result<Message> {
    let mut futures = servers.iter()
        .cloned()
        .map(move |server| {
            let qc = q.clone();
            Future::from_fn(move || query(qc, server))
        })
        .collect::<Vec<Future<Result<Message>>>>();
    loop {
        let result_index = Future::wait_any(&mut futures);
        let result = futures.remove(result_index).consume();
        let mut should_return = futures.len() == 0;
        match result {
            Ok(ref msg) => {
                match msg.get_response_code() {
                    ResponseCode::ServFail |
                    ResponseCode::NotImp |
                    ResponseCode::Refused => {
                        // Fall below to wait for remaining servers, if any
                    },
                    _ => { should_return = true; },
                }
            },
            Err(Error::Io(ref err)) if err.kind() == std::io::ErrorKind::TimedOut => {
                debug!("{:?} timed out", q);
            },
            Err(ref err) => {
                debug!("{:?} returned error {:?}", q, err);
            },
        };
        if should_return {
            return result;
        }
    }
}

fn handle_request(msg: Message) -> Message {
    let mut ret : Message = msg.new_resp();
    ret.recursion_available(true);
    if msg.get_queries().len() != 1 {
        // For simplicity, only support one question
        ret.response_code(ResponseCode::Refused);
        return ret;
    }
    // TODO: EDNS?
    match query_multiple(&msg.get_queries()[0], &[Ipv4Addr::new(8, 8, 8, 8), Ipv4Addr::new(8, 8, 4, 4)]) {
        Ok(resp) => { ret.copy_resp_from(&resp); },
        Err(_)   => { ret.response_code(ResponseCode::ServFail); },
    };
    ret
}
fn handle_request_async(msg: Message, addr: SocketAddr, sender: Sender<(Message, SocketAddr)>) {
    mioco::spawn(move || {
        sender.send((handle_request(msg), addr)).unwrap();
    });
}

fn main() {
    env_logger::init().unwrap();
    println!("Hello, world!");

    mioco::start(move || {
        let ip = Ipv4Addr::new(0, 0, 0, 0);
        let port = 5354;
        let addr = SocketAddr::V4(SocketAddrV4::new(ip, port));

        mioco::spawn(move || -> Result<()> {
            let mut sock : UdpSocket = UdpSocket::v4().unwrap();
            sock.bind(&addr).unwrap();

            let (sender, receiver) = channel::<(Message, SocketAddr)>();
            {
                let mut sock_resp = sock.try_clone().unwrap();
                mioco::spawn(move || {
                    loop {
                        let (msg, addr) = receiver.recv().unwrap();
                        let bytes = msg.to_bytes().unwrap();
                        match sock_resp.send(&bytes, &addr) {
                            Ok(_) => {},
                            Err(x) => warn!("Fail to send reply to {}: {:?}", addr, x),
                        };
                    }
                });
            }

            loop {
                let (msg, addr) = try!(Message::from_udp(&mut sock));
                handle_request_async(msg, addr, sender.clone());
            }
        });
    }).unwrap();
}
<|endoftext|>


<commit_before>extern crate lz4;

use std::env;
use std::fs::File;
use std::io;
use std::io::Result;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use lz4::Encoder;

fn main() {
    let args: &Vec<String> = &mut env::args().collect();

    let mut width: u32 = 0;
    let mut height: u32 = 0;
    let mut frame: u32 = 0;
    let mut out_file: &str = "";

    let mut index: usize = 0;
    for argument in args {
        let arg: &str = &argument;
        let args_len: usize = *(&args.len());

        match arg {
            "-w" => {
                if index < (args_len - 1) {
                    width = args[index + 1].parse::<u32>().unwrap();;
                }
            }
            "-h" => {
                if index < (args_len - 1) {
                    height = args[index + 1].parse::<u32>().unwrap();;
                }
            }
            "-frame" => {
                if index < (args_len - 1) {
                    frame = args[index + 1].parse::<u32>().unwrap();
                }
            }
            "-o" => {
                if index < (args_len - 1) {
                    out_file = &args[index + 1];
                }
            }
            _ => {}
        }
        index += 1;
    }

    if width == 0 || height == 0 || frame == 0 || out_file == "" {
        println!("Usage of : splityv12pipe -w <width> -h <height> -frame <number> -o <filename>");
        return;
    }

    let max_bytes_len: usize = (frame * (width * height + width * height / 2)) as usize;
    compress(out_file.to_string(), max_bytes_len).unwrap();
}

fn compress(dst: String, maxlen: usize) -> Result<()> {
    let count: i32 = 0;
    let file_name: String = format!("{}_{}", dst, count.to_string());
    let path: &Path = Path::new(&file_name);

    let mut fi = io::stdin();
    let mut fo = try!(lz4::EncoderBuilder::new().build(try!(File::create(path))));

    let file_path: &str = path.to_str().unwrap();

    copy(&mut fi,
         &mut fo,
         &dst,
         maxlen,
         count + 1,
         &move || {
             println!("{}", file_path);
             return Ok(());
         })
        .unwrap();
    fo.finish();

    Ok(())
}

fn copy(fi: &mut Read,
        fo: &mut Encoder<std::fs::File>,
        dst: &str,
        maxlen: usize,
        count: i32,
        done: &Fn() -> Result<()>)
        -> Result<()> {
    let mut buffer: [u8; 1024] = [0; 1024];
    let mut write_len: usize = 0;

    loop {
        let len = try!(fi.read(&mut buffer));
        if len == 0 {
            done().unwrap();
            break;
        }
        if write_len + len >= maxlen {
            let mut l = 0;
            if (write_len + len) - maxlen > 0 {
                l = maxlen - write_len;
                try!(fo.write_all(&buffer[0..l]));
            }
            done().unwrap();

            let file_name: &str = &format!("{}_{}", dst, count.to_string());
            let path = Path::new(file_name);
            let file_path = path.to_str().unwrap();
            let mut new_fo = try!(lz4::EncoderBuilder::new().build(try!(File::create(path))));
            try!(new_fo.write_all(&buffer[l..len]));

            copy(fi,
                 &mut new_fo,
                 dst,
                 maxlen,
                 count + 1,
                 &move || {
                     println!("{}", file_path);
                     return Ok(());
                 })
                .unwrap();

            new_fo.finish();

            break;
        }
        try!(fo.write_all(&buffer[0..len]));
        write_len += len;
    }
    Ok(())
}
<commit_msg>fix file display<commit_after>extern crate lz4;

use std::env;
use std::fs::File;
use std::io;
use std::io::Result;
use std::io::Read;
use std::io::Write;
use std::path::Path;
use lz4::Encoder;

fn main() {
    let args: &Vec<String> = &mut env::args().collect();

    let mut width: u32 = 0;
    let mut height: u32 = 0;
    let mut frame: u32 = 0;
    let mut out_file: &str = "";

    let mut index: usize = 0;
    for argument in args {
        let arg: &str = &argument;
        let args_len: usize = *(&args.len());

        match arg {
            "-w" => {
                if index < (args_len - 1) {
                    width = args[index + 1].parse::<u32>().unwrap();;
                }
            }
            "-h" => {
                if index < (args_len - 1) {
                    height = args[index + 1].parse::<u32>().unwrap();;
                }
            }
            "-frame" => {
                if index < (args_len - 1) {
                    frame = args[index + 1].parse::<u32>().unwrap();
                }
            }
            "-o" => {
                if index < (args_len - 1) {
                    out_file = &args[index + 1];
                }
            }
            _ => {}
        }
        index += 1;
    }

    if width == 0 || height == 0 || frame == 0 || out_file == "" {
        println!("Usage of : splityv12pipe -w <width> -h <height> -frame <number> -o <filename>");
        return;
    }

    let max_bytes_len: usize = (frame * (width * height + width * height / 2)) as usize;
    compress(out_file.to_string(), max_bytes_len).unwrap();
}

fn compress(dst: String, maxlen: usize) -> Result<()> {
    let count: i32 = 0;
    let file_name: String = format!("{}_{}", dst, count.to_string());
    let path: &Path = Path::new(&file_name);

    let mut fi = io::stdin();
    let mut fo = try!(lz4::EncoderBuilder::new().build(try!(File::create(path))));

    copy(&mut fi,
         &mut fo,
         &dst,
         maxlen,
         count + 1,
         &move || {
             println!("{}", path.display());
             return Ok(());
         })
        .unwrap();
    fo.finish();

    Ok(())
}

fn copy(fi: &mut Read,
        fo: &mut Encoder<std::fs::File>,
        dst: &str,
        maxlen: usize,
        count: i32,
        done: &Fn() -> Result<()>)
        -> Result<()> {
    let mut buffer: [u8; 1024] = [0; 1024];
    let mut write_len: usize = 0;

    loop {
        let len = try!(fi.read(&mut buffer));
        if len == 0 {
            done().unwrap();
            break;
        }
        if write_len + len >= maxlen {
            let mut l = 0;
            if (write_len + len) - maxlen > 0 {
                l = maxlen - write_len;
                try!(fo.write_all(&buffer[0..l]));
            }
            done().unwrap();

            let file_name: &str = &format!("{}_{}", dst, count.to_string());
            let path = Path::new(file_name);
            let mut new_fo = try!(lz4::EncoderBuilder::new().build(try!(File::create(path))));
            try!(new_fo.write_all(&buffer[l..len]));

            copy(fi,
                 &mut new_fo,
                 dst,
                 maxlen,
                 count + 1,
                 &move || {
                     println!("{}", path.display());
                     return Ok(());
                 })
                .unwrap();

            new_fo.finish();

            break;
        }
        try!(fo.write_all(&buffer[0..len]));
        write_len += len;
    }
    Ok(())
}
<|endoftext|>


<commit_before>#[crate_id = "rboy"];

#[feature(phase)];
#[phase(syntax, link)] extern crate log;

extern crate native;
extern crate green;
extern crate getopts;
extern crate sync;
extern crate time;
extern crate sdl;

use cpu::CPU;
use sync::DuplexStream;
use sync::RWArc;

mod register;
mod mbc;
mod mmu;
mod cpu;
mod serial;
mod timer;
mod keypad;
mod gpu;
mod sound;
mod gbmode;

static SCALE: int = 2;

#[start]
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }

fn main() {
	let args: ~[~str] = std::os::args();
	let program = args[0].clone() + " <filename>";

	let opts = ~[ getopts::optflag("s", "serial", "Output serial to stdout"), getopts::optflag("c", "classic", "Force Classic mode") ];
	let matches = match getopts::getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => { println!("{}", f.to_err_msg()); return }
	};

	let filename: ~str = if !matches.free.is_empty() {
		matches.free[0].clone()
	} else {
		println!("{}", getopts::usage(program, opts));
		return;
	};

	sdl::init([sdl::InitVideo]);
	sdl::wm::set_caption("RBoy - A gameboy in Rust", "rboy");
	let screen = match sdl::video::set_video_mode(160*SCALE, 144*SCALE, 32, [sdl::video::HWSurface], [sdl::video::DoubleBuf]) {
		Ok(screen) => screen,
		Err(err) => fail!("failed to open screen: {}", err),
	};

	let (sdlstream, cpustream) = sync::duplex();
	let rawscreen = ~[0x00u8,.. 160*144*3];
	let arc = RWArc::new(rawscreen);
	let arc2 = arc.clone();
	native::task::spawn(proc() cpuloop(&cpustream, arc2, filename, &matches));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(8);

	'main : loop {
		periodic.recv();
		match sdlstream.try_recv() {
			std::comm::Disconnected => { break 'main },
			std::comm::Data(_) => recalculate_screen(screen, &arc),
			std::comm::Empty => {},
		}
		'event : loop {
			match sdl::event::poll_event() {
				sdl::event::QuitEvent => break 'main,
				sdl::event::NoEvent => break 'event,
				sdl::event::KeyEvent(sdl::event::EscapeKey, _, _, _)
					=> break 'main,
				sdl::event::KeyEvent(sdl::event::LShiftKey, true, _, _)
					=> sdlstream.send(SpeedUp),
				sdl::event::KeyEvent(sdl::event::LShiftKey, false, _, _)
					=> sdlstream.send(SlowDown),
				sdl::event::KeyEvent(sdlkey, true, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => sdlstream.send(KeyDown(key)),
						None => {},
					}
				},
				sdl::event::KeyEvent(sdlkey, false, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => sdlstream.send(KeyUp(key)),
						None => {},
					}
				},
				_ => {}
			}
		}
	}
}

fn sdl_to_keypad(key: sdl::event::Key) -> Option<keypad::KeypadKey> {
	match key {
		sdl::event::ZKey => Some(keypad::A),
		sdl::event::XKey => Some(keypad::B),
		sdl::event::UpKey => Some(keypad::Up),
		sdl::event::DownKey => Some(keypad::Down),
		sdl::event::LeftKey => Some(keypad::Left),
		sdl::event::RightKey => Some(keypad::Right),
		sdl::event::SpaceKey => Some(keypad::Select),
		sdl::event::ReturnKey => Some(keypad::Start),
		_ => None,
	}
}

fn recalculate_screen(screen: &sdl::video::Surface, arc: &RWArc<~[u8]>) {
	arc.read(|data|
		for y in range(0, 144) {
			for x in range(0, 160) {
				screen.fill_rect(
					Some(sdl::Rect { x: (x*SCALE) as i16, y: (y*SCALE) as i16, w: SCALE as u16, h: SCALE as u16 }),
					sdl::video::RGB(data[y*160*3 + x*3 + 0],
					                data[y*160*3 + x*3 + 1],
					                data[y*160*3 + x*3 + 2])
				);
			}
		}
	);
	screen.flip();
}

enum GBEvent {
	KeyUp(keypad::KeypadKey),
	KeyDown(keypad::KeypadKey),
	SpeedUp,
	SlowDown,
}

fn cpuloop(channel: &DuplexStream<uint, GBEvent>, arc: RWArc<~[u8]>, filename: ~str, matches: &getopts::Matches) {
	let mut c = match matches.opt_present("classic") {
		true => CPU::new(filename),
		false => CPU::new_cgb(filename),
	};
	c.mmu.serial.tostdout = matches.opt_present("serial");

	let mut timer = std::io::timer::Timer::new().unwrap();
	let mut periodic = timer.periodic(8);

	let waitticks = (4194.304 * 4.0) as uint;

	let mut ticks = 0;
	loop {
		while ticks < waitticks {
			ticks += c.cycle();
			if c.mmu.gpu.updated {
				c.mmu.gpu.updated = false;
				arc.write(|data|
					for i in range(0, data.len()) { data[i] = c.mmu.gpu.data[i]; }
				);
				channel.try_send(0);
			}
		}
		ticks -= waitticks;
		periodic.recv();

		match channel.try_recv() {
			std::comm::Data(event) => match event {
				KeyUp(key) => c.mmu.keypad.keyup(key),
				KeyDown(key) => c.mmu.keypad.keydown(key),
				SpeedUp => periodic = timer.periodic(1),
				SlowDown => periodic = timer.periodic(8),
			},
			std::comm::Empty => {},
			std::comm::Disconnected => { break },
		};
	}
}
<commit_msg>Fix matches now being of type Vec<commit_after>#[crate_id = "rboy"];

#[feature(phase)];
#[phase(syntax, link)] extern crate log;

extern crate native;
extern crate green;
extern crate getopts;
extern crate sync;
extern crate time;
extern crate sdl;

use cpu::CPU;
use sync::DuplexStream;
use sync::RWArc;

mod register;
mod mbc;
mod mmu;
mod cpu;
mod serial;
mod timer;
mod keypad;
mod gpu;
mod sound;
mod gbmode;

static SCALE: int = 2;

#[start]
fn start(argc: int, argv: **u8) -> int { green::start(argc, argv, main) }

fn main() {
	let args = std::os::args();
	let program = args[0].clone() + " <filename>";

	let opts = [ getopts::optflag("s", "serial", "Output serial to stdout"), getopts::optflag("c", "classic", "Force Classic mode") ];
	let matches = match getopts::getopts(args.tail(), opts) {
		Ok(m) => { m }
		Err(f) => { println!("{}", f.to_err_msg()); return }
	};

	let filename = if !matches.free.is_empty() {
		matches.free.get(0).clone()
	} else {
		println!("{}", getopts::usage(program, opts));
		return;
	};

	sdl::init([sdl::InitVideo]);
	sdl::wm::set_caption("RBoy - A gameboy in Rust", "rboy");
	let screen = match sdl::video::set_video_mode(160*SCALE, 144*SCALE, 32, [sdl::video::HWSurface], [sdl::video::DoubleBuf]) {
		Ok(screen) => screen,
		Err(err) => fail!("failed to open screen: {}", err),
	};

	let (sdlstream, cpustream) = sync::duplex();
	let rawscreen = ~[0x00u8,.. 160*144*3];
	let arc = RWArc::new(rawscreen);
	let arc2 = arc.clone();
	native::task::spawn(proc() cpuloop(&cpustream, arc2, filename, &matches));

	let mut timer = std::io::timer::Timer::new().unwrap();
	let periodic = timer.periodic(8);

	'main : loop {
		periodic.recv();
		match sdlstream.try_recv() {
			std::comm::Disconnected => { break 'main },
			std::comm::Data(_) => recalculate_screen(screen, &arc),
			std::comm::Empty => {},
		}
		'event : loop {
			match sdl::event::poll_event() {
				sdl::event::QuitEvent => break 'main,
				sdl::event::NoEvent => break 'event,
				sdl::event::KeyEvent(sdl::event::EscapeKey, _, _, _)
					=> break 'main,
				sdl::event::KeyEvent(sdl::event::LShiftKey, true, _, _)
					=> sdlstream.send(SpeedUp),
				sdl::event::KeyEvent(sdl::event::LShiftKey, false, _, _)
					=> sdlstream.send(SlowDown),
				sdl::event::KeyEvent(sdlkey, true, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => sdlstream.send(KeyDown(key)),
						None => {},
					}
				},
				sdl::event::KeyEvent(sdlkey, false, _, _) => {
					match sdl_to_keypad(sdlkey) {
						Some(key) => sdlstream.send(KeyUp(key)),
						None => {},
					}
				},
				_ => {}
			}
		}
	}
}

fn sdl_to_keypad(key: sdl::event::Key) -> Option<keypad::KeypadKey> {
	match key {
		sdl::event::ZKey => Some(keypad::A),
		sdl::event::XKey => Some(keypad::B),
		sdl::event::UpKey => Some(keypad::Up),
		sdl::event::DownKey => Some(keypad::Down),
		sdl::event::LeftKey => Some(keypad::Left),
		sdl::event::RightKey => Some(keypad::Right),
		sdl::event::SpaceKey => Some(keypad::Select),
		sdl::event::ReturnKey => Some(keypad::Start),
		_ => None,
	}
}

fn recalculate_screen(screen: &sdl::video::Surface, arc: &RWArc<~[u8]>) {
	arc.read(|data|
		for y in range(0, 144) {
			for x in range(0, 160) {
				screen.fill_rect(
					Some(sdl::Rect { x: (x*SCALE) as i16, y: (y*SCALE) as i16, w: SCALE as u16, h: SCALE as u16 }),
					sdl::video::RGB(data[y*160*3 + x*3 + 0],
					                data[y*160*3 + x*3 + 1],
					                data[y*160*3 + x*3 + 2])
				);
			}
		}
	);
	screen.flip();
}

enum GBEvent {
	KeyUp(keypad::KeypadKey),
	KeyDown(keypad::KeypadKey),
	SpeedUp,
	SlowDown,
}

fn cpuloop(channel: &DuplexStream<uint, GBEvent>, arc: RWArc<~[u8]>, filename: ~str, matches: &getopts::Matches) {
	let mut c = match matches.opt_present("classic") {
		true => CPU::new(filename),
		false => CPU::new_cgb(filename),
	};
	c.mmu.serial.tostdout = matches.opt_present("serial");

	let mut timer = std::io::timer::Timer::new().unwrap();
	let mut periodic = timer.periodic(8);

	let waitticks = (4194.304 * 4.0) as uint;

	let mut ticks = 0;
	loop {
		while ticks < waitticks {
			ticks += c.cycle();
			if c.mmu.gpu.updated {
				c.mmu.gpu.updated = false;
				arc.write(|data|
					for i in range(0, data.len()) { data[i] = c.mmu.gpu.data[i]; }
				);
				channel.try_send(0);
			}
		}
		ticks -= waitticks;
		periodic.recv();

		match channel.try_recv() {
			std::comm::Data(event) => match event {
				KeyUp(key) => c.mmu.keypad.keyup(key),
				KeyDown(key) => c.mmu.keypad.keydown(key),
				SpeedUp => periodic = timer.periodic(1),
				SlowDown => periodic = timer.periodic(8),
			},
			std::comm::Empty => {},
			std::comm::Disconnected => { break },
		};
	}
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
extern crate uuid;
use uuid::Uuid;
extern crate getopts;
use getopts::Options;
use std::io;

macro_rules! exit_with_exception {
    ($error:ident, $extra:tt) => {
        let _ = write!(&mut std::io::stderr(), "{}\n", $extra);
        let _ = write!(&mut std::io::stderr(), "{}\n", $error);
        std::process::exit(-1);
    };
}

fn print_usage(program: &str, opts: Options, include_info: bool, include_copyright: bool) {
    let path = PathBuf::from(program);
    let command = path.file_name().unwrap().to_string_lossy();

    let copyright =
        "rewrite 0.2 by NeoSmart Technologies. Written by Mahmoud Al-Qudsi <mqudsi@neosmart.net>";
    let brief = format!("Usage: {} FILE [options]", command);
    let info = "Safely rewrite contents of FILE with stdin, even where FILE is being read by \
                upstream command";

    if include_copyright {
        println!("{}", copyright);
    }
    if include_info {
        println!("{}", info);
    }
    print!("{}", opts.usage(&brief));
}

fn redirect_to_file(outfile: &str) {
    // Create the temporary file in the same directory as outfile this lets us guarantee a rename
    // (instead of a move) on completion
    let mut tempfile = PathBuf::from(outfile);
    tempfile.pop(); // Now refers to parent, which might be nothing
    tempfile.push(Uuid::new_v4().hyphenated().to_string());
    // println!("{}", tempfile.display());

    {
        let mut buffer = [0; 512];
        let mut stdin = io::stdin();
        let mut f = File::create(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create temporary output file!");
        });

        loop {
            let read_bytes = stdin.read(&mut buffer).unwrap_or_else(|e| {
                exit_with_exception!(e, "Error reading from stdin!");
            });
            if read_bytes == 0 {
                break;
            }

            f.write_all(&buffer[0..read_bytes]).unwrap_or_else(|e| {
                exit_with_exception!(e, "Failed to write to temporary output file!");
            });
        }
    }

    std::fs::rename(&tempfile, &outfile).unwrap_or_else(|_x| {
        // fs::rename() does not support cross-device linking.
        // Copy and delete instead.
        std::fs::copy(&tempfile, &outfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create output file!");
        });
        std::fs::remove_file(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to delete temporary output file!");
        });
    });
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let program = &args[0];

    let mut opts = Options::new();
    opts.optflag("h", "help", "prints this help info");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => {
            println!("{}", e);
            print_usage(&program, opts, false, false);
            return;
        }
    };

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

    let infile = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts, true, false);
        return;
    };

    redirect_to_file(&infile);
}
<commit_msg>Explicitly lock stdin/stderr<commit_after>use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::PathBuf;
extern crate uuid;
use uuid::Uuid;
extern crate getopts;
use getopts::Options;
use std::io;

macro_rules! exit_with_exception {
    ($error:ident, $extra:tt) => {
        let stderr = std::io::stderr();
        let mut stderr = stderr.lock();
        let _ = write!(&mut stderr, "{}\n", $extra);
        let _ = write!(&mut stderr, "{}\n", $error);
        std::process::exit(-1);
    };
}

fn print_usage(program: &str, opts: Options, include_info: bool, include_copyright: bool) {
    let path = PathBuf::from(program);
    let command = path.file_name().unwrap().to_string_lossy();

    let copyright =
        "rewrite 0.2 by NeoSmart Technologies. Written by Mahmoud Al-Qudsi <mqudsi@neosmart.net>";
    let brief = format!("Usage: {} FILE [options]", command);
    let info = "Safely rewrite contents of FILE with stdin, even where FILE is being read by \
                upstream command";

    if include_copyright {
        println!("{}", copyright);
    }
    if include_info {
        println!("{}", info);
    }
    print!("{}", opts.usage(&brief));
}

fn redirect_to_file(outfile: &str) {
    // Create the temporary file in the same directory as outfile this lets us guarantee a rename
    // (instead of a move) on completion
    let mut tempfile = PathBuf::from(outfile);
    tempfile.pop(); // Now refers to parent, which might be nothing
    tempfile.push(Uuid::new_v4().hyphenated().to_string());
    // println!("{}", tempfile.display());

    {
        let mut buffer = [0; 512];
        let stdin = io::stdin();
        let mut stdin = stdin.lock();
        let mut f = File::create(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create temporary output file!");
        });

        loop {
            let read_bytes = stdin.read(&mut buffer).unwrap_or_else(|e| {
                exit_with_exception!(e, "Error reading from stdin!");
            });
            if read_bytes == 0 {
                break;
            }

            f.write_all(&buffer[0..read_bytes]).unwrap_or_else(|e| {
                exit_with_exception!(e, "Failed to write to temporary output file!");
            });
        }
    }

    std::fs::rename(&tempfile, &outfile).unwrap_or_else(|_x| {
        // fs::rename() does not support cross-device linking.
        // Copy and delete instead.
        std::fs::copy(&tempfile, &outfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to create output file!");
        });
        std::fs::remove_file(&tempfile).unwrap_or_else(|e| {
            exit_with_exception!(e, "Failed to delete temporary output file!");
        });
    });
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let program = &args[0];

    let mut opts = Options::new();
    opts.optflag("h", "help", "prints this help info");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(e) => {
            println!("{}", e);
            print_usage(&program, opts, false, false);
            return;
        }
    };

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

    let infile = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts, true, false);
        return;
    };

    redirect_to_file(&infile);
}
<|endoftext|>