<commit_before>#![feature(path_ext, exit_status)]

extern crate time;

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

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

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

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

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

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

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

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

    // commands

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

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

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

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

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

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

    // aux. methods

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

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

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

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

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

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

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

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

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

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

fn print_time_worked(t: &Duration, day: &Tm) {
    println!("{}: {:>2}:{:02}",
        day.strftime("%a, %d %b %Y").unwrap(),
        t.num_hours() ,
        t.num_minutes() % 60
    );
}
<commit_msg>Get rid of exits_status feature<commit_after>#![feature(path_ext)]

extern crate time;

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

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

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

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

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

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

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

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

    // commands

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

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

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

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

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

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

    // aux. methods

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

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

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

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

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

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

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

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

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

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

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


<commit_before>#![feature(io)]

extern crate argparse;
extern crate bit_set;
extern crate compress;
extern crate libc;

use std::fs;
use std::io;
use std::mem;
use std::path;
use std::slice;

use argparse::Store;

use bit_set::BitSet;

use libc::c_void;

//magic:
use std::io::Read;
use std::os::unix::io::AsRawFd;

type CharResult = Result<char, io::CharsError>;

static TRI_MAX: usize = 64 * 64 * 64;

fn simplify(wut: char) -> u8 {
    let c = match wut {
        'a' ... 'z' => (wut as u8 - 'a' as u8 + 'A' as u8) as char,
        _ => wut,
    };

    if c > 128 as char {
        if c.is_whitespace() {
            return 2;
        }
        if c.is_control() {
            return 0;
        }
        return 63;
    }

    let sym_end = 33u8;
    let letters = 21u8;

    match c {
        '\r' | '\n' => 1,
        '\t' | '\x0c' | '\x0b' | ' ' => 2,
        '!' => 3,
        '"' | '\'' | '`' => 4,
        '$' => 5,
        '%' => 6,
        '&' => 7,
        '(' ... '@' => 8 + (c as u8 - '(' as u8),
        'A' ... 'I' => sym_end + (c as u8 - 'A' as u8),
        'J' | 'K' => sym_end + letters,
        'L' ... 'P' => sym_end + (c as u8 - 'A' as u8) - 2,
        'Q' => sym_end + letters,
        'R' ... 'W' => sym_end + (c as u8 - 'A' as u8) - 3,
        'X' | 'Z' => sym_end + letters,
        'Y' => sym_end + letters - 1,
        '[' => 55,
        '\\' => 56,
        ']'=> 57,
        '^' | '~' | '#' => 58,
        '_' => 59,
        '{' ... '}' => 60 + (c as u8 - '{' as u8),
        _ => 0,
    }
}

fn explain(wut: u8) -> char {
    match wut {
        0 => 'X',
        1 => 'N',
        2 => ' ',
        3 => '!',
        4 => '"',
        5 => '$',
        6 => '%',
        7 => '&',
        8 ... 32 => (wut - 8 + '(' as u8) as char,
        33 ... 41 => (wut - 33 + 'a' as u8) as char,
        42 ... 46 => (wut - 42 + 'l' as u8) as char,
        47 ... 52 => (wut - 47 + 'r' as u8) as char,
        53 => 'y',
        54 => 'X',
        55 => '[',
        56 => '\\',
        57 => ']',
        58 => '#',
        59 => '_',
        60 ... 62 => (wut - 60 + '{' as u8) as char,
        63 => 'U',
        _ => 'D',
    }
}

fn unpack(wut: usize) -> String {
    let mut ret = String::with_capacity(3);
    ret.push(explain((wut / 64 / 64 % 64) as u8));
    ret.push(explain((wut / 64 % 64) as u8));
    ret.push(explain((wut % 64) as u8));
    return ret;
}

fn trigrams_for<T: Iterator<Item=CharResult>>(input: T) -> Result<BitSet, String> {
    let mut line: u64 = 1;
    let mut prev: [u8; 3] = [0; 3];
    let mut ret: BitSet = BitSet::with_capacity(64 * 64 * 64);

    for (off, maybe_char) in input.enumerate() {
        let c = try!(maybe_char.map_err(|e| {
            format!("line {}: file char {}: failed: {}", line, off, e)
        }));
        if '\n' == c {
            line += 1;
        }
        if '\0' == c {
            return Err(format!("line {}: null found: not a text file", line));
        }
        prev[0] = prev[1];
        prev[1] = prev[2];
        prev[2] = simplify(c);
        let tri: usize = 64 * 64 * prev[0] as usize + 64 * prev[1] as usize + prev[2] as usize;
        ret.insert(tri);
    }
    return Ok(ret);
}

struct Mapped<'a, T: 'a> {
    file: fs::File,
    map: *mut c_void,
    data: &'a mut [T],
}

impl <'a, T: 'a> Mapped<'a, T> {
    fn fixed_len<P>(path: P, len: usize) -> io::Result<Mapped<'a, T>>
        where P: AsRef<path::Path> {
        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(path)?;
        file.set_len(mem::size_of::<T>() as u64 * len as u64)?;
        let map: *mut c_void = unsafe {
            libc::mmap(0 as *mut c_void,
                       len * mem::size_of::<T>(),
                       libc::PROT_READ | libc::PROT_WRITE,
                       libc::MAP_SHARED,
                       file.as_raw_fd(),
                       0)
        };

        if libc::MAP_FAILED == map {
            return Err(io::Error::last_os_error());
        }

        let data = unsafe { slice::from_raw_parts_mut(map as *mut T, len) };
        Ok(Mapped { file, map, data })
    }

    fn remap(&mut self, len: usize) -> io::Result<()> {
        self.file.set_len(mem::size_of::<T>() as u64 * len as u64)?;
        let new_map = unsafe {
            libc::mremap(self.map,
                         self.data.len() * mem::size_of::<T>(),
                         len * mem::size_of::<T>(),
                         libc::MREMAP_MAYMOVE)
        };

        if libc::MAP_FAILED == new_map {
            return Err(io::Error::last_os_error());
        }

        self.data = unsafe { slice::from_raw_parts_mut(new_map as *mut T, len) };
        self.map = new_map;
        Ok(())
    }
}

impl <'a, T: 'a> Drop for Mapped<'a, T> {
    fn drop(&mut self) {
        unsafe {
            assert_eq!(0, libc::munmap(self.map, self.data.len() * mem::size_of::<T>()));
        }
    }
}

fn main() {
    let mut from: String = "".to_string();
    let mut simple: u64 = 0;
    {
        let mut ap = argparse::ArgumentParser::new();
        ap.set_description("totally not a load of tools glued together");
        ap.refer(&mut from)
                .required()
                .add_option(&["-f", "--input-file"], Store,
                            "pack file to read");
        ap.refer(&mut simple)
                .add_option(&["--simple"], Store,
                            "not a pack, just a normal decompressed file");
        ap.parse_args_or_exit();
    }

    let mut idx: Mapped<u32> = Mapped::fixed_len("idx", TRI_MAX).unwrap();

    let page_size: usize = 1024;

    let pages_len: usize = match fs::metadata("pages") {
        Ok(m) => {
            let proposed: u64 = m.len() / mem::size_of::<u64>() as u64;
            assert!(proposed < usize::max_value() as u64);
            proposed as usize
        },
        Err(e) => if e.kind() == io::ErrorKind::NotFound {
            2 * page_size
        } else {
            panic!("couldn't get info on pages file: {}", e)
        }
    };

    let mut pages: Mapped<u64> = Mapped::fixed_len("pages", pages_len).unwrap();
    let mut avail_pages: usize = pages.data.len() / page_size;
    let mut free_page: usize = avail_pages;

    loop {
        if 0 != pages.data[(free_page - 1) * page_size] {
            break;
        }
        if 1 == free_page {
            break;
        }
        free_page -= 1;
    }

    if 0 != simple {
        let fh = fs::File::open(from).expect("input file must exist and be readable");
        let trigrams = trigrams_for(fh.chars()).expect("trigramming must work");
        for found in trigrams.iter() {
            let mut page = idx.data[found] as usize;
            if 0 == page {
                page = free_page;
                idx.data[found] = page as u32;
                free_page += 1;
                if free_page > avail_pages {
                    avail_pages += 100;
                    pages.remap(avail_pages * page_size).unwrap();
                }
            }

            let header_loc = page * page_size;
            let header = pages.data[header_loc];
            assert!(header < page_size as u64);
            pages.data[header_loc] += 1;
            pages.data[page * page_size + 1 + header as usize] = simple;
        }
        return;
    }

    unimplemented!();
}
<commit_msg>remove tracking variable<commit_after>#![feature(io)]

extern crate argparse;
extern crate bit_set;
extern crate compress;
extern crate libc;

use std::fs;
use std::io;
use std::mem;
use std::path;
use std::slice;

use argparse::Store;

use bit_set::BitSet;

use libc::c_void;

//magic:
use std::io::Read;
use std::os::unix::io::AsRawFd;

type CharResult = Result<char, io::CharsError>;

static TRI_MAX: usize = 64 * 64 * 64;

fn simplify(wut: char) -> u8 {
    let c = match wut {
        'a' ... 'z' => (wut as u8 - 'a' as u8 + 'A' as u8) as char,
        _ => wut,
    };

    if c > 128 as char {
        if c.is_whitespace() {
            return 2;
        }
        if c.is_control() {
            return 0;
        }
        return 63;
    }

    let sym_end = 33u8;
    let letters = 21u8;

    match c {
        '\r' | '\n' => 1,
        '\t' | '\x0c' | '\x0b' | ' ' => 2,
        '!' => 3,
        '"' | '\'' | '`' => 4,
        '$' => 5,
        '%' => 6,
        '&' => 7,
        '(' ... '@' => 8 + (c as u8 - '(' as u8),
        'A' ... 'I' => sym_end + (c as u8 - 'A' as u8),
        'J' | 'K' => sym_end + letters,
        'L' ... 'P' => sym_end + (c as u8 - 'A' as u8) - 2,
        'Q' => sym_end + letters,
        'R' ... 'W' => sym_end + (c as u8 - 'A' as u8) - 3,
        'X' | 'Z' => sym_end + letters,
        'Y' => sym_end + letters - 1,
        '[' => 55,
        '\\' => 56,
        ']'=> 57,
        '^' | '~' | '#' => 58,
        '_' => 59,
        '{' ... '}' => 60 + (c as u8 - '{' as u8),
        _ => 0,
    }
}

