<commit_before>extern crate num;
extern crate portaudio;
extern crate rtlsdr;

use portaudio as pa;
use rtlsdr::{RTLSDRDevice, RTLSDRError};
use num::complex::Complex;
use std::env;
use std::collections::VecDeque;
use std::f32::consts::PI;
use std::error::Error;

// Make sure that the buffer size is radix-2, otherwise the read_sync function
// will fail with an error code of -8.
const SDR_BUF_SIZE: usize = 524288;

// Separating out the buffer sizes seems to help some.
const BUF_SIZE: usize = 262144;

// Most other sample rates fail, but this one works for my particular device.
// I will investigate exactly what's happening here and generate a list of
// possible sample rates (if there are others besides this one).
const SAMPLE_RATE: u32 = 2800000;

// Here is the sample rate of the output waveform we'll try to use.
const SAMPLE_RATE_AUDIO: f64 = 48000.0;

// The bandwidth of the received signal.
const BANDWIDTH: u32 = 5000;

// The number of channels being used for audio.
const CHANNELS: i32 = 2;

fn main() {
    match run() {
        Ok(()) => (),
        Err(e) => println!("ERROR: {}", e),
    }
}

struct RTLSDR {
    rtlsdr: RTLSDRDevice,
}

unsafe impl Send for RTLSDR {}

fn run() -> Result<(), Box<Error>> {
    let sdr_index: i32 = env::args().nth(1)
        .expect("Please specify the SDR index")
        .parse::<i32>()?;
    let fm_freq_mhz: f32 = env::args().nth(2)
        .expect("Please specify a center frequency (MHz).")
        .parse::<f32>()?;

    // Initialize the PortAudio class.
    let audio = try!(pa::PortAudio::new());
    let settings =
        try!(audio.default_output_stream_settings(CHANNELS,
                                                  SAMPLE_RATE_AUDIO,
                                                  BUF_SIZE as u32));
    let mut stream = try!(audio.open_blocking_stream(settings));
    try!(stream.start());

    let fm_freq: u32 = (fm_freq_mhz * 1e6) as u32;

    // TODO: we need to figure out the appropriate decimation here. I've seen
    // talk that we decimate based on the bandwidth but after decimation the
    // audio signal comes out much slower. Changing the decimation value
    // seems to affect the speed of the audio, so I need to establish the
    // relationship here. Just playing with the decimation value, 30 seems
    // to work well but I need to figure out _why_.
    // let dec_rate = (SAMPLE_RATE as f64 / BANDWIDTH as f64) as usize;
    let dec_rate = 25;
    println!("dec rate is {}", dec_rate);
    let mut sdr = RTLSDR { rtlsdr: init_sdr(sdr_index, fm_freq).unwrap() };
    let mut prev = Complex::new(0.0, 0.0);

    loop {
        // Read the samples and decimate down to match the sample rate of
        // the audio that'll be going out.
        let bytes = sdr.rtlsdr.read_sync(SDR_BUF_SIZE).unwrap();
        let iq_vec =
            decimate(read_samples(bytes).unwrap().as_slice(),
                     dec_rate);

        // After decimation, demodulate the signal and send out of the
        // thread to the receiver.
        let mut res = demod_fm(iq_vec, prev);
        let mut demod_iq = res.0;
        prev = res.1;

        // Get the write stream and write our samples to the stream.
        let out_frames = match stream.write_available() {
            Ok(available) => {
                match available {
                    pa::StreamAvailable::Frames(frames) => frames as u32,
                    _ => return Err(Box::new(pa::error::Error::NullCallback)),
                }
            }
            Err(e) => return Err(Box::new(e)),
        };

        let buffer_frames = (demod_iq.len() / CHANNELS as usize) as u32;
        let write_frames = std::cmp::min(buffer_frames, out_frames);
        if write_frames == 0 {
            println!("write frames is 0, are we not generating fast enough?");
        }
        let n_write_samples = write_frames as usize * CHANNELS as usize;

        stream.write(write_frames,
                   |output| for ix in 0..n_write_samples as usize {
                       output[ix] = 0.005 * demod_iq.pop_front().unwrap();
                   })?;
    }
}

fn init_sdr(sdr_index: i32, fm_freq: u32) -> Result<RTLSDRDevice, RTLSDRError> {
    let mut sdr = try!(rtlsdr::open(sdr_index));
    try!(sdr.set_center_freq(fm_freq));
    try!(sdr.set_sample_rate(SAMPLE_RATE));
    try!(sdr.set_tuner_bandwidth(BANDWIDTH));
    try!(sdr.set_agc_mode(false));
    try!(sdr.reset_buffer());
    Ok(sdr)
}

fn decimate(signal: &[Complex<f32>], dec_rate: usize) -> Vec<Complex<f32>> {
    let mut ix = 0;
    let new_size = (signal.len() / dec_rate + 1) as usize;
    let mut signal_dec = Vec::<Complex<f32>>::with_capacity(new_size);
    while ix < signal.len() {
        signal_dec.push(signal[ix]);
        ix += dec_rate;
    }
    signal_dec
}

fn read_samples(bytes: Vec<u8>) -> Option<Vec<Complex<f32>>> {
    // First, check that we've been given an even number of bytes. Not sure
    // what to do if we don't get I and Q.
    let bytes_len = bytes.len();
    if bytes_len % 2 != 0 {
        println!("Received an odd number of samples.");
        return None;

    }
    let mut iq_vec: Vec<Complex<f32>> = Vec::with_capacity(bytes_len / 2);

    // Write the values to the complex value and normalize from [0, 255] to
    // [-1, 1]. If we don't normalize, it seems we don't get anything.
    for iq in bytes.chunks(2) {
        let iq_cmplx = Complex::new((iq[0] as f32 - 127.0),
                                    (iq[1] as f32 - 127.0));
        iq_vec.push(iq_cmplx);
    }
    Some(iq_vec)
}

fn demod_fm(iq: Vec<Complex<f32>>, prev: Complex<f32>) -> (VecDeque<f32>, Complex<f32>) {
    let mut p = prev.clone();
    let mut demod_queue: VecDeque<f32> = VecDeque::with_capacity(iq.len());
    let gain = SAMPLE_RATE as f32 / (2.0 * PI * 75e3 / 8.0);

    for samp in iq.iter() {
        let conj = p.conj() * samp;
        let fm_val = conj.im.atan2(conj.re);
        demod_queue.push_back(fm_val * gain);
        p = *samp;
    }
    (demod_queue, p)
}
<commit_msg>Added code to apply filters to a signal<commit_after>extern crate num;
extern crate portaudio;
extern crate rtlsdr;

use portaudio as pa;
use rtlsdr::{RTLSDRDevice, RTLSDRError};
use num::complex::Complex;
use std::env;
use std::collections::VecDeque;
use std::f32::consts::PI;
use std::error::Error;

// Make sure that the buffer size is radix-2, otherwise the read_sync function
// will fail with an error code of -8.
const SDR_BUF_SIZE: usize = 524288;

// Separating out the buffer sizes seems to help some.
const BUF_SIZE: usize = 262144;

// Most other sample rates fail, but this one works for my particular device.
// I will investigate exactly what's happening here and generate a list of
// possible sample rates (if there are others besides this one).
const SAMPLE_RATE: u32 = 2800000;

// Here is the sample rate of the output waveform we'll try to use.
const SAMPLE_RATE_AUDIO: f64 = 48000.0;

// The number of channels being used for audio.
const CHANNELS: i32 = 2;

fn main() {
    match run() {
        Ok(()) => (),
        Err(e) => println!("ERROR: {}", e),
    }
}

struct RTLSDR {
    rtlsdr: RTLSDRDevice,
}

unsafe impl Send for RTLSDR {}

fn run() -> Result<(), Box<Error>> {
    let sdr_index: i32 = env::args().nth(1)
        .expect("Please specify the SDR index")
        .parse::<i32>()?;
    let fm_freq_mhz: f32 = env::args().nth(2)
        .expect("Please specify a center frequency (MHz).")
        .parse::<f32>()?;
    let bandwidth: u32 = env::args().nth(3)
        .expect("Please specify the bandwidth.")
        .parse::<u32>()?;

    // Initialize the PortAudio class.
    let audio = try!(pa::PortAudio::new());
    let settings =
        try!(audio.default_output_stream_settings(CHANNELS,
                                                  SAMPLE_RATE_AUDIO,
                                                  BUF_SIZE as u32));
    let mut stream = try!(audio.open_blocking_stream(settings));
    try!(stream.start());

    let fm_freq: u32 = (fm_freq_mhz * 1e6) as u32;

    // TODO: we need to figure out the appropriate decimation here. I've seen
    // talk that we decimate based on the bandwidth but after decimation the
    // audio signal comes out much slower. Changing the decimation value
    // seems to affect the speed of the audio, so I need to establish the
    // relationship here. Just playing with the decimation value, 30 seems
    // to work well but I need to figure out _why_.
    // let dec_rate = (SAMPLE_RATE as f64 / bandwidth as f64) as usize;
    let dec_rate = 30;
    println!("dec rate is {}", dec_rate);
    let mut sdr =
        RTLSDR { rtlsdr: init_sdr(sdr_index, fm_freq, bandwidth).unwrap() };
    let mut prev = Complex::new(0.0, 0.0);

    loop {
        // Read the samples and decimate down to match the sample rate of
        // the audio that'll be going out.
        let bytes = sdr.rtlsdr.read_sync(SDR_BUF_SIZE).unwrap();
        let mut iq_vec = decimate(read_samples(bytes).unwrap().as_slice(),
                                  dec_rate);
        iq_vec = filter(iq_vec, moving_average(10));

        // After decimation, demodulate the signal and send out of the
        // thread to the receiver.
        let res = demod_fm(iq_vec, prev);
        let mut demod_iq = res.0; // filter_queue(res.0, moving_average(1));
        prev = res.1;

        // Get the write stream and write our samples to the stream.
        let out_frames = match stream.write_available() {
            Ok(available) => {
                match available {
                    pa::StreamAvailable::Frames(frames) => frames as u32,
                    _ => return Err(Box::new(pa::error::Error::NullCallback)),
                }
            }
            Err(e) => return Err(Box::new(e)),
        };

        let buffer_frames = (demod_iq.len() / CHANNELS as usize) as u32;
        let write_frames = std::cmp::min(buffer_frames, out_frames);
        if write_frames == 0 {
            println!("write frames is 0, are we not generating fast enough?");
        }
        let n_write_samples = write_frames as usize * CHANNELS as usize;

        stream.write(write_frames,
                   |output| for ix in 0..n_write_samples as usize {
                       output[ix] = 0.005 * demod_iq.pop_front().unwrap();
                   })?;
    }
}

fn init_sdr(sdr_index: i32,
            fm_freq: u32,
            bandwidth: u32)
            -> Result<RTLSDRDevice, RTLSDRError> {
    let mut sdr = try!(rtlsdr::open(sdr_index));
    try!(sdr.set_center_freq(fm_freq));
    try!(sdr.set_sample_rate(SAMPLE_RATE));
    try!(sdr.set_tuner_bandwidth(bandwidth));
    try!(sdr.set_agc_mode(false));
    try!(sdr.reset_buffer());
    Ok(sdr)
}

