<commit_before>use redox::*;

// nvp implementation version
pub const NV_VERSION: i32 = 0;

// nvlist header
//#[derive(Debug)]
pub struct NvList {
    pub version: i32,
    pub nvflag:  u32, // persistent flags
    pub pairs: Vec<(String, NvValue)>,
}

impl NvList {
    pub fn new(nvflag: u32) -> Self {
        NvList {
            version: NV_VERSION,
            nvflag: nvflag,
            pairs: Vec::new(),
        }
    }

    pub fn find(&self, name: &str) -> Option<&NvValue> {
        for pair in &self.pairs {
            if pair.0.as_str() == name {
                return Some(&pair.1);
            }
        }
        None
    }
}

impl fmt::Debug for NvList {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "NvList {{ version: {:X}, nvflag: {:X}, pairs: [\n", self.version, self.nvflag));
        for &(ref name, ref value) in &self.pairs {
            try!(write!(f, "{} : {:?}\n", name, value));
        }
        try!(write!(f, "] }}\n"));
        Ok(())
    }
}

// TODO Auto implement Debug. format! currently crashes with big u32 values
//#[derive(Debug)]
pub enum NvValue {
    Unknown,
    Boolean,
    Byte(u8),
    Int16(i16),
    Uint16(u16),
    Int32(i32),
    Uint32(u32),
    Int64(i64),
    Uint64(u64),
    String(String),
    ByteArray(Vec<u8>),
    Int16Array(Vec<i16>),
    Uint16Array(Vec<u16>),
    Int32Array(Vec<i32>),
    Uint32Array(Vec<u32>),
    Int64Array(Vec<i64>),
    Uint64Array(Vec<u64>),
    StringArray(Vec<String>),
    HrTime(i64),
    NvList(Box<NvList>),
    NvListArray(Vec<Box<NvList>>),
    BooleanValue(bool),
    Int8(i8),
    Uint8(u8),
    BooleanArray(Vec<bool>),
    Int8Array(Vec<i8>),
    Uint8Array(Vec<u8>),
}

impl NvValue {
    pub fn data_type(&self) -> DataType {
        match *self {
            NvValue::Unknown => DataType::Unknown,
            NvValue::Boolean => DataType::Boolean,
            NvValue::Byte(_) => DataType::Byte,
            NvValue::Int16(_) => DataType::Int16,
            NvValue::Uint16(_) => DataType::Uint16,
            NvValue::Int32(_) => DataType::Int32,
            NvValue::Uint32(_) => DataType::Uint32,
            NvValue::Int64(_) => DataType::Int64,
            NvValue::Uint64(_) => DataType::Uint64,
            NvValue::String(_) => DataType::String,
            NvValue::ByteArray(_) => DataType::ByteArray,
            NvValue::Int16Array(_) => DataType::Int16Array,
            NvValue::Uint16Array(_) => DataType::Uint16Array,
            NvValue::Int32Array(_) => DataType::Int32Array,
            NvValue::Uint32Array(_) => DataType::Uint32Array,
            NvValue::Int64Array(_) => DataType::Int64Array,
            NvValue::Uint64Array(_) => DataType::Uint64Array,
            NvValue::StringArray(_) => DataType::StringArray,
            NvValue::HrTime(_) => DataType::HrTime,
            NvValue::NvList(_) => DataType::NvList,
            NvValue::NvListArray(_) => DataType::NvListArray,
            NvValue::BooleanValue(_) => DataType::BooleanValue,
            NvValue::Int8(_) => DataType::Int8,
            NvValue::Uint8(_) => DataType::Uint8,
            NvValue::BooleanArray(_) => DataType::BooleanArray,
            NvValue::Int8Array(_) => DataType::Int8Array,
            NvValue::Uint8Array(_) => DataType::Uint8Array,
        }
    }

    pub fn num_elements(&self) -> usize {
        match *self {
            NvValue::Unknown => 1,
            NvValue::Boolean => 1,
            NvValue::Byte(_) => 1,
            NvValue::Int16(_) => 1,
            NvValue::Uint16(_) => 1,
            NvValue::Int32(_) => 1,
            NvValue::Uint32(_) => 1,
            NvValue::Int64(_) => 1,
            NvValue::Uint64(_) => 1,
            NvValue::String(_) => 1,
            NvValue::ByteArray(ref a) => a.len(),
            NvValue::Int16Array(ref a) => a.len(),
            NvValue::Uint16Array(ref a) => a.len(),
            NvValue::Int32Array(ref a) => a.len(),
            NvValue::Uint32Array(ref a) => a.len(),
            NvValue::Int64Array(ref a) => a.len(),
            NvValue::Uint64Array(ref a) => a.len(),
            NvValue::StringArray(ref a) => a.len(),
            NvValue::HrTime(_) => 1,
            NvValue::NvList(_) => 1,
            NvValue::NvListArray(ref a) => a.len(),
            NvValue::BooleanValue(_) => 1,
            NvValue::Int8(_) => 1,
            NvValue::Uint8(_) => 1,
            NvValue::BooleanArray(ref a) => a.len(),
            NvValue::Int8Array(ref a) => a.len(),
            NvValue::Uint8Array(ref a) => a.len(),
        }
    }
}

impl fmt::Debug for NvValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            NvValue::Int64(v) => write!(f, "Int64(0x{:X})", v),
            NvValue::Uint64(v) => write!(f, "Uint64(0x{:X})", v),
            NvValue::NvList(ref v) => write!(f, "NvList({:?})", **v),
            NvValue::NvListArray(ref v) => {
                try!(write!(f, "NvListArray(["));
                for nv_list in v {
                    try!(write!(f, "NvList({:?})", **nv_list));
                }
                write!(f, "])")
            },
            NvValue::String(ref v) => { write!(f, "String({})", v) },
            _ => write!(f, "{:?}", self),
        }
    }
}

#[derive(Copy, Clone, Debug)]
pub enum DataType {
    Unknown = 0,
    Boolean,
    Byte,
    Int16,
    Uint16,
    Int32,
    Uint32,
    Int64,
    Uint64,
    String,
    ByteArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Int64Array,
    Uint64Array,
    StringArray,
    HrTime,
    NvList,
    NvListArray,
    BooleanValue,
    Int8,
    Uint8,
    BooleanArray,
    Int8Array,
    Uint8Array,
}

impl DataType {
    pub fn from_u8(u: u8) -> Option<DataType> {
        match u {
            0 => Some(DataType::Unknown),
            1 => Some(DataType::Boolean),
            2 => Some(DataType::Byte),
            3 => Some(DataType::Int16),
            4 => Some(DataType::Uint16),
            5 => Some(DataType::Int32),
            6 => Some(DataType::Uint32),
            7 => Some(DataType::Int64),
            8 => Some(DataType::Uint64),
            9 => Some(DataType::String),
            10 => Some(DataType::ByteArray),
            11 => Some(DataType::Int16Array),
            12 => Some(DataType::Uint16Array),
            13 => Some(DataType::Int32Array),
            14 => Some(DataType::Uint32Array),
            15 => Some(DataType::Int64Array),
            16 => Some(DataType::Uint64Array),
            17 => Some(DataType::StringArray),
            18 => Some(DataType::HrTime),
            19 => Some(DataType::NvList),
            20 => Some(DataType::NvListArray),
            21 => Some(DataType::BooleanValue),
            22 => Some(DataType::Int8),
            23 => Some(DataType::Uint8),
            24 => Some(DataType::BooleanArray),
            25 => Some(DataType::Int8Array),
            26 => Some(DataType::Uint8Array),
            _ => None,
        }
    }

    pub fn to_u8(self) -> u8 {
        match self {
            DataType::Unknown => 0,
            DataType::Boolean => 1,
            DataType::Byte => 2,
            DataType::Int16 => 3,
            DataType::Uint16 => 4,
            DataType::Int32 => 5,
            DataType::Uint32 => 6,
            DataType::Int64 => 7,
            DataType::Uint64 => 8,
            DataType::String => 9,
            DataType::ByteArray => 10,
            DataType::Int16Array => 11,
            DataType::Uint16Array => 12,
            DataType::Int32Array => 13,
            DataType::Uint32Array => 14,
            DataType::Int64Array => 15,
            DataType::Uint64Array => 16,
            DataType::StringArray => 17,
            DataType::HrTime => 18,
            DataType::NvList => 19,
            DataType::NvListArray => 20,
            DataType::BooleanValue => 21,
            DataType::Int8 => 22,
            DataType::Uint8 => 23,
            DataType::BooleanArray => 24,
            DataType::Int8Array => 25,
            DataType::Uint8Array => 26,
        }
    }
}
<commit_msg>NvList::find_mut<commit_after>use redox::*;

// nvp implementation version
pub const NV_VERSION: i32 = 0;

// nvlist header
//#[derive(Debug)]
pub struct NvList {
    pub version: i32,
    pub nvflag:  u32, // persistent flags
    pub pairs: Vec<(String, NvValue)>,
}

impl NvList {
    pub fn new(nvflag: u32) -> Self {
        NvList {
            version: NV_VERSION,
            nvflag: nvflag,
            pairs: Vec::new(),
        }
    }

    pub fn find(&self, name: &str) -> Option<&NvValue> {
        for pair in &self.pairs {
            if pair.0.as_str() == name {
                return Some(&pair.1);
            }
        }
        None
    }

    pub fn find_mut(&mut self, name: &str) -> Option<&mut NvValue> {
        for pair in &mut self.pairs {
            if pair.0.as_str() == name {
                return Some(&mut pair.1);
            }
        }
        None
    }
}