fn explain(wut: u8) -> char {
    match wut {
        0 => 'X',
        1 => 'N',
        2 => ' ',
        3 => '!',
        4 => '"',
        5 => '$',
        6 => '%',
        7 => '&',
        8 ... 32 => (wut - 8 + '(' as u8) as char,
        33 ... 41 => (wut - 33 + 'a' as u8) as char,
        42 ... 46 => (wut - 42 + 'l' as u8) as char,
        47 ... 52 => (wut - 47 + 'r' as u8) as char,
        53 => 'y',
        54 => 'X',
        55 => '[',
        56 => '\\',
        57 => ']',
        58 => '#',
        59 => '_',
        60 ... 62 => (wut - 60 + '{' as u8) as char,
        63 => 'U',
        _ => 'D',
    }
}

fn unpack(wut: usize) -> String {
    let mut ret = String::with_capacity(3);
    ret.push(explain((wut / 64 / 64 % 64) as u8));
    ret.push(explain((wut / 64 % 64) as u8));
    ret.push(explain((wut % 64) as u8));
    return ret;
}

fn trigrams_for<T: Iterator<Item=CharResult>>(input: T) -> Result<BitSet, String> {
    let mut line: u64 = 1;
    let mut prev: [u8; 3] = [0; 3];
    let mut ret: BitSet = BitSet::with_capacity(64 * 64 * 64);

    for (off, maybe_char) in input.enumerate() {
        let c = try!(maybe_char.map_err(|e| {
            format!("line {}: file char {}: failed: {}", line, off, e)
        }));
        if '\n' == c {
            line += 1;
        }
        if '\0' == c {
            return Err(format!("line {}: null found: not a text file", line));
        }
        prev[0] = prev[1];
        prev[1] = prev[2];
        prev[2] = simplify(c);
        let tri: usize = 64 * 64 * prev[0] as usize + 64 * prev[1] as usize + prev[2] as usize;
        ret.insert(tri);
    }
    return Ok(ret);
}

struct Mapped<'a, T: 'a> {
    file: fs::File,
    map: *mut c_void,
    data: &'a mut [T],
}

impl <'a, T: 'a> Mapped<'a, T> {
    fn fixed_len<P>(path: P, len: usize) -> io::Result<Mapped<'a, T>>
        where P: AsRef<path::Path> {
        let file = fs::OpenOptions::new().read(true).write(true).create(true).open(path)?;
        file.set_len(mem::size_of::<T>() as u64 * len as u64)?;
        let map: *mut c_void = unsafe {
            libc::mmap(0 as *mut c_void,
                       len * mem::size_of::<T>(),
                       libc::PROT_READ | libc::PROT_WRITE,
                       libc::MAP_SHARED,
                       file.as_raw_fd(),
                       0)
        };

        if libc::MAP_FAILED == map {
            return Err(io::Error::last_os_error());
        }

        let data = unsafe { slice::from_raw_parts_mut(map as *mut T, len) };
        Ok(Mapped { file, map, data })
    }

    fn remap(&mut self, len: usize) -> io::Result<()> {
        self.file.set_len(mem::size_of::<T>() as u64 * len as u64)?;
        let new_map = unsafe {
            libc::mremap(self.map,
                         self.data.len() * mem::size_of::<T>(),
                         len * mem::size_of::<T>(),
                         libc::MREMAP_MAYMOVE)
        };

        if libc::MAP_FAILED == new_map {
            return Err(io::Error::last_os_error());
        }

        self.data = unsafe { slice::from_raw_parts_mut(new_map as *mut T, len) };
        self.map = new_map;
        Ok(())
    }
}

impl <'a, T: 'a> Drop for Mapped<'a, T> {
    fn drop(&mut self) {
        unsafe {
            assert_eq!(0, libc::munmap(self.map, self.data.len() * mem::size_of::<T>()));
        }
    }
}

fn main() {
    let mut from: String = "".to_string();
    let mut simple: u64 = 0;
    {
        let mut ap = argparse::ArgumentParser::new();
        ap.set_description("totally not a load of tools glued together");
        ap.refer(&mut from)
                .required()
                .add_option(&["-f", "--input-file"], Store,
                            "pack file to read");
        ap.refer(&mut simple)
                .add_option(&["--simple"], Store,
                            "not a pack, just a normal decompressed file");
        ap.parse_args_or_exit();
    }

    let mut idx: Mapped<u32> = Mapped::fixed_len("idx", TRI_MAX).unwrap();

    let page_size: usize = 1024;

    let pages_len: usize = match fs::metadata("pages") {
        Ok(m) => {
            let proposed: u64 = m.len() / mem::size_of::<u64>() as u64;
            assert!(proposed < usize::max_value() as u64);
            proposed as usize
        },
        Err(e) => if e.kind() == io::ErrorKind::NotFound {
            2 * page_size
        } else {
            panic!("couldn't get info on pages file: {}", e)
        }
    };

    let mut pages: Mapped<u64> = Mapped::fixed_len("pages", pages_len).unwrap();
    let mut free_page: usize = pages.data.len() / page_size;

    loop {
        if 0 != pages.data[(free_page - 1) * page_size] {
            break;
        }
        if 1 == free_page {
            break;
        }
        free_page -= 1;
    }

    if 0 != simple {
        let fh = fs::File::open(from).expect("input file must exist and be readable");
        let trigrams = trigrams_for(fh.chars()).expect("trigramming must work");
        for found in trigrams.iter() {
            let mut page = idx.data[found] as usize;
            if 0 == page {
                page = free_page;
                idx.data[found] = page as u32;
                free_page += 1;
                if free_page > pages.data.len() / page_size {
                    let old_len = pages.data.len();
                    pages.remap(old_len + 100 * page_size).unwrap();
                }
            }

            let header_loc = page * page_size;
            let header = pages.data[header_loc];
            assert!(header < page_size as u64);
            pages.data[header_loc] += 1;
            pages.data[page * page_size + 1 + header as usize] = simple;
        }
        return;
    }

    unimplemented!();
}
<|endoftext|>


<commit_before>extern crate regex;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use irc::client::server::NetIrcServer;
use xdg_basedir::*;
use std::io::Read;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    let urlregex = Regex::new(r"https?://.+\.[:alpha:]{2,}").unwrap();

    match urlregex.captures(post) {
        Some(x) => {
            match client.get(x.at(0).unwrap()).send() {
                Ok(mut resp) => {
                    let mut body = String::new();
                    resp.read_to_string(&mut body).unwrap();
                    let titleregex = Regex::new(r"<title>(.+)</title>").unwrap();
                    match titleregex.captures(&body) {
                        Some(cap) => { return Some("Title: ".to_string() + cap.at(1).unwrap()); },
                        None => {},
                    }
                },
                Err(..) => {},
            }

        },
        None => {},
    }

    let issueregex = Regex::new(r"(\S+)/(\S+)#(\d+)").unwrap();
    let cap = match issueregex.captures(post) {
        Some(x) => x,
        None => return None
    };
    let user = cap.at(1).unwrap();
    let repo = cap.at(2).unwrap();
    let number = cap.at(3).unwrap();

    github::get_display_text(user, repo, number).ok()
}

fn handle_message(server: &NetIrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => {
                server.send_join(parameter).unwrap();
            },
            "part" => {
                server.send(Command::PART(parameter.to_string(), None)).unwrap();
            },
            "quit" => {
                server.send_quit("").unwrap();
            }
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_privmsg(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.into_string());
        if message.command == "PRIVMSG" {
            let from = message.get_source_nickname().unwrap().to_owned();
            let to = message.args[0].to_owned();
            let content = message.suffix.unwrap();
            handle_message(&server, &from, &to, &content);
        }
    }
}
<commit_msg>Make url regex not match spaces<commit_after>extern crate regex;
extern crate irc;
extern crate xdg_basedir;
extern crate hyper;

mod github;

use regex::Regex;
use irc::client::prelude::*;
use irc::client::server::NetIrcServer;
use xdg_basedir::*;
use std::io::Read;

fn parse_post(post: &str) -> Option<String> {
    let client = hyper::client::Client::new();
    let urlregex = Regex::new(r"https?://\S+\.[:alpha:]{2,}").unwrap();

    match urlregex.captures(post) {
        Some(x) => {
            match client.get(x.at(0).unwrap()).send() {
                Ok(mut resp) => {
                    let mut body = String::new();
                    resp.read_to_string(&mut body).unwrap();
                    let titleregex = Regex::new(r"<title>(.+)</title>").unwrap();
                    match titleregex.captures(&body) {
                        Some(cap) => { return Some("Title: ".to_string() + cap.at(1).unwrap()); },
                        None => {},
                    }
                },
                Err(..) => {},
            }

        },
        None => {},
    }

    let issueregex = Regex::new(r"(\S+)/(\S+)#(\d+)").unwrap();
    let cap = match issueregex.captures(post) {
        Some(x) => x,
        None => return None
    };
    let user = cap.at(1).unwrap();
    let repo = cap.at(2).unwrap();
    let number = cap.at(3).unwrap();

    github::get_display_text(user, repo, number).ok()
}

fn handle_message(server: &NetIrcServer, from: &str, to: &str, message: &str) {
    let nickname = server.config().nickname.as_ref().unwrap();

    if to == nickname && from == "ids1024" {
        let mut words = message.split_whitespace();
        let command = words.next().unwrap_or("");
        let parameter = words.next().unwrap_or("");
        match command {
            "join" => {
                server.send_join(parameter).unwrap();
            },
            "part" => {
                server.send(Command::PART(parameter.to_string(), None)).unwrap();
            },
            "quit" => {
                server.send_quit("").unwrap();
            }
            _ => {},
        }
    }

    if let Some(x) = parse_post(&message) {
        for line in x.lines() {
            server.send_privmsg(&to, &line).unwrap();
        }
    }
}