fn decimate(signal: &[Complex<f32>], dec_rate: usize) -> Vec<Complex<f32>> {
    let mut ix = 0;
    let new_size = (signal.len() / dec_rate + 1) as usize;
    let mut signal_dec = Vec::<Complex<f32>>::with_capacity(new_size);
    while ix < signal.len() {
        signal_dec.push(signal[ix]);
        ix += dec_rate;
    }
    signal_dec
}

fn read_samples(bytes: Vec<u8>) -> Option<Vec<Complex<f32>>> {
    // First, check that we've been given an even number of bytes. Not sure
    // what to do if we don't get I and Q.
    let bytes_len = bytes.len();
    if bytes_len % 2 != 0 {
        println!("Received an odd number of samples.");
        return None;

    }
    let mut iq_vec: Vec<Complex<f32>> = Vec::with_capacity(bytes_len / 2);

    // Write the values to the complex value and normalize from [0, 255] to
    // [-1, 1]. If we don't normalize, it seems we don't get anything.
    for iq in bytes.chunks(2) {
        let iq_cmplx = Complex::new((iq[0] as f32 - 127.0) / 127.0,
                                    (iq[1] as f32 - 127.0) / 127.0);
        iq_vec.push(iq_cmplx);
    }
    Some(iq_vec)
}

fn demod_fm(iq: Vec<Complex<f32>>,
            prev: Complex<f32>)
            -> (VecDeque<f32>, Complex<f32>) {

    let mut p = prev.clone();
    let mut demod_queue: VecDeque<f32> = VecDeque::with_capacity(iq.len());
    let gain = SAMPLE_RATE as f32 / (2.0 * PI * 75e3 / 8.0);

    for samp in iq.iter() {
        let conj = p.conj() * samp;
        let fm_val = conj.im.atan2(conj.re);
        demod_queue.push_back(fm_val * gain);
        p = *samp;
    }
    (demod_queue, p)
}

fn filter(samples: Vec<Complex<f32>>, taps: Vec<f32>) -> Vec<Complex<f32>> {
    let mut filt_samps: Vec<Complex<f32>> = Vec::new();
    for window in samples.as_slice().windows(taps.len()) {
        let iter = window.iter().zip(taps.iter());
        let filt_samp = iter.map(|(x, y)| x * y)
            .fold(Complex::new(0.0, 0.0), |acc, x| acc + x);
        filt_samps.push(filt_samp);
    }
    filt_samps
}

fn filter_queue(samples: VecDeque<f32>, taps: Vec<f32>) -> VecDeque<f32> {
    let mut filt_samps: VecDeque<f32> = VecDeque::new();
    for window in samples.as_slices().0.windows(taps.len()) {
        let iter = window.iter().zip(taps.iter());
        let filt_samp = iter.map(|(x, y)| x * y).sum();
        filt_samps.push_back(filt_samp);
    }
    filt_samps

}

fn moving_average(ntaps: usize) -> Vec<f32> {
    vec![1.0 / ntaps as f32; ntaps]
}
<|endoftext|>


<commit_before>#![deny(bare_trait_objects, anonymous_parameters, elided_lifetimes_in_paths)]

use cargo;
use env_logger;

#[macro_use]
mod macros;
mod cargo_ops;
use crate::cargo_ops::{ElaborateWorkspace, TempProject};

use cargo::core::shell::Verbosity;
use cargo::core::Workspace;
use cargo::util::important_paths::find_root_manifest_for_wd;
use cargo::util::{CargoResult, CliError, Config};
use docopt::Docopt;

pub const USAGE: &str = "
Displays information about project dependency versions

USAGE:
    cargo outdated [options]

Options:
    -a, --aggressive            Ignores channels for latest updates
    -h, --help                  Prints help information
    -q, --quiet                 Suppresses warnings
    -R, --root-deps-only        Only check root dependencies (Equivalent to --depth=1)
    -V, --version               Prints version information
    -v, --verbose ...           Use verbose output
    -w, --workspace             Checks updates for all workspace members rather than
                                only the root package
        --color COLOR           Coloring: auto, always, never [default: auto]
                                [values: auto, always, never]
    -d, --depth NUM             How deep in the dependency chain to search
                                (Defaults to all dependencies when omitted)
        --exit-code NUM         The exit code to return on new versions found [default: 0]
        --features FEATURES     Space-separated list of features
    -m, --manifest-path FILE    An absolute path to the Cargo.toml file to use
                                (Defaults to Cargo.toml in project root)
    -p, --packages PKGS         Packages to inspect for updates
    -r, --root ROOT             Package to treat as the root package
";

/// Options from CLI arguments
#[derive(serde_derive::Deserialize, Debug)]
pub struct Options {
    flag_color: Option<String>,
    flag_features: Vec<String>,
    flag_manifest_path: Option<String>,
    flag_quiet: bool,
    flag_verbose: u32,
    flag_exit_code: i32,
    flag_packages: Vec<String>,
    flag_root: Option<String>,
    flag_depth: Option<i32>,
    flag_root_deps_only: bool,
    flag_workspace: bool,
    flag_aggressive: bool,
}

impl Options {
    fn all_features(&self) -> bool { self.flag_features.is_empty() }

    fn no_default_features(&self) -> bool {
        !(self.flag_features.is_empty() || self.flag_features.contains(&"default".to_owned()))
    }

    fn locked(&self) -> bool { false }

    fn frozen(&self) -> bool { false }
}

fn main() {
    env_logger::init();
    let options = {
        let mut options: Options = Docopt::new(USAGE)
            .and_then(|d| {
                d.version(Some(
                    concat!(env!("CARGO_PKG_NAME"), " v", env!("CARGO_PKG_VERSION")).to_owned(),
                ))
                .deserialize()
            })
            .unwrap_or_else(|e| e.exit());
        fn flat_split(arg: &[String]) -> Vec<String> {
            arg.iter()
                .flat_map(|s| s.split_whitespace())
                .flat_map(|s| s.split(','))
                .filter(|s| !s.is_empty())
                .map(|s| s.to_string())
                .collect()
        }
        options.flag_features = flat_split(&options.flag_features);
        options.flag_packages = flat_split(&options.flag_packages);
        if options.flag_root_deps_only {
            options.flag_depth = Some(1);
        }
        options
    };

    let mut config = match Config::default() {
        Ok(cfg) => cfg,
        Err(e) => {
            let mut shell = cargo::core::Shell::new();
            cargo::exit_with_error(e.into(), &mut shell)
        }
    };
    let exit_code = options.flag_exit_code;
    let result = execute(options, &mut config);
    match result {
        Err(e) => {
            config.shell().set_verbosity(Verbosity::Normal);
            let cli_error = CliError::new(e, 1);
            cargo::exit_with_error(cli_error, &mut *config.shell())
        }
        Ok(i) => {
            if i > 0 {
                std::process::exit(exit_code);
            } else {
                std::process::exit(0);
            }
        }
    }
}

#[allow(unknown_lints)]
#[allow(needless_pass_by_value)]
pub fn execute(options: Options, config: &mut Config) -> CargoResult<i32> {
    config.configure(
        options.flag_verbose,
        None,
        &options.flag_color,
        options.frozen(),
        options.locked(),
        &None,
        &[],
    )?;
    debug!(config, format!("options: {:?}", options));

    verbose!(config, "Parsing...", "current workspace");
    // the Cargo.toml that we are actually working on
    let curr_manifest = if let Some(ref manifest_path) = options.flag_manifest_path {
        manifest_path.into()
    } else {
        find_root_manifest_for_wd(config.cwd())?
    };
    let curr_workspace = Workspace::new(&curr_manifest, config)?;
    verbose!(config, "Resolving...", "current workspace");
    if options.flag_verbose == 0 {
        config.shell().set_verbosity(Verbosity::Quiet);
    }
    let ela_curr = ElaborateWorkspace::from_workspace(&curr_workspace, &options)?;
    if options.flag_verbose > 0 {
        config.shell().set_verbosity(Verbosity::Verbose);
    } else {
        config.shell().set_verbosity(Verbosity::Normal);
    }

    verbose!(config, "Parsing...", "compat workspace");
    let compat_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    compat_proj.write_manifest_semver(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "compat workspace");
    compat_proj.cargo_update()?;
    verbose!(config, "Resolving...", "compat workspace");
    let compat_workspace = compat_proj.workspace.borrow();
    let ela_compat =
        ElaborateWorkspace::from_workspace(compat_workspace.as_ref().unwrap(), &options)?;

    verbose!(config, "Parsing...", "latest workspace");
    let latest_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    latest_proj.write_manifest_latest(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "latest workspace");
    latest_proj.cargo_update()?;
    verbose!(config, "Resolving...", "latest workspace");
    let latest_workspace = latest_proj.workspace.borrow();
    let ela_latest =
        ElaborateWorkspace::from_workspace(latest_workspace.as_ref().unwrap(), &options)?;

    if ela_curr.workspace_mode {
        let mut sum = 0;
        verbose!(config, "Printing...", "Package status in list format");
        for member in ela_curr.workspace.members() {
            ela_curr.resolve_status(
                &ela_compat,
                &ela_latest,
                &options,
                config,
                member.package_id(),
            )?;
            sum += ela_curr.print_list(&options, member.package_id(), sum > 0)?;
        }
        if sum == 0 {
            println!("All dependencies are up to date, yay!");
        }
        Ok(sum)
    } else {
        verbose!(config, "Resolving...", "package status");
        let root = ela_curr.determine_root(&options)?;
        ela_curr.resolve_status(&ela_compat, &ela_latest, &options, config, root)?;
        verbose!(config, "Printing...", "list format");
        let count = ela_curr.print_list(&options, root, false)?;
        Ok(count)
    }
}
<commit_msg>Allow nightly cargo features<commit_after>#![deny(bare_trait_objects, anonymous_parameters, elided_lifetimes_in_paths)]

use cargo;
use env_logger;

#[macro_use]
mod macros;
mod cargo_ops;
use crate::cargo_ops::{ElaborateWorkspace, TempProject};

use cargo::core::maybe_allow_nightly_features;
use cargo::core::shell::Verbosity;
use cargo::core::Workspace;
use cargo::util::important_paths::find_root_manifest_for_wd;
use cargo::util::{CargoResult, CliError, Config};
use docopt::Docopt;

pub const USAGE: &str = "
Displays information about project dependency versions

USAGE:
    cargo outdated [options]

Options:
    -a, --aggressive            Ignores channels for latest updates
    -h, --help                  Prints help information
    -q, --quiet                 Suppresses warnings
    -R, --root-deps-only        Only check root dependencies (Equivalent to --depth=1)
    -V, --version               Prints version information
    -v, --verbose ...           Use verbose output
    -w, --workspace             Checks updates for all workspace members rather than
                                only the root package
        --color COLOR           Coloring: auto, always, never [default: auto]
                                [values: auto, always, never]
    -d, --depth NUM             How deep in the dependency chain to search
                                (Defaults to all dependencies when omitted)
        --exit-code NUM         The exit code to return on new versions found [default: 0]
        --features FEATURES     Space-separated list of features
    -m, --manifest-path FILE    An absolute path to the Cargo.toml file to use
                                (Defaults to Cargo.toml in project root)
    -p, --packages PKGS         Packages to inspect for updates
    -r, --root ROOT             Package to treat as the root package
