<commit_before>use core::mem::size_of;

use common::debug::*;
use common::memory::*;
use common::pio::*;

//Status port bits
const ATA_SR_BSY: u8 = 0x80;
const ATA_SR_DRDY: u8 = 0x40;
const ATA_SR_DF: u8 = 0x20;
const ATA_SR_DSC: u8 = 0x10;
const ATA_SR_DRQ: u8 = 0x08;
const ATA_SR_CORR: u8 = 0x04;
const ATA_SR_IDX: u8 = 0x02;
const ATA_SR_ERR: u8 = 0x01;

//Error port bits
const ATA_ER_BBK: u8 = 0x80;
const ATA_ER_UNC: u8 = 0x40;
const ATA_ER_MC: u8 = 0x20;
const ATA_ER_IDNF: u8 = 0x10;
const ATA_ER_MCR: u8 = 0x08;
const ATA_ER_ABRT: u8 = 0x04;
const ATA_ER_TK0NF: u8 = 0x02;
const ATA_ER_AMNF: u8 = 0x01;

//Commands
const ATA_CMD_READ_PIO: u8 = 0x20;
const ATA_CMD_READ_PIO_EXT: u8 = 0x24;
const ATA_CMD_READ_DMA: u8 = 0xC8;
const ATA_CMD_READ_DMA_EXT: u8 = 0x25;
const ATA_CMD_WRITE_PIO: u8 = 0x30;
const ATA_CMD_WRITE_PIO_EXT: u8 = 0x34;
const ATA_CMD_WRITE_DMA: u8 = 0xCA;
const ATA_CMD_WRITE_DMA_EXT: u8 = 0x35;
const ATA_CMD_CACHE_FLUSH: u8 = 0xE7;
const ATA_CMD_CACHE_FLUSH_EXT: u8 = 0xEA;
const ATA_CMD_PACKET: u8 = 0xA0;
const ATA_CMD_IDENTIFY_PACKET: u8 = 0xA1;
const ATA_CMD_IDENTIFY: u8 = 0xEC;

//Identification
const ATA_IDENT_DEVICETYPE: u8 = 0;
const ATA_IDENT_CYLINDERS: u8 = 2;
const ATA_IDENT_HEADS: u8 = 6;
const ATA_IDENT_SECTORS: u8 = 12;
const ATA_IDENT_SERIAL: u8 = 20;
const ATA_IDENT_MODEL: u8 = 54;
const ATA_IDENT_CAPABILITIES: u8 = 98;
const ATA_IDENT_FIELDVALID: u8 = 106;
const ATA_IDENT_MAX_LBA: u8 = 120;
const ATA_IDENT_COMMANDSETS: u8 = 164;
const ATA_IDENT_MAX_LBA_EXT: u8 = 200;

//Selection
const ATA_MASTER: u8 = 0x00;
const ATA_SLAVE: u8 = 0x01;

//Types
const IDE_ATA: u8 = 0x00;
const IDE_ATAPI: u8 = 0x01;

//Registers
const ATA_REG_DATA: u16 = 0x00;
const ATA_REG_ERROR: u16 = 0x01;
const ATA_REG_FEATURES: u16 = 0x01;
const ATA_REG_SECCOUNT0: u16 = 0x02;
const ATA_REG_LBA0: u16 = 0x03;
const ATA_REG_LBA1: u16 = 0x04;
const ATA_REG_LBA2: u16 = 0x05;
const ATA_REG_HDDEVSEL: u16 = 0x06;
const ATA_REG_COMMAND: u16 = 0x07;
const ATA_REG_STATUS: u16 = 0x07;
const ATA_REG_SECCOUNT1: u16 = 0x08;
const ATA_REG_LBA3: u16 = 0x09;
const ATA_REG_LBA4: u16 = 0x0A;
const ATA_REG_LBA5: u16 = 0x0B;
const ATA_REG_CONTROL: u16 = 0x0C;
const ATA_REG_ALTSTATUS: u16 = 0x0C;
const ATA_REG_DEVADDRESS: u16 = 0x0D;

pub struct PRDTE {
    pub ptr: u32,
    pub size: u16,
    pub reserved: u16
}

pub struct Disk{
    base: u16,
    ctrl: u16
}

impl Disk {
    pub fn new() -> Disk{
        Disk{
            base: 0x1F0,
            ctrl: 0x3F4
        }
    }

    unsafe fn ide_read(&self, reg: u16) -> u8{
        let ret;
        if reg < 0x08 {
            ret = inb(self.base + reg - 0x00);
        } else if reg < 0x0C {
            ret = inb(self.base + reg - 0x06);
        } else if reg < 0x0E {
            ret = inb(self.ctrl + reg - 0x0A);
        }else{
            ret = 0;
        }
        ret
    }

    unsafe fn ide_write(&self, reg: u16, data: u8){
        if reg < 0x08 {
            outb(self.base + reg - 0x00, data);
        } else if reg < 0x0C {
            outb(self.base + reg - 0x06, data);
        } else if reg < 0x0E {
            outb(self.ctrl + reg - 0x0A, data);
        }
    }

    unsafe fn ide_poll(&self, check_error: bool) -> u8{
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);

        while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

        }

        if check_error {
            let state = self.ide_read(ATA_REG_STATUS);
            if state & ATA_SR_ERR == ATA_SR_ERR {
                return 2;
            }
            if state & ATA_SR_DF == ATA_SR_DF {
                return 1;
            }
            if !(state & ATA_SR_DRQ == ATA_SR_DRQ) {
                return 3;
            }
        }

        return 0;
    }

    //TODO: Make sure count is not zero!
    pub unsafe fn read(&self, lba: u64, count: u16, destination: usize) -> u8{
        if destination > 0 {
            while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

            }

            self.ide_write(ATA_REG_HDDEVSEL, 0x40);

            self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

            self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA0, (lba & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);
            self.ide_write(ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);

            for sector in 0..count as usize {
                let err = self.ide_poll(true);
                if err > 0{
                    return err;
                }

                for word in 0..256 {
                    let data = inw(self.base + ATA_REG_DATA);
                    *((destination + sector*512 + word*2) as *mut u16) = data;
                }
            }
        }

        return 0;
    }

    pub unsafe fn read_dma(&self, lba: u64, count: u16, destination: usize, busmaster: u16) -> u8{
        if destination > 0 {
            //Allocate PDTR
            let mut prdt = ind(busmaster + 4) as usize;

            if prdt == 0 {
                let size = count as usize * 512;
                let entries = (size + 65535)/65536;
                prdt = alloc(size_of::<PRDTE>() * entries);
                for i in 0..entries {
                    if i == entries - 1 {
                        *(prdt as *mut PRDTE).offset(i as isize) = PRDTE {
                            ptr: (destination + i * 65536) as u32,
                            size: (size % 65536) as u16,
                            reserved: 0x8000
                        };
                    }else{
                        *(prdt as *mut PRDTE).offset(i as isize) = PRDTE {
                            ptr: (destination + i * 65536) as u32,
                            size: 0,
                            reserved: 0
                        };
                    }
                }

                outd(busmaster + 4, prdt as u32);

                //Set read bit
                outb(busmaster, 8);

                //Clear interrupt, error bit
                outb(busmaster + 2, 0);

                //DMA Transfer Command
                while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

                }

                self.ide_write(ATA_REG_HDDEVSEL, 0x40);

                self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

                self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA0, (lba & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);
                self.ide_write(ATA_REG_COMMAND, ATA_CMD_READ_DMA_EXT);

                //Engage bus mastering
                outb(busmaster, inb(busmaster) | 1);
            }else{
                d("Operation Running!\n");
            }
        }

        return 0;
    }

    //TODO: Fix and make sure count is not zero!
    pub unsafe fn write(&self, lba: u64, count: u16, source: usize) -> u8{
        if source > 0 {
            while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

            }

            self.ide_write(ATA_REG_HDDEVSEL, 0x40);

            self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

            self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA0, ((lba >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);

            self.ide_write(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);

            for sector in 0..count as usize {
                let err = self.ide_poll(true);
                if err > 0{
                    return err;
                }

                for word in 0..256 {
                    outw(self.base + ATA_REG_DATA, *((source + sector*512 + word*2) as *const u16));
                }

                self.ide_write(ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
                self.ide_poll(false);
            }
        }

        return 0;
    }
}
<commit_msg>Allow slave/master selection<commit_after>use core::mem::size_of;

use common::debug::*;
use common::memory::*;
use common::pio::*;

//Status port bits
const ATA_SR_BSY: u8 = 0x80;
const ATA_SR_DRDY: u8 = 0x40;
const ATA_SR_DF: u8 = 0x20;
const ATA_SR_DSC: u8 = 0x10;
const ATA_SR_DRQ: u8 = 0x08;
const ATA_SR_CORR: u8 = 0x04;
const ATA_SR_IDX: u8 = 0x02;
const ATA_SR_ERR: u8 = 0x01;

//Error port bits
const ATA_ER_BBK: u8 = 0x80;
const ATA_ER_UNC: u8 = 0x40;
const ATA_ER_MC: u8 = 0x20;
const ATA_ER_IDNF: u8 = 0x10;
const ATA_ER_MCR: u8 = 0x08;
const ATA_ER_ABRT: u8 = 0x04;
const ATA_ER_TK0NF: u8 = 0x02;
const ATA_ER_AMNF: u8 = 0x01;

//Commands
const ATA_CMD_READ_PIO: u8 = 0x20;
const ATA_CMD_READ_PIO_EXT: u8 = 0x24;
const ATA_CMD_READ_DMA: u8 = 0xC8;
const ATA_CMD_READ_DMA_EXT: u8 = 0x25;
const ATA_CMD_WRITE_PIO: u8 = 0x30;
const ATA_CMD_WRITE_PIO_EXT: u8 = 0x34;
const ATA_CMD_WRITE_DMA: u8 = 0xCA;
const ATA_CMD_WRITE_DMA_EXT: u8 = 0x35;
const ATA_CMD_CACHE_FLUSH: u8 = 0xE7;
const ATA_CMD_CACHE_FLUSH_EXT: u8 = 0xEA;
const ATA_CMD_PACKET: u8 = 0xA0;
const ATA_CMD_IDENTIFY_PACKET: u8 = 0xA1;
const ATA_CMD_IDENTIFY: u8 = 0xEC;