fn main() {
    let mut configpath = get_config_home().unwrap();
    configpath.push("idsbot/config.json");

    let config = Config::load(configpath).unwrap();
    let server = IrcServer::from_config(config).unwrap();
    server.identify().unwrap();

    for message in server.iter() {
        let message = message.unwrap();
        print!("{}", message.into_string());
        if message.command == "PRIVMSG" {
            let from = message.get_source_nickname().unwrap().to_owned();
            let to = message.args[0].to_owned();
            let content = message.suffix.unwrap();
            handle_message(&server, &from, &to, &content);
        }
    }
}
<|endoftext|>


<commit_before>//! Author : Thibault Barbie
//!
//! A simple evolutionary algorithm written in Rust.

extern crate rand;

use std::collections::{HashMap};
use rand::{Rng};

fn main() {
    let target: String = String::from("METHINKS IT IS LIKE A WEASEL");
    let mut parent: String = "".to_string();
    let nb_copy = 400;
    let mutation_rate : f64 = 0.05;
    let mut counter=0;

    generate_first_sentence(&mut parent);

    println!("{}", target);
    println!("{}", parent);

    while fitness(&target, &parent) != 0 {
        let mut sentences: HashMap<u32, String> = HashMap::new();
        let mut f_min: u32 = 30;

        counter+=1;

        for _ in 0..nb_copy {
            let sentence = mutate(&mut parent, mutation_rate);
            let f = fitness(&target, &sentence);
            sentences.insert(f,sentence);

            if f<f_min { f_min = f; }
        }

        if fitness(&target, &parent) > f_min {
            match sentences.get(&f_min) {
                Some(s) => {
                    parent = s.clone();
                    println!("{} : {}", parent, counter);
                },
                None => panic!("Error, fitness minimum but no sentence."),
            }
        }
    }
}

/// Computes the fitness of a sentence against a target string.
fn fitness(target: &String, sentence: &String) -> u32 {
    let mut fitness = 0;

    for (c1, c2) in target.chars().zip(sentence.chars()) {
        if c1 != c2 {
            fitness += 1;
        }
    }

    fitness
}

/// Mutation algorithm.
///
/// It mutates each character of a string, according to a `mutation_rate`.
/// Please note that for full usefullness, `mutation_rate` should be between
/// 0 and 1.
fn mutate(sentence: &mut String, mutation_rate: f64) -> String {
    let mut rng = rand::thread_rng();

    let mut mutation: String = "".to_string();

    for c in sentence.chars() {
        if mutation_rate > rng.gen_range(0f64, 1f64) {
            mutation.push(c);
        } else {
            mutation.push(random_char());
        }
    }
    mutation
}

/// Generates a random sentence of length 28 from completly random chars.
fn generate_first_sentence(parent: &mut String) {
    for _ in 0..28 {
        parent.push(random_char());
    }
}

/// Generates a random char (between 'A' and '\\').
fn random_char() -> char {
    match rand::thread_rng().gen_range('A' as u8, '\\' as u8) as char {
        '[' => ' ',
        c @ _ => c
    }
}
<commit_msg>Code: again, some code lints.<commit_after>//! Author : Thibault Barbie
//!
//! A simple evolutionary algorithm written in Rust.

extern crate rand;

use std::collections::{HashMap};
use rand::{Rng};

fn main() {
    let target: String = String::from("METHINKS IT IS LIKE A WEASEL");
    let mut parent: String = "".to_string();
    let nb_copy = 400;
    let mutation_rate : f64 = 0.05;
    let mut counter=0;

    generate_first_sentence(&mut parent);

    println!("{}", target);
    println!("{}", parent);

    while fitness(&target, &parent) != 0 {
        let mut sentences: HashMap<u32, String> = HashMap::new();
        let mut f_min: u32 = 30;

        counter+=1;

        for _ in 0..nb_copy {
            let sentence = mutate(&mut parent, mutation_rate);
            let f = fitness(&target, &sentence);

            sentences.insert(f,sentence);
            if f<f_min {
                f_min = f;
            }
        }

        if fitness(&target, &parent) > f_min {
            match sentences.get(&f_min) {
                Some(s) => {
                    parent = s.clone();
                    println!("{} : {}", parent, counter);
                },
                None => panic!("Error, fitness minimum but no sentence."),
            }
        }
    }
}

/// Computes the fitness of a sentence against a target string.
fn fitness(target: &String, sentence: &String) -> u32 {
    let mut fitness = 0;

    for (c1, c2) in target.chars().zip(sentence.chars()) {
        if c1 != c2 {
            fitness += 1;
        }
    }

    fitness
}

/// Mutation algorithm.
///
/// It mutates each character of a string, according to a `mutation_rate`.
/// Please note that for full usefullness, `mutation_rate` should be between
/// 0 and 1.
fn mutate(sentence: &mut String, mutation_rate: f64) -> String {
    let mut rng = rand::thread_rng();
    let mut mutation: String = "".to_string();

    for c in sentence.chars() {
        if mutation_rate > rng.gen_range(0f64, 1f64) {
            mutation.push(c);
        } else {
            mutation.push(random_char());
        }
    }

    mutation
}

/// Generates a random sentence of length 28 from completly random chars.
fn generate_first_sentence(parent: &mut String) {
    for _ in 0..28 {
        parent.push(random_char());
    }
}

/// Generates a random char (between 'A' and '\\').
fn random_char() -> char {
    match rand::thread_rng().gen_range('A' as u8, '\\' as u8) as char {
        '['     => ' ',
        c @ _   => c
    }
}
<|endoftext|>


<commit_before><commit_msg>add DynamoDB integration tests<commit_after>#![cfg(feature = "dynamodb")]

extern crate rusoto;

use rusoto::dynamodb::{DynamoDbClient, ListTablesInput};
use rusoto::{DefaultCredentialsProvider, Region};

#[test]
fn should_list_tables() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DynamoDbClient::new(credentials, Region::UsEast1);

    let request = ListTablesInput::default();

    match client.list_tables(&request) {
        Ok(response) => {
            println!("{:#?}", response);
            assert!(true)
        },
        Err(err) => panic!("Expected OK response, got {:#?}", err)
    };
}

<|endoftext|>


<commit_before><commit_msg>Fix a typo in the documentation of the connection tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add PWM example<commit_after>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// pwm_blinkled.rs
//
// Blinks an LED attached to a GPIO pin using PWM.
//
// Remember to add a resistor of an appropriate value in series, to prevent
// exceeding the maximum current rating of the GPIO pin and the LED.
//
// Interrupting the process by pressing Ctrl-C causes the application to exit
// immediately without disabling the PWM channel. Check out the
// gpio_blinkled_signals.rs example to learn how to properly handle incoming
// signals to prevent an abnormal termination.

use std::process::exit;
use std::thread::sleep;
use std::time::Duration;

use rppal::pwm::{Channel, Polarity, Pwm};

fn main() {
    // Enable PWM channel 0 (BCM GPIO 18, physical pin 12) at 2 Hz with a 25% duty cycle.
    let pwm =
        Pwm::with_frequency(Channel::Pwm0, 2.0, 0.25, Polarity::Normal, true).unwrap_or_else(|e| {
            eprintln!("Error: Can't access PWM peripheral ({})", e);
            exit(1);
        });

    // Sleep for 2 seconds while the LED blinks.
    sleep(Duration::from_secs(2));

    // Reconfigure the PWM channel for an 8 Hz frequency, 50% duty cycle.
    pwm.set_frequency(8.0, 0.5).unwrap_or_else(|e| {
        eprintln!("Error: Invalid frequency or duty cycle ({})", e);
        exit(1);
    });

    sleep(Duration::from_secs(3));

    // When the pwm variable goes out of scope at the end of the main()
    // function, the PWM channel is automatically disabled. You can manually
    // disable the channel by calling the Pwm::disable() method.
}
<|endoftext|>


<commit_before>import syntax::ast;
import lib::llvm::llvm::ValueRef;
import trans_common::*;
import trans_build::*;
import trans::{
    trans_shared_malloc,
    type_of_or_i8,
    size_of,
    move_val_if_temp,
    node_id_type,
    trans_lval,
    INIT,
    trans_shared_free,
    drop_ty,
    new_sub_block_ctxt
};

export trans_uniq, make_free_glue, type_is_unique_box, copy_val, autoderef;

pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
    unchecked {
        ty::type_is_unique_box(bcx_tcx(bcx), ty)
    }
}

fn trans_uniq(cx: @block_ctxt, contents: @ast::expr,
              node_id: ast::node_id) -> result {
    let bcx = cx;

    let lv = trans_lval(bcx, contents);
    bcx = lv.bcx;

    let uniq_ty = node_id_type(bcx_ccx(cx), node_id);
    check type_is_unique_box(bcx, uniq_ty);
    let content_ty = content_ty(bcx, uniq_ty);
    let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);

    add_clean_temp(bcx, llptr, uniq_ty);

    bcx = move_val_if_temp(bcx, INIT, llptr, lv,
                           content_ty);

    ret rslt(bcx, llptr);
}

fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t)
    : type_is_unique_box(cx, uniq_ty) -> result {

    let bcx = cx;
    let contents_ty = content_ty(bcx, uniq_ty);
    let r = size_of(bcx, contents_ty);
    bcx = r.bcx;
    let llsz = r.val;

    let llptrty = T_ptr(type_of_or_i8(bcx, contents_ty));

    r = trans_shared_malloc(bcx, llptrty, llsz);
    bcx = r.bcx;
    let llptr = r.val;

    ret rslt(bcx, llptr);
}

fn make_free_glue(cx: @block_ctxt, v: ValueRef, t: ty::t)
    : type_is_unique_box(cx, t) -> @block_ctxt {

    let bcx = cx;
    let free_cx = new_sub_block_ctxt(bcx, "uniq_free");
    let next_cx = new_sub_block_ctxt(bcx, "uniq_free_next");
    let vptr = Load(bcx, v);
    let null_test = IsNull(bcx, vptr);
    CondBr(bcx, null_test, next_cx.llbb, free_cx.llbb);

    let bcx = free_cx;
    let bcx = drop_ty(bcx, vptr, content_ty(cx, t));
    let bcx = trans_shared_free(bcx, vptr);
    Store(bcx, C_null(val_ty(vptr)), v);
    Br(bcx, next_cx.llbb);

    next_cx
}

