<commit_before>extern crate time;

use std::fs::{File, create_dir, OpenOptions, remove_file};
use std::io::{Seek, SeekFrom, BufReader, BufRead, Lines, Write};
use std::io;
use std::path::{Path, PathBuf};
use std::env::{args, home_dir};
use std::fmt;
use std::process::exit;
use time::{Duration, now_utc, Tm, empty_tm, strptime};

fn main() {
    let result = match args().nth(1) {
        None => Err(PunchClockError::NoCommandGiven),
        Some(command) => {
            let mut time_clock = TimeClock::new().unwrap();
            match &command[..] {
                "in" => time_clock.punch_in(),
                "out" => time_clock.punch_out(),
                "status" => time_clock.status(),
                "report" => time_clock.report_daily_hours(),
                _ => Err(PunchClockError::UnknownCommand)
            }
        }
    };

    if let Err(e) = result {
        println!("Error: {}", e);
        exit(1);
    }
}

#[derive(Debug)]
enum PunchClockError {
    NoCommandGiven,
    UnknownCommand,
    AlreadyPunchedIn,
    AlreadyPunchedOut,
    CorruptedTimeSheet,
    IoError(io::Error),
}

impl fmt::Display for PunchClockError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use PunchClockError::*;
        fmt.write_str(
            match *self {
                NoCommandGiven => "No command given",
                UnknownCommand => "Unknown command",
                AlreadyPunchedIn => "You are already punched in",
                AlreadyPunchedOut => "You're not currently punched in",
                CorruptedTimeSheet => "Bad data in timesheet",
                IoError(_) => "IO error"
            }
        )
    }
}

impl From<io::Error> for PunchClockError {
    fn from(err: io::Error) -> PunchClockError {
        PunchClockError::IoError(err)
    }
}
type PunchClockResult<T> = Result<T, PunchClockError>;

struct TimeClock {
    now: Tm,
    timesheet: File,
    timesheet_path: PathBuf,
    currently_working: bool,
    state_path: PathBuf
}

impl TimeClock {
    fn new() -> PunchClockResult<TimeClock> {
        let now = now_utc();
        let home = home_dir().unwrap();
        let base_dir = home.join(Path::new(".punch"));
        let timesheet_path = base_dir.join("timesheet");
        let working_state_path = base_dir.join("state");
        if !path_exists(&base_dir) {
            try!(create_dir(&base_dir));
        }
        let timesheet = try!(OpenOptions::new().write(true).append(true)
                            .open(&timesheet_path));
        Ok(TimeClock {
            timesheet: timesheet,
            timesheet_path: timesheet_path,
            currently_working: path_exists(&working_state_path),
            state_path: working_state_path,
            now: now
        })
    }

    // commands

    fn punch_in(&mut self) -> PunchClockResult<()> {
        if self.currently_working {
            return Err(PunchClockError::AlreadyPunchedIn);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        writeln!(&mut self.timesheet, "in: {}", self.now.rfc822()).unwrap();
        self.set_current_working_state(true);
        Ok(())
    }

    fn punch_out(&mut self) -> PunchClockResult<()> {
        if !self.currently_working {
            return Err(PunchClockError::AlreadyPunchedOut);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        try!(writeln!(&mut self.timesheet, "out: {}", self.now.rfc822()));
        self.set_current_working_state(false);
        Ok(())
    }

    fn status(&self) -> PunchClockResult<()> {
        if self.currently_working {
            println!("You're punched in");
        } else {
            println!("You're punched out");
        }
        Ok(())
    }

    fn report_daily_hours(&mut self) -> PunchClockResult<()> {
        try!(self.timesheet.seek(SeekFrom::Start(0)));
        let buf = BufReader::new(try!(File::open(&self.timesheet_path)));
        let mut current_day = empty_tm();
        let mut time_worked_today = Duration::zero();

        for interval in IntervalIter::from_lines(buf.lines()) {
            let (start, end) = try!(interval);
            if !same_day(&start, &current_day) {
                if !time_worked_today.is_zero() {
                    print_time_worked(&time_worked_today, &current_day);
                }
                current_day = start;
                time_worked_today = Duration::zero();
            }
            time_worked_today =
                time_worked_today + (end.to_timespec() - start.to_timespec());
        }

        if !time_worked_today.is_zero() {
            print_time_worked(&time_worked_today, &current_day);
        }
        Ok(())
    }

    // aux. methods

    fn set_current_working_state(&mut self, currently_working: bool) {
        self.currently_working = currently_working;
        if currently_working {
            File::create(&self.state_path).unwrap();
        } else {
            remove_file(&self.state_path).unwrap();
        }
    }
}

struct IntervalIter {
    lines: Lines<BufReader<File>>
}

impl IntervalIter {
    fn from_lines(lines: Lines<BufReader<File>>) -> IntervalIter {
        IntervalIter {lines: lines}
    }
}

impl Iterator for IntervalIter {
    type Item = PunchClockResult<(Tm, Tm)>;
    fn next(&mut self) -> Option<PunchClockResult<(Tm, Tm)>> {

        // helper function to make error handling a bit nicer
        fn inner_unwrap<T>(x: Option<io::Result<T>>)
                -> PunchClockResult<Option<T>> {
            match x {
                None => Ok(None),
                Some(Ok(inner)) => Ok(Some(inner)),
                Some(Err(e)) => Err(PunchClockError::IoError(e))
            }
        }

        let line_1 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };
        let line_2 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };

        match (line_1, line_2) {
            (None, None) => None,
            (Some(start_line), o_end_line) => {
                if !start_line.starts_with("in: ") {
                    return Some(Err(PunchClockError::CorruptedTimeSheet));
                }
                let start = parse_time(&start_line[4..]);
                let end = match o_end_line {
                    None => now_utc(),
                    Some(end_line) => {
                        if !end_line.starts_with("out: ") {
                            return Some(Err(PunchClockError::CorruptedTimeSheet));
                        }
                        parse_time(&end_line[5..])
                    },
                };
                Some(Ok((start, end)))
            },
            _ => unreachable!() // (None, Some(l)) should not happen
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

fn parse_time(s: &str) -> Tm {
    strptime(&s[..s.len() - 1], "%a, %d %b %Y %T %Z").unwrap()
}

fn same_day(t1: &Tm, t2: &Tm) -> bool {
    t1.tm_year == t2.tm_year &&
    t1.tm_mon == t2.tm_mon &&
    t1.tm_mday == t2.tm_mday
}

fn print_time_worked(t: &Duration, day: &Tm) {
    println!("{}: {:>2}:{:02}",
        day.strftime("%a, %d %b %Y").unwrap(),
        t.num_hours() ,
        t.num_minutes() % 60
    );
}

fn path_exists<P: AsRef<Path>>(path: P) -> bool {
    ::std::fs::metadata(path).is_ok()
}
<commit_msg>Create timesheet file if it does not exist<commit_after>extern crate time;

use std::fs::{File, create_dir, OpenOptions, remove_file};
use std::io::{Seek, SeekFrom, BufReader, BufRead, Lines, Write};
use std::io;
use std::path::{Path, PathBuf};
use std::env::{args, home_dir};
use std::fmt;
use std::process::exit;
use time::{Duration, now_utc, Tm, empty_tm, strptime};

fn main() {
    let result = match args().nth(1) {
        None => Err(PunchClockError::NoCommandGiven),
        Some(command) => {
            let mut time_clock = TimeClock::new().unwrap();
            match &command[..] {
                "in" => time_clock.punch_in(),
                "out" => time_clock.punch_out(),
                "status" => time_clock.status(),
                "report" => time_clock.report_daily_hours(),
                _ => Err(PunchClockError::UnknownCommand)
            }
        }
    };

    if let Err(e) = result {
        println!("Error: {}", e);
        exit(1);
    }
}

#[derive(Debug)]
enum PunchClockError {
    NoCommandGiven,
    UnknownCommand,
    AlreadyPunchedIn,
    AlreadyPunchedOut,
    CorruptedTimeSheet,
    IoError(io::Error),
}

impl fmt::Display for PunchClockError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        use PunchClockError::*;
        fmt.write_str(
            match *self {
                NoCommandGiven => "No command given",
                UnknownCommand => "Unknown command",
                AlreadyPunchedIn => "You are already punched in",
                AlreadyPunchedOut => "You're not currently punched in",
                CorruptedTimeSheet => "Bad data in timesheet",
                IoError(_) => "IO error"
            }
        )
    }
}

impl From<io::Error> for PunchClockError {
    fn from(err: io::Error) -> PunchClockError {
        PunchClockError::IoError(err)
    }
}

type PunchClockResult<T> = Result<T, PunchClockError>;

struct TimeClock {
    now: Tm,
    timesheet: File,
    timesheet_path: PathBuf,
    currently_working: bool,
    state_path: PathBuf
}

impl TimeClock {
    fn new() -> PunchClockResult<TimeClock> {
        let now = now_utc();
        let home = home_dir().unwrap();
        let base_dir = home.join(Path::new(".punch"));
        let timesheet_path = base_dir.join("timesheet");
        let working_state_path = base_dir.join("state");
        if !path_exists(&base_dir) {
            try!(create_dir(&base_dir));
        }
        let timesheet = try!(OpenOptions::new().write(true).append(true)
                            .create(true).open(&timesheet_path));
        Ok(TimeClock {
            timesheet: timesheet,
            timesheet_path: timesheet_path,
            currently_working: path_exists(&working_state_path),
            state_path: working_state_path,
            now: now
        })
    }

    // commands

    fn punch_in(&mut self) -> PunchClockResult<()> {
        if self.currently_working {
            return Err(PunchClockError::AlreadyPunchedIn);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        writeln!(&mut self.timesheet, "in: {}", self.now.rfc822()).unwrap();
        self.set_current_working_state(true);
        Ok(())
    }

    fn punch_out(&mut self) -> PunchClockResult<()> {
        if !self.currently_working {
            return Err(PunchClockError::AlreadyPunchedOut);
        }
        try!(self.timesheet.seek(SeekFrom::End(0)));
        try!(writeln!(&mut self.timesheet, "out: {}", self.now.rfc822()));
        self.set_current_working_state(false);
        Ok(())
    }

    fn status(&self) -> PunchClockResult<()> {
        if self.currently_working {
            println!("You're punched in");
        } else {
            println!("You're punched out");
        }
        Ok(())
    }

    fn report_daily_hours(&mut self) -> PunchClockResult<()> {
        try!(self.timesheet.seek(SeekFrom::Start(0)));
        let buf = BufReader::new(try!(File::open(&self.timesheet_path)));
        let mut current_day = empty_tm();
        let mut time_worked_today = Duration::zero();

        for interval in IntervalIter::from_lines(buf.lines()) {
            let (start, end) = try!(interval);
            if !same_day(&start, &current_day) {
                if !time_worked_today.is_zero() {
                    print_time_worked(&time_worked_today, &current_day);
                }
                current_day = start;
                time_worked_today = Duration::zero();
            }
            time_worked_today =
                time_worked_today + (end.to_timespec() - start.to_timespec());
        }

        if !time_worked_today.is_zero() {
            print_time_worked(&time_worked_today, &current_day);
        }
        Ok(())
    }

    // aux. methods

    fn set_current_working_state(&mut self, currently_working: bool) {
        self.currently_working = currently_working;
        if currently_working {
            File::create(&self.state_path).unwrap();
        } else {
            remove_file(&self.state_path).unwrap();
        }
    }
}

struct IntervalIter {
    lines: Lines<BufReader<File>>
}

impl IntervalIter {
    fn from_lines(lines: Lines<BufReader<File>>) -> IntervalIter {
        IntervalIter {lines: lines}
    }
}

impl Iterator for IntervalIter {
    type Item = PunchClockResult<(Tm, Tm)>;
    fn next(&mut self) -> Option<PunchClockResult<(Tm, Tm)>> {

        // helper function to make error handling a bit nicer
        fn inner_unwrap<T>(x: Option<io::Result<T>>)
                -> PunchClockResult<Option<T>> {
            match x {
                None => Ok(None),
                Some(Ok(inner)) => Ok(Some(inner)),
                Some(Err(e)) => Err(PunchClockError::IoError(e))
            }
        }

        let line_1 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };
        let line_2 = match inner_unwrap(self.lines.next()) {
            Ok(l) => l,
            Err(e) => return Some(Err(e))
        };