impl fmt::Debug for NvList {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        try!(write!(f, "NvList {{ version: {:X}, nvflag: {:X}, pairs: [\n", self.version, self.nvflag));
        for &(ref name, ref value) in &self.pairs {
            try!(write!(f, "{} : {:?}\n", name, value));
        }
        try!(write!(f, "] }}\n"));
        Ok(())
    }
}

// TODO Auto implement Debug. format! currently crashes with big u32 values
//#[derive(Debug)]
pub enum NvValue {
    Unknown,
    Boolean,
    Byte(u8),
    Int16(i16),
    Uint16(u16),
    Int32(i32),
    Uint32(u32),
    Int64(i64),
    Uint64(u64),
    String(String),
    ByteArray(Vec<u8>),
    Int16Array(Vec<i16>),
    Uint16Array(Vec<u16>),
    Int32Array(Vec<i32>),
    Uint32Array(Vec<u32>),
    Int64Array(Vec<i64>),
    Uint64Array(Vec<u64>),
    StringArray(Vec<String>),
    HrTime(i64),
    NvList(Box<NvList>),
    NvListArray(Vec<Box<NvList>>),
    BooleanValue(bool),
    Int8(i8),
    Uint8(u8),
    BooleanArray(Vec<bool>),
    Int8Array(Vec<i8>),
    Uint8Array(Vec<u8>),
}

impl NvValue {
    pub fn data_type(&self) -> DataType {
        match *self {
            NvValue::Unknown => DataType::Unknown,
            NvValue::Boolean => DataType::Boolean,
            NvValue::Byte(_) => DataType::Byte,
            NvValue::Int16(_) => DataType::Int16,
            NvValue::Uint16(_) => DataType::Uint16,
            NvValue::Int32(_) => DataType::Int32,
            NvValue::Uint32(_) => DataType::Uint32,
            NvValue::Int64(_) => DataType::Int64,
            NvValue::Uint64(_) => DataType::Uint64,
            NvValue::String(_) => DataType::String,
            NvValue::ByteArray(_) => DataType::ByteArray,
            NvValue::Int16Array(_) => DataType::Int16Array,
            NvValue::Uint16Array(_) => DataType::Uint16Array,
            NvValue::Int32Array(_) => DataType::Int32Array,
            NvValue::Uint32Array(_) => DataType::Uint32Array,
            NvValue::Int64Array(_) => DataType::Int64Array,
            NvValue::Uint64Array(_) => DataType::Uint64Array,
            NvValue::StringArray(_) => DataType::StringArray,
            NvValue::HrTime(_) => DataType::HrTime,
            NvValue::NvList(_) => DataType::NvList,
            NvValue::NvListArray(_) => DataType::NvListArray,
            NvValue::BooleanValue(_) => DataType::BooleanValue,
            NvValue::Int8(_) => DataType::Int8,
            NvValue::Uint8(_) => DataType::Uint8,
            NvValue::BooleanArray(_) => DataType::BooleanArray,
            NvValue::Int8Array(_) => DataType::Int8Array,
            NvValue::Uint8Array(_) => DataType::Uint8Array,
        }
    }

    pub fn num_elements(&self) -> usize {
        match *self {
            NvValue::Unknown => 1,
            NvValue::Boolean => 1,
            NvValue::Byte(_) => 1,
            NvValue::Int16(_) => 1,
            NvValue::Uint16(_) => 1,
            NvValue::Int32(_) => 1,
            NvValue::Uint32(_) => 1,
            NvValue::Int64(_) => 1,
            NvValue::Uint64(_) => 1,
            NvValue::String(_) => 1,
            NvValue::ByteArray(ref a) => a.len(),
            NvValue::Int16Array(ref a) => a.len(),
            NvValue::Uint16Array(ref a) => a.len(),
            NvValue::Int32Array(ref a) => a.len(),
            NvValue::Uint32Array(ref a) => a.len(),
            NvValue::Int64Array(ref a) => a.len(),
            NvValue::Uint64Array(ref a) => a.len(),
            NvValue::StringArray(ref a) => a.len(),
            NvValue::HrTime(_) => 1,
            NvValue::NvList(_) => 1,
            NvValue::NvListArray(ref a) => a.len(),
            NvValue::BooleanValue(_) => 1,
            NvValue::Int8(_) => 1,
            NvValue::Uint8(_) => 1,
            NvValue::BooleanArray(ref a) => a.len(),
            NvValue::Int8Array(ref a) => a.len(),
            NvValue::Uint8Array(ref a) => a.len(),
        }
    }
}

impl fmt::Debug for NvValue {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            NvValue::Int64(v) => write!(f, "Int64(0x{:X})", v),
            NvValue::Uint64(v) => write!(f, "Uint64(0x{:X})", v),
            NvValue::NvList(ref v) => write!(f, "NvList({:?})", **v),
            NvValue::NvListArray(ref v) => {
                try!(write!(f, "NvListArray(["));
                for nv_list in v {
                    try!(write!(f, "NvList({:?})", **nv_list));
                }
                write!(f, "])")
            },
            NvValue::String(ref v) => { write!(f, "String({})", v) },
            _ => write!(f, "{:?}", self),
        }
    }
}

#[derive(Copy, Clone, Debug)]
pub enum DataType {
    Unknown = 0,
    Boolean,
    Byte,
    Int16,
    Uint16,
    Int32,
    Uint32,
    Int64,
    Uint64,
    String,
    ByteArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Int64Array,
    Uint64Array,
    StringArray,
    HrTime,
    NvList,
    NvListArray,
    BooleanValue,
    Int8,
    Uint8,
    BooleanArray,
    Int8Array,
    Uint8Array,
}

impl DataType {
    pub fn from_u8(u: u8) -> Option<DataType> {
        match u {
            0 => Some(DataType::Unknown),
            1 => Some(DataType::Boolean),
            2 => Some(DataType::Byte),
            3 => Some(DataType::Int16),
            4 => Some(DataType::Uint16),
            5 => Some(DataType::Int32),
            6 => Some(DataType::Uint32),
            7 => Some(DataType::Int64),
            8 => Some(DataType::Uint64),
            9 => Some(DataType::String),
            10 => Some(DataType::ByteArray),
            11 => Some(DataType::Int16Array),
            12 => Some(DataType::Uint16Array),
            13 => Some(DataType::Int32Array),
            14 => Some(DataType::Uint32Array),
            15 => Some(DataType::Int64Array),
            16 => Some(DataType::Uint64Array),
            17 => Some(DataType::StringArray),
            18 => Some(DataType::HrTime),
            19 => Some(DataType::NvList),
            20 => Some(DataType::NvListArray),
            21 => Some(DataType::BooleanValue),
            22 => Some(DataType::Int8),
            23 => Some(DataType::Uint8),
            24 => Some(DataType::BooleanArray),
            25 => Some(DataType::Int8Array),
            26 => Some(DataType::Uint8Array),
            _ => None,
        }
    }