fn content_ty(bcx: @block_ctxt, t: ty::t)
    : type_is_unique_box(bcx, t) -> ty::t {

    alt ty::struct(bcx_tcx(bcx), t) {
      ty::ty_uniq({ty: ct, _}) { ct }
    }
}

fn copy_val(cx: @block_ctxt, dst: ValueRef, src: ValueRef,
            ty: ty::t) : type_is_unique_box(cx, ty) -> @block_ctxt {

    let content_ty = content_ty(cx, ty);
    let {bcx, val: llptr} = alloc_uniq(cx, ty);
    Store(bcx, llptr, dst);

    let src = Load(bcx, src);
    let dst = Load(bcx, dst);
    let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
    Store(bcx, src, llptr);
    ret bcx;
}

fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
    : type_is_unique_box(bcx, t) -> {v: ValueRef, t: ty::t} {

    let content_ty = content_ty(bcx, t);
    ret {v: v, t: content_ty};
}<commit_msg>Remove nonsensical load and store from trans_uniq::copy_val<commit_after>import syntax::ast;
import lib::llvm::llvm::ValueRef;
import trans_common::*;
import trans_build::*;
import trans::{
    trans_shared_malloc,
    type_of_or_i8,
    size_of,
    move_val_if_temp,
    node_id_type,
    trans_lval,
    INIT,
    trans_shared_free,
    drop_ty,
    new_sub_block_ctxt
};

export trans_uniq, make_free_glue, type_is_unique_box, copy_val, autoderef;

pure fn type_is_unique_box(bcx: @block_ctxt, ty: ty::t) -> bool {
    unchecked {
        ty::type_is_unique_box(bcx_tcx(bcx), ty)
    }
}

fn trans_uniq(cx: @block_ctxt, contents: @ast::expr,
              node_id: ast::node_id) -> result {
    let bcx = cx;

    let lv = trans_lval(bcx, contents);
    bcx = lv.bcx;

    let uniq_ty = node_id_type(bcx_ccx(cx), node_id);
    check type_is_unique_box(bcx, uniq_ty);
    let content_ty = content_ty(bcx, uniq_ty);
    let {bcx, val: llptr} = alloc_uniq(bcx, uniq_ty);

    add_clean_temp(bcx, llptr, uniq_ty);

    bcx = move_val_if_temp(bcx, INIT, llptr, lv,
                           content_ty);

    ret rslt(bcx, llptr);
}

fn alloc_uniq(cx: @block_ctxt, uniq_ty: ty::t)
    : type_is_unique_box(cx, uniq_ty) -> result {

    let bcx = cx;
    let contents_ty = content_ty(bcx, uniq_ty);
    let r = size_of(bcx, contents_ty);
    bcx = r.bcx;
    let llsz = r.val;

    let llptrty = T_ptr(type_of_or_i8(bcx, contents_ty));

    r = trans_shared_malloc(bcx, llptrty, llsz);
    bcx = r.bcx;
    let llptr = r.val;

    ret rslt(bcx, llptr);
}

fn make_free_glue(cx: @block_ctxt, v: ValueRef, t: ty::t)
    : type_is_unique_box(cx, t) -> @block_ctxt {

    let bcx = cx;
    let free_cx = new_sub_block_ctxt(bcx, "uniq_free");
    let next_cx = new_sub_block_ctxt(bcx, "uniq_free_next");
    let vptr = Load(bcx, v);
    let null_test = IsNull(bcx, vptr);
    CondBr(bcx, null_test, next_cx.llbb, free_cx.llbb);

    let bcx = free_cx;
    let bcx = drop_ty(bcx, vptr, content_ty(cx, t));
    let bcx = trans_shared_free(bcx, vptr);
    Store(bcx, C_null(val_ty(vptr)), v);
    Br(bcx, next_cx.llbb);

    next_cx
}

fn content_ty(bcx: @block_ctxt, t: ty::t)
    : type_is_unique_box(bcx, t) -> ty::t {

    alt ty::struct(bcx_tcx(bcx), t) {
      ty::ty_uniq({ty: ct, _}) { ct }
    }
}

fn copy_val(cx: @block_ctxt, dst: ValueRef, src: ValueRef,
            ty: ty::t) : type_is_unique_box(cx, ty) -> @block_ctxt {

    let content_ty = content_ty(cx, ty);
    let {bcx, val: llptr} = alloc_uniq(cx, ty);
    Store(bcx, llptr, dst);

    let src = Load(bcx, src);
    let dst = llptr;
    let bcx = trans::copy_val(bcx, INIT, dst, src, content_ty);
    ret bcx;
}

fn autoderef(bcx: @block_ctxt, v: ValueRef, t: ty::t)
    : type_is_unique_box(bcx, t) -> {v: ValueRef, t: ty::t} {

    let content_ty = content_ty(bcx, t);
    ret {v: v, t: content_ty};
}<|endoftext|>


<commit_before><commit_msg>introduce `Universe` struct<commit_after><|endoftext|>


<commit_before><commit_msg>Remove the remainder of the explicit shader stages, default to sampler uniforms only used in fragment shaders<commit_after><|endoftext|>


<commit_before>use alloc::arc::{Arc, Weak};
use alloc::boxed::Box;

use collections::{BTreeMap, String};
use collections::string::ToString;

use core::cell::Cell;
use core::mem::size_of;

use scheduler::context::context_switch;

use schemes::{Result, Resource, ResourceSeek, KScheme, Url};

use sync::Intex;

use system::error::{Error, EBADF, EINVAL, ENOENT, ESPIPE};
use system::scheme::Packet;
use system::syscall::SYS_OPEN;

struct SchemeInner {
    name: String,
    next_id: Cell<usize>,
    todo: Intex<BTreeMap<usize, (usize, usize, usize, usize)>>,
    done: Intex<BTreeMap<usize, (usize, usize, usize, usize)>>,
}

impl SchemeInner {
    fn new(name: String) -> SchemeInner {
        SchemeInner {
            name: name,
            next_id: Cell::new(1),
            todo: Intex::new(BTreeMap::new()),
            done: Intex::new(BTreeMap::new()),
        }
    }

    fn recv(&self, packet: &mut Packet) {
        loop {
            {
                let mut todo = self.todo.lock();

                packet.id = if let Some(id) = todo.keys().next() {
                    *id
                } else {
                    0
                };

                if packet.id > 0 {
                    if let Some(regs) = todo.remove(&packet.id) {
                        packet.a = regs.0;
                        packet.b = regs.1;
                        packet.c = regs.2;
                        packet.d = regs.3;
                        return
                    }
                }
            }

            unsafe { context_switch(false) } ;
        }
    }

    fn send(&self, packet: &Packet) {
        self.done.lock().insert(packet.id, (packet.a, packet.b, packet.c, packet.d));
    }

    fn call(&self, a: usize, b: usize, c: usize, d: usize) -> usize {
        let id = self.next_id.get();

        //TODO: What should be done about collisions in self.todo or self.done?
        {
            let mut next_id = id + 1;
            if next_id <= 0 {
                next_id = 1;
            }
            self.next_id.set(next_id);
        }

        self.todo.lock().insert(id, (a, b, c, d));

        loop {
            if let Some(regs) = self.done.lock().remove(&id) {
                return regs.0;
            }

            unsafe { context_switch(false) } ;
        }
    }
}

pub struct SchemeResource {
    inner: Weak<SchemeInner>,
    file_id: usize,
}

impl Resource for SchemeResource {
    /// Duplicate the resource
    fn dup(&self) -> Result<Box<Resource>> {
        Err(Error::new(EBADF))
    }

    /// Return the url of this resource
    fn url(&self) -> Url {
        Url::new()
    }

    // TODO: Make use of Write and Read trait
    /// Read data to buffer
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    /// Write to resource
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    /// Seek
    fn seek(&mut self, pos: ResourceSeek) -> Result<usize> {
        Err(Error::new(EBADF))
    }

    /// Sync the resource
    fn sync(&mut self) -> Result<()> {
        Err(Error::new(EBADF))
    }

    fn truncate(&mut self, len: usize) -> Result<()> {
        Err(Error::new(EBADF))
    }
}

pub struct SchemeServerResource {
    inner: Weak<SchemeInner>,
}

impl Resource for SchemeServerResource {
    /// Duplicate the resource
    fn dup(&self) -> Result<Box<Resource>> {
        Ok(box SchemeServerResource {
            inner: self.inner.clone()
        })
    }

    /// Return the url of this resource
    fn url(&self) -> Url {
        if let Some(scheme) = self.inner.upgrade() {
            Url::from_string(":".to_string() + &scheme.name)
        } else {
            Url::new()
        }
    }

    // TODO: Make use of Write and Read trait
    /// Read data to buffer
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            if buf.len() == size_of::<Packet>() {
                let packet_ptr: *mut Packet = buf.as_mut_ptr() as *mut Packet;
                scheme.recv(unsafe { &mut *packet_ptr });

                Ok(size_of::<Packet>())
            } else {
                Err(Error::new(EINVAL))
            }
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Write to resource
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            if buf.len() == size_of::<Packet>() {
                let packet_ptr: *const Packet = buf.as_ptr() as *const Packet;
                scheme.send(unsafe { &*packet_ptr });

                Ok(size_of::<Packet>())
            } else {
                Err(Error::new(EINVAL))
            }
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Seek
    fn seek(&mut self, pos: ResourceSeek) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(ESPIPE))
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Sync the resource
    fn sync(&mut self) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(EINVAL))
        }else {
            Err(Error::new(EBADF))
        }
    }

    fn truncate(&mut self, len: usize) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(EINVAL))
        }else {
            Err(Error::new(EBADF))
        }
    }
}

/// Scheme has to be wrapped
pub struct Scheme {
    inner: Arc<SchemeInner>
}

impl Scheme {
    pub fn new(name: String) -> Box<Scheme> {
        box Scheme {
            inner: Arc::new(SchemeInner::new(name))
        }
    }