";

/// Options from CLI arguments
#[derive(serde_derive::Deserialize, Debug)]
pub struct Options {
    flag_color: Option<String>,
    flag_features: Vec<String>,
    flag_manifest_path: Option<String>,
    flag_quiet: bool,
    flag_verbose: u32,
    flag_exit_code: i32,
    flag_packages: Vec<String>,
    flag_root: Option<String>,
    flag_depth: Option<i32>,
    flag_root_deps_only: bool,
    flag_workspace: bool,
    flag_aggressive: bool,
}

impl Options {
    fn all_features(&self) -> bool { self.flag_features.is_empty() }

    fn no_default_features(&self) -> bool {
        !(self.flag_features.is_empty() || self.flag_features.contains(&"default".to_owned()))
    }

    fn locked(&self) -> bool { false }

    fn frozen(&self) -> bool { false }
}

fn main() {
    env_logger::init();
    let options = {
        let mut options: Options = Docopt::new(USAGE)
            .and_then(|d| {
                d.version(Some(
                    concat!(env!("CARGO_PKG_NAME"), " v", env!("CARGO_PKG_VERSION")).to_owned(),
                ))
                .deserialize()
            })
            .unwrap_or_else(|e| e.exit());
        fn flat_split(arg: &[String]) -> Vec<String> {
            arg.iter()
                .flat_map(|s| s.split_whitespace())
                .flat_map(|s| s.split(','))
                .filter(|s| !s.is_empty())
                .map(|s| s.to_string())
                .collect()
        }
        options.flag_features = flat_split(&options.flag_features);
        options.flag_packages = flat_split(&options.flag_packages);
        if options.flag_root_deps_only {
            options.flag_depth = Some(1);
        }
        options
    };

    let mut config = match Config::default() {
        Ok(cfg) => cfg,
        Err(e) => {
            let mut shell = cargo::core::Shell::new();
            cargo::exit_with_error(e.into(), &mut shell)
        }
    };
    let exit_code = options.flag_exit_code;
    let result = execute(options, &mut config);
    match result {
        Err(e) => {
            config.shell().set_verbosity(Verbosity::Normal);
            let cli_error = CliError::new(e, 1);
            cargo::exit_with_error(cli_error, &mut *config.shell())
        }
        Ok(i) => {
            if i > 0 {
                std::process::exit(exit_code);
            } else {
                std::process::exit(0);
            }
        }
    }
}

#[allow(unknown_lints)]
#[allow(needless_pass_by_value)]
pub fn execute(options: Options, config: &mut Config) -> CargoResult<i32> {
    config.configure(
        options.flag_verbose,
        None,
        &options.flag_color,
        options.frozen(),
        options.locked(),
        &None,
        &[],
    )?;
    debug!(config, format!("options: {:?}", options));

    // Needed to allow nightly features
    maybe_allow_nightly_features();

    verbose!(config, "Parsing...", "current workspace");
    // the Cargo.toml that we are actually working on
    let curr_manifest = if let Some(ref manifest_path) = options.flag_manifest_path {
        manifest_path.into()
    } else {
        find_root_manifest_for_wd(config.cwd())?
    };
    let curr_workspace = Workspace::new(&curr_manifest, config)?;
    verbose!(config, "Resolving...", "current workspace");
    if options.flag_verbose == 0 {
        config.shell().set_verbosity(Verbosity::Quiet);
    }
    let ela_curr = ElaborateWorkspace::from_workspace(&curr_workspace, &options)?;
    if options.flag_verbose > 0 {
        config.shell().set_verbosity(Verbosity::Verbose);
    } else {
        config.shell().set_verbosity(Verbosity::Normal);
    }

    verbose!(config, "Parsing...", "compat workspace");
    let compat_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    compat_proj.write_manifest_semver(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "compat workspace");
    compat_proj.cargo_update()?;
    verbose!(config, "Resolving...", "compat workspace");
    let compat_workspace = compat_proj.workspace.borrow();
    let ela_compat =
        ElaborateWorkspace::from_workspace(compat_workspace.as_ref().unwrap(), &options)?;

    verbose!(config, "Parsing...", "latest workspace");
    let latest_proj =
        TempProject::from_workspace(&ela_curr, &curr_manifest.to_string_lossy(), &options)?;
    latest_proj.write_manifest_latest(
        curr_workspace.root(),
        compat_proj.temp_dir.path(),
        &ela_curr,
    )?;
    verbose!(config, "Updating...", "latest workspace");
    latest_proj.cargo_update()?;
    verbose!(config, "Resolving...", "latest workspace");
    let latest_workspace = latest_proj.workspace.borrow();
    let ela_latest =
        ElaborateWorkspace::from_workspace(latest_workspace.as_ref().unwrap(), &options)?;

    if ela_curr.workspace_mode {
        let mut sum = 0;
        verbose!(config, "Printing...", "Package status in list format");
        for member in ela_curr.workspace.members() {
            ela_curr.resolve_status(
                &ela_compat,
                &ela_latest,
                &options,
                config,
                member.package_id(),
            )?;
            sum += ela_curr.print_list(&options, member.package_id(), sum > 0)?;
        }
        if sum == 0 {
            println!("All dependencies are up to date, yay!");
        }
        Ok(sum)
    } else {
        verbose!(config, "Resolving...", "package status");
        let root = ela_curr.determine_root(&options)?;
        ela_curr.resolve_status(&ela_compat, &ela_latest, &options, config, root)?;
        verbose!(config, "Printing...", "list format");
        let count = ela_curr.print_list(&options, root, false)?;
        Ok(count)
    }
}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate commodore;

use commodore::Mux;
use hyper::server::Server;

fn main() {
    let addr = "0.0.0.0:6789";
    let mux: Mux = Default::default();
    let _ = Server::http(addr)
        .unwrap()
        .handle(mux);
}
<commit_msg>rm main<commit_after><|endoftext|>


<commit_before>mod words;

use std::env;

fn matches(pat: &String, line: &str) -> bool {
    fn check<P, L>(mut pc: P, lc: L) -> bool where P: Iterator<Item=char>, L: Iterator<Item=char> {
        let mut c = pc.next();
        for outer in lc {
            match c {
                Some(ch) => {
                    if outer == ch {
                        c = pc.next();
                    }
                    else if words::consonant(outer) {
                        return false;
                    }
                },

                None => {
                    return true;
                }
            }
        }

        false
    }

    check(pat.chars(), line.chars()) || check(pat.chars().rev(), line.chars().rev())
}

fn usage(args: Vec<String>) -> ! {
    println!("Usage: {} <consonants>", args[0]);
    std::process::exit(2);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        usage(args);
    }
    if args[1].chars().any(|c| {!words::consonant(c)}) {
        usage(args);
    }

    let words = words::WORDS.lines().map(|line| {
        line.to_lowercase()
    }).filter(|line| {
        matches(&args[1], line)
    });

    let mut found = false;
    for word in words {
        println!("{}", word);
        found = true;
    }
    if !found {
        println!("No matches found.");
    }
}
<commit_msg>Output words in decreasing length order.<commit_after>mod words;

use std::env;
use std::collections::{BTreeSet};

fn matches(pat: &String, line: &str) -> bool {
    fn check<P, L>(mut pc: P, lc: L) -> bool where P: Iterator<Item=char>, L: Iterator<Item=char> {
        let mut c = pc.next();
        for outer in lc {
            match c {
                Some(ch) => {
                    if outer == ch {
                        c = pc.next();
                        if c.is_none() {
                            return true;
                        }
                    }
                    else if words::consonant(outer) {
                        return false;
                    }
                },

                None => {
                    return true;
                }
            }
        }

        false
    }

    check(pat.chars(), line.chars()) || check(pat.chars().rev(), line.chars().rev())
}

fn usage(args: Vec<String>) -> ! {
    println!("Usage: {} <consonants>", args[0]);
    std::process::exit(2);
}

#[derive(Eq, PartialEq, PartialOrd)]
struct Word(String);

impl Ord for Word {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.0.len().cmp(&other.0.len()).reverse()
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() != 2 {
        usage(args);
    }
    if args[1].chars().any(|c| {!words::consonant(c)}) {
        usage(args);
    }

    let words = words::WORDS.lines().map(|line| {
        line.to_lowercase()
    }).filter(|line| {
        matches(&args[1], line)
    });

    let mut found = BTreeSet::new();
    for word in words {
        found.insert(Word(word));
    }
    if found.len() == 0 {
        println!("No matches found.");
        return;
    }

    for word in found.iter() {
        println!("{}", word.0);
    }
}
<|endoftext|>


<commit_before>extern crate git2;

use git2::Error;
use git2::{Repository,Branch,BranchType,Oid,Reference,StatusShow};
use git2::{StatusOptions,Statuses,Status,RepositoryState};
use git2::{STATUS_WT_MODIFIED,STATUS_WT_DELETED,STATUS_WT_NEW,STATUS_WT_TYPECHANGE,STATUS_WT_RENAMED};
use git2::{STATUS_INDEX_MODIFIED,STATUS_INDEX_DELETED,STATUS_INDEX_NEW,STATUS_INDEX_TYPECHANGE,STATUS_INDEX_RENAMED};

struct Program {
    repo: Repository,
}

fn get_branch_remote(reference: Reference) -> Option<Oid> {
    let b = Branch::wrap(reference);
    let upstream = match b.upstream() {
        Ok(u) => u,
        Err(_) => return None,
    };
    upstream.get().target()
}

fn get_ref_to_oid(reference: Reference) -> Oid {
    match reference.target() {
        Some(v) => v,
        None => panic!("Failed to get oid for reference."),
    }
}

impl Program {
    fn get_head(&self) -> Reference {
        match self.repo.head() {
            Ok(head) => head,
            Err(e) => panic!("Failed to get head: {}.", e)
        }
    }

    fn get_current_branch_oid(&self) -> Oid {
        let head = self.get_head();
        match head.target() {
            Some(v) => v,
            None => panic!("Failed to get reference to head."),
        }
    }

    fn get_current_branch_name(&self) -> String {
        match self.get_head().shorthand() {
            Some(v) => v.to_string(),
            None => panic!("Failed to get name of head."),
        }
    }

    // fn get_current_branch_remote(&self) -> String {
    //     let oid = self.get_current_branch_oid();
    //     let b = Branch::wrap(oid);
    //     let upstream = b.upstream().ok().unwrap();
    //     String::from(upstream.name().ok().unwrap().unwrap())
    // }

    fn get_current_branch_remote_oid(&self) -> Option<Oid> {
        get_branch_remote(self.get_head())
    }