    pub fn to_u8(self) -> u8 {
        match self {
            DataType::Unknown => 0,
            DataType::Boolean => 1,
            DataType::Byte => 2,
            DataType::Int16 => 3,
            DataType::Uint16 => 4,
            DataType::Int32 => 5,
            DataType::Uint32 => 6,
            DataType::Int64 => 7,
            DataType::Uint64 => 8,
            DataType::String => 9,
            DataType::ByteArray => 10,
            DataType::Int16Array => 11,
            DataType::Uint16Array => 12,
            DataType::Int32Array => 13,
            DataType::Uint32Array => 14,
            DataType::Int64Array => 15,
            DataType::Uint64Array => 16,
            DataType::StringArray => 17,
            DataType::HrTime => 18,
            DataType::NvList => 19,
            DataType::NvListArray => 20,
            DataType::BooleanValue => 21,
            DataType::Int8 => 22,
            DataType::Uint8 => 23,
            DataType::BooleanArray => 24,
            DataType::Int8Array => 25,
            DataType::Uint8Array => 26,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix: Ignore Broken Pipe errors when writing list<commit_after><|endoftext|>


<commit_before><commit_msg>Implement "Strip comments from a string".<commit_after>// http://rosettacode.org/wiki/Strip_comments_from_a_string

fn strip_comments(str: &str) -> &str {
    let markers = ['#', ';'];
    str.find(markers.as_slice()).map_or(str, |i| str.slice_to(i)).trim_right()
}

#[test]
fn test_strip_comments() {
    let inputs = ["apples, pears # and bananas",
                  "apples, pears ; and bananas",
                  "apples, pears "];
    let output = "apples, pears";

    for &input in inputs.iter() {
        assert_eq!(strip_comments(input), output)
    }
}

#[cfg(not(test))]
fn main() {
    let inputs = ["apples, pears # and bananas",
                  "apples, pears ; and bananas",
                  "apples, pears "];

    for &input in inputs.iter() {
        println!("Input: {}\nStripped: {}", input, strip_comments(input))
    }
}
<|endoftext|>


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

use std::io;

struct Struct {
    r: io::Reader //~ ERROR reference to trait `io::Reader` where a type is expected
}

fn new_struct(r: io::Reader) -> Struct { //~ ERROR reference to trait `io::Reader` where a type is expected
    Struct { r: r }
}

trait Curve {}
enum E {X(Curve)} //~ ERROR reference to trait `Curve` where a type is expected
fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add a run-pass test for linked failure<commit_after>// -*- rust -*-

// error-pattern:1 == 2
use std;
import std::task;
import std::comm::port;
import std::comm::recv;

fn child() { assert (1 == 2); }

fn parent() {
    // Since this task isn't supervised it won't bring down the whole
    // process
    task::unsupervise();
    let p = port::<int>();
    let f = child;
    task::spawn(f);
    let x = recv(p);
}

fn main() {
    let f = parent;
    task::spawn(f);
}<|endoftext|>


<commit_before>use audio::ac97::AC97;
use audio::intelhda::IntelHDA;

use core::cell::UnsafeCell;

use common::debug;

use disk::ahci::Ahci;
use disk::ide::Ide;

use env::Environment;

use network::intel8254x::Intel8254x;
use network::rtl8139::Rtl8139;

use schemes::file::FileScheme;

use usb::ehci::Ehci;
use usb::ohci::Ohci;
use usb::uhci::Uhci;
use usb::xhci::Xhci;

use super::config::PciConfig;
use super::common::class::*;
use super::common::subclass::*;
use super::common::programming_interface::*;
use super::common::vendorid::*;
use super::common::deviceid::*;

/// PCI device
pub unsafe fn pci_device(env: &mut Environment,
                         mut pci: PciConfig,
                         class_id: u8,
                         subclass_id: u8,
                         interface_id: u8,
                         vendor_code: u16,
                         device_code: u16) {
    if class_id == MASS_STORAGE {
        if subclass_id == IDE {
            if let Some(module) = FileScheme::new(Ide::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        } else if subclass_id == SATA && interface_id == AHCI {
            if let Some(module) = FileScheme::new(Ahci::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        }
    } else if class_id == SERIAL_BUS && subclass_id == USB {
        if interface_id == XHCI {
            let base = pci.read(0x10) as usize;

            let mut module = box Xhci {
                pci: pci,
                base: base & 0xFFFFFFF0,
                memory_mapped: base & 1 == 0,
                irq: pci.read(0x3C) as u8 & 0xF,
            };
            module.init();
            env.schemes.push(UnsafeCell::new(module));
        } else if interface_id == EHCI {
            env.schemes.push(UnsafeCell::new(Ehci::new(pci)));
        } else if interface_id == OHCI {
            env.schemes.push(UnsafeCell::new(Ohci::new(pci)));
        } else if interface_id == UHCI {
            env.schemes.push(UnsafeCell::new(Uhci::new(pci)));
        } else {
            debug!("Unknown USB interface version {:X}\n", interface_id);
        }
    } else {
        match (vendor_code, device_code) {
            (REALTEK, RTL8139) => env.schemes.push(UnsafeCell::new(Rtl8139::new(pci))),
            (INTEL, GBE_82540EM) => env.schemes.push(UnsafeCell::new(Intel8254x::new(pci))),
            (INTEL, AC97_82801AA) => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
            (INTEL, AC97_ICH4) => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
            (INTEL, INTELHDA_ICH6) => {
                let base = pci.read(0x10) as usize;
                let mut module = box IntelHDA {
                    pci: pci,
                    base: base & 0xFFFFFFF0,
                    memory_mapped: base & 1 == 0,
                    irq: pci.read(0x3C) as u8 & 0xF,
                };
                module.init();
                env.schemes.push(UnsafeCell::new(module));
            }
            _ => (),
        }
    }
}

/// Initialize PCI session
pub unsafe fn pci_init(env: &mut Environment) {
    for bus in 0..256 {
        for slot in 0..32 {
            for func in 0..8 {
                let mut pci = PciConfig::new(bus as u8, slot as u8, func as u8);
                let id = pci.read(0);

                if (id & 0xFFFF) != 0xFFFF {
                    let class_id = pci.read(8);

                    debug!(" * PCI {}, {}, {}: ID {:X} CL {:X}",
                           bus,
                           slot,
                           func,
                           id,
                           class_id);

                    for i in 0..6 {
                        let bar = pci.read(i * 4 + 0x10);
                        if bar > 0 {
                            debug!(" BAR{}: {:X}", i, bar);

                            pci.write(i * 4 + 0x10, 0xFFFFFFFF);
                            let size = (0xFFFFFFFF - (pci.read(i * 4 + 0x10) & 0xFFFFFFF0)) + 1;
                            pci.write(i * 4 + 0x10, bar);

                            if size > 0 {
                                debug!(" {}", size);
                            }
                        }
                    }

                    debug::dl();

                    pci_device(env,
                               pci,
                               ((class_id >> 24) & 0xFF) as u8,
                               ((class_id >> 16) & 0xFF) as u8,
                               ((class_id >> 8) & 0xFF) as u8,
                               (id & 0xFFFF) as u16,
                               ((id >> 16) & 0xFFFF) as u16);
                }
            }
        }
    }
}
<commit_msg>[PCI binding] Use match instead of if-else sequense<commit_after>use audio::ac97::AC97;
use audio::intelhda::IntelHDA;

use core::cell::UnsafeCell;

use common::debug;

use disk::ahci::Ahci;
use disk::ide::Ide;

use env::Environment;

use network::intel8254x::Intel8254x;
use network::rtl8139::Rtl8139;

use schemes::file::FileScheme;

use usb::ehci::Ehci;
use usb::ohci::Ohci;
use usb::uhci::Uhci;
use usb::xhci::Xhci;

use super::config::PciConfig;
use super::common::class::*;
use super::common::subclass::*;
use super::common::programming_interface::*;
use super::common::vendorid::*;
use super::common::deviceid::*;

/// PCI device
pub unsafe fn pci_device(env: &mut Environment,
                         mut pci: PciConfig,
                         class_id: u8,
                         subclass_id: u8,
                         interface_id: u8,
                         vendor_code: u16,
                         device_code: u16) {
    match (class_id, subclass_id, interface_id) {
        (MASS_STORAGE, IDE, _) => {
            if let Some(module) = FileScheme::new(Ide::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        }
        (MASS_STORAGE, SATA, AHCI) => {
            if let Some(module) = FileScheme::new(Ahci::disks(pci)) {
                env.schemes.push(UnsafeCell::new(module));
            }
        }
        (SERIAL_BUS, USB, UHCI) => env.schemes.push(UnsafeCell::new(Uhci::new(pci))),
        (SERIAL_BUS, USB, OHCI) => env.schemes.push(UnsafeCell::new(Ohci::new(pci))),
        (SERIAL_BUS, USB, EHCI) => env.schemes.push(UnsafeCell::new(Ehci::new(pci))),
        (SERIAL_BUS, USB, XHCI) => {
            let base = pci.read(0x10) as usize;
            let mut module = box Xhci {
                pci: pci,
                base: base & 0xFFFFFFF0,
                memory_mapped: base & 1 == 0,
                irq: pci.read(0x3C) as u8 & 0xF,
            };
            module.init();
            env.schemes.push(UnsafeCell::new(module));
        }
        _ => {
            match (vendor_code, device_code) {
                (REALTEK, RTL8139) => env.schemes.push(UnsafeCell::new(Rtl8139::new(pci))),
                (INTEL, GBE_82540EM) => env.schemes.push(UnsafeCell::new(Intel8254x::new(pci))),
                (INTEL, AC97_82801AA) => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                (INTEL, AC97_ICH4) => env.schemes.push(UnsafeCell::new(AC97::new(pci))),
                (INTEL, INTELHDA_ICH6) => {
                    let base = pci.read(0x10) as usize;
                    let mut module = box IntelHDA {
                        pci: pci,
                        base: base & 0xFFFFFFF0,
                        memory_mapped: base & 1 == 0,
                        irq: pci.read(0x3C) as u8 & 0xF,
                    };
                    module.init();
                    env.schemes.push(UnsafeCell::new(module));
                }
                _ => (),
            }
        }
    }
}

/// Initialize PCI session
pub unsafe fn pci_init(env: &mut Environment) {
    for bus in 0..256 {
        for slot in 0..32 {
            for func in 0..8 {
                let mut pci = PciConfig::new(bus as u8, slot as u8, func as u8);
                let id = pci.read(0);

                if (id & 0xFFFF) != 0xFFFF {
                    let class_id = pci.read(8);

                    debug!(" * PCI {}, {}, {}: ID {:X} CL {:X}",
                           bus,
                           slot,
                           func,
                           id,
                           class_id);

                    for i in 0..6 {
                        let bar = pci.read(i * 4 + 0x10);
                        if bar > 0 {
                            debug!(" BAR{}: {:X}", i, bar);

                            pci.write(i * 4 + 0x10, 0xFFFFFFFF);
                            let size = (0xFFFFFFFF - (pci.read(i * 4 + 0x10) & 0xFFFFFFF0)) + 1;
                            pci.write(i * 4 + 0x10, bar);

                            if size > 0 {
                                debug!(" {}", size);
                            }
                        }
                    }

                    debug::dl();

                    pci_device(env,
                               pci,
                               ((class_id >> 24) & 0xFF) as u8,
                               ((class_id >> 16) & 0xFF) as u8,
                               ((class_id >> 8) & 0xFF) as u8,
                               (id & 0xFFFF) as u16,
                               ((id >> 16) & 0xFFFF) as u16);
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::*;
use redox::io::*;
use redox::env::*;
use redox::time::Duration;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application<'static> = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     main: box|args: &Vec<String>| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command<'a> {
    pub name: &'a str,
    pub main: Box<Fn(&Vec<String>)>,
}

impl<'a> Command<'a> {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();

        commands.push(Command {
            name: "cat",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read: {}", path),
                    }
                } else {
                    println!("Failed to open file: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "cd",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(path) => {
                        if !change_cwd(&path) {
                            println!("Bad path: {}", path);
                        }
                    }
                    None => println!("No path given")
                }
            }),
        });

        commands.push(Command {
            name: "echo",
            main: Box::new(|args: &Vec<String>| {
                let echo = args.iter()
                    .skip(1)
                    .fold(String::new(), |string, arg| string + " " + arg);
                println!("{}", echo.trim());
            }),
        });

        commands.push(Command {
            name: "else",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "exec",
            main: Box::new(|args: &Vec<String>| {
                if let Some(arg) = args.get(1) {
                    File::exec(arg);
                }
            }),
        });

        commands.push(Command {
            name: "exit",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "fi",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "if",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "ls",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(dir) = read_dir(&path) {
                    for entry in dir {
                        println!("{}", entry.path());
                    }
                } else {
                    println!("Failed to open directory: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "pwd",
            main: Box::new(|_: &Vec<String>| {
                if let Some(file) = File::open("") {
                    if let Some(path) = file.path() {
                        println!("{}", path);
                    } else {
                        println!("Could not get the path");
                    }
                } else {
                    println!("Could not open the working directory");
                }
            }),
        });

        commands.push(Command {
            name: "read",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "run",
            main: Box::new(|args: &Vec<String>| {
                if let Some(path) = args.get(1) {

                    let mut commands = String::new();
                    if let Some(mut file) = File::open(path) {
                        file.read_to_string(&mut commands);
                    }

                    for command in commands.split('\n') {
                        exec!(command);
                    }
                }
            }),
        });

        commands.push(Command {
            name: "sleep",
            main: Box::new(|args: &Vec<String>| {
                let secs = {
                    match args.get(1) {
                        Some(arg) => arg.to_num() as i64,
                        None => 0,
                    }
                };

                let nanos = {
                    match args.get(2) {
                        Some(arg) => arg.to_num() as i32,
                        None => 0,
                    }
                };

                println!("Sleep: {} {}", secs, nanos);
                let remaining = Duration::new(secs, nanos).sleep();
                println!("Remaining: {} {}", remaining.secs, remaining.nanos);
            }),
        });

        commands.push(Command {
            name: "send",
            main: Box::new(|args: &Vec<String>| {
                if args.len() < 3 {
                    println!("Error: incorrect arguments");
                    println!("Usage: send [url] [data]");
                    return;
                }

                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    println!("URL: {:?}", file.path());

                    let string: String = args.iter()
                        .skip(2)
                        .fold(String::new(), |s, arg| s + " " + arg)
                        + "\r\n\r\n";

                    match file.write(string.trim_left().as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        // Simple command to create a file, in the current directory
        // The file has got the name given as the first argument of the command
        // If the command have no arguments, the command don't create the file
        commands.push(Command {
            name: "touch",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(file_name) => if File::create(file_name).is_none() {
                        println!("Failed to create: {}", file_name);
                    },
                    None => println!("No name provided")
                }
            }),
        });

        commands.push(Command {
            name: "url_hex",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        commands.push(Command {
            name: "wget",
            main: Box::new(|args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            }),
        });

        let command_list = commands.iter().fold(String::new(), |l , c| l + " " + c.name);

        commands.push(Command {
            name: "help",
            main: Box::new(move |_: &Vec<String>| {
                println!("Commands:{}", command_list);
            }),
         });

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application<'a> {
    commands: Vec<Command<'a>>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl<'a> Application<'a> {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &str) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if command_string == "$" {
            for variable in self.variables.iter() {
                println!("{}={}", variable.name, variable.value);
            }
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if !arg.is_empty() {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        if let Some(cmd) = args.get(0) {
            if cmd == "if" {
                let mut value = false;

                if let Some(left) = args.get(1) {
                    if let Some(cmp) = args.get(2) {
                        if let Some(right) = args.get(3) {
                            if cmp == "==" {
                                value = *left == *right;
                            } else if cmp == "!=" {
                                value = *left != *right;
                            } else if cmp == ">" {
                                value = left.to_num_signed() > right.to_num_signed();
                            } else if cmp == ">=" {
                                value = left.to_num_signed() >= right.to_num_signed();
                            } else if cmp == "<" {
                                value = left.to_num_signed() < right.to_num_signed();
                            } else if cmp == "<=" {
                                value = left.to_num_signed() <= right.to_num_signed();
                            } else {
                                println!("Unknown comparison: {}", cmp);
                            }
                        } else {
                            println!("No right hand side");
                        }
                    } else {
                        println!("No comparison operator");
                    }
                } else {
                    println!("No left hand side");
                }

                self.modes.insert(0, Mode { value: value });
                return;
            }

            if cmd == "else" {
                let mut syntax_error = false;
                match self.modes.get_mut(0) {
                    Some(mode) => mode.value = !mode.value,
                    None => syntax_error = true,
                }
                if syntax_error {
                    println!("Syntax error: else found with no previous if");
                }
                return;
            }

            if cmd == "fi" {
                let mut syntax_error = false;
                if !self.modes.is_empty() {
                    self.modes.remove(0);
                } else {
                    syntax_error = true;
                }
                if syntax_error {
                    println!("Syntax error: fi found with no previous if");
                }
                return;
            }

            for mode in self.modes.iter() {
                if !mode.value {
                    return;
                }
            }

            if cmd == "read" {
                for i in 1..args.len() {
                    if let Some(arg_original) = args.get(i) {
                        let arg = arg_original.trim();
                        print!("{}=", arg);
                        if let Some(value_original) = readln!() {
                            let value = value_original.trim();
                            self.set_var(arg, value);
                        }
                    }
                }
            }

            //Set variables
            if let Some(i) = cmd.find('=') {
                let name = cmd[0 .. i].trim();
                let mut value = cmd[i + 1 .. cmd.len()].trim().to_string();

                for i in 1..args.len() {
                    if let Some(arg) = args.get(i) {
                        value = value + " " + &arg;
                    }
                }

                self.set_var(name, &value);
                return;
            }

            //Commands
            for command in self.commands.iter() {
                if &command.name == cmd {
                    (*command.main)(&args);
                    return;
                }
            }

            println!("Unknown command: '{}'", cmd);
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str){
        if name.is_empty() {
            return;
        }

        if value.is_empty() {
            let mut remove = -1;
            for i in 0..self.variables.len() {
                match self.variables.get(i) {
                    Some(variable) => if variable.name == name {
                        remove = i as isize;
                        break;
                    },
                    None => break,
                }
            }

            if remove >= 0 {
                self.variables.remove(remove as usize);
            }
        } else {
            for variable in self.variables.iter_mut() {
                if variable.name == name {
                    variable.value = value.to_string();
                    return;
                }
            }

            self.variables.push(Variable {
                name: name.to_string(),
                value: value.to_string(),
            });
        }
    }

    /// Method to return the current directory
    /// If the current directory canno't be find, a default string ("?") will be returned
    pub fn get_current_directory(&mut self) -> String {
        if let Some(file) = File::open("") {
            if let Some(path) = file.path() {
                // Return the current path
                return path
            }
        // Return a default string if the path canno't be find
            else {
                return "?".to_string()
            }
        }
        else {
            return "?".to_string()
        }
    }

    /// Run the application
    pub fn main(&mut self) {
        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("user@redox:{}# {}", self.get_current_directory(), command);
            self.on_command(&command);
        }

        loop {
            for mode in self.modes.iter().rev() {
                if mode.value {
                    print!("+ ");
                } else {
                    print!("- ");
                }
            }
            print!("user@redox:{}# ", self.get_current_directory());
            if let Some(command_original) = readln!() {
                let command = command_original.trim();
                if command == "exit" {
                    println!("Exit temporarily blocked (due to using terminal as init)")
                    //break;
                } else if !command.is_empty() {
                    self.on_command(&command);
                }
            } else {
                println!("Failed to read from stdin");
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = Box::new(Application::new());
        application = app.deref_mut();
        app.main();
    }
}
<commit_msg>Rustify get_current_directory<commit_after>use redox::ops::DerefMut;
use redox::string::*;
use redox::vec::Vec;
use redox::boxed::Box;
use redox::fs::*;
use redox::io::*;
use redox::env::*;
use redox::time::Duration;
use redox::to_num::*;

/* Magic Macros { */
static mut application: *mut Application<'static> = 0 as *mut Application;

/// Execute a command
macro_rules! exec {
    ($cmd:expr) => ({
        unsafe {
            (*application).on_command(&$cmd.to_string());
        }
    })
}
/* } Magic Macros */

/// Structure which represents a Terminal's command.
/// This command structure contains a name, and the code which run the functionnality associated to this one, with zero, one or several argument(s).
/// # Example
/// ```
/// let my_command = Command {
///     name: "my_command",
///     main: box|args: &Vec<String>| {
///         println!("Say 'hello' to my command! :-D");
///     }
/// }
/// ```
pub struct Command<'a> {
    pub name: &'a str,
    pub main: Box<Fn(&Vec<String>)>,
}

impl<'a> Command<'a> {
    /// Return the vector of the commands
    // TODO: Use a more efficient collection instead
    pub fn vec() -> Vec<Self> {
        let mut commands: Vec<Self> = Vec::new();

        commands.push(Command {
            name: "cat",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read: {}", path),
                    }
                } else {
                    println!("Failed to open file: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "cd",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(path) => {
                        if !change_cwd(&path) {
                            println!("Bad path: {}", path);
                        }
                    }
                    None => println!("No path given")
                }
            }),
        });

        commands.push(Command {
            name: "echo",
            main: Box::new(|args: &Vec<String>| {
                let echo = args.iter()
                    .skip(1)
                    .fold(String::new(), |string, arg| string + " " + arg);
                println!("{}", echo.trim());
            }),
        });

        commands.push(Command {
            name: "else",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "exec",
            main: Box::new(|args: &Vec<String>| {
                if let Some(arg) = args.get(1) {
                    File::exec(arg);
                }
            }),
        });

        commands.push(Command {
            name: "exit",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "fi",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "if",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "ls",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(dir) = read_dir(&path) {
                    for entry in dir {
                        println!("{}", entry.path());
                    }
                } else {
                    println!("Failed to open directory: {}", path);
                }
            }),
        });

        commands.push(Command {
            name: "pwd",
            main: Box::new(|_: &Vec<String>| {
                if let Some(file) = File::open("") {
                    if let Some(path) = file.path() {
                        println!("{}", path);
                    } else {
                        println!("Could not get the path");
                    }
                } else {
                    println!("Could not open the working directory");
                }
            }),
        });

        commands.push(Command {
            name: "read",
            main: Box::new(|_: &Vec<String>| {}),
        });

        commands.push(Command {
            name: "run",
            main: Box::new(|args: &Vec<String>| {
                if let Some(path) = args.get(1) {

                    let mut commands = String::new();
                    if let Some(mut file) = File::open(path) {
                        file.read_to_string(&mut commands);
                    }

                    for command in commands.split('\n') {
                        exec!(command);
                    }
                }
            }),
        });

        commands.push(Command {
            name: "sleep",
            main: Box::new(|args: &Vec<String>| {
                let secs = {
                    match args.get(1) {
                        Some(arg) => arg.to_num() as i64,
                        None => 0,
                    }
                };

                let nanos = {
                    match args.get(2) {
                        Some(arg) => arg.to_num() as i32,
                        None => 0,
                    }
                };

                println!("Sleep: {} {}", secs, nanos);
                let remaining = Duration::new(secs, nanos).sleep();
                println!("Remaining: {} {}", remaining.secs, remaining.nanos);
            }),
        });

        commands.push(Command {
            name: "send",
            main: Box::new(|args: &Vec<String>| {
                if args.len() < 3 {
                    println!("Error: incorrect arguments");
                    println!("Usage: send [url] [data]");
                    return;
                }

                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    println!("URL: {:?}", file.path());

                    let string: String = args.iter()
                        .skip(2)
                        .fold(String::new(), |s, arg| s + " " + arg)
                        + "\r\n\r\n";

                    match file.write(string.trim_left().as_bytes()) {
                        Some(size) => println!("Wrote {} bytes", size),
                        None => println!("Failed to write"),
                    }

                    let mut string = String::new();
                    match file.read_to_string(&mut string) {
                        Some(_) => println!("{}", string),
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        // Simple command to create a file, in the current directory
        // The file has got the name given as the first argument of the command
        // If the command have no arguments, the command don't create the file
        commands.push(Command {
            name: "touch",
            main: Box::new(|args: &Vec<String>| {
                match args.get(1) {
                    Some(file_name) => if File::create(file_name).is_none() {
                        println!("Failed to create: {}", file_name);
                    },
                    None => println!("No name provided")
                }
            }),
        });

        commands.push(Command {
            name: "url_hex",
            main: Box::new(|args: &Vec<String>| {
                let path = {
                    match args.get(1) {
                        Some(arg) => arg.clone(),
                        None => String::new(),
                    }
                };

                if let Some(mut file) = File::open(&path) {
                    let mut vec: Vec<u8> = Vec::new();
                    match file.read_to_end(&mut vec) {
                        Some(_) => {
                            let mut line = "HEX:".to_string();
                            for byte in vec.iter() {
                                line = line + " " + &format!("{:X}", *byte);
                            }
                            println!("{}", line);
                        }
                        None => println!("Failed to read"),
                    }
                }
            }),
        });

        commands.push(Command {
            name: "wget",
            main: Box::new(|args: &Vec<String>| {
                if let Some(host) = args.get(1) {
                    if let Some(req) = args.get(2) {
                        if let Some(mut con) = File::open(&("tcp://".to_string() + host)) {
                            con.write(("GET ".to_string() + req + " HTTP/1.1").as_bytes());

                            let mut res = Vec::new();
                            con.read_to_end(&mut res);

                            if let Some(mut file) = File::open(&req) {
                                file.write(&res);
                            }
                        }
                    } else {
                        println!("No request given");
                    }
                } else {
                    println!("No url given");
                }
            }),
        });

        let command_list = commands.iter().fold(String::new(), |l , c| l + " " + c.name);

        commands.push(Command {
            name: "help",
            main: Box::new(move |_: &Vec<String>| {
                println!("Commands:{}", command_list);
            }),
         });

        commands
    }
}

/// A (env) variable
pub struct Variable {
    pub name: String,
    pub value: String,
}

pub struct Mode {
    value: bool,
}

/// An application
pub struct Application<'a> {
    commands: Vec<Command<'a>>,
    variables: Vec<Variable>,
    modes: Vec<Mode>,
}

impl<'a> Application<'a> {
    /// Create a new empty application
    pub fn new() -> Self {
        return Application {
            commands: Command::vec(),
            variables: Vec::new(),
            modes: Vec::new(),
        };
    }

    fn on_command(&mut self, command_string: &str) {
        //Comment
        if command_string.starts_with('#') {
            return;
        }

        //Show variables
        if command_string == "$" {
            for variable in self.variables.iter() {
                println!("{}={}", variable.name, variable.value);
            }
            return;
        }

        //Explode into arguments, replace variables
        let mut args: Vec<String> = Vec::<String>::new();
        for arg in command_string.split(' ') {
            if !arg.is_empty() {
                if arg.starts_with('$') {
                    let name = arg[1 .. arg.len()].to_string();
                    for variable in self.variables.iter() {
                        if variable.name == name {
                            args.push(variable.value.clone());
                            break;
                        }
                    }
                } else {
                    args.push(arg.to_string());
                }
            }
        }

        //Execute commands
        if let Some(cmd) = args.get(0) {
            if cmd == "if" {
                let mut value = false;

                if let Some(left) = args.get(1) {
                    if let Some(cmp) = args.get(2) {
                        if let Some(right) = args.get(3) {
                            if cmp == "==" {
                                value = *left == *right;
                            } else if cmp == "!=" {
                                value = *left != *right;
                            } else if cmp == ">" {
                                value = left.to_num_signed() > right.to_num_signed();
                            } else if cmp == ">=" {
                                value = left.to_num_signed() >= right.to_num_signed();
                            } else if cmp == "<" {
                                value = left.to_num_signed() < right.to_num_signed();
                            } else if cmp == "<=" {
                                value = left.to_num_signed() <= right.to_num_signed();
                            } else {
                                println!("Unknown comparison: {}", cmp);
                            }
                        } else {
                            println!("No right hand side");
                        }
                    } else {
                        println!("No comparison operator");
                    }
                } else {
                    println!("No left hand side");
                }

                self.modes.insert(0, Mode { value: value });
                return;
            }

            if cmd == "else" {
                let mut syntax_error = false;
                match self.modes.get_mut(0) {
                    Some(mode) => mode.value = !mode.value,
                    None => syntax_error = true,
                }
                if syntax_error {
                    println!("Syntax error: else found with no previous if");
                }
                return;
            }

            if cmd == "fi" {
                let mut syntax_error = false;
                if !self.modes.is_empty() {
                    self.modes.remove(0);
                } else {
                    syntax_error = true;
                }
                if syntax_error {
                    println!("Syntax error: fi found with no previous if");
                }
                return;
            }

            for mode in self.modes.iter() {
                if !mode.value {
                    return;
                }
            }

            if cmd == "read" {
                for i in 1..args.len() {
                    if let Some(arg_original) = args.get(i) {
                        let arg = arg_original.trim();
                        print!("{}=", arg);
                        if let Some(value_original) = readln!() {
                            let value = value_original.trim();
                            self.set_var(arg, value);
                        }
                    }
                }
            }

            //Set variables
            if let Some(i) = cmd.find('=') {
                let name = cmd[0 .. i].trim();
                let mut value = cmd[i + 1 .. cmd.len()].trim().to_string();

                for i in 1..args.len() {
                    if let Some(arg) = args.get(i) {
                        value = value + " " + &arg;
                    }
                }

                self.set_var(name, &value);
                return;
            }

            //Commands
            for command in self.commands.iter() {
                if &command.name == cmd {
                    (*command.main)(&args);
                    return;
                }
            }

            println!("Unknown command: '{}'", cmd);
        }
    }

    pub fn set_var(&mut self, name: &str, value: &str){
        if name.is_empty() {
            return;
        }

        if value.is_empty() {
            let mut remove = -1;
            for i in 0..self.variables.len() {
                match self.variables.get(i) {
                    Some(variable) => if variable.name == name {
                        remove = i as isize;
                        break;
                    },
                    None => break,
                }
            }

            if remove >= 0 {
                self.variables.remove(remove as usize);
            }
        } else {
            for variable in self.variables.iter_mut() {
                if variable.name == name {
                    variable.value = value.to_string();
                    return;
                }
            }

            self.variables.push(Variable {
                name: name.to_string(),
                value: value.to_string(),
            });
        }
    }

    /// Method to return the current directory
    /// If the current directory cannot be found, a default string ("?") will be returned
    pub fn get_current_directory(&mut self) -> String {
        // Return the current path
        File::open("")
            .and_then(|file| file.path())
            .unwrap_or("?".to_string())
    }

    /// Run the application
    pub fn main(&mut self) {
        println!("Type help for a command list");
        if let Some(arg) = args().get(1) {
            let command = "run ".to_string() + arg;
            println!("user@redox:{}# {}", self.get_current_directory(), command);
            self.on_command(&command);
        }

        loop {
            for mode in self.modes.iter().rev() {
                if mode.value {
                    print!("+ ");
                } else {
                    print!("- ");
                }
            }
            print!("user@redox:{}# ", self.get_current_directory());
            if let Some(command_original) = readln!() {
                let command = command_original.trim();
                if command == "exit" {
                    println!("Exit temporarily blocked (due to using terminal as init)")
                    //break;
                } else if !command.is_empty() {
                    self.on_command(&command);
                }
            } else {
                println!("Failed to read from stdin");
            }
        }
    }
}

pub fn main() {
    unsafe {
        let mut app = Box::new(Application::new());
        application = app.deref_mut();
        app.main();
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove redundant import<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify get_data_for_date by extracting crate filtering.<commit_after><|endoftext|>


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

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Warn,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub UNREACHABLE_PATTERNS,
    Warn,
    "detects unreachable patterns"
}

declare_lint! {
    pub UNUSED_MACROS,
    Warn,
    "detects macros that were not used"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Warn,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
    Deny,
    "detect public reexports of private extern crates"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Deny,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
    Deny,
    "attempt to resolve a trait on an expression whose type cannot be inferred but which \
     currently defaults to ()"
}

declare_lint! {
    pub SAFE_EXTERN_STATICS,
    Deny,
    "safe access to extern statics was erroneously allowed"
}

declare_lint! {
    pub PATTERNS_IN_FNS_WITHOUT_BODY,
    Warn,
    "patterns in functions without body were erroneously allowed"
}

declare_lint! {
    pub EXTRA_REQUIREMENT_IN_IMPL,
    Deny,
    "detects extra requirements in impls that were erroneously allowed"
}

declare_lint! {
    pub LEGACY_DIRECTORY_OWNERSHIP,
    Deny,
    "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
     not named `mod.rs`"
}

declare_lint! {
    pub LEGACY_IMPORTS,
    Deny,
    "detects names that resolve to ambiguous glob imports with RFC 1560"
}

declare_lint! {
    pub LEGACY_CONSTRUCTOR_VISIBILITY,
    Deny,
    "detects use of struct constructors that would be invisible with new visibility rules"
}

declare_lint! {
    pub MISSING_FRAGMENT_SPECIFIER,
    Deny,
    "detects missing fragment specifiers in unused `macro_rules!` patterns"
}

declare_lint! {
    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
    Deny,
    "detects parenthesized generic parameters in type and module names"
}

declare_lint! {
    pub LATE_BOUND_LIFETIME_ARGUMENTS,
    Warn,
    "detects generic lifetime arguments in path segments with late bound lifetime parameters"
}

declare_lint! {
    pub DEPRECATED,
    Warn,
    "detects use of deprecated items"
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            UNREACHABLE_PATTERNS,
            UNUSED_MACROS,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            PUB_USE_OF_PRIVATE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            CONST_ERR,
            RENAMED_AND_REMOVED_LINTS,
            RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
            SAFE_EXTERN_STATICS,
            PATTERNS_IN_FNS_WITHOUT_BODY,
            EXTRA_REQUIREMENT_IN_IMPL,
            LEGACY_DIRECTORY_OWNERSHIP,
            LEGACY_IMPORTS,
            LEGACY_CONSTRUCTOR_VISIBILITY,
            MISSING_FRAGMENT_SPECIFIER,
            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
            LATE_BOUND_LIFETIME_ARGUMENTS,
            DEPRECATED,
            UNUSED_UNSAFE
        )
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
<commit_msg>Auto merge of #44825 - dtolnay:cratelint, r=aturon<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Some lints that are built in to the compiler.
//!
//! These are the built-in lints that are emitted direct in the main
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.

use lint::{LintPass, LateLintPass, LintArray};

declare_lint! {
    pub CONST_ERR,
    Warn,
    "constant evaluation detected erroneous expression"
}

declare_lint! {
    pub UNUSED_IMPORTS,
    Warn,
    "imports that are never used"
}

declare_lint! {
    pub UNUSED_EXTERN_CRATES,
    Allow,
    "extern crates that are never used"
}

declare_lint! {
    pub UNUSED_QUALIFICATIONS,
    Allow,
    "detects unnecessarily qualified names"
}

declare_lint! {
    pub UNKNOWN_LINTS,
    Warn,
    "unrecognized lint attribute"
}

declare_lint! {
    pub UNUSED_VARIABLES,
    Warn,
    "detect variables which are not used in any way"
}

declare_lint! {
    pub UNUSED_ASSIGNMENTS,
    Warn,
    "detect assignments that will never be read"
}

declare_lint! {
    pub DEAD_CODE,
    Warn,
    "detect unused, unexported items"
}

declare_lint! {
    pub UNREACHABLE_CODE,
    Warn,
    "detects unreachable code paths"
}

declare_lint! {
    pub UNREACHABLE_PATTERNS,
    Warn,
    "detects unreachable patterns"
}

declare_lint! {
    pub UNUSED_MACROS,
    Warn,
    "detects macros that were not used"
}

declare_lint! {
    pub WARNINGS,
    Warn,
    "mass-change the level for lints which produce warnings"
}

declare_lint! {
    pub UNUSED_FEATURES,
    Warn,
    "unused or unknown features found in crate-level #[feature] directives"
}

declare_lint! {
    pub STABLE_FEATURES,
    Warn,
    "stable features found in #[feature] directive"
}

declare_lint! {
    pub UNKNOWN_CRATE_TYPES,
    Deny,
    "unknown crate type found in #[crate_type] directive"
}

declare_lint! {
    pub FAT_PTR_TRANSMUTES,
    Allow,
    "detects transmutes of fat pointers"
}

declare_lint! {
    pub TRIVIAL_CASTS,
    Allow,
    "detects trivial casts which could be removed"
}

declare_lint! {
    pub TRIVIAL_NUMERIC_CASTS,
    Allow,
    "detects trivial casts of numeric types which could be removed"
}

declare_lint! {
    pub PRIVATE_IN_PUBLIC,
    Warn,
    "detect private items in public interfaces not caught by the old implementation"
}

declare_lint! {
    pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
    Deny,
    "detect public reexports of private extern crates"
}

declare_lint! {
    pub INVALID_TYPE_PARAM_DEFAULT,
    Deny,
    "type parameter default erroneously allowed in invalid location"
}

declare_lint! {
    pub RENAMED_AND_REMOVED_LINTS,
    Warn,
    "lints that have been renamed or removed"
}

declare_lint! {
    pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
    Deny,
    "attempt to resolve a trait on an expression whose type cannot be inferred but which \
     currently defaults to ()"
}

declare_lint! {
    pub SAFE_EXTERN_STATICS,
    Deny,
    "safe access to extern statics was erroneously allowed"
}

declare_lint! {
    pub PATTERNS_IN_FNS_WITHOUT_BODY,
    Warn,
    "patterns in functions without body were erroneously allowed"
}

declare_lint! {
    pub EXTRA_REQUIREMENT_IN_IMPL,
    Deny,
    "detects extra requirements in impls that were erroneously allowed"
}

declare_lint! {
    pub LEGACY_DIRECTORY_OWNERSHIP,
    Deny,
    "non-inline, non-`#[path]` modules (e.g. `mod foo;`) were erroneously allowed in some files \
     not named `mod.rs`"
}

declare_lint! {
    pub LEGACY_IMPORTS,
    Deny,
    "detects names that resolve to ambiguous glob imports with RFC 1560"
}

declare_lint! {
    pub LEGACY_CONSTRUCTOR_VISIBILITY,
    Deny,
    "detects use of struct constructors that would be invisible with new visibility rules"
}

declare_lint! {
    pub MISSING_FRAGMENT_SPECIFIER,
    Deny,
    "detects missing fragment specifiers in unused `macro_rules!` patterns"
}

declare_lint! {
    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
    Deny,
    "detects parenthesized generic parameters in type and module names"
}

declare_lint! {
    pub LATE_BOUND_LIFETIME_ARGUMENTS,
    Warn,
    "detects generic lifetime arguments in path segments with late bound lifetime parameters"
}

declare_lint! {
    pub DEPRECATED,
    Warn,
    "detects use of deprecated items"
}

declare_lint! {
    pub UNUSED_UNSAFE,
    Warn,
    "unnecessary use of an `unsafe` block"
}

/// Does nothing as a lint pass, but registers some `Lint`s
/// which are used by other parts of the compiler.
#[derive(Copy, Clone)]
pub struct HardwiredLints;

impl LintPass for HardwiredLints {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNUSED_IMPORTS,
            UNUSED_EXTERN_CRATES,
            UNUSED_QUALIFICATIONS,
            UNKNOWN_LINTS,
            UNUSED_VARIABLES,
            UNUSED_ASSIGNMENTS,
            DEAD_CODE,
            UNREACHABLE_CODE,
            UNREACHABLE_PATTERNS,
            UNUSED_MACROS,
            WARNINGS,
            UNUSED_FEATURES,
            STABLE_FEATURES,
            UNKNOWN_CRATE_TYPES,
            FAT_PTR_TRANSMUTES,
            TRIVIAL_CASTS,
            TRIVIAL_NUMERIC_CASTS,
            PRIVATE_IN_PUBLIC,
            PUB_USE_OF_PRIVATE_EXTERN_CRATE,
            INVALID_TYPE_PARAM_DEFAULT,
            CONST_ERR,
            RENAMED_AND_REMOVED_LINTS,
            RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
            SAFE_EXTERN_STATICS,
            PATTERNS_IN_FNS_WITHOUT_BODY,
            EXTRA_REQUIREMENT_IN_IMPL,
            LEGACY_DIRECTORY_OWNERSHIP,
            LEGACY_IMPORTS,
            LEGACY_CONSTRUCTOR_VISIBILITY,
            MISSING_FRAGMENT_SPECIFIER,
            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
            LATE_BOUND_LIFETIME_ARGUMENTS,
            DEPRECATED,
            UNUSED_UNSAFE
        )
    }
}

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for HardwiredLints {}
<|endoftext|>


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

//! Implementation of `std::os` functionality for Windows

#![allow(bad_style)]

use prelude::v1::*;
use os::windows::prelude::*;

use error::Error as StdError;
use ffi::{OsString, OsStr};
use fmt;
use io;
use libc::{c_int, c_void};
use ops::Range;
use os::windows::ffi::EncodeWide;
use path::{self, PathBuf};
use ptr;
use slice;
use sys::{c, cvt};
use sys::handle::Handle;

use super::to_u16s;

pub fn errno() -> i32 {
    unsafe { c::GetLastError() as i32 }
}

/// Gets a detailed string description for the given error number.
pub fn error_string(errnum: i32) -> String {
    // This value is calculated from the macro
    // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
    let langId = 0x0800 as c::DWORD;

    let mut buf = [0 as c::WCHAR; 2048];

    unsafe {
        let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
                                        c::FORMAT_MESSAGE_IGNORE_INSERTS,
                                    ptr::null_mut(),
                                    errnum as c::DWORD,
                                    langId,
                                    buf.as_mut_ptr(),
                                    buf.len() as c::DWORD,
                                    ptr::null()) as usize;
        if res == 0 {
            // Sometimes FormatMessageW can fail e.g. system doesn't like langId,
            let fm_err = errno();
            return format!("OS Error {} (FormatMessageW() returned error {})",
                           errnum, fm_err);
        }

        match String::from_utf16(&buf[..res]) {
            Ok(mut msg) => {
                // Trim trailing CRLF inserted by FormatMessageW
                let len = msg.trim_right().len();
                msg.truncate(len);
                msg
            },
            Err(..) => format!("OS Error {} (FormatMessageW() returned \
                                invalid UTF-16)", errnum),
        }
    }
}

pub struct Env {
    base: c::LPWCH,
    cur: c::LPWCH,
}

impl Iterator for Env {
    type Item = (OsString, OsString);

    fn next(&mut self) -> Option<(OsString, OsString)> {
        loop {
            unsafe {
                if *self.cur == 0 { return None }
                let p = &*self.cur as *const u16;
                let mut len = 0;
                while *p.offset(len) != 0 {
                    len += 1;
                }
                let s = slice::from_raw_parts(p, len as usize);
                self.cur = self.cur.offset(len + 1);

                // Windows allows environment variables to start with an equals
                // symbol (in any other position, this is the separator between
                // variable name and value). Since`s` has at least length 1 at
                // this point (because the empty string terminates the array of
                // environment variables), we can safely slice.
                let pos = match s[1..].iter().position(|&u| u == b'=' as u16).map(|p| p + 1) {
                    Some(p) => p,
                    None => continue,
                };
                return Some((
                    OsStringExt::from_wide(&s[..pos]),
                    OsStringExt::from_wide(&s[pos+1..]),
                ))
            }
        }
    }
}

impl Drop for Env {
    fn drop(&mut self) {
        unsafe { c::FreeEnvironmentStringsW(self.base); }
    }
}

pub fn env() -> Env {
    unsafe {
        let ch = c::GetEnvironmentStringsW();
        if ch as usize == 0 {
            panic!("failure getting env string from OS: {}",
                   io::Error::last_os_error());
        }
        Env { base: ch, cur: ch }
    }
}

pub struct SplitPaths<'a> {
    data: EncodeWide<'a>,
    must_yield: bool,
}

pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
    SplitPaths {
        data: unparsed.encode_wide(),
        must_yield: true,
    }
}

impl<'a> Iterator for SplitPaths<'a> {
    type Item = PathBuf;
    fn next(&mut self) -> Option<PathBuf> {
        // On Windows, the PATH environment variable is semicolon separated.
        // Double quotes are used as a way of introducing literal semicolons
        // (since c:\some;dir is a valid Windows path). Double quotes are not
        // themselves permitted in path names, so there is no way to escape a
        // double quote.  Quoted regions can appear in arbitrary locations, so
        //
        //   c:\foo;c:\som"e;di"r;c:\bar
        //
        // Should parse as [c:\foo, c:\some;dir, c:\bar].
        //
        // (The above is based on testing; there is no clear reference available
        // for the grammar.)

        let must_yield = self.must_yield;
        self.must_yield = false;

        let mut in_progress = Vec::new();
        let mut in_quote = false;
        for b in self.data.by_ref() {
            if b == '"' as u16 {
                in_quote = !in_quote;
            } else if b == ';' as u16 && !in_quote {
                self.must_yield = true;
                break
            } else {
                in_progress.push(b)
            }
        }

        if !must_yield && in_progress.is_empty() {
            None
        } else {
            Some(super::os2path(&in_progress))
        }
    }
}

#[derive(Debug)]
pub struct JoinPathsError;

pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
    where I: Iterator<Item=T>, T: AsRef<OsStr>
{
    let mut joined = Vec::new();
    let sep = b';' as u16;

    for (i, path) in paths.enumerate() {
        let path = path.as_ref();
        if i > 0 { joined.push(sep) }
        let v = path.encode_wide().collect::<Vec<u16>>();
        if v.contains(&(b'"' as u16)) {
            return Err(JoinPathsError)
        } else if v.contains(&sep) {
            joined.push(b'"' as u16);
            joined.extend_from_slice(&v[..]);
            joined.push(b'"' as u16);
        } else {
            joined.extend_from_slice(&v[..]);
        }
    }

    Ok(OsStringExt::from_wide(&joined[..]))
}

impl fmt::Display for JoinPathsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "path segment contains `\"`".fmt(f)
    }
}

impl StdError for JoinPathsError {
    fn description(&self) -> &str { "failed to join paths" }
}

pub fn current_exe() -> io::Result<PathBuf> {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetModuleFileNameW(ptr::null_mut(), buf, sz)
    }, super::os2path)
}

pub fn getcwd() -> io::Result<PathBuf> {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetCurrentDirectoryW(sz, buf)
    }, super::os2path)
}

pub fn chdir(p: &path::Path) -> io::Result<()> {
    let p: &OsStr = p.as_ref();
    let mut p = p.encode_wide().collect::<Vec<_>>();
    p.push(0);

    cvt(unsafe {
        c::SetCurrentDirectoryW(p.as_ptr())
    }).map(|_| ())
}

pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
    let k = try!(to_u16s(k));
    let res = super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
    }, |buf| {
        OsStringExt::from_wide(buf)
    });
    match res {
        Ok(value) => Ok(Some(value)),
        Err(e) => {
            if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND as i32) {
                Ok(None)
            } else {
                Err(e)
            }
        }
    }
}

pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
    let k = try!(to_u16s(k));
    let v = try!(to_u16s(v));

    cvt(unsafe {
        c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
    }).map(|_| ())
}

pub fn unsetenv(n: &OsStr) -> io::Result<()> {
    let v = try!(to_u16s(n));
    cvt(unsafe {
        c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
    }).map(|_| ())
}

pub struct Args {
    range: Range<isize>,
    cur: *mut *mut u16,
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> {
        self.range.next().map(|i| unsafe {
            let ptr = *self.cur.offset(i);
            let mut len = 0;
            while *ptr.offset(len) != 0 { len += 1; }

            // Push it onto the list.
            let ptr = ptr as *const u16;
            let buf = slice::from_raw_parts(ptr, len as usize);
            OsStringExt::from_wide(buf)
        })
    }
    fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.range.len() }
}

impl Drop for Args {
    fn drop(&mut self) {
        // self.cur can be null if CommandLineToArgvW previously failed,
        // but LocalFree ignores NULL pointers
        unsafe { c::LocalFree(self.cur as *mut c_void); }
    }
}

pub fn args() -> Args {
    unsafe {
        let mut nArgs: c_int = 0;
        let lpCmdLine = c::GetCommandLineW();
        let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs);

        // szArcList can be NULL if CommandLinToArgvW failed,
        // but in that case nArgs is 0 so we won't actually
        // try to read a null pointer
        Args { cur: szArgList, range: 0..(nArgs as isize) }
    }
}

