<commit_before>use alloc::boxed::Box;

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

pub struct InterruptScheme;

impl KScheme for InterruptScheme {
    fn scheme(&self) -> &str {
        "interrupt"
    }

    fn open(&mut self, _: &Url, _: usize) -> Result<Box<Resource>> {
        let mut string = format!("{:<6}{:<16}{}", "INT", "COUNT", "DESCRIPTION");

        {
            let interrupts = ::env().interrupts.lock();
            for interrupt in 0..interrupts.len() {
                let count = interrupts[interrupt];

                if count > 0 {
                    let description = match interrupt {
                        0x20 => "Programmable Interrupt Timer",
                        0x21 => "Keyboard",
                        0x22 => "Cascade",
                        0x23 => "Serial 2 and 4",
                        0x24 => "Serial 1 and 3",
                        0x25 => "Parallel 2",
                        0x26 => "Floppy",
                        0x27 => "Parallel 1",
                        0x28 => "Realtime Clock",
                        0x29 => "PCI 1",
                        0x2A => "PCI 2",
                        0x2B => "PCI 3",
                        0x2C => "Mouse",
                        0x2D => "Coprocessor",
                        0x2E => "IDE Primary",
                        0x2F => "IDE Secondary",
                        0x80 => "System Call",
                        0x0 => "Divide by zero exception",
                        0x1 => "Debug exception",
                        0x2 => "Non-maskable interrupt",
                        0x3 => "Breakpoint exception",
                        0x4 => "Overflow exception",
                        0x5 => "Bound range exceeded exception",
                        0x6 => "Invalid opcode exception",
                        0x7 => "Device not available exception",
                        0x8 => "Double fault",
                        0xA => "Invalid TSS exception",
                        0xB => "Segment not present exception",
                        0xC => "Stack-segment fault",
                        0xD => "General protection fault",
                        0xE => "Page fault",
                        0x10 => "x87 floating-point exception",
                        0x11 => "Alignment check exception",
                        0x12 => "Machine check exception",
                        0x13 => "SIMD floating-point exception",
                        0x14 => "Virtualization exception",
                        0x1E => "Security exception",
                        _ => "Unknown Interrupt",
                    };

                    string = string + "\n" + &format!("{:<6X}{:<16}{}", interrupt, count, description);
                }
            }
        }

        Ok(box VecResource::new(Url::from_str("interrupt:"), string.into_bytes()))
    }
}
<commit_msg>Correct mispelling of PIT<commit_after>use alloc::boxed::Box;

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

pub struct InterruptScheme;

impl KScheme for InterruptScheme {
    fn scheme(&self) -> &str {
        "interrupt"
    }

    fn open(&mut self, _: &Url, _: usize) -> Result<Box<Resource>> {
        let mut string = format!("{:<6}{:<16}{}", "INT", "COUNT", "DESCRIPTION");

        {
            let interrupts = ::env().interrupts.lock();
            for interrupt in 0..interrupts.len() {
                let count = interrupts[interrupt];

                if count > 0 {
                    let description = match interrupt {
                        0x20 => "Programmable Interval Timer",
                        0x21 => "Keyboard",
                        0x22 => "Cascade",
                        0x23 => "Serial 2 and 4",
                        0x24 => "Serial 1 and 3",
                        0x25 => "Parallel 2",
                        0x26 => "Floppy",
                        0x27 => "Parallel 1",
                        0x28 => "Realtime Clock",
                        0x29 => "PCI 1",
                        0x2A => "PCI 2",
                        0x2B => "PCI 3",
                        0x2C => "Mouse",
                        0x2D => "Coprocessor",
                        0x2E => "IDE Primary",
                        0x2F => "IDE Secondary",
                        0x80 => "System Call",
                        0x0 => "Divide by zero exception",
                        0x1 => "Debug exception",
                        0x2 => "Non-maskable interrupt",
                        0x3 => "Breakpoint exception",
                        0x4 => "Overflow exception",
                        0x5 => "Bound range exceeded exception",
                        0x6 => "Invalid opcode exception",
                        0x7 => "Device not available exception",
                        0x8 => "Double fault",
                        0xA => "Invalid TSS exception",
                        0xB => "Segment not present exception",
                        0xC => "Stack-segment fault",
                        0xD => "General protection fault",
                        0xE => "Page fault",
                        0x10 => "x87 floating-point exception",
                        0x11 => "Alignment check exception",
                        0x12 => "Machine check exception",
                        0x13 => "SIMD floating-point exception",
                        0x14 => "Virtualization exception",
                        0x1E => "Security exception",
                        _ => "Unknown Interrupt",
                    };

                    string = string + "\n" + &format!("{:<6X}{:<16}{}", interrupt, count, description);
                }
            }
        }

        Ok(box VecResource::new(Url::from_str("interrupt:"), string.into_bytes()))
    }
}
<|endoftext|>


<commit_before>use std::io::{mod, fs, File};

use url::Url;

use cargo::util::{process, ProcessBuilder};
use support::UPDATING;
use support::{ResultTest, execs, cargo_dir};
use support::paths;
use support::git::repo;

use hamcrest::assert_that;

fn registry_path() -> Path { paths::root().join("registry") }
fn registry() -> Url { Url::from_file_path(&registry_path()).unwrap() }
fn api_path() -> Path { paths::root().join("api") }
fn api() -> Url { Url::from_file_path(&api_path()).unwrap() }