//Identification
const ATA_IDENT_DEVICETYPE: u8 = 0;
const ATA_IDENT_CYLINDERS: u8 = 2;
const ATA_IDENT_HEADS: u8 = 6;
const ATA_IDENT_SECTORS: u8 = 12;
const ATA_IDENT_SERIAL: u8 = 20;
const ATA_IDENT_MODEL: u8 = 54;
const ATA_IDENT_CAPABILITIES: u8 = 98;
const ATA_IDENT_FIELDVALID: u8 = 106;
const ATA_IDENT_MAX_LBA: u8 = 120;
const ATA_IDENT_COMMANDSETS: u8 = 164;
const ATA_IDENT_MAX_LBA_EXT: u8 = 200;

//Selection
const ATA_MASTER: u8 = 0x00;
const ATA_SLAVE: u8 = 0x01;

//Types
const IDE_ATA: u8 = 0x00;
const IDE_ATAPI: u8 = 0x01;

//Registers
const ATA_REG_DATA: u16 = 0x00;
const ATA_REG_ERROR: u16 = 0x01;
const ATA_REG_FEATURES: u16 = 0x01;
const ATA_REG_SECCOUNT0: u16 = 0x02;
const ATA_REG_LBA0: u16 = 0x03;
const ATA_REG_LBA1: u16 = 0x04;
const ATA_REG_LBA2: u16 = 0x05;
const ATA_REG_HDDEVSEL: u16 = 0x06;
const ATA_REG_COMMAND: u16 = 0x07;
const ATA_REG_STATUS: u16 = 0x07;
const ATA_REG_SECCOUNT1: u16 = 0x08;
const ATA_REG_LBA3: u16 = 0x09;
const ATA_REG_LBA4: u16 = 0x0A;
const ATA_REG_LBA5: u16 = 0x0B;
const ATA_REG_CONTROL: u16 = 0x0C;
const ATA_REG_ALTSTATUS: u16 = 0x0C;
const ATA_REG_DEVADDRESS: u16 = 0x0D;

pub struct PRDTE {
    pub ptr: u32,
    pub size: u16,
    pub reserved: u16
}

pub struct Disk{
    base: u16,
    ctrl: u16,
    master: bool
}

impl Disk {
    pub fn new() -> Disk{
        Disk{
            base: 0x1F0,
            ctrl: 0x3F4,
            master: true
        }
    }

    unsafe fn ide_read(&self, reg: u16) -> u8{
        let ret;
        if reg < 0x08 {
            ret = inb(self.base + reg - 0x00);
        } else if reg < 0x0C {
            ret = inb(self.base + reg - 0x06);
        } else if reg < 0x0E {
            ret = inb(self.ctrl + reg - 0x0A);
        }else{
            ret = 0;
        }
        ret
    }

    unsafe fn ide_write(&self, reg: u16, data: u8){
        if reg < 0x08 {
            outb(self.base + reg - 0x00, data);
        } else if reg < 0x0C {
            outb(self.base + reg - 0x06, data);
        } else if reg < 0x0E {
            outb(self.ctrl + reg - 0x0A, data);
        }
    }

    unsafe fn ide_poll(&self, check_error: bool) -> u8{
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);
        self.ide_read(ATA_REG_ALTSTATUS);

        while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

        }

        if check_error {
            let state = self.ide_read(ATA_REG_STATUS);
            if state & ATA_SR_ERR == ATA_SR_ERR {
                return 2;
            }
            if state & ATA_SR_DF == ATA_SR_DF {
                return 1;
            }
            if !(state & ATA_SR_DRQ == ATA_SR_DRQ) {
                return 3;
            }
        }

        return 0;
    }

    //TODO: Make sure count is not zero!
    pub unsafe fn read(&self, lba: u64, count: u16, destination: usize) -> u8{
        if destination > 0 {
            while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

            }

            if self.master {
                self.ide_write(ATA_REG_HDDEVSEL, 0x40);
            }else{
                self.ide_write(ATA_REG_HDDEVSEL, 0x50);
            }

            self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

            self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA0, (lba & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);
            self.ide_write(ATA_REG_COMMAND, ATA_CMD_READ_PIO_EXT);

            for sector in 0..count as usize {
                let err = self.ide_poll(true);
                if err > 0{
                    return err;
                }

                for word in 0..256 {
                    let data = inw(self.base + ATA_REG_DATA);
                    *((destination + sector*512 + word*2) as *mut u16) = data;
                }
            }
        }

        return 0;
    }

    pub unsafe fn read_dma(&self, lba: u64, count: u16, destination: usize, busmaster: u16) -> u8{
        if destination > 0 {
            //Allocate PDTR
            let mut prdt = ind(busmaster + 4) as usize;

            if prdt == 0 {
                let size = count as usize * 512;
                let entries = (size + 65535)/65536;
                prdt = alloc(size_of::<PRDTE>() * entries);
                for i in 0..entries {
                    if i == entries - 1 {
                        *(prdt as *mut PRDTE).offset(i as isize) = PRDTE {
                            ptr: (destination + i * 65536) as u32,
                            size: (size % 65536) as u16,
                            reserved: 0x8000
                        };
                    }else{
                        *(prdt as *mut PRDTE).offset(i as isize) = PRDTE {
                            ptr: (destination + i * 65536) as u32,
                            size: 0,
                            reserved: 0
                        };
                    }
                }

                outd(busmaster + 4, prdt as u32);

                //Set read bit
                outb(busmaster, 8);

                //Clear interrupt, error bit
                outb(busmaster + 2, 0);

                //DMA Transfer Command
                while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

                }

                if self.master {
                    self.ide_write(ATA_REG_HDDEVSEL, 0x40);
                }else{
                    self.ide_write(ATA_REG_HDDEVSEL, 0x50);
                }

                self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

                self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA0, (lba & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
                self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);
                self.ide_write(ATA_REG_COMMAND, ATA_CMD_READ_DMA_EXT);

                //Engage bus mastering
                outb(busmaster, inb(busmaster) | 1);
            }else{
                d("Operation Running!\n");
            }
        }

        return 0;
    }

    //TODO: Fix and make sure count is not zero!
    pub unsafe fn write(&self, lba: u64, count: u16, source: usize) -> u8{
        if source > 0 {
            while self.ide_read(ATA_REG_STATUS) & ATA_SR_BSY == ATA_SR_BSY {

            }

            if self.master {
                self.ide_write(ATA_REG_HDDEVSEL, 0x40);
            }else{
                self.ide_write(ATA_REG_HDDEVSEL, 0x50);
            }

            self.ide_write(ATA_REG_SECCOUNT1, ((count >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA3, ((lba >> 24) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA4, ((lba >> 32) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA5, ((lba >> 40) & 0xFF) as u8);

            self.ide_write(ATA_REG_SECCOUNT0, ((count >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA0, ((lba >> 0) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA1, ((lba >> 8) & 0xFF) as u8);
            self.ide_write(ATA_REG_LBA2, ((lba >> 16) & 0xFF) as u8);

            self.ide_write(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO_EXT);

            for sector in 0..count as usize {
                let err = self.ide_poll(true);
                if err > 0{
                    return err;
                }

                for word in 0..256 {
                    outw(self.base + ATA_REG_DATA, *((source + sector*512 + word*2) as *const u16));
                }

                self.ide_write(ATA_REG_COMMAND, ATA_CMD_CACHE_FLUSH_EXT);
                self.ide_poll(false);
            }
        }

        return 0;
    }
}
<|endoftext|>


<commit_before><commit_msg>Formatting<commit_after><|endoftext|>


<commit_before>use std::collections::VecDeque;
use diff;
use term;

#[derive(Debug, PartialEq)]
pub enum DiffLine {
    Context(String),
    Expected(String),
    Resulting(String),
}

#[derive(Debug, PartialEq)]
pub struct Mismatch {
    pub line_number: u32,
    pub lines: Vec<DiffLine>,
}

impl Mismatch {
    fn new(line_number: u32) -> Mismatch {
        Mismatch {
            line_number: line_number,
            lines: Vec::new(),
        }
    }
}

// Produces a diff between the expected output and actual output of rustfmt.
pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
    let mut line_number = 1;
    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
    let mut lines_since_mismatch = context_size + 1;
    let mut results = Vec::new();
    let mut mismatch = Mismatch::new(0);

    for result in diff::lines(expected, actual) {
        match result {
            diff::Result::Left(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
                lines_since_mismatch = 0;
            }
            diff::Result::Right(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
                line_number += 1;
                lines_since_mismatch = 0;
            }
            diff::Result::Both(str, _) => {
                if context_queue.len() >= context_size {
                    let _ = context_queue.pop_front();
                }

                if lines_since_mismatch < context_size {
                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
                } else {
                    context_queue.push_back(str);
                }

                line_number += 1;
                lines_since_mismatch += 1;
            }
        }
    }

    results.push(mismatch);
    results.remove(0);

    results
}

pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    let mut t = term::stdout().unwrap();

    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        writeln!(t, "{}", title).unwrap();

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    t.reset().unwrap();
                    writeln!(t, " {}⏎", str).unwrap();
                }
                DiffLine::Expected(ref str) => {
                    t.fg(term::color::GREEN).unwrap();
                    writeln!(t, "+{}⏎", str).unwrap();
                }
                DiffLine::Resulting(ref str) => {
                    t.fg(term::color::RED).unwrap();
                    writeln!(t, "-{}⏎", str).unwrap();
                }
            }
        }
        t.reset().unwrap();
    }
}
<commit_msg>Fall back to basic stdout if we can't unwrap a fancy terminal (#995)<commit_after>use std::collections::VecDeque;
use diff;
use term;
use std::io;