        match (line_1, line_2) {
            (None, None) => None,
            (Some(start_line), o_end_line) => {
                if !start_line.starts_with("in: ") {
                    return Some(Err(PunchClockError::CorruptedTimeSheet));
                }
                let start = parse_time(&start_line[4..]);
                let end = match o_end_line {
                    None => now_utc(),
                    Some(end_line) => {
                        if !end_line.starts_with("out: ") {
                            return Some(Err(PunchClockError::CorruptedTimeSheet));
                        }
                        parse_time(&end_line[5..])
                    },
                };
                Some(Ok((start, end)))
            },
            _ => unreachable!() // (None, Some(l)) should not happen
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
}

fn parse_time(s: &str) -> Tm {
    strptime(&s[..s.len() - 1], "%a, %d %b %Y %T %Z").unwrap()
}

fn same_day(t1: &Tm, t2: &Tm) -> bool {
    t1.tm_year == t2.tm_year &&
    t1.tm_mon == t2.tm_mon &&
    t1.tm_mday == t2.tm_mday
}

fn print_time_worked(t: &Duration, day: &Tm) {
    println!("{}: {:>2}:{:02}",
        day.strftime("%a, %d %b %Y").unwrap(),
        t.num_hours() ,
        t.num_minutes() % 60
    );
}

fn path_exists<P: AsRef<Path>>(path: P) -> bool {
    ::std::fs::metadata(path).is_ok()
}
<|endoftext|>


<commit_before>#![feature(macro_rules, slicing_syntax, while_let, if_let, phase, globs)]

extern crate term;
#[phase(plugin, link)] extern crate log;

use lval::LVal;

mod parser;
mod lval;

fn main() {
    println!("MLisp VErsion 0.0.0.1");
    println!("Press Ctrl+c to exit");

    loop {
        print!("mlisp> ");

        let input = std::io::stdin().read_line().unwrap();
        let ast = parser::Parser::new(input[], "<input>").parse();

        let lval = LVal::from_ast(ast);

        lval.println();
    }
}<commit_msg>Detect Ctrl+d as alias for exit<commit_after>#![feature(macro_rules, slicing_syntax, while_let, if_let, phase, globs)]

extern crate term;
#[phase(plugin, link)] extern crate log;

use lval::LVal;

mod parser;
mod lval;

fn main() {
    println!("MLisp VErsion 0.0.0.1");
    println!("Press Ctrl+c to exit");

    loop {
        print!("mlisp> ");

        let input = std::io::stdin().read_line().unwrap();
        if input.as_bytes()[0] == 4 {
            break
        }

        let ast = parser::Parser::new(input[], "<input>").parse();
        let lval = LVal::from_ast(ast);

        println!("{}", lval);
    }

    println!("Exiting...")
}<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::collections;
use std::io;
use std::path;
use std::process;

use std::os::unix::fs::FileTypeExt;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] [<path>] <pattern>
    srch --help
    srch --version

Options:
    -h, --help              Show this help screen
    -v, --version           Show this program's version
    -i, --invisible         Also search inside directories starting with a . character
    -f, --filesonly         Only search filenames and NOT directory names
";

#[derive(RustcDecodable)]
struct Args {
    arg_pattern: String,
    arg_path: String,

    flag_i: bool,
    flag_invisible: bool,

    flag_f: bool,
    flag_filesonly: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .unwrap()
        .help(true)
        .version(Some(String::from("srch ") +
                      option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
        .decode()
        .unwrap_or_else(|e| e.exit());

    let dir = path::PathBuf::from(&args.arg_path);
    if args.arg_path.is_empty() {
        let curdir = path::PathBuf::from(".");
        handle(&curdir, &args);
    } else if !dir.exists() {
        println!("Invalid search path: {}",
                 Colour::Red.bold().paint(args.arg_path.as_str()));
        process::exit(1);
    } else {
        handle(&dir, &args);
    }
}

fn ignore(path: &path::PathBuf, args: &Args) -> io::Result<bool> {
    if !path.is_dir() {
        return Ok(true);
    }

    let m = try!(path.symlink_metadata()).file_type();
    if m.is_symlink() || m.is_block_device() || m.is_char_device() || m.is_fifo() || m.is_socket() {
        return Ok(true);
    }

    if args.flag_i || args.flag_invisible {
        return Ok(false);
    }

    let fname = path.file_name();
    if fname == None {
        return Ok(false);
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return Ok(true);
    }

    Ok(false)
}

trait Misc {
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if self.is_dir() {
            Ok(Colour::Purple.paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false;
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true;
        }
        false
    }
}

struct SearchResults {
    directories: i32,
    files: i32,

    scanned: i32,
    pushed: i32,
}

impl SearchResults {
    fn add(&mut self, other: SearchResults) {
        self.directories += other.directories;
        self.files += other.files;

        self.scanned += other.scanned;
        self.pushed += other.pushed;
    }
}

fn handle(path: &path::PathBuf, args: &Args) -> () {
    let mut q: collections::VecDeque<path::PathBuf> = collections::VecDeque::new();
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 1,
    };

    let pattern = &args.arg_pattern;

    println!("Searching {} for {}",
             Colour::Yellow.bold().paint(path.to_str().unwrap()),
             Colour::Green.bold().paint(pattern.as_str()));
    q.push_back(path.clone());
    while q.len() > 0 {
        let p = q.pop_front().unwrap();
        let i = ignore(&p, args);
        match i {
            Ok(tf) => {
                if tf {
                    continue;
                }
            }
            Err(_) => continue,
        };

        let r = search(&mut q, &p, pattern, args.flag_f || args.flag_filesonly);
        match r {
            Ok(n) => {
                results.add(n);
            }
            Err(_) => (),
        };
    }

    print!("Explored {} directories and searched {} objects, ",
           Colour::Yellow.bold().paint(results.pushed.to_string()),
           Colour::Yellow.bold().paint(results.scanned.to_string()));
    println!("found {} directories and {} files",
             Colour::Green.bold().paint(results.directories.to_string()),
             Colour::Green.bold().paint(results.files.to_string()));
}

fn search(q: &mut collections::VecDeque<path::PathBuf>,
          path: &path::PathBuf,
          pattern: &String,
          ignore_dirs: bool)
          -> std::io::Result<SearchResults> {
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 0,
    };

    for item in try!(path.read_dir()) {
        let f = try!(item); // f is a DirEntry
        let dir: bool;
        if f.path().is_dir() {
            results.pushed += 1;
            q.push_back(f.path());
            if ignore_dirs {
                continue;
            }
            dir = true;
            results.scanned += 1;
        } else {
            dir = false;
            results.scanned += 1;
        }

        if f.path().matches(&pattern) {
            println!("{}", try!(f.path().display_colour()));
            if dir {
                results.directories += 1;
            } else {
                results.files += 1;
            }
        }
    }

    Ok(results)
}
<commit_msg>Add additional argument parsing logic<commit_after>extern crate ansi_term;
extern crate docopt;
extern crate rustc_serialize;

use ansi_term::Colour;
use docopt::Docopt;

use std::collections;
use std::io;
use std::path;
use std::process;

use std::os::unix::fs::FileTypeExt;

const USAGE: &'static str = "
srch, a command-line file search utility written in Rust.

Usage:
    srch [options] [<path>] <pattern>
    srch --help
    srch --version

Options:
    -h, --help              Show this help screen
    -v, --version           Show this program's version
    -i, --invisible         Also search inside directories starting with a . character
    -f, --filesonly         Only search filenames and NOT directory names
";

#[derive(RustcDecodable)]
struct Args {
    arg_pattern: String,
    arg_path: String,

    flag_i: bool,
    flag_invisible: bool,

    flag_f: bool,
    flag_filesonly: bool,
}

struct Settings {
    pattern: String,
    path: String,