fn setup() {
    let config = paths::root().join(".cargo/config");
    fs::mkdir_recursive(&config.dir_path(), io::USER_DIR).assert();
    File::create(&config).write_str(format!(r#"
        [registry]
            index = "{reg}"
    "#, reg = registry()).as_slice()).assert();
    fs::mkdir_recursive(&api_path().join("api/v1"), io::USER_DIR).assert();

    repo(&registry_path())
        .file("config.json", format!(r#"{{
            "dl": "{0}",
            "api": "{0}"
        }}"#, api()))
        .build();
}

fn cargo_process(s: &str) -> ProcessBuilder {
    process(cargo_dir().join("cargo")).unwrap().arg(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

test!(simple {
    let crates = api_path().join("api/v1/crates");
    File::create(&crates).write_str(r#"{
        "crates": [{
            "created_at": "2014-11-16T20:17:35Z",
            "description": "Design by contract style assertions for Rust",
            "documentation": null,
            "downloads": 2,
            "homepage": null,
            "id": "hoare",
            "keywords": [],
            "license": null,
            "links": {
                "owners": "/api/v1/crates/hoare/owners",
                "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
                "version_downloads": "/api/v1/crates/hoare/downloads",
                "versions": "/api/v1/crates/hoare/versions"
            },
            "max_version": "0.1.1",
            "name": "hoare",
            "repository": "https://github.com/nick29581/libhoare",
            "updated_at": "2014-11-20T21:49:21Z",
            "versions": null
        }],
        "meta": {
            "total": 1
        }
    }"#).assert();

    assert_that(cargo_process("search").arg("postgres"),
                execs().with_status(0).with_stdout(format!("\
{updating} registry `[..]`
hoare (0.1.1)    Design by contract style assertions for Rust", updating = UPDATING)));
})
<commit_msg>Fix mac nightly builds<commit_after>use std::io::{mod, fs, File};

use url::Url;

use cargo::util::{process, ProcessBuilder};
use support::UPDATING;
use support::{ResultTest, execs, cargo_dir};
use support::paths;
use support::git::repo;

use hamcrest::assert_that;

fn registry_path() -> Path { paths::root().join("registry") }
fn registry() -> Url { Url::from_file_path(&registry_path()).unwrap() }
fn api_path() -> Path { paths::root().join("api") }
fn api() -> Url { Url::from_file_path(&api_path()).unwrap() }

fn setup() {
    let config = paths::root().join(".cargo/config");
    fs::mkdir_recursive(&config.dir_path(), io::USER_DIR).assert();
    File::create(&config).write_str(format!(r#"
        [registry]
            index = "{reg}"
    "#, reg = registry()).as_slice()).assert();
    fs::mkdir_recursive(&api_path().join("api/v1"), io::USER_DIR).assert();

    repo(&registry_path())
        .file("config.json", format!(r#"{{
            "dl": "{0}",
            "api": "{0}"
        }}"#, api()))
        .build();
}

fn cargo_process(s: &str) -> ProcessBuilder {
    process(cargo_dir().join("cargo")).unwrap().arg(s)
        .cwd(paths::root())
        .env("HOME", Some(paths::home()))
}

test!(simple {
    let contents = r#"{
        "crates": [{
            "created_at": "2014-11-16T20:17:35Z",
            "description": "Design by contract style assertions for Rust",
            "documentation": null,
            "downloads": 2,
            "homepage": null,
            "id": "hoare",
            "keywords": [],
            "license": null,
            "links": {
                "owners": "/api/v1/crates/hoare/owners",
                "reverse_dependencies": "/api/v1/crates/hoare/reverse_dependencies",
                "version_downloads": "/api/v1/crates/hoare/downloads",
                "versions": "/api/v1/crates/hoare/versions"
            },
            "max_version": "0.1.1",
            "name": "hoare",
            "repository": "https://github.com/nick29581/libhoare",
            "updated_at": "2014-11-20T21:49:21Z",
            "versions": null
        }],
        "meta": {
            "total": 1
        }
    }"#;
    let base = api_path().join("api/v1/crates");

    // Older versions of curl don't peel off query parameters when looking for
    // filenames, so just make both files.
    //
    // On windows, though, `?` is an invalid character, but we always build curl
    // from source there anyway!
    File::create(&base).write_str(contents).unwrap();
    if !cfg!(windows) {
        File::create(&base.with_filename("crates?q=postgres"))
             .write_str(contents).unwrap();
    }

    assert_that(cargo_process("search").arg("postgres"),
                execs().with_status(0).with_stdout(format!("\
{updating} registry `[..]`
hoare (0.1.1)    Design by contract style assertions for Rust", updating = UPDATING)));
})
<|endoftext|>


<commit_before>//! Array type node attribute.

use std::fmt;
use std::marker::PhantomData;
use std::io;
use std::io::Read;
#[cfg(feature = "flate2")]
use flate2::read::ZlibDecoder;
#[cfg(feature = "libflate")]
use libflate::zlib;

use parser::binary::BinaryParser;
use parser::binary::error::{Result, Error, Warning};
use parser::binary::reader::{ParserSource, ReadLittleEndian};

/// Read array type attribute from the given parser.
pub fn read_array_attribute<R: ParserSource>(
    parser: &mut BinaryParser<R>,
    type_code: u8
) -> Result<(ArrayAttribute<R>, u64)> {
    let header = ArrayAttributeHeader::read_from_parser(parser)?;
    let current_pos = parser.source.position();
    let BinaryParser { ref mut source, ref mut warnings, .. } = *parser;
    let reader = ArrayDecoder::new(source, &header)?;

    let value = match type_code {
        b'b' => ArrayAttribute::Bool(ArrayAttributeReader::new(&header, reader, warnings)),
        b'i' => ArrayAttribute::I32(ArrayAttributeReader::new(&header, reader, warnings)),
        b'l' => ArrayAttribute::I64(ArrayAttributeReader::new(&header, reader, warnings)),
        b'f' => ArrayAttribute::F32(ArrayAttributeReader::new(&header, reader, warnings)),
        b'd' => ArrayAttribute::F64(ArrayAttributeReader::new(&header, reader, warnings)),
        _ => unreachable!(),
    };
    Ok((value, current_pos + header.bytelen_elements as u64))
}

/// Header of an array attribute.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
struct ArrayAttributeHeader {
    /// Number of elements.
    num_elements: u32,
    /// Array encoding, i.e. compression method.
    encoding: u32,
    /// Length of the array (excluding this header) in bytes.
    bytelen_elements: u32,
}

impl ArrayAttributeHeader {
    fn read_from_parser<R: ParserSource>(parser: &mut BinaryParser<R>) -> io::Result<Self> {
        let num_elements = parser.source.read_u32()?;
        let encoding = parser.source.read_u32()?;
        let bytelen_elements = parser.source.read_u32()?;

        Ok(ArrayAttributeHeader {
            num_elements: num_elements,
            encoding: encoding,
            bytelen_elements: bytelen_elements,
        })
    }
}

/// Array type attribute.
#[derive(Debug)]
pub enum ArrayAttribute<'a, R: 'a> {
    /// Array of `bool`.
    Bool(ArrayAttributeReader<'a, R, bool>),
    /// Array of `i32`.
    I32(ArrayAttributeReader<'a, R, i32>),
    /// Array of `i64`.
    I64(ArrayAttributeReader<'a, R, i64>),
    /// Array of `f32`.
    F32(ArrayAttributeReader<'a, R, f32>),
    /// Array of `f64`.
    F64(ArrayAttributeReader<'a, R, f64>),
}

/// Reader of array attribute elements.
#[derive(Debug)]
pub struct ArrayAttributeReader<'a, R: 'a, T> {
    num_elements: u64,
    rest_elements: u64,
    reader: ArrayDecoder<'a, R>,
    warnings: &'a mut Vec<Warning>,
    _value_type: PhantomData<T>,
}

impl<'a, R: 'a + Read, T> ArrayAttributeReader<'a, R, T> {
    fn new<'b>(
        header: &'b ArrayAttributeHeader,
        reader: ArrayDecoder<'a, R>,
        warnings: &'a mut Vec<Warning>
    ) -> Self {
        ArrayAttributeReader {
            num_elements: header.num_elements as u64,
            rest_elements: header.num_elements as u64,
            reader: reader,
            warnings: warnings,
            _value_type: PhantomData,
        }
    }

    /// Returns number of elements.
    pub fn num_elements(&self) -> u64 {
        self.num_elements
    }

    /// Returns number of rest elements.
    pub fn rest_elements(&self) -> u64 {
        self.num_elements
    }
}

impl<'a, R: 'a + Read> ArrayAttributeReader<'a, R, bool> {
    /// Reads elements into the given buffer.
    pub fn read_into_buf(&mut self, buf: &mut [bool]) -> io::Result<usize> {
        let size = ::std::cmp::min(buf.len(), self.rest_elements as usize);
        for elem in &mut buf[0..size] {
            self.rest_elements -= 1;
            *elem = (self.reader.read_u8()? & 1) == 1;
        }
        Ok(size)
    }

    /// Reads all elements into `Vec`.
    pub fn into_vec(mut self) -> io::Result<Vec<bool>> {
        let mut vec = vec![false; self.rest_elements as usize];
        self.read_into_buf(&mut vec[..])?;
        Ok(vec)
    }
}

macro_rules! impl_attr_array_read {
    ($ty:ty, $f:ident) => {
        impl<'a, R: 'a + Read> ArrayAttributeReader<'a, R, $ty> {
            /// Reads elements into the given buffer.
            pub fn read_into_buf(&mut self, buf: &mut [$ty]) -> io::Result<usize> {
                let size = ::std::cmp::min(buf.len(), self.rest_elements as usize);
                self.rest_elements -= size as u64;
                self.reader.$f(&mut buf[0..size])?;
                Ok(size)
            }

            /// Reads all elements into `Vec`.
            pub fn into_vec(mut self) -> io::Result<Vec<$ty>> {
                let mut vec = vec![0 as $ty; self.rest_elements as usize];
                self.read_into_buf(&mut vec[..])?;
                Ok(vec)
            }
        }
    }
}

impl_attr_array_read!(i32, read_i32_arr);
impl_attr_array_read!(i64, read_i64_arr);
impl_attr_array_read!(f32, read_f32_arr);
impl_attr_array_read!(f64, read_f64_arr);

impl<'a, R: 'a + Read> Iterator for ArrayAttributeReader<'a, R, bool> {
    type Item = io::Result<bool>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.rest_elements == 0 {
            return None;
        }
        self.rest_elements -= 1;
        let raw = match self.reader.read_u8() {
            Ok(val) => val,
            Err(err) => return Some(Err(err)),
        };
        let val = (raw & 1) == 1;
        Some(Ok(val))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.rest_elements as usize, Some(self.rest_elements as usize))
    }

    fn count(self) -> usize {
        self.rest_elements as usize
    }
}

macro_rules! impl_attr_array_iter {
    ($ty:ty, $f:ident) => {
        impl<'a, R: 'a + Read> Iterator for ArrayAttributeReader<'a, R, $ty> {
            type Item = io::Result<$ty>;

            fn next(&mut self) -> Option<Self::Item> {
                if self.rest_elements == 0 {
                    return None;
                }
                self.rest_elements -= 1;
                Some(self.reader.$f())
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.rest_elements as usize, Some(self.rest_elements as usize))
            }

            fn count(self) -> usize {
                self.rest_elements as usize
            }
        }
    }
}

impl_attr_array_iter!(i32, read_i32);
impl_attr_array_iter!(i64, read_i64);
impl_attr_array_iter!(f32, read_f32);
impl_attr_array_iter!(f64, read_f64);

/// Attribute array decoder.
enum ArrayDecoder<'a, R: 'a> {
    /// Non-compressed stream.
    ///
    /// `encoding` == 0.
    Raw(io::Take<&'a mut R>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "flate2")]
    Zlib(ZlibDecoder<io::Take<&'a mut R>>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "libflate")]
    Zlib(zlib::Decoder<io::Take<&'a mut R>>),
}

impl<'a, R: 'a + Read> ArrayDecoder<'a, R> {
    fn new(reader: &'a mut R, header: &ArrayAttributeHeader) -> Result<Self> {
        match header.encoding {
            0 => Ok(ArrayDecoder::Raw(reader.take(header.bytelen_elements as u64))),
            #[cfg(feature = "flate2")]
            1 => Ok(ArrayDecoder::Zlib(ZlibDecoder::new(reader.take(header.bytelen_elements as u64)))),
            #[cfg(feature = "libflate")]
            1 => Ok(ArrayDecoder::Zlib(zlib::Decoder::new(reader.take(header.bytelen_elements as u64))?)),
            _ => Err(Error::UnknownArrayAttributeEncoding(header.encoding)),
        }
    }
}

impl<'a, R: 'a + Read> Read for ArrayDecoder<'a, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            ArrayDecoder::Raw(ref mut reader) => reader.read(buf),
            #[cfg(feature = "flate2")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
            #[cfg(feature = "libflate")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
        }
    }
}

impl<'a, R: 'a> fmt::Debug for ArrayDecoder<'a, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "ArrayDecoder::{}",
               match *self {
                   ArrayDecoder::Raw(_) => "Raw",
                   #[cfg(feature = "flate2")]
                   ArrayDecoder::Zlib(_) => "Zlib",
                   #[cfg(feature = "libflate")]
                   ArrayDecoder::Zlib(_) => "Zlib",
               })
    }
}
<commit_msg>Specify return value of the method<commit_after>//! Array type node attribute.

use std::fmt;
use std::marker::PhantomData;
use std::io;
use std::io::Read;
#[cfg(feature = "flate2")]
use flate2::read::ZlibDecoder;
#[cfg(feature = "libflate")]
use libflate::zlib;

use parser::binary::BinaryParser;
use parser::binary::error::{Result, Error, Warning};
use parser::binary::reader::{ParserSource, ReadLittleEndian};

/// Read array type attribute from the given parser.
pub fn read_array_attribute<R: ParserSource>(
    parser: &mut BinaryParser<R>,
    type_code: u8
) -> Result<(ArrayAttribute<R>, u64)> {
    let header = ArrayAttributeHeader::read_from_parser(parser)?;
    let current_pos = parser.source.position();
    let BinaryParser { ref mut source, ref mut warnings, .. } = *parser;
    let reader = ArrayDecoder::new(source, &header)?;

    let value = match type_code {
        b'b' => ArrayAttribute::Bool(ArrayAttributeReader::new(&header, reader, warnings)),
        b'i' => ArrayAttribute::I32(ArrayAttributeReader::new(&header, reader, warnings)),
        b'l' => ArrayAttribute::I64(ArrayAttributeReader::new(&header, reader, warnings)),
        b'f' => ArrayAttribute::F32(ArrayAttributeReader::new(&header, reader, warnings)),
        b'd' => ArrayAttribute::F64(ArrayAttributeReader::new(&header, reader, warnings)),
        _ => unreachable!(),
    };
    Ok((value, current_pos + header.bytelen_elements as u64))
}

/// Header of an array attribute.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
struct ArrayAttributeHeader {
    /// Number of elements.
    num_elements: u32,
    /// Array encoding, i.e. compression method.
    encoding: u32,
    /// Length of the array (excluding this header) in bytes.
    bytelen_elements: u32,
}

impl ArrayAttributeHeader {
    fn read_from_parser<R: ParserSource>(parser: &mut BinaryParser<R>) -> io::Result<Self> {
        let num_elements = parser.source.read_u32()?;
        let encoding = parser.source.read_u32()?;
        let bytelen_elements = parser.source.read_u32()?;

        Ok(ArrayAttributeHeader {
            num_elements: num_elements,
            encoding: encoding,
            bytelen_elements: bytelen_elements,
        })
    }
}

/// Array type attribute.
#[derive(Debug)]
pub enum ArrayAttribute<'a, R: 'a> {
    /// Array of `bool`.
    Bool(ArrayAttributeReader<'a, R, bool>),
    /// Array of `i32`.
    I32(ArrayAttributeReader<'a, R, i32>),
    /// Array of `i64`.
    I64(ArrayAttributeReader<'a, R, i64>),
    /// Array of `f32`.
    F32(ArrayAttributeReader<'a, R, f32>),
    /// Array of `f64`.
    F64(ArrayAttributeReader<'a, R, f64>),
}

/// Reader of array attribute elements.
#[derive(Debug)]
pub struct ArrayAttributeReader<'a, R: 'a, T> {
    num_elements: u64,
    rest_elements: u64,
    reader: ArrayDecoder<'a, R>,
    warnings: &'a mut Vec<Warning>,
    _value_type: PhantomData<T>,
}

impl<'a, R: 'a + Read, T> ArrayAttributeReader<'a, R, T> {
    fn new<'b>(
        header: &'b ArrayAttributeHeader,
        reader: ArrayDecoder<'a, R>,
        warnings: &'a mut Vec<Warning>
    ) -> Self {
        ArrayAttributeReader {
            num_elements: header.num_elements as u64,
            rest_elements: header.num_elements as u64,
            reader: reader,
            warnings: warnings,
            _value_type: PhantomData,
        }
    }

    /// Returns number of elements.
    pub fn num_elements(&self) -> u64 {
        self.num_elements
    }

    /// Returns number of rest elements.
    pub fn rest_elements(&self) -> u64 {
        self.num_elements
    }
}

impl<'a, R: 'a + Read> ArrayAttributeReader<'a, R, bool> {
    /// Reads elements into the given buffer and returns the read byte length.
    pub fn read_into_buf(&mut self, buf: &mut [bool]) -> io::Result<usize> {
        let size = ::std::cmp::min(buf.len(), self.rest_elements as usize);
        for elem in &mut buf[0..size] {
            self.rest_elements -= 1;
            *elem = (self.reader.read_u8()? & 1) == 1;
        }
        Ok(size)
    }

    /// Reads all elements into `Vec`.
    pub fn into_vec(mut self) -> io::Result<Vec<bool>> {
        let mut vec = vec![false; self.rest_elements as usize];
        self.read_into_buf(&mut vec[..])?;
        Ok(vec)
    }
}

macro_rules! impl_attr_array_read {
    ($ty:ty, $f:ident) => {
        impl<'a, R: 'a + Read> ArrayAttributeReader<'a, R, $ty> {
            /// Reads elements into the given buffer and returns the read byte length.
            pub fn read_into_buf(&mut self, buf: &mut [$ty]) -> io::Result<usize> {
                let size = ::std::cmp::min(buf.len(), self.rest_elements as usize);
                self.rest_elements -= size as u64;
                self.reader.$f(&mut buf[0..size])?;
                Ok(size)
            }

            /// Reads all elements into `Vec`.
            pub fn into_vec(mut self) -> io::Result<Vec<$ty>> {
                let mut vec = vec![0 as $ty; self.rest_elements as usize];
                self.read_into_buf(&mut vec[..])?;
                Ok(vec)
            }
        }
    }
}

impl_attr_array_read!(i32, read_i32_arr);
impl_attr_array_read!(i64, read_i64_arr);
impl_attr_array_read!(f32, read_f32_arr);
impl_attr_array_read!(f64, read_f64_arr);

impl<'a, R: 'a + Read> Iterator for ArrayAttributeReader<'a, R, bool> {
    type Item = io::Result<bool>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.rest_elements == 0 {
            return None;
        }
        self.rest_elements -= 1;
        let raw = match self.reader.read_u8() {
            Ok(val) => val,
            Err(err) => return Some(Err(err)),
        };
        let val = (raw & 1) == 1;
        Some(Ok(val))
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.rest_elements as usize, Some(self.rest_elements as usize))
    }

    fn count(self) -> usize {
        self.rest_elements as usize
    }
}

macro_rules! impl_attr_array_iter {
    ($ty:ty, $f:ident) => {
        impl<'a, R: 'a + Read> Iterator for ArrayAttributeReader<'a, R, $ty> {
            type Item = io::Result<$ty>;

            fn next(&mut self) -> Option<Self::Item> {
                if self.rest_elements == 0 {
                    return None;
                }
                self.rest_elements -= 1;
                Some(self.reader.$f())
            }

            fn size_hint(&self) -> (usize, Option<usize>) {
                (self.rest_elements as usize, Some(self.rest_elements as usize))
            }

            fn count(self) -> usize {
                self.rest_elements as usize
            }
        }
    }
}

