<commit_before>#![feature(collections)]

extern crate byteorder;
extern crate crc;
extern crate unix_socket;
extern crate nix;

use std::fs::File;
use std::io::{Read, Result, Error, Seek, SeekFrom};
use std::io::ErrorKind::Other;
use std::path::{Path, PathBuf};
use std::fs;
//use std::fs::PathExt;

use nix::sys::stat;

use byteorder::{LittleEndian, ByteOrder};

use crc::{crc32, Hasher32};

const LABEL_SCAN_SECTORS: usize = 4;
const MYPATH: &'static str = "/dev/mapper/luks-291e9250-200e-4c36-8e5e-66aa257669ed";
const ID_LEN: usize = 32;
const MDA_MAGIC: &'static [u8] = b"\x20\x4c\x56\x4d\x32\x20\x78\x5b\x35\x41\x25\x72\x30\x4e\x2a\x3e";
const INITIAL_CRC: u32 = 0xf597a6cf;
const SECTOR_SIZE: usize = 512;

mod lexer;

use lexer::{Lexer, Token};

use unix_socket::UnixStream;
use std::io::Write;

// TODO: Replace once PathExt is stable
trait MyPathExt {
    fn exists(&self) -> bool;
    fn is_file(&self) -> bool;
    fn is_dir(&self) -> bool;
}

impl MyPathExt for Path {
    fn exists(&self) -> bool {
        self.is_dir() || self.is_file()
    }
    fn is_file(&self) -> bool {
        match fs::metadata(self) {
            Ok(m) => m.is_file(),
            Err(_) => false
        }
    }
    fn is_dir(&self) -> bool {
        match fs::metadata(self) {
            Ok(m) => m.is_dir(),
            Err(_) => false
        }
    }
}

#[derive(Debug)]
struct Label {
    id: String,
    sector: u64,
    crc: u32,
    offset: u32,
    label: String,
}

#[derive(Debug)]
struct PvArea {
    offset: u64,
    size: u64,
}

#[derive(Debug)]
struct PvHeader {
    uuid: String,
    size: u64, // in bytes
    ext_version: u32,
    ext_flags: u32,
    data_areas: Vec<PvArea>,
    metadata_areas: Vec<PvArea>,
    bootloader_areas: Vec<PvArea>,
}

fn get_label(buf: &[u8]) -> Result<Label> {
    for x in 0..LABEL_SCAN_SECTORS {
        let sec_buf = &buf[x*SECTOR_SIZE..x*SECTOR_SIZE+SECTOR_SIZE];
        if &sec_buf[..8] == b"LABELONE" {
            let crc = LittleEndian::read_u32(&sec_buf[16..20]);
            crc32_ok(crc, &sec_buf[20..SECTOR_SIZE]);

            let sector = LittleEndian::read_u64(&sec_buf[8..16]);
            if sector != x as u64 {
                println!("sector field is {} in sector {}", sector, x);
            }

            return Ok(Label{
                id: String::from_utf8_lossy(&sec_buf[..8]).into_owned(),
                sector: sector,
                crc: crc,
                offset: LittleEndian::read_u32(&sec_buf[20..24]) + (x*SECTOR_SIZE as usize) as u32,
                label: String::from_utf8_lossy(&sec_buf[24..32]).into_owned(),
            })
        }
    }

    Err(Error::new(Other, "bad"))
}

#[derive(Debug)]
struct PvAreaIter<'a> {
    area: &'a[u8],
}

fn iter_pv_area<'a>(buf: &'a[u8]) -> PvAreaIter<'a> {
    PvAreaIter { area: buf }
}

impl<'a> Iterator for PvAreaIter<'a> {
    type Item = PvArea;

    fn next (&mut self) -> Option<PvArea> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[16..];
            Some(PvArea {
                offset: off,
                size: size,
            })
        }
    }
}

//
// PV HEADER LAYOUT:
// - static header (uuid and size)
// - 0+ data areas
// - blank entry
// - 0+ metadata areas
// - blank entry
// - 8 bytes of pvextension header
// - if version > 0
//   - list of bootloader areas
//
fn get_pv_header(buf: &[u8]) -> Result<PvHeader> {

    let mut da_buf = &buf[ID_LEN+8..];

    let da_vec: Vec<_> = iter_pv_area(da_buf).collect();

    // move slice past any actual entries plus blank
    // terminating entry
    da_buf = &da_buf[(da_vec.len()+1)*16..];

    let md_vec: Vec<_> = iter_pv_area(da_buf).collect();

    da_buf = &da_buf[(md_vec.len()+1)*16..];

    let ext_version = LittleEndian::read_u32(&da_buf[..4]);
    let mut ext_flags = 0;
    let mut ba_vec = Vec::new();

    if ext_version != 0 {
        ext_flags = LittleEndian::read_u32(&da_buf[4..8]);

        da_buf = &da_buf[8..];

        ba_vec = iter_pv_area(da_buf).collect();
    }

    Ok(PvHeader{
        uuid: String::from_utf8_lossy(&buf[..ID_LEN]).into_owned(),
        size: LittleEndian::read_u64(&buf[ID_LEN..ID_LEN+8]),
        ext_version: ext_version,
        ext_flags: ext_flags,
        data_areas: da_vec,
        metadata_areas: md_vec,
        bootloader_areas: ba_vec,
    })
}

fn crc32_ok(val: u32, buf: &[u8]) -> bool {
    let mut digest = crc32::Digest::new(INITIAL_CRC);
    digest.write(&buf);
    let crc32 = digest.sum32();

    // TODO: all our crcs are failing, how come?
    if val != crc32 {
        println!("CRC32: input {:x} != calculated {:x}", val, crc32);
    }
    val == crc32
}

#[derive(Debug)]
struct RawLocn {
    offset: u64,
    size: u64,
    checksum: u32,
    flags: u32,
}

#[derive(Debug)]
struct RawLocnIter<'a> {
    area: &'a[u8],
}

fn iter_raw_locn<'a>(buf: &'a[u8]) -> RawLocnIter<'a> {
    RawLocnIter { area: buf }
}

impl<'a> Iterator for RawLocnIter<'a> {
    type Item = RawLocn;

    fn next (&mut self) -> Option<RawLocn> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);
        let checksum = LittleEndian::read_u32(&self.area[16..20]);
        let flags = LittleEndian::read_u32(&self.area[20..24]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[24..];
            Some(RawLocn {
                offset: off,
                size: size,
                checksum: checksum,
                flags: flags,
            })
        }
    }
}

fn parse_mda_header(buf: &[u8]) -> () {

    crc32_ok(LittleEndian::read_u32(&buf[..4]), &buf[4..512]);

    if &buf[4..20] != MDA_MAGIC {
        println!("'{}' doesn't match '{}'", String::from_utf8_lossy(&buf[4..20]),
                 String::from_utf8_lossy(MDA_MAGIC));
    }

    let ver = LittleEndian::read_u32(&buf[20..24]);
    if ver != 1 {
        println!("bad version {}", ver);
    }

    println!("mdah start {}", LittleEndian::read_u64(&buf[24..32]));
    println!("mdah size {}", LittleEndian::read_u64(&buf[32..40]));

    for x in iter_raw_locn(&buf[40..]) {
        println!("rawlocn {:?}", x);
        let start = x.offset as usize;
        let end = start + x.size as usize;
        do_some_stuff(&buf[start..end]);
    }
}

fn find_label_in_dev(path: &Path) -> Result<Label> {

    let mut f = try!(File::open(path));

    let mut buf = vec![0; LABEL_SCAN_SECTORS * 512];

    try!(f.read(&mut buf));

    let label = try!(get_label(&buf));

    let pvheader = try!(get_pv_header(&buf[label.offset as usize..]));

    for md in &pvheader.metadata_areas {

        println!("mda {:?}", md);

        try!(f.seek(SeekFrom::Start(md.offset)));

        let mut buf = vec![0; md.size as usize];

        try!(f.read(&mut buf));

//        parse_mda_header(&buf);
    }

    return Ok(label);
}

fn scan_for_pvs(dirs: &[&Path]) -> Result<Vec<PathBuf>> {

    let mut ret_vec = Vec::new();

    for dir in dirs {
        for path in try!(fs::read_dir(dir)) {
            if let Ok(path) = path {
                let pathbuf = path.path();
                let s = stat::stat(&pathbuf);
                if let Ok(s) = s {
                    if (s.st_mode & 0x6000) == 0x6000 { // S_IFBLK
                        if find_label_in_dev(&pathbuf).is_ok() {
                            ret_vec.push(pathbuf);
                        }
                    }
                }
            }
        }
    }

    Ok(ret_vec)
}

fn main() {

    let dirs = vec![Path::new("/dev")];

    let pv_devs = scan_for_pvs(&dirs);

    println!("asdas {:?}", pv_devs);

 //   let label = find_label_in_dev(&PathBuf::from(MYPATH)).unwrap();

//    println!("{}", label.id);

    //open_lvmetad();
}

fn do_some_stuff(s: &[u8]) -> () {
    for token in Lexer::new(&s) {
        match token {
            Token::String(x) => { println!("string {}", String::from_utf8_lossy(x)) },
            Token::Comment(x) => { println!("comment {}", String::from_utf8_lossy(x)) },
            Token::Number(x) => { println!("number {}", x) },
            Token::Ident(x) => { println!("ident {}", String::from_utf8_lossy(x)) },
            _ => { println!("{:?}", token); },
        };
    }
}

fn read_response(stream: &mut UnixStream) -> Result<Vec<u8>> {
    let mut response = [0; 32];
    let mut v = Vec::new();

    loop {
        let bytes_read = try!(stream.read(&mut response));

        v.push_all(&response[..bytes_read]);

        if v.ends_with(b"\n##\n") {
            // drop the end marker
            let len = v.len() - 4;
            v.truncate(len);
            return Ok(v);
        }
    }
}

fn open_lvmetad() {

    lvmetad_request(b"hello", false);
//    lvmetad_request(b"vg_list", true);
//    lvmetad_request(b"pv_list", true);
//    lvmetad_request(b"dump", false);

}

fn lvmetad_request(s: &[u8], token: bool) {

    let path = "/run/lvm/lvmetad.socket";

    let mut stream = UnixStream::connect(path).unwrap();
    stream.write_all(b"request = \"").unwrap();
    stream.write_all(s).unwrap();
    stream.write_all(b"\"\n").unwrap();
    if token {
        stream.write_all(b"token = \"filter:0\"").unwrap();
        stream.write_all(b"\n").unwrap();
    }
    stream.write_all(b"\n##\n").unwrap();

    let r = read_response(&mut stream).unwrap();

    do_some_stuff(&r);
}
<commit_msg>document and name stuff better<commit_after>#![feature(collections)]

extern crate byteorder;
extern crate crc;
extern crate unix_socket;
extern crate nix;

use std::fs::File;
use std::io::{Read, Result, Error, Seek, SeekFrom};
use std::io::ErrorKind::Other;
use std::path::{Path, PathBuf};
use std::fs;