pub fn temp_dir() -> PathBuf {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetTempPathW(sz, buf)
    }, super::os2path).unwrap()
}

pub fn home_dir() -> Option<PathBuf> {
    ::env::var_os("HOME").or_else(|| {
        ::env::var_os("USERPROFILE")
    }).map(PathBuf::from).or_else(|| unsafe {
        let me = c::GetCurrentProcess();
        let mut token = ptr::null_mut();
        if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
            return None
        }
        let _handle = Handle::new(token);
        super::fill_utf16_buf(|buf, mut sz| {
            match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
                0 if c::GetLastError() != 0 => 0,
                0 => sz,
                n => n as c::DWORD,
            }
        }, super::os2path).ok()
    })
}

pub fn exit(code: i32) -> ! {
    unsafe { c::ExitProcess(code as c::UINT) }
}
<commit_msg>Auto merge of #31557 - retep998:house-directory, r=alexcrichton<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of `std::os` functionality for Windows

#![allow(bad_style)]

use prelude::v1::*;
use os::windows::prelude::*;

use error::Error as StdError;
use ffi::{OsString, OsStr};
use fmt;
use io;
use libc::{c_int, c_void};
use ops::Range;
use os::windows::ffi::EncodeWide;
use path::{self, PathBuf};
use ptr;
use slice;
use sys::{c, cvt};
use sys::handle::Handle;