impl_attr_array_iter!(i32, read_i32);
impl_attr_array_iter!(i64, read_i64);
impl_attr_array_iter!(f32, read_f32);
impl_attr_array_iter!(f64, read_f64);

/// Attribute array decoder.
enum ArrayDecoder<'a, R: 'a> {
    /// Non-compressed stream.
    ///
    /// `encoding` == 0.
    Raw(io::Take<&'a mut R>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "flate2")]
    Zlib(ZlibDecoder<io::Take<&'a mut R>>),
    /// Zlib-compressed stream.
    ///
    /// `encoding` == 1.
    #[cfg(feature = "libflate")]
    Zlib(zlib::Decoder<io::Take<&'a mut R>>),
}

impl<'a, R: 'a + Read> ArrayDecoder<'a, R> {
    fn new(reader: &'a mut R, header: &ArrayAttributeHeader) -> Result<Self> {
        match header.encoding {
            0 => Ok(ArrayDecoder::Raw(reader.take(header.bytelen_elements as u64))),
            #[cfg(feature = "flate2")]
            1 => Ok(ArrayDecoder::Zlib(ZlibDecoder::new(reader.take(header.bytelen_elements as u64)))),
            #[cfg(feature = "libflate")]
            1 => Ok(ArrayDecoder::Zlib(zlib::Decoder::new(reader.take(header.bytelen_elements as u64))?)),
            _ => Err(Error::UnknownArrayAttributeEncoding(header.encoding)),
        }
    }
}

impl<'a, R: 'a + Read> Read for ArrayDecoder<'a, R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            ArrayDecoder::Raw(ref mut reader) => reader.read(buf),
            #[cfg(feature = "flate2")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
            #[cfg(feature = "libflate")]
            ArrayDecoder::Zlib(ref mut reader) => reader.read(buf),
        }
    }
}

impl<'a, R: 'a> fmt::Debug for ArrayDecoder<'a, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "ArrayDecoder::{}",
               match *self {
                   ArrayDecoder::Raw(_) => "Raw",
                   #[cfg(feature = "flate2")]
                   ArrayDecoder::Zlib(_) => "Zlib",
                   #[cfg(feature = "libflate")]
                   ArrayDecoder::Zlib(_) => "Zlib",
               })
    }
}
<|endoftext|>


<commit_before>extern crate rtlsdr;

use std::os::raw::{c_void, c_uchar};
use std::ptr;
use rtlsdr::Error;
use std::time::Duration;
use std::thread;

fn sdr_config(dev: &rtlsdr::Device) -> Error {
    let (m, p, s, mut err) = dev.get_usb_strings();
    match err {
        Error::NoError => println!("set_xtal_freq successful"),
        _ => return err,
    };
    println!("m: {}\n p: {}\n s: {}\n err: {:?}\n", m, p, s, err);

    // ---------- Get/Set/Get Hardware Info ----------
    println!("1. Getting hardware info...");
    let (mut hw_info, mut err) = dev.get_hw_info();

    println!("Error: {:?}", err);
    println!("Vendor ID:             {:?}", hw_info.vendor_id);
    println!("Product ID:            {:?}", hw_info.product_id);
    println!("Manufacturer:          {:?}", hw_info.manufact);
    println!("Product:               {:?}", hw_info.product);
    println!("Serial number:         {:?}", hw_info.serial);
    println!("Serial number enabled: {:?}", hw_info.have_serial);
    println!("IR endpoint enabled:   {:?}", hw_info.enable_ir);
    println!("Remote wakeup enabled: {:?}", hw_info.remote_wakeup);
    println!("");

    println!("Writing hardware info...");
    err = dev.set_hw_info(&hw_info);
    println!("Writing hardware info return message: {:?}\n", err);

    println!("2. Getting hardware info...");
    let (hw_info, mut err) = dev.get_hw_info();

    println!("Error: {:?}", err);
    println!("Vendor ID:             {:?}", hw_info.vendor_id);
    println!("Product ID:            {:?}", hw_info.product_id);
    println!("Manufacturer:          {:?}", hw_info.manufact);
    println!("Product:               {:?}", hw_info.product);
    println!("Serial number:         {:?}", hw_info.serial);
    println!("Serial number enabled: {:?}", hw_info.have_serial);
    println!("IR endpoint enabled:   {:?}", hw_info.enable_ir);
    println!("Remote wakeup enabled: {:?}", hw_info.remote_wakeup);
    println!("");

    // ---------- Get Tuner Gain ----------
    println!("get_tuner_type: {}", dev.get_tuner_type());
    err = dev.set_xtal_freq(28800000, 28800000);
    match err {
        Error::NoError => println!("set_xtal_freq - 28800000"),
        _ => return err,
    };
    println!("");

    // ---------- Set Tuner Gain ----------
    err = dev.set_tuner_gain_mode(true);
    match err {
        Error::NoError => println!("set_tuner_gain_mode successful..."),
        _ => return err,
    };

    let (gains, mut err) = dev.get_tuner_gains();
    match err {
        Error::NoError => println!("get_tuner_gains successful..."),
        _ => println!("get_tuner_gains failed - {:?}", err), // return err,
    };

    println!("\ntuner gains:  {:?}\n", gains);

    err = dev.set_tuner_gain(gains[2]);
    match err {
        Error::NoError => println!("set_tuner_gain {:?} successful...", gains[2]),
        _ => return err,
    };
    println!("");

    // ---------- Get/Set Sample Rate ----------
    let samplerate: i32 = 2083334;
    err = dev.set_sample_rate(samplerate);
    match err {
        Error::NoError => println!("set_sample_rate {} successful...", samplerate),
        _ => return err,
    };

    println!("get_sample_rate {} successful...\n", dev.get_sample_rate());

    // ---------- Get/Set Xtal Freq ----------
    let (mut rtl_freq, mut tuner_freq, mut err) = dev.get_xtal_freq();
    match err {
        Error::NoError => {
            println!("get_xtal_freq successful - rtl_freq: {}, tuner_freq: {}",
                     rtl_freq,
                     tuner_freq)
        }
        _ => return err,
    };

    rtl_freq = 28800000;
    tuner_freq = 28800000;

    err = dev.set_xtal_freq(rtl_freq, tuner_freq);
    match err {
        Error::NoError => {
            println!("set_xtal_freq successful - rtl_freq: {}, tuner_freq: {}",
                     rtl_freq,
                     tuner_freq)
        }
        _ => return err,
    };
    println!("");

    // ---------- Get/Set Center Freq ----------
    err = dev.set_center_freq(978000000);
    match err {
        Error::NoError => println!("set_center_freq successful - 978000000"),
        _ => return err,
    };

    println!("get_center_freq: {}\n", dev.get_center_freq());

    // ---------- Set Tuner Bandwidth ----------
    let bw: i32 = 1000000;
    println!("Setting bandwidth: {}", bw);

    err = dev.set_tuner_bandwidth(bw);
    match err {
        Error::NoError => println!("set_tuner_bandwidth {} Successful", bw),
        _ => return err,
    };
    println!("");

    // ---------- Buffer Reset ----------
    err = dev.reset_buffer();
    match err {
        Error::NoError => println!("reset_buffer successful..."),
        _ => return err,
    };

    // ---------- Get/Set Freq Correction ----------
    let mut freq_corr = dev.get_freq_correction();
    println!("get_freq_correction - {}", freq_corr);

    freq_corr += 1;
    let err = dev.set_freq_correction(freq_corr);
    match err {
        Error::NoError => println!("set_freq_correction successful - {}", freq_corr),
        _ => return err,
    };
    println!("");
    // ----------  ----------
    Error::NoError
}

unsafe extern "C" fn read_async_callback(buf: *mut c_uchar, len: u32, ctx: *mut c_void) {
    let _ = ctx;
    let v = Vec::<u8>::from_raw_parts(buf, len as usize, len as usize);
    println!("----- read_async_callback buffer size - {}", len);
    println!("----- {} {} {} {} {} {}",
             v[0],
             v[1],
             v[2],
             v[3],
             v[4],
             v[5]);
}