use nix::sys::stat;

use byteorder::{LittleEndian, ByteOrder};

use crc::{crc32, Hasher32};

const LABEL_SCAN_SECTORS: usize = 4;
const ID_LEN: usize = 32;
const MDA_MAGIC: &'static [u8] = b"\x20\x4c\x56\x4d\x32\x20\x78\x5b\x35\x41\x25\x72\x30\x4e\x2a\x3e";
const INITIAL_CRC: u32 = 0xf597a6cf;
const SECTOR_SIZE: usize = 512;

mod lexer;

use lexer::{Lexer, Token};

use unix_socket::UnixStream;
use std::io::Write;

// TODO: Replace once PathExt is stable
trait MyPathExt {
    fn exists(&self) -> bool;
    fn is_file(&self) -> bool;
    fn is_dir(&self) -> bool;
}

impl MyPathExt for Path {
    fn exists(&self) -> bool {
        self.is_dir() || self.is_file()
    }
    fn is_file(&self) -> bool {
        match fs::metadata(self) {
            Ok(m) => m.is_file(),
            Err(_) => false
        }
    }
    fn is_dir(&self) -> bool {
        match fs::metadata(self) {
            Ok(m) => m.is_dir(),
            Err(_) => false
        }
    }
}

#[derive(Debug)]
struct Label {
    id: String,
    sector: u64,
    crc: u32,
    offset: u32,
    label: String,
}

#[derive(Debug)]
struct PvArea {
    offset: u64,
    size: u64,
}

#[derive(Debug)]
struct PvHeader {
    uuid: String,
    size: u64, // in bytes
    ext_version: u32,
    ext_flags: u32,
    data_areas: Vec<PvArea>,
    metadata_areas: Vec<PvArea>,
    bootloader_areas: Vec<PvArea>,
}

fn get_label(buf: &[u8]) -> Result<Label> {

    for x in 0..LABEL_SCAN_SECTORS {
        let sec_buf = &buf[x*SECTOR_SIZE..x*SECTOR_SIZE+SECTOR_SIZE];
        if &sec_buf[..8] == b"LABELONE" {
            let crc = LittleEndian::read_u32(&sec_buf[16..20]);
            crc32_ok(crc, &sec_buf[20..SECTOR_SIZE]);

            let sector = LittleEndian::read_u64(&sec_buf[8..16]);
            if sector != x as u64 {
                return Err(Error::new(Other, "Sector field should equal sector count"));
            }

            return Ok(Label{
                id: String::from_utf8_lossy(&sec_buf[..8]).into_owned(),
                sector: sector,
                crc: crc,
                offset: LittleEndian::read_u32(&sec_buf[20..24]) + (x*SECTOR_SIZE as usize) as u32,
                label: String::from_utf8_lossy(&sec_buf[24..32]).into_owned(),
            })
        }
    }

    Err(Error::new(Other, "Label not found"))
}

#[derive(Debug)]
struct PvAreaIter<'a> {
    area: &'a[u8],
}

fn iter_pv_area<'a>(buf: &'a[u8]) -> PvAreaIter<'a> {
    PvAreaIter { area: buf }
}

impl<'a> Iterator for PvAreaIter<'a> {
    type Item = PvArea;

    fn next (&mut self) -> Option<PvArea> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[16..];
            Some(PvArea {
                offset: off,
                size: size,
            })
        }
    }
}

//
// PV HEADER LAYOUT:
// - static header (uuid and size)
// - 0+ data areas (actually max 1, usually 1; size 0 == "rest of blkdev")
// - blank entry
// - 0+ metadata areas (max 1, usually 1)
// - blank entry
// - 8 bytes of pvextension header
// - if version > 0
//   - 0+ bootloader areas (usually 0)
//
fn get_pv_header(buf: &[u8]) -> Result<PvHeader> {

    let mut da_buf = &buf[ID_LEN+8..];

    let da_vec: Vec<_> = iter_pv_area(da_buf).collect();

    // move slice past any actual entries plus blank
    // terminating entry
    da_buf = &da_buf[(da_vec.len()+1)*16..];

    let md_vec: Vec<_> = iter_pv_area(da_buf).collect();

    da_buf = &da_buf[(md_vec.len()+1)*16..];

    let ext_version = LittleEndian::read_u32(&da_buf[..4]);
    let mut ext_flags = 0;
    let mut ba_vec = Vec::new();

    if ext_version != 0 {
        ext_flags = LittleEndian::read_u32(&da_buf[4..8]);

        da_buf = &da_buf[8..];

        ba_vec = iter_pv_area(da_buf).collect();
    }

    Ok(PvHeader{
        uuid: String::from_utf8_lossy(&buf[..ID_LEN]).into_owned(),
        size: LittleEndian::read_u64(&buf[ID_LEN..ID_LEN+8]),
        ext_version: ext_version,
        ext_flags: ext_flags,
        data_areas: da_vec,
        metadata_areas: md_vec,
        bootloader_areas: ba_vec,
    })
}

fn crc32_ok(val: u32, buf: &[u8]) -> bool {
    let mut digest = crc32::Digest::new(INITIAL_CRC);
    digest.write(&buf);
    let crc32 = digest.sum32();

    // TODO: all our crcs are failing, how come?
    if val != crc32 {
        println!("CRC32: input {:x} != calculated {:x}", val, crc32);
    }
    val == crc32
}

#[derive(Debug)]
struct RawLocn {
    offset: u64,
    size: u64,
    checksum: u32,
    flags: u32,
}

#[derive(Debug)]
struct RawLocnIter<'a> {
    area: &'a[u8],
}

fn iter_raw_locn<'a>(buf: &'a[u8]) -> RawLocnIter<'a> {
    RawLocnIter { area: buf }
}

impl<'a> Iterator for RawLocnIter<'a> {
    type Item = RawLocn;

    fn next (&mut self) -> Option<RawLocn> {
        let off = LittleEndian::read_u64(&self.area[..8]);
        let size = LittleEndian::read_u64(&self.area[8..16]);
        let checksum = LittleEndian::read_u32(&self.area[16..20]);
        let flags = LittleEndian::read_u32(&self.area[20..24]);

        if off == 0 {
            None
        }
        else {
            self.area = &self.area[24..];
            Some(RawLocn {
                offset: off,
                size: size,
                checksum: checksum,
                flags: flags,
            })
        }
    }
}

fn parse_mda_header(buf: &[u8]) -> Result<()> {

    crc32_ok(LittleEndian::read_u32(&buf[..4]), &buf[4..512]);

    if &buf[4..20] != MDA_MAGIC {
        return Err(Error::new(
            Other, format!("'{}' doesn't match MDA_MAGIC",
                           String::from_utf8_lossy(&buf[4..20]))));
    }

    let ver = LittleEndian::read_u32(&buf[20..24]);
    if ver != 1 {
        return Err(Error::new(Other, format!("Bad version, expected 1")));
    }

    // TODO: validate these somehow
    //println!("mdah start {}", LittleEndian::read_u64(&buf[24..32]));
    //println!("mdah size {}", LittleEndian::read_u64(&buf[32..40]));

    for x in iter_raw_locn(&buf[40..]) {
        println!("rawlocn {:?}", x);
        let start = x.offset as usize;
        let end = start + x.size as usize;
        //lex_and_print(&buf[start..end]);
    }

    Ok(())
}

fn find_label_in_dev(path: &Path) -> Result<Label> {

    let mut f = try!(File::open(path));

    let mut buf = vec![0; LABEL_SCAN_SECTORS * 512];

    try!(f.read(&mut buf));

    let label = try!(get_label(&buf));

    let pvheader = try!(get_pv_header(&buf[label.offset as usize..]));

    println!("{:?}", &pvheader);

    for md in &pvheader.metadata_areas {

        try!(f.seek(SeekFrom::Start(md.offset)));

        let mut buf = vec![0; md.size as usize];

        try!(f.read(&mut buf));

        parse_mda_header(&buf);
    }

    return Ok(label);
}

fn scan_for_pvs(dirs: &[&Path]) -> Result<Vec<PathBuf>> {

    let mut ret_vec = Vec::new();

    for dir in dirs {
        for direntry in try!(fs::read_dir(dir)) {
            let path = direntry.unwrap().path();
            let s = stat::stat(&path).unwrap();

            if (s.st_mode & 0x6000) == 0x6000 { // S_IFBLK
                if find_label_in_dev(&path).is_ok() {
                    ret_vec.push(path);
                }
            }
        }
    }

    Ok(ret_vec)
}

fn main() {

    let dirs = vec![Path::new("/dev")];

    let pv_devs = scan_for_pvs(&dirs);

    //    println!("{}", label.id);

    //open_lvmetad();
}

fn lex_and_print(s: &[u8]) -> () {
    for token in Lexer::new(&s) {
        match token {
            Token::String(x) => { println!("string {}", String::from_utf8_lossy(x)) },
            Token::Comment(x) => { println!("comment {}", String::from_utf8_lossy(x)) },
            Token::Number(x) => { println!("number {}", x) },
            Token::Ident(x) => { println!("ident {}", String::from_utf8_lossy(x)) },
            _ => { println!("{:?}", token); },
        };
    }
}

fn read_response(stream: &mut UnixStream) -> Result<Vec<u8>> {
    let mut response = [0; 32];
    let mut v = Vec::new();

    loop {
        let bytes_read = try!(stream.read(&mut response));

        v.push_all(&response[..bytes_read]);

        if v.ends_with(b"\n##\n") {
            // drop the end marker
            let len = v.len() - 4;
            v.truncate(len);
            return Ok(v);
        }
    }
}

fn open_lvmetad() {

    lvmetad_request(b"hello", false);
//    lvmetad_request(b"vg_list", true);
//    lvmetad_request(b"pv_list", true);
//    lvmetad_request(b"dump", false);

}

fn lvmetad_request(s: &[u8], token: bool) {

    let path = "/run/lvm/lvmetad.socket";

    let mut stream = UnixStream::connect(path).unwrap();
    stream.write_all(b"request = \"").unwrap();
    stream.write_all(s).unwrap();
    stream.write_all(b"\"\n").unwrap();
    if token {
        stream.write_all(b"token = \"filter:0\"").unwrap();
        stream.write_all(b"\n").unwrap();
    }
    stream.write_all(b"\n##\n").unwrap();

    let r = read_response(&mut stream).unwrap();

    lex_and_print(&r);
}
<|endoftext|>


<commit_before>#[macro_use(shared_ntfy)]
extern crate rust_install;

extern crate chrono;
extern crate clap;
extern crate multirust;

extern crate rustc_bisect;

use chrono::{Datelike, NaiveDate};
use clap::{App, AppSettings, Arg};

use multirust::{Cfg, Notification};

use rustc_bisect::{Cmd, Error, Result, ToolchainSpec, bisect};