    pub fn server(&self) -> Box<Resource> {
        box SchemeServerResource {
            inner: Arc::downgrade(&self.inner)
        }
    }
}

impl KScheme for Scheme {
    fn on_irq(&mut self, irq: u8) {

    }

    fn on_poll(&mut self) {

    }

    fn scheme(&self) -> &str {
        &self.inner.name
    }

    fn open(&mut self, url: &Url, flags: usize) -> Result<Box<Resource>> {
        let c_str = url.string.clone() + "\0";
        debugln!("{} open: {}", self.inner.name, self.inner.call(SYS_OPEN, c_str.as_ptr() as usize, 0, 0));

        Err(Error::new(ENOENT))
    }

    fn unlink(&mut self, url: &Url) -> Result<()> {
        Err(Error::new(ENOENT))
    }
}
<commit_msg>Pass file operations and unlink to scheme<commit_after>use alloc::arc::{Arc, Weak};
use alloc::boxed::Box;

use collections::{BTreeMap, String};
use collections::string::ToString;

use core::cell::Cell;
use core::mem::size_of;

use scheduler::context::context_switch;

use schemes::{Result, Resource, ResourceSeek, KScheme, Url};

use sync::Intex;

use system::error::{Error, EBADF, EINVAL, ENOENT, ESPIPE};
use system::scheme::Packet;
use system::syscall::{SYS_FSYNC, SYS_FTRUNCATE, SYS_LSEEK, SEEK_SET, SEEK_CUR, SEEK_END, SYS_OPEN, SYS_READ, SYS_WRITE, SYS_UNLINK};

struct SchemeInner {
    name: String,
    next_id: Cell<usize>,
    todo: Intex<BTreeMap<usize, (usize, usize, usize, usize)>>,
    done: Intex<BTreeMap<usize, (usize, usize, usize, usize)>>,
}

impl SchemeInner {
    fn new(name: String) -> SchemeInner {
        SchemeInner {
            name: name,
            next_id: Cell::new(1),
            todo: Intex::new(BTreeMap::new()),
            done: Intex::new(BTreeMap::new()),
        }
    }

    fn recv(&self, packet: &mut Packet) {
        loop {
            {
                let mut todo = self.todo.lock();

                packet.id = if let Some(id) = todo.keys().next() {
                    *id
                } else {
                    0
                };

                if packet.id > 0 {
                    if let Some(regs) = todo.remove(&packet.id) {
                        packet.a = regs.0;
                        packet.b = regs.1;
                        packet.c = regs.2;
                        packet.d = regs.3;
                        return
                    }
                }
            }

            unsafe { context_switch(false) } ;
        }
    }

    fn send(&self, packet: &Packet) {
        self.done.lock().insert(packet.id, (packet.a, packet.b, packet.c, packet.d));
    }

    fn call(&self, a: usize, b: usize, c: usize, d: usize) -> usize {
        let id = self.next_id.get();

        //TODO: What should be done about collisions in self.todo or self.done?
        {
            let mut next_id = id + 1;
            if next_id <= 0 {
                next_id = 1;
            }
            self.next_id.set(next_id);
        }

        self.todo.lock().insert(id, (a, b, c, d));

        loop {
            if let Some(regs) = self.done.lock().remove(&id) {
                return regs.0;
            }

            unsafe { context_switch(false) } ;
        }
    }
}

pub struct SchemeResource {
    inner: Weak<SchemeInner>,
    file_id: usize,
}

impl Resource for SchemeResource {
    /// Duplicate the resource
    fn dup(&self) -> Result<Box<Resource>> {
        Err(Error::new(EBADF))
    }

    /// Return the url of this resource
    fn url(&self) -> Url {
        Url::new()
    }

    // TODO: Make use of Write and Read trait
    /// Read data to buffer
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            Error::demux(scheme.call(SYS_READ, self.file_id, buf.as_mut_ptr() as usize, buf.len()))
        } else {
            Err(Error::new(EBADF))
        }
    }

    /// Write to resource
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            Error::demux(scheme.call(SYS_WRITE, self.file_id, buf.as_ptr() as usize, buf.len()))
        } else {
            Err(Error::new(EBADF))
        }
    }

    /// Seek
    fn seek(&mut self, pos: ResourceSeek) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            let (whence, offset) = match pos {
                ResourceSeek::Start(offset) => (SEEK_SET, offset as usize),
                ResourceSeek::Current(offset) => (SEEK_CUR, offset as usize),
                ResourceSeek::End(offset) => (SEEK_END, offset as usize)
            };

            Error::demux(scheme.call(SYS_LSEEK, self.file_id, offset, whence))
        } else {
            Err(Error::new(EBADF))
        }
    }

    /// Sync the resource
    fn sync(&mut self) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Error::demux(scheme.call(SYS_FSYNC, self.file_id, 0, 0)).and(Ok(()))
        } else {
            Err(Error::new(EBADF))
        }
    }

    fn truncate(&mut self, len: usize) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Error::demux(scheme.call(SYS_FTRUNCATE, self.file_id, len, 0)).and(Ok(()))
        } else {
            Err(Error::new(EBADF))
        }
    }
}

pub struct SchemeServerResource {
    inner: Weak<SchemeInner>,
}

impl Resource for SchemeServerResource {
    /// Duplicate the resource
    fn dup(&self) -> Result<Box<Resource>> {
        Ok(box SchemeServerResource {
            inner: self.inner.clone()
        })
    }

    /// Return the url of this resource
    fn url(&self) -> Url {
        if let Some(scheme) = self.inner.upgrade() {
            Url::from_string(":".to_string() + &scheme.name)
        } else {
            Url::new()
        }
    }

    // TODO: Make use of Write and Read trait
    /// Read data to buffer
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            if buf.len() == size_of::<Packet>() {
                let packet_ptr: *mut Packet = buf.as_mut_ptr() as *mut Packet;
                scheme.recv(unsafe { &mut *packet_ptr });

                Ok(size_of::<Packet>())
            } else {
                Err(Error::new(EINVAL))
            }
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Write to resource
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            if buf.len() == size_of::<Packet>() {
                let packet_ptr: *const Packet = buf.as_ptr() as *const Packet;
                scheme.send(unsafe { &*packet_ptr });

                Ok(size_of::<Packet>())
            } else {
                Err(Error::new(EINVAL))
            }
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Seek
    fn seek(&mut self, pos: ResourceSeek) -> Result<usize> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(ESPIPE))
        }else {
            Err(Error::new(EBADF))
        }
    }

    /// Sync the resource
    fn sync(&mut self) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(EINVAL))
        }else {
            Err(Error::new(EBADF))
        }
    }

    fn truncate(&mut self, len: usize) -> Result<()> {
        if let Some(scheme) = self.inner.upgrade() {
            Err(Error::new(EINVAL))
        }else {
            Err(Error::new(EBADF))
        }
    }
}

/// Scheme has to be wrapped
pub struct Scheme {
    inner: Arc<SchemeInner>
}

impl Scheme {
    pub fn new(name: String) -> Box<Scheme> {
        box Scheme {
            inner: Arc::new(SchemeInner::new(name))
        }
    }

    pub fn server(&self) -> Box<Resource> {
        box SchemeServerResource {
            inner: Arc::downgrade(&self.inner)
        }
    }
}

impl KScheme for Scheme {
    fn on_irq(&mut self, irq: u8) {

    }

    fn on_poll(&mut self) {

    }

    fn scheme(&self) -> &str {
        &self.inner.name
    }

    fn open(&mut self, url: &Url, flags: usize) -> Result<Box<Resource>> {
        let c_str = url.string.clone() + "\0";
        match Error::demux(self.inner.call(SYS_OPEN, c_str.as_ptr() as usize, 0, 0)) {
            Ok(file_id) => Ok(box SchemeResource {
                inner: Arc::downgrade(&self.inner),
                file_id: file_id,
            }),
            Err(err) => Err(err)
        }
    }

    fn unlink(&mut self, url: &Url) -> Result<()> {
        let c_str = url.string.clone() + "\0";
        Error::demux(self.inner.call(SYS_UNLINK, c_str.as_ptr() as usize, 0, 0)).and(Ok(()))
    }
}
<|endoftext|>


<commit_before><commit_msg>Updated board to take closures which compute how generic types should be added and compared.<commit_after><|endoftext|>


<commit_before><commit_msg>First (incomplete) const folding<commit_after>use rustc::lint::Context;
use rustc::middle::const_eval::lookup_const_by_id;
use syntax::ast::*;
use syntax::ptr::P;