    invisible: bool,
    files_only: bool,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .unwrap()
        .help(true)
        .version(Some(String::from("srch ") +
                      option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")))
        .decode()
        .unwrap_or_else(|e| e.exit());

    let settings = Settings {
        pattern: args.arg_pattern,
        path: args.arg_path,
        invisible: args.flag_i || args.flag_invisible,
        files_only: args.flag_f || args.flag_filesonly,
    };

    let dir = path::PathBuf::from(&settings.path);
    if settings.path.is_empty() {
        let curdir = path::PathBuf::from(".");
        handle(&curdir, &settings);
    } else if !dir.exists() {
        println!("Invalid search path: {}",
                 Colour::Red.bold().paint(settings.path.as_str()));
        process::exit(1);
    } else {
        handle(&dir, &settings);
    }
}

fn ignore(path: &path::PathBuf, settings: &Settings) -> io::Result<bool> {
    if !path.is_dir() {
        return Ok(true);
    }

    let m = try!(path.symlink_metadata()).file_type();
    if m.is_symlink() || m.is_block_device() || m.is_char_device() || m.is_fifo() || m.is_socket() {
        return Ok(true);
    }

    if settings.invisible {
        return Ok(false);
    }

    let fname = path.file_name();
    if fname == None {
        return Ok(false);
    }

    let fname = fname.unwrap().to_str().unwrap();
    if fname.chars().next().unwrap() == '.' {
        return Ok(true);
    }

    Ok(false)
}

trait Misc {
    fn display_colour(&self) -> io::Result<String>;
    fn matches(&self, pattern: &String) -> bool;
}

impl Misc for path::PathBuf {
    fn display_colour(&self) -> io::Result<String> {
        let s: &str = self.to_str().unwrap();

        if self.is_dir() {
            Ok(Colour::Purple.paint(s).to_string())
        } else {
            Ok(s.to_string())
        }
    }

    fn matches(&self, pattern: &String) -> bool {
        let fname = self.file_name();
        if fname == None {
            return false;
        }

        let fname = fname.unwrap().to_str().unwrap().to_string();
        if fname == *pattern {
            return true;
        }
        false
    }
}

struct SearchResults {
    directories: i32,
    files: i32,

    scanned: i32,
    pushed: i32,
}

impl SearchResults {
    fn add(&mut self, other: SearchResults) {
        self.directories += other.directories;
        self.files += other.files;

        self.scanned += other.scanned;
        self.pushed += other.pushed;
    }
}

fn handle(path: &path::PathBuf, settings: &Settings) -> () {
    let mut q: collections::VecDeque<path::PathBuf> = collections::VecDeque::new();
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 1,
    };

    let pattern = &settings.pattern;

    println!("Searching {} for {}",
             Colour::Yellow.bold().paint(path.to_str().unwrap()),
             Colour::Green.bold().paint(pattern.as_str()));
    q.push_back(path.clone());
    while q.len() > 0 {
        let p = q.pop_front().unwrap();
        let i = ignore(&p, settings);
        match i {
            Ok(tf) => {
                if tf {
                    continue;
                }
            }
            Err(_) => continue,
        };

        let r = search(&mut q, &p, pattern, settings.files_only);
        match r {
            Ok(n) => {
                results.add(n);
            }
            Err(_) => (),
        };
    }

    print!("Explored {} directories and searched {} objects, ",
           Colour::Yellow.bold().paint(results.pushed.to_string()),
           Colour::Yellow.bold().paint(results.scanned.to_string()));
    println!("found {} directories and {} files",
             Colour::Green.bold().paint(results.directories.to_string()),
             Colour::Green.bold().paint(results.files.to_string()));
}

fn search(q: &mut collections::VecDeque<path::PathBuf>,
          path: &path::PathBuf,
          pattern: &String,
          ignore_dirs: bool)
          -> std::io::Result<SearchResults> {
    let mut results = SearchResults {
        directories: 0,
        files: 0,
        scanned: 0,
        pushed: 0,
    };

    for item in try!(path.read_dir()) {
        let f = try!(item); // f is a DirEntry
        let dir: bool;
        if f.path().is_dir() {
            results.pushed += 1;
            q.push_back(f.path());
            if ignore_dirs {
                continue;
            }
            dir = true;
            results.scanned += 1;
        } else {
            dir = false;
            results.scanned += 1;
        }

        if f.path().matches(&pattern) {
            println!("{}", try!(f.path().display_colour()));
            if dir {
                results.directories += 1;
            } else {
                results.files += 1;
            }
        }
    }

    Ok(results)
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>parse ip address<commit_after>extern crate getopts;

use getopts::Options;
use std::os;
use std::net::{SocketAddr};
use std::str::FromStr;

fn main() {
    let args: Vec<String> = os::args();
    let mut opts = Options::new();
    let matches = match opts.parse(args.tail()) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };
    let addr_arg = matches.free[0].as_slice();
    let addr:SocketAddr = FromStr::from_str(addr_arg.as_slice()).unwrap();
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate x11;

extern crate lanta;

use std::process::Command;

use lanta::cmd;
use lanta::RustWindowManager;
use lanta::groups::GroupBuilder;
use lanta::keys::ModKey;
use lanta::layout::{StackLayout, TiledLayout};
use x11::keysym;

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

    let modkey = ModKey::Control;
    let shift = ModKey::Shift;
    let mut keys =
        vec![(vec![modkey], keysym::XK_w, cmd::lazy::close_focused_window()),
             (vec![modkey], keysym::XK_j, cmd::lazy::focus_next()),
             (vec![modkey], keysym::XK_k, cmd::lazy::focus_previous()),
             (vec![modkey, shift], keysym::XK_j, cmd::lazy::shuffle_next()),
             (vec![modkey, shift], keysym::XK_k, cmd::lazy::shuffle_previous()),
             (vec![modkey], keysym::XK_Tab, cmd::lazy::layout_next()),
             (vec![modkey], keysym::XK_q, cmd::lazy::spawn(Command::new("change-wallpaper"))),
             (vec![modkey], keysym::XK_Return, cmd::lazy::spawn(Command::new("urxvt"))),
             (vec![modkey], keysym::XK_c, cmd::lazy::spawn(Command::new("chrome"))),
             (vec![modkey], keysym::XK_v, cmd::lazy::spawn(Command::new("code")))];

    let layouts = vec![StackLayout::new("stack".to_owned()),
                       TiledLayout::new("tiled".to_owned())];

    let group_metadata = vec![(keysym::XK_a, "chrome", "stack"),
                              (keysym::XK_s, "code", "stack"),
                              (keysym::XK_d, "term", "tiled"),
                              (keysym::XK_f, "misc", "tiled")];
    let groups: Vec<GroupBuilder> = group_metadata
        .into_iter()
        .map(|(key, name, default_layout_name)| {
                 keys.push((vec![modkey], key, cmd::lazy::switch_group(name)));
                 keys.push((vec![modkey, ModKey::Shift],
                            key,
                            cmd::lazy::move_window_to_group(name)));

                 GroupBuilder::new(name.to_owned(), default_layout_name.to_owned())
             })
        .collect();

    let mut wm = RustWindowManager::new(keys, groups, layouts).unwrap();
    wm.run_event_loop();
}
<commit_msg>Use Mod4 by default again.<commit_after>extern crate env_logger;
extern crate x11;

extern crate lanta;

use std::process::Command;

use lanta::cmd;
use lanta::RustWindowManager;
use lanta::groups::GroupBuilder;
use lanta::keys::ModKey;
use lanta::layout::{StackLayout, TiledLayout};
use x11::keysym;

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

    let modkey = ModKey::Mod4;
    let shift = ModKey::Shift;
    let mut keys =
        vec![(vec![modkey], keysym::XK_w, cmd::lazy::close_focused_window()),
             (vec![modkey], keysym::XK_j, cmd::lazy::focus_next()),
             (vec![modkey], keysym::XK_k, cmd::lazy::focus_previous()),
             (vec![modkey, shift], keysym::XK_j, cmd::lazy::shuffle_next()),
             (vec![modkey, shift], keysym::XK_k, cmd::lazy::shuffle_previous()),
             (vec![modkey], keysym::XK_Tab, cmd::lazy::layout_next()),
             (vec![modkey], keysym::XK_q, cmd::lazy::spawn(Command::new("change-wallpaper"))),
             (vec![modkey], keysym::XK_Return, cmd::lazy::spawn(Command::new("urxvt"))),
             (vec![modkey], keysym::XK_c, cmd::lazy::spawn(Command::new("chrome"))),
             (vec![modkey], keysym::XK_v, cmd::lazy::spawn(Command::new("code")))];

    let layouts = vec![StackLayout::new("stack".to_owned()),
                       TiledLayout::new("tiled".to_owned())];

    let group_metadata = vec![(keysym::XK_a, "chrome", "stack"),
                              (keysym::XK_s, "code", "stack"),
                              (keysym::XK_d, "term", "tiled"),
                              (keysym::XK_f, "misc", "tiled")];
    let groups: Vec<GroupBuilder> = group_metadata
        .into_iter()
        .map(|(key, name, default_layout_name)| {
                 keys.push((vec![modkey], key, cmd::lazy::switch_group(name)));
                 keys.push((vec![modkey, ModKey::Shift],
                            key,
                            cmd::lazy::move_window_to_group(name)));

                 GroupBuilder::new(name.to_owned(), default_layout_name.to_owned())
             })
        .collect();

    let mut wm = RustWindowManager::new(keys, groups, layouts).unwrap();
    wm.run_event_loop();
}
<|endoftext|>


<commit_before>#![allow(unused_features)] // so we can still feature(os) when testing
#![feature(collections, path, io, core, os, plugin)]
extern crate getopts;

use getopts::Options;
use std::os;

mod elem;
mod parser;
mod error;
mod database;
mod mass;
mod balance;

const USAGE: &'static str = "\
Usage:
    chemtool <formula>... [options]
    chemtool [-h | --help]
    chemtool [-v | --version]";

const VERSION: &'static str = "chemtool 0.2.1";

#[cfg(not(test))]
fn main() {
    let args = os::args();
    let mut opts = Options::new();
    opts.optflag("h", "help", "Display this message and then exit.");
    opts.optflag("v", "version", "Display the version number and then exit.");
    opts.optopt("", "db-path", "Explicitly specify the path to the database file.", "PATH");
    let given_opts = match opts.parse(args.tail()) {
        Ok(go) => go,
        Err(msg) => {
            println!("{}", msg.to_string());
            println!("{}", opts.usage(USAGE));
            return;
        },
    };
    if given_opts.opt_present("help") {
        println!("{}", opts.usage(USAGE));
    } else if given_opts.opt_present("version") {
        println!("{}", VERSION);
    } else {
        let path = if let Some(path) = given_opts.opt_str("db-path") {
            Path::new(path)
        } else {
            let mut path = Path::new(&args[0]);
            path.set_filename("elemdb.csv");
            path
        };
        if given_opts.free.len() > 0 {
            let input = given_opts.free[0].as_slice();
            if let Err(e) = mass::pretty_print_mass(input, &path) {
                e.print(input);
            }
        } else {
            println!("Missing formula to parse.");
            println!("{}", opts.usage(USAGE));
        }
    }
}<commit_msg>Make the balancer usable by the user<commit_after>#![allow(unused_features)] // so we can still feature(os) when testing
#![feature(collections, path, io, core, os, plugin)]
extern crate getopts;

use getopts::{Options, Matches};
use std::os;
use parser::Parser;

mod elem;
mod parser;
mod error;
mod database;
mod mass;
mod balance;

const USAGE: &'static str = "\
Usage:
    chemtool mass <formula> [options]
    chemtool balance <reaction> [options]
    chemtool [-h | --help]
    chemtool [-v | --version]";

const VERSION: &'static str = "chemtool 0.2.1";

#[cfg(not(test))]
fn main() {
    let args = os::args();
    let mut opts = Options::new();
    opts.optflag("h", "help", "Display this message and then exit.");
    opts.optflag("v", "version", "Display the version number and then exit.");
    opts.optopt("", "db-path", "Explicitly specify the path to the database file.", "PATH");
    let given_opts = match opts.parse(args.tail()) {
        Ok(go) => go,
        Err(msg) => {
            println!("{}", msg.to_string());
            println!("{}", opts.usage(USAGE));
            return;
        },
    };
    if given_opts.opt_present("help") {
        println!("{}", opts.usage(USAGE));
    } else if given_opts.opt_present("version") {
        println!("{}", VERSION);
    } else {
        let path = if let Some(path) = given_opts.opt_str("db-path") {
            Path::new(path)
        } else {
            let mut path = Path::new(&args[0]);
            path.set_filename("elemdb.csv");
            path
        };
        if given_opts.free.len() > 0 {
            let cmd = &given_opts.free[0];
            let args = given_opts.free.tail();
            match cmd.as_slice() {
                "mass" => mass_cmd(&args, &opts, &path),
                "balance" => balance_cmd(&args, &opts),
                _ => {
                    println!("Invalid command");
                    println!("{}", opts.usage(USAGE));
                }
            }
        } else {
            println!("Missing command.");
            println!("{}", opts.usage(USAGE));
        }
    }
}

fn mass_cmd(args: &[String], opts: &Options, db_path: &Path) {
    if args.len() < 1 {
        println!("Missing formula.");
        println!("{}", opts.usage(USAGE));
    } else if args.len() > 1 {
        println!("Too many arguments.");
        println!("{}", opts.usage(USAGE));
    } else {
        let formula = args[0].as_slice();
        if let Err(e) = mass::pretty_print_mass(formula, &db_path) {
            e.print(formula);
        }
    }
}

fn balance_cmd(args: &[String], opts: &Options) {
    if args.len() < 1 {
        println!("Missing reaction.");
        println!("{}", opts.usage(USAGE));
    } else if args.len() > 1 {
        println!("Too many arguments.");
        println!("{}", opts.usage(USAGE));
    } else {
        let input = args[0].as_slice();
        let mut parser = Parser::new(input);
        let reaction = match parser.parse_reaction() {
            Ok(r) => r,
            Err(e) => {
                e.print(input);
                return;
            }
        };
        let coefs = match balance::balance_reaction(&reaction) {
            Ok(c) => c,
            Err(e) => {
                e.print(input);
                return;
            }
        };
        balance::pretty_print_balanced(&reaction, &coefs);
    }
}<|endoftext|>


<commit_before>#[macro_use]
extern crate imgui;

extern crate mush;
use mush::interface::Interface;
use mush::file::FileState;
use mush::app::AppState;

use std::time::{Duration,Instant};
use std::thread;

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.006, 0.006, 0.006, 1.0);

/// represents 15ms as nanos
static FPS_60: u32 = 15000000;

fn main() {
    let mut ifc = Interface::init();
    let mut app = AppState::default();
    let mut file = FileState::default();

    loop {
        let start_time = Instant::now();

        let r = ifc.render(CLEAR_COLOR, |ui| {
            app.render(ui);
            file.render(ui, &mut app);
        });
        if !r | app.exit{ break }

        maybe_sleep(start_time); // we must manage sleep if we run too fast
    }
}

fn maybe_sleep(start_time: Instant) {
    let duration = Duration::new(0,FPS_60);
    if start_time.elapsed() < duration {
        let delay = duration - start_time.elapsed();
        thread::sleep(delay);
    }
}
<commit_msg>add examples<commit_after>#[macro_use]
extern crate imgui;

extern crate mush;
use mush::interface::Interface;
use mush::file::FileState;
use mush::app::AppState;

use std::time::{Duration,Instant};
use std::thread;

const CLEAR_COLOR: (f32, f32, f32, f32) = (0.006, 0.006, 0.006, 1.0);

/// represents 15ms as nanos
static FPS_60: u32 = 15000000;

fn main() {
    let mut ifc = Interface::init();
    let mut app = AppState::default();
    let mut file = FileState::default();

    loop {
        let start_time = Instant::now();

        let r = ifc.render(CLEAR_COLOR, |ui| {
            app.render(ui);
            file.render(ui, &mut app);

            // ui.show_test_window(&mut true) // NOTE: use for imgui examples
        });
        if !r | app.exit{ break }

        maybe_sleep(start_time); // we must manage sleep if we run too fast
    }
}

fn maybe_sleep(start_time: Instant) {
    let duration = Duration::new(0,FPS_60);
    if start_time.elapsed() < duration {
        let delay = duration - start_time.elapsed();
        thread::sleep(delay);
    }
}
<|endoftext|>


<commit_before>extern mod sdl2;

use mem::Mem;
use std::io::stdio;

mod cartridge;
mod cpu;
mod debug;
mod disasm;
mod interrupt;
mod joypad;
mod mem;
mod ram;
mod serial;
mod sound;
mod timer;
mod video;

//
// Memory Map
//

struct Dummy;
impl Mem for Dummy {
  fn loadb(&mut self, addr: u16) -> u8 {
    //debug!("load in unmapped memory at 0x{:04X}", addr);
    0xff
  }