// Copied from multirust-rs.
fn set_globals() -> multirust::Result<Cfg> {
    // Base config
    let verbose = false;
    Cfg::from_env(shared_ntfy!(move |n: Notification| {
        use multirust::notify::NotificationLevel::*;
        match n.level() {
            Verbose => {
                if verbose {
                    println!("{}", n);
                }
            }
            _ => {
                println!("{}", n);
            }
        }
    }))
}

fn run_rust_bisect() -> Result<()> {
    let matches = App::new("rustc-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .setting(AppSettings::TrailingVarArg)
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("COMMAND")
                               .multiple(true)
                               .required(true))
                      .get_matches();

    let cfg = try!(set_globals());

    use std::str::FromStr;

    let good = matches.value_of("good").expect("good");
    let good_spec = try!(ToolchainSpec::from_str(good));

    let bad = matches.value_of("bad").expect("bad");
    let bad_spec = try!(ToolchainSpec::from_str(bad));

    fn get_nightly_date(spec: ToolchainSpec) -> Result<NaiveDate> {
        match spec {
            ToolchainSpec::Nightly(date) => Ok(date),
            _ => Err(Error::from("only nightlies for now")),
        }
    }

    let good_date = try!(get_nightly_date(good_spec));
    let bad_date = try!(get_nightly_date(bad_spec));

    let cmd: Vec<_> = matches.values_of_os("COMMAND").expect("COMMAND").collect();
    let cmd = Cmd::from(&cmd[..]);

    let range = good_date.num_days_from_ce()..bad_date.num_days_from_ce();

    let out = bisect(range, |num_days| {
        let spec = ToolchainSpec::Nightly(NaiveDate::from_num_days_from_ce(num_days));
        let toolchain = cfg.get_toolchain(&spec.to_string(), false).expect("get_toolchain");

        if toolchain.install_from_dist_if_not_installed().is_err() {
            return None;
        }

        let res = cmd.succeeds_with(&toolchain).expect("run command");

        println!("command {} at {}", if res { "succeeded" } else { "failed" }, spec);
        Some(!res)
    }).expect("bisect");

    println!("{:?} {:?}", out, NaiveDate::from_num_days_from_ce(out));

    Ok(())
}

fn main() {
    run_rust_bisect().expect("something went wrong");
}
<commit_msg>Silence multirust<commit_after>extern crate chrono;
extern crate clap;
extern crate multirust;
extern crate rust_install;

extern crate rustc_bisect;

use chrono::{Datelike, NaiveDate};
use clap::{App, AppSettings, Arg};

use rustc_bisect::{Cmd, Error, Result, ToolchainSpec, bisect};

fn run_rust_bisect() -> Result<()> {
    let matches = App::new("rustc-bisect")
                      .author("Kamal Marhubi <kamal@marhubi.com>")
                      .setting(AppSettings::TrailingVarArg)
                      .arg(Arg::with_name("good")
                               .long("good")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("bad")
                               .long("bad")
                               .takes_value(true)
                               .value_name("TOOLCHAIN")
                               .required(true))
                      .arg(Arg::with_name("COMMAND")
                               .multiple(true)
                               .required(true))
                      .get_matches();

    let cfg = try!(multirust::Cfg::from_env(rust_install::notify::SharedNotifyHandler::none()));

    use std::str::FromStr;

    let good = matches.value_of("good").expect("good");
    let good_spec = try!(ToolchainSpec::from_str(good));

    let bad = matches.value_of("bad").expect("bad");
    let bad_spec = try!(ToolchainSpec::from_str(bad));

    fn get_nightly_date(spec: ToolchainSpec) -> Result<NaiveDate> {
        match spec {
            ToolchainSpec::Nightly(date) => Ok(date),
            _ => Err(Error::from("only nightlies for now")),
        }
    }

    let good_date = try!(get_nightly_date(good_spec));
    let bad_date = try!(get_nightly_date(bad_spec));

    let cmd: Vec<_> = matches.values_of_os("COMMAND").expect("COMMAND").collect();
    let cmd = Cmd::from(&cmd[..]);

    let range = good_date.num_days_from_ce()..bad_date.num_days_from_ce();

    let out = bisect(range, |num_days| {
        let spec = ToolchainSpec::Nightly(NaiveDate::from_num_days_from_ce(num_days));
        let toolchain = cfg.get_toolchain(&spec.to_string(), false).expect("get_toolchain");

        if toolchain.install_from_dist_if_not_installed().is_err() {
            return None;
        }

        let res = cmd.succeeds_with(&toolchain).expect("run command");

        println!("command {} at {}", if res { "succeeded" } else { "failed" }, spec);
        Some(!res)
    }).expect("bisect");

    println!("{:?} {:?}", out, NaiveDate::from_num_days_from_ce(out));

    Ok(())
}

fn main() {
    run_rust_bisect().expect("something went wrong");
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate serde;
#[macro_use] extern crate serde_derive;
extern crate serde_json;

mod data;

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

fn main() {
    let matches = App::new(env!("CARGO_PKG_NAME"))
                        .version(env!("CARGO_PKG_VERSION"))
                        .author(env!("CARGO_PKG_AUTHORS"))
                        .about(env!("CARGO_PKG_DESCRIPTION"))
                        .arg(Arg::with_name("version")
                                    .short("v")
                                    .long("version")
                                    .help("Prints version information"))
                        .get_matches();

    if matches.is_present("version") {
        println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
    }
}
<commit_msg>simplify --version handling<commit_after>extern crate clap;
extern crate serde;
#[macro_use] extern crate serde_derive;
extern crate serde_json;

mod data;

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

fn main() {
    let matches = App::new(env!("CARGO_PKG_NAME"))
                        .version(env!("CARGO_PKG_VERSION"))
                        .author(env!("CARGO_PKG_AUTHORS"))
                        .about(env!("CARGO_PKG_DESCRIPTION"))
                        .get_matches();
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate getopts;
#[macro_use]
extern crate shoop;

use std::str;
use std::env;
use std::path::Path;
use getopts::Options;
use shoop::{ShoopLogger, Server, download};
use shoop::connection::PortRange;

const DEFAULT_PORT_RANGE: &'static str = "55000-55050";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Shoop is a ultrafast, (hopefully) secure file transfer tool, that is
\
                         (hopefully) ideal for transferring large files.

Usage: {0} [options] \
                         HOST:PATH DEST
...where HOST is an SSH host
...where PATH is the path \
                         on the *remote* machine of the file you want
...where DEST is either an \
                         existing folder or a location for the new
                 file (\".\" \
                         by default)

Example: {0} \
                         seedbox.facebook.com:/home/zuck/internalized_sadness.zip .",
                        program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    enum Mode {
        Server,
        Client,
    }
    ShoopLogger::init().expect("Error starting shoop logger.");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // TODO
    // opts.optopt("o", "output", "set output file name", "NAME");
    // opts.optopt("a", "ssh-args", "arguments to pass to ssh directly (at your own risk)", ARGS);
    opts.optopt("p",
                "port-range",
                "server listening port range",
                DEFAULT_PORT_RANGE);
    opts.optflag("s", "server", "server mode (advanced usage only)");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

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

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

    let mode: Mode = if matches.opt_present("s") {
        Mode::Server
    } else {
        Mode::Client
    };

    let port_range = {
        let range_opt = &matches.opt_str("p").unwrap_or_else(|| String::from(DEFAULT_PORT_RANGE));
        PortRange::from(range_opt).unwrap()
    };

    match mode {
        Mode::Server => {
            Server::new(port_range, &input).start();
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(':').collect();
            let remote_addr: String = sections[0].to_owned();
            let remote_path_str = &sections[1].to_owned();
            let remote_path = Path::new(remote_path_str);
            let remote_file_name = match remote_path.file_name() {
                Some(s) => s,
                None => {
                    die!("The remote path specified doesn't look like a path to a file.");
                }
            };

            let output = if matches.free.len() > 1 {
                matches.free[1].clone()
            } else {
                String::from(".")
            };

            let output_path = Path::new(&output);
            let dest_path = if output_path.is_dir() {
                output_path.join(remote_file_name)
            } else {
                output_path.to_path_buf()
            };

            download(&remote_addr, port_range, remote_path_str, dest_path);
        }
    }
}
<commit_msg>i don't know why rustfmt did that<commit_after>#[macro_use]
extern crate log;
extern crate getopts;
#[macro_use]
extern crate shoop;

use std::str;
use std::env;
use std::path::Path;
use getopts::Options;
use shoop::{ShoopLogger, Server, download};
use shoop::connection::PortRange;

const DEFAULT_PORT_RANGE: &'static str = "55000-55050";

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Shoop is a ultrafast, (hopefully) secure file transfer tool, that is
(hopefully) ideal for transferring large files.

Usage: {0} [options] HOST:PATH DEST
...where HOST is an SSH host
...where PATH is the path on the *remote* machine of the file you want
...where DEST is either an existing folder or a location for the new
                 file (\".\" by default)

Example: {0} seedbox.facebook.com:/home/zuck/internalized_sadness.zip .",
                        program);
    print!("{}", opts.usage(&brief));
}

fn main() {
    enum Mode {
        Server,
        Client,
    }
    ShoopLogger::init().expect("Error starting shoop logger.");

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    // TODO
    // opts.optopt("o", "output", "set output file name", "NAME");
    // opts.optopt("a", "ssh-args", "arguments to pass to ssh directly (at your own risk)", ARGS);
    opts.optopt("p",
                "port-range",
                "server listening port range",
                DEFAULT_PORT_RANGE);
    opts.optflag("s", "server", "server mode (advanced usage only)");
    opts.optflag("h", "help", "print this help menu");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };

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

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

    let mode: Mode = if matches.opt_present("s") {
        Mode::Server
    } else {
        Mode::Client
    };

    let port_range = {
        let range_opt = &matches.opt_str("p").unwrap_or_else(|| String::from(DEFAULT_PORT_RANGE));
        PortRange::from(range_opt).unwrap()
    };

    match mode {
        Mode::Server => {
            Server::new(port_range, &input).start();
        }
        Mode::Client => {
            let sections: Vec<&str> = input.split(':').collect();
            let remote_addr: String = sections[0].to_owned();
            let remote_path_str = &sections[1].to_owned();
            let remote_path = Path::new(remote_path_str);
            let remote_file_name = match remote_path.file_name() {
                Some(s) => s,
                None => {
                    die!("The remote path specified doesn't look like a path to a file.");
                }
            };

            let output = if matches.free.len() > 1 {
                matches.free[1].clone()
            } else {
                String::from(".")
            };

            let output_path = Path::new(&output);
            let dest_path = if output_path.is_dir() {
                output_path.join(remote_file_name)
            } else {
                output_path.to_path_buf()
            };

            download(&remote_addr, port_range, remote_path_str, dest_path);
        }
    }
}
<|endoftext|>


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

#![feature(test)]

extern crate jsrs_common;
extern crate jsrs_parser;
extern crate french_press;

extern crate walkdir;
extern crate unescape;
extern crate rustyline;
extern crate rustc_serialize;
extern crate docopt;

extern crate test;

mod js_error;
mod var;

mod eval;
mod native;
mod number;
mod bench;
mod preprocess;