use super::to_u16s;

pub fn errno() -> i32 {
    unsafe { c::GetLastError() as i32 }
}

/// Gets a detailed string description for the given error number.
pub fn error_string(errnum: i32) -> String {
    // This value is calculated from the macro
    // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
    let langId = 0x0800 as c::DWORD;

    let mut buf = [0 as c::WCHAR; 2048];

    unsafe {
        let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
                                        c::FORMAT_MESSAGE_IGNORE_INSERTS,
                                    ptr::null_mut(),
                                    errnum as c::DWORD,
                                    langId,
                                    buf.as_mut_ptr(),
                                    buf.len() as c::DWORD,
                                    ptr::null()) as usize;
        if res == 0 {
            // Sometimes FormatMessageW can fail e.g. system doesn't like langId,
            let fm_err = errno();
            return format!("OS Error {} (FormatMessageW() returned error {})",
                           errnum, fm_err);
        }

        match String::from_utf16(&buf[..res]) {
            Ok(mut msg) => {
                // Trim trailing CRLF inserted by FormatMessageW
                let len = msg.trim_right().len();
                msg.truncate(len);
                msg
            },
            Err(..) => format!("OS Error {} (FormatMessageW() returned \
                                invalid UTF-16)", errnum),
        }
    }
}

pub struct Env {
    base: c::LPWCH,
    cur: c::LPWCH,
}