/// a Lit_-like enum to fold constant `Expr`s into
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Constant {
    ConstantStr(&'static str, StrStyle),
    ConstantBinary(Rc<Vec<u8>>),
    ConstantByte(u8),
    ConstantChar(char),
    ConstantInt(u64, LitIntType),
    ConstantFloat(Cow<'static, str>, FloatTy),
    ConstantFloatUnsuffixed(Cow<'static, str>),
    ConstantBool(bool),
    ConstantVec(Vec<Constant>),
    ConstantTuple(Vec<Constant>),
}

/// simple constant folding
pub fn constant(cx: &Context, e: &Expr) -> Option<Constant> {
    match e {
        &ExprParen(ref inner) => constant(cx, inner),
        &ExprPath(_, _) => fetch_path(cx, e),
        &ExprBlock(ref block) => constant_block(cx, inner),
        &ExprIf(ref cond, ref then, ref otherwise) =>
            match constant(cx, cond) {
                Some(LitBool(true)) => constant(cx, then),
                Some(LitBool(false)) => constant(cx, otherwise),
                _ => None,
            },
        &ExprLit(ref lit) => Some(lit_to_constant(lit)),
        &ExprVec(ref vec) => constant_vec(cx, vec),
        &ExprTup(ref tup) => constant_tup(cx, tup),
        &ExprUnary(op, ref operand) => constant(cx, operand).and_then(
            |o| match op {
                UnNot =>
                    if let ConstantBool(b) = o {
                        Some(ConstantBool(!b))
                    } else { None },
                UnNeg =>
                    match o {
                        &ConstantInt(value, ty) =>
                            Some(ConstantInt(value, match ty {
                                SignedIntLit(ity, sign) =>
                                    SignedIntLit(ity, neg_sign(sign)),
                                UnsuffixedIntLit(sign) =>
                                    UnsuffixedIntLit(neg_sign(sign)),
                                _ => { return None; },
                            })),
                        &LitFloat(ref is, ref ty) =>
                            Some(ConstantFloat(neg_float_str(is), ty)),
                        &LitFloatUnsuffixed(ref is) =>
                            Some(ConstantFloatUnsuffixed(neg_float_str(is))),
                        _ => None,
                    },
                UnUniq | UnDeref => o,
            }),
        //TODO: add other expressions
        _ => None,
    }
}

fn lit_to_constant(lit: &Lit_) -> Constant {
    match lit {
        &LitStr(ref is, style) => ConstantStr(&*is, style),
        &LitBinary(ref blob) => ConstantBinary(blob.clone()),
        &LitByte(b) => ConstantByte(b),
        &LitChar(c) => ConstantChar(c),
        &LitInt(value, ty) => ConstantInt(value, ty),
        &LitFloat(ref is, ty) => ConstantFloat(Cow::Borrowed(&*is), ty),
        &LitFloatUnsuffixed(InternedString) =>
            ConstantFloatUnsuffixed(Cow::Borrowed(&*is)),
        &LitBool(b) => ConstantBool(b),
    }
}

/// create `Some(ConstantVec(..))` of all constants, unless there is any
/// non-constant part
fn constant_vec(cx: &Context, vec: &[&Expr]) -> Option<Constant> {
    Vec<Constant> parts = Vec::new();
    for opt_part in vec {
        match constant(cx, opt_part) {
            Some(ref p) => parts.push(p),
            None => { return None; },
        }
    }
    Some(ConstantVec(parts))
}

fn constant_tup(cx, &Context, tup: &[&Expr]) -> Option<Constant> {
    Vec<Constant> parts = Vec::new();
    for opt_part in vec {
        match constant(cx, opt_part) {
            Some(ref p) => parts.push(p),
            None => { return None; },
        }
    }
    Some(ConstantTuple(parts))
}

/// lookup a possibly constant expression from a ExprPath
fn fetch_path(cx: &Context, e: &Expr) -> Option<Constant> {
    if let Some(&PathResolution { base_def: DefConst(id), ..}) =
            cx.tcx.def_map.borrow().get(&e.id) {
        lookup_const_by_id(cx.tcx, id, None).map(|l| constant(cx, l))
    } else { None }
}

/// A block can only yield a constant if it only has one constant expression
fn constant_block(cx: &Context, block: &Block) -> Option<Constant> {
    if block.stmts.is_empty() {
        block.expr.map(|b| constant(cx, b))
    } else { None }
}

fn neg_sign(s: Sign) -> Sign {
    match s:
        Sign::Plus => Sign::Minus,
        Sign::Minus => Sign::Plus,
    }
}

fn neg_float_str(s: &InternedString) -> Cow<'static, str> {
    if s.startsWith('-') {
        Cow::Borrowed(s[1..])
    } else {
        Cow::Owned(format!("-{}", &*s))
    }
}
<|endoftext|>


<commit_before><commit_msg>Forgot to check in the error.rs<commit_after>extern crate capnp;
extern crate rocksdb;

use std::{error, fmt};

#[derive(Debug)]
pub enum Error {
    Parse(String),
    Shred(String),
    Capnp(capnp::Error),
    Rocks(rocksdb::Error),
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Parse(ref description) => description,
            Error::Shred(ref description) => description,
            Error::Capnp(ref err) => err.description(),
            // XXX vmx 2016-11-07: It should be fixed on the RocksDB wrapper
            // that it has the std::error:Error implemented and hence
            // and err.description()
            Error::Rocks(_) => "This is an rocksdb error",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::Parse(_) => None,
            Error::Shred(_) => None,
            Error::Capnp(ref err) => Some(err as &error::Error),
            // NOTE vmx 2016-11-07: Looks like the RocksDB Wrapper needs to be
            // patched to be based on the std::error::Error trait
            Error::Rocks(_) => None,
        }
    }
}

impl From<capnp::Error> for Error {
    fn from(err: capnp::Error) -> Error {
        Error::Capnp(err)
    }
}

impl From<rocksdb::Error> for Error {
    fn from(err: rocksdb::Error) -> Error {
        Error::Rocks(err)
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Parse(ref err) => write!(f, "Parse error: {}", err),
            Error::Shred(ref err) => write!(f, "Shred error: {}", err),
            Error::Capnp(ref err) => write!(f, "Capnproto error: {}", err),
            Error::Rocks(ref err) => write!(f, "RocksDB error: {}", err),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement debug for error<commit_after><|endoftext|>


<commit_before>use common::debug::*;
use common::memory::*;
use common::pio::*;

/* Networking { */

const CTRL: u32 = 0x00;
    const CTRL_LRST: u32 = 1 << 3;
    const CTRL_ASDE: u32 = 1 << 5;
    const CTRL_SLU: u32 = 1 << 6;
    const CTRL_ILOS: u32 = 1 << 7;
    const CTRL_VME: u32 = 1 << 30;
    const CTRL_PHY_RST: u32 = 1 << 31;

const STATUS: u32 = 0x08;

const FCAL: u32 = 0x28;
const FCAH: u32 = 0x2C;
const FCT: u32 = 0x30;
const FCTTV: u32 = 0x170;

const IMS: u32 = 0xD0;
    const IMS_LSC: u32 = 1 << 2;
    const IMS_RXSEQ: u32 = 1 << 3;
    const IMS_RXDMT: u32 = 1 << 4;
    const IMS_RX: u32 = 1 << 6;
    const IMS_RXT: u32 = 1 << 7;

const RCTL: u32 = 0x100;
    const RCTL_EN: u32 = 1 << 1;
    const RCTL_LPE: u32 = 1 << 5;
    const RCTL_LBM: u32 = 1 << 6 | 1 << 7;
    const RCTL_BAM: u32 = 1 << 15;
    const RCTL_BSIZE: u32 = 1 << 16 | 1 << 17;
    const RCTL_BSEX: u32 = 1 << 25;
    const RCTL_SECRC: u32 = 1 << 26;

const RDBAL: u32 = 0x2800;
const RDBAH: u32 = 0x2804;
const RDLEN: u32 = 0x2808;
const RDH: u32 = 0x2810;
const RDT: u32 = 0x2818;

const RAL0: u32 = 0x5400;
const RAH0: u32 = 0x5404;

pub struct Intel8254x {
    base: usize,
    memory_mapped: bool
}

impl Intel8254x {
    pub unsafe fn read(&self, register: u32) -> u32 {
        let data;

        if self.memory_mapped {
            data = *((self.base + register as usize) as *mut u32);
        }else{
            outl(self.base as u16, register);
            data = inl((self.base + 4) as u16);
        }

        d("Read ");
        dh(register as usize);
        d(", result ");
        dh(data as usize);
        dl();

        return data;
    }

    pub unsafe fn write(&self, register: u32, data: u32){
        let result;
        if self.memory_mapped {
            *((self.base + register as usize) as *mut u32) = data;
            result = *((self.base + register as usize) as *mut u32);
        }else{
            outl(self.base as u16, register);
            outl((self.base + 4) as u16, data);
            result = inl((self.base + 4) as u16);
        }

        d("Set ");
        dh(register as usize);
        d(" to ");
        dh(data as usize);
        d(", result ");
        dh(result as usize);
        dl();
    }

    pub unsafe fn flag(&self, register: u32, flag: u32, value: bool){
        if value {
            self.write(register, self.read(register) | flag);
        }else{
            self.write(register, self.read(register) & (0xFFFFFFFF - flag));
        }
    }

    pub unsafe fn handle(&self){
        d("Intel 8254x handle\n");
    }

    pub unsafe fn init(&self){
        d("Intel 8254x on: ");
        dh(self.base);
        if self.memory_mapped {
            d(" memory mapped");
        }else{
            d(" port mapped");
        }
        dl();

        self.read(CTRL);
        self.read(STATUS);
        self.read(IMS);

        //Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal
        self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true);
        self.flag(CTRL, CTRL_LRST, false);
        self.flag(CTRL, CTRL_PHY_RST, false);
        self.flag(CTRL, CTRL_ILOS, false);

        //No flow control
        self.write(FCAH, 0);
        self.write(FCAL, 0);
        self.write(FCT, 0);
        self.write(FCTTV, 0);

        //Do not use VLANs
        self.flag(CTRL, CTRL_VME, false);

        // TODO: Clear statistical counters

        self.write(RAL0, 0x20202020);
        self.write(RAH0, 0x2020);
        /*
        MTA => 0;
        */
        self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ | IMS_LSC);

        //Receive Buffer
        let receive_ring_length = 4096;
        let receive_ring = alloc(receive_ring_length * 16);
        for i in 0..receive_ring_length {
            let receive_buffer = alloc(4096);
            *((receive_ring + i * 16) as *mut u64) = receive_buffer as u64;
        }

        self.write(RDBAH, 0);
        self.write(RDBAL, receive_ring as u32);
        self.write(RDLEN, (receive_ring_length * 16) as u32);
        self.write(RDH, 0);
        self.write(RDT, (receive_ring_length * 16) as u32);

        self.flag(RCTL, RCTL_EN, true);
        self.flag(RCTL, RCTL_LPE, true);
        self.flag(RCTL, RCTL_LBM, false);
        /* RCTL.RDMTS = Minimum threshold size ??? */
        /* RCTL.MO = Multicast offset */
        self.flag(RCTL, RCTL_BAM, true);
        self.flag(RCTL, RCTL_BSIZE, true);
        self.flag(RCTL, RCTL_BSEX, true);
        self.flag(RCTL, RCTL_SECRC, true);

        self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ | IMS_LSC);

        /*
        self.flag(TCTL, TCTL_EN, true);
        self.flag(TCTL, TCTL_PSP, true);
        */
        /* TCTL.CT = Collition threshold */
        /* TCTL.COLD = Collision distance */
        /* TIPG Packet Gap */
        /* TODO ... */

        self.read(CTRL);
        self.read(STATUS);
        self.read(IMS);
    }
}