use std::cell::RefCell;
use std::fs::{File, metadata};
use std::io::{self, BufReader};
use std::io::prelude::*;
use std::path::Path;
use std::process::exit;
use std::rc::Rc;

use rustyline::error::ReadlineError;
use rustyline::Editor;
use walkdir::WalkDir;

use jsrs_common::types::js_var::JsPtrEnum;
use french_press::{init_gc, ScopeManager};

use eval::eval_string;
use native::add_pervasives;
use preprocess::clean_string;

docopt!(Args derive Debug, "
js.rs - a javascript interpreter

Usage:
jsrs
jsrs <file>
jsrs --test
");

fn eval_file(filename: String, debug: bool, should_repl: bool,
             scope_manager: Rc<RefCell<ScopeManager>>) -> js_error::Result<()> {
    if debug {
        println!("Reading from \"{}\"", filename);
    }

    let path = Path::new(&filename);
    let file = File::open(&path)
        .expect(&format!("Cannot open \"{}\": no such file or directory", filename));
    let file_buffer = BufReader::new(file);

    let mut line_builder = String::new();
    let mut braces = Vec::new();

    let mut file_iter = file_buffer.lines();
    loop {
        if let Some(line) = file_iter.next() {
            let input = String::from(line.expect(&format!("Cannot read from {}", filename))
                                         .trim());
            if let Some(input) = clean_string(input) {
                let mut last = '\0';
                // Match braces to see if we should wait for more input
                for c in input.chars() {
                    if c == '(' {
                        braces.push('(');
                    } else if c == '{' {
                        braces.push('{');
                    } else if c == '*' && last == '/' {
                        braces.push('/');
                    } else if c == ')' {
                        if braces.pop() != Some('(') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    } else if c == '}' {
                        if braces.pop() != Some('{') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    } else if c == '/' && last == '*' {
                        if braces.pop() != Some('/') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    }
                    last = c;
                }

                line_builder.push_str(&input);

                if braces.len() == 0 {
                    if let Some(js_string) = clean_string(line_builder.clone()) {
                        line_builder = String::new();
                        if debug {
                            println!("\n{}", js_string);
                        }

                        let ret = try!(eval_string(&js_string, scope_manager.clone()));
                        if debug {
                            println!("=> {:?}", ret);
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    if should_repl {
        repl(scope_manager);
    }
    Ok(())
}

fn test_dir(dir_name: String) {
    for entry in WalkDir::new(dir_name) {
        let entry = entry.unwrap();
        if !entry.path().is_dir() {
            let entry_path = entry.path().display().to_string();
            let scope_manager = Rc::new(RefCell::new(init_gc()));
            add_pervasives(scope_manager.clone());
            match eval_file(entry_path.clone(), false, false, scope_manager.clone()) {
                Ok(_) => {
                    println!("{}: {}", entry_path, "OK");
                }
                Err(e) => {
                    println!("{}: {}", entry_path, e);
                }
            }
        }
    }
}

fn repl(scope_manager: Rc<RefCell<ScopeManager>>) -> i32 {
    let mut rl = Editor::new();
    let mut stderr = io::stderr();

    if metadata(".history").is_ok() && rl.load_history(".history").is_err() {
        writeln!(stderr, "Error: unable to load history on startup").unwrap();
    }

    loop {
        // prompt
        let readline = rl.readline(">> ");

        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                let input = String::from(line.trim());
                clean_string(input).map(|input| {
                    rl.add_history_entry(&input);

                    match eval_string(&input, scope_manager.clone()) {
                        Ok((var, ptr)) => {
                            match ptr {
                                Some(JsPtrEnum::JsSym(s)) => println!("=> Symbol({:?})", s),
                                Some(JsPtrEnum::JsStr(s)) => println!("=> {:?}", s.text),
                                _ => println!("=> {:?}", var.t),
                            }
                        },
                        Err(e) => {
                            println!("{:?}", e);
                        }
                    }
                });
            },
            Err(ReadlineError::Interrupted) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 1;
            },
            Err(ReadlineError::Eof) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);

                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 3;
            }
        }
    }
    0
}

fn main() {
    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_test {
        let dir_name = "sputnik";

        test_dir(String::from(dir_name))
    } else {
        let scope_manager = Rc::new(RefCell::new(init_gc()));
        add_pervasives(scope_manager.clone());

        if args.arg_file == "" {
            let ret = repl(scope_manager.clone());
            exit(ret)
        } else {
            eval_file(args.arg_file, true, true, scope_manager.clone());
        }
    }
}
<commit_msg>deal with result from eval_file<commit_after>#![feature(plugin)]
#![plugin(docopt_macros)]

#![feature(test)]

extern crate jsrs_common;
extern crate jsrs_parser;
extern crate french_press;

extern crate walkdir;
extern crate unescape;
extern crate rustyline;
extern crate rustc_serialize;
extern crate docopt;

extern crate test;

mod js_error;
mod var;

mod eval;
mod native;
mod number;
mod bench;
mod preprocess;

use std::cell::RefCell;
use std::fs::{File, metadata};
use std::io::{self, BufReader};
use std::io::prelude::*;
use std::path::Path;
use std::process::exit;
use std::rc::Rc;

use rustyline::error::ReadlineError;
use rustyline::Editor;
use walkdir::WalkDir;

use jsrs_common::types::js_var::JsPtrEnum;
use french_press::{init_gc, ScopeManager};

use eval::eval_string;
use native::add_pervasives;
use preprocess::clean_string;

docopt!(Args derive Debug, "
js.rs - a javascript interpreter

Usage:
jsrs
jsrs <file>
jsrs --test
");

fn eval_file(filename: String, debug: bool, should_repl: bool,
             scope_manager: Rc<RefCell<ScopeManager>>) -> js_error::Result<()> {
    if debug {
        println!("Reading from \"{}\"", filename);
    }

    let path = Path::new(&filename);
    let file = File::open(&path)
        .expect(&format!("Cannot open \"{}\": no such file or directory", filename));
    let file_buffer = BufReader::new(file);

    let mut line_builder = String::new();
    let mut braces = Vec::new();

    let mut file_iter = file_buffer.lines();
    loop {
        if let Some(line) = file_iter.next() {
            let input = String::from(line.expect(&format!("Cannot read from {}", filename))
                                         .trim());
            if let Some(input) = clean_string(input) {
                let mut last = '\0';
                // Match braces to see if we should wait for more input
                for c in input.chars() {
                    if c == '(' {
                        braces.push('(');
                    } else if c == '{' {
                        braces.push('{');
                    } else if c == '*' && last == '/' {
                        braces.push('/');
                    } else if c == ')' {
                        if braces.pop() != Some('(') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    } else if c == '}' {
                        if braces.pop() != Some('{') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    } else if c == '/' && last == '*' {
                        if braces.pop() != Some('/') {
                            panic!("parse error: unexpected token {}", c);
                        }
                    }
                    last = c;
                }

                line_builder.push_str(&input);

                if braces.len() == 0 {
                    if let Some(js_string) = clean_string(line_builder.clone()) {
                        line_builder = String::new();
                        if debug {
                            println!("\n{}", js_string);
                        }

                        let ret = try!(eval_string(&js_string, scope_manager.clone()));
                        if debug {
                            println!("=> {:?}", ret);
                        }
                    }
                }
            }
        } else {
            break;
        }
    }
    if should_repl {
        repl(scope_manager);
    }
    Ok(())
}

fn test_dir(dir_name: String) {
    for entry in WalkDir::new(dir_name) {
        let entry = entry.unwrap();
        if !entry.path().is_dir() {
            let entry_path = entry.path().display().to_string();
            let scope_manager = Rc::new(RefCell::new(init_gc()));
            add_pervasives(scope_manager.clone());
            match eval_file(entry_path.clone(), false, false, scope_manager.clone()) {
                Ok(_) => {
                    println!("{}: {}", entry_path, "OK");
                }
                Err(e) => {
                    println!("{}: {}", entry_path, e);
                }
            }
        }
    }
}

fn repl(scope_manager: Rc<RefCell<ScopeManager>>) -> i32 {
    let mut rl = Editor::new();
    let mut stderr = io::stderr();

    if metadata(".history").is_ok() && rl.load_history(".history").is_err() {
        writeln!(stderr, "Error: unable to load history on startup").unwrap();
    }

    loop {
        // prompt
        let readline = rl.readline(">> ");

        match readline {
            Ok(line) => {
                rl.add_history_entry(&line);
                let input = String::from(line.trim());
                clean_string(input).map(|input| {
                    rl.add_history_entry(&input);

                    match eval_string(&input, scope_manager.clone()) {
                        Ok((var, ptr)) => {
                            match ptr {
                                Some(JsPtrEnum::JsSym(s)) => println!("=> Symbol({:?})", s),
                                Some(JsPtrEnum::JsStr(s)) => println!("=> {:?}", s.text),
                                _ => println!("=> {:?}", var.t),
                            }
                        },
                        Err(e) => {
                            println!("{:?}", e);
                        }
                    }
                });
            },
            Err(ReadlineError::Interrupted) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 1;
            },
            Err(ReadlineError::Eof) => {
                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                break
            },
            Err(err) => {
                println!("Error: {:?}", err);

                if rl.save_history(".history").is_err() {
                    writeln!(stderr, "Error: unable to save history on exit").unwrap();
                    return 2;
                }
                return 3;
            }
        }
    }
    0
}

fn main() {
    let args: Args = Args::docopt().decode().unwrap_or_else(|e| e.exit());
    if args.flag_test {
        let dir_name = "sputnik";

        test_dir(String::from(dir_name))
    } else {
        let scope_manager = Rc::new(RefCell::new(init_gc()));
        add_pervasives(scope_manager.clone());

        if args.arg_file == "" {
            let ret = repl(scope_manager.clone());
            exit(ret)
        } else {
            eval_file(args.arg_file, true, true, scope_manager.clone()).expect("Error evaluating file");
        }
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Write};

fn main() {
    println!("Welcome to Chifir!");
    println!("");
    println!("Type 'help' to get started.");

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

        let mut command = String::new();

        io::stdin().read_line(&mut command).expect("Failed to read command");

        match command.trim() {
            "help" => println!("help, quit"),
            "quit" => break,
            _ => continue
        }
    }
}
<commit_msg>Include the "machine" module so the tests run.<commit_after>mod machine;

use std::io::{self, Write};

fn main() {
    println!("Welcome to Chifir!");
    println!("");
    println!("Type 'help' to get started.");

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

        let mut command = String::new();

        io::stdin().read_line(&mut command).expect("Failed to read command");

        match command.trim() {
            "help" => println!("help, quit"),
            "quit" => break,
            _ => continue
        }
    }
}
<|endoftext|>


<commit_before>extern crate bindgen;
#[macro_use]
extern crate log;
extern crate docopt;
#[macro_use]
extern crate rustc_serialize;
extern crate env_logger;

use bindgen::{Builder, LinkType};
use std::io::{self, Write};
use std::fs::File;
use std::process::exit;

const USAGE: &'static str = "
Generate C bindings for Rust.

Usage:
  bindgen [options] <file> [-- <clang-args>...]
  bindgen (-h | --help)

Options:
  <clang-args>                 Options passed directly to clang.
  -h, --help                   Display this help message.
  --link=<library>             Link to a dynamic library, can be provided multiple times.
                               <library> is in the format `[kind=]lib`, where `kind` is
                               one of `static`, `dynamic` or `framework`.
  --output=<output>            Write bindings to <output> (- is stdout).
                               [default: -]
  --match=<name>               Only output bindings for definitions from files
                               whose name contains <name>
                               If multiple -match options are provided, files
                               matching any rule are bound to.
  --builtins                   Output bindings for builtin definitions
                               (for example __builtin_va_list)
  --emit-clang-ast             Output the ast (for debugging purposes)
  --override-enum-type=<type>  Override enum type, type name could be
                                 uchar
                                 schar
                                 ushort
                                 sshort
                                 uint
                                 sint
                                 ulong
                                 slong
                                 ulonglong
                                 slonglong
  --use-core                  Use `core` as a base crate for `Option` and such.
                              See also `--ctypes-prefix`.
  --ctypes-prefix=<prefix>    Use this prefix for all the types in the generated
                              code.
                              [default: std::os::raw]
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_file: String,
    arg_clang_args: Vec<String>,
    flag_link: String,
    flag_output: String,
    flag_match: Option<String>,
    flag_builtins: bool,
    flag_emit_clang_ast: bool,
    flag_override_enum_type: String,
    flag_ctypes_prefix: String,
    flag_use_core: bool,
}