    fn get_current_branch_ahead_behind(&self) -> Option<(usize, usize)> {
        let oid = match self.get_current_branch_remote_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(
            self.get_current_branch_oid(),
            oid
        );
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn get_upstream_branch_ahead_behind(&self) -> Option<(usize, usize)>  {
        let upstream_reference = match self.find_upstream_repo_branch() {
            Ok(u) => u.into_reference(),
            Err(_) => return None,
        };
        let res = self.repo.graph_ahead_behind(
            self.get_current_branch_oid(),
            get_ref_to_oid(upstream_reference),
        );
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn find_upstream_repo_branch(&self) -> Result<Branch, Error> {
        let us_branch_name = format!("{}{}", "upstream/", self.get_current_branch_name());
        self.repo.find_branch(&us_branch_name, BranchType::Remote)
    }

    fn get_status(&self) -> Statuses {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        let statuses = match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => s,
            Err(e) => panic!("failed to get statuses: {}", e),
        };
        statuses
    }

    fn get_repository_state(&self) -> RepositoryState {
        self.repo.state()
    }
}

fn main() {
    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(e) => panic!("failed to open: {}", e),
    };
    let program = Program{ repo: repo };
    println!("{}", program.get_current_branch_name());

    match program.get_current_branch_ahead_behind() {
        Some((ahead, behind)) => println!("A: {}, B: {}", ahead, behind),
        None => {}
    }

    match program.get_upstream_branch_ahead_behind() {
        Some((ahead, behind)) => println!("U A: {}, B: {}", ahead, behind),
        None => {}
    }

    let statuses = program.get_status();
    for s in statuses.iter() {
        let file_status = s.status();
        println!("{}", s.path().unwrap());
        if file_status.intersects(
            STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED
        ) {
            println!("changes");
        };
        if file_status.contains(STATUS_WT_NEW) {
            println!("new files");
        };
        if file_status.intersects(
            STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW
        ) {
            println!("index update");
        };
    }
    println!("{:?}", program.get_repository_state());
}
<commit_msg>add todo list<commit_after>// TODO:
//  * remove every panic!() -- this is meant for prompt
//  * add option to debug: print all errors
//  * create function to display everything
//  * colors

extern crate git2;

use git2::Error;
use git2::{Repository,Branch,BranchType,Oid,Reference,StatusShow};
use git2::{StatusOptions,Statuses,Status,RepositoryState};
use git2::{STATUS_WT_MODIFIED,STATUS_WT_DELETED,STATUS_WT_NEW,STATUS_WT_TYPECHANGE,STATUS_WT_RENAMED};
use git2::{STATUS_INDEX_MODIFIED,STATUS_INDEX_DELETED,STATUS_INDEX_NEW,STATUS_INDEX_TYPECHANGE,STATUS_INDEX_RENAMED};

struct Program {
    repo: Repository,
}

fn get_branch_remote(reference: Reference) -> Option<Oid> {
    let b = Branch::wrap(reference);
    let upstream = match b.upstream() {
        Ok(u) => u,
        Err(_) => return None,
    };
    upstream.get().target()
}

fn get_ref_to_oid(reference: Reference) -> Oid {
    match reference.target() {
        Some(v) => v,
        None => panic!("Failed to get oid for reference."),
    }
}

impl Program {
    fn get_head(&self) -> Reference {
        match self.repo.head() {
            Ok(head) => head,
            Err(e) => panic!("Failed to get head: {}.", e)
        }
    }

    fn get_current_branch_oid(&self) -> Oid {
        let head = self.get_head();
        match head.target() {
            Some(v) => v,
            None => panic!("Failed to get reference to head."),
        }
    }

    fn get_current_branch_name(&self) -> String {
        match self.get_head().shorthand() {
            Some(v) => v.to_string(),
            None => panic!("Failed to get name of head."),
        }
    }

    // fn get_current_branch_remote(&self) -> String {
    //     let oid = self.get_current_branch_oid();
    //     let b = Branch::wrap(oid);
    //     let upstream = b.upstream().ok().unwrap();
    //     String::from(upstream.name().ok().unwrap().unwrap())
    // }

    fn get_current_branch_remote_oid(&self) -> Option<Oid> {
        get_branch_remote(self.get_head())
    }

    fn get_current_branch_ahead_behind(&self) -> Option<(usize, usize)> {
        let oid = match self.get_current_branch_remote_oid() {
            Some(r) => r,
            None => return None
        };
        let res = self.repo.graph_ahead_behind(
            self.get_current_branch_oid(),
            oid
        );
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn get_upstream_branch_ahead_behind(&self) -> Option<(usize, usize)>  {
        let upstream_reference = match self.find_upstream_repo_branch() {
            Ok(u) => u.into_reference(),
            Err(_) => return None,
        };
        let res = self.repo.graph_ahead_behind(
            self.get_current_branch_oid(),
            get_ref_to_oid(upstream_reference),
        );
        match res {
            Ok(r) => Some(r),
            Err(_) => None
        }
    }

    fn find_upstream_repo_branch(&self) -> Result<Branch, Error> {
        let us_branch_name = format!("{}{}", "upstream/", self.get_current_branch_name());
        self.repo.find_branch(&us_branch_name, BranchType::Remote)
    }

    fn get_status(&self) -> Statuses {
        let mut so = StatusOptions::new();
        let mut opts = so.show(StatusShow::IndexAndWorkdir);
        opts.include_untracked(true);
        let statuses = match self.repo.statuses(Some(&mut opts)) {
            Ok(s) => s,
            Err(e) => panic!("failed to get statuses: {}", e),
        };
        statuses
    }

    fn get_repository_state(&self) -> RepositoryState {
        self.repo.state()
    }
}

fn main() {
    let repo = match Repository::open(".") {
        Ok(repo) => repo,
        Err(e) => panic!("failed to open: {}", e),
    };
    let program = Program{ repo: repo };
    println!("{}", program.get_current_branch_name());

    match program.get_current_branch_ahead_behind() {
        Some((ahead, behind)) => println!("A: {}, B: {}", ahead, behind),
        None => {}
    }

    match program.get_upstream_branch_ahead_behind() {
        Some((ahead, behind)) => println!("U A: {}, B: {}", ahead, behind),
        None => {}
    }

    let statuses = program.get_status();
    for s in statuses.iter() {
        let file_status = s.status();
        println!("{}", s.path().unwrap());
        if file_status.intersects(
            STATUS_WT_MODIFIED | STATUS_WT_DELETED | STATUS_WT_TYPECHANGE | STATUS_WT_RENAMED
        ) {
            println!("changes");
        };
        if file_status.contains(STATUS_WT_NEW) {
            println!("new files");
        };
        if file_status.intersects(
            STATUS_INDEX_MODIFIED | STATUS_INDEX_DELETED | STATUS_INDEX_TYPECHANGE | STATUS_INDEX_RENAMED | STATUS_INDEX_NEW
        ) {
            println!("index update");
        };
    }
    println!("{:?}", program.get_repository_state());
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]

mod snes_apu;

use std::iter;
use std::env;
use std::io::{Result, Error, ErrorKind, Write, stdout, stdin};
use std::thread;
use std::sync::{Arc, Mutex};
use snes_apu::apu::Apu;
use snes_apu::smp::Smp;
use snes_apu::spc::{Spc, Emulator};

fn main() {
    if let Err(e) = play_spc_files() {
        println!("ERROR: {}", e);
        std::process::exit(1);
    }
}

fn play_spc_files() -> Result<()> {
    for file_name in try!(get_file_names()) {
        try!(play_spc_file(&file_name));
    }
    Ok(())
}

fn get_file_names() -> Result<iter::Skip<env::Args>> {
    let args = env::args();
    match args.len() {
        1 => Err(Error::new(ErrorKind::Other, "No file(s) specified")),
        _ => Ok(args.skip(1))
    }
}

fn play_spc_file(file_name: &String) -> Result<()> {
    let spc = try!(Spc::load(file_name));

    println!("SPC: {}", file_name);
    println!(" Version Minor: {}", spc.version_minor);
    println!(" PC: {}", spc.pc);
    println!(" A: {}", spc.a);
    println!(" X: {}", spc.x);
    println!(" Y: {}", spc.y);
    println!(" PSW: {}", spc.psw);
    println!(" SP: {}", spc.sp);

    if let Some(id666_tag) = spc.id666_tag {
        println!(" ID666 tag present:");
        println!("  Song title: {}", id666_tag.song_title);
        println!("  Game title: {}", id666_tag.game_title);
        println!("  Dumper name: {}", id666_tag.dumper_name);
        println!("  Comments: {}", id666_tag.comments);
        println!("  Date dumped (MM/DD/YYYY): {}", id666_tag.date_dumped);
        println!("  Seconds to play before fading out: {}", id666_tag.seconds_to_play_before_fading_out);
        println!("  Fade out length: {}ms", id666_tag.fade_out_length);
        println!("  Artist name: {}", id666_tag.artist_name);
        println!("  Default channel disables: {}", id666_tag.default_channel_disables);
        println!("  Dumping emulator: {}", match id666_tag.dumping_emulator {
            Emulator::Unknown => "Unknown",
            Emulator::ZSnes => "ZSnes",
            Emulator::Snes9x => "Snes9x"
        });
    } else {
        println!(" No ID666 tag present.");
    }

    let mut apu = Apu::new();
    //let smp = Smp::new(&mut apu as *mut _);
    //apu.set_smp(smp);
    //apu.reset();

    println!("Return quits.");
    try!(wait_for_key_press_with_busy_icon());

    Ok(())
}

// TODO: This function is super thread-safe but can panic XD
fn wait_for_key_press_with_busy_icon() -> Result<()> {
    let is_done = Arc::new(Mutex::new(false));

    let thread_is_done = is_done.clone();
    let handle = thread::spawn(move || {
        let chars = ['-', '/', '|', '\\'];
        let mut char_index = 0;
        while !*(thread_is_done.lock().unwrap()) {
            print!("\r[{}]", chars[char_index]);
            stdout().flush().unwrap();
            char_index = (char_index + 1) % chars.len();

            thread::sleep_ms(5);
        }
        print!("\r   \r");
    });

    let mut s = String::new();
    try!(stdin().read_line(&mut s));
    *is_done.lock().unwrap() = true;
    handle.join().unwrap();

    Ok(())
}
<commit_msg>the cpu is officially doing SOMEthing :)<commit_after>#![feature(box_syntax)]

mod snes_apu;

use std::iter;
use std::env;
use std::io::{Result, Error, ErrorKind, Write, stdout, stdin};
use std::thread;
use std::sync::{Arc, Mutex};
use snes_apu::apu::Apu;
use snes_apu::smp::Smp;
use snes_apu::spc::{Spc, Emulator};

fn main() {
    if let Err(e) = play_spc_files() {
        println!("ERROR: {}", e);
        std::process::exit(1);
    }
}

fn play_spc_files() -> Result<()> {
    for file_name in try!(get_file_names()) {
        try!(play_spc_file(&file_name));
    }
    Ok(())
}

fn get_file_names() -> Result<iter::Skip<env::Args>> {
    let args = env::args();
    match args.len() {
        1 => Err(Error::new(ErrorKind::Other, "No file(s) specified")),
        _ => Ok(args.skip(1))
    }
}