  fn storeb(&mut self, addr: u16, val: u8) {
    //debug!("store in unmapped memory at 0x{:04X}", addr);
  }
}

struct MemMap {
  cart: ~cartridge::Cartridge,
  wram: ram::WorkRam,
  timer: timer::Timer,
  intr: interrupt::InterruptCtrl,
  sound: sound::Sound,
  video: video::Video,
  serial: serial::SerialIO,
  joypad: joypad::Joypad,
  dummy: Dummy,
}

impl MemMap {
  fn mem_from_addr<'a>(&'a mut self, addr: u16) -> &'a mut Mem {
    match addr {
      0x0000..0x7fff | // ROM banks
      0xa000..0xbfff   // External RAM
                      => &mut *self.cart as &mut Mem,
      0x8000..0x9fff | // VRAM
      0xfe00..0xfe9f | // OAM
      0xff40..0xff4b   // Video I/O
                      => &mut self.video as &mut Mem,
      0xc000..0xfdff | // WRAM (including echo area 0xe000-0xfdff)
      0xff80..0xfffe   // HRAM
                      => &mut self.wram as &mut Mem,
      0xff00          => &mut self.joypad as &mut Mem,
      0xff01..0xff02  => &mut self.serial as &mut Mem,
      0xff04..0xff07  => &mut self.timer as &mut Mem,
      0xff0f | 0xffff => &mut self.intr as &mut Mem,
      0xff10..0xff3f  => &mut self.sound as &mut Mem,
      _ => &mut self.dummy as &mut Mem,
      //_ => fail!("unmapped memory at 0x{:04X}", addr),
    }
  }
}

impl Mem for MemMap {
  fn loadb(&mut self, addr: u16) -> u8 {
    self.mem_from_addr(addr).loadb(addr)
  }

  fn storeb(&mut self, addr: u16, val: u8) {
    self.mem_from_addr(addr).storeb(addr, val)
  }
}

//
// Video Output
//

struct VideoOut {
  renderer: ~sdl2::render::Renderer,
  texture: ~sdl2::render::Texture,
}

impl VideoOut {
  fn new(scale: int) -> VideoOut {
    use sdl2::render::Renderer;

    sdl2::init([sdl2::InitVideo]);

    let window_width = video::SCREEN_WIDTH as int * scale;
    let window_height = video::SCREEN_HEIGHT as int * scale;

    let renderer = match Renderer::new_with_window(window_width,
                                                   window_height,
                                                   [sdl2::video::Resizable]) {
      Ok(renderer) => renderer,
      Err(err) => fail!("Failed to create renderer: {}", err)
    };

    let texture = match renderer.create_texture(sdl2::pixels::ARGB8888,
                                                sdl2::render::AccessStreaming,
                                                video::SCREEN_WIDTH as int,
                                                video::SCREEN_HEIGHT as int) {
      Ok(texture) => texture,
      Err(err) => fail!("Failed to create texture: {}", err),
    };

    VideoOut { renderer: renderer, texture: texture }
  }

  fn blit_and_present(&self, pixels: &[u8]) {
    self.texture.update(None, pixels, (video::SCREEN_WIDTH * 4) as int);
    self.renderer.copy(self.texture, None, None);
    self.renderer.present();
  }

  fn set_title(&self, title: &str) {
    match self.renderer.parent {
      sdl2::render::Window(ref w) => w.set_title(title),
      _ => (),
    }
  }
}

fn keymap(code: sdl2::keycode::KeyCode) -> Option<joypad::Button> {
  match code {
    sdl2::keycode::UpKey     => Some(joypad::Up),
    sdl2::keycode::DownKey   => Some(joypad::Down),
    sdl2::keycode::LeftKey   => Some(joypad::Left),
    sdl2::keycode::RightKey  => Some(joypad::Right),
    sdl2::keycode::ReturnKey => Some(joypad::Start),
    sdl2::keycode::RShiftKey => Some(joypad::Select),
    sdl2::keycode::CKey      => Some(joypad::ButtonA),
    sdl2::keycode::XKey      => Some(joypad::ButtonB),
    _ => None,
  }
}

fn main() {
  let args = std::os::args();
  if args.len() != 2 && !(args.len() == 3 && args[1] == ~"-d") {
    println!("Usage: {:s} [-d] rom.gb", args[0]);
    return;
  }

  let mut disassemble = false;
  let path =
    if args.len() == 2 {
      args[1]
    } else {
      disassemble = true;
      args[2]
    };

  let mut cart = match cartridge::Cartridge::from_path(&Path::new(path)) {
    Ok(cart) => ~cart,
    Err(e)   => fail!("I/O error: {:s}", e.to_str()),
  };

  if disassemble {
    // Disassemble only
    let mut d = disasm::Disasm { mem: &mut *cart, pc: 0 };
    while d.pc <= 0x7fff {
      let pc = d.pc;
      println!("${:04X}\t{:s}", pc, cpu::decode(&mut d));
    }
    return;
  }

  println!("Name: {:s}", cart.title);
  println!("Type: {:u}", cart.cartridge_type);

  let memmap = MemMap {
    cart: cart,
    wram: ram::WorkRam::new(),
    timer: timer::Timer::new(),
    intr: interrupt::InterruptCtrl::new(),
    sound: sound::Sound,
    video: video::Video::new(),
    serial: serial::SerialIO::new(Some(~stdio::stdout() as ~std::io::Writer)),
    joypad: joypad::Joypad::new(),
    dummy: Dummy,
  };
  let mut cpu = cpu::Cpu::new(memmap);
  cpu.regs.pc = 0x100;

  let video_out = VideoOut::new(4);
  video_out.set_title("Rustboy");

  let mut done = false;
  let mut running = false;
  let mut debugger = debug::Debugger::new();

  let counts_per_sec = sdl2::timer::get_performance_frequency();
  let counts_per_frame = counts_per_sec * video::SCREEN_REFRESH_CYCLES as u64 / cpu::CYCLES_PER_SEC as u64;
  let mut last_frame_start_count = sdl2::timer::get_performance_counter();

  println!("c/s: {:u}; c/f: {:u}", counts_per_sec, counts_per_frame);

  while !done {
    if running {
      if debugger.should_break(&cpu) {
        running = false;
      }
    }

    if !running {
      match debugger.prompt(&mut cpu) {
        debug::Quit => break,
        debug::Run  => running = true,
        debug::Step => (),
      }
    }

    let cycles = cpu.step();

    match cpu.mem.timer.tick(cycles) {
      Some(timer::TIMAOverflow) => cpu.mem.intr.irq(interrupt::IRQ_TIMER),
      None => (),
    }

    let mut new_frame = false;
    match cpu.mem.video.tick(cycles) {
      Some(video::DMA(base)) => {
        // Do DMA transfer instantaneously
        let base_addr = base as u16 << 8;
        for offset in range(0x00u16, 0xa0u16) {
          let val = cpu.mem.loadb(base_addr + offset);
          cpu.mem.storeb(0xfe00 + offset, val);
        }
      },
      Some(video::VBlank) => {
        video_out.blit_and_present(cpu.mem.video.screen);
        cpu.mem.intr.irq(interrupt::IRQ_VBLANK);
        new_frame = true;
      }
      Some(video::LCD)    => cpu.mem.intr.irq(interrupt::IRQ_LCD),
      None => (),
    }

    // Synchronize speed based on frame time
    if new_frame {
      let now = sdl2::timer::get_performance_counter();
      let frame_time = now - last_frame_start_count;
      if frame_time < counts_per_frame {
        let delay_msec = (1_000 * (counts_per_frame - frame_time) / counts_per_sec) as uint;
        sdl2::timer::delay(delay_msec);
      }
      // TODO: What should we do when we take longer than counts_per_frame?
      last_frame_start_count = sdl2::timer::get_performance_counter();
    }

    loop {
      match sdl2::event::poll_event() {
        sdl2::event::QuitEvent(_) => { done = true; break }
        sdl2::event::KeyDownEvent(_, _, key, _, _) => {
          match keymap(key) {
            Some(button) => cpu.mem.joypad.set_button(button, true),
            None => {
              match key {
                sdl2::keycode::EscapeKey => { running = false },
                _ => (),
              }
            }
          }
        },
        sdl2::event::KeyUpEvent(_, _, key, _, _) => {
          match keymap(key) {
            Some(button) => cpu.mem.joypad.set_button(button, false),
            None => (),
          }
        }
        sdl2::event::NoEvent => break,
        _ => (),
      }
    }
  }
}
<commit_msg>Added frames/second counter<commit_after>extern mod sdl2;