fn args_to_opts(args: Args, builder: &mut Builder) {
    builder.header(args.arg_file)
           .emit_ast(args.flag_emit_clang_ast)
           .ctypes_prefix(args.flag_ctypes_prefix
                              .split("::")
                              .map(String::from)
                              .collect::<Vec<_>>())
           .use_core(args.flag_use_core)
           .override_enum_ty(args.flag_override_enum_type);
    for arg in args.arg_clang_args {
        builder.clang_arg(arg);
    }
    if let Some(s) = args.flag_match {
        builder.match_pat(s);
    }
    if args.flag_builtins {
        builder.builtins();
    }
    let mut parts = args.flag_link.split('=');
    let (lib, kind) = match (parts.next(), parts.next()) {
        (Some(lib), None) => (lib, LinkType::Dynamic),
        (Some(kind), Some(lib)) => {
            (lib,
             match kind {
                "static" => LinkType::Static,
                "dynamic" => LinkType::Dynamic,
                "framework" => LinkType::Framework,
                _ => {
                    println!("Link type unknown: {}", kind);
                    exit(1);
                }
            })
        }
        _ => {
            println!("Wrong link format: {}", args.flag_link);
            exit(1);
        }
    };
    builder.link(lib, kind);
}

fn get_output(o: &str) -> Box<Write> {
    if o == "-" {
        Box::new(io::stdout())
    } else {
        Box::new(File::open(o).expect(&format!("\"{}\" unreadable", o)))
    }
}

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

    let args: Args = docopt::Docopt::new(USAGE)
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());
    debug!("{:?}", args);

    let output = get_output(&args.flag_output);

    let mut builder = Builder::new();
    args_to_opts(args, &mut builder);
    debug!("{:?}", builder);

    match builder.generate() {
        Ok(bindings) => {
            match bindings.write(output) {
                Ok(()) => (),
                Err(e) => {
                    error!("Unable to write bindings to file. {}", e);
                    exit(-1);
                }
            }
        }
        Err(()) => exit(-1),
    }
}
<commit_msg>[main] Add some warnings by default.<commit_after>extern crate bindgen;
#[macro_use]
extern crate log;
extern crate docopt;
#[macro_use]
extern crate rustc_serialize;
extern crate env_logger;

use bindgen::{Builder, LinkType};
use std::io::{self, Write};
use std::fs::File;
use std::process::exit;

const USAGE: &'static str = "
Generate C bindings for Rust.

Usage:
  bindgen [options] <file> [-- <clang-args>...]
  bindgen (-h | --help)

Options:
  <clang-args>                 Options passed directly to clang.
  -h, --help                   Display this help message.
  --link=<library>             Link to a dynamic library, can be provided multiple times.
                               <library> is in the format `[kind=]lib`, where `kind` is
                               one of `static`, `dynamic` or `framework`.
  --output=<output>            Write bindings to <output> (- is stdout).
                               [default: -]
  --match=<name>               Only output bindings for definitions from files
                               whose name contains <name>
                               If multiple -match options are provided, files
                               matching any rule are bound to.
  --builtins                   Output bindings for builtin definitions
                               (for example __builtin_va_list)
  --emit-clang-ast             Output the ast (for debugging purposes)
  --override-enum-type=<type>  Override enum type, type name could be
                                 uchar
                                 schar
                                 ushort
                                 sshort
                                 uint
                                 sint
                                 ulong
                                 slong
                                 ulonglong
                                 slonglong
  --use-core                  Use `core` as a base crate for `Option` and such.
                              See also `--ctypes-prefix`.
  --ctypes-prefix=<prefix>    Use this prefix for all the types in the generated
                              code.
                              [default: std::os::raw]
";

#[derive(Debug, RustcDecodable)]
struct Args {
    arg_file: String,
    arg_clang_args: Vec<String>,
    flag_link: String,
    flag_output: String,
    flag_match: Option<String>,
    flag_builtins: bool,
    flag_emit_clang_ast: bool,
    flag_override_enum_type: String,
    flag_ctypes_prefix: String,
    flag_use_core: bool,
}

fn args_to_opts(args: Args, builder: &mut Builder) {
    builder.header(args.arg_file)
           .emit_ast(args.flag_emit_clang_ast)
           .ctypes_prefix(args.flag_ctypes_prefix
                              .split("::")
                              .map(String::from)
                              .collect::<Vec<_>>())
           .use_core(args.flag_use_core)
           .override_enum_ty(args.flag_override_enum_type);
    for arg in args.arg_clang_args {
        builder.clang_arg(arg);
    }
    if let Some(s) = args.flag_match {
        builder.match_pat(s);
    }
    if args.flag_builtins {
        builder.builtins();
    }
    let mut parts = args.flag_link.split('=');
    let (lib, kind) = match (parts.next(), parts.next()) {
        (Some(lib), None) => (lib, LinkType::Dynamic),
        (Some(kind), Some(lib)) => {
            (lib,
             match kind {
                "static" => LinkType::Static,
                "dynamic" => LinkType::Dynamic,
                "framework" => LinkType::Framework,
                _ => {
                    println!("Link type unknown: {}", kind);
                    exit(1);
                }
            })
        }
        _ => {
            println!("Wrong link format: {}", args.flag_link);
            exit(1);
        }
    };
    builder.link(lib, kind);
}

fn get_output(o: &str) -> Box<Write> {
    if o == "-" {
        Box::new(io::stdout())
    } else {
        Box::new(File::open(o).expect(&format!("\"{}\" unreadable", o)))
    }
}

pub fn main() {
    env_logger::LogBuilder::new().parse("bindgen=warn").init().unwrap();

    let args: Args = docopt::Docopt::new(USAGE)
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());
    debug!("{:?}", args);

    let output = get_output(&args.flag_output);

    let mut builder = Builder::new();
    args_to_opts(args, &mut builder);
    debug!("{:?}", builder);

    match builder.generate() {
        Ok(bindings) => {
            match bindings.write(output) {
                Ok(()) => (),
                Err(e) => {
                    error!("Unable to write bindings to file. {}", e);
                    exit(-1);
                }
            }
        }
        Err(()) => exit(-1),
    }
}
<|endoftext|>


<commit_before>extern crate getopts;
extern crate time;

use std::collections::LinkedList;
use std::str::Split;

mod args;

fn main() {
    let args: std::env::Args = std::env::args();
    let opts = args::parse_args(args);
    let dow = [
        "Duinday",
        "Sitaday",
        "Wikiday",
        "Tuxday",
        "Gnuday",
        "Commonday",
    ];
    let moy = [
        "Jabim", "Zodrak", "Trogool", "Yanar", "Shkumbe", "Habniah", "Skarl", "Mikon", "Pertunda",
        "Kib", "Broket",
    ];
    let dpm = 33;
    let dpw = dow.len();
    let mpy = moy.len();
    let (year, month, day, yoff) = current_day(time::now());
    let mut select_year = year;
    let mut select_yoff = yoff;
    if opts.has_year && opts.year < i16::max_value() {
        select_year = opts.year;
        let rem = select_year % 2;
        select_yoff = (rem + if rem < 0 { 2 } else { 0 }) as usize * 3;
    }

    let wd = (select_yoff + month * 3 + day - 1) % dpw;
    let mut moff = select_yoff;
    let mut months_across = LinkedList::<String>::new();

    if opts.exit {
        return;
    }

    if !opts.date_only {
        if opts.has_month {
            let mut select_month = month;
            if opts.month < usize::max_value() {
                select_month = opts.month;
            }

            let spaces = (17 - moy[select_month].len()) / 2;
            let mut month_text = "".to_string();
            for _ in 0..spaces {
                month_text = format!("{} ", month_text);
            }

            month_text = format!("{}{}", month_text, moy[select_month]);
            for _ in 0..(18 - spaces - moy[select_month].len()) {
                month_text = format!("{} ", month_text);
            }

            month_text = format!("{}\n", month_text);
            for dd in dow.iter().take(dpw) {
                let mut abbrd = String::from(*dd);
                abbrd.truncate(2);
                month_text = format!("{}{} ", month_text, abbrd);
            }

            let dd = if select_month == month { day } else { 1000 };
            let days = format_days(moff, dpm, dpw, dd);
            month_text = format!("{}{}", month_text, days.0);
            if select_month == 2 {
                month_text = format!("{}--  Peer  Day  --", month_text);
            } else if select_month == 6 {
                month_text = format!("{}--Torrent Feast--", month_text);
            } else if is_leap_year(select_year) && select_month == 10 {
                month_text = format!("{}--Immersion Day--", month_text);
            }

            println!("{}", month_text);
        } else {
            for (mm, mon) in moy.iter().enumerate().take(mpy) {
                let spaces = (17 - mon.len()) / 2;
                let mut month_text = format!("");
                for _ in 0..spaces {
                    month_text = format!("{} ", month_text);
                }

                month_text = format!("{}{}", month_text, moy[mm]);
                for _ in 0..(18 - spaces - mon.len()) {
                    month_text = format!("{} ", month_text);
                }

                month_text = format!("{}\n", month_text);
                for dd in dow.iter().take(dpw) {
                    let mut abbrd = String::from(*dd);
                    abbrd.truncate(2);
                    month_text = format!("{}{} ", month_text, abbrd);
                }

                let dd = if mm == month { day } else { 1000 };
                let days = format_days(moff, dpm, dpw, dd);
                month_text = format!("{}{}", month_text, days.0);
                moff = days.1;
                if mm == 2 {
                    month_text = format!("{}--  Peer  Day  --", month_text);
                } else if mm == 6 {
                    month_text = format!("{}--Torrent Feast--", month_text);
                } else if is_leap_year(select_year) && mm == 10 {
                    month_text = format!("{}--Immersion Day--", month_text);
                }

                month_text = format!("{}\n", month_text);
                months_across.push_back(month_text);
                if mm % 4 == 3 {
                    month_zipper(months_across.clone(), "   ", 1);
                    months_across.clear();
                }
            }

            month_zipper(months_across.clone(), "   ", 11);
        }
    }

    if !opts.has_year && !opts.has_month {
        let mut datestr = format!("{}, {:02} of {}", dow[wd], day, moy[month]);
        let mut daystr = format!("{:02}.{:02}", month + 1, day);
        if day == 34 {
            if month == 2 {
                datestr = "Peer Day".to_string();
                daystr = "P".to_string();
            } else if month == 6 {
                datestr = "Torrent Feast".to_string();
                daystr = "T".to_string();
            } else if month == 10 {
                datestr = "Immersion Feast".to_string();
                daystr = "T".to_string();
            }
        }

        let hol = what_holiday(month, day);
        println!(
            "Today is {} {}{}.  [{}.{}]",
            datestr, year, hol, year, daystr
        );
    }
}