fn play_spc_file(file_name: &String) -> Result<()> {
    let spc = try!(Spc::load(file_name));

    println!("SPC: {}", file_name);
    println!(" Version Minor: {}", spc.version_minor);
    println!(" PC: {}", spc.pc);
    println!(" A: {}", spc.a);
    println!(" X: {}", spc.x);
    println!(" Y: {}", spc.y);
    println!(" PSW: {}", spc.psw);
    println!(" SP: {}", spc.sp);

    if let Some(id666_tag) = spc.id666_tag {
        println!(" ID666 tag present:");
        println!("  Song title: {}", id666_tag.song_title);
        println!("  Game title: {}", id666_tag.game_title);
        println!("  Dumper name: {}", id666_tag.dumper_name);
        println!("  Comments: {}", id666_tag.comments);
        println!("  Date dumped (MM/DD/YYYY): {}", id666_tag.date_dumped);
        println!("  Seconds to play before fading out: {}", id666_tag.seconds_to_play_before_fading_out);
        println!("  Fade out length: {}ms", id666_tag.fade_out_length);
        println!("  Artist name: {}", id666_tag.artist_name);
        println!("  Default channel disables: {}", id666_tag.default_channel_disables);
        println!("  Dumping emulator: {}", match id666_tag.dumping_emulator {
            Emulator::Unknown => "Unknown",
            Emulator::ZSnes => "ZSnes",
            Emulator::Snes9x => "Snes9x"
        });
    } else {
        println!(" No ID666 tag present.");
    }

    let mut apu = Apu::new();
    let smp = Smp::new(&mut apu as *mut _);
    apu.set_smp(smp);
    apu.reset();

    // loltest
    apu.render(256);

    println!("Return quits.");
    try!(wait_for_key_press_with_busy_icon());

    Ok(())
}

// TODO: This function is super thread-safe but can panic XD
fn wait_for_key_press_with_busy_icon() -> Result<()> {
    let is_done = Arc::new(Mutex::new(false));

    let thread_is_done = is_done.clone();
    let handle = thread::spawn(move || {
        let chars = ['-', '/', '|', '\\'];
        let mut char_index = 0;
        while !*(thread_is_done.lock().unwrap()) {
            print!("\r[{}]", chars[char_index]);
            stdout().flush().unwrap();
            char_index = (char_index + 1) % chars.len();

            thread::sleep_ms(5);
        }
        print!("\r   \r");
    });

    let mut s = String::new();
    try!(stdin().read_line(&mut s));
    *is_done.lock().unwrap() = true;
    handle.join().unwrap();

    Ok(())
}
<|endoftext|>


<commit_before>#![cfg_attr(test, allow(dead_code))]

use std::path::Path;
use std::io::{self, Write};
use std::process::{self, Command};
use std::env;
use path_ext::PathExt;

use file_conflict::{
   ConflictType,
   Wuala,
   Dropbox
};

use user_reply::UserReply::{
   TakeFile,
   MoveToTrash,
   ShowDiff,
   ShowDiffWith,
   ShowDiffBetween,
   Skip,
   Quit,
   Help
};

use app_result::{
   AppResult,
   AppError
};

use args::{
   ResolveWuala,
   ResolveDropbox,
   PrintHelp,
   InvalidUsage
};

use file_system::{
   move_to_trash,
   move_file,
   trash_dir
};

mod app_result;
mod file_system;
mod file_conflict;
mod parser;
mod user_reply;
mod appdirs;
mod args;
mod path_ext;

fn main()
{
   let cmd = args::get_command();
   match cmd {
      ResolveWuala(path) => {
         resolve_conflicts(Wuala, &path)
            .unwrap_or_else(|err| { exit_with_error(&err); });
      }

      ResolveDropbox(path) => {
         resolve_conflicts(Dropbox, &path)
            .unwrap_or_else(|err| { exit_with_error(&err); });
      }

      PrintHelp => args::print_help(),

      InvalidUsage => {
         args::print_help();
      }
   }
}

fn exit_with_error(err: &AppError)
{
   writeln!(&mut io::stderr(), "{}", err).unwrap();
   process::exit(1);
}

/// Finds file conflicts of type `conf_type` starting at the directory `start_dir`,
/// recursively visiting every file, asking the user how each conflict should
/// be handled and then executing the user command.
fn resolve_conflicts(conf_type: ConflictType, start_dir: &Path) -> AppResult<()>
{
   let mut stdin = io::stdin();
   let mut stdout = io::stdout();

   let confs = try!(file_conflict::find(conf_type, start_dir));
   for conf in confs.iter() {
      if ! conf.original_path.is_file() {
         println!("\nFound conflicts for the file '{}', but the file itself is missing! Skipping it.",
                  conf.original_path.display());
         continue;
      }

      let num_conf_files = conf.conflicting_files.len();
      println!("\n{}", conf);

      loop {
         print!("{}", "(T)ake File (NUM) | (M)ove to Trash | Show (D)iff (NUM [NUM]) | (S)kip | (Q)uit | (H)elp: ");
         let _ = stdout.flush();

         let mut line = String::new();
         try!(stdin.read_line(&mut line));

         match user_reply::parse(&line, num_conf_files) {
            Some(reply) => {
               match reply {
                  TakeFile(num) => {
                     let ref take_file = conf.conflicting_files[num - 1].path;
                     for conf_file in conf.conflicting_files.iter() {
                        if conf_file.path != *take_file {
                           try!(move_to_trash(&conf_file.path));
                        }
                     }

                     try!(move_to_trash(&conf.original_path));
                     try!(move_file(take_file, &conf.original_path));

                     break;
                  }

                  MoveToTrash => {
                     for conf_file in conf.conflicting_files.iter() {
                        try!(move_to_trash(&conf_file.path));
                     }

                     break;
                  }

                  ShowDiff => {
                     try!(show_diff(&conf.original_path, &conf.conflicting_files[0].path));
                  }

                  ShowDiffWith(num) => {
                     try!(show_diff(&conf.original_path, &conf.conflicting_files[num - 1].path));
                  }

                  ShowDiffBetween(num1, num2) => {
                     try!(show_diff(&conf.conflicting_files[num1 - 1].path,
                                    &conf.conflicting_files[num2 - 1].path));
                  }

                  Skip => { break; }
                  Quit => { return Ok(()); }
                  Help => try!(print_runtime_help())
               }
            }

            None => {
               // remove newline at end of line
               line.pop();
               println!("\nInvalid user input: '{}' !\n", line);
            }
         }
      }
   }

   Ok(())
}

/// Calls the diff command specified by the environment variable `CONFSOLVE_DIFF`
/// or - if not defined - `gvimdiff -f` with the files `file1` and `file2`.
fn show_diff(file1: &Path, file2: &Path) -> AppResult<()>
{
   let diff_cmd_and_args = env::var("CONFSOLVE_DIFF").unwrap_or("gvimdiff -f".to_string());
   let diff_cmd_and_args = diff_cmd_and_args.split(' ').collect::<Vec<&str>>();

   let diff_cmd = diff_cmd_and_args[0];

   let args = diff_cmd_and_args.iter().skip(1);
   let mut cmd = Command::new(diff_cmd);
   for arg in args {
      cmd.arg(arg);
   }

   cmd.arg(file1);
   cmd.arg(file2);

   try!(cmd.output());
   Ok(())
}