use mem::Mem;
use std::io::stdio;

mod cartridge;
mod cpu;
mod debug;
mod disasm;
mod interrupt;
mod joypad;
mod mem;
mod ram;
mod serial;
mod sound;
mod timer;
mod video;

//
// Memory Map
//

struct Dummy;
impl Mem for Dummy {
  fn loadb(&mut self, addr: u16) -> u8 {
    //debug!("load in unmapped memory at 0x{:04X}", addr);
    0xff
  }

  fn storeb(&mut self, addr: u16, val: u8) {
    //debug!("store in unmapped memory at 0x{:04X}", addr);
  }
}

struct MemMap {
  cart: ~cartridge::Cartridge,
  wram: ram::WorkRam,
  timer: timer::Timer,
  intr: interrupt::InterruptCtrl,
  sound: sound::Sound,
  video: video::Video,
  serial: serial::SerialIO,
  joypad: joypad::Joypad,
  dummy: Dummy,
}

impl MemMap {
  fn mem_from_addr<'a>(&'a mut self, addr: u16) -> &'a mut Mem {
    match addr {
      0x0000..0x7fff | // ROM banks
      0xa000..0xbfff   // External RAM
                      => &mut *self.cart as &mut Mem,
      0x8000..0x9fff | // VRAM
      0xfe00..0xfe9f | // OAM
      0xff40..0xff4b   // Video I/O
                      => &mut self.video as &mut Mem,
      0xc000..0xfdff | // WRAM (including echo area 0xe000-0xfdff)
      0xff80..0xfffe   // HRAM
                      => &mut self.wram as &mut Mem,
      0xff00          => &mut self.joypad as &mut Mem,
      0xff01..0xff02  => &mut self.serial as &mut Mem,
      0xff04..0xff07  => &mut self.timer as &mut Mem,
      0xff0f | 0xffff => &mut self.intr as &mut Mem,
      0xff10..0xff3f  => &mut self.sound as &mut Mem,
      _ => &mut self.dummy as &mut Mem,
      //_ => fail!("unmapped memory at 0x{:04X}", addr),
    }
  }
}

impl Mem for MemMap {
  fn loadb(&mut self, addr: u16) -> u8 {
    self.mem_from_addr(addr).loadb(addr)
  }

  fn storeb(&mut self, addr: u16, val: u8) {
    self.mem_from_addr(addr).storeb(addr, val)
  }
}

//
// Video Output
//

struct VideoOut {
  renderer: ~sdl2::render::Renderer,
  texture: ~sdl2::render::Texture,
}

impl VideoOut {
  fn new(scale: int) -> VideoOut {
    use sdl2::render::Renderer;

    sdl2::init([sdl2::InitVideo]);

    let window_width = video::SCREEN_WIDTH as int * scale;
    let window_height = video::SCREEN_HEIGHT as int * scale;

    let renderer = match Renderer::new_with_window(window_width,
                                                   window_height,
                                                   [sdl2::video::Resizable]) {
      Ok(renderer) => renderer,
      Err(err) => fail!("Failed to create renderer: {}", err)
    };

    let texture = match renderer.create_texture(sdl2::pixels::ARGB8888,
                                                sdl2::render::AccessStreaming,
                                                video::SCREEN_WIDTH as int,
                                                video::SCREEN_HEIGHT as int) {
      Ok(texture) => texture,
      Err(err) => fail!("Failed to create texture: {}", err),
    };

    VideoOut { renderer: renderer, texture: texture }
  }

  fn blit_and_present(&self, pixels: &[u8]) {
    self.texture.update(None, pixels, (video::SCREEN_WIDTH * 4) as int);
    self.renderer.copy(self.texture, None, None);
    self.renderer.present();
  }

  fn set_title(&self, title: &str) {
    match self.renderer.parent {
      sdl2::render::Window(ref w) => w.set_title(title),
      _ => (),
    }
  }
}

fn keymap(code: sdl2::keycode::KeyCode) -> Option<joypad::Button> {
  match code {
    sdl2::keycode::UpKey     => Some(joypad::Up),
    sdl2::keycode::DownKey   => Some(joypad::Down),
    sdl2::keycode::LeftKey   => Some(joypad::Left),
    sdl2::keycode::RightKey  => Some(joypad::Right),
    sdl2::keycode::ReturnKey => Some(joypad::Start),
    sdl2::keycode::RShiftKey => Some(joypad::Select),
    sdl2::keycode::CKey      => Some(joypad::ButtonA),
    sdl2::keycode::XKey      => Some(joypad::ButtonB),
    _ => None,
  }
}

fn main() {
  let args = std::os::args();
  if args.len() != 2 && !(args.len() == 3 && args[1] == ~"-d") {
    println!("Usage: {:s} [-d] rom.gb", args[0]);
    return;
  }

  let mut disassemble = false;
  let path =
    if args.len() == 2 {
      args[1]
    } else {
      disassemble = true;
      args[2]
    };

  let mut cart = match cartridge::Cartridge::from_path(&Path::new(path)) {
    Ok(cart) => ~cart,
    Err(e)   => fail!("I/O error: {:s}", e.to_str()),
  };

  if disassemble {
    // Disassemble only
    let mut d = disasm::Disasm { mem: &mut *cart, pc: 0 };
    while d.pc <= 0x7fff {
      let pc = d.pc;
      println!("${:04X}\t{:s}", pc, cpu::decode(&mut d));
    }
    return;
  }

  println!("Name: {:s}", cart.title);
  println!("Type: {:u}", cart.cartridge_type);

  let memmap = MemMap {
    cart: cart,
    wram: ram::WorkRam::new(),
    timer: timer::Timer::new(),
    intr: interrupt::InterruptCtrl::new(),
    sound: sound::Sound,
    video: video::Video::new(),
    serial: serial::SerialIO::new(Some(~stdio::stdout() as ~std::io::Writer)),
    joypad: joypad::Joypad::new(),
    dummy: Dummy,
  };
  let mut cpu = cpu::Cpu::new(memmap);
  cpu.regs.pc = 0x100;

  let video_out = VideoOut::new(4);
  video_out.set_title("Rustboy");

  let mut done = false;
  let mut running = false;
  let mut debugger = debug::Debugger::new();

  let counts_per_sec = sdl2::timer::get_performance_frequency();
  let counts_per_frame = counts_per_sec * video::SCREEN_REFRESH_CYCLES as u64 / cpu::CYCLES_PER_SEC as u64;
  let mut last_frame_start_count = sdl2::timer::get_performance_counter();

  let mut last_fps_update = last_frame_start_count;
  let mut frames = 0;

  println!("c/s: {:u}; c/f: {:u}", counts_per_sec, counts_per_frame);

  while !done {
    if running {
      if debugger.should_break(&cpu) {
        running = false;
      }
    }

    if !running {
      match debugger.prompt(&mut cpu) {
        debug::Quit => break,
        debug::Run  => running = true,
        debug::Step => (),
      }
    }

    let cycles = cpu.step();

    match cpu.mem.timer.tick(cycles) {
      Some(timer::TIMAOverflow) => cpu.mem.intr.irq(interrupt::IRQ_TIMER),
      None => (),
    }

    let mut new_frame = false;
    match cpu.mem.video.tick(cycles) {
      Some(video::DMA(base)) => {
        // Do DMA transfer instantaneously
        let base_addr = base as u16 << 8;
        for offset in range(0x00u16, 0xa0u16) {
          let val = cpu.mem.loadb(base_addr + offset);
          cpu.mem.storeb(0xfe00 + offset, val);
        }
      },
      Some(video::VBlank) => {
        video_out.blit_and_present(cpu.mem.video.screen);
        cpu.mem.intr.irq(interrupt::IRQ_VBLANK);
        new_frame = true;
      }
      Some(video::LCD)    => cpu.mem.intr.irq(interrupt::IRQ_LCD),
      None => (),
    }

    // Synchronize speed based on frame time
    if new_frame {
      let now = sdl2::timer::get_performance_counter();

      frames += 1;
      if now - last_fps_update > counts_per_sec {
        let fps = frames * (now - last_fps_update) / counts_per_sec;
        video_out.set_title(format!("Rustboy - {} fps", fps));
        last_fps_update = now;
        frames = 0;
      }

      let frame_time = now - last_frame_start_count;
      if frame_time < counts_per_frame {
        let delay_msec = (1_000 * (counts_per_frame - frame_time) / counts_per_sec) as uint;
        sdl2::timer::delay(delay_msec);
      }
      // TODO: What should we do when we take longer than counts_per_frame?
      last_frame_start_count = sdl2::timer::get_performance_counter();
    }

    loop {
      match sdl2::event::poll_event() {
        sdl2::event::QuitEvent(_) => { done = true; break }
        sdl2::event::KeyDownEvent(_, _, key, _, _) => {
          match keymap(key) {
            Some(button) => cpu.mem.joypad.set_button(button, true),
            None => {
              match key {
                sdl2::keycode::EscapeKey => { running = false },
                _ => (),
              }
            }
          }
        },
        sdl2::event::KeyUpEvent(_, _, key, _, _) => {
          match keymap(key) {
            Some(button) => cpu.mem.joypad.set_button(button, false),
            None => (),
          }
        }
        sdl2::event::NoEvent => break,
        _ => (),
      }
    }
  }
}
<|endoftext|>


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

use docopt::Docopt;

use iron::mime::Mime;
use iron::prelude::*;
use iron::status;

static USAGE: &'static str = "
Usage: rustwarsaw [options]

Options:
    -p <port>, --port <port>  Port number [default: 3000]
    -h, --help  Show help and exit
";

#[derive(RustcDecodable)]
struct Args {
    flag_port: u16,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).decode())
        .unwrap_or_else(|e| e.exit());
    println!("Starting server on port {}", args.flag_port);
    Iron::new(|_: &mut Request| {
        let content_type: Mime = "text/html".parse().unwrap();
        Ok(Response::with((status::Ok, "Hello Rust Warsaw!")).set(content_type))
    }).http(("127.0.0.1", args.flag_port)).unwrap();
}
<commit_msg>Moved hello handler to a regular function.<commit_after>extern crate docopt;
extern crate iron;
extern crate rustc_serialize;