fn format_days(moff: usize, dpm: usize, dpw: usize, highlight: usize) -> (String, usize) {
    let mut month = format!("");

    if moff != 0 {
        month = format!("{}\n", month);
    }

    for _ in 0..moff {
        month = format!("{}   ", month);
    }

    for day in 1..dpm + 1 {
        if (day + moff) % dpw == 1 {
            month = format!("{}\n", month);
        }

        let ch = if day == highlight {
            ">"
        } else if day + 1 == highlight {
            "<"
        } else {
            " "
        };
        month = format!("{}{:2}{}", month, day, ch);
    }

    for _ in 0..(3 - moff) {
        month = format!("{}   ", month);
    }

    month = format!("{}\n", month);
    (month, if moff == 0 { 3 } else { 0 })
}

fn current_day(current_time: time::Tm) -> (i16, usize, usize, usize) {
    let epoch_days_offset = 1483889;
    let seconds_per_day = 86400;
    let now = current_time.to_timespec();
    let days_since_epoch = (epoch_days_offset + now.sec / seconds_per_day) as i32;
    let days_per_year = 365;
    let leap_year = 4;
    let not_leap_year = 33;
    let days_per_month = 33;

    let mut count = 1;
    let mut days_remaining = days_since_epoch;
    let mut year = 0;
    while days_remaining > days_per_year + 1 {
        days_remaining -= days_per_year;
        year += 1;
        if count > not_leap_year {
            count = 1;
        }
        if count % leap_year == 0 {
            days_remaining -= 1;
        }
        count += 1;
    }
    if days_remaining == days_per_year + 1 && count % leap_year == 0 {
        days_remaining = 0;
        year += 1;
    }

    let mut month = 0;
    while days_remaining > days_per_month {
        month += 1;
        days_remaining -= days_per_month;
        if month == 3 || month == 7 || month == 11 {
            days_remaining -= 1;
        }
    }

    let day = days_remaining;

    (
        year,
        month as usize,
        day as usize + 1,
        (year % 2 * 3) as usize,
    )
}

fn is_leap_year(year: i16) -> bool {
    let rem = year % 33 + if year < 0 { 33 } else { 0 };

    rem != 0 && rem % 4 == 0
}

fn what_holiday(month: usize, day: usize) -> String {
    let mut result = "".to_string();
    if month == 0 && day == 1 {
        result = ", New Year's Day".to_string();
    } else if month == 2 && day == 12 {
        result = ", Purification Day".to_string();
    } else if month == 2 && day == 24 {
        result = ", Document Freedom Day".to_string();
    } else if month == 3 && day == 33 {
        result = ", Hardware Freedom Day".to_string();
    } else if month == 5 && day == 4 {
        result = ", Harvest Gift".to_string();
    } else if month == 5 && day == 9 {
        result = ", Culture Freedom Day".to_string();
    } else if month == 7 && day == 29 {
        result = ", Familytide".to_string();
    } else if month == 8 && day == 33 {
        result = ", Software Freedom Day".to_string();
    } else if month == 9 && day == 30 {
        result = ", Open Access Day".to_string();
    } else if month == 10 && day == 21 {
        result = ", Freedom Day".to_string();
    } else if month == 0 && day == 27 {
        result = ", International Workers' Day".to_string();
    }

    result
}

fn month_zipper(months: LinkedList<String>, buffer: &str, front: usize) {
    let mut length = 0;
    let mut split_months = LinkedList::<Split<&str>>::new();
    for m in months.iter() {
        let split = m.split("\n");

        if split.clone().count() > length {
            length = split.clone().count();
        }

        split_months.push_back(split);
    }

    for i in 0..(length - 1) {
        for _ in 0..front {
            print!(" ");
        }

        let mut full_line = format!("");
        for m in split_months.iter() {
            let line = m.clone().nth(i);

            if let Some(l) = line {
                let part = if l.is_empty() {
                    "                  "
                } else {
                    l
                };
                full_line = format!("{}{}{}", full_line, part, buffer);
            }
        }

        println!("{}", full_line.trim_end());
    }
}
<commit_msg>Use character to split strings<commit_after>extern crate getopts;
extern crate time;

use std::collections::LinkedList;
use std::str::Split;

mod args;

fn main() {
    let args: std::env::Args = std::env::args();
    let opts = args::parse_args(args);
    let dow = [
        "Duinday",
        "Sitaday",
        "Wikiday",
        "Tuxday",
        "Gnuday",
        "Commonday",
    ];
    let moy = [
        "Jabim", "Zodrak", "Trogool", "Yanar", "Shkumbe", "Habniah", "Skarl", "Mikon", "Pertunda",
        "Kib", "Broket",
    ];
    let dpm = 33;
    let dpw = dow.len();
    let mpy = moy.len();
    let (year, month, day, yoff) = current_day(time::now());
    let mut select_year = year;
    let mut select_yoff = yoff;
    if opts.has_year && opts.year < i16::max_value() {
        select_year = opts.year;
        let rem = select_year % 2;
        select_yoff = (rem + if rem < 0 { 2 } else { 0 }) as usize * 3;
    }

    let wd = (select_yoff + month * 3 + day - 1) % dpw;
    let mut moff = select_yoff;
    let mut months_across = LinkedList::<String>::new();

    if opts.exit {
        return;
    }

    if !opts.date_only {
        if opts.has_month {
            let mut select_month = month;
            if opts.month < usize::max_value() {
                select_month = opts.month;
            }

            let spaces = (17 - moy[select_month].len()) / 2;
            let mut month_text = "".to_string();
            for _ in 0..spaces {
                month_text = format!("{} ", month_text);
            }

            month_text = format!("{}{}", month_text, moy[select_month]);
            for _ in 0..(18 - spaces - moy[select_month].len()) {
                month_text = format!("{} ", month_text);
            }

            month_text = format!("{}\n", month_text);
            for dd in dow.iter().take(dpw) {
                let mut abbrd = String::from(*dd);
                abbrd.truncate(2);
                month_text = format!("{}{} ", month_text, abbrd);
            }

            let dd = if select_month == month { day } else { 1000 };
            let days = format_days(moff, dpm, dpw, dd);
            month_text = format!("{}{}", month_text, days.0);
            if select_month == 2 {
                month_text = format!("{}--  Peer  Day  --", month_text);
            } else if select_month == 6 {
                month_text = format!("{}--Torrent Feast--", month_text);
            } else if is_leap_year(select_year) && select_month == 10 {
                month_text = format!("{}--Immersion Day--", month_text);
            }

            println!("{}", month_text);
        } else {
            for (mm, mon) in moy.iter().enumerate().take(mpy) {
                let spaces = (17 - mon.len()) / 2;
                let mut month_text = format!("");
                for _ in 0..spaces {
                    month_text = format!("{} ", month_text);
                }

                month_text = format!("{}{}", month_text, moy[mm]);
                for _ in 0..(18 - spaces - mon.len()) {
                    month_text = format!("{} ", month_text);
                }

                month_text = format!("{}\n", month_text);
                for dd in dow.iter().take(dpw) {
                    let mut abbrd = String::from(*dd);
                    abbrd.truncate(2);
                    month_text = format!("{}{} ", month_text, abbrd);
                }

                let dd = if mm == month { day } else { 1000 };
                let days = format_days(moff, dpm, dpw, dd);
                month_text = format!("{}{}", month_text, days.0);
                moff = days.1;
                if mm == 2 {
                    month_text = format!("{}--  Peer  Day  --", month_text);
                } else if mm == 6 {
                    month_text = format!("{}--Torrent Feast--", month_text);
                } else if is_leap_year(select_year) && mm == 10 {
                    month_text = format!("{}--Immersion Day--", month_text);
                }

                month_text = format!("{}\n", month_text);
                months_across.push_back(month_text);
                if mm % 4 == 3 {
                    month_zipper(months_across.clone(), "   ", 1);
                    months_across.clear();
                }
            }

            month_zipper(months_across.clone(), "   ", 11);
        }
    }

    if !opts.has_year && !opts.has_month {
        let mut datestr = format!("{}, {:02} of {}", dow[wd], day, moy[month]);
        let mut daystr = format!("{:02}.{:02}", month + 1, day);
        if day == 34 {
            if month == 2 {
                datestr = "Peer Day".to_string();
                daystr = "P".to_string();
            } else if month == 6 {
                datestr = "Torrent Feast".to_string();
                daystr = "T".to_string();
            } else if month == 10 {
                datestr = "Immersion Feast".to_string();
                daystr = "T".to_string();
            }
        }

        let hol = what_holiday(month, day);
        println!(
            "Today is {} {}{}.  [{}.{}]",
            datestr, year, hol, year, daystr
        );
    }
}

fn format_days(moff: usize, dpm: usize, dpw: usize, highlight: usize) -> (String, usize) {
    let mut month = format!("");

    if moff != 0 {
        month = format!("{}\n", month);
    }

    for _ in 0..moff {
        month = format!("{}   ", month);
    }

    for day in 1..dpm + 1 {
        if (day + moff) % dpw == 1 {
            month = format!("{}\n", month);
        }

        let ch = if day == highlight {
            ">"
        } else if day + 1 == highlight {
            "<"
        } else {
            " "
        };
        month = format!("{}{:2}{}", month, day, ch);
    }

    for _ in 0..(3 - moff) {
        month = format!("{}   ", month);
    }

    month = format!("{}\n", month);
    (month, if moff == 0 { 3 } else { 0 })
}