fn print_runtime_help() -> AppResult<()>
{
   let trash_dir = try!(trash_dir());
   let dir_str   = trash_dir.display();

   println!("
Runtime Options:
   (T)ake File (NUM) => By pressing 't' and a number (e.g 't1'), the conflicting file with the
                        number NUM is used as the new version. A copy of the
                        current file and the other conflicting files is put
                        into the trash directory '{}'.

   (M)ove to Trash   => By pressing 'm', all conflicting files are
                        moved into the trash directory '{}'.

   Show (D)iff (NUM) => By pressing 'd' and a number (e.g 'd1'), the difference between the
                        current file and the conflicting file NUM is shown.
                        If there's only one conflicting file, then only pressing
                        'd' is sufficient.
                        By pressing 'd' and two numbers (e.g 'd1 2'), the difference between
                        the two conflicting files is shown.
                        The diff tool can be specified by the user by setting the environment
                        variable 'CONFSOLVE_DIFF'. The default diff tool is 'gvimdiff -f'.

   (S)kip            => By pressing 's', the current conflict is skipped
                        and the next one is shown.

   (Q)uit            => By pressing 'q', the application is quit.

   (H)elp            => By pressing 'h', this help is printed.\n", dir_str, dir_str);

   Ok(())
}
<commit_msg>Remove mut from stdin<commit_after>#![cfg_attr(test, allow(dead_code))]

use std::path::Path;
use std::io::{self, Write};
use std::process::{self, Command};
use std::env;
use path_ext::PathExt;

use file_conflict::{
   ConflictType,
   Wuala,
   Dropbox
};

use user_reply::UserReply::{
   TakeFile,
   MoveToTrash,
   ShowDiff,
   ShowDiffWith,
   ShowDiffBetween,
   Skip,
   Quit,
   Help
};

use app_result::{
   AppResult,
   AppError
};

use args::{
   ResolveWuala,
   ResolveDropbox,
   PrintHelp,
   InvalidUsage
};

use file_system::{
   move_to_trash,
   move_file,
   trash_dir
};

mod app_result;
mod file_system;
mod file_conflict;
mod parser;
mod user_reply;
mod appdirs;
mod args;
mod path_ext;

fn main()
{
   let cmd = args::get_command();
   match cmd {
      ResolveWuala(path) => {
         resolve_conflicts(Wuala, &path)
            .unwrap_or_else(|err| { exit_with_error(&err); });
      }

      ResolveDropbox(path) => {
         resolve_conflicts(Dropbox, &path)
            .unwrap_or_else(|err| { exit_with_error(&err); });
      }

      PrintHelp => args::print_help(),

      InvalidUsage => {
         args::print_help();
      }
   }
}

fn exit_with_error(err: &AppError)
{
   writeln!(&mut io::stderr(), "{}", err).unwrap();
   process::exit(1);
}

/// Finds file conflicts of type `conf_type` starting at the directory `start_dir`,
/// recursively visiting every file, asking the user how each conflict should
/// be handled and then executing the user command.
fn resolve_conflicts(conf_type: ConflictType, start_dir: &Path) -> AppResult<()>
{
   let stdin = io::stdin();
   let mut stdout = io::stdout();

   let confs = try!(file_conflict::find(conf_type, start_dir));
   for conf in confs.iter() {
      if ! conf.original_path.is_file() {
         println!("\nFound conflicts for the file '{}', but the file itself is missing! Skipping it.",
                  conf.original_path.display());
         continue;
      }

      let num_conf_files = conf.conflicting_files.len();
      println!("\n{}", conf);

      loop {
         print!("{}", "(T)ake File (NUM) | (M)ove to Trash | Show (D)iff (NUM [NUM]) | (S)kip | (Q)uit | (H)elp: ");
         let _ = stdout.flush();

         let mut line = String::new();
         try!(stdin.read_line(&mut line));

         match user_reply::parse(&line, num_conf_files) {
            Some(reply) => {
               match reply {
                  TakeFile(num) => {
                     let ref take_file = conf.conflicting_files[num - 1].path;
                     for conf_file in conf.conflicting_files.iter() {
                        if conf_file.path != *take_file {
                           try!(move_to_trash(&conf_file.path));
                        }
                     }

                     try!(move_to_trash(&conf.original_path));
                     try!(move_file(take_file, &conf.original_path));

                     break;
                  }

                  MoveToTrash => {
                     for conf_file in conf.conflicting_files.iter() {
                        try!(move_to_trash(&conf_file.path));
                     }

                     break;
                  }

                  ShowDiff => {
                     try!(show_diff(&conf.original_path, &conf.conflicting_files[0].path));
                  }

                  ShowDiffWith(num) => {
                     try!(show_diff(&conf.original_path, &conf.conflicting_files[num - 1].path));
                  }

                  ShowDiffBetween(num1, num2) => {
                     try!(show_diff(&conf.conflicting_files[num1 - 1].path,
                                    &conf.conflicting_files[num2 - 1].path));
                  }

                  Skip => { break; }
                  Quit => { return Ok(()); }
                  Help => try!(print_runtime_help())
               }
            }

            None => {
               // remove newline at end of line
               line.pop();
               println!("\nInvalid user input: '{}' !\n", line);
            }
         }
      }
   }

   Ok(())
}

/// Calls the diff command specified by the environment variable `CONFSOLVE_DIFF`
/// or - if not defined - `gvimdiff -f` with the files `file1` and `file2`.
fn show_diff(file1: &Path, file2: &Path) -> AppResult<()>
{
   let diff_cmd_and_args = env::var("CONFSOLVE_DIFF").unwrap_or("gvimdiff -f".to_string());
   let diff_cmd_and_args = diff_cmd_and_args.split(' ').collect::<Vec<&str>>();

   let diff_cmd = diff_cmd_and_args[0];

   let args = diff_cmd_and_args.iter().skip(1);
   let mut cmd = Command::new(diff_cmd);
   for arg in args {
      cmd.arg(arg);
   }

   cmd.arg(file1);
   cmd.arg(file2);

   try!(cmd.output());
   Ok(())
}

fn print_runtime_help() -> AppResult<()>
{
   let trash_dir = try!(trash_dir());
   let dir_str   = trash_dir.display();

   println!("
Runtime Options:
   (T)ake File (NUM) => By pressing 't' and a number (e.g 't1'), the conflicting file with the
                        number NUM is used as the new version. A copy of the
                        current file and the other conflicting files is put
                        into the trash directory '{}'.

   (M)ove to Trash   => By pressing 'm', all conflicting files are
                        moved into the trash directory '{}'.

   Show (D)iff (NUM) => By pressing 'd' and a number (e.g 'd1'), the difference between the
                        current file and the conflicting file NUM is shown.
                        If there's only one conflicting file, then only pressing
                        'd' is sufficient.
                        By pressing 'd' and two numbers (e.g 'd1 2'), the difference between
                        the two conflicting files is shown.
                        The diff tool can be specified by the user by setting the environment
                        variable 'CONFSOLVE_DIFF'. The default diff tool is 'gvimdiff -f'.

   (S)kip            => By pressing 's', the current conflict is skipped
                        and the next one is shown.

   (Q)uit            => By pressing 'q', the application is quit.

   (H)elp            => By pressing 'h', this help is printed.\n", dir_str, dir_str);

   Ok(())
}
<|endoftext|>


<commit_before>/* Stones esoteric programming language
 * (c) 2016 Zack Hixon - see LICENSE.txt */

#[derive(Debug)]
struct Stone {
    x: i32,
    y: i32,
    id: i32,
    color: String
}

fn main() {
    let mut stone = Stone {
        x: 0,
        y: 0,
        id: 1,
        color: String::from("yellow")
    };

    println!("{:?}", stone);

    stone.x = 1;
    stone.y = 1;
    stone.id = 2;
    stone.color = String::from("blue");

    println!("{:?}", stone);
}

<commit_msg>Add empty stone type<commit_after>/* Stones esoteric programming language
 * (c) 2016 Zack Hixon - see LICENSE.txt */

#[derive(Debug)]
struct Stone {
    x: i32,
    y: i32,
    id: i32,
    color: Color
}

impl Stone {
    fn new(x: i32, y: i32, id: i32, color: Color) -> Stone {
        Stone {
            x: x,
            y: y,
            id: id,
            color: color
        }
    }

    /* only check stones with 0 <= x <= 9 and 0 <= y <= 9 */
    fn empty() -> Stone {
        Stone {
            x: -1,
            y: -1,
            id: -1,
            color: Color::Red
        }
    }
}

#[derive(Debug)]
enum Color {
    Red,
    Orange,
    Yellow,
    Green,
    Blue,
    Purple
}

fn main() {
    println!("test stone: (debug)");

    let mut test_stone = Stone {
        x: 0,
        y: 0,
        id: 1,
        color: Color::Yellow
    };

    println!("{:?}", test_stone);

    test_stone.x = 1;
    test_stone.y = 1;
    test_stone.id = 2;
    test_stone.color = Color::Blue;

    println!("{:?}", test_stone);

    let mut field: Vec<Vec<Stone>> =
        vec![vec![Stone::new(0, 0, 1, Color::Red),
                  Stone::new(1, 0, 2, Color::Blue),
                  Stone::new(2, 0, 3, Color::Green)],
             vec![Stone::empty(),
                  Stone::empty(),
                  Stone::empty()],
             vec![Stone::empty(),
                  Stone::empty(),
                  Stone::empty()]];

    println!("\nall stones:");
    for row in field {
        for stone in row {
            print!("{} {} {} {:?}\n", stone.x, stone.y, stone.id, stone.color);
        }
        println!("");
    }
}

<|endoftext|>


<commit_before>extern crate clap;
extern crate rand;
use clap::{App, Arg};
use rand::Rng;
use std::fs::File;
use std::io;
use std::io::BufRead;
use std::io::BufReader;
use std::thread::sleep;
use std::time::Duration;

mod cat;

fn main() {
    let mut filename: String = "".to_string();
    let mut c = parse_cli_args(&mut filename);
    let stdin = io::stdin(); // For lifetime reasons

    if filename == "" {
        for line in stdin.lock().lines() {
            cat::print_with_lolcat(line.unwrap(), &mut c);
            if c.dialup_mode {
                let stall = Duration::from_millis(rand::thread_rng().gen_range(30, 200));
                sleep(stall);
            }
        }
    } else if lolcat_file(&filename, &mut c).is_err() {
        println!("Error opening file {}.", filename)
    }
}

fn lolcat_file(filename: &str, c: &mut cat::Control) -> Result<(), io::Error> {
    let f = try!(File::open(filename));
    let file = BufReader::new(&f);
    for line in file.lines() {
        cat::print_with_lolcat(line.unwrap(), c);

        if c.dialup_mode {
            let stall = Duration::from_millis(rand::thread_rng().gen_range(30, 700));
            sleep(stall);
        }
    }
    Ok(())
}

fn parse_cli_args(filename: &mut String) -> cat::Control {
    let matches = App::new("lolcat")
        .version("1.0.1")
        .author("Umang Raghuvanshi <u@umangis.me>")
        .about("The good ol' lolcat, now with fearless concurrency.")
        .arg(
            Arg::with_name("seed")
                .short("s")
                .long("seed")
                .help("A seed for your lolcat. Setting this to 0 randomizes the seed.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("spread")
                .short("S")
                .long("spread")
                .help("How much should we spread dem colors? Defaults to 3.0")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("frequency")
                .short("f")
                .long("frequency")
                .help("Frequency - used in our math. Defaults to 0.1")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("background")
                .short("B")
                .long("bg")
                .help("Background mode - If selected the background will be rainbow. Default false")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("dialup")
                .short("D")
                .long("dialup")
                .help("Dialup mode - Simulate dialup connection")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("filename")
                .short("i")
                .long("input file name")
                .help("Lolcat this file. Reads from STDIN if missing")
                .takes_value(true)
                .index(1),
        )
        .get_matches();

    let seed = matches.value_of("seed").unwrap_or("0.0");
    let spread = matches.value_of("spread").unwrap_or("3.0");
    let frequency = matches.value_of("frequency").unwrap_or("0.1");
    let background = matches.is_present("background");
    let dialup = matches.is_present("dialup");

    *filename = matches.value_of("filename").unwrap_or("").to_string();

    let mut seed: f64 = seed.parse().unwrap();
    let spread: f64 = spread.parse().unwrap();
    let frequency: f64 = frequency.parse().unwrap();

    if seed == 0.0 {
        seed = rand::random::<f64>() * 10e9;
    }

    cat::Control {
        seed,
        spread,
        frequency,
        background_mode: background,
        dialup_mode: dialup,
    }
}
<commit_msg>Remove try! usage<commit_after>extern crate clap;
extern crate rand;
use clap::{App, Arg};
use rand::Rng;
use std::fs::File;
use std::io;
use std::io::BufRead;
use std::io::BufReader;
use std::thread::sleep;
use std::time::Duration;

mod cat;

fn main() {
    let mut filename: String = "".to_string();
    let mut c = parse_cli_args(&mut filename);
    let stdin = io::stdin(); // For lifetime reasons

    if filename == "" {
        for line in stdin.lock().lines() {
            cat::print_with_lolcat(line.unwrap(), &mut c);
            if c.dialup_mode {
                let stall = Duration::from_millis(rand::thread_rng().gen_range(30, 200));
                sleep(stall);
            }
        }
    } else if lolcat_file(&filename, &mut c).is_err() {
        println!("Error opening file {}.", filename)
    }
}

fn lolcat_file(filename: &str, c: &mut cat::Control) -> Result<(), io::Error> {
    let f = File::open(filename)?;
    let file = BufReader::new(&f);
    for line in file.lines() {
        cat::print_with_lolcat(line.unwrap(), c);

        if c.dialup_mode {
            let stall = Duration::from_millis(rand::thread_rng().gen_range(30, 700));
            sleep(stall);
        }
    }
    Ok(())
}

fn parse_cli_args(filename: &mut String) -> cat::Control {
    let matches = App::new("lolcat")
        .version("1.0.1")
        .author("Umang Raghuvanshi <u@umangis.me>")
        .about("The good ol' lolcat, now with fearless concurrency.")
        .arg(
            Arg::with_name("seed")
                .short("s")
                .long("seed")
                .help("A seed for your lolcat. Setting this to 0 randomizes the seed.")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("spread")
                .short("S")
                .long("spread")
                .help("How much should we spread dem colors? Defaults to 3.0")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("frequency")
                .short("f")
                .long("frequency")
                .help("Frequency - used in our math. Defaults to 0.1")
                .takes_value(true),
        )
        .arg(
            Arg::with_name("background")
                .short("B")
                .long("bg")
                .help("Background mode - If selected the background will be rainbow. Default false")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("dialup")
                .short("D")
                .long("dialup")
                .help("Dialup mode - Simulate dialup connection")
                .takes_value(false),
        )
        .arg(
            Arg::with_name("filename")
                .short("i")
                .long("input file name")
                .help("Lolcat this file. Reads from STDIN if missing")
                .takes_value(true)
                .index(1),
        )
        .get_matches();

    let seed = matches.value_of("seed").unwrap_or("0.0");
    let spread = matches.value_of("spread").unwrap_or("3.0");
    let frequency = matches.value_of("frequency").unwrap_or("0.1");
    let background = matches.is_present("background");
    let dialup = matches.is_present("dialup");

    *filename = matches.value_of("filename").unwrap_or("").to_string();

    let mut seed: f64 = seed.parse().unwrap();
    let spread: f64 = spread.parse().unwrap();
    let frequency: f64 = frequency.parse().unwrap();

    if seed == 0.0 {
        seed = rand::random::<f64>() * 10e9;
    }

    cat::Control {
        seed,
        spread,
        frequency,
        background_mode: background,
        dialup_mode: dialup,
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;

#[derive(Debug)]
struct Token {
}

fn tokenize(source: &String) -> Vec<Token> {
    unimplemented!();
}

fn run(source: &String) -> i32 {
    let tokens = tokenize(source);
    for token in tokens {
        println!("{:?}", token);
    }
    0
}

fn run_file(file_name: &String) -> i32 {
    match File::open(file_name) {
        Err(e) => {
            println!("Error opening {}", file_name);
            1
        }
        Ok(mut file) => {
            let mut source = String::new();
            match file.read_to_string(&mut source) {
                Err(e) => {
                    println!("Error reading {}", file_name);
                    1
                }
                Ok(_) => run(&source),
            }
        }
    }
}

fn run_prompt() -> i32 {
    loop {
        print!("> ");
        io::stdout().flush();
        let mut source = String::new();
        match io::stdin().read_line(&mut source) {
            Ok(n) => {
                run(&source);
                ()
            }
            Err(e) => (),
        }
    }
    0
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let exit_code = match args.len() {
        // The first argument is the program name
        1 => run_prompt(),
        2 => run_file(&args[1]),
        _ => {
            println!("Usage: rulox [script]");
            1
        }
    };
    std::process::exit(exit_code)
}
<commit_msg>improved types<commit_after>use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;

#[derive(Debug)]
struct Token {
}

fn tokenize(source: &String) -> Result<Vec<Token>, String> {
    unimplemented!();
}

fn run(source: &String) -> Result<(), String> {
    let tokens = try!(tokenize(source));
    for token in tokens {
        println!("{:?}", token);
    }
    Ok(())
}

fn run_file(file_name: &String) -> Result<(), String> {
    match File::open(file_name) {
        Err(_) => {
            Err("Error opening file".into()) // TODO: add context
        }
        Ok(mut file) => {
            let mut source = String::new();
            match file.read_to_string(&mut source) {
                Err(_) => {
                    Err("Error reading file".into()) // TODO: add context
                }
                Ok(_) => run(&source),
            }
        }
    }
}

fn run_prompt() -> Result<(), String> {
    loop {
        print!("> ");
        io::stdout().flush();
        let mut source = String::new();
        io::stdin().read_line(&mut source);
        try!(run(&source));
        ()
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let result = match args.len() {
        // The first argument is the program name
        1 => run_prompt(),
        2 => run_file(&args[1]),
        _ => {
            println!("Usage: rulox [script]");
            Ok(())
        }
    };
    let exit_code = match result {
        Ok(_) => 0,
        Err(e) => {
            println!("{}", e);
            1
        }
    };
    std::process::exit(exit_code)
}
<|endoftext|>


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

use std::error::Error;
use std::fs::File;
use std::io::{self, Write};
use std::path::Path;
use std::str;

use docopt::Docopt;

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

const BUF_SIZE: usize = 4 * 1024 - 1;

const USAGE: &'static str = "
Base64 encode or decode FILE, or standard input, to standard output.

Usage: base64 [options] [<file>]
       base64 (--help | --version)

Options:
  -d --decode   decode data
  -h --help     display this help and exit
  --version     output version information and exit
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_file: String,
    flag_decode: bool,
    flag_help: bool,
    flag_version: bool,
}

fn encode(file: &mut io::Read) {
    let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
    let mut stdout = io::stdout();

    loop {
        match file.read(&mut buf[..]) {
            Ok(count) => {
                if count == 0 {
                    print!("\n");
                    break;
                }
                let res = base64::encode(&buf[..count]);
                stdout.write(&res).unwrap();
            },
            Err(err) => panic!(err),
        }
    }
}

fn decode(file: &mut io::Read) {
    let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
    let mut stdout = io::stdout();
    let mut stderr = io::stderr();

    loop {
        match file.read(&mut buf[..]) {
            Ok(count) => {
                if count == 0 {
                     break;
                }
                match base64::decode(&buf[..count]) {
                    Ok(res) => {
                        stdout.write(&res).unwrap();
                    },
                    Err(msg) => {
                        stderr.write(msg.as_bytes()).unwrap();

                    },
                }
            },
            Err(err) => panic!(err),
        }
    }
}

fn process(file: &mut io::Read, is_decode: bool) {
    if is_decode {
        decode(file);
    } else {
        encode(file);
    }
}

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

    if args.flag_version {
        println!("base64 v{}", VERSION);
        return;
    }

    if args.arg_file != "" {
        let path = Path::new(&args.arg_file);
        let mut file = match File::open(&path) {
            Err(why) => panic!("couldn't open {}: {}",
                               path.display(), why.description()),
            Ok(file) => file,
        };
        process(&mut file, args.flag_decode);
    } else {
        process(&mut io::stdin(), args.flag_decode);
    }
}
<commit_msg>Fix size of buffer<commit_after>extern crate base64;
extern crate docopt;
extern crate rustc_serialize;

use std::error::Error;
use std::fs::File;
use std::io::{self, Write};
use std::path::Path;
use std::str;

use docopt::Docopt;

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

// MAGIC (!) buf size divisible by 3 for encode and by 4 for decode
const BUF_SIZE: usize = 4092;

const USAGE: &'static str = "
Base64 encode or decode FILE, or standard input, to standard output.

Usage: base64 [options] [<file>]
       base64 (--help | --version)

Options:
  -d --decode   decode data
  -h --help     display this help and exit
  --version     output version information and exit
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_file: String,
    flag_decode: bool,
    flag_help: bool,
    flag_version: bool,
}

fn encode(file: &mut io::Read) {
    let mut buf = [0u8; BUF_SIZE];
    let mut stdout = io::stdout();

    loop {
        match file.read(&mut buf[..]) {
            Ok(count) => {
                if count == 0 {
                    print!("\n");
                    break;
                }
                let res = base64::encode(&buf[..count]);
                stdout.write(&res).unwrap();
            },
            Err(err) => panic!(err),
        }
    }
}

fn decode(file: &mut io::Read) {
    let mut buf = [0u8; BUF_SIZE];
    let mut stdout = io::stdout();
    let mut stderr = io::stderr();

    loop {
        match file.read(&mut buf[..]) {
            Ok(count) => {
                if count == 0 {
                     break;
                }
                match base64::decode(&buf[..count]) {
                    Ok(res) => {
                        stdout.write(&res).unwrap();
                    },
                    Err(msg) => {
                        stderr.write(msg.as_bytes()).unwrap();

                    },
                }
            },
            Err(err) => panic!(err),
        }
    }
}

fn process(file: &mut io::Read, is_decode: bool) {
    if is_decode {
        decode(file);
    } else {
        encode(file);
    }
}

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

    if args.flag_version {
        println!("base64 v{}", VERSION);
        return;
    }

    if args.arg_file != "" {
        let path = Path::new(&args.arg_file);
        let mut file = match File::open(&path) {
            Err(why) => panic!("couldn't open {}: {}",
                               path.display(), why.description()),
            Ok(file) => file,
        };
        process(&mut file, args.flag_decode);
    } else {
        process(&mut io::stdin(), args.flag_decode);
    }
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Read, stdin, stderr, BufReader, Write, BufRead};
use std::fs::File;
use std::process::exit;
use std::str::from_utf8;
use std::cmp::max;
use std::collections::HashMap;

use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

impl FileInfo {
    fn wrap_error<'a>(e: std::io::Error) -> FileInfoResult {
        Err(ProcessingError::IO(e))
    }
    fn process<T: Read>(reader: T) -> FileInfoResult {
        // TODO: Process reader
        let mut info = FileInfo{
            bytes: 0,
            chars: 0,
            lines: 0,
            words: 0,
            max_line_length: 0,
        };

        let mut rbuf = BufReader::new(reader);
        let mut lbuf: Vec<u8> = Vec::new();
        loop {
            let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
            info.bytes += size;
            if size == 0 {
                break;
            }
            // Create a scope because we're going to borrow lbuf and
            // the borrow must end before we can clear it.
            {
                let line = try!(from_utf8(&lbuf));
                let size = line.chars().count();
                info.max_line_length = match line.chars().last() {
                    Some(x) => {
                        if x == LF {
                            info.lines += 1;
                            max(info.max_line_length, size - 1)
                        } else {
                            max(info.max_line_length, size)
                        }
                    },
                    None => max(info.max_line_length, size),
                };
                info.chars += size;
                let words: Vec<&str> = line.split(|c: char| c.is_whitespace()).collect();
                for word in words {
                    if word.len() > 0 {
                        info.words += 1;
                    }

                }
            }
            lbuf.clear()
        }
        Ok(info)
    }
}

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

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

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut stderr(), "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut stderr(), "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        exit(1);
    }

    // TODO: Process --files0-from
    let mut results = HashMap::new();

    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        results.insert(filename, match filename {
            "-" => FileInfo::process(stdin()),
            _ => {
                let file = File::open(filename.to_string());
                match file {
                    Ok(f) => FileInfo::process(f),
                    Err(e) => FileInfo::wrap_error(e),
                }
            }
        });
    }
    for (filename, result) in results.iter() {
        match *result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = max(totals.max_line_length, r.max_line_length);
            },
            Err(_) => {},
        }
        println!("{}: {:?}", filename, result);
    }
    println!("total: {:?}", totals);

}
<commit_msg>Cleanup<commit_after>extern crate rustc_serialize;
extern crate docopt;