use docopt::Docopt;

use iron::mime::Mime;
use iron::prelude::*;
use iron::status;

static USAGE: &'static str = "
Usage: rustwarsaw [options]

Options:
    -p <port>, --port <port>  Port number [default: 3000]
    -h, --help  Show help and exit
";

#[derive(RustcDecodable)]
struct Args {
    flag_port: u16,
}

fn hello(_: &mut Request) -> IronResult<Response> {
    let content_type: Mime = "text/html".parse().unwrap();
    Ok(Response::with((status::Ok, "Hello Rust Warsaw!")).set(content_type))
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.help(true).decode())
        .unwrap_or_else(|e| e.exit());
    println!("Starting server on port {}", args.flag_port);
    Iron::new(hello).http(("127.0.0.1", args.flag_port)).unwrap();
}
<|endoftext|>


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

use docopt::Docopt;
pub use time::Timespec;
pub use conductor::{Item, ItemId, ItemSchedData};

use conductor::Conductor;

mod conductor;
mod core;
mod persist;
mod fuzzy;

static USAGE: &'static str = "
Usage:
  hippo review [<N> | --id=<id>]
  hippo add <description>
  hippo edit <id> <description>
  hippo view <id>
  hippo remove <id>
  hippo list [--unreviewed --fuzzy] [<string>]
  hippo (-h | --help)

Options:
  -h, --help    Show this screen.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_description: Option<String>,
    arg_id: Option<String>,
    arg_N: Option<String>,
    arg_string: Option<String>,
    flag_id: Option<String>,
    flag_unreviewed: bool,
    flag_fuzzy: bool,
    cmd_add: bool,
    cmd_edit: bool,
    cmd_view: bool,
    cmd_remove: bool,
    cmd_list: bool,
    cmd_review: bool,
}

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

    let default_review_num = 20;

    let cond = Conductor::new();

    if args.cmd_add {
        let desc_string = args.arg_description.unwrap();
        let desc = desc_string.as_slice();
        cond.add_item(desc);

    } else if args.cmd_edit {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        let desc_string = args.arg_description.unwrap();
        let desc = desc_string.as_slice();
        cond.edit_item(id, desc);

    } else if args.cmd_view {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        cond.view_item(id);

    } else if args.cmd_remove {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        cond.remove_item(id);

    } else if args.cmd_list {
        cond.list_items(args.arg_string, args.flag_unreviewed, args.flag_fuzzy);

    } else if args.cmd_review {
        match args.arg_N {
            Some(n) => cond.review(n.as_slice().parse().unwrap()),
            None =>
                match args.flag_id {
                    Some(id) => cond.review_item(id.as_slice().parse().unwrap()),
                    None     => cond.review(default_review_num),
                }
        }

    } else {
        println!("No command provided");
    }
}
<commit_msg>Convert a few uses of as_slice() to [..]<commit_after>extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;
extern crate rusqlite;
extern crate time;

use docopt::Docopt;
pub use time::Timespec;
pub use conductor::{Item, ItemId, ItemSchedData};

use conductor::Conductor;

mod conductor;
mod core;
mod persist;
mod fuzzy;

static USAGE: &'static str = "
Usage:
  hippo review [<N> | --id=<id>]
  hippo add <description>
  hippo edit <id> <description>
  hippo view <id>
  hippo remove <id>
  hippo list [--unreviewed --fuzzy] [<string>]
  hippo (-h | --help)