#[derive(Debug, PartialEq)]
pub enum DiffLine {
    Context(String),
    Expected(String),
    Resulting(String),
}

#[derive(Debug, PartialEq)]
pub struct Mismatch {
    pub line_number: u32,
    pub lines: Vec<DiffLine>,
}

impl Mismatch {
    fn new(line_number: u32) -> Mismatch {
        Mismatch {
            line_number: line_number,
            lines: Vec::new(),
        }
    }
}

// Produces a diff between the expected output and actual output of rustfmt.
pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Mismatch> {
    let mut line_number = 1;
    let mut context_queue: VecDeque<&str> = VecDeque::with_capacity(context_size);
    let mut lines_since_mismatch = context_size + 1;
    let mut results = Vec::new();
    let mut mismatch = Mismatch::new(0);

    for result in diff::lines(expected, actual) {
        match result {
            diff::Result::Left(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
                lines_since_mismatch = 0;
            }
            diff::Result::Right(str) => {
                if lines_since_mismatch >= context_size {
                    results.push(mismatch);
                    mismatch = Mismatch::new(line_number - context_queue.len() as u32);
                }

                while let Some(line) = context_queue.pop_front() {
                    mismatch.lines.push(DiffLine::Context(line.to_owned()));
                }

                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
                line_number += 1;
                lines_since_mismatch = 0;
            }
            diff::Result::Both(str, _) => {
                if context_queue.len() >= context_size {
                    let _ = context_queue.pop_front();
                }

                if lines_since_mismatch < context_size {
                    mismatch.lines.push(DiffLine::Context(str.to_owned()));
                } else {
                    context_queue.push_back(str);
                }

                line_number += 1;
                lines_since_mismatch += 1;
            }
        }
    }

    results.push(mismatch);
    results.remove(0);

    results
}

pub fn print_diff<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    if let Some(t) = term::stdout() {
        print_diff_fancy(diff, get_section_title, t);
    } else {
        print_diff_basic(diff, get_section_title);
    }
}

fn print_diff_fancy<F>(diff: Vec<Mismatch>,
                       get_section_title: F,
                       mut t: Box<term::Terminal<Output = io::Stdout>>)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        writeln!(t, "{}", title).unwrap();

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    t.reset().unwrap();
                    writeln!(t, " {}⏎", str).unwrap();
                }
                DiffLine::Expected(ref str) => {
                    t.fg(term::color::GREEN).unwrap();
                    writeln!(t, "+{}⏎", str).unwrap();
                }
                DiffLine::Resulting(ref str) => {
                    t.fg(term::color::RED).unwrap();
                    writeln!(t, "-{}⏎", str).unwrap();
                }
            }
        }
        t.reset().unwrap();
    }
}