fn current_day(current_time: time::Tm) -> (i16, usize, usize, usize) {
    let epoch_days_offset = 1483889;
    let seconds_per_day = 86400;
    let now = current_time.to_timespec();
    let days_since_epoch = (epoch_days_offset + now.sec / seconds_per_day) as i32;
    let days_per_year = 365;
    let leap_year = 4;
    let not_leap_year = 33;
    let days_per_month = 33;

    let mut count = 1;
    let mut days_remaining = days_since_epoch;
    let mut year = 0;
    while days_remaining > days_per_year + 1 {
        days_remaining -= days_per_year;
        year += 1;
        if count > not_leap_year {
            count = 1;
        }
        if count % leap_year == 0 {
            days_remaining -= 1;
        }
        count += 1;
    }
    if days_remaining == days_per_year + 1 && count % leap_year == 0 {
        days_remaining = 0;
        year += 1;
    }

    let mut month = 0;
    while days_remaining > days_per_month {
        month += 1;
        days_remaining -= days_per_month;
        if month == 3 || month == 7 || month == 11 {
            days_remaining -= 1;
        }
    }

    let day = days_remaining;

    (
        year,
        month as usize,
        day as usize + 1,
        (year % 2 * 3) as usize,
    )
}

fn is_leap_year(year: i16) -> bool {
    let rem = year % 33 + if year < 0 { 33 } else { 0 };

    rem != 0 && rem % 4 == 0
}

fn what_holiday(month: usize, day: usize) -> String {
    let mut result = "".to_string();
    if month == 0 && day == 1 {
        result = ", New Year's Day".to_string();
    } else if month == 2 && day == 12 {
        result = ", Purification Day".to_string();
    } else if month == 2 && day == 24 {
        result = ", Document Freedom Day".to_string();
    } else if month == 3 && day == 33 {
        result = ", Hardware Freedom Day".to_string();
    } else if month == 5 && day == 4 {
        result = ", Harvest Gift".to_string();
    } else if month == 5 && day == 9 {
        result = ", Culture Freedom Day".to_string();
    } else if month == 7 && day == 29 {
        result = ", Familytide".to_string();
    } else if month == 8 && day == 33 {
        result = ", Software Freedom Day".to_string();
    } else if month == 9 && day == 30 {
        result = ", Open Access Day".to_string();
    } else if month == 10 && day == 21 {
        result = ", Freedom Day".to_string();
    } else if month == 0 && day == 27 {
        result = ", International Workers' Day".to_string();
    }

    result
}

fn month_zipper(months: LinkedList<String>, buffer: &str, front: usize) {
    let mut length = 0;
    let mut split_months = LinkedList::<Split<char>>::new();
    for m in months.iter() {
        let split = m.split('\n');

        if split.clone().count() > length {
            length = split.clone().count();
        }

        split_months.push_back(split);
    }

    for i in 0..(length - 1) {
        for _ in 0..front {
            print!(" ");
        }

        let mut full_line = format!("");
        for m in split_months.iter() {
            let line = m.clone().nth(i);

            if let Some(l) = line {
                let part = if l.is_empty() {
                    "                  "
                } else {
                    l
                };
                full_line = format!("{}{}{}", full_line, part, buffer);
            }
        }

        println!("{}", full_line.trim_end());
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Gomez Guillaume
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fs::{self, File, OpenOptions};
use std::io::{BufReader, SeekFrom, BufRead, Write, Read, Seek};
use std::fmt::{Display, Formatter, Error};
use std::path::PathBuf;

struct CommentEntry {
    line: String,
    file: String,
    comment_lines: Vec<String>,
}

impl CommentEntry {
    pub fn new(file: &str) -> CommentEntry {
        CommentEntry {
            line: String::new(),
            file: file.to_owned(),
            comment_lines: Vec::new(),
        }
    }
}

impl Display for CommentEntry {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        let mut out = format!("=!={}\n=|={}\n", self.file, self.line);

        //println!("{}: {} => {:?}", self.file, self.line, self.comment_lines);
        for comment in &self.comment_lines {
            out.push_str(&comment);
            out.push_str("\n");
        }
        writeln!(f, "{}", out)
    }
}

fn loop_over_files(path: &str, comments: &mut Vec<CommentEntry>) {
    match fs::read_dir(path) {
        Ok(it) => {
            for entry in it {
                check_path_type(entry.unwrap().path().to_str().unwrap(), comments);
            }
        }
        Err(e) => {
            println!("Error while trying to iterate over {}: {}", path, e);
        }
    }
}

fn move_reader(it: &mut usize, lines: &[&str], file: &str,
               comments: &mut Vec<CommentEntry>) {
    let mut cm = CommentEntry::new(file);

    cm.comment_lines.push(lines[*it].to_owned());
    *it += 1;
    while *it < lines.len() {
        if lines[*it].trim_left().starts_with("///") {
            cm.comment_lines.push(lines[*it].to_owned());
        } else {
            break;
        }
        *it += 1;
    }
    cm.line = lines[*it].to_owned();
    comments.push(cm);
    //write!(comments, "{}", cm).unwrap();
    //comments.flush();
}

fn strip_comments(path: &str, comments: &mut Vec<CommentEntry>) {
    match File::open(path) {
        Ok(mut f) => {
            let mut out_lines = vec!();
            let mut content = String::new();
            f.read_to_string(&mut content).unwrap();
            let lines : Vec<&str> = content.split('\n').collect();
            let mut it = 0;

            while it < lines.len() {
                let worker = lines[it].trim_left().to_owned();

                if worker.starts_with("///") {
                    // "normal" doc comments
                    move_reader(&mut it, &lines, path, comments);
                } else if worker.starts_with("//!")/* || worker.starts_with("/*!*/")*/ {
                    // module comments
                    move_reader(&mut it, &lines, path, comments);
                }
                out_lines.push(lines[it].to_owned());
                it += 1;
            }
            let mut pb = PathBuf::from(path);
            println!("{:?}", pb);
            let tmp = format!("_{}", pb.file_name().unwrap().to_str().unwrap());
            println!("{:?}", tmp);
            pb.set_file_name(&tmp);
            println!("{:?}", pb);
            match OpenOptions::new().write(true).create(true).truncate(true).open(&pb) {
                Ok(mut f) => {
                    for line in out_lines {
                        writeln!(f, "{}", line).unwrap();
                    }
                }
                Err(e) => {
                    println!("Unable to open \"{}\": {}", pb.to_str().unwrap(), e);
                }
            }
        }
        Err(e) => {
            println!("Unable to open \"{}\": {}", path, e);
        }
    }
}

fn check_path_type(path: &str, comments: &mut Vec<CommentEntry>) {
    match fs::metadata(path) {
        Ok(m) => {
            if m.is_dir() {
                if path == ".." || path == "." {
                    return;
                }
                loop_over_files(path, comments);
            } else {
                if path == "./comments.cmts" {
                    return;
                }
                println!("-> {}", path);
                strip_comments(path, comments);
            }
        }
        Err(e) => {
            println!("An error occurred: {}", e);
        }
    }
}

fn main() {
    println!("Starting...");
    match fs::remove_file("comments.cmts") { _ => {} }
    let mut comments = vec!();
    loop_over_files(".", &mut comments);
    match OpenOptions::new().write(true).create(true).truncate(true).open("comments.cmts") {
        Ok(mut f) => {
            for com_entry in comments {
                write!(f, "{}", com_entry).unwrap();
            }
            println!("Done !");
        }
        Err(e) => {
            println!("Error while opening \"{}\": {}", "comments.cmts", e);
        }
    }
}
<commit_msg>New way to parse<commit_after>// Copyright 2015 Gomez Guillaume
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::fs::{self, File, OpenOptions};
use std::io::{BufReader, SeekFrom, BufRead, Write, Read, Seek};
use std::fmt::{Display, Formatter, Error};
use std::path::PathBuf;

/*struct CommentEntry {
    file: String,
    text: String,
}

impl CommentEntry {
    fn new(file: &str, text: &str) -> CommentEntry {

    }
}

impl Display for CommentEntry {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        //let mut out = format!("=!={}\n=|={}\n", self.file, self.type_);
        let mut out = String::new();

        //println!("{}: {} => {:?}", self.file, self.line, self.comment_lines);
        /*for comment in &self.comment_lines {
            out.push_str(&comment);
            out.push_str("\n");
        }*/
        //writeln!(f, "{}", out)
        writeln!(f, "=!={}\n{}", self.file, self.text)
    }
}*/

enum EventType {
    Comment(String),
    Type(TypeStruct),
    InScope,
    OutScope,
}

struct TypeStruct {
    ty: Type,
    parent: Option<Box<TypeStruct>>,
    name: String,
}

impl TypeStruct {
    fn new(ty: Type, name: &str) -> TypeStruct {
        TypeStruct {
            ty: ty,
            name: name.to_owned(),
            parent: None,
        }
    }
}

#[derive(Debug)]
enum Type {
    Struct,
    Mod,
    Enum,
    Fn,
    Const,
    Static,
    Type,
    Variant,
}

impl Type {
    fn from(s: &str) -> Type {
        match s {
            "struct" => Type::Struct,
            "mod" => Type::Mod,
            "enum" => Type::Enum,
            "fn" => Type::Fn,
            "const" => Type::Const,
            "static" => Type::Static,
            "type" => Type::Type,
            _ => Type::Variant,
        }
    }
}

fn loop_over_files(path: &str/*, comments: &mut Vec<CommentEntry>*/) {
    match fs::read_dir(path) {
        Ok(it) => {
            for entry in it {
                check_path_type(entry.unwrap().path().to_str().unwrap()/*, comments*/);
            }
        }
        Err(e) => {
            println!("Error while trying to iterate over {}: {}", path, e);
        }
    }
}

fn move_to(words: &[&str], it: &mut usize, limit: &str) {
    while (*it + 1) < words.len() && words[*it + 1] != limit {
        *it += 1;
    }
}

fn strip_comments(path: &str/*, comments: &mut Vec<CommentEntry>*/) {
    match File::open(path) {
        Ok(mut f) => {
            let mut b_content = String::new();
            f.read_to_string(&mut b_content).unwrap();
            let content = b_content.replace("{", " { ")
                                   .replace("}", " } ")
                                   .replace("///", "/// ")
                                   .replace("\n", " \n ")
                                   .replace("(", " (");
            let b_content : Vec<&str> = b_content.split('\n').collect();
            let words : Vec<&str> = content.split(' ').filter(|s| s.len() > 0).collect();
            let mut it = 0;
            let mut line = 0;
            let mut event_list = vec!();

            while it < words.len() {
                match words[it] {
                    "///" => {
                        event_list.push(EventType::Comment(b_content[line].to_owned()));
                        move_to(&words, &mut it, "\n");
                    }
                    "struct" | "mod" | "fn" | "enum" | "const" | "static" | "type" => {
                        event_list.push(EventType::Type(TypeStruct::new(Type::from(words[it]), words[it + 1])));
                        it += 1;
                    }
                    "{" => {
                        event_list.push(EventType::InScope);
                    }
                    "}" => {
                        event_list.push(EventType::OutScope);
                    }
                    "\n" => {
                        line += 1;
                    }
                    _ => {}
                }
                it += 1;
            }
            for event in event_list {
                match event {
                    EventType::Comment(s) => { println!("{}", s); }
                    EventType::Type(t) => { println!("{:?} {}", t.ty, t.name);}
                    EventType::InScope => { println!("{{"); }
                    EventType::OutScope => { println!("}}"); }
                }
            }
        }
        Err(e) => {
            println!("Unable to open \"{}\": {}", path, e);
        }
    }
}