Options:
  -h, --help    Show this screen.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_description: Option<String>,
    arg_id: Option<String>,
    arg_N: Option<String>,
    arg_string: Option<String>,
    flag_id: Option<String>,
    flag_unreviewed: bool,
    flag_fuzzy: bool,
    cmd_add: bool,
    cmd_edit: bool,
    cmd_view: bool,
    cmd_remove: bool,
    cmd_list: bool,
    cmd_review: bool,
}

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

    let default_review_num = 20;

    let cond = Conductor::new();

    if args.cmd_add {
        let desc_string = args.arg_description.unwrap();
        let desc = &desc_string[..];
        cond.add_item(desc);

    } else if args.cmd_edit {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        let desc_string = args.arg_description.unwrap();
        let desc = &desc_string[..];
        cond.edit_item(id, desc);

    } else if args.cmd_view {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        cond.view_item(id);

    } else if args.cmd_remove {
        let id = args.arg_id.unwrap().as_slice().parse().unwrap();
        cond.remove_item(id);

    } else if args.cmd_list {
        cond.list_items(args.arg_string, args.flag_unreviewed, args.flag_fuzzy);

    } else if args.cmd_review {
        match args.arg_N {
            Some(n) => cond.review(n.as_slice().parse().unwrap()),
            None =>
                match args.flag_id {
                    Some(id) => cond.review_item(id.as_slice().parse().unwrap()),
                    None     => cond.review(default_review_num),
                }
        }

    } else {
        println!("No command provided");
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::str;
use std::path::Path;
use std::char;

/*
vector: 10101010
key:    0111111101

byte 1: 00000001  -> 11110100
byte 2: 00100011  -> 00001011

plain                cipher
00000001 00100011 -> 11110100 00001011

% cargo run [-d] <init_key> <init_vector> <original_file> <result_file>
cargo run -d 0111111101 10101010 file1 file2 //decrypts

*/

struct Crypto {
    flag: char,
    init_key: u16,
    init_vec: u8,
    init_key_str: String,
    init_vec_str: String,
    original_file: String,
    output_file: String
}

fn check_flag(index: usize) -> bool
{
    let flag = env::args().nth(index).unwrap();
    match flag.as_ref() {
        "d" => true,
        _ => {
            println!("incorrect flag");
            false
        }
    }
}

fn check_key(index: usize) -> bool
{
    let key = env::args().nth(index).unwrap();
    let key_len = key.len();
    let mut count = 0;

    println!("init_key: {:?}", key);

    match key_len {
        10 => {
            for c in key.chars()
            {
                match c {
                    '0' => continue,
                    '1' => continue,
                    _ =>
                    {
                        println!("init key must be binary (0s and 1s only)");
                        count = count + 1;
                    }
                }
            }

            match count {
                0 => true,
                _ => false
            }
        },
        _ => {
            println!("init key must be 10 bits long!");
            false
        }
    }
}

fn check_vector(index: usize) -> bool
{
    let vector = env::args().nth(index).unwrap();
    let vector_len = vector.len();
    let mut count = 0;

    println!("init_vec: {:?}", vector);

    match vector_len {
        8 => {
            for c in vector.chars()
            {
                match c {
                    '0' => continue,
                    '1' => continue,
                    _ =>
                    {
                        println!("vector must be binary (0s and 1s only)");
                        count = count + 1;
                    }
                }
            }

            match count {
                0 => true,
                _ => false
            }
        },
        _ => {
            println!("init key must be 8 bits long!");
            false
        }
    }
}

fn check_file(index: usize) -> bool
{
    let mut path = String::from("./");
    let file_name = String::from(env::args().nth(index).unwrap());
    path.push_str(&file_name);
    let check = Path::new(&path).is_file();
    match check
    {
        true => {
            println!("file    : {:?}", file_name);
            true
        },
        _ => {
            println!("file not found");
            false
        }
    }
}

fn check_arguments() -> bool
{
    let args_amount = env::args().len() - 1;
    match args_amount {
        4 => {
            println!("encryption mode");
            match check_key(1) //key is arg #1
            {
                true => {
                    match check_vector(2)
                    {
                        true => {
                            match check_file(3)
                            {
                                true => true,
                                _ => false
                            }
                        },
                        _ => false
                    }
                },
                _ => false
            }
        },
        5 => {
            println!("decryption mode");
            match check_flag(1) //flag is arg #1
            {
                true => {
                    match check_key(2)
                    {
                        true => match check_vector(3)
                        {
                            true => {
                                match check_file(4)
                                {
                                    true => true,
                                    _ => false
                                }
                            },
                            _ => false
                        },
                        _ => false
                    }
                },
                _ => false
            }

        },
        _ => {
            println!("incorrect amount of arguments");
            println!("cargo run [d] <init_key> <init_vector> <original_file> <result_file>");
            false
        },
    }
}

fn key_to_bits(key_string: &String) -> u16
{
    let text_key = key_string;
    let mut sixteen_bit: u16 = 0b0000_0000_0000_0000;

    for c in text_key.chars()
    {
        match c {
            '0' => {
                sixteen_bit = sixteen_bit.rotate_left(1);
            }
            '1' => {
                sixteen_bit |= 0b1000_0000_0000_0000;
                sixteen_bit = sixteen_bit.rotate_left(1);
            }
            _ => println!("failed to convert key to bits"),
        }
    }
    //sixteen_bit.leading_zeros());
    println!("{:?} -> {:010b}_bin", text_key, sixteen_bit);
    sixteen_bit
}

fn vec_to_bits(vec_string: &String) -> u8
{
    // u8 = 0b0000_0000;
    let text_vec = vec_string;
    let mut eight_bit: u8 = 0b0000_0000;

    for c in text_vec.chars()
    {
        match c {
            '0' => {
                eight_bit = eight_bit.rotate_left(1);
            },
            '1' => {
                eight_bit |= 0b1000_0000; //set first bit
                eight_bit = eight_bit.rotate_left(1);
            },
            _ => println!("failed to convert vector to bits"),
        }
    }
    println!("{:?}   -> {:08b}_bin", text_vec, eight_bit);
    eight_bit
}

fn permute_ten(init_key_str: String) -> String
{
    let mut permuted_chars: Vec<char> = Vec::new();
    let mut permuted_string = String::with_capacity(10);
    let p_ten: [usize;10] = [3,5,2,7,4,10,1,9,8,6];

    for x in 0..10 {
        permuted_chars.push(init_key_str.chars().nth(p_ten[x]-1).unwrap() as char);
    }

    for c in &permuted_chars // to avoid 'move' errors, we pass a reference
    {                        // as '&permuted_chars' and dereference '*c'
        permuted_string.push(*c);
    }

    println!("{:?} ==P10=> {:?}", init_key_str, permuted_string);
    permuted_string
}

fn main() {

    if check_arguments() == false
    {
        std::process::exit(1);
    }

    let mut cr = Crypto {
        flag: ' ',
        init_key: 0b0000000000000000,
        init_vec: 0b00000000,
        init_key_str: String::new(),
        init_vec_str: String::new(),
        original_file: String::new(),
        output_file: String::new()
    };

    let args_amount = env::args().len() - 1;
    match args_amount {
        4 => {
            cr.flag='e';
            cr.init_key_str = String::from(env::args().nth(1).unwrap());
            cr.init_vec_str = String::from(env::args().nth(2).unwrap());
            cr.init_key = key_to_bits(&cr.init_key_str);
            cr.init_vec = vec_to_bits(&cr.init_vec_str);
            cr.original_file = env::args().nth(3).unwrap();
            cr.output_file = env::args().nth(4).unwrap();
        },
        5 => {
            cr.flag = 'd';
            cr.init_key_str = String::from(env::args().nth(2).unwrap());
            cr.init_vec_str = String::from(env::args().nth(3).unwrap());
            cr.init_key = key_to_bits(&cr.init_key_str);
            cr.init_vec = vec_to_bits(&cr.init_vec_str);
            cr.original_file = env::args().nth(4).unwrap();
            cr.output_file = env::args().nth(5).unwrap();
        }
        _ => std::process::exit(1)
    }

    println!("cr: {:?} {:010b} {:08b} {:?} {:?}", cr.flag,
                                                  cr.init_key,
                                                  cr.init_vec,
                                                  cr.original_file,
                                                  cr.output_file);

    /* * * * * * * * * *
     * KEY GENERATION *
     * * * * * * * * */

    //P10
    permute_ten(cr.init_key_str);

    //Circular Left Shift (LS-1) on first 5 bits of P10

    //Circular Left Shift (LS-1) on last 5 bits of P10

    //P8 (picks and permutes 8 out of 10 bits) = K1

}
<commit_msg>started on left shifts<commit_after>use std::env;
use std::str;
use std::path::Path;
use std::char;

/*
vector: 10101010
key:    0111111101

byte 1: 00000001  -> 11110100
byte 2: 00100011  -> 00001011

plain                cipher
00000001 00100011 -> 11110100 00001011

% cargo run [-d] <init_key> <init_vector> <original_file> <result_file>
cargo run -d 0111111101 10101010 file1 file2 //decrypts

*/

struct Crypto {
    flag: char,
    init_key: u16,
    init_vec: u8,
    init_key_str: String,
    init_vec_str: String,
    key_one: u8,
    key_two: u8,
    original_file: String,
    output_file: String
}

fn check_flag(index: usize) -> bool
{
    let flag = env::args().nth(index).unwrap();
    match flag.as_ref() {
        "d" => true,
        _ => {
            println!("incorrect flag");
            false
        }
    }
}

fn check_key(index: usize) -> bool
{
    let key = env::args().nth(index).unwrap();
    let key_len = key.len();
    let mut count = 0;

    println!("init_key: {:?}", key);

    match key_len {
        10 => {
            for c in key.chars()
            {
                match c {
                    '0' => continue,
                    '1' => continue,
                    _ =>
                    {
                        println!("init key must be binary (0s and 1s only)");
                        count = count + 1;
                    }
                }
            }

            match count {
                0 => true,
                _ => false
            }
        },
        _ => {
            println!("init key must be 10 bits long!");
            false
        }
    }
}

fn check_vector(index: usize) -> bool
{
    let vector = env::args().nth(index).unwrap();
    let vector_len = vector.len();
    let mut count = 0;

    println!("init_vec: {:?}", vector);

    match vector_len {
        8 => {
            for c in vector.chars()
            {
                match c {
                    '0' => continue,
                    '1' => continue,
                    _ =>
                    {
                        println!("vector must be binary (0s and 1s only)");
                        count = count + 1;
                    }
                }
            }

            match count {
                0 => true,
                _ => false
            }
        },
        _ => {
            println!("init key must be 8 bits long!");
            false
        }
    }
}

fn check_file(index: usize) -> bool
{
    let mut path = String::from("./");
    let file_name = String::from(env::args().nth(index).unwrap());
    path.push_str(&file_name);
    let check = Path::new(&path).is_file();
    match check
    {
        true => {
            println!("file    : {:?}", file_name);
            true
        },
        _ => {
            println!("file not found");
            false
        }
    }
}

fn check_arguments() -> bool
{
    let args_amount = env::args().len() - 1;
    match args_amount {
        4 => {
            println!("encryption mode");
            match check_key(1) //key is arg #1
            {
                true => {
                    match check_vector(2)
                    {
                        true => {
                            match check_file(3)
                            {
                                true => true,
                                _ => false
                            }
                        },
                        _ => false
                    }
                },
                _ => false
            }
        },
        5 => {
            println!("decryption mode");
            match check_flag(1) //flag is arg #1
            {
                true => {
                    match check_key(2)
                    {
                        true => match check_vector(3)
                        {
                            true => {
                                match check_file(4)
                                {
                                    true => true,
                                    _ => false
                                }
                            },
                            _ => false
                        },
                        _ => false
                    }
                },
                _ => false
            }

        },
        _ => {
            println!("incorrect amount of arguments");
            println!("cargo run [d] <init_key> <init_vector> <original_file> <result_file>");
            false
        },
    }
}

fn key_to_bits(key_string: &String) -> u16
{
    let text_key = key_string;
    let mut sixteen_bit: u16 = 0b0000_0000_0000_0000;

    for c in text_key.chars()
    {
        match c {
            '0' => {
                sixteen_bit = sixteen_bit.rotate_left(1);
            }
            '1' => {
                sixteen_bit |= 0b1000_0000_0000_0000;
                sixteen_bit = sixteen_bit.rotate_left(1);
            }
            _ => println!("failed to convert key to bits"),
        }
    }
    //sixteen_bit.leading_zeros());
    println!("{:?} -> {:010b}_bin", text_key, sixteen_bit);
    sixteen_bit
}

fn vec_to_bits(vec_string: &String) -> u8
{
    // u8 = 0b0000_0000;
    let text_vec = vec_string;
    let mut eight_bit: u8 = 0b0000_0000;

    for c in text_vec.chars()
    {
        match c {
            '0' => {
                eight_bit = eight_bit.rotate_left(1);
            },
            '1' => {
                eight_bit |= 0b1000_0000; //set first bit
                eight_bit = eight_bit.rotate_left(1);
            },
            _ => println!("failed to convert vector to bits"),
        }
    }
    println!("{:?}   -> {:08b}_bin", text_vec, eight_bit);
    eight_bit
}

fn permute_ten(init_key_str: String) -> String
{
    let mut permuted_chars: Vec<char> = Vec::new();
    let mut permuted_string = String::with_capacity(10);
    let p_ten: [usize;10] = [3,5,2,7,4,10,1,9,8,6];

    for x in 0..10 {
        permuted_chars.push(init_key_str.chars().nth(p_ten[x]-1).unwrap() as char);
    }

    for c in &permuted_chars // to avoid 'move' errors, we pass a reference
    {                        // as '&permuted_chars' and dereference '*c'
        permuted_string.push(*c);
    }

    println!("{:?} ==P10=> {:?}", init_key_str, permuted_string);
    permuted_string
}

fn circular_left_shift(init_key_str: &String, half: usize) -> u8
{
    let mut first_half_str = init_key_str.clone();
    let second_half_str = first_half_str.split_off(5);

    let mut first_half_bits  = 0b0000_0000;
    let mut second_half_bits = 0b0000_0000;

    //catch the half we want to work on
    match half {
        1 => {
            println!("performing shift on: {:?}", first_half_str);
            first_half_bits = vec_to_bits(&first_half_str);
            first_half_bits = first_half_bits.rotate_left(4);
            println!("fuck me: {:05b}_bin", first_half_bits);
            return first_half_bits
        },
        2 => {
            println!("performing shift on: {:?}", second_half_str);
        },
        _ => println!("invalid half")
    }
    162
}

fn main() {

    if check_arguments() == false
    {
        std::process::exit(1);
    }

    let mut cr = Crypto {
        flag: ' ',
        init_key: 0b0000000000000000,
        init_vec: 0b00000000,
        init_key_str: String::new(),
        init_vec_str: String::new(),
        key_one: 0b00000000,
        key_two: 0b00000000,
        original_file: String::new(),
        output_file: String::new()
    };

    let args_amount = env::args().len() - 1;
    match args_amount {
        4 => {
            cr.flag='e';
            cr.init_key_str = String::from(env::args().nth(1).unwrap());
            cr.init_vec_str = String::from(env::args().nth(2).unwrap());
            cr.init_key = key_to_bits(&cr.init_key_str);
            cr.init_vec = vec_to_bits(&cr.init_vec_str);
            cr.original_file = env::args().nth(3).unwrap();
            cr.output_file = env::args().nth(4).unwrap();
        },
        5 => {
            cr.flag = 'd';
            cr.init_key_str = String::from(env::args().nth(2).unwrap());
            cr.init_vec_str = String::from(env::args().nth(3).unwrap());
            cr.init_key = key_to_bits(&cr.init_key_str);
            cr.init_vec = vec_to_bits(&cr.init_vec_str);
            cr.original_file = env::args().nth(4).unwrap();
            cr.output_file = env::args().nth(5).unwrap();
        }
        _ => std::process::exit(1)
    }

    println!("cr: {:?} {:010b} {:08b} {:?} {:?}", cr.flag,
                                                  cr.init_key,
                                                  cr.init_vec,
                                                  cr.original_file,
                                                  cr.output_file);

    /* * * * * * * * * *
     * KEY GENERATION *
     * * * * * * * * */

    println!("key generation:");
    //P10
    cr.init_key_str = permute_ten(cr.init_key_str);

    //Circular Left Shift (LS-1) on first 5 bits of P10
    circular_left_shift(&cr.init_key_str, 1);

    //Circular Left Shift (LS-1) on last 5 bits of P10
    //circular_left_shift(&cr.init_key_str, 2);
    //P8 (picks and permutes 8 out of 10 bits) = K1

}
<|endoftext|>


<commit_before>extern crate libc;
extern crate termios;

use libc::{STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, winsize};
use termios::{Termios, tcsetattr, TCSAFLUSH, VMIN, VTIME};
use termios::{BRKINT, ICRNL, INPCK, ISTRIP, IXON};
use termios::{OPOST, CS8};
use termios::{ECHO, ICANON, IEXTEN, ISIG};

use std::io::{self, Stdin, Stdout, Read, Error, ErrorKind, Write};

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

const ARROW_LEFT: u32 = 1000;
const ARROW_RIGHT: u32 = 1001;
const ARROW_UP: u32 = 1002;
const ARROW_DOWN: u32 = 1003;

macro_rules! ctrl_key {
    ($k:expr) => (($k & 0x1f) as u32);
}

struct RawMode {
    orig_term: Termios
}

struct Editor {
    _mode: RawMode,
    cx: u16,
    cy: u16,
    screenrows: u16,
    screencols: u16,
    stdin: Stdin,
    stdout: Stdout,
}

impl RawMode {
    fn enable_raw_mode() -> io::Result<RawMode> {
        let mut term = Termios::from_fd(STDIN_FILENO)?;
        let mode = RawMode { orig_term: term.clone() };

        term.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        term.c_oflag &= !OPOST;
        term.c_cflag |= CS8;
        term.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
        term.c_cc[VMIN] = 0;
        term.c_cc[VTIME] = 1;

        tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)?;
        Ok(mode)
    }
}

impl Drop for RawMode {
    fn drop(&mut self) {
        tcsetattr(STDIN_FILENO, TCSAFLUSH, &self.orig_term).unwrap()
    }
}

fn read_non_blocking<R : Read>(r : &mut R, buf: &mut [u8]) -> usize {
    r.read(buf)
     .or_else(|e| if e.kind() == ErrorKind::WouldBlock { Ok(0) } else { Err(e) })
     .expect("read_non_blocking")
}