pub struct RTL8139 {
    base: usize,
    memory_mapped: bool,
    receive_buffer: usize
}

impl RTL8139 {
    pub unsafe fn handle(&self){
        d("RTL8139 handle\n");

        let base = self.base as u16;

        let mut capr = (inw(base + 0x38) + 16) as usize;
        let cbr = inw(base + 0x3A) as usize;

        d("CAPR: ");
        dh(capr);
        dl();

        d("CBR: ");
        dh(cbr);
        dl();

        d("Packet len: ");
        let packet_len = *((self.receive_buffer + 2) as *const u16) as usize;
        dh(packet_len);
        dl();

        for i in capr..cbr {
            let data = *((self.receive_buffer + i*4) as *const u8);
            dbh(data);
            if i % 40 == 39 {
                dl();
            }else if i % 4 == 3{
                d(" ");
            }
        }
        dl();

        capr = capr + packet_len + 4;
        capr = (capr + 3) & (0xFFFFFFFF - 3);
        if capr >= 8192 {
            capr -= 8192
        }

        outw(base + 0x38, (capr as u16) - 16);
        outw(base + 0x3E, 0x0001);
    }

    pub unsafe fn init(&self){
        d("RTL8139 on: ");
        dh(self.base);
        if self.memory_mapped {
            d(" memory mapped");
        }else{
            d(" port mapped");
        }
        dl();

        let base = self.base as u16;

        outb(base + 0x52, 0x00);

        outb(base + 0x37, 0x10);
        while inb(base + 0x37) & 0x10 != 0 {
        }

        outl(base + 0x30, self.receive_buffer as u32);
        outw(base + 0x38, 0);
        outw(base + 0x3A, 0);

        outw(base + 0x3C, 0x0005);

        outl(base + 0x44, 0xf | (1 << 7));

        outb(base + 0x37, 0x0C);
    }
}

/* } Networking */

const CONFIG_ADDRESS: u16 = 0xCF8;
const CONFIG_DATA: u16 = 0xCFC;

unsafe fn pci_read(bus: usize, slot: usize, function: usize, offset: usize) -> usize{
    outl(CONFIG_ADDRESS, ((1 << 31) | (bus << 16) | (slot << 11) | (function << 8) | (offset & 0xfc)) as u32);
    return inl(CONFIG_DATA) as usize;
}

unsafe fn pci_write(bus: usize, slot: usize, function: usize, offset: usize, data: usize){
    outl(CONFIG_ADDRESS, ((1 << 31) | (bus << 16) | (slot << 11) | (function << 8) | (offset & 0xfc)) as u32);
    outl(CONFIG_DATA, data as u32);
}

pub unsafe fn pci_handle(irq: u8){
    d("PCI Handle ");
    dh(irq as usize);
    dl();

    for device in 0..32 {
        let data = pci_read(0, device, 0, 0);

        if (data & 0xFFFF) != 0xFFFF {
            if irq == pci_read(0, device, 0, 0x3C) as u8 & 0xF {
                if data == 0x100E8086 {
                    let base = pci_read(0, device, 0, 0x10);
                    let device = Intel8254x {
                        base: base & (0xFFFFFFFF - 1),
                        memory_mapped: base & 1 == 0
                    };
                    device.handle();
                } else if data == 0x813910EC {
                    let base = pci_read(0, device, 0, 0x10);
                    let device = RTL8139 {
                        base: base & (0xFFFFFFFF - 1),
                        memory_mapped: base & 1 == 0,
                        receive_buffer: 0x2A0000
                    };
                    device.handle();
                }
            }
        }
    }
}

pub unsafe fn pci_test(){
    d("PCI\n");

    for device in 0..32 {
        let data = pci_read(0, device, 0, 0);

        if (data & 0xFFFF) != 0xFFFF {
            d("Device ");
            dd(device);
            d(": ");
            dh(data);
            d(", ");
            dh(pci_read(0, device, 0, 8));
            dl();

            for i in 0..6 {
                d("    ");
                dd(i);
                d(": ");
                dh(pci_read(0, device, 0, i*4 + 0x10));
                dl();
            }

            if data == 0x100E8086 {
                let base = pci_read(0, device, 0, 0x10);
                let device = Intel8254x {
                    base: base & (0xFFFFFFFF - 1),
                    memory_mapped: base & 1 == 0
                };
                device.init();
            } else if data == 0x813910EC {
                pci_write(0, device, 0, 0x04, pci_read(0, device, 0, 0x04) | (1 << 2));

                d("IRQ ");
                dh(pci_read(0, device, 0, 0x3C) & 0xF + 0x20);
                dl();

                let base = pci_read(0, device, 0, 0x10);
                let device = RTL8139 {
                    base: base & (0xFFFFFFFF - 1),
                    memory_mapped: base & 1 == 0,
                    receive_buffer: 0x2A0000
                };
                device.init();
            }

            dl();
        }
    }
}<commit_msg>Fix RTL8139 driver<commit_after>use common::debug::*;
use common::memory::*;
use common::pio::*;

/* Networking { */

const CTRL: u32 = 0x00;
    const CTRL_LRST: u32 = 1 << 3;
    const CTRL_ASDE: u32 = 1 << 5;
    const CTRL_SLU: u32 = 1 << 6;
    const CTRL_ILOS: u32 = 1 << 7;
    const CTRL_VME: u32 = 1 << 30;
    const CTRL_PHY_RST: u32 = 1 << 31;

const STATUS: u32 = 0x08;

const FCAL: u32 = 0x28;
const FCAH: u32 = 0x2C;
const FCT: u32 = 0x30;
const FCTTV: u32 = 0x170;

const IMS: u32 = 0xD0;
    const IMS_LSC: u32 = 1 << 2;
    const IMS_RXSEQ: u32 = 1 << 3;
    const IMS_RXDMT: u32 = 1 << 4;
    const IMS_RX: u32 = 1 << 6;
    const IMS_RXT: u32 = 1 << 7;

const RCTL: u32 = 0x100;
    const RCTL_EN: u32 = 1 << 1;
    const RCTL_LPE: u32 = 1 << 5;
    const RCTL_LBM: u32 = 1 << 6 | 1 << 7;
    const RCTL_BAM: u32 = 1 << 15;
    const RCTL_BSIZE: u32 = 1 << 16 | 1 << 17;
    const RCTL_BSEX: u32 = 1 << 25;
    const RCTL_SECRC: u32 = 1 << 26;

const RDBAL: u32 = 0x2800;
const RDBAH: u32 = 0x2804;
const RDLEN: u32 = 0x2808;
const RDH: u32 = 0x2810;
const RDT: u32 = 0x2818;

const RAL0: u32 = 0x5400;
const RAH0: u32 = 0x5404;

pub struct Intel8254x {
    base: usize,
    memory_mapped: bool
}

impl Intel8254x {
    pub unsafe fn read(&self, register: u32) -> u32 {
        let data;

        if self.memory_mapped {
            data = *((self.base + register as usize) as *mut u32);
        }else{
            outl(self.base as u16, register);
            data = inl((self.base + 4) as u16);
        }

        d("Read ");
        dh(register as usize);
        d(", result ");
        dh(data as usize);
        dl();

        return data;
    }

    pub unsafe fn write(&self, register: u32, data: u32){
        let result;
        if self.memory_mapped {
            *((self.base + register as usize) as *mut u32) = data;
            result = *((self.base + register as usize) as *mut u32);
        }else{
            outl(self.base as u16, register);
            outl((self.base + 4) as u16, data);
            result = inl((self.base + 4) as u16);
        }

        d("Set ");
        dh(register as usize);
        d(" to ");
        dh(data as usize);
        d(", result ");
        dh(result as usize);
        dl();
    }

    pub unsafe fn flag(&self, register: u32, flag: u32, value: bool){
        if value {
            self.write(register, self.read(register) | flag);
        }else{
            self.write(register, self.read(register) & (0xFFFFFFFF - flag));
        }
    }

    pub unsafe fn handle(&self){
        d("Intel 8254x handle\n");
    }

    pub unsafe fn init(&self){
        d("Intel 8254x on: ");
        dh(self.base);
        if self.memory_mapped {
            d(" memory mapped");
        }else{
            d(" port mapped");
        }
        dl();

        self.read(CTRL);
        self.read(STATUS);
        self.read(IMS);

        //Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal
        self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true);
        self.flag(CTRL, CTRL_LRST, false);
        self.flag(CTRL, CTRL_PHY_RST, false);
        self.flag(CTRL, CTRL_ILOS, false);

        //No flow control
        self.write(FCAH, 0);
        self.write(FCAL, 0);
        self.write(FCT, 0);
        self.write(FCTTV, 0);

        //Do not use VLANs
        self.flag(CTRL, CTRL_VME, false);

        // TODO: Clear statistical counters

        self.write(RAL0, 0x20202020);
        self.write(RAH0, 0x2020);
        /*
        MTA => 0;
        */
        self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ | IMS_LSC);

        //Receive Buffer
        let receive_ring_length = 4096;
        let receive_ring = alloc(receive_ring_length * 16);
        for i in 0..receive_ring_length {
            let receive_buffer = alloc(4096);
            *((receive_ring + i * 16) as *mut u64) = receive_buffer as u64;
        }

        self.write(RDBAH, 0);
        self.write(RDBAL, receive_ring as u32);
        self.write(RDLEN, (receive_ring_length * 16) as u32);
        self.write(RDH, 0);
        self.write(RDT, (receive_ring_length * 16) as u32);

        self.flag(RCTL, RCTL_EN, true);
        self.flag(RCTL, RCTL_LPE, true);
        self.flag(RCTL, RCTL_LBM, false);
        /* RCTL.RDMTS = Minimum threshold size ??? */
        /* RCTL.MO = Multicast offset */
        self.flag(RCTL, RCTL_BAM, true);
        self.flag(RCTL, RCTL_BSIZE, true);
        self.flag(RCTL, RCTL_BSEX, true);
        self.flag(RCTL, RCTL_SECRC, true);

        self.write(IMS, IMS_RXT | IMS_RX | IMS_RXDMT | IMS_RXSEQ | IMS_LSC);

        /*
        self.flag(TCTL, TCTL_EN, true);
        self.flag(TCTL, TCTL_PSP, true);
        */
        /* TCTL.CT = Collition threshold */
        /* TCTL.COLD = Collision distance */
        /* TIPG Packet Gap */
        /* TODO ... */

        self.read(CTRL);
        self.read(STATUS);
        self.read(IMS);
    }
}