fn main() {
    // ---------- Device Check ----------
    let count = rtlsdr::get_device_count();
    if count == 0 {
        println!("No devices found, exiting.");
        return;
    }

    for i in 0..count {
        let (m, p, s, err) = rtlsdr::get_device_usb_strings(i);
        println!("get_device_usb_strings: {:?} - {} {} {}", err, m, p, s);
    }

    let index = 0;
    println!("===== Device name, index {}: {} =====",
             index,
             rtlsdr::get_device_name(0));
    println!("===== Running tests using device indx: 0 =====\n");

    let (dev, mut err) = rtlsdr::open(index);
    match err {
        Error::NoError => println!("open successful"),
        _ => return,
    }

    err = sdr_config(&dev);
    match err {
        Error::NoError => println!("sdr_config successful..."),
        _ => return,
    }

    println!("calling read_sync...");
    for i in 0..10 {
        let (_, read_count, err) = dev.read_sync(rtlsdr::DEFAULT_BUF_LENGTH);
        println!("----- read_sync requested iteration {} -----", i);
        println!("\tread_sync requested - {}", rtlsdr::DEFAULT_BUF_LENGTH);
        println!("\tread_sync received  - {}", read_count);
        println!("\tread_sync err msg   - {:?}", err);
    }

    dev.reset_buffer();

    // read_async is a blocking call and doesn't return until
    // async_stop is called , so we spawn a thread that sleeps
    // for a bit while our async callback is called...
    let d = dev.clone();
    thread::spawn(move || {
        println!("async_stop thread sleeping for 5 seconds...");
        thread::sleep(Duration::from_millis(5000));
        println!("async_stop thread awake, canceling read async...");
        d.cancel_async();
    });

    println!("calling read_async...");
    err = dev.read_async(Some(read_async_callback),
                         ptr::null_mut(),
                         rtlsdr::DEFAULT_ASYNC_BUF_NUMBER,
                         rtlsdr::DEFAULT_BUF_LENGTH);
    match err {
        Error::NoError => println!("device close successful..."),
        _ => println!("dev close error - {:?}", err),
    }

    err = dev.close();
    match err {
        Error::NoError => println!("device close successful..."),
        _ => println!("dev close error - {:?}", err),
    }
}
<commit_msg>allow unused mut in example<commit_after>extern crate rtlsdr;

use std::os::raw::{c_void, c_uchar};
use std::ptr;
use rtlsdr::Error;
use std::time::Duration;
use std::thread;

#[allow(unused_mut)]
fn sdr_config(dev: &rtlsdr::Device) -> Error {
    let (m, p, s, mut err) = dev.get_usb_strings();
    match err {
        Error::NoError => println!("set_xtal_freq successful"),
        _ => return err,
    };
    println!("m: {}\n p: {}\n s: {}\n err: {:?}\n", m, p, s, err);

    // ---------- Get/Set/Get Hardware Info ----------
    println!("1. Getting hardware info...");
    let (mut hw_info, mut err) = dev.get_hw_info();

    println!("Error: {:?}", err);
    println!("Vendor ID:             {:?}", hw_info.vendor_id);
    println!("Product ID:            {:?}", hw_info.product_id);
    println!("Manufacturer:          {:?}", hw_info.manufact);
    println!("Product:               {:?}", hw_info.product);
    println!("Serial number:         {:?}", hw_info.serial);
    println!("Serial number enabled: {:?}", hw_info.have_serial);
    println!("IR endpoint enabled:   {:?}", hw_info.enable_ir);
    println!("Remote wakeup enabled: {:?}", hw_info.remote_wakeup);
    println!("");

    println!("Writing hardware info...");
    err = dev.set_hw_info(&hw_info);
    println!("Writing hardware info return message: {:?}\n", err);

    println!("2. Getting hardware info...");
    let (hw_info, mut err) = dev.get_hw_info();

    println!("Error: {:?}", err);
    println!("Vendor ID:             {:?}", hw_info.vendor_id);
    println!("Product ID:            {:?}", hw_info.product_id);
    println!("Manufacturer:          {:?}", hw_info.manufact);
    println!("Product:               {:?}", hw_info.product);
    println!("Serial number:         {:?}", hw_info.serial);
    println!("Serial number enabled: {:?}", hw_info.have_serial);
    println!("IR endpoint enabled:   {:?}", hw_info.enable_ir);
    println!("Remote wakeup enabled: {:?}", hw_info.remote_wakeup);
    println!("");

    // ---------- Get Tuner Gain ----------
    println!("get_tuner_type: {}", dev.get_tuner_type());
    err = dev.set_xtal_freq(28800000, 28800000);
    match err {
        Error::NoError => println!("set_xtal_freq - 28800000"),
        _ => return err,
    };
    println!("");

    // ---------- Set Tuner Gain ----------
    err = dev.set_tuner_gain_mode(true);
    match err {
        Error::NoError => println!("set_tuner_gain_mode successful..."),
        _ => return err,
    };

    let (gains, mut err) = dev.get_tuner_gains();
    match err {
        Error::NoError => println!("get_tuner_gains successful..."),
        _ => println!("get_tuner_gains failed - {:?}", err), // return err,
    };

    println!("\ntuner gains:  {:?}\n", gains);

    err = dev.set_tuner_gain(gains[2]);
    match err {
        Error::NoError => println!("set_tuner_gain {:?} successful...", gains[2]),
        _ => return err,
    };
    println!("");

    // ---------- Get/Set Sample Rate ----------
    let samplerate: i32 = 2083334;
    err = dev.set_sample_rate(samplerate);
    match err {
        Error::NoError => println!("set_sample_rate {} successful...", samplerate),
        _ => return err,
    };

    println!("get_sample_rate {} successful...\n", dev.get_sample_rate());

    // ---------- Get/Set Xtal Freq ----------
    let (mut rtl_freq, mut tuner_freq, mut err) = dev.get_xtal_freq();
    match err {
        Error::NoError => {
            println!("get_xtal_freq successful - rtl_freq: {}, tuner_freq: {}",
                     rtl_freq,
                     tuner_freq)
        }
        _ => return err,
    };

    rtl_freq = 28800000;
    tuner_freq = 28800000;

    err = dev.set_xtal_freq(rtl_freq, tuner_freq);
    match err {
        Error::NoError => {
            println!("set_xtal_freq successful - rtl_freq: {}, tuner_freq: {}",
                     rtl_freq,
                     tuner_freq)
        }
        _ => return err,
    };
    println!("");

    // ---------- Get/Set Center Freq ----------
    err = dev.set_center_freq(978000000);
    match err {
        Error::NoError => println!("set_center_freq successful - 978000000"),
        _ => return err,
    };

    println!("get_center_freq: {}\n", dev.get_center_freq());

    // ---------- Set Tuner Bandwidth ----------
    let bw: i32 = 1000000;
    println!("Setting bandwidth: {}", bw);

    err = dev.set_tuner_bandwidth(bw);
    match err {
        Error::NoError => println!("set_tuner_bandwidth {} Successful", bw),
        _ => return err,
    };
    println!("");

    // ---------- Buffer Reset ----------
    err = dev.reset_buffer();
    match err {
        Error::NoError => println!("reset_buffer successful..."),
        _ => return err,
    };

    // ---------- Get/Set Freq Correction ----------
    let mut freq_corr = dev.get_freq_correction();
    println!("get_freq_correction - {}", freq_corr);

    freq_corr += 1;
    let err = dev.set_freq_correction(freq_corr);
    match err {
        Error::NoError => println!("set_freq_correction successful - {}", freq_corr),
        _ => return err,
    };
    println!("");
    // ----------  ----------
    Error::NoError
}

unsafe extern "C" fn read_async_callback(buf: *mut c_uchar, len: u32, ctx: *mut c_void) {
    let _ = ctx;
    let v = Vec::<u8>::from_raw_parts(buf, len as usize, len as usize);
    println!("----- read_async_callback buffer size - {}", len);
    println!("----- {} {} {} {} {} {}",
             v[0],
             v[1],
             v[2],
             v[3],
             v[4],
             v[5]);
}

fn main() {
    // ---------- Device Check ----------
    let count = rtlsdr::get_device_count();
    if count == 0 {
        println!("No devices found, exiting.");
        return;
    }

    for i in 0..count {
        let (m, p, s, err) = rtlsdr::get_device_usb_strings(i);
        println!("get_device_usb_strings: {:?} - {} {} {}", err, m, p, s);
    }

    let index = 0;
    println!("===== Device name, index {}: {} =====",
             index,
             rtlsdr::get_device_name(0));
    println!("===== Running tests using device indx: 0 =====\n");

    let (dev, mut err) = rtlsdr::open(index);
    match err {
        Error::NoError => println!("open successful"),
        _ => return,
    }

    err = sdr_config(&dev);
    match err {
        Error::NoError => println!("sdr_config successful..."),
        _ => return,
    }

    println!("calling read_sync...");
    for i in 0..10 {
        let (_, read_count, err) = dev.read_sync(rtlsdr::DEFAULT_BUF_LENGTH);
        println!("----- read_sync requested iteration {} -----", i);
        println!("\tread_sync requested - {}", rtlsdr::DEFAULT_BUF_LENGTH);
        println!("\tread_sync received  - {}", read_count);
        println!("\tread_sync err msg   - {:?}", err);
    }

    dev.reset_buffer();

    // read_async is a blocking call and doesn't return until
    // async_stop is called , so we spawn a thread that sleeps
    // for a bit while our async callback is called...
    let d = dev.clone();
    thread::spawn(move || {
        println!("async_stop thread sleeping for 5 seconds...");
        thread::sleep(Duration::from_millis(5000));
        println!("async_stop thread awake, canceling read async...");
        d.cancel_async();
    });

    println!("calling read_async...");
    err = dev.read_async(Some(read_async_callback),
                         ptr::null_mut(),
                         rtlsdr::DEFAULT_ASYNC_BUF_NUMBER,
                         rtlsdr::DEFAULT_BUF_LENGTH);
    match err {
        Error::NoError => println!("device close successful..."),
        _ => println!("dev close error - {:?}", err),
    }

    err = dev.close();
    match err {
        Error::NoError => println!("device close successful..."),
        _ => println!("dev close error - {:?}", err),
    }
}
<|endoftext|>


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

use core::failure;
use core::fmt;

use platform::io;
use platform::cpu::mmu::Page;
use cpu::Context;

#[repr(u8)]
pub enum Fault {
    DivideError = 0,
    NMI = 2,
    Breakpoint = 3,
    Overflow = 4,
    BoundExceeded = 5,
    InvalidOpcode = 6,
    NoMathCoprocessor = 7,
    DoubleFault = 8,
    CoprocessorSegmentOverun = 9,
    InvalidTss = 10,
    SegmentNotPresent = 11,
    StackSegmentFault = 12,
    GeneralProtection = 13,
    PageFault = 14,
    FloatingPointError = 16,
    AlignmentCheck = 17,
    MachineCheck = 18,
    SimdFpException = 19,
}

static Exceptions: &'static [&'static str] = &[
    "Divide-by-zero Error",
    "Debug",
    "Non-maskable Interrupt",
    "Breakpoint",
    "Overflow",
    "Bound Range Exceeded",
    "Invalid Opcode",
    "Device Not Available",
    "Double Fault",
    "Coprocessor Segment Overrun",
    "Invalid TSS",
    "Segment Not Present",
    "Stack-Segment Fault",
    "General Protection Fault",
    "Page Fault",
    "Reserved",
    "x87 Floating-Point Exception",
    "Alignment Check",
    "Machine Check",
    "SIMD Floating-Point Exception",
    "Virtualization Exception",
];

// TODO respect destructors
#[lang="begin_unwind"]
unsafe extern "C" fn begin_unwind(fmt: &fmt::Arguments, file: &str, line: uint) -> ! {
    asm!("hlt");
    loop { }; // for divergence check
}

#[no_split_stack]
#[inline(never)]
unsafe fn blue_screen(stack: &Context) {
    io::puts("Exception ");
    io::puts(Exceptions[stack.int_no as uint]);
    asm!("hlt");
}