use std::io::{Read, stdin, stderr, BufReader, Write, BufRead};
use std::fs::File;
use std::process::exit;
use std::str::from_utf8;
use std::cmp::max;
use std::collections::HashMap;

use docopt::Docopt;

static LF: char = '\n';
static VERSION: &'static str = "0.0.1";
static USAGE: &'static str = "
Usage: wc [options] FILE...
       wc [options] --files0-from=F
       wc (-h|--help)
       wc (-v|--version)

Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, or when FILE is -,
read standard input. A word is a non-zero-length sequence of characters
delimited by white space.
The options below may be used to select which counts are printed, always in
the following order: newline, word, character, byte, maximum line length.

Options:
   -c, --bytes            print the byte counts
   -m, --chars            print the character counts
   -l, --lines            print the newline counts
   --files0-from=F        read input from the files specified by NUL-terminated
                          names in file F; If F is - then read names from
                          standard input
   -L, --max-line-length  print the length of the longest line
   -w, --words            print the word counts
   -h, --help             display this help and quit
   -v, --version          output version information and exit
";

#[allow(non_snake_case)]
#[derive(RustcDecodable, Debug)]
struct Args {
    arg_FILE: Vec<String>,
    flag_bytes: bool,
    flag_chars: bool,
    flag_lines: bool,
    flag_max_line_length: bool,
    flag_words: bool,
    flag_help: bool,
    flag_version: bool,
    flag_files0_from: String,
}