pub struct RTL8139 {
    base: usize,
    memory_mapped: bool,
    receive_buffer: usize
}

impl RTL8139 {
    pub unsafe fn handle(&self){
        d("RTL8139 handle\n");

        let base = self.base as u16;

        let mut capr = (inw(base + 0x38) + 16) as usize;

        d("CAPR: ");
        dh(capr);
        dl();

        d("Packet len: ");
        let packet_len = *((self.receive_buffer + capr + 2) as *const u16) as usize;
        dh(packet_len);
        dl();

        for i in capr..capr + packet_len {
            let data = *((self.receive_buffer + i) as *const u8);
            dbh(data);
            if (i - capr) % 40 == 39 {
                dl();
            }else if (i - capr) % 4 == 3{
                d(" ");
            }
        }
        dl();

        capr = capr + packet_len + 4;
        capr = (capr + 3) & (0xFFFFFFFF - 3);
        if capr >= 8192 {
            capr -= 8192
        }

        outw(base + 0x38, (capr as u16) - 16);
        outw(base + 0x3E, 0x0001);
    }

    pub unsafe fn init(&self){
        d("RTL8139 on: ");
        dh(self.base);
        if self.memory_mapped {
            d(" memory mapped");
        }else{
            d(" port mapped");
        }
        dl();

        let base = self.base as u16;

        outb(base + 0x52, 0x00);

        outb(base + 0x37, 0x10);
        while inb(base + 0x37) & 0x10 != 0 {
        }

        outl(base + 0x30, self.receive_buffer as u32);
        outw(base + 0x38, 0);
        outw(base + 0x3A, 0);

        outw(base + 0x3C, 0x0005);

        outl(base + 0x44, 0xf | (1 << 7));

        outb(base + 0x37, 0x0C);
    }
}

/* } Networking */

const CONFIG_ADDRESS: u16 = 0xCF8;
const CONFIG_DATA: u16 = 0xCFC;

unsafe fn pci_read(bus: usize, slot: usize, function: usize, offset: usize) -> usize{
    outl(CONFIG_ADDRESS, ((1 << 31) | (bus << 16) | (slot << 11) | (function << 8) | (offset & 0xfc)) as u32);
    return inl(CONFIG_DATA) as usize;
}

unsafe fn pci_write(bus: usize, slot: usize, function: usize, offset: usize, data: usize){
    outl(CONFIG_ADDRESS, ((1 << 31) | (bus << 16) | (slot << 11) | (function << 8) | (offset & 0xfc)) as u32);
    outl(CONFIG_DATA, data as u32);
}

pub unsafe fn pci_handle(irq: u8){
    d("PCI Handle ");
    dh(irq as usize);
    dl();

    for device in 0..32 {
        let data = pci_read(0, device, 0, 0);

        if (data & 0xFFFF) != 0xFFFF {
            if irq == pci_read(0, device, 0, 0x3C) as u8 & 0xF {
                if data == 0x100E8086 {
                    let base = pci_read(0, device, 0, 0x10);
                    let device = Intel8254x {
                        base: base & (0xFFFFFFFF - 1),
                        memory_mapped: base & 1 == 0
                    };
                    device.handle();
                } else if data == 0x813910EC {
                    let base = pci_read(0, device, 0, 0x10);
                    let device = RTL8139 {
                        base: base & (0xFFFFFFFF - 1),
                        memory_mapped: base & 1 == 0,
                        receive_buffer: 0x2A0000
                    };
                    device.handle();
                }
            }
        }
    }
}

pub unsafe fn pci_test(){
    d("PCI\n");

    for device in 0..32 {
        let data = pci_read(0, device, 0, 0);

        if (data & 0xFFFF) != 0xFFFF {
            d("Device ");
            dd(device);
            d(": ");
            dh(data);
            d(", ");
            dh(pci_read(0, device, 0, 8));
            dl();

            for i in 0..6 {
                d("    ");
                dd(i);
                d(": ");
                dh(pci_read(0, device, 0, i*4 + 0x10));
                dl();
            }

            if data == 0x100E8086 {
                let base = pci_read(0, device, 0, 0x10);
                let device = Intel8254x {
                    base: base & (0xFFFFFFFF - 1),
                    memory_mapped: base & 1 == 0
                };
                device.init();
            } else if data == 0x813910EC {
                pci_write(0, device, 0, 0x04, pci_read(0, device, 0, 0x04) | (1 << 2));

                d("IRQ ");
                dh(pci_read(0, device, 0, 0x3C) & 0xF + 0x20);
                dl();

                let base = pci_read(0, device, 0, 0x10);
                let device = RTL8139 {
                    base: base & (0xFFFFFFFF - 1),
                    memory_mapped: base & 1 == 0,
                    receive_buffer: 0x2A0000
                };
                device.init();
            }

            dl();
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Update model.rs<commit_after><|endoftext|>


<commit_before><commit_msg>critters are scary<commit_after><|endoftext|>


<commit_before><commit_msg>Add transform between u16/u32 and Opcode<commit_after><|endoftext|>


<commit_before><commit_msg>Use fmt::Display formatting for timer in panic handler<commit_after><|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Generic hashing support.

pub use core_collections::hash::{Hash, Hasher, Writer, hash, sip};

use default::Default;
use rand::Rng;
use rand;

/// `RandomSipHasher` computes the SipHash algorithm from a stream of bytes
/// initialized with random keys.
#[deriving(Clone)]
pub struct RandomSipHasher {
    hasher: sip::SipHasher,
}

impl RandomSipHasher {
    /// Construct a new `RandomSipHasher` that is initialized with random keys.
    #[inline]
    pub fn new() -> RandomSipHasher {
        let mut r = rand::task_rng();
        let r0 = r.gen();
        let r1 = r.gen();
        RandomSipHasher {
            hasher: sip::SipHasher::new_with_keys(r0, r1),
        }
    }
}

impl Hasher<sip::SipState> for RandomSipHasher {
    #[inline]
    fn hash<T: Hash<sip::SipState>>(&self, value: &T) -> u64 {
        self.hasher.hash(value)
    }
}

impl Default for RandomSipHasher {
    #[inline]
    fn default() -> RandomSipHasher {
        RandomSipHasher::new()
    }
}
<commit_msg>std: move the hash docstring over to std::hash.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
 * Generic hashing support.
 *
 * This module provides a generic way to compute the hash of a value. The
 * simplest way to make a type hashable is to use `#[deriving(Hash)]`:
 *
 * # Example
 *
 * ```rust
 * use std::hash;
 * use std::hash::Hash;
 *
 * #[deriving(Hash)]
 * struct Person {
 *     id: uint,
 *     name: String,
 *     phone: u64,
 * }
 *
 * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
 * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
 *
 * assert!(hash::hash(&person1) != hash::hash(&person2));
 * ```
 *
 * If you need more control over how a value is hashed, you need to implement
 * the trait `Hash`:
 *
 * ```rust
 * use std::hash;
 * use std::hash::Hash;
 * use std::hash::sip::SipState;
 *
 * struct Person {
 *     id: uint,
 *     name: String,
 *     phone: u64,
 * }
 *
 * impl Hash for Person {
 *     fn hash(&self, state: &mut SipState) {
 *         self.id.hash(state);
 *         self.phone.hash(state);
 *     }
 * }
 *
 * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
 * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
 *
 * assert!(hash::hash(&person1) == hash::hash(&person2));
 * ```
 */

pub use core_collections::hash::{Hash, Hasher, Writer, hash, sip};

use default::Default;
use rand::Rng;
use rand;

/// `RandomSipHasher` computes the SipHash algorithm from a stream of bytes
/// initialized with random keys.
#[deriving(Clone)]
pub struct RandomSipHasher {
    hasher: sip::SipHasher,
}

impl RandomSipHasher {
    /// Construct a new `RandomSipHasher` that is initialized with random keys.
    #[inline]
    pub fn new() -> RandomSipHasher {
        let mut r = rand::task_rng();
        let r0 = r.gen();
        let r1 = r.gen();
        RandomSipHasher {
            hasher: sip::SipHasher::new_with_keys(r0, r1),
        }
    }
}

impl Hasher<sip::SipState> for RandomSipHasher {
    #[inline]
    fn hash<T: Hash<sip::SipState>>(&self, value: &T) -> u64 {
        self.hasher.hash(value)
    }
}

impl Default for RandomSipHasher {
    #[inline]
    fn default() -> RandomSipHasher {
        RandomSipHasher::new()
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove some dead code<commit_after><|endoftext|>


<commit_before><commit_msg>Fixes for prometheus upgrade.<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #88565 - lqd:issue-83190, r=spastorino<commit_after>// check-pass

// Regression test for issue #83190, triggering an ICE in borrowck.

pub trait Any {}
impl<T> Any for T {}

pub trait StreamOnce {
    type Range;
}

pub trait Parser<Input>: Sized {
    type Output;
    type PartialState;
    fn map(self) -> Map<Self> {
        todo!()
    }
}

pub struct Map<P>(P);
impl<I, P: Parser<I, Output = ()>> Parser<I> for Map<P> {
    type Output = ();
    type PartialState = P::PartialState;
}

struct TakeWhile1<Input>(Input);
impl<I: StreamOnce> Parser<I> for TakeWhile1<I> {
    type Output = I::Range;
    type PartialState = ();
}
impl<I> TakeWhile1<I> {
    fn new() -> Self {
        todo!()
    }
}

impl<I, A: Parser<I>> Parser<I> for (A,) {
    type Output = ();
    type PartialState = Map<A::Output>;
}

pub fn metric_stream_parser<'a, I>() -> impl Parser<I, Output = (), PartialState = impl Any + 'a>
where
    I: StreamOnce<Range = &'a [()]>,
{
    (TakeWhile1::new(),).map()
}

fn main() {}
<|endoftext|>