#[no_split_stack]
#[inline(never)]
pub unsafe fn exception_handler() -> unsafe extern "C" fn() {
    asm!("jmp skip_exception_handler
      exception_handler_asm:"
        :::: "volatile", "intel");

    // Points to the data on the stack
    let stack_ptr = Context::save();

    if stack_ptr.int_no as u8 == PageFault as u8 {
        let cr2: uint;
        asm!("mov %cr2, %eax" : "={eax}"(cr2));
        println!("Accessed {} from {}", cr2, stack_ptr.call_stack.eip);
    }

    if stack_ptr.int_no as u8 == Breakpoint as u8 {
        asm!("debug:" :::: "volatile")
    }
    else {
        blue_screen(stack_ptr);
    }

    Context::restore();

    asm!("skip_exception_handler:"
        :::: "volatile", "intel");

    extern { fn exception_handler_asm(); }
    exception_handler_asm
}
<commit_msg>Print the SP and IP in hex<commit_after>use core::mem::transmute;

use core::failure;
use core::fmt;

use platform::io;
use platform::cpu::mmu::Page;
use cpu::Context;

#[repr(u8)]
pub enum Fault {
    DivideError = 0,
    NMI = 2,
    Breakpoint = 3,
    Overflow = 4,
    BoundExceeded = 5,
    InvalidOpcode = 6,
    NoMathCoprocessor = 7,
    DoubleFault = 8,
    CoprocessorSegmentOverun = 9,
    InvalidTss = 10,
    SegmentNotPresent = 11,
    StackSegmentFault = 12,
    GeneralProtection = 13,
    PageFault = 14,
    FloatingPointError = 16,
    AlignmentCheck = 17,
    MachineCheck = 18,
    SimdFpException = 19,
}

static Exceptions: &'static [&'static str] = &[
    "Divide-by-zero Error",
    "Debug",
    "Non-maskable Interrupt",
    "Breakpoint",
    "Overflow",
    "Bound Range Exceeded",
    "Invalid Opcode",
    "Device Not Available",
    "Double Fault",
    "Coprocessor Segment Overrun",
    "Invalid TSS",
    "Segment Not Present",
    "Stack-Segment Fault",
    "General Protection Fault",
    "Page Fault",
    "Reserved",
    "x87 Floating-Point Exception",
    "Alignment Check",
    "Machine Check",
    "SIMD Floating-Point Exception",
    "Virtualization Exception",
];

// TODO respect destructors
#[lang="begin_unwind"]
unsafe extern "C" fn begin_unwind(fmt: &fmt::Arguments, file: &str, line: uint) -> ! {
    asm!("hlt");
    loop { }; // for divergence check
}

#[no_split_stack]
#[inline(never)]
unsafe fn blue_screen(stack: &Context) {
    io::puts("Exception ");
    io::puts(Exceptions[stack.int_no as uint]);
    asm!("hlt");
}

#[no_split_stack]
#[inline(never)]
pub unsafe fn exception_handler() -> unsafe extern "C" fn() {
    asm!("jmp skip_exception_handler
      exception_handler_asm:"
        :::: "volatile", "intel");

    // Points to the data on the stack
    let stack_ptr = Context::save();

    if stack_ptr.int_no as u8 == PageFault as u8 {
        let cr2: uint;
        asm!("mov %cr2, %eax" : "={eax}"(cr2));
        println!("Accessed {0:x} from {1:x}", cr2, stack_ptr.call_stack.eip);
    }

    if stack_ptr.int_no as u8 == Breakpoint as u8 {
        asm!("debug:" :::: "volatile")
    }
    else {
        blue_screen(stack_ptr);
    }

    Context::restore();

    asm!("skip_exception_handler:"
        :::: "volatile", "intel");

    extern { fn exception_handler_asm(); }
    exception_handler_asm
}
<|endoftext|>


<commit_before>//! FIXME: write short doc here

use itertools::Itertools;
use ra_db::SourceDatabase;
use ra_syntax::{
    ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner},
    SyntaxNode, TextRange,
};

use crate::{db::RootDatabase, FileId};

#[derive(Debug)]
pub struct Runnable {
    pub range: TextRange,
    pub kind: RunnableKind,
}

#[derive(Debug)]
pub enum RunnableKind {
    Test { name: String },
    TestMod { path: String },
    Bench { name: String },
    Bin,
}

pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
    let parse = db.parse(file_id);
    parse.tree().syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
}

fn runnable(db: &RootDatabase, file_id: FileId, item: SyntaxNode) -> Option<Runnable> {
    if let Some(fn_def) = ast::FnDef::cast(item.clone()) {
        runnable_fn(fn_def)
    } else if let Some(m) = ast::Module::cast(item) {
        runnable_mod(db, file_id, m)
    } else {
        None
    }
}

fn runnable_fn(fn_def: ast::FnDef) -> Option<Runnable> {
    let name = fn_def.name()?.text().clone();
    let kind = if name == "main" {
        RunnableKind::Bin
    } else if fn_def.has_atom_attr("test") {
        RunnableKind::Test { name: name.to_string() }
    } else if fn_def.has_atom_attr("bench") {
        RunnableKind::Bench { name: name.to_string() }
    } else {
        return None;
    };
    Some(Runnable { range: fn_def.syntax().text_range(), kind })
}

fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Option<Runnable> {
    let has_test_function = module
        .item_list()?
        .items()
        .filter_map(|it| match it {
            ast::ModuleItem::FnDef(it) => Some(it),
            _ => None,
        })
        .any(|f| f.has_atom_attr("test"));
    if !has_test_function {
        return None;
    }
    let range = module.syntax().text_range();
    let src = hir::ModuleSource::from_child_node(db, file_id, &module.syntax());
    let module =
        hir::Module::from_definition(db, hir::Source { file_id: file_id.into(), ast: src })?;

    let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::");
    Some(Runnable { range, kind: RunnableKind::TestMod { path } })
}

#[cfg(test)]
mod tests {
    use insta::assert_debug_snapshot;

    use crate::mock_analysis::analysis_and_position;

    #[test]
    fn test_runnables() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        fn main() {}

        #[test]
        fn test_foo() {}