#[derive(Debug)]
enum ProcessingError {
    IO(std::io::Error),
    Utf8(std::str::Utf8Error),
}

impl From<std::io::Error> for ProcessingError {
    fn from(e: std::io::Error) -> ProcessingError {
        ProcessingError::IO(e)
    }
}
impl From<std::str::Utf8Error> for ProcessingError {
    fn from(e: std::str::Utf8Error) -> ProcessingError {
        ProcessingError::Utf8(e)
    }
}

#[derive(Debug)]
struct FileInfo{
    bytes: usize,
    chars: usize,
    lines: usize,
    words: usize,
    max_line_length: usize,
}

type FileInfoResult = Result<FileInfo, ProcessingError>;

impl FileInfo {
    fn wrap_error<'a>(e: std::io::Error) -> FileInfoResult {
        Err(ProcessingError::IO(e))
    }
    fn process<T: Read>(reader: T) -> FileInfoResult {
        let mut info = FileInfo{
            bytes: 0,
            chars: 0,
            lines: 0,
            words: 0,
            max_line_length: 0,
        };
        let mut rbuf = BufReader::new(reader);
        let mut lbuf: Vec<u8> = Vec::new();
        loop {
            let size = try!(rbuf.read_until(LF as u8, &mut lbuf));
            info.bytes += size;
            if size == 0 {
                break;
            }
            // Create a scope because we're going to borrow lbuf and
            // the borrow must end before we can clear it.
            {
                let line = try!(from_utf8(&lbuf));
                let size = line.chars().count();
                info.max_line_length = match line.chars().last() {
                    Some(c) => {
                        if c == LF {
                            info.lines += 1;
                            max(info.max_line_length, size - 1)
                        } else {
                            max(info.max_line_length, size)
                        }
                    },
                    None => max(info.max_line_length, size),
                };
                info.chars += size;
                let mut words: Vec<&str> = line.split(|c: char| c.is_whitespace()).collect();
                words.retain(|s: &&str| s.len() > 0);
                // words.retain(|s: &&str| s.len() > 0);
                info.words += words.len();
            }
            lbuf.clear()
        }
        Ok(info)
    }
}

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

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

    if args.flag_files0_from.len() != 0  && args.arg_FILE.len() != 0 {
        match writeln!(&mut stderr(), "wc: file operands cannot be combined with --files0-from") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        match writeln!(&mut stderr(), "Try 'wc --help' for more information") {
            Ok(_) => {},
            Err(e) => panic!("Unable to write to stderr: {}", e)
        }
        exit(1);
    }

    // TODO: Process --files0-from
    let mut results = HashMap::new();
    let mut totals = FileInfo{
        bytes: 0,
        chars: 0,
        lines: 0,
        words: 0,
        max_line_length: 0,
    };
    for file_arg in &args.arg_FILE {
        let filename = file_arg.as_ref();
        results.insert(filename, match filename {
            "-" => FileInfo::process(stdin()),
            _ => {
                let file = File::open(filename.to_string());
                match file {
                    Ok(f) => FileInfo::process(f),
                    Err(e) => FileInfo::wrap_error(e),
                }
            }
        });
    }
    for (filename, result) in results.iter() {
        match *result {
            Ok(ref r) => {
                totals.chars += r.chars;
                totals.lines += r.lines;
                totals.bytes += r.bytes;
                totals.words += r.words;
                totals.max_line_length = max(totals.max_line_length, r.max_line_length);
            },
            Err(_) => {},
        }
        println!("{}: {:?}", filename, result);
    }
    println!("total: {:?}", totals);

}
<|endoftext|>


<commit_before>use std::io::File;

mod parser;

fn main() {
    let input =
r#"{
let x = 0;
loop {
    __clear();
    __draw_pos(x, 5);
    __get_font(3);
    __draw(5);
    x = x + 1;
    __key_wait(0);
}
}"#;

    let code = parser::parse(input);
    for &op in code.iter() {
        print!("{:02x}", op);
    }
    println!("");

    let mut file = File::create(&Path::new("a.out"));
    file.write(code);
}
<commit_msg>Change to reading input from file<commit_after>use std::io::File;
use std::os;

mod parser;

fn main() {
    let args = os::args();
    if args.len() != 2 {
        println!("Invalid usage");
        return;
    }
    let input = match File::open(&Path::new(args[1])) {
        Some(mut f) => f.read_to_str(),
        None => { println!("Error reading file"); return; }
    };
    let code = parser::parse(input);
    let mut output = File::create(&Path::new("program.ch8"));
    output.write(code);
}
<|endoftext|>


<commit_before>#![feature(plugin)]

extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;
#[plugin] #[no_link] extern crate docopt_macros;

extern crate baps3_protocol;

use std::borrow::ToOwned;
use std::error;
use std::error::Error;
use std::io;
use std::io::net::ip;
use std::sync::mpsc;

use baps3_protocol::proto;
use baps3_protocol::server;

docopt!(Args, "
baps3-faked, a dummy BAPS3 service daemon

Usage:
    baps3-faked -h
    baps3-faked [-a ADDRESS]

Options:
    -a, --address=ADDRESS  Where to listen for connections (host:port).
                           [default: localhost:1350]
    -h, --help             Show this message.
");

enum FakedError {
    Io(io::IoError),
    Send
}

impl error::FromError<io::IoError> for FakedError {
    fn from_error(err: io::IoError) -> FakedError {
        FakedError::Io(err)
    }
}

impl<T> error::FromError<mpsc::SendError<T>> for FakedError {
    fn from_error(_: mpsc::SendError<T>) -> FakedError {
        FakedError::Send
    }
}

impl error::Error for FakedError {
    fn description(&self) -> &str {
        match *self {
            FakedError::Io(ref io) => io.description(),
            FakedError::Send => "send error"
        }
    }

    fn detail(&self) -> Option<String> {
        match *self {
            FakedError::Io(ref io) => io.detail(),
            _ => None
        }
    }
}

type FakedResult<A> = Result<A, FakedError>;

fn main() {
    let args: Args = Args::docopt()
                          .decode()
                          .unwrap_or_else(|e| e.exit());

    if let Err(e) = faked(args) {
        println!(
            "caught error: {} ({})",
            e.description(),
            &*e.detail().unwrap_or("no additional info".to_owned())
        );
    }
}

/// Says hi to a new connection.
fn hi(addr: ip::SocketAddr, tx: mpsc::Sender<server::Response>)
  -> FakedResult<()> {
    println!("new connection: {:?}", addr);

    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::new("OHAI", &["baps3-faked"])
    )));
    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::from_word("FEATURES")
    )));
    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::new("STATE", &["Ready"])
    )));

    Ok(())
}

/// Reports on a lost connection.
fn bye(addr: ip::SocketAddr) -> FakedResult<()> {
    println!("lost connection: {:?}", addr);

    Ok(())
}

/// Reports on a client message.
fn msg(addr: ip::SocketAddr, m: proto::Message) -> FakedResult<()> {
    println!("{:?} says: {} {:?}", addr, m.word(), m.args());

    Ok(())
}

/// The function holding most of the logic for faked.
fn faked(args: Args) -> FakedResult<()> {
    let server::Server {
        request_rx,
        response_tx
    } = try!(server::Server::new(&*args.flag_address));

    for request in request_rx.iter() {
        try!(match request {
            server::ctl::Request::Hi(addr) => hi(addr, response_tx.clone()),
            server::ctl::Request::Bye(addr) => bye(addr),
            server::ctl::Request::Message(addr, m) => msg(addr, m),
            server::ctl::Request::Gone => break,
            server::ctl::Request::ServerError(e) =>
                return Err(FakedError::Io(e))
        })
    }

    Ok(())
}
<commit_msg>Add and clean up stdout spew.<commit_after>#![feature(plugin)]

extern crate "rustc-serialize" as rustc_serialize;
extern crate docopt;
#[plugin] #[no_link] extern crate docopt_macros;

extern crate baps3_protocol;

use std::borrow::ToOwned;
use std::error;
use std::error::Error;
use std::io;
use std::io::net::ip;
use std::sync::mpsc;

use baps3_protocol::proto;
use baps3_protocol::server;

/// Name used for OHAI as well as server announcements.
static NAME: &'static str = "baps3-faked";

docopt!(Args, "
baps3-faked, a dummy BAPS3 service daemon

Usage:
    baps3-faked -h
    baps3-faked [-a ADDRESS]

Options:
    -a, --address=ADDRESS  Where to listen for connections (host:port).
                           [default: localhost:1350]
    -h, --help             Show this message.
");

enum FakedError {
    Io(io::IoError),
    Send
}

impl error::FromError<io::IoError> for FakedError {
    fn from_error(err: io::IoError) -> FakedError {
        FakedError::Io(err)
    }
}

impl<T> error::FromError<mpsc::SendError<T>> for FakedError {
    fn from_error(_: mpsc::SendError<T>) -> FakedError {
        FakedError::Send
    }
}

impl error::Error for FakedError {
    fn description(&self) -> &str {
        match *self {
            FakedError::Io(ref io) => io.description(),
            FakedError::Send => "send error"
        }
    }

    fn detail(&self) -> Option<String> {
        match *self {
            FakedError::Io(ref io) => io.detail(),
            _ => None
        }
    }
}

type FakedResult<A> = Result<A, FakedError>;

fn main() {
    let args: Args = Args::docopt()
                          .decode()
                          .unwrap_or_else(|e| e.exit());

    println!("{} is starting (listening on {})", NAME, &*args.flag_address);

    if let Err(e) = faked(args) {
        println!(
            "caught error: {} ({})",
            e.description(),
            &*e.detail().unwrap_or("no additional info".to_owned())
        );
    }

    println!("{} is terminating", NAME);
}

/// Says hi to a new connection.
fn hi(addr: ip::SocketAddr, tx: mpsc::Sender<server::Response>)
  -> FakedResult<()> {
    println!("new connection: {}", addr);

    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::new("OHAI", &[NAME])
    )));
    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::from_word("FEATURES")
    )));
    try!(tx.send(server::Response::Unicast(
        addr,
        proto::Message::new("STATE", &["Ready"])
    )));

    Ok(())
}

/// Reports on a lost connection.
fn bye(addr: ip::SocketAddr) -> FakedResult<()> {
    println!("lost connection: {}", addr);

    Ok(())
}

/// Reports on a client message.
fn msg(addr: ip::SocketAddr, m: proto::Message) -> FakedResult<()> {
    println!("{} says: {} {:?}", addr, m.word(), m.args());

    Ok(())
}

/// The function holding most of the logic for faked.
fn faked(args: Args) -> FakedResult<()> {
    let server::Server {
        request_rx,
        response_tx
    } = try!(server::Server::new(&*args.flag_address));

    for request in request_rx.iter() {
        try!(match request {
            server::ctl::Request::Hi(addr) => hi(addr, response_tx.clone()),
            server::ctl::Request::Bye(addr) => bye(addr),
            server::ctl::Request::Message(addr, m) => msg(addr, m),
            server::ctl::Request::Gone => break,
            server::ctl::Request::ServerError(e) =>
                return Err(FakedError::Io(e))
        })
    }

    Ok(())
}
<|endoftext|>