pub fn print_diff_basic<F>(diff: Vec<Mismatch>, get_section_title: F)
    where F: Fn(u32) -> String
{
    for mismatch in diff {
        let title = get_section_title(mismatch.line_number);
        println!("{}", title);

        for line in mismatch.lines {
            match line {
                DiffLine::Context(ref str) => {
                    println!(" {}⏎", str);
                }
                DiffLine::Expected(ref str) => {
                    println!("+{}⏎", str);
                }
                DiffLine::Resulting(ref str) => {
                    println!("-{}⏎", str);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent{
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct Node {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            name: self.name,
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem{
        unsafe{
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_ptr: *const Node = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_ptr as usize);
                        nodes.push(ptr::read(node_ptr));
                    }
                }
            }
            unalloc(node_ptr as usize);

            return FileSystem {
                disk:disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node>{
        for node in self.nodes.iter() {
            if String::from_c_slice(&node.name) == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            let node_name = String::from_c_slice(&node.name);
            if node_name.starts_with(directory.clone()) {
                ret.push(node_name.substr(directory.len(), node_name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&String::from_c_slice(&self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    fn flush(&mut self) -> bool {
        return false;
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource>{
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        }else{
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    }else{
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        }else{
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        node: node,
                        vec: vec,
                        seek: 0
                    };
                },
                Option::None => {
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                }
            }
        }
    }
}
<commit_msg>Remove insert function, for now<commit_after>use common::memory::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

#[derive(Copy, Clone)]
#[repr(packed)]
pub struct Extent{
    pub block: u64,
    pub length: u64
}

#[repr(packed)]
pub struct Header {
    pub signature: [u8; 8],
    pub version: u32,
    pub name: [u8; 244],
    pub extents: [Extent; 16]
}

#[repr(packed)]
pub struct Node {
    pub name: [u8; 256],
    pub extents: [Extent; 16]
}

impl Clone for Node {
    fn clone(&self) -> Node {
        return Node {
            name: self.name,
            extents: self.extents
        };
    }
}

pub struct FileSystem {
    pub disk: Disk,
    pub header: Header,
    pub nodes: Vec<Node>
}

impl FileSystem {
    pub fn from_disk(disk: Disk) -> FileSystem{
        unsafe{
            let header_ptr: *const Header = alloc_type();
            disk.read(1, 1, header_ptr as usize);
            let header = ptr::read(header_ptr);
            unalloc(header_ptr as usize);

            let mut nodes = Vec::new();
            let node_ptr: *const Node = alloc_type();
            for extent in &header.extents {
                if extent.block > 0 {
                    for node_address in extent.block..extent.block + (extent.length + 511)/512 {
                        disk.read(node_address, 1, node_ptr as usize);
                        nodes.push(ptr::read(node_ptr));
                    }
                }
            }
            unalloc(node_ptr as usize);

            return FileSystem {
                disk:disk,
                header: header,
                nodes: nodes
            };
        }
    }

    pub fn valid(&self) -> bool {
        return self.header.signature[0] == 'R' as u8
            && self.header.signature[1] == 'E' as u8
            && self.header.signature[2] == 'D' as u8
            && self.header.signature[3] == 'O' as u8
            && self.header.signature[4] == 'X' as u8
            && self.header.signature[5] == 'F' as u8
            && self.header.signature[6] == 'S' as u8
            && self.header.signature[7] == '\0' as u8
            && self.header.version == 0xFFFFFFFF;
    }

    pub fn node(&self, filename: &String) -> Option<Node>{
        for node in self.nodes.iter() {
            if String::from_c_slice(&node.name) == *filename {
                return Option::Some(node.clone());
            }
        }

        return Option::None;
    }

    pub fn list(&self, directory: &String) -> Vec<String> {
        let mut ret = Vec::<String>::new();

        for node in self.nodes.iter() {
            let node_name = String::from_c_slice(&node.name);
            if node_name.starts_with(directory.clone()) {
                ret.push(node_name.substr(directory.len(), node_name.len() - directory.len()));
            }
        }

        return ret;
    }
}

pub struct FileResource {
    pub node: Node,
    pub vec: Vec<u8>,
    pub seek: usize
}

impl Resource for FileResource {
    fn url(&self) -> URL {
        return URL::from_string(&String::from_c_slice(&self.node.name));
    }

    fn stat(&self) -> ResourceType {
        return ResourceType::File;
    }

    fn read(&mut self, buf: &mut [u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            match self.vec.get(self.seek) {
                Option::Some(b) => buf[i] = *b,
                Option::None => ()
            }
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn write(&mut self, buf: &[u8]) -> Option<usize> {
        let mut i = 0;
        while i < buf.len() && self.seek < self.vec.len() {
            self.vec.set(self.seek, buf[i]);
            self.seek += 1;
            i += 1;
        }
        while i < buf.len() {
            self.vec.push(buf[i]);
            self.seek += 1;
            i += 1;
        }
        return Option::Some(i);
    }

    fn seek(&mut self, pos: ResourceSeek) -> Option<usize> {
        match pos {
            ResourceSeek::Start(offset) => self.seek = offset,
            ResourceSeek::Current(offset) => self.seek = max(0, self.seek as isize + offset) as usize,
            ResourceSeek::End(offset) => self.seek = max(0, self.vec.len() as isize + offset) as usize
        }
        while self.vec.len() < self.seek {
            self.vec.push(0);
        }
        return Option::Some(self.seek);
    }

    fn flush(&mut self) -> bool {
        return false;
    }
}

pub struct FileScheme {
    pub fs: FileSystem
}

impl SessionItem for FileScheme {
    fn scheme(&self) -> String {
        return "file".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource>{
        let path = url.path();
        if path.len() == 0 || path.ends_with("/".to_string()) {
            let mut list = String::new();
            let mut dirs: Vec<String> = Vec::new();

            for file in self.fs.list(&path).iter() {
                let line;
                match file.find("/".to_string()) {
                    Option::Some(index) => {
                        let dirname = file.substr(0, index + 1);
                        let mut found = false;
                        for dir in dirs.iter() {
                            if dirname == *dir {
                                found = true;
                                break;
                            }
                        }
                        if found {
                            line = String::new();
                        }else{
                            line = dirname.clone();
                            dirs.push(dirname);
                        }
                    },
                    Option::None => line = file.clone()
                }
                if line.len() > 0 {
                    if list.len() > 0 {
                        list = list + '\n' + line;
                    }else{
                        list = line;
                    }
                }
            }

            return box VecResource::new(url.clone(), ResourceType::Dir, list.to_utf8());
        }else{
            match self.fs.node(&path) {
                Option::Some(node) => {
                    let mut vec: Vec<u8> = Vec::new();
                    if node.extents[0].block > 0 && node.extents[0].length > 0 {
                        unsafe {
                            let data = alloc(node.extents[0].length as usize);
                            if data > 0 {
                                let reenable = start_no_ints();

                                self.fs.disk.read(node.extents[0].block, ((node.extents[0].length + 511)/512) as u16, data);

                                end_no_ints(reenable);

                                vec = Vec {
                                    data: data as *mut u8,
                                    length: node.extents[0].length as usize
                                };
                            }
                        }
                    }

                    return box FileResource {
                        node: node,
                        vec: vec,
                        seek: 0
                    };
                },
                Option::None => {
                    /*
                    d("Creating ");
                    path.d();
                    dl();

                    let mut name = [0; 256];
                    for i in 0..256 {
                        //TODO: UTF8
                        let b = path[i] as u8;
                        name[i] = b;
                        if b == 0 {
                            break;
                        }
                    }

                    let node = Node {
                        name: name,
                        extents: [Extent { block: 0, length: 0 }; 16]
                    };

                    //TODO: Sync to disk
                    let mut node_i = 0;
                    while node_i < self.fs.nodes.len() {
                        let mut cmp = 0;

                        if let Option::Some(other_node) = self.fs.nodes.get(node_i) {
                            for i in 0..256 {
                                if other_node.name[i] != node.name[i] {
                                    cmp = other_node.name[i] as isize - node.name[i] as isize;
                                    break;
                                }
                            }
                        }

                        if cmp >= 0 {
                            break;
                        }

                        node_i += 1;
                    }
                    d("Insert at ");
                    dd(node_i);
                    dl();
                    self.fs.nodes.insert(node_i, node.clone());

                    return box FileResource {
                        node: node,
                        vec: Vec::new(),
                        seek: 0
                    };
                    */
                    return box NoneResource;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::prelude::v1::*;
use std::sync::Arc;
use std::cell::UnsafeCell;

// One critical piece of this module's contents are the `TaskRc<A>` handles.
// The purpose of this is to conceptually be able to store data in a task,
// allowing it to be accessed within multiple futures at once. For example if
// you have some concurrent futures working, they may all want mutable access to
// some data. We already know that when the futures are being poll'ed that we're
// entirely synchronized (aka `&mut Task`), so you shouldn't require an
// `Arc<Mutex<T>>` to share as the synchronization isn't necessary!
//
// So the idea here is that you insert data into a task via `Task::insert`, and
// a handle to that data is then returned to you. That handle can later get
// presented to the task itself to actually retrieve the underlying data. The
// invariant is that the data can only ever be accessed with the task present,
// and the lifetime of the actual data returned is connected to the lifetime of
// the task itself.
//
// Conceptually I at least like to think of this as "dynamically adding more
// struct fields to a `Task`". Each call to insert creates a new "name" for the
// struct field, a `TaskRc<A>`, and then you can access the fields of a struct
// with the struct itself (`Task`) as well as the name of the field
// (`TaskRc<A>`). If that analogy doesn't make sense then oh well, it at least
// helped me!
//
// So anyway, we do some interesting trickery here to actually get it to work.
// Each `TaskRc<A>` handle stores `Arc<UnsafeCell<A>>`. So it turns out, we're
// not even adding data to the `Task`! Each `TaskRc<A>` contains a reference
// to this `Arc`, and `TaskRc` handles can be cloned which just bumps the
// reference count on the `Arc` itself.
//
// As before, though, you can present the `Arc` to a `Task` and if they
// originated from the same place you're allowed safe access to the internals.
// We allow but shared and mutable access without the `Sync` bound on the data,
// crucially noting that a `Task` itself is not `Sync`.
//
// So hopefully I've convinced you of this point that the `get` and `get_mut`
// methods below are indeed safe. The data is always valid as it's stored in an
// `Arc`, and access is only allowed with the proof of the associated `Task`.
// One thing you might be asking yourself though is what exactly is this "proof
// of a task"? Right now it's a `usize` corresponding to the `Task`'s
// `TaskHandle` arc allocation.
//
// Wait a minute, isn't that the ABA problem! That is, we create a task A, add
// some data to it, destroy task A, do some work, create a task B, and then ask
// to get the data from task B. In this case though the point of the
// `task_inner` "proof" field is simply that there's some non-`Sync` token
// proving that you can get access to the data. So while weird, this case should
// still be safe, as the data's not stored in the task itself.

/// A reference to a piece of data that's accessible only within a specific
/// `Task`.
///
/// This data is `Send` even when `A` is not `Sync`, because the data stored
/// within is accessed in a single-threaded way. The thread accessing it may
/// change over time, if the task migrates, so `A` must be `Send`.
pub struct TaskRc<A> {
    task_id: usize,
    ptr: Arc<UnsafeCell<A>>,
}

// for safety here, see docs at the top of this module
unsafe impl<A: Send> Send for TaskRc<A> {}
unsafe impl<A: Sync> Sync for TaskRc<A> {}

impl<A> TaskRc<A> {
    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `with` method to get a reference back to the original
    /// data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    ///
    /// # Panics
    ///
    /// This function will panic if a task is not currently running.
    pub fn new(a: A) -> TaskRc<A> {
        super::with(|task, _| {
            TaskRc {
                task_id: task.id,
                ptr: Arc::new(UnsafeCell::new(a)),
            }
        })
    }

    /// Operate with a reference to the underlying data.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if a task is not currently running or if `self`
    /// does not belong to the task that is currently running. That is, if
    /// another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn with<F, R>(&self, f: F) -> R
        where F: FnOnce(&A) -> R
    {
        // for safety here, see docs at the top of this module
        super::with(|task, _| {
            assert_eq!(self.task_id, task.id);
            f(unsafe { &*self.ptr.get() })
        })
    }
}

impl<A> Clone for TaskRc<A> {
    fn clone(&self) -> TaskRc<A> {
        TaskRc {
            task_id: self.task_id,
            ptr: self.ptr.clone(),
        }
    }
}
<commit_msg>Add message to assert in TaskRc<commit_after>use std::prelude::v1::*;
use std::sync::Arc;
use std::cell::UnsafeCell;

// One critical piece of this module's contents are the `TaskRc<A>` handles.
// The purpose of this is to conceptually be able to store data in a task,
// allowing it to be accessed within multiple futures at once. For example if
// you have some concurrent futures working, they may all want mutable access to
// some data. We already know that when the futures are being poll'ed that we're
// entirely synchronized (aka `&mut Task`), so you shouldn't require an
// `Arc<Mutex<T>>` to share as the synchronization isn't necessary!
//
// So the idea here is that you insert data into a task via `Task::insert`, and
// a handle to that data is then returned to you. That handle can later get
// presented to the task itself to actually retrieve the underlying data. The
// invariant is that the data can only ever be accessed with the task present,
// and the lifetime of the actual data returned is connected to the lifetime of
// the task itself.
//
// Conceptually I at least like to think of this as "dynamically adding more
// struct fields to a `Task`". Each call to insert creates a new "name" for the
// struct field, a `TaskRc<A>`, and then you can access the fields of a struct
// with the struct itself (`Task`) as well as the name of the field
// (`TaskRc<A>`). If that analogy doesn't make sense then oh well, it at least
// helped me!
//
// So anyway, we do some interesting trickery here to actually get it to work.
// Each `TaskRc<A>` handle stores `Arc<UnsafeCell<A>>`. So it turns out, we're
// not even adding data to the `Task`! Each `TaskRc<A>` contains a reference
// to this `Arc`, and `TaskRc` handles can be cloned which just bumps the
// reference count on the `Arc` itself.
//
// As before, though, you can present the `Arc` to a `Task` and if they
// originated from the same place you're allowed safe access to the internals.
// We allow but shared and mutable access without the `Sync` bound on the data,
// crucially noting that a `Task` itself is not `Sync`.
//
// So hopefully I've convinced you of this point that the `get` and `get_mut`
// methods below are indeed safe. The data is always valid as it's stored in an
// `Arc`, and access is only allowed with the proof of the associated `Task`.
// One thing you might be asking yourself though is what exactly is this "proof
// of a task"? Right now it's a `usize` corresponding to the `Task`'s
// `TaskHandle` arc allocation.
//
// Wait a minute, isn't that the ABA problem! That is, we create a task A, add
// some data to it, destroy task A, do some work, create a task B, and then ask
// to get the data from task B. In this case though the point of the
// `task_inner` "proof" field is simply that there's some non-`Sync` token
// proving that you can get access to the data. So while weird, this case should
// still be safe, as the data's not stored in the task itself.

/// A reference to a piece of data that's accessible only within a specific
/// `Task`.
///
/// This data is `Send` even when `A` is not `Sync`, because the data stored
/// within is accessed in a single-threaded way. The thread accessing it may
/// change over time, if the task migrates, so `A` must be `Send`.
pub struct TaskRc<A> {
    task_id: usize,
    ptr: Arc<UnsafeCell<A>>,
}

// for safety here, see docs at the top of this module
unsafe impl<A: Send> Send for TaskRc<A> {}
unsafe impl<A: Sync> Sync for TaskRc<A> {}

impl<A> TaskRc<A> {
    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `with` method to get a reference back to the original
    /// data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    ///
    /// # Panics
    ///
    /// This function will panic if a task is not currently running.
    pub fn new(a: A) -> TaskRc<A> {
        super::with(|task, _| {
            TaskRc {
                task_id: task.id,
                ptr: Arc::new(UnsafeCell::new(a)),
            }
        })
    }

    /// Operate with a reference to the underlying data.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if a task is not currently running or if `self`
    /// does not belong to the task that is currently running. That is, if
    /// another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn with<F, R>(&self, f: F) -> R
        where F: FnOnce(&A) -> R
    {
        // for safety here, see docs at the top of this module
        super::with(|task, _| {
            assert_eq!(self.task_id, task.id,
                       "TaskRc being accessed on task it does not belong to");
            f(unsafe { &*self.ptr.get() })
        })
    }
}

impl<A> Clone for TaskRc<A> {
    fn clone(&self) -> TaskRc<A> {
        TaskRc {
            task_id: self.task_id,
            ptr: self.ptr.clone(),
        }
    }
}
<|endoftext|>


<commit_before>// Binop corner cases

fn test_nil() {
    assert (() == ());
    assert (!(() != ()));
    assert (!(() < ()));
    assert (() <= ());
    assert (!(() > ()));
    assert (() >= ());
}

fn test_bool() {
    assert (!(true < false));
    assert (!(true <= false));
    assert (true > false);
    assert (true >= false);

    assert (false < true);
    assert (false <= true);
    assert (!(false > true));
    assert (!(false >= true));

    // Bools support bitwise binops
    assert (false & false == false);
    assert (true & false == false);
    assert (true & true == true);
    assert (false | false == false);
    assert (true | false == true);
    assert (true | true == true);
    assert (false ^ false == false);
    assert (true ^ false == true);
    assert (true ^ true == false);
}

fn test_char() {
    let ch10 = 10 as char;
    let ch4 = 4 as char;
    let ch2 = 2 as char;
    assert (ch10 + ch4 == 14 as char);
    assert (ch10 - ch4 == 6 as char);
    assert (ch10 * ch4 == 40 as char);
    assert (ch10 / ch4 == ch2);
    assert (ch10 % ch4 == ch2);
    assert (ch10 >> ch2 == ch2);
    assert (ch10 >>> ch2 == ch2);
    assert (ch10 << ch4 == 160 as char);
    assert (ch10 | ch4 == 14 as char);
    assert (ch10 & ch2 == ch2);
    assert (ch10 ^ ch2 == 8 as char);
}

fn test_box() {
    assert (@10 == 10);
    assert (0xFF & @0xF0 == 0xF0);
    assert ({a: 1, b: 3} < @{a: 1, b: 4});
    assert (@{a: 'x'} != @{a: 'y'});
}

fn test_port() {
    let p1: port[int] = port();
    let p2: port[int] = port();

    // FIXME (#577) comparison of ports
    // assert (p1 != p2);
    // assert !(p1 < p2);
    // etc
}

fn test_chan() {
    let p: port[int] = port();
    let ch1 = chan(p);
    let ch2 = chan(p);

    // FIXME (#577) comparison of channels
    // assert (ch1 != ch2);
    // etc
}

fn test_ptr() {
    // FIXME: Don't know what binops apply to pointers. Don't know how
    // to make or use pointers
}

fn test_task() {
    fn f() { }
    let t1 = spawn f();
    let t2 = spawn f();
    // FIXME (#577) comparison of tasks
    //assert t1 != t2;
}

fn test_fn() {
    fn f() { }
    fn g() { }
    fn h(i: int) { }
    let f1 = f;
    let f2 = f;
    let g1 = g;
    let h1 = h;
    let h2 = h;
    assert (f1 == f2);
    assert (f1 == f);

    assert (f1 == g1);
    assert (h1 == h2);
    assert (!(f1 != f2));
    assert (!(h1 < h2));
    assert (h1 <= h2);
    assert (!(h1 > h2));
    assert (h1 >= h2);
}

native "rust" mod native_mod = "" {
    fn str_byte_len(s: str) -> vec[u8];
    fn str_alloc(n_bytes: uint) -> str;
}

// FIXME: comparison of native fns
fn test_native_fn() {
    /*assert (native_mod::str_byte_len == native_mod::str_byte_len);
      assert (native_mod::str_byte_len != native_mod::str_alloc);*/
}

fn test_obj() {
    let o1 = obj () {  };
    let o2 = obj () {  };

    assert (o1 == o2);
    assert (!(o1 != o2));
    assert (!(o1 < o2));
    assert (o1 <= o2);
    assert (!(o1 > o2));
    assert (o1 >= o2);

    obj constr1(i: int) { }
    obj constr2(i: int) { }

    let o5 = constr1(10);
    let o6 = constr1(10);
    let o7 = constr1(11);
    let o8 = constr2(11);

    assert (o5 == o6);
    assert (o6 == o7);
    assert (o7 == o8);
}

fn main() {
    test_nil();
    test_bool();
    test_char();
    test_box();
    test_port();
    test_chan();
    test_ptr();
    test_task();
    test_fn();
    test_native_fn();
    test_obj();
}<commit_msg>test: Update binops.rs with the new equality semantics<commit_after>// Binop corner cases

fn test_nil() {
    assert (() == ());
    assert (!(() != ()));
    assert (!(() < ()));
    assert (() <= ());
    assert (!(() > ()));
    assert (() >= ());
}

fn test_bool() {
    assert (!(true < false));
    assert (!(true <= false));
    assert (true > false);
    assert (true >= false);

    assert (false < true);
    assert (false <= true);
    assert (!(false > true));
    assert (!(false >= true));

    // Bools support bitwise binops
    assert (false & false == false);
    assert (true & false == false);
    assert (true & true == true);
    assert (false | false == false);
    assert (true | false == true);
    assert (true | true == true);
    assert (false ^ false == false);
    assert (true ^ false == true);
    assert (true ^ true == false);
}

fn test_char() {
    let ch10 = 10 as char;
    let ch4 = 4 as char;
    let ch2 = 2 as char;
    assert (ch10 + ch4 == 14 as char);
    assert (ch10 - ch4 == 6 as char);
    assert (ch10 * ch4 == 40 as char);
    assert (ch10 / ch4 == ch2);
    assert (ch10 % ch4 == ch2);
    assert (ch10 >> ch2 == ch2);
    assert (ch10 >>> ch2 == ch2);
    assert (ch10 << ch4 == 160 as char);
    assert (ch10 | ch4 == 14 as char);
    assert (ch10 & ch2 == ch2);
    assert (ch10 ^ ch2 == 8 as char);
}

fn test_box() {
    assert (@10 == 10);
    assert (0xFF & @0xF0 == 0xF0);
    assert ({a: 1, b: 3} < @{a: 1, b: 4});
    assert (@{a: 'x'} != @{a: 'y'});
}

fn test_port() {
    let p1: port[int] = port();
    let p2: port[int] = port();

    // FIXME (#577) comparison of ports
    // assert (p1 != p2);
    // assert !(p1 < p2);
    // etc
}

fn test_chan() {
    let p: port[int] = port();
    let ch1 = chan(p);
    let ch2 = chan(p);

    // FIXME (#577) comparison of channels
    // assert (ch1 != ch2);
    // etc
}

fn test_ptr() {
    // FIXME: Don't know what binops apply to pointers. Don't know how
    // to make or use pointers
}

fn test_task() {
    fn f() { }
    let t1 = spawn f();
    let t2 = spawn f();
    // FIXME (#577) comparison of tasks
    //assert t1 != t2;
}

fn test_fn() {
    fn f() { }
    fn g() { }
    fn h(i: int) { }
    let f1 = f;
    let f2 = f;
    let g1 = g;
    let h1 = h;
    let h2 = h;
    assert (f1 == f2);
    assert (f1 == f);

    assert (f1 != g1);
    assert (h1 == h2);
    assert (!(f1 != f2));
    assert (!(h1 < h2));
    assert (h1 <= h2);
    assert (!(h1 > h2));
    assert (h1 >= h2);
}

native "rust" mod native_mod = "" {
    fn str_byte_len(s: str) -> vec[u8];
    fn str_alloc(n_bytes: uint) -> str;
}

// FIXME: comparison of native fns
fn test_native_fn() {
    /*assert (native_mod::str_byte_len == native_mod::str_byte_len);
      assert (native_mod::str_byte_len != native_mod::str_alloc);*/
}

fn test_obj() {
    let o1 = obj () {  };
    let o2 = obj () {  };

    assert (o1 != o2);
    assert (!(o1 == o2));

    obj constr1(i: int) { }
    obj constr2(i: int) { }

    let o5 = constr1(10);
    let o6 = constr1(10);
    let o7 = constr1(11);
    let o8 = constr2(11);

    assert (o5 != o6);
    assert (o6 != o7);
    assert (o7 != o8);
}

fn main() {
    test_nil();
    test_bool();
    test_char();
    test_box();
    test_port();
    test_chan();
    test_ptr();
    test_task();
    test_fn();
    test_native_fn();
    test_obj();
}
<|endoftext|>


<commit_before><commit_msg>day 10, part 1<commit_after>/*
fn seq_counts<T: Eq + PartialEq + Clone>(list: Vec<T>) -> Vec<(T, usize)> {
    let len = list.len();
    let mut vec = vec![];
    let mut items = 0;
    while items < len {
        let first = list.iter().skip(items).next().unwrap();
        let count = list.iter().skip(items).take_while(|&x| first == x).count();
        vec.push((first.clone(), count));
        items += count;
    }
    vec
}
*/

fn seq_counts(list: Vec<char>) -> Vec<(char, usize)> {
    let mut vec = vec![];
    let mut items = 0;
    while items < list.len() {
        let first = list.iter().skip(items).next().unwrap();
        let count = list.iter().skip(items).take_while(|&x| first == x).count();
        vec.push((first.clone(), count));
        items += count;
    }
    vec
}

fn concat(substrings: Vec<String>) -> String {
    substrings.iter().fold("".to_string(), |a, s| a + &s)
}

fn main() {
    let chars: Vec<char> = "3113322113".chars().collect();
    //let chars: Vec<char> = "1".chars().collect();
    let result = (0..40).fold(
        chars,
        |s, _| {
            let subseq: Vec<String> = seq_counts(s).iter().map(|tup| {
                let c: char = tup.0;
                let count: usize = tup.1;
                format!("{}{}", count, c)
            }).collect();
            let string: String = concat(subseq);
            string.chars().collect()
        }
    );
    println!("{}", result.len());
    /*
    for c in result {
        print!("{}", c);
    }
    println!("");
    */
}
<|endoftext|>


<commit_before>use {localhost, TryRead};
use mio::*;
use mio::deprecated::{EventLoop, Handler};
use bytes::ByteBuf;
use mio::tcp::*;

use self::TestState::{Initial, AfterRead};

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

#[derive(Debug, PartialEq)]
enum TestState {
    Initial,
    AfterRead,
}

struct TestHandler {
    srv: TcpListener,
    cli: TcpStream,
    state: TestState
}

impl TestHandler {
    fn new(srv: TcpListener, cli: TcpStream) -> TestHandler {
        TestHandler {
            srv: srv,
            cli: cli,
            state: Initial
        }
    }

    fn handle_read(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, events: Ready) {
        debug!("readable; tok={:?}; hint={:?}", tok, events);

        match tok {
            SERVER => {
                debug!("server connection ready for accept");
                let _ = self.srv.accept().unwrap();
            }
            CLIENT => {
                debug!("client readable");

                match self.state {
                    Initial => {
                        let mut buf = [0; 4096];
                        debug!("GOT={:?}", self.cli.try_read(&mut buf[..]));
                        self.state = AfterRead;
                    },
                    AfterRead => {}
                }

                let mut buf = ByteBuf::mut_with_capacity(1024);

                match self.cli.try_read_buf(&mut buf) {
                    Ok(Some(0)) => event_loop.shutdown(),
                    _ => panic!("the client socket should not be readable")
                }
            }
            _ => panic!("received unknown token {:?}", tok)
        }
        event_loop.reregister(&self.cli, CLIENT, Ready::readable() | Ready::hup(), PollOpt::edge()).unwrap();
    }

    fn handle_write(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, _: Ready) {
        match tok {
            SERVER => panic!("received writable for token 0"),
            CLIENT => {
                debug!("client connected");
                event_loop.reregister(&self.cli, CLIENT, Ready::readable() | Ready::hup(), PollOpt::edge()).unwrap();
            }
            _ => panic!("received unknown token {:?}", tok)
        }
    }
}

impl Handler for TestHandler {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<TestHandler>, tok: Token, events: Ready) {
        if events.is_readable() {
            self.handle_read(event_loop, tok, events);
        }

        if events.is_writable() {
            self.handle_write(event_loop, tok, events);
        }
    }
}

#[test]
pub fn test_close_on_drop() {
    debug!("Starting TEST_CLOSE_ON_DROP");
    let mut event_loop = EventLoop::new().unwrap();

    // The address to connect to - localhost + a unique port
    let addr = localhost();

    // == Create & setup server socket
    let srv = TcpListener::bind(&addr).unwrap();

    event_loop.register(&srv, SERVER, Ready::readable(), PollOpt::edge()).unwrap();

    // == Create & setup client socket
    let sock = TcpStream::connect(&addr).unwrap();

    event_loop.register(&sock, CLIENT, Ready::writable(), PollOpt::edge()).unwrap();

    // == Setup test handler
    let mut handler = TestHandler::new(srv, sock);

    // == Run test
    event_loop.run(&mut handler).unwrap();
    assert!(handler.state == AfterRead, "actual={:?}", handler.state);
}
<commit_msg>Change test_close_on_drop to use Poll API. (#694)<commit_after>use {localhost, TryRead};
use mio::{Events, Poll, PollOpt, Ready, Token};
use bytes::ByteBuf;
use mio::tcp::*;

use self::TestState::{Initial, AfterRead};

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

#[derive(Debug, PartialEq)]
enum TestState {
    Initial,
    AfterRead,
}

struct TestHandler {
    srv: TcpListener,
    cli: TcpStream,
    state: TestState,
    shutdown: bool,
}

impl TestHandler {
    fn new(srv: TcpListener, cli: TcpStream) -> TestHandler {
        TestHandler {
            srv: srv,
            cli: cli,
            state: Initial,
            shutdown: false,
        }
    }

    fn handle_read(&mut self, poll: &mut Poll, tok: Token, events: Ready) {
        debug!("readable; tok={:?}; hint={:?}", tok, events);

        match tok {
            SERVER => {
                debug!("server connection ready for accept");
                let _ = self.srv.accept().unwrap();
            }
            CLIENT => {
                debug!("client readable");

                match self.state {
                    Initial => {
                        let mut buf = [0; 4096];
                        debug!("GOT={:?}", self.cli.try_read(&mut buf[..]));
                        self.state = AfterRead;
                    },
                    AfterRead => {}
                }

                let mut buf = ByteBuf::mut_with_capacity(1024);

                match self.cli.try_read_buf(&mut buf) {
                    Ok(Some(0)) => self.shutdown = true,
                    _ => panic!("the client socket should not be readable")
                }
            }
            _ => panic!("received unknown token {:?}", tok)
        }
        poll.reregister(&self.cli, CLIENT, Ready::readable() | Ready::hup(), PollOpt::edge()).unwrap();
    }

    fn handle_write(&mut self, poll: &mut Poll, tok: Token, _: Ready) {
        match tok {
            SERVER => panic!("received writable for token 0"),
            CLIENT => {
                debug!("client connected");
                poll.reregister(&self.cli, CLIENT, Ready::readable() | Ready::hup(), PollOpt::edge()).unwrap();
            }
            _ => panic!("received unknown token {:?}", tok)
        }
    }
}

#[test]
pub fn test_close_on_drop() {
    debug!("Starting TEST_CLOSE_ON_DROP");
    let mut poll = Poll::new().unwrap();

    // The address to connect to - localhost + a unique port
    let addr = localhost();

    // == Create & setup server socket
    let srv = TcpListener::bind(&addr).unwrap();

    poll.register(&srv, SERVER, Ready::readable(), PollOpt::edge()).unwrap();

    // == Create & setup client socket
    let sock = TcpStream::connect(&addr).unwrap();

    poll.register(&sock, CLIENT, Ready::writable(), PollOpt::edge()).unwrap();

    // == Create storage for events
    let mut events = Events::with_capacity(1024);

    // == Setup test handler
    let mut handler = TestHandler::new(srv, sock);

    // == Run test
    while !handler.shutdown {
        poll.poll(&mut events, None).unwrap();

        for event in &events {
            if event.readiness().is_readable() {
                handler.handle_read(&mut poll, event.token(), event.readiness());
            }

            if event.readiness().is_writable() {
                handler.handle_write(&mut poll, event.token(), event.readiness());
            }
        }
    }
    assert!(handler.state == AfterRead, "actual={:?}", handler.state);
}
<|endoftext|>


<commit_before><commit_msg>Add a regression test for issue-51446<commit_after>// Regression test for #51446.
// check-pass

trait Foo {
    type Item;
    fn get(&self) -> Self::Item;
}

fn blah<T, F>(x: T, f: F) -> B<T::Item, impl Fn(T::Item)>
where
    T: Foo,
    F: Fn(T::Item),
{
    B { x: x.get(), f }
}

pub struct B<T, F>
where
    F: Fn(T),
{
    pub x: T,
    pub f: F,
}

impl Foo for i32 {
    type Item = i32;
    fn get(&self) -> i32 {
        *self
    }
}

fn main() {
    let _ = blah(0, |_| ());
}
<|endoftext|>


<commit_before><commit_msg>betweenness centrality example<commit_after>extern crate rand;
extern crate time;
extern crate timely;
extern crate differential_dataflow;
extern crate docopt;

use docopt::Docopt;

use std::thread;

use std::fs::File;
use std::io::{BufRead, BufReader};

use timely::example_shared::*;
use timely::example_shared::operators::*;
use timely::communication::{Communicator, ProcessCommunicator, ThreadCommunicator};
use timely::networking::initialize_networking;

use rand::{Rng, SeedableRng, StdRng};

use differential_dataflow::collection_trace::LeastUpperBound;

use differential_dataflow::operators::*;

static USAGE: &'static str = "
Usage: bc [options] [<arguments>...]

Options:
    -w <arg>, --workers <arg>    number of workers per process [default: 1]
    -p <arg>, --processid <arg>  identity of this process      [default: 0]
    -n <arg>, --processes <arg>  number of processes involved  [default: 1]
    -h <arg>, --hosts <arg>      file containing list of host:port for workers
";

fn main () {
    let args = Docopt::new(USAGE).and_then(|dopt| dopt.parse()).unwrap_or_else(|e| e.exit());

    let workers: u64 = if let Ok(threads) = args.get_str("-w").parse() { threads }
                       else { panic!("invalid setting for --workers: {}", args.get_str("-t")) };
    let process_id: u64 = if let Ok(proc_id) = args.get_str("-p").parse() { proc_id }
                          else { panic!("invalid setting for --processid: {}", args.get_str("-p")) };
    let processes: u64 = if let Ok(processes) = args.get_str("-n").parse() { processes }
                         else { panic!("invalid setting for --processes: {}", args.get_str("-n")) };

    println!("Starting bc dataflow with");
    println!("\tworkers:\t{}", workers);
    println!("\tprocesses:\t{}", processes);
    println!("\tprocessid:\t{}", process_id);

    // vector holding communicators to use; one per local worker.
    if processes > 1 {
        println!("Initializing BinaryCommunicator");

        let hosts = args.get_str("-h");
        let addresses: Vec<_> = if hosts != "" {
            let reader = BufReader::new(File::open(hosts).unwrap());
            reader.lines().take(processes as usize).map(|x| x.unwrap()).collect()
        }
        else {
            (0..processes).map(|index| format!("localhost:{}", 2101 + index).to_string()).collect()
        };

        if addresses.len() != processes as usize { panic!("only {} hosts for -p: {}", addresses.len(), processes); }

        let communicators = initialize_networking(addresses, process_id, workers).ok().expect("error initializing networking");

        bc_spawn(communicators);
    }
    else if workers > 1 { bc_spawn(ProcessCommunicator::new_vector(workers)); }
    else { bc_spawn(vec![ThreadCommunicator]); };
}

fn bc_spawn<C: Communicator+Send>(communicators: Vec<C>) {

    let mut guards = Vec::new();
    for communicator in communicators.into_iter() {
        guards.push(thread::Builder::new().name(format!("worker thread {}", communicator.index()))
                                          .spawn(move || thread_main(communicator))
                                          .unwrap());
    }

    for guard in guards { guard.join().unwrap(); }
}

fn thread_main<C: Communicator>(comm: C) {

    let index = comm.index();
    let start = time::precise_time_s();
    let start2 = time::precise_time_s();

    // define a new computational scope, in which to run BFS
    let mut computation = GraphRoot::new(comm);

    // define BFS dataflow; return handles to roots and edges inputs
    let (mut roots, mut graph) = computation.subcomputation(|builder| {

        let (edge_input, graph) = builder.new_input();
        let (node_input, roots) = builder.new_input();

        let edges = graph.map(|((x,y),w)| ((y,x), w)).concat(&graph);

        let dists = bc(&edges, &roots);    // determine distances to each graph node

        dists.consolidate(|x| x.0, |x| x.0)
             .inspect_batch(move |t,b| {
             println!("epoch: {:?}, length: {}, processing: {}", t, b.len(), (time::precise_time_s() - start2) - (t.inner as f64));
            //  for elem in b.iter() {
            //      println!("\t{:?}", elem);
            //  }
        });

        // dists.map(|((_,s),w)| (s,w))        // keep only the distances, not node ids
        //      .consolidate(|x| *x, |x| *x)   // aggregate into one record per distance
        //      .inspect_batch(move |t, x| {   // print up something neat for each update
        //          println!("observed at {:?}:", t);
        //          println!("elapsed: {}s", time::precise_time_s() - (start + t.inner as f64));
        //          for y in x {
        //              println!("\t{:?}", y);
        //          }
        //      });

        (node_input, edge_input)
    });

    let nodes = 100_000u32; // the u32 helps type inference understand what nodes are
    let edges = 200_000;

    let seed: &[_] = &[1, 2, 3, 4];
    let mut rng1: StdRng = SeedableRng::from_seed(seed);    // rng for edge additions
    let mut rng2: StdRng = SeedableRng::from_seed(seed);    // rng for edge deletions

    println!("performing BFS on {} nodes, {} edges:", nodes, edges);

    // trickle edges in to dataflow
    let mut left = edges;
    while left > 0 {
        let next = std::cmp::min(left, 1000);
        graph.send_at(0, (0..next).map(|_| ((rng1.gen_range(0, nodes),
                                             rng1.gen_range(0, nodes)), 1)));
        computation.step();
        left -= next;
    }

    // start the root set out with roots 0, 1, and 2
    roots.advance_to(0);
    computation.step();
    computation.step();
    computation.step();
    println!("loaded; elapsed: {}s", time::precise_time_s() - start);

        if index == 0 { roots.send_at(0, (0..10).map(|x| (x,1))); }
    roots.advance_to(1);
    roots.close();

    // repeatedly change edges
    if index == 0 {

    let mut round = 0 as u32;

    while computation.step() {
        // once each full second ticks, change an edge
        if time::precise_time_s() - start >= round as f64 {
            // add edges using prior rng; remove edges using fresh rng with the same seed
            let changes = vec![((rng1.gen_range(0, nodes), rng1.gen_range(0, nodes)), 1),
                               ((rng2.gen_range(0, nodes), rng2.gen_range(0, nodes)),-1)];
            graph.send_at(round, changes.into_iter());
            graph.advance_to(round + 1);
            round += 1;
        }
    }
}

    graph.close();                  // seal the source of edges
    while computation.step() { }    // wind down the computation
}

// returns pairs (n, (r, b, s)) indicating node n can be reached from root r by b in s steps.
// one pair for each shortest path (so, this number can get quite large, but it is in binary)
fn bc<G: GraphBuilder>(edges: &Stream<G, ((u32, u32), i32)>,
                       roots: &Stream<G, (u32 ,i32)>)
                            -> Stream<G, ((u32, u32, u32, u32), i32)>
where G::Timestamp: LeastUpperBound {

    // initialize roots as reaching themselves at distance 0
    let nodes = roots.map(|(x,w)| ((x, x, x, 0), w));

    let dists = nodes.iterate(u32::max_value(), |x| x.0, |x| x.0, |dists| {

        let edges = dists.builder().enter(&edges);
        let nodes = dists.builder().enter(&nodes);

        dists.join_u(&edges, |(n,r,_,s)| (n, (r,s)), |e| e, |&n, &(r,s), &d| (d, r, n, s+1))
             .concat(&nodes)
             .group_by(|(n,r,b,s)| ((n,r),(s,b)),
                       |&(n,r,_,_)| (n + r) as u64,
                       |&(n,r)| (n + r) as u64,
                       |&(n,r), &(b,s)| (n,r,b,s),
                       |&(_n,_r), mut s, t| {
                 // keep only shortest paths
                 let ref_s: &(u32, u32) = s.peek().unwrap().0;
                 let min_s = ref_s.0;
                 t.extend(s.take_while(|x| (x.0).0 == min_s).map(|(&(s,b),w)| ((b,s), w)));
             })
             .inspect_batch(|t,b| {
                 println!("iteration: {:?}, length: {}", t, b.len());
                //  for elem in b.iter() {
                //      println!("\t{:?}", elem);
                //  }
             })
     });

     dists
}
<|endoftext|>


<commit_before><commit_msg>Add example for fullscreen toggle using `set_monitor` and `with_primary_monitor_mut`<commit_after>// Copyright 2016 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// NOTE: Make sure to resize the OpenGL viewport (or whatever else) after any size changes.

extern crate glfw;

use glfw::{Action, Context, Key};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    let (mut window, events) = glfw.create_window(600, 400, "Press F11 to toggle Fullscreen (it will be blank)", glfw::WindowMode::Windowed)
                                   .expect("Failed to create GLFW window.");

    window.set_key_polling(true);
    window.make_current();
    glfw.set_swap_interval(glfw::SwapInterval::Sync(1));

    //Store fullscreen state
    let mut is_fullscreen = false;

    //Keep track of last position and size so we can restore the window to the originals
    let mut last_pos = (0, 0);
    let mut last_size = (0, 0);

    while !window.should_close() {
        glfw.poll_events();
        for (_, event) in glfw::flush_messages(&events) {
            match event {
                glfw::WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
                    window.set_should_close(true)
                }
                //F11 is pretty standard for fullscreen
                glfw::WindowEvent::Key(Key::F11, _, Action::Press, _) => {
                    if is_fullscreen {
                        window.set_monitor(glfw::WindowMode::Windowed, last_pos.0, last_pos.1, last_size.0 as u32, last_size.1 as u32, None);
                        println!("Window restored to {:?} at location {:?}", last_size, last_pos);
                    } else {
                        last_pos = window.get_pos();
                        last_size = window.get_size();

                        glfw.with_primary_monitor_mut(|_: &mut _, m: Option<&glfw::Monitor>| {
                            let monitor = m.unwrap();

                            let mode = monitor.get_video_mode().unwrap();

                            window.set_monitor(glfw::WindowMode::FullScreen(&monitor), 0, 0, mode.width, mode.height, Some(mode.refresh_rate));

                            println!("{}x{} fullscreen enabled at {}Hz on monitor {}", mode.width, mode.height, mode.refresh_rate, monitor.get_name());
                        });
                    }

                    is_fullscreen = !is_fullscreen;
                }
                _ => {}
            }
        }
    }
}<|endoftext|>


<commit_before><commit_msg>Add I2C 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.

// i2c_ds3231.rs - Set and retrieve the time on a DS3231 RTC using I2C.

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

use rppal::i2c::I2c;

// DS3231 I2C default slave address.
const ADDR_DS3231: u16 = 0x68;

// DS3231 register addresses.
const SECONDS: usize = 0x00;
const MINUTES: usize = 0x01;
const HOURS: usize = 0x02;

// Helper functions to encode and decode binary-coded decimal (BCD) values.
fn bcd2dec(bcd: u8) -> u8 {
    (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F)
}

fn dec2bcd(dec: u8) -> u8 {
    ((dec / 10) << 4) | (dec % 10)
}

fn main() {
    let mut i2c = I2c::new().unwrap_or_else(|e| {
        eprintln!("Error: Can't access I2C peripheral ({})", e);
        exit(1);
    });

    // Set the I2C slave address to the device we're communicating with.
    i2c.set_slave_address(ADDR_DS3231).unwrap();

    // Set the time to 11:59:50 AM. Start at register address 0x00 (Seconds) and
    // write 3 bytes, overwriting the Seconds, Minutes and Hours registers.
    // Setting bit 6 of the Hours register indicates we're using a 12-hour
    // format. Leaving bit 5 unset indicates AM.
    i2c.block_write(
        SECONDS as u8,
        &[dec2bcd(50), dec2bcd(59), dec2bcd(11) | (1 << 6)],
    )
    .unwrap();

    let mut reg: [u8; 3] = [0; 3];
    loop {
        // Start at the Seconds register (0x00) and read the values for the next
        // 3 registers (Seconds, Minutes, Hours) into the reg variable.
        i2c.block_read(SECONDS as u8, &mut reg).unwrap();

        // Display the retrieved time in the appropriate format based on bit 6 of
        // the Hours register.
        if reg[HOURS] & (1 << 6) > 0 {
            // 12-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2} {}",
                bcd2dec(reg[HOURS] & 0x1F),
                bcd2dec(reg[MINUTES]),
                bcd2dec(reg[SECONDS]),
                if reg[HOURS] & (1 << 5) > 0 {
                    "PM"
                } else {
                    "AM"
                }
            );
        } else {
            // 24-hour format.
            println!(
                "{:0>2}:{:0>2}:{:0>2}",
                bcd2dec(reg[HOURS] & 0x3F),
                bcd2dec(reg[MINUTES]),
                bcd2dec(reg[SECONDS])
            );
        }

        sleep(Duration::from_secs(1));
    }
}
<|endoftext|>


<commit_before><commit_msg>TINY bit faster :D<commit_after><|endoftext|>


<commit_before>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<usize>, // Index for right node
    right: Option<usize>, // Index for left node
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T>(&self, avl: &'a Avl<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }
}

pub struct Avl<T> {
    root: usize, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T> Avl<T> {
    pub fn new() -> Self {
        Avl {
            root: 0,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    pub fn insert(&mut self, value: T) -> AvlNodeId {
        // TODO this is just a placeholder, we need to deal with all the fancy rotation stuff that
        // AVL trees do
        self.allocate_node(value)
    }

    fn allocate_node(&mut self, value: T) -> AvlNodeId {
        match self.free_list.pop() {
            Some(index) => {
                AvlNodeId { time_stamp: self.nodes[index].time_stamp+1, index: index }
            },
            None => {
                // No free slots, create a new one
                let id = AvlNodeId { index: self.nodes.len(), time_stamp: 0 };
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                id
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<commit_msg>Starting avl rotation stuff<commit_after>use redox::Vec;

pub struct AvlNode<T> {
    value: T,
    left: Option<AvlNodeId>, // ID for left node
    right: Option<AvlNodeId>, // ID for right node
}

#[derive(Copy, Clone)]
pub struct AvlNodeId {
    index: usize,
    time_stamp: u64,
}

impl AvlNodeId {
    pub fn get<'a, T>(&self, avl: &'a Avl<T>) -> Option<&'a AvlNode<T>> {
        avl.nodes
           .get(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_ref()
               } else {
                   None
               }
           })
    }

    pub fn get_mut<'a, T>(&self, avl: &'a mut Avl<T>) -> Option<&'a mut AvlNode<T>> {
        avl.nodes
           .get_mut(self.index)
           .and_then(|slot| {
               if slot.time_stamp == self.time_stamp {
                   slot.node.as_mut()
               } else {
                   None
               }
           })
    }
}

pub struct Avl<T> {
    root: usize, // Index of the root node
    nodes: Vec<AvlSlot<T>>,
    free_list: Vec<usize>,
}

impl<T> Avl<T> {
    pub fn new() -> Self {
        Avl {
            root: 0,
            nodes: Vec::new(),
            free_list: Vec::new(),
        }
    }

    pub fn insert(&mut self, value: T) -> AvlNodeId {
        // TODO this is just a placeholder, we need to deal with all the fancy rotation stuff that
        // AVL trees do
        self.allocate_node(value)
    }

    // Performs a left rotation on a tree/subtree.
    fn rotate_left(&mut self, node: &mut AvlNodeId) {
        // Keep track of the original node positions
        // For a rotate left, the right child node must exist
        let mut original = *node;
        let r = node.get(self).unwrap().right.unwrap();
        let rl = r.get(self).unwrap().left;

        *node = r;
        original.get_mut(self).unwrap().right = rl;
        node.get_mut(self).unwrap().left = Some(original);
    }

    // Performs a right rotation on a tree/subtree.
    fn rotate_right(&mut self, node: &mut AvlNodeId) {
        // Keep track of the original node positions
        // For a rotate right, the left child node must exist
        let mut original = *node;
        let l = original.get(self).unwrap().left.unwrap();
        let lr = l.get(self).unwrap().right;

        *node = l;
        original.get_mut(self).unwrap().left = lr;
        node.get_mut(self).unwrap().right = Some(original);
    }

    // performs a left-right double rotation on a tree/subtree.
    fn rotate_leftright(&mut self, node: &mut AvlNodeId) {
        self.rotate_left(node.get_mut(self).unwrap().left.as_mut().unwrap()); // Left node needs to exist
        self.rotate_right(node);
    }

    // performs a right-left double rotation on a tree/subtree.
    fn rotate_rightleft(&mut self, node: &mut AvlNodeId) {
        self.rotate_right(node.get_mut(self).unwrap().right.as_mut().unwrap()); // Right node needs to exist
        self.rotate_left(node);
    }

    // _ins is the implementation of the binary tree insert function. Lesser values will be stored on
    // the left, while greater values will be stored on the right. No duplicates are allowed.
    /*fn _ins(int n, Node*& node) {
        if (!node) {
            // The node doesn't exist, create it here.

            node = new Node;
            node->val = n;
            node->left = 0;
            node->right = 0;
        }
        else
        {
            // Node exists, check which way to branch.

            if (n == node->val)
                return;
            else if (n < node->val)
                _ins(n, node->left);
            else if (n > node->val)
                _ins(n, node->right);
        }

        rebalance(node);
    }

    // _rebalance rebalances the provided node
    fn rebalance(Node*& node) {
        if (!node)
        {
            return;
        }

        int balance = _height(node->left) - _height(node->right);
        if (balance == 2) // left
        {
            int lbalance = _height(node->left->left) - _height(node->left->right);
            if (lbalance == 0 || lbalance == 1) // left left - need to rotate right
            {
                rotate_right(node);
            }
            else if (lbalance == -1) // left right
            {
                rotate_leftright(node); // function name is just a coincidence
            }
        }
        else if (balance == -2) // right
        {
            int rbalance = _height(node->right->left) - _height(node->right->right);
            if (rbalance == 1) // right left
            {
                rotate_rightleft(node); // function name is just a coincidence
            }
            else if (rbalance == 0 || rbalance == -1) // right right - need to rotate left
            {
                rotate_left(node);
            }
        }
    }

    // _height gets the height of a tree or subtree
    fn _height(node: AvlNodeId) -> usize {
        if (!node)
            return -1;

        int left_height = _height(node->left);
        int right_height = _height(node->right);

        if (left_height > right_height)
            return left_height+1;
        else
            return right_height+1;
    }*/

    fn allocate_node(&mut self, value: T) -> AvlNodeId {
        match self.free_list.pop() {
            Some(index) => {
                AvlNodeId { time_stamp: self.nodes[index].time_stamp+1, index: index }
            },
            None => {
                // No free slots, create a new one
                let id = AvlNodeId { index: self.nodes.len(), time_stamp: 0 };
                self.nodes.push(AvlSlot { time_stamp: 0,
                                          node: Some(AvlNode { value: value, left: None, right: None }) });
                id
            },
        }
    }

    fn free_node(&mut self, id: AvlNodeId) -> AvlNode<T> {
        self.free_list.push(id.index);

        // NOTE: We unwrap here, because we trust that `id` points to a valid node, because
        // only we can create and free AvlNodes and their AvlNodeIds
        self.nodes[id.index].node.take().unwrap()
    }
}

struct AvlSlot<T> {
    time_stamp: u64,
    node: Option<AvlNode<T>>,
}
<|endoftext|>


<commit_before><commit_msg>Example of service without a service trait<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tk_bufstream;

use std::io;
use std::str;
use std::io::Write;
use std::net::SocketAddr;
use std::time::Duration;
use std::env;

use futures::{Future, Sink};
use futures::stream::Stream;
use tokio_core::net::TcpListener;
use tokio_core::reactor::{Core, Timeout};
use tk_bufstream::{Buf, IoBuf, Encode, Decode};

const MAX_CONNECTIONS: usize = 200;

struct Codec;

impl Encode for Codec {
    type Item = String;
    fn encode(&mut self, data: String, buf: &mut Buf) {
        writeln!(buf, "{}", &data).unwrap();
    }
}

impl Decode for Codec {
    type Item = String;
    fn decode(&mut self, buf: &mut Buf) -> Result<Option<String>, io::Error> {
        if let Some(end) = buf[..].iter().position(|&x| x == b'\n') {
            let s = str::from_utf8(&buf[..end])
                .map(|v| String::from(v))
                .map_err(|_| io::Error::new(io::ErrorKind::Other,
                                            "can't decode utf-8"))?;
            buf.consume(end+1);
            Ok(Some(s))
        } else {
            Ok(None)
        }
    }
}

fn main() {
    let addr = env::args().nth(1).unwrap_or("127.0.0.1:7777".to_string());
    let addr = addr.parse::<SocketAddr>().unwrap();

    let mut lp = Core::new().unwrap();
    let handle = lp.handle();
    let socket = TcpListener::bind(&addr, &handle).unwrap();
    println!("Listening on: {}", addr);

    let done = socket.incoming()
        .map_err(|e| { println!("Accept error: {}", e); })
        .map(|(socket, _addr)| {
            let (stream, sink) = IoBuf::new(socket)
                .framed(Codec).split();
            sink.send_all(
                stream
                .map(|l| {
                    Timeout::new(Duration::new(5, 0), &handle).unwrap()
                    .map(move |()| format!("after timeout: {}", l))
                })
                .buffered(5)
            )
            .map(|_| ())
            .map_err(|e| { println!("Connection error: {}", e); })
        }).buffer_unordered(MAX_CONNECTIONS)
          .for_each(|()| Ok(()));
    lp.run(done).unwrap();
}

<|endoftext|>


<commit_before><commit_msg>clippy: fix cast_ptr_alignment error<commit_after><|endoftext|>


<commit_before><commit_msg>[katas] one more kata<commit_after>struct MyQueue {
    pub input_buffer: Vec<i32>,
    pub output_buffer: Vec<i32>
}

/**
 * `&self` means the method takes an immutable reference.
 * If you need a mutable reference, change it to `&mut self` instead.
 */
impl MyQueue {

    /** Initialize your data structure here. */
    fn new() -> Self {
        MyQueue {
            input_buffer: Vec::new(),
            output_buffer: Vec::new()
        }
    }

    /** Push element x to the back of queue. */
    fn push(&mut self, x: i32) {
        self.input_buffer.push(x);
    }

    /** Removes the element from in front of queue and returns that element. */
    fn pop(&mut self) -> i32 {
        if (self.output_buffer.is_empty()) {
            self.output_buffer = self.input_buffer.iter().rev().map(|elem| { *elem }).collect();
            self.input_buffer = Vec::new();
        }

        match self.output_buffer.pop() {
            Some(elem) => elem,
            None => panic!("Don't expect to pop empty")
        }
    }

    /** Get the front element. */
    fn peek(&mut self) -> i32 {
        if (self.output_buffer.is_empty()) {
            self.output_buffer = self.input_buffer.iter().rev().map(|elem| { *elem }).collect();
            self.input_buffer = Vec::new();
        }

        match self.output_buffer.last() {
            Some(elem) => *elem,
            None => panic!("Don't expect to pop empty")
        }
    }

    /** Returns whether the queue is empty. */
    fn empty(&self) -> bool {
      self.input_buffer.is_empty() && self.output_buffer.is_empty()
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * let obj = MyQueue::new();
 * obj.push(x);
 * let ret_2: i32 = obj.pop();
 * let ret_3: i32 = obj.peek();
 * let ret_4: bool = obj.empty();
 */
<|endoftext|>