impl Iterator for Env {
    type Item = (OsString, OsString);

    fn next(&mut self) -> Option<(OsString, OsString)> {
        loop {
            unsafe {
                if *self.cur == 0 { return None }
                let p = &*self.cur as *const u16;
                let mut len = 0;
                while *p.offset(len) != 0 {
                    len += 1;
                }
                let s = slice::from_raw_parts(p, len as usize);
                self.cur = self.cur.offset(len + 1);

                // Windows allows environment variables to start with an equals
                // symbol (in any other position, this is the separator between
                // variable name and value). Since`s` has at least length 1 at
                // this point (because the empty string terminates the array of
                // environment variables), we can safely slice.
                let pos = match s[1..].iter().position(|&u| u == b'=' as u16).map(|p| p + 1) {
                    Some(p) => p,
                    None => continue,
                };
                return Some((
                    OsStringExt::from_wide(&s[..pos]),
                    OsStringExt::from_wide(&s[pos+1..]),
                ))
            }
        }
    }
}

impl Drop for Env {
    fn drop(&mut self) {
        unsafe { c::FreeEnvironmentStringsW(self.base); }
    }
}

pub fn env() -> Env {
    unsafe {
        let ch = c::GetEnvironmentStringsW();
        if ch as usize == 0 {
            panic!("failure getting env string from OS: {}",
                   io::Error::last_os_error());
        }
        Env { base: ch, cur: ch }
    }
}