        #[test]
        #[ignore]
        fn test_foo() {}
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [1; 21),
        kind: Bin,
    },
    Runnable {
        range: [22; 46),
        kind: Test {
            name: "test_foo",
        },
    },
    Runnable {
        range: [47; 81),
        kind: Test {
            name: "test_foo",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod test_mod {
            #[test]
            fn test_foo1() {}
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [1; 59),
        kind: TestMod {
            path: "test_mod",
        },
    },
    Runnable {
        range: [28; 57),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_one_depth_layer_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod foo {
            mod test_mod {
                #[test]
                fn test_foo1() {}
            }
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [23; 85),
        kind: TestMod {
            path: "foo::test_mod",
        },
    },
    Runnable {
        range: [46; 79),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_multiple_depth_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod foo {
            mod bar {
                mod test_mod {
                    #[test]
                    fn test_foo1() {}
                }
            }
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [41; 115),
        kind: TestMod {
            path: "foo::bar::test_mod",
        },
    },
    Runnable {
        range: [68; 105),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_no_test_function_in_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod test_mod {
            fn foo1() {}
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert!(runnables.is_empty())
    }
}
<commit_msg>runnables => match_ast!<commit_after>//! FIXME: write short doc here

use itertools::Itertools;
use ra_db::SourceDatabase;
use ra_syntax::{
    ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner},
    match_ast, SyntaxNode, TextRange,
};

use crate::{db::RootDatabase, FileId};

#[derive(Debug)]
pub struct Runnable {
    pub range: TextRange,
    pub kind: RunnableKind,
}

#[derive(Debug)]
pub enum RunnableKind {
    Test { name: String },
    TestMod { path: String },
    Bench { name: String },
    Bin,
}

pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
    let parse = db.parse(file_id);
    parse.tree().syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
}

fn runnable(db: &RootDatabase, file_id: FileId, item: SyntaxNode) -> Option<Runnable> {
    match_ast! {
        match item {
            ast::FnDef(it) => { runnable_fn(it) },
            ast::Module(it) => { runnable_mod(db, file_id, it) },
            _ => { None },
        }
    }
}

fn runnable_fn(fn_def: ast::FnDef) -> Option<Runnable> {
    let name = fn_def.name()?.text().clone();
    let kind = if name == "main" {
        RunnableKind::Bin
    } else if fn_def.has_atom_attr("test") {
        RunnableKind::Test { name: name.to_string() }
    } else if fn_def.has_atom_attr("bench") {
        RunnableKind::Bench { name: name.to_string() }
    } else {
        return None;
    };
    Some(Runnable { range: fn_def.syntax().text_range(), kind })
}

fn runnable_mod(db: &RootDatabase, file_id: FileId, module: ast::Module) -> Option<Runnable> {
    let has_test_function = module
        .item_list()?
        .items()
        .filter_map(|it| match it {
            ast::ModuleItem::FnDef(it) => Some(it),
            _ => None,
        })
        .any(|f| f.has_atom_attr("test"));
    if !has_test_function {
        return None;
    }
    let range = module.syntax().text_range();
    let src = hir::ModuleSource::from_child_node(db, file_id, &module.syntax());
    let module =
        hir::Module::from_definition(db, hir::Source { file_id: file_id.into(), ast: src })?;

    let path = module.path_to_root(db).into_iter().rev().filter_map(|it| it.name(db)).join("::");
    Some(Runnable { range, kind: RunnableKind::TestMod { path } })
}

#[cfg(test)]
mod tests {
    use insta::assert_debug_snapshot;

    use crate::mock_analysis::analysis_and_position;

    #[test]
    fn test_runnables() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        fn main() {}

        #[test]
        fn test_foo() {}

        #[test]
        #[ignore]
        fn test_foo() {}
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [1; 21),
        kind: Bin,
    },
    Runnable {
        range: [22; 46),
        kind: Test {
            name: "test_foo",
        },
    },
    Runnable {
        range: [47; 81),
        kind: Test {
            name: "test_foo",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod test_mod {
            #[test]
            fn test_foo1() {}
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [1; 59),
        kind: TestMod {
            path: "test_mod",
        },
    },
    Runnable {
        range: [28; 57),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_one_depth_layer_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod foo {
            mod test_mod {
                #[test]
                fn test_foo1() {}
            }
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [23; 85),
        kind: TestMod {
            path: "foo::test_mod",
        },
    },
    Runnable {
        range: [46; 79),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_multiple_depth_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod foo {
            mod bar {
                mod test_mod {
                    #[test]
                    fn test_foo1() {}
                }
            }
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert_debug_snapshot!(&runnables,
        @r#"[
    Runnable {
        range: [41; 115),
        kind: TestMod {
            path: "foo::bar::test_mod",
        },
    },
    Runnable {
        range: [68; 105),
        kind: Test {
            name: "test_foo1",
        },
    },
]"#
                );
    }

    #[test]
    fn test_runnables_no_test_function_in_module() {
        let (analysis, pos) = analysis_and_position(
            r#"
        //- /lib.rs
        <|> //empty
        mod test_mod {
            fn foo1() {}
        }
        "#,
        );
        let runnables = analysis.runnables(pos.file_id).unwrap();
        assert!(runnables.is_empty())
    }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate rusoto_core;
extern crate rusoto_dynamodb;
extern crate tokio_core;

use futures::future::Future;
use rusoto_core::Region;
use rusoto_dynamodb::{
    AttributeDefinition, AttributeValue, CreateTableInput, CreateTableOutput, DynamoDb,
    DynamoDbClient, GetItemError, GetItemInput, GetItemOutput, KeySchemaElement,
    ProvisionedThroughput, UpdateItemInput, UpdateItemOutput,
};
use std::collections::HashMap;
use tokio_core::reactor::Core;

fn main() {
    let item = make_item();
    let client = get_dynamodb_local_client();

    let create_table_future = make_create_table_future(&client);
    let upsert_item_future = make_upsert_item_future(&client, &item);
    let item_from_dynamo_future = make_get_item_future(&client, &item);

    // tie them together
    let chained_futures = create_table_future
        .then(|_| upsert_item_future)
        .then(|_| item_from_dynamo_future);

    // This tokio core will run our futures to completion:
    let mut core = Core::new().unwrap();

    // run 'em
    let item_from_dynamo = match core.run(chained_futures) {
        Ok(item) => item,
        Err(_) => panic!("Error completing futures: {}"),
    };

    println!("item_from_dynamo is {:?}", item_from_dynamo);
    println!("Done");
}

fn make_create_table_future(client: &DynamoDbClient) -> impl Future<Item = CreateTableOutput> {
    let attribute_def = AttributeDefinition {
        attribute_name: "foo_name".to_string(),
        attribute_type: "S".to_string(),
    };
    let k_schema = KeySchemaElement {
        attribute_name: "foo_name".to_string(),
        key_type: "HASH".to_string(), // case sensitive
    };
    let p_throughput = ProvisionedThroughput {
        read_capacity_units: 1,
        write_capacity_units: 1,
    };
    let make_table_request = CreateTableInput {
        table_name: "a-testing-table".to_string(),
        attribute_definitions: vec![attribute_def],
        key_schema: vec![k_schema],
        provisioned_throughput: p_throughput,
        ..Default::default()
    };

    client.create_table(make_table_request)
}

fn make_upsert_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> impl Future<Item = UpdateItemOutput> {
    let add_item = UpdateItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };

    client.update_item(add_item)
}

fn make_get_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> impl Future<Item = GetItemOutput, Error = GetItemError> {
    // future for getting the entry
    let get_item_request = GetItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };
    client.get_item(get_item_request)
}

fn make_item() -> HashMap<String, AttributeValue> {
    let item_key = "foo_name";
    let mut item = HashMap::new();
    item.insert(
        item_key.to_string(),
        AttributeValue {
            s: Some("baz".to_string()),
            ..Default::default()
        },
    );

    item
}

fn get_dynamodb_local_client() -> DynamoDbClient {
    // Create custom Region
    let region = Region::Custom {
        name: "us-east-1".to_owned(),
        endpoint: "http://localhost:8000".to_owned(),
    };

    DynamoDbClient::new(region)
}<commit_msg>More futures fun.<commit_after>extern crate futures;
extern crate rusoto_core;
extern crate rusoto_dynamodb;
extern crate tokio_core;

use futures::future::Future;
use rusoto_core::Region;
use rusoto_dynamodb::{
    AttributeDefinition, AttributeValue, CreateTableError, CreateTableInput, CreateTableOutput,
    DynamoDb, DynamoDbClient, GetItemError, GetItemInput, GetItemOutput, KeySchemaElement,
    ProvisionedThroughput, UpdateItemInput, UpdateItemOutput,
};
use std::collections::HashMap;
use tokio_core::reactor::Core;

fn main() {
    let item = make_item();
    let client = get_dynamodb_local_client();
    // This tokio core will run our futures to completion:
    let mut core = Core::new().unwrap();

    // These two Futures don't return an error:
    let create_table_future = make_create_table_future(&client);
    let upsert_item_future = make_upsert_item_future(&client, &item);
    // This Future returns a result: it's similar to calling
    // client.get_item(get_item_request).sync()
    let item_from_dynamo_future = make_get_item_future(&client, &item);

    // tie them together, ignoring any output from the previous futures:
    let chained_futures = create_table_future
        .then(|_| upsert_item_future)
        .then(|_| item_from_dynamo_future);

    // ----------------------------------------------------
    // Comment out below to run part two
    // ----------------------------------------------------
    let item_from_dynamo = match core.run(chained_futures) {
        Ok(item) => item,
        Err(e) => panic!("Error completing futures: {}", e),
    };

    println!("item_from_dynamo is {:?}", item_from_dynamo);
    // ----------------------------------------------------
    // Comment out above to run part two
    // ----------------------------------------------------

    let make_table_future_the_second = create_table_future_with_error_handling(&client);
    let get_item_future = make_get_item_future_with_error_handling(&client, &item);

    let chained = make_table_future_the_second
        .map_err(|e| {
            println!("We could do something with the table creation error here.");
            // We need to make any error return look like the innermost error returned.
            // Let's create a GetItemError:
            GetItemError::InternalServerError(format!(
                "Actually from us! Real error from attempting to making the table: {}",
                e
            ))
        })
        .and_then(|r| {
            // If we're here, we successfully made the new table.
            // r will be the CreateTableOutput:
            println!("r is {:?}\n\n", r);

            // Finally, call the get_item_future and return the Result<GetItemOutput, GetItemError>
            // and we can match on that later.
            get_item_future
        });

    // `core.run(chained)` will look like the innermost future we called, which will get an item.
    // This is just like a synchronous Rusoto call of client.get_item(get_item_request).sync():
    let chained_with_failure_handling = match core.run(chained) {
        Ok(result) => format!("Got item: {:?}", result),
        Err(e) => format!("Didn't get item: {}", e),
    };
    println!(
        "chained_with_failure_handling is {}",
        chained_with_failure_handling
    );

    println!("Done");
}

fn create_table_future_with_error_handling(
    client: &DynamoDbClient,
) -> impl Future<Item = CreateTableOutput, Error = CreateTableError> {
    let attribute_def = AttributeDefinition {
        attribute_name: "foo_name".to_string(),
        attribute_type: "S".to_string(),
    };
    let k_schema = KeySchemaElement {
        attribute_name: "foo_name".to_string(),
        key_type: "HASH".to_string(), // case sensitive
    };
    let p_throughput = ProvisionedThroughput {
        read_capacity_units: 1,
        write_capacity_units: 1,
    };
    let make_table_request = CreateTableInput {
        table_name: "a-testing-table".to_string(),
        attribute_definitions: vec![attribute_def],
        key_schema: vec![k_schema],
        provisioned_throughput: p_throughput,
        ..Default::default()
    };

    client.create_table(make_table_request)
}

fn make_create_table_future(client: &DynamoDbClient) -> impl Future<Item = CreateTableOutput> {
    let attribute_def = AttributeDefinition {
        attribute_name: "foo_name".to_string(),
        attribute_type: "S".to_string(),
    };
    let k_schema = KeySchemaElement {
        attribute_name: "foo_name".to_string(),
        key_type: "HASH".to_string(), // case sensitive
    };
    let p_throughput = ProvisionedThroughput {
        read_capacity_units: 1,
        write_capacity_units: 1,
    };
    let make_table_request = CreateTableInput {
        table_name: "a-testing-table".to_string(),
        attribute_definitions: vec![attribute_def],
        key_schema: vec![k_schema],
        provisioned_throughput: p_throughput,
        ..Default::default()
    };

    client.create_table(make_table_request)
}

fn make_upsert_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> impl Future<Item = UpdateItemOutput> {
    let add_item = UpdateItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };

    client.update_item(add_item)
}

fn make_get_item_future_with_error_handling(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> impl Future<Item = GetItemOutput, Error = GetItemError> {
    // future for getting the entry
    let get_item_request = GetItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };
    client.get_item(get_item_request)
}

fn make_get_item_future(
    client: &DynamoDbClient,
    item: &HashMap<String, AttributeValue>,
) -> impl Future<Item = GetItemOutput, Error = GetItemError> {
    // future for getting the entry
    let get_item_request = GetItemInput {
        key: item.clone(),
        table_name: "a-testing-table".to_string(),
        ..Default::default()
    };
    client.get_item(get_item_request)
}

fn make_item() -> HashMap<String, AttributeValue> {
    let item_key = "foo_name";
    let mut item = HashMap::new();
    item.insert(
        item_key.to_string(),
        AttributeValue {
            s: Some("baz".to_string()),
            ..Default::default()
        },
    );

    item
}

fn get_dynamodb_local_client() -> DynamoDbClient {
    // Create custom Region
    let region = Region::Custom {
        name: "us-east-1".to_owned(),
        endpoint: "http://localhost:8000".to_owned(),
    };

    DynamoDbClient::new(region)
}
<|endoftext|>


<commit_before>#[allow(unused_imports, deprecated)]
use std::ascii::AsciiExt;

use std::str::FromStr;

use language_tags::LanguageTag;
use locale_config::{LanguageRange, Locale};

use crate::error::*;
use crate::parsers::ParseError;

// No extensions at the moment.
static IMPLEMENTED_EXTENSIONS: &[&str] = &[];

#[derive(Debug, PartialEq)]
pub struct RequiredExtensions(pub bool);

impl RequiredExtensions {
    // Parse a requiredExtensions attribute
    // http://www.w3.org/TR/SVG/struct.html#RequiredExtensionsAttribute
    pub fn from_attribute(s: &str) -> Result<RequiredExtensions, ValueErrorKind> {
        Ok(RequiredExtensions(
            s.split_whitespace()
                .all(|f| IMPLEMENTED_EXTENSIONS.binary_search(&f).is_ok()),
        ))
    }
}

// Keep these sorted alphabetically for binary_search.
static IMPLEMENTED_FEATURES: &[&str] = &[
    "http://www.w3.org/TR/SVG11/feature#BasicFilter",
    "http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute",
    "http://www.w3.org/TR/SVG11/feature#BasicPaintAttribute",
    "http://www.w3.org/TR/SVG11/feature#BasicStructure",
    "http://www.w3.org/TR/SVG11/feature#BasicText",
    "http://www.w3.org/TR/SVG11/feature#ConditionalProcessing",
    "http://www.w3.org/TR/SVG11/feature#ContainerAttribute",
    "http://www.w3.org/TR/SVG11/feature#Filter",
    "http://www.w3.org/TR/SVG11/feature#Gradient",
    "http://www.w3.org/TR/SVG11/feature#Image",
    "http://www.w3.org/TR/SVG11/feature#Marker",
    "http://www.w3.org/TR/SVG11/feature#Mask",
    "http://www.w3.org/TR/SVG11/feature#OpacityAttribute",
    "http://www.w3.org/TR/SVG11/feature#Pattern",
    "http://www.w3.org/TR/SVG11/feature#SVG",
    "http://www.w3.org/TR/SVG11/feature#SVG-static",
    "http://www.w3.org/TR/SVG11/feature#Shape",
    "http://www.w3.org/TR/SVG11/feature#Structure",
    "http://www.w3.org/TR/SVG11/feature#Style",
    "http://www.w3.org/TR/SVG11/feature#View",
    "org.w3c.svg.static", // deprecated SVG 1.0 feature string
];

#[derive(Debug, PartialEq)]
pub struct RequiredFeatures(pub bool);

impl RequiredFeatures {
    // Parse a requiredFeatures attribute
    // http://www.w3.org/TR/SVG/struct.html#RequiredFeaturesAttribute
    pub fn from_attribute(s: &str) -> Result<RequiredFeatures, ValueErrorKind> {
        Ok(RequiredFeatures(
            s.split_whitespace()
                .all(|f| IMPLEMENTED_FEATURES.binary_search(&f).is_ok()),
        ))
    }
}

#[derive(Debug, PartialEq)]
pub struct SystemLanguage(pub bool);

impl SystemLanguage {
    /// Parse a `systemLanguage` attribute and match it against a given `Locale`
    ///
    /// The [`systemLanguage`] conditional attribute is a
    /// comma-separated list of [BCP47] Language Tags.  This function
    /// parses the attribute and matches the result against a given
    /// `locale`.  If there is a match, i.e. if the given locale
    /// supports one of the languages listed in the `systemLanguage`
    /// attribute, then the `SystemLanguage.0` will be `true`;
    /// otherwise it will be `false`.
    ///
    /// Normally, calling code will pass `&Locale::current()` for the
    /// `locale` attribute; this is the user's current locale.
    ///
    /// [`systemLanguage`]: https://www.w3.org/TR/SVG/struct.html#ConditionalProcessingSystemLanguageAttribute
    /// [BCP47]: http://www.ietf.org/rfc/bcp/bcp47.txt
    pub fn from_attribute(s: &str, locale: &Locale) -> Result<SystemLanguage, ValueErrorKind> {
        s.split(',').map(LanguageTag::from_str).try_fold(
            // start with no match
            SystemLanguage(false),
            // The accumulator is Result<SystemLanguage, ValueErrorKind>
            |acc, tag_result| match tag_result {
                Ok(language_tag) => {
                    let have_match = acc.0;
                    if have_match {
                        Ok(SystemLanguage(have_match))
                    } else {
                        locale_accepts_language_tag(locale, &language_tag)
                            .map(|matches| SystemLanguage(matches))
                    }
                }

                Err(e) => Err(ValueErrorKind::Parse(ParseError::new(&format!(
                    "invalid language tag: \"{}\"",
                    e
                )))),
            },
        )
    }
}

fn locale_accepts_language_tag(
    locale: &Locale,
    language_tag: &LanguageTag,
) -> Result<bool, ValueErrorKind> {
    for locale_range in locale.tags_for("messages") {
        if locale_range == LanguageRange::invariant() {
            continue;
        }

        let str_locale_range = locale_range.as_ref();

        let locale_tag = LanguageTag::from_str(str_locale_range).map_err(|e| {
            ValueErrorKind::Parse(ParseError::new(&format!(
                "invalid language tag \"{}\" in locale: {}",
                str_locale_range, e
            )))
        })?;

        if !locale_tag.is_language_range() {
            return Err(ValueErrorKind::Value(format!(
                "language tag \"{}\" is not a language range",
                locale_tag
            )));
        }

        if locale_tag.matches(language_tag) {
            return Ok(true);
        }
    }

    Ok(false)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn required_extensions() {
        assert_eq!(
            RequiredExtensions::from_attribute("http://test.org/NotExisting/1.0"),
            Ok(RequiredExtensions(false))
        );
    }

    #[test]
    fn required_features() {
        assert_eq!(
            RequiredFeatures::from_attribute("http://www.w3.org/TR/SVG11/feature#NotExisting"),
            Ok(RequiredFeatures(false))
        );

        assert_eq!(
            RequiredFeatures::from_attribute("http://www.w3.org/TR/SVG11/feature#BasicFilter"),
            Ok(RequiredFeatures(true))
        );

        assert_eq!(
            RequiredFeatures::from_attribute(
                "http://www.w3.org/TR/SVG11/feature#BasicFilter \
                 http://www.w3.org/TR/SVG11/feature#NotExisting",
            ),
            Ok(RequiredFeatures(false))
        );

        assert_eq!(
            RequiredFeatures::from_attribute(
                "http://www.w3.org/TR/SVG11/feature#BasicFilter \
                 http://www.w3.org/TR/SVG11/feature#BasicText",
            ),
            Ok(RequiredFeatures(true))
        );
    }

    #[test]
    fn system_language() {
        let user_prefers = Locale::new("de,en-US").unwrap();

        assert!(SystemLanguage::from_attribute("", &user_prefers).is_err());

        assert!(SystemLanguage::from_attribute("12345", &user_prefers).is_err());

        assert_eq!(
            SystemLanguage::from_attribute("fr", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("de", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en-US", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en-GB", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("DE", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("de-LU", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("fr, de", &user_prefers),
            Ok(SystemLanguage(true))
        );
    }
}
<commit_msg>cond: cleanup map() call<commit_after>#[allow(unused_imports, deprecated)]
use std::ascii::AsciiExt;

use std::str::FromStr;

use language_tags::LanguageTag;
use locale_config::{LanguageRange, Locale};

use crate::error::*;
use crate::parsers::ParseError;

// No extensions at the moment.
static IMPLEMENTED_EXTENSIONS: &[&str] = &[];

#[derive(Debug, PartialEq)]
pub struct RequiredExtensions(pub bool);

impl RequiredExtensions {
    // Parse a requiredExtensions attribute
    // http://www.w3.org/TR/SVG/struct.html#RequiredExtensionsAttribute
    pub fn from_attribute(s: &str) -> Result<RequiredExtensions, ValueErrorKind> {
        Ok(RequiredExtensions(
            s.split_whitespace()
                .all(|f| IMPLEMENTED_EXTENSIONS.binary_search(&f).is_ok()),
        ))
    }
}

// Keep these sorted alphabetically for binary_search.
static IMPLEMENTED_FEATURES: &[&str] = &[
    "http://www.w3.org/TR/SVG11/feature#BasicFilter",
    "http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute",
    "http://www.w3.org/TR/SVG11/feature#BasicPaintAttribute",
    "http://www.w3.org/TR/SVG11/feature#BasicStructure",
    "http://www.w3.org/TR/SVG11/feature#BasicText",
    "http://www.w3.org/TR/SVG11/feature#ConditionalProcessing",
    "http://www.w3.org/TR/SVG11/feature#ContainerAttribute",
    "http://www.w3.org/TR/SVG11/feature#Filter",
    "http://www.w3.org/TR/SVG11/feature#Gradient",
    "http://www.w3.org/TR/SVG11/feature#Image",
    "http://www.w3.org/TR/SVG11/feature#Marker",
    "http://www.w3.org/TR/SVG11/feature#Mask",
    "http://www.w3.org/TR/SVG11/feature#OpacityAttribute",
    "http://www.w3.org/TR/SVG11/feature#Pattern",
    "http://www.w3.org/TR/SVG11/feature#SVG",
    "http://www.w3.org/TR/SVG11/feature#SVG-static",
    "http://www.w3.org/TR/SVG11/feature#Shape",
    "http://www.w3.org/TR/SVG11/feature#Structure",
    "http://www.w3.org/TR/SVG11/feature#Style",
    "http://www.w3.org/TR/SVG11/feature#View",
    "org.w3c.svg.static", // deprecated SVG 1.0 feature string
];

#[derive(Debug, PartialEq)]
pub struct RequiredFeatures(pub bool);

impl RequiredFeatures {
    // Parse a requiredFeatures attribute
    // http://www.w3.org/TR/SVG/struct.html#RequiredFeaturesAttribute
    pub fn from_attribute(s: &str) -> Result<RequiredFeatures, ValueErrorKind> {
        Ok(RequiredFeatures(
            s.split_whitespace()
                .all(|f| IMPLEMENTED_FEATURES.binary_search(&f).is_ok()),
        ))
    }
}

#[derive(Debug, PartialEq)]
pub struct SystemLanguage(pub bool);

impl SystemLanguage {
    /// Parse a `systemLanguage` attribute and match it against a given `Locale`
    ///
    /// The [`systemLanguage`] conditional attribute is a
    /// comma-separated list of [BCP47] Language Tags.  This function
    /// parses the attribute and matches the result against a given
    /// `locale`.  If there is a match, i.e. if the given locale
    /// supports one of the languages listed in the `systemLanguage`
    /// attribute, then the `SystemLanguage.0` will be `true`;
    /// otherwise it will be `false`.
    ///
    /// Normally, calling code will pass `&Locale::current()` for the
    /// `locale` attribute; this is the user's current locale.
    ///
    /// [`systemLanguage`]: https://www.w3.org/TR/SVG/struct.html#ConditionalProcessingSystemLanguageAttribute
    /// [BCP47]: http://www.ietf.org/rfc/bcp/bcp47.txt
    pub fn from_attribute(s: &str, locale: &Locale) -> Result<SystemLanguage, ValueErrorKind> {
        s.split(',').map(LanguageTag::from_str).try_fold(
            // start with no match
            SystemLanguage(false),
            // The accumulator is Result<SystemLanguage, ValueErrorKind>
            |acc, tag_result| match tag_result {
                Ok(language_tag) => {
                    let have_match = acc.0;
                    if have_match {
                        Ok(SystemLanguage(have_match))
                    } else {
                        locale_accepts_language_tag(locale, &language_tag)
                            .map(SystemLanguage)
                    }
                }

                Err(e) => Err(ValueErrorKind::Parse(ParseError::new(&format!(
                    "invalid language tag: \"{}\"",
                    e
                )))),
            },
        )
    }
}

fn locale_accepts_language_tag(
    locale: &Locale,
    language_tag: &LanguageTag,
) -> Result<bool, ValueErrorKind> {
    for locale_range in locale.tags_for("messages") {
        if locale_range == LanguageRange::invariant() {
            continue;
        }

        let str_locale_range = locale_range.as_ref();

        let locale_tag = LanguageTag::from_str(str_locale_range).map_err(|e| {
            ValueErrorKind::Parse(ParseError::new(&format!(
                "invalid language tag \"{}\" in locale: {}",
                str_locale_range, e
            )))
        })?;

        if !locale_tag.is_language_range() {
            return Err(ValueErrorKind::Value(format!(
                "language tag \"{}\" is not a language range",
                locale_tag
            )));
        }

        if locale_tag.matches(language_tag) {
            return Ok(true);
        }
    }

    Ok(false)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn required_extensions() {
        assert_eq!(
            RequiredExtensions::from_attribute("http://test.org/NotExisting/1.0"),
            Ok(RequiredExtensions(false))
        );
    }

    #[test]
    fn required_features() {
        assert_eq!(
            RequiredFeatures::from_attribute("http://www.w3.org/TR/SVG11/feature#NotExisting"),
            Ok(RequiredFeatures(false))
        );

        assert_eq!(
            RequiredFeatures::from_attribute("http://www.w3.org/TR/SVG11/feature#BasicFilter"),
            Ok(RequiredFeatures(true))
        );

        assert_eq!(
            RequiredFeatures::from_attribute(
                "http://www.w3.org/TR/SVG11/feature#BasicFilter \
                 http://www.w3.org/TR/SVG11/feature#NotExisting",
            ),
            Ok(RequiredFeatures(false))
        );

        assert_eq!(
            RequiredFeatures::from_attribute(
                "http://www.w3.org/TR/SVG11/feature#BasicFilter \
                 http://www.w3.org/TR/SVG11/feature#BasicText",
            ),
            Ok(RequiredFeatures(true))
        );
    }

    #[test]
    fn system_language() {
        let user_prefers = Locale::new("de,en-US").unwrap();

        assert!(SystemLanguage::from_attribute("", &user_prefers).is_err());

        assert!(SystemLanguage::from_attribute("12345", &user_prefers).is_err());

        assert_eq!(
            SystemLanguage::from_attribute("fr", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("de", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en-US", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("en-GB", &user_prefers),
            Ok(SystemLanguage(false))
        );

        assert_eq!(
            SystemLanguage::from_attribute("DE", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("de-LU", &user_prefers),
            Ok(SystemLanguage(true))
        );

        assert_eq!(
            SystemLanguage::from_attribute("fr, de", &user_prefers),
            Ok(SystemLanguage(true))
        );
    }
}
<|endoftext|>


<commit_before>use bounding_volume::PolyhedralCone;
use math::{Isometry, Point};
use na::{Real, Unit};
use pipeline::narrow_phase::{ContactDispatcher, ContactManifoldGenerator};
use query::{Contact, ContactKinematic, ContactManifold, ContactPrediction};
use shape::{Ball, FeatureId, Shape};
use utils::{IdAllocator, IsometryOps};

/// Collision detector between two balls.
pub struct BallConvexPolyhedronManifoldGenerator<N: Real> {
    flip: bool,
    contact_manifold: ContactManifold<N>,
}

impl<N: Real> Clone for BallConvexPolyhedronManifoldGenerator<N> {
    fn clone(&self) -> BallConvexPolyhedronManifoldGenerator<N> {
        BallConvexPolyhedronManifoldGenerator {
            flip: self.flip,
            contact_manifold: self.contact_manifold.clone(),
        }
    }
}

impl<N: Real> BallConvexPolyhedronManifoldGenerator<N> {
    /// Creates a new persistent collision detector between two balls.
    #[inline]
    pub fn new(flip: bool) -> BallConvexPolyhedronManifoldGenerator<N> {
        BallConvexPolyhedronManifoldGenerator {
            flip,
            contact_manifold: ContactManifold::new(),
        }
    }

    fn do_update(
        &mut self,
        m1: &Isometry<N>,
        a: &Shape<N>,
        m2: &Isometry<N>,
        b: &Shape<N>,
        prediction: &ContactPrediction<N>,
        id_alloc: &mut IdAllocator,
        flip: bool,
    ) -> bool {
        if let (Some(ball), Some(pq2), Some(cp2)) = (
            a.as_shape::<Ball<N>>(),
            b.as_point_query(),
            b.as_convex_polyhedron(),
        ) {
            self.contact_manifold.save_cache_and_clear(id_alloc);

            let ball_center = Point::from_coordinates(m1.translation.vector);
            let (proj, f2) = pq2.project_point_with_feature(m2, &ball_center);
            let world2 = proj.point;
            let dpt = world2 - ball_center;

            let depth;
            let normal;
            if let Some((dir, dist)) = Unit::try_new_and_get(dpt, N::default_epsilon()) {
                if proj.is_inside {
                    depth = dist + ball.radius();
                    normal = -dir;
                } else {
                    depth = -dist + ball.radius();
                    normal = dir;
                }
            } else {
                if f2 == FeatureId::Unknown() {
                    // We cant do anything more at this point.
                    return true;
                }

                depth = N::zero();
                normal = -cp2.feature_normal(f2);
            }

            if depth >= -prediction.linear {
                let mut kinematic = ContactKinematic::new();
                let f1 = FeatureId::Face(0);
                let world1 = ball_center + normal.unwrap() * ball.radius();

                let contact;

                if !flip {
                    contact = Contact::new(world1, world2, normal, depth);
                    kinematic.set_point1(f1, Point::origin(), PolyhedralCone::Full);
                    kinematic.set_dilation1(ball.radius());
                } else {
                    contact = Contact::new(world2, world1, -normal, depth);
                    kinematic.set_point2(f1, Point::origin(), PolyhedralCone::Full);
                    kinematic.set_dilation2(ball.radius());
                }

                let local2 = m2.inverse_transform_point(&world2);
                let n2 = cp2.normal_cone(f2);

                match f2 {
                    FeatureId::Face { .. } => {
                        if !flip {
                            kinematic.set_plane2(f2, local2, n2.unwrap_half_line())
                        } else {
                            kinematic.set_plane1(f2, local2, n2.unwrap_half_line())
                        }
                    }
                    #[cfg(feature = "dim3")]
                    FeatureId::Edge { .. } => {
                        let edge = cp2.edge(f2);
                        let dir = Unit::new_normalize(edge.1 - edge.0);

                        if !flip {
                            kinematic.set_line2(f2, local2, dir, n2)
                        } else {
                            kinematic.set_line1(f2, local2, dir, n2)
                        }
                    }
                    FeatureId::Vertex { .. } => {
                        if !flip {
                            kinematic.set_point2(f2, local2, n2)
                        } else {
                            kinematic.set_point1(f2, local2, n2)
                        }
                    }
                    FeatureId::Unknown => panic!("Feature id cannot be unknown."),
                }

                let _ = self.contact_manifold.push(contact, kinematic, id_alloc);
            }

            true
        } else {
            false
        }
    }
}

impl<N: Real> ContactManifoldGenerator<N>
for BallConvexPolyhedronManifoldGenerator<N>
{
    fn update(
        &mut self,
        _: &ContactDispatcher<N>,
        id1: usize,
        m1: &Isometry<N>,
        a: &Shape<N>,
        id2: usize,
        m2: &Isometry<N>,
        b: &Shape<N>,
        prediction: &ContactPrediction<N>,
        id_alloc: &mut IdAllocator,
    ) -> bool {
        self.contact_manifold.set_subshape_id1(id1);
        self.contact_manifold.set_subshape_id2(id2);

        if !self.flip {
            self.do_update(m1, a, m2, b, prediction, id_alloc, false)
        } else {
            self.do_update(m2, b, m1, a, prediction, id_alloc, true)
        }
    }

    fn clear(&mut self, id_alloc: &mut IdAllocator) {
        self.contact_manifold.clear(id_alloc)
    }

    #[inline]
    fn num_contacts(&self) -> usize {
        self.contact_manifold.len()
    }

    #[inline]
    fn contacts<'a: 'b, 'b>(&'a self, out: &'b mut Vec<&'a ContactManifold<N>>) {
        if self.contact_manifold.len() != 0 {
            out.push(&self.contact_manifold)
        }
    }
}
<commit_msg>Fix typo.<commit_after>use bounding_volume::PolyhedralCone;
use math::{Isometry, Point};
use na::{Real, Unit};
use pipeline::narrow_phase::{ContactDispatcher, ContactManifoldGenerator};
use query::{Contact, ContactKinematic, ContactManifold, ContactPrediction};
use shape::{Ball, FeatureId, Shape};
use utils::{IdAllocator, IsometryOps};

/// Collision detector between two balls.
pub struct BallConvexPolyhedronManifoldGenerator<N: Real> {
    flip: bool,
    contact_manifold: ContactManifold<N>,
}

impl<N: Real> Clone for BallConvexPolyhedronManifoldGenerator<N> {
    fn clone(&self) -> BallConvexPolyhedronManifoldGenerator<N> {
        BallConvexPolyhedronManifoldGenerator {
            flip: self.flip,
            contact_manifold: self.contact_manifold.clone(),
        }
    }
}

impl<N: Real> BallConvexPolyhedronManifoldGenerator<N> {
    /// Creates a new persistent collision detector between two balls.
    #[inline]
    pub fn new(flip: bool) -> BallConvexPolyhedronManifoldGenerator<N> {
        BallConvexPolyhedronManifoldGenerator {
            flip,
            contact_manifold: ContactManifold::new(),
        }
    }

    fn do_update(
        &mut self,
        m1: &Isometry<N>,
        a: &Shape<N>,
        m2: &Isometry<N>,
        b: &Shape<N>,
        prediction: &ContactPrediction<N>,
        id_alloc: &mut IdAllocator,
        flip: bool,
    ) -> bool {
        if let (Some(ball), Some(pq2), Some(cp2)) = (
            a.as_shape::<Ball<N>>(),
            b.as_point_query(),
            b.as_convex_polyhedron(),
        ) {
            self.contact_manifold.save_cache_and_clear(id_alloc);

            let ball_center = Point::from_coordinates(m1.translation.vector);
            let (proj, f2) = pq2.project_point_with_feature(m2, &ball_center);
            let world2 = proj.point;
            let dpt = world2 - ball_center;

            let depth;
            let normal;
            if let Some((dir, dist)) = Unit::try_new_and_get(dpt, N::default_epsilon()) {
                if proj.is_inside {
                    depth = dist + ball.radius();
                    normal = -dir;
                } else {
                    depth = -dist + ball.radius();
                    normal = dir;
                }
            } else {
                if f2 == FeatureId::Unknown {
                    // We cant do anything more at this point.
                    return true;
                }

                depth = N::zero();
                normal = -cp2.feature_normal(f2);
            }

            if depth >= -prediction.linear {
                let mut kinematic = ContactKinematic::new();
                let f1 = FeatureId::Face(0);
                let world1 = ball_center + normal.unwrap() * ball.radius();

                let contact;

                if !flip {
                    contact = Contact::new(world1, world2, normal, depth);
                    kinematic.set_point1(f1, Point::origin(), PolyhedralCone::Full);
                    kinematic.set_dilation1(ball.radius());
                } else {
                    contact = Contact::new(world2, world1, -normal, depth);
                    kinematic.set_point2(f1, Point::origin(), PolyhedralCone::Full);
                    kinematic.set_dilation2(ball.radius());
                }

                let local2 = m2.inverse_transform_point(&world2);
                let n2 = cp2.normal_cone(f2);

                match f2 {
                    FeatureId::Face { .. } => {
                        if !flip {
                            kinematic.set_plane2(f2, local2, n2.unwrap_half_line())
                        } else {
                            kinematic.set_plane1(f2, local2, n2.unwrap_half_line())
                        }
                    }
                    #[cfg(feature = "dim3")]
                    FeatureId::Edge { .. } => {
                        let edge = cp2.edge(f2);
                        let dir = Unit::new_normalize(edge.1 - edge.0);

                        if !flip {
                            kinematic.set_line2(f2, local2, dir, n2)
                        } else {
                            kinematic.set_line1(f2, local2, dir, n2)
                        }
                    }
                    FeatureId::Vertex { .. } => {
                        if !flip {
                            kinematic.set_point2(f2, local2, n2)
                        } else {
                            kinematic.set_point1(f2, local2, n2)
                        }
                    }
                    FeatureId::Unknown => panic!("Feature id cannot be unknown."),
                }

                let _ = self.contact_manifold.push(contact, kinematic, id_alloc);
            }

            true
        } else {
            false
        }
    }
}

impl<N: Real> ContactManifoldGenerator<N>
for BallConvexPolyhedronManifoldGenerator<N>
{
    fn update(
        &mut self,
        _: &ContactDispatcher<N>,
        id1: usize,
        m1: &Isometry<N>,
        a: &Shape<N>,
        id2: usize,
        m2: &Isometry<N>,
        b: &Shape<N>,
        prediction: &ContactPrediction<N>,
        id_alloc: &mut IdAllocator,
    ) -> bool {
        self.contact_manifold.set_subshape_id1(id1);
        self.contact_manifold.set_subshape_id2(id2);

        if !self.flip {
            self.do_update(m1, a, m2, b, prediction, id_alloc, false)
        } else {
            self.do_update(m2, b, m1, a, prediction, id_alloc, true)
        }
    }

    fn clear(&mut self, id_alloc: &mut IdAllocator) {
        self.contact_manifold.clear(id_alloc)
    }

    #[inline]
    fn num_contacts(&self) -> usize {
        self.contact_manifold.len()
    }

    #[inline]
    fn contacts<'a: 'b, 'b>(&'a self, out: &'b mut Vec<&'a ContactManifold<N>>) {
        if self.contact_manifold.len() != 0 {
            out.push(&self.contact_manifold)
        }
    }
}
<|endoftext|>