fn check_path_type(path: &str/*, comments: &mut Vec<CommentEntry>*/) {
    match fs::metadata(path) {
        Ok(m) => {
            if m.is_dir() {
                if path == ".." || path == "." {
                    return;
                }
                loop_over_files(path/*, comments*/);
            } else {
                if path == "./comments.cmts" {
                    return;
                }
                println!("-> {}", path);
                strip_comments(path/*, comments*/);
            }
        }
        Err(e) => {
            println!("An error occurred: {}", e);
        }
    }
}

fn main() {
    println!("Starting...");
    match fs::remove_file("comments.cmts") { _ => {} }
    //let mut comments = vec!();
    loop_over_files("."/*, &mut comments*/);
    match OpenOptions::new().write(true).create(true).truncate(true).open("comments.cmts") {
        Ok(mut f) => {
            /*for com_entry in comments {
                write!(f, "{}", com_entry).unwrap();
            }*/
            println!("Done !");
        }
        Err(e) => {
            println!("Error while opening \"{}\": {}", "comments.cmts", e);
        }
    }
}

// au lieu de splitter le fichier via '\n', lis le sur "une seule ligne".
// quand tu croises un "///", tu stockes ça comme un commentaire, un "mod", comme un module, etc...
// il faudra compter les '{' / '}' pour voir si t'es toujours danns le truc courant ou non<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate quick_error;
extern crate walkdir;

use std::env;
use std::path::{Path, PathBuf};

mod error;
mod file;
mod parser;
mod questions;
mod stamp;
mod template;
mod template_file;

use clap::{App, AppSettings};

use error::Error;

fn run() -> Result<(), Error> {
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml)
        .setting(AppSettings::ArgRequiredElseHelp)
        .get_matches();

    let source_arg = matches.value_of("source").ok_or(Error::SourceNotProvided)?;
    let dest_arg = matches.value_of("destination").unwrap_or("");

    let source = find_source(source_arg)?;
    let dest = find_destination(dest_arg)?;

    let files = file::read_all_files(&source)?;
    let (templates, vars) = stamp::compile_templates(&files);

    let conf = questions::get_vars(&vars)?;
    let rendered = stamp::render_templates(&templates, &conf)?;

    stamp::write_files(&dest, &rendered)?;

    Ok(())
}

pub fn find_source(source_arg: &str) -> Result<PathBuf, Error> {
    let mut path = Path::new(source_arg).to_owned();
    if path.is_relative() {
        let in_current_dir = env::current_dir()?.join(&path);
        if in_current_dir.exists() {
            return Ok(in_current_dir);
        } else {
            path = env::home_dir()
                .ok_or(Error::HomeDirNotAccessible)?
                .join(".stamps")
                .join(&path);
        }
    }
    if path.exists() {
        Ok(path)
    } else {
        Err(Error::StampNotFound)
    }
}

fn find_destination(dest_arg: &str) -> Result<PathBuf, Error> {
    let path = Path::new(dest_arg).to_owned();
    if path.is_relative() {
        Ok(env::current_dir()?.join(&path))
    } else {
        Ok(path)
    }
}

fn main() {
    run().unwrap()
}
<commit_msg>Turn having source into an invariant<commit_after>#[macro_use]
extern crate clap;
#[macro_use]
extern crate nom;
#[macro_use]
extern crate quick_error;
extern crate walkdir;

use std::env;
use std::path::{Path, PathBuf};

mod error;
mod file;
mod parser;
mod questions;
mod stamp;
mod template;
mod template_file;

use clap::{App, AppSettings};

use error::Error;

fn run() -> Result<(), Error> {
    let yaml = load_yaml!("cli.yaml");
    let matches = App::from_yaml(yaml)
        .setting(AppSettings::ArgRequiredElseHelp)
        .get_matches();

    let source_arg = matches.value_of("source").expect("Source is a required argument");
    let dest_arg = matches.value_of("destination").unwrap_or("");

    let source = find_source(source_arg)?;
    let dest = find_destination(dest_arg)?;

    let files = file::read_all_files(&source)?;
    let (templates, vars) = stamp::compile_templates(&files);

    let conf = questions::get_vars(&vars)?;
    let rendered = stamp::render_templates(&templates, &conf)?;

    stamp::write_files(&dest, &rendered)?;

    Ok(())
}

pub fn find_source(source_arg: &str) -> Result<PathBuf, Error> {
    let mut path = Path::new(source_arg).to_owned();
    if path.is_relative() {
        let in_current_dir = env::current_dir()?.join(&path);
        if in_current_dir.exists() {
            return Ok(in_current_dir);
        } else {
            path = env::home_dir()
                .ok_or(Error::HomeDirNotAccessible)?
                .join(".stamps")
                .join(&path);
        }
    }
    if path.exists() {
        Ok(path)
    } else {
        Err(Error::StampNotFound)
    }
}

fn find_destination(dest_arg: &str) -> Result<PathBuf, Error> {
    let path = Path::new(dest_arg).to_owned();
    if path.is_relative() {
        Ok(env::current_dir()?.join(&path))
    } else {
        Ok(path)
    }
}

fn main() {
    run().unwrap()
}
<|endoftext|>


<commit_before>extern crate gnuplot;
use gnuplot::{Figure, Color};
use gnuplot::PlotOption::LineWidth;

mod genetic;
use genetic::population::{Population, Range};
use genetic::fitness::max_alternating_bits;
use genetic::crossover::one_point_crossover;
use genetic::mutation::bit_flip;

fn main() {
    let total_generations = 100;

    let population_size = 5;
    let genome_size = 10;
    let crossover_probability = 0.95;
    let mutation_probability = 0.05;
    let has_elitism = true;
    let fitness_function = max_alternating_bits;
    let mutation_function = bit_flip;
    let mut population = Population::<u8>::new(population_size,
                                               genome_size,
                                               crossover_probability,
                                               mutation_probability,
                                               Range::new(0, 2),
                                               has_elitism,
                                               fitness_function,
                                               one_point_crossover,
                                               mutation_function);

    println!("Initial population");
    population.print();

    for current_generation in 0..total_generations {
        println!("\nA E S T H E T I C S: {}", current_generation);
        population.iterate_generation();
        population.print();
    }

    if let Some(best_individual) = population.best_individual_in_generation.last() {
        println!("Best genome: {:?}", best_individual.genome);
    }

    show_convergence_plot(&population.average_fitness_in_generation,
                          &population.best_fitness_in_generation);

}

fn show_convergence_plot(average_fitnesses: &Vec<f32>, best_fitnesses: &Vec<f32>) {
    let generations: Vec<usize> = (0..average_fitnesses.len()).collect();

    let mut fg = Figure::new();
    fg.axes2d()
        .lines(&generations,
               average_fitnesses,
               &[Color("#505050"), LineWidth(1.5)])
        .lines(&generations,
               best_fitnesses,
               &[Color("#0072bd"), LineWidth(1.5)]);
    fg.show();
}
<commit_msg>Now it prints the best genome's fitness after all generations<commit_after>extern crate gnuplot;
use gnuplot::{Figure, Color};
use gnuplot::PlotOption::LineWidth;

mod genetic;
use genetic::population::{Population, Range};
use genetic::fitness::max_alternating_bits;
use genetic::crossover::one_point_crossover;
use genetic::mutation::bit_flip;

fn main() {
    let total_generations = 100;

    let population_size = 5;
    let genome_size = 10;
    let crossover_probability = 0.95;
    let mutation_probability = 0.05;
    let has_elitism = true;
    let fitness_function = max_alternating_bits;
    let mutation_function = bit_flip;
    let mut population = Population::<u8>::new(population_size,
                                               genome_size,
                                               crossover_probability,
                                               mutation_probability,
                                               Range::new(0, 2),
                                               has_elitism,
                                               fitness_function,
                                               one_point_crossover,
                                               mutation_function);

    println!("Initial population");
    population.print();

    for current_generation in 0..total_generations {
        println!("\nA E S T H E T I C S: {}", current_generation);
        population.iterate_generation();
        population.print();
    }

    if let Some(best_individual) = population.best_individual_in_generation.last() {
        if let Some(best_fitness) = population.best_fitness_in_generation.last() {
            println!("Best genome: {:?} : {}", best_individual.genome, best_fitness);
        }
    }

    show_convergence_plot(&population.average_fitness_in_generation,
                          &population.best_fitness_in_generation);

}

fn show_convergence_plot(average_fitnesses: &Vec<f32>, best_fitnesses: &Vec<f32>) {
    let generations: Vec<usize> = (0..average_fitnesses.len()).collect();

    let mut fg = Figure::new();
    fg.axes2d()
        .lines(&generations,
               average_fitnesses,
               &[Color("#505050"), LineWidth(1.5)])
        .lines(&generations,
               best_fitnesses,
               &[Color("#0072bd"), LineWidth(1.5)]);
    fg.show();
}
<|endoftext|>


<commit_before>#[macro_use]

extern crate capnp;
extern crate chrono;
#[cfg(feature = "coroutines")]
extern crate coio;
extern crate kafka;
extern crate log;
extern crate openssl;
extern crate rand;
extern crate redis;
extern crate serde;
extern crate serde_json;
extern crate toml;

mod flowgger;
pub use flowgger::record_capnp;

const DEFAULT_CONFIG_FILE: &'static str = "flowgger.toml";
const FLOWGGER_VERSION_STRING: &'static str = "0.2.1";

fn main() {
    println!("Flowgger v{}", FLOWGGER_VERSION_STRING);
    let config_file = std::env::args().skip(1).next().unwrap_or(DEFAULT_CONFIG_FILE.to_owned());
    flowgger::start(&config_file);
}
<commit_msg>Do not include the Kafka crate with the without_kafka feature<commit_after>#[macro_use]

extern crate capnp;
extern crate chrono;
#[cfg(feature = "coroutines")]
extern crate coio;
#[cfg(not(feature = "without_kafka"))]
extern crate kafka;
extern crate log;
extern crate openssl;
extern crate rand;
extern crate redis;
extern crate serde;
extern crate serde_json;
extern crate toml;

mod flowgger;
pub use flowgger::record_capnp;

const DEFAULT_CONFIG_FILE: &'static str = "flowgger.toml";
const FLOWGGER_VERSION_STRING: &'static str = "0.2.1";

fn main() {
    println!("Flowgger v{}", FLOWGGER_VERSION_STRING);
    let config_file = std::env::args().skip(1).next().unwrap_or(DEFAULT_CONFIG_FILE.to_owned());
    flowgger::start(&config_file);
}
<|endoftext|>