pub struct SplitPaths<'a> {
    data: EncodeWide<'a>,
    must_yield: bool,
}

pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
    SplitPaths {
        data: unparsed.encode_wide(),
        must_yield: true,
    }
}

impl<'a> Iterator for SplitPaths<'a> {
    type Item = PathBuf;
    fn next(&mut self) -> Option<PathBuf> {
        // On Windows, the PATH environment variable is semicolon separated.
        // Double quotes are used as a way of introducing literal semicolons
        // (since c:\some;dir is a valid Windows path). Double quotes are not
        // themselves permitted in path names, so there is no way to escape a
        // double quote.  Quoted regions can appear in arbitrary locations, so
        //
        //   c:\foo;c:\som"e;di"r;c:\bar
        //
        // Should parse as [c:\foo, c:\some;dir, c:\bar].
        //
        // (The above is based on testing; there is no clear reference available
        // for the grammar.)

        let must_yield = self.must_yield;
        self.must_yield = false;

        let mut in_progress = Vec::new();
        let mut in_quote = false;
        for b in self.data.by_ref() {
            if b == '"' as u16 {
                in_quote = !in_quote;
            } else if b == ';' as u16 && !in_quote {
                self.must_yield = true;
                break
            } else {
                in_progress.push(b)
            }
        }

        if !must_yield && in_progress.is_empty() {
            None
        } else {
            Some(super::os2path(&in_progress))
        }
    }
}

#[derive(Debug)]
pub struct JoinPathsError;

pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
    where I: Iterator<Item=T>, T: AsRef<OsStr>
{
    let mut joined = Vec::new();
    let sep = b';' as u16;

    for (i, path) in paths.enumerate() {
        let path = path.as_ref();
        if i > 0 { joined.push(sep) }
        let v = path.encode_wide().collect::<Vec<u16>>();
        if v.contains(&(b'"' as u16)) {
            return Err(JoinPathsError)
        } else if v.contains(&sep) {
            joined.push(b'"' as u16);
            joined.extend_from_slice(&v[..]);
            joined.push(b'"' as u16);
        } else {
            joined.extend_from_slice(&v[..]);
        }
    }

    Ok(OsStringExt::from_wide(&joined[..]))
}

impl fmt::Display for JoinPathsError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        "path segment contains `\"`".fmt(f)
    }
}

impl StdError for JoinPathsError {
    fn description(&self) -> &str { "failed to join paths" }
}

pub fn current_exe() -> io::Result<PathBuf> {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetModuleFileNameW(ptr::null_mut(), buf, sz)
    }, super::os2path)
}

pub fn getcwd() -> io::Result<PathBuf> {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetCurrentDirectoryW(sz, buf)
    }, super::os2path)
}

pub fn chdir(p: &path::Path) -> io::Result<()> {
    let p: &OsStr = p.as_ref();
    let mut p = p.encode_wide().collect::<Vec<_>>();
    p.push(0);

    cvt(unsafe {
        c::SetCurrentDirectoryW(p.as_ptr())
    }).map(|_| ())
}

pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
    let k = try!(to_u16s(k));
    let res = super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
    }, |buf| {
        OsStringExt::from_wide(buf)
    });
    match res {
        Ok(value) => Ok(Some(value)),
        Err(e) => {
            if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND as i32) {
                Ok(None)
            } else {
                Err(e)
            }
        }
    }
}

pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
    let k = try!(to_u16s(k));
    let v = try!(to_u16s(v));

    cvt(unsafe {
        c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
    }).map(|_| ())
}

pub fn unsetenv(n: &OsStr) -> io::Result<()> {
    let v = try!(to_u16s(n));
    cvt(unsafe {
        c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
    }).map(|_| ())
}

pub struct Args {
    range: Range<isize>,
    cur: *mut *mut u16,
}

impl Iterator for Args {
    type Item = OsString;
    fn next(&mut self) -> Option<OsString> {
        self.range.next().map(|i| unsafe {
            let ptr = *self.cur.offset(i);
            let mut len = 0;
            while *ptr.offset(len) != 0 { len += 1; }

            // Push it onto the list.
            let ptr = ptr as *const u16;
            let buf = slice::from_raw_parts(ptr, len as usize);
            OsStringExt::from_wide(buf)
        })
    }
    fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
}

impl ExactSizeIterator for Args {
    fn len(&self) -> usize { self.range.len() }
}

impl Drop for Args {
    fn drop(&mut self) {
        // self.cur can be null if CommandLineToArgvW previously failed,
        // but LocalFree ignores NULL pointers
        unsafe { c::LocalFree(self.cur as *mut c_void); }
    }
}

pub fn args() -> Args {
    unsafe {
        let mut nArgs: c_int = 0;
        let lpCmdLine = c::GetCommandLineW();
        let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs);

        // szArcList can be NULL if CommandLinToArgvW failed,
        // but in that case nArgs is 0 so we won't actually
        // try to read a null pointer
        Args { cur: szArgList, range: 0..(nArgs as isize) }
    }
}

pub fn temp_dir() -> PathBuf {
    super::fill_utf16_buf(|buf, sz| unsafe {
        c::GetTempPathW(sz, buf)
    }, super::os2path).unwrap()
}

pub fn home_dir() -> Option<PathBuf> {
    ::env::var_os("HOME").or_else(|| {
        ::env::var_os("USERPROFILE")
    }).map(PathBuf::from).or_else(|| unsafe {
        let me = c::GetCurrentProcess();
        let mut token = ptr::null_mut();
        if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
            return None
        }
        let _handle = Handle::new(token);
        super::fill_utf16_buf(|buf, mut sz| {
            match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
                0 if c::GetLastError() != c::ERROR_INSUFFICIENT_BUFFER => 0,
                0 => sz,
                _ => sz - 1, // sz includes the null terminator
            }
        }, super::os2path).ok()
    })
}

pub fn exit(code: i32) -> ! {
    unsafe { c::ExitProcess(code as c::UINT) }
}
<|endoftext|>


<commit_before><commit_msg>Add xfail'd test for #6762.<commit_after>//xfail-test

// Creating a stack closure which references an owned pointer and then
// transferring ownership of the owned box before invoking the stack
// closure results in a crash.

fn twice(x: ~uint) -> uint
{
     *x * 2
}

fn invoke(f : &fn() -> uint)
{
     f();
}

fn main()
{
      let x  : ~uint         = ~9;
      let sq : &fn() -> uint = || { *x * *x };

      twice(x);
      invoke(sq);
}<|endoftext|>


<commit_before><commit_msg>fix(version): `from_str` has been deprecated in favor of `parse()`<commit_after><|endoftext|>