fn editor_read_key(stdin: &mut Stdin) -> u32 {
    let mut buf = [0; 1];
    loop {
        let n = read_non_blocking(stdin, &mut buf);
        if n == 1 {
            if buf[0] == b'\x1b' {
                let mut seq = [0; 2];
                let n = read_non_blocking(stdin, &mut seq);
                if n == 2 && seq[0] == b'[' {
                    return match seq[1] {
                        b'A' => ARROW_UP,
                        b'B' => ARROW_DOWN,
                        b'C' => ARROW_RIGHT,
                        b'D' => ARROW_LEFT,
                        _ => b'\x1b' as u32,
                    }
                } else {
                    return b'\x1b' as u32;
                }
            } else {
                return buf[0] as u32;
            }
        }
    }
}

fn get_window_size() -> io::Result<(u16, u16)> {
    let ws = winsize { ws_col: 0, ws_row: 0, ws_xpixel: 0, ws_ypixel: 0 };
    unsafe {
        if libc::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0 {
            return Err(Error::new(ErrorKind::Other, "get_window_size: ioctl failed"))
        }
    }
    Ok((ws.ws_row, ws.ws_col))
}

impl Editor {
    fn new() -> io::Result<Editor> {
        let mode = RawMode::enable_raw_mode()?;
        let (rows, cols) = get_window_size()?;
        let stdin = io::stdin();
        let stdout = io::stdout();
        Ok(Editor {
            _mode: mode,
            cx: 0,
            cy: 0,
            screenrows: rows,
            screencols: cols,
            stdin: stdin,
            stdout: stdout
        })
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.stdout.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.stdout.flush()
    }

    fn draw_rows(&mut self) -> io::Result<()> {
        for y in 0..(self.screenrows) {
            if y == self.screenrows / 3 {
                let mut msg = format!("Kilo-rs editor -- version {}", VERSION);
                msg.truncate(self.screencols as usize);
                let padding = (self.screencols - msg.len() as u16) / 2;
                if padding > 0 {
                    self.write(b"~")?;
                    for _ in 1..padding {
                        self.write(b" ")?;
                    }
                }
                self.write(msg.as_bytes())?;
            } else {
                self.write(b"~")?;
            }

            self.write(b"\x1b[K")?;
            if y < self.screenrows - 1 {
                self.write(b"\r\n")?;
            }
        }
        Ok(())
    }

    fn refresh_screen(&mut self) -> io::Result<()> {
        self.write(b"\x1b[?25l")?;
        self.write(b"\x1b[H")?;

        self.draw_rows()?;

        let move_cursor = format!("\x1b[{};{}H", self.cy + 1, self.cx + 1).into_bytes();
        self.write(&move_cursor)?;

        self.write(b"\x1b[?25h")?;
        self.flush()
    }

    fn move_cursor(&mut self, c: u32) {
        match c {
            ARROW_UP => {
                if self.cy > 0 {
                    self.cy -= 1;
                }
            },
            ARROW_DOWN => {
                if self.cy < self.screenrows - 1 {
                    self.cy += 1;
                }
            },
            ARROW_LEFT => {
                if self.cx > 0 {
                    self.cx -= 1;
                }
            },
            ARROW_RIGHT => {
                if self.cx < self.screencols - 1 {
                    self.cx += 1;
                }
            },
            _ => {},
        }
    }

    fn process_keypress(&mut self) -> bool {
        let c = editor_read_key(&mut self.stdin);

        match c {
            k if k == ctrl_key!(b'q') => {
                false
            },
            ARROW_UP | ARROW_DOWN | ARROW_LEFT | ARROW_RIGHT => {
                self.move_cursor(c);
                true
            },
            _ => true
        }
    }
}

impl Drop for Editor {
    fn drop(&mut self) {
        // clear screen
        self.stdout.write(b"\x1b[2J").unwrap();
        self.stdout.write(b"\x1b[H").unwrap();
        self.stdout.flush().unwrap();
    }
}

fn main() {
    let mut editor = Editor::new().unwrap();

    editor.refresh_screen().unwrap();
    while editor.process_keypress() {
        editor.refresh_screen().unwrap();
    }
}
<commit_msg>Page Up and Page Down keys<commit_after>extern crate libc;
extern crate termios;

use libc::{STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, winsize};
use termios::{Termios, tcsetattr, TCSAFLUSH, VMIN, VTIME};
use termios::{BRKINT, ICRNL, INPCK, ISTRIP, IXON};
use termios::{OPOST, CS8};
use termios::{ECHO, ICANON, IEXTEN, ISIG};

use std::io::{self, Stdin, Stdout, Read, Error, ErrorKind, Write};

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

const ARROW_LEFT: u32 = 1000;
const ARROW_RIGHT: u32 = 1001;
const ARROW_UP: u32 = 1002;
const ARROW_DOWN: u32 = 1003;
const PAGE_UP: u32 = 1004;
const PAGE_DOWN: u32 = 1005;

macro_rules! ctrl_key {
    ($k:expr) => (($k & 0x1f) as u32);
}

struct RawMode {
    orig_term: Termios
}

struct Editor {
    _mode: RawMode,
    cx: u16,
    cy: u16,
    screenrows: u16,
    screencols: u16,
    stdin: Stdin,
    stdout: Stdout,
}

impl RawMode {
    fn enable_raw_mode() -> io::Result<RawMode> {
        let mut term = Termios::from_fd(STDIN_FILENO)?;
        let mode = RawMode { orig_term: term.clone() };

        term.c_iflag &= !(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
        term.c_oflag &= !OPOST;
        term.c_cflag |= CS8;
        term.c_lflag &= !(ECHO | ICANON | IEXTEN | ISIG);
        term.c_cc[VMIN] = 0;
        term.c_cc[VTIME] = 1;

        tcsetattr(STDIN_FILENO, TCSAFLUSH, &term)?;
        Ok(mode)
    }
}

impl Drop for RawMode {
    fn drop(&mut self) {
        tcsetattr(STDIN_FILENO, TCSAFLUSH, &self.orig_term).unwrap()
    }
}

fn read_non_blocking<R : Read>(r : &mut R, buf: &mut [u8]) -> usize {
    r.read(buf)
     .or_else(|e| if e.kind() == ErrorKind::WouldBlock { Ok(0) } else { Err(e) })
     .expect("read_non_blocking")
}

fn editor_read_key(stdin: &mut Stdin) -> u32 {
    let mut buf = [0; 1];
    loop {
        let n = read_non_blocking(stdin, &mut buf);
        if n == 1 {
            if buf[0] == b'\x1b' {
                let mut seq = [0; 2];
                let n = read_non_blocking(stdin, &mut seq);
                if n == 2 && seq[0] == b'[' {
                    if seq[1] >= b'0' && seq[1] <= b'9' {
                        let mut last = [0; 1];
                        let n = read_non_blocking(stdin, &mut last);
                        if n == 0 {
                            return b'\x1b' as u32;
                        }
                        if last[0] == b'~' {
                            if seq[1] == b'5' {
                                return PAGE_UP;
                            } else if seq[1] == b'6' {
                                return PAGE_DOWN;
                            }
                        }
                    } else {
                        return match seq[1] {
                            b'A' => ARROW_UP,
                            b'B' => ARROW_DOWN,
                            b'C' => ARROW_RIGHT,
                            b'D' => ARROW_LEFT,
                            _ => b'\x1b' as u32,
                        }
                    }
                } else {
                    return b'\x1b' as u32;
                }
            } else {
                return buf[0] as u32;
            }
        }
    }
}

fn get_window_size() -> io::Result<(u16, u16)> {
    let ws = winsize { ws_col: 0, ws_row: 0, ws_xpixel: 0, ws_ypixel: 0 };
    unsafe {
        if libc::ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0 {
            return Err(Error::new(ErrorKind::Other, "get_window_size: ioctl failed"))
        }
    }
    Ok((ws.ws_row, ws.ws_col))
}

impl Editor {
    fn new() -> io::Result<Editor> {
        let mode = RawMode::enable_raw_mode()?;
        let (rows, cols) = get_window_size()?;
        let stdin = io::stdin();
        let stdout = io::stdout();
        Ok(Editor {
            _mode: mode,
            cx: 0,
            cy: 0,
            screenrows: rows,
            screencols: cols,
            stdin: stdin,
            stdout: stdout
        })
    }

    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.stdout.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.stdout.flush()
    }

    fn draw_rows(&mut self) -> io::Result<()> {
        for y in 0..(self.screenrows) {
            if y == self.screenrows / 3 {
                let mut msg = format!("Kilo-rs editor -- version {}", VERSION);
                msg.truncate(self.screencols as usize);
                let padding = (self.screencols - msg.len() as u16) / 2;
                if padding > 0 {
                    self.write(b"~")?;
                    for _ in 1..padding {
                        self.write(b" ")?;
                    }
                }
                self.write(msg.as_bytes())?;
            } else {
                self.write(b"~")?;
            }

            self.write(b"\x1b[K")?;
            if y < self.screenrows - 1 {
                self.write(b"\r\n")?;
            }
        }
        Ok(())
    }

    fn refresh_screen(&mut self) -> io::Result<()> {
        self.write(b"\x1b[?25l")?;
        self.write(b"\x1b[H")?;

        self.draw_rows()?;

        let move_cursor = format!("\x1b[{};{}H", self.cy + 1, self.cx + 1).into_bytes();
        self.write(&move_cursor)?;

        self.write(b"\x1b[?25h")?;
        self.flush()
    }

    fn move_cursor(&mut self, c: u32) {
        match c {
            ARROW_UP => {
                if self.cy > 0 {
                    self.cy -= 1;
                }
            },
            ARROW_DOWN => {
                if self.cy < self.screenrows - 1 {
                    self.cy += 1;
                }
            },
            ARROW_LEFT => {
                if self.cx > 0 {
                    self.cx -= 1;
                }
            },
            ARROW_RIGHT => {
                if self.cx < self.screencols - 1 {
                    self.cx += 1;
                }
            },
            _ => (),
        }
    }

    fn process_keypress(&mut self) -> bool {
        let c = editor_read_key(&mut self.stdin);

        match c {
            k if k == ctrl_key!(b'q') => {
                return false
            },
            PAGE_UP | PAGE_DOWN => {
                for _ in 0..(self.screenrows) {
                    self.move_cursor(if c == PAGE_UP { ARROW_UP } else { ARROW_DOWN });
                }
            },
            ARROW_UP | ARROW_DOWN | ARROW_LEFT | ARROW_RIGHT => {
                self.move_cursor(c);
            },
            _ => ()
        };
        true
    }
}

impl Drop for Editor {
    fn drop(&mut self) {
        // clear screen
        self.stdout.write(b"\x1b[2J").unwrap();
        self.stdout.write(b"\x1b[H").unwrap();
        self.stdout.flush().unwrap();
    }
}

fn main() {
    let mut editor = Editor::new().unwrap();

    editor.refresh_screen().unwrap();
    while editor.process_keypress() {
        editor.refresh_screen().unwrap();
    }
}
<|endoftext|>