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

use container::Container;
use fmt;
use from_str::FromStr;
use libc;
use option::{Some, None, Option};
use os;
use str::StrSlice;
use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
use unstable::running_on_valgrind;

// Indicates whether we should perform expensive sanity checks, including rtassert!
// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);

/// Get the number of cores available
pub fn num_cpus() -> uint {
    unsafe {
        return rust_get_num_cpus();
    }

    extern {
        fn rust_get_num_cpus() -> libc::uintptr_t;
    }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
/// wired into it; this is a hard limit and requires rebuilding valgrind if you
/// want to go beyond it. Normally this is not a problem, but in some tests, we
/// produce a lot of threads casually.  Making lots of threads alone might not
/// be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
/// perfect storm of creating "too many mappings" for valgrind to handle when
/// running certain stress tests in the runtime.
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    (cfg!(target_os="macos")) && running_on_valgrind()
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => {
            let opt_n: Option<uint> = FromStr::from_str(nstr);
            match opt_n {
                Some(n) if n > 0 => n,
                _ => rtabort!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
            }
        }
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                num_cpus()
            }
        }
    }
}

pub fn dumb_println(args: &fmt::Arguments) {
    use io::native::file::FileDesc;
    use io;
    use libc;
    let mut out = FileDesc::new(libc::STDERR_FILENO, false);
    fmt::writeln(&mut out as &mut io::Writer, args);
}

pub fn abort(msg: &str) -> ! {
    let msg = if !msg.is_empty() { msg } else { "aborted" };
    let hash = msg.iter().fold(0, |accum, val| accum + (val as uint) );
    let quote = match hash % 10 {
        0 => "
It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.",
        1 => "
There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.",
        2 => "
Instead of the poems I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
ever dared to breathe before — the unwhisperable secret of secrets — The fact
that this city of stone and stridor is not a sentient perpetuation of Old New
York as London is of Old London and Paris of Old Paris, but that it is in fact
quite dead, its sprawling body imperfectly embalmed and infested with queer
animate things which have nothing to do with it as it was in life.",
        3 => "
The ocean ate the last of the land and poured into the smoking gulf, thereby
giving up all it had ever conquered. From the new-flooded lands it flowed
again, uncovering death and decay; and from its ancient and immemorial bed it
trickled loathsomely, uncovering nighted secrets of the years when Time was
young and the gods unborn. Above the waves rose weedy remembered spires. The
moon laid pale lilies of light on dead London, and Paris stood up from its damp
grave to be sanctified with star-dust. Then rose spires and monoliths that were
weedy but not remembered; terrible spires and monoliths of lands that men never
knew were lands...",
        4 => "
There was a night when winds from unknown spaces whirled us irresistibly into
limitless vacum beyond all thought and entity. Perceptions of the most
maddeningly untransmissible sort thronged upon us; perceptions of infinity
which at the time convulsed us with joy, yet which are now partly lost to my
memory and partly incapable of presentation to others.",
        _ => "You've met with a terrible fate, haven't you?"
    };
    rterrln!("{}", "");
    rterrln!("{}", quote);
    rterrln!("{}", "");
    rterrln!("fatal runtime error: {}", msg);

    abort();

    fn abort() -> ! {
        unsafe { libc::abort() }
    }
}

static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;

pub fn set_exit_status(code: int) {
    unsafe { EXIT_STATUS.store(code, SeqCst) }
}

pub fn get_exit_status() -> int {
    unsafe { EXIT_STATUS.load(SeqCst) }
}
<commit_msg>auto merge of #10643 : jorendorff/rust/master, r=alexcrichton<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use container::Container;
use fmt;
use from_str::FromStr;
use libc;
use option::{Some, None, Option};
use os;
use str::StrSlice;
use unstable::atomics::{AtomicInt, INIT_ATOMIC_INT, SeqCst};
use unstable::running_on_valgrind;

// Indicates whether we should perform expensive sanity checks, including rtassert!
// XXX: Once the runtime matures remove the `true` below to turn off rtassert, etc.
pub static ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) || cfg!(rtassert);

/// Get the number of cores available
pub fn num_cpus() -> uint {
    unsafe {
        return rust_get_num_cpus();
    }

    extern {
        fn rust_get_num_cpus() -> libc::uintptr_t;
    }
}

/// Valgrind has a fixed-sized array (size around 2000) of segment descriptors
/// wired into it; this is a hard limit and requires rebuilding valgrind if you
/// want to go beyond it. Normally this is not a problem, but in some tests, we
/// produce a lot of threads casually.  Making lots of threads alone might not
/// be a problem _either_, except on OSX, the segments produced for new threads
/// _take a while_ to get reclaimed by the OS. Combined with the fact that libuv
/// schedulers fork off a separate thread for polling fsevents on OSX, we get a
/// perfect storm of creating "too many mappings" for valgrind to handle when
/// running certain stress tests in the runtime.
pub fn limit_thread_creation_due_to_osx_and_valgrind() -> bool {
    (cfg!(target_os="macos")) && running_on_valgrind()
}

/// Get's the number of scheduler threads requested by the environment
/// either `RUST_THREADS` or `num_cpus`.
pub fn default_sched_threads() -> uint {
    match os::getenv("RUST_THREADS") {
        Some(nstr) => {
            let opt_n: Option<uint> = FromStr::from_str(nstr);
            match opt_n {
                Some(n) if n > 0 => n,
                _ => rtabort!("`RUST_THREADS` is `{}`, should be a positive integer", nstr)
            }
        }
        None => {
            if limit_thread_creation_due_to_osx_and_valgrind() {
                1
            } else {
                num_cpus()
            }
        }
    }
}

pub fn dumb_println(args: &fmt::Arguments) {
    use io::native::file::FileDesc;
    use io;
    use libc;
    let mut out = FileDesc::new(libc::STDERR_FILENO, false);
    fmt::writeln(&mut out as &mut io::Writer, args);
}

pub fn abort(msg: &str) -> ! {
    let msg = if !msg.is_empty() { msg } else { "aborted" };
    let hash = msg.iter().fold(0, |accum, val| accum + (val as uint) );
    let quote = match hash % 10 {
        0 => "
It was from the artists and poets that the pertinent answers came, and I
know that panic would have broken loose had they been able to compare notes.
As it was, lacking their original letters, I half suspected the compiler of
having asked leading questions, or of having edited the correspondence in
corroboration of what he had latently resolved to see.",
        1 => "
There are not many persons who know what wonders are opened to them in the
stories and visions of their youth; for when as children we listen and dream,
we think but half-formed thoughts, and when as men we try to remember, we are
dulled and prosaic with the poison of life. But some of us awake in the night
with strange phantasms of enchanted hills and gardens, of fountains that sing
in the sun, of golden cliffs overhanging murmuring seas, of plains that stretch
down to sleeping cities of bronze and stone, and of shadowy companies of heroes
that ride caparisoned white horses along the edges of thick forests; and then
we know that we have looked back through the ivory gates into that world of
wonder which was ours before we were wise and unhappy.",
        2 => "
Instead of the poems I had hoped for, there came only a shuddering blackness
and ineffable loneliness; and I saw at last a fearful truth which no one had
ever dared to breathe before — the unwhisperable secret of secrets — The fact
that this city of stone and stridor is not a sentient perpetuation of Old New
York as London is of Old London and Paris of Old Paris, but that it is in fact
quite dead, its sprawling body imperfectly embalmed and infested with queer
animate things which have nothing to do with it as it was in life.",
        3 => "
The ocean ate the last of the land and poured into the smoking gulf, thereby
giving up all it had ever conquered. From the new-flooded lands it flowed
again, uncovering death and decay; and from its ancient and immemorial bed it
trickled loathsomely, uncovering nighted secrets of the years when Time was
young and the gods unborn. Above the waves rose weedy remembered spires. The
moon laid pale lilies of light on dead London, and Paris stood up from its damp
grave to be sanctified with star-dust. Then rose spires and monoliths that were
weedy but not remembered; terrible spires and monoliths of lands that men never
knew were lands...",
        4 => "
There was a night when winds from unknown spaces whirled us irresistibly into
limitless vacuum beyond all thought and entity. Perceptions of the most
maddeningly untransmissible sort thronged upon us; perceptions of infinity
which at the time convulsed us with joy, yet which are now partly lost to my
memory and partly incapable of presentation to others.",
        _ => "You've met with a terrible fate, haven't you?"
    };
    rterrln!("{}", "");
    rterrln!("{}", quote);
    rterrln!("{}", "");
    rterrln!("fatal runtime error: {}", msg);

    abort();

    fn abort() -> ! {
        unsafe { libc::abort() }
    }
}

static mut EXIT_STATUS: AtomicInt = INIT_ATOMIC_INT;

pub fn set_exit_status(code: int) {
    unsafe { EXIT_STATUS.store(code, SeqCst) }
}

pub fn get_exit_status() -> int {
    unsafe { EXIT_STATUS.load(SeqCst) }
}
<|endoftext|>


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

// Check that trans doesn't ICE when translating an array repeat
// expression with a count of 1 and a non-Copy element type.

fn main() {
    let _ = [box 1u, ..1];
}
<|endoftext|>


<commit_before><commit_msg>added thread example<commit_after>use std::thread;

static NTHREADS: i32 = 10;

// This is the `main` thread
fn main() {
    let mut thread_vec: Vec<_> = Vec::new();

    for i in 0..NTHREADS {
        // Spawn up another thread
        let child = thread::spawn(move || {
            println!("this is thread number {}", i)
        });
        thread_vec.push(child);
    }

    for handle in thread_vec {
        handle.join().unwrap();
    }
}<|endoftext|>


<commit_before><commit_msg>Check in a forgotten new file<commit_after>import syntax::ast::*;
import syntax::visit;
import driver::session::session;

type ctx = {in_loop: bool, can_ret: bool};

fn check_crate(sess: session, crate: @crate) {
    visit::visit_crate(*crate, {in_loop: false,can_ret: true}, visit::mk_vt(@{
        visit_item: {|i, _cx, v|
            visit::visit_item(i, {in_loop: false, can_ret: true}, v);
        },
        visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
            alt e.node {
              expr_for(_, e, b) | expr_while(e, b) | expr_do_while(b, e) {
                v.visit_expr(e, cx, v);
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_loop(b) {
                v.visit_block(b, {in_loop: true with cx}, v);
              }
              expr_fn(_, _, _, _) {
                visit::visit_expr(e, {in_loop: false, can_ret: true}, v);
              }
              expr_fn_block(fn_decl, blk) {
                visit::visit_expr(e, {in_loop: false, can_ret: false}, v);
              }
              expr_break {
                if !cx.in_loop {
                    sess.span_err(e.span, "`break` outside of loop");
                }
              }
              expr_cont {
                if !cx.in_loop {
                    sess.span_err(e.span, "`cont` outside of loop");
                }
              }
              expr_ret(oe) {
                if !cx.can_ret {
                    sess.span_err(e.span, "`ret` in block function");
                }
                visit::visit_expr_opt(oe, cx, v);
              }
              expr_be(re) {
                if !cx.can_ret {
                    sess.span_err(e.span, "`be` in block function");
                }
                v.visit_expr(re, cx, v);
              }
              _ { visit::visit_expr(e, cx, v); }
            }
        }
        with *visit::default_visitor()
    }));
}<|endoftext|>


<commit_before><commit_msg>Add mir opt test for AddressOf<commit_after>fn address_of_reborrow() {
    let y = &[0; 10];
    let mut z = &mut [0; 10];

    y as *const _;
    y as *const [i32; 10];
    y as *const dyn Send;
    y as *const [i32];
    y as *const i32;            // This is a cast, not a coercion

    let p: *const _ = y;
    let p: *const [i32; 10] = y;
    let p: *const dyn Send = y;
    let p: *const [i32] = y;

    z as *const _;
    z as *const [i32; 10];
    z as *const dyn Send;
    z as *const [i32];

    let p: *const _ = z;
    let p: *const [i32; 10] = z;
    let p: *const dyn Send = z;
    let p: *const [i32] = z;

    z as *mut _;
    z as *mut [i32; 10];
    z as *mut dyn Send;
    z as *mut [i32];

    let p: *mut _ = z;
    let p: *mut [i32; 10] = z;
    let p: *mut dyn Send = z;
    let p: *mut [i32] = z;
}

// The normal borrows here should be preserved
fn borrow_and_cast(mut x: i32) {
    let p = &x as *const i32;
    let q = &mut x as *const i32;
    let r = &mut x as *mut i32;
}

fn main() {}

// START rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
// bb0: {
//  ...
//  _5 = &raw const (*_1); // & to *const casts
//  ...
//  _7 = &raw const (*_1);
//  ...
//  _11 = &raw const (*_1);
//  ...
//  _14 = &raw const (*_1);
//  ...
//  _16 = &raw const (*_1);
//  ...
//  _17 = &raw const (*_1); // & to *const coercions
//  ...
//  _18 = &raw const (*_1);
//  ...
//  _20 = &raw const (*_1);
//  ...
//  _22 = &raw const (*_1);
// ...
//  _24 = &raw const (*_2); // &mut to *const casts
// ...
//  _26 = &raw const (*_2);
// ...
//  _30 = &raw const (*_2);
// ...
//  _33 = &raw const (*_2);
// ...
//  _34 = &raw const (*_2); // &mut to *const coercions
// ...
//  _35 = &raw const (*_2);
// ...
//  _37 = &raw const (*_2);
// ...
//  _39 = &raw const (*_2);
// ...
//  _41 = &raw mut (*_2); // &mut to *mut casts
// ...
//  _43 = &raw mut (*_2);
// ...
//  _47 = &raw mut (*_2);
// ...
//  _50 = &raw mut (*_2);
// ...
//  _51 = &raw mut (*_2); // &mut to *mut coercions
// ...
//  _52 = &raw mut (*_2);
// ...
//  _54 = &raw mut (*_2);
// ...
//  _56 = &raw mut (*_2);
// ...
// }
// END rustc.address_of_reborrow.SimplifyCfg-initial.after.mir

// START rustc.borrow_and_cast.EraseRegions.after.mir
// bb0: {
//  ...
//  _4 = &_1;
//  ...
//  _7 = &mut _1;
//  ...
//  _10 = &mut _1;
//  ...
// }
// END rustc.borrow_and_cast.EraseRegions.after.mir
<|endoftext|>


<commit_before><commit_msg>Add test for #43398<commit_after>// run-pass

#![feature(core_intrinsics)]
#![feature(repr128)]

#[repr(i128)]
enum Big { A, B }

fn main() {
    unsafe {
        println!("{} {:?}",
            std::intrinsics::discriminant_value(&Big::A),
            std::mem::discriminant(&Big::B));
    }
}
<|endoftext|>


<commit_before><commit_msg>Add a test for #44255<commit_after>// run-pass

use std::marker::PhantomData;

fn main() {
    let _arr = [1; <Multiply<Five, Five>>::VAL];
}

trait TypeVal<T> {
    const VAL: T;
}

struct Five;

impl TypeVal<usize> for Five {
    const VAL: usize = 5;
}

struct Multiply<N, M> {
    _n: PhantomData<N>,
    _m: PhantomData<M>,
}

impl<N, M> TypeVal<usize> for Multiply<N, M>
    where N: TypeVal<usize>,
          M: TypeVal<usize>,
{
    const VAL: usize = N::VAL * M::VAL;
}
<|endoftext|>


<commit_before>use alloc::arc::*;

use common::memory::*;
use common::pci::*;
use common::pio::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

pub struct IDERequest {
    pub sector: u64,
    pub count: u64,
    pub destination: usize,
    pub callback: Box<FnBox(usize)>
}

pub struct IDE {
    pub bus: usize,
    pub slot: usize,
    pub func: usize,
    pub base: usize,
    pub memory_mapped: bool,
    pub requests: Vec<IDERequest>
}

impl SessionItem for IDE {
    fn on_irq(&mut self, irq: u8){
        if irq == 0xE || irq == 0xF {
            self.on_poll();
        }
    }

    fn on_poll(&mut self){
        unsafe {
            let base = self.base as u16;

            let command = inb(base);
            let status = inb(base + 2);
            if status & 4 == 4 {
                d("IDE");

                d(" Status ");
                dbh(status);

                outb(base + 0x2, status);
                let new_status = inb(base + 0x2);

                d(" to ");
                dbh(new_status);

                d(" Command ");
                dbh(command);

                if command & 1 == 1 && new_status & 1 == 0 {
                    outb(base, 0);

                    d(" to ");
                    dbh(inb(base));

                    d(" DMA COMPLETED");

                    //WARNING: This should be stored in request.prdt
                    let prdt = ind(base + 0x4) as usize & 0xFFFF0000;
                    outd(base + 0x4, 0);

                    d(" PRDT ");
                    dh(prdt);

                    if prdt > 0 {
                        //WARNING: This should be compared to request.destination
                        let destination = (*(prdt as *const PRDTE)).ptr as usize;
                        unalloc(prdt);

                        match self.requests.remove(0){
                            Option::Some(request) => (request.callback)(request.destination),
                            Option::None => ()
                        }

                        match self.requests.get(0) {
                            Option::Some(request) => {
                                d(" NEXT ");
                                dd(request.sector as usize);
                                d(" ");
                                dd(request.count as usize);

                                let disk = Disk::primary_master();
                                disk.read_dma(request.sector, request.count, request.destination, base);
                            },
                            Option::None => ()
                        }
                    }
                }

                dl();
            }
        }
    }

    fn scheme(&self) -> String {
        return "ide".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        let data: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0xFFFFFFFF));
        let data_callback = data.clone();

        let mut request = IDERequest {
            sector: 1,
            count: 1,
            destination: 0,
            callback: box move |destination: usize|{
                data_callback.store(destination, Ordering::SeqCst);
            }
        };

        let mut i = 0;
        for part in url.path_parts().iter() {
            match i {
                0 => request.sector = part.to_num() as u64,
                1 => request.count = part.to_num() as u64,
                _ => ()
            }
            i += 1;
        }

        let url = URL::from_string(&("ide:///".to_string() + request.sector as usize + "/" + request.count as usize));

        unsafe {
            if request.count > 0 {
                request.destination = alloc(request.count as usize * 512);
                if request.destination > 0 {
                    let reenable = start_no_ints();
                    self.requests.push(request);
                    if self.requests.len() == 1 {
                        match self.requests.get(0) {
                            Option::Some(request) => {
                                d("IDE DMA Request ");
                                dd(request.sector as usize);
                                d(" ");
                                dd(request.count as usize);

                                let disk = Disk::primary_master();
                                disk.read_dma(request.sector, request.count, request.destination, self.base as u16);

                                dl();
                            },
                            Option::None => ()
                        }
                    }
                    end_no_ints(reenable);
                }
            }

            while data.load(Ordering::SeqCst) == 0xFFFFFFFF {
                sys_yield();
            }

            let destination = data.load(Ordering::SeqCst);
            if destination > 0 {
                return box VecResource::new(url, ResourceType::File, Vec::<u8> {
                    data: destination as *mut u8,
                    length: alloc_size(destination)
                });
            }else{
                return box NoneResource;
            }
        }
    }
}

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

        pci_write(self.bus, self.slot, self.func, 0x04, pci_read(self.bus, self.slot, self.func, 0x04) | (1 << 2)); // Bus mastering

        let base = self.base as u16;

        d(" PRDT ");
        dh(ind(base + 0x4) as usize);

        d(" CMD ");
        dbh(inb(base));

        d(" STS ");
        dbh(inb(base + 0x2));

        dl();
    }
}
<commit_msg>Go back to PIO for real hardware testing, there is still a small bug in DMA<commit_after>use alloc::arc::*;

use common::memory::*;
use common::pci::*;
use common::pio::*;
use common::scheduler::*;

use drivers::disk::*;

use programs::common::*;

pub struct IDERequest {
    pub sector: u64,
    pub count: u64,
    pub destination: usize,
    pub callback: Box<FnBox(usize)>
}

pub struct IDE {
    pub bus: usize,
    pub slot: usize,
    pub func: usize,
    pub base: usize,
    pub memory_mapped: bool,
    pub requests: Vec<IDERequest>
}

impl SessionItem for IDE {
    fn on_irq(&mut self, irq: u8){
        if irq == 0xE || irq == 0xF {
            self.on_poll();
        }
    }

    fn on_poll(&mut self){
        unsafe {
            let base = self.base as u16;

            let command = inb(base);
            let status = inb(base + 2);
            if status & 4 == 4 {
                d("IDE");

                d(" Status ");
                dbh(status);

                outb(base + 0x2, status);
                let new_status = inb(base + 0x2);

                d(" to ");
                dbh(new_status);

                d(" Command ");
                dbh(command);

                if command & 1 == 1 && new_status & 1 == 0 {
                    outb(base, 0);

                    d(" to ");
                    dbh(inb(base));

                    d(" DMA COMPLETED");

                    //WARNING: This should be stored in request.prdt
                    let prdt = ind(base + 0x4) as usize & 0xFFFF0000;
                    outd(base + 0x4, 0);

                    d(" PRDT ");
                    dh(prdt);

                    if prdt > 0 {
                        //WARNING: This should be compared to request.destination
                        let destination = (*(prdt as *const PRDTE)).ptr as usize;
                        unalloc(prdt);

                        match self.requests.remove(0){
                            Option::Some(request) => (request.callback)(request.destination),
                            Option::None => ()
                        }

                        match self.requests.get(0) {
                            Option::Some(request) => {
                                d(" NEXT ");
                                dd(request.sector as usize);
                                d(" ");
                                dd(request.count as usize);

                                let disk = Disk::primary_master();
                                disk.read_dma(request.sector, request.count, request.destination, base);
                            },
                            Option::None => ()
                        }
                    }
                }

                dl();
            }
        }
    }

    fn scheme(&self) -> String {
        return "ide".to_string();
    }

    fn open(&mut self, url: &URL) -> Box<Resource> {
        let data: Arc<AtomicUsize> = Arc::new(AtomicUsize::new(0xFFFFFFFF));
        let data_callback = data.clone();

        let mut request = IDERequest {
            sector: 1,
            count: 1,
            destination: 0,
            callback: box move |destination: usize|{
                data_callback.store(destination, Ordering::SeqCst);
            }
        };

        let mut i = 0;
        for part in url.path_parts().iter() {
            match i {
                0 => request.sector = part.to_num() as u64,
                1 => request.count = part.to_num() as u64,
                _ => ()
            }
            i += 1;
        }

        let url = URL::from_string(&("ide:///".to_string() + request.sector as usize + "/" + request.count as usize));

        unsafe {
            if request.count > 0 {
                request.destination = alloc(request.count as usize * 512);
                if request.destination > 0 {
                    let reenable = start_no_ints();
                    d("IDE PIO Request ");
                    dd(request.sector as usize);
                    d(" ");
                    dd(request.count as usize);

                    let disk = Disk::primary_master();
                    disk.read(request.sector, request.count as u16, request.destination);
                    (request.callback)(request.destination);

                    dl();

                    /* DMA
                    self.requests.push(request);
                    if self.requests.len() == 1 {
                        match self.requests.get(0) {
                            Option::Some(request) => {
                                d("IDE DMA Request ");
                                dd(request.sector as usize);
                                d(" ");
                                dd(request.count as usize);

                                let disk = Disk::primary_master();
                                disk.read_dma(request.sector, request.count, request.destination, self.base as u16);

                                dl();
                            },
                            Option::None => ()
                        }
                    }
                    */
                    end_no_ints(reenable);
                }
            }

            while data.load(Ordering::SeqCst) == 0xFFFFFFFF {
                sys_yield();
            }

            let destination = data.load(Ordering::SeqCst);
            if destination > 0 {
                return box VecResource::new(url, ResourceType::File, Vec::<u8> {
                    data: destination as *mut u8,
                    length: alloc_size(destination)
                });
            }else{
                return box NoneResource;
            }
        }
    }
}

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

        pci_write(self.bus, self.slot, self.func, 0x04, pci_read(self.bus, self.slot, self.func, 0x04) | (1 << 2)); // Bus mastering

        let base = self.base as u16;

        d(" PRDT ");
        dh(ind(base + 0x4) as usize);

        d(" CMD ");
        dbh(inb(base));

        d(" STS ");
        dbh(inb(base + 0x2));

        dl();
    }
}
<|endoftext|>


<commit_before><commit_msg>:sparkles: Add fetch_rescheduled_tasks<commit_after><|endoftext|>


<commit_before><commit_msg>DenseVector: Inner product<commit_after><|endoftext|>


<commit_before><commit_msg>Changed indention with whitespaces to idention with tabs so everyone can ident the code they want.<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify cycle search in the solution for Day 13<commit_after><|endoftext|>


<commit_before><commit_msg>Test illustrating issue #2263.<commit_after>//xfail-test

// Issue #2263.

// Should pass region checking.
fn ok(f: fn@(x: &uint)) {
    // Here, g is a function that can accept a uint pointer with
    // lifetime r, and f is a function that can accept a uint pointer
    // with any lifetime.  The assignment g = f should be OK (i.e., f
    // should be a subtype of g), because f can be used in any context
    // that expects g's type.  But this currently fails.
    let mut g: fn@(y: &r.uint) = fn@(x: &r.uint) { };
    g = f;
}

// This version is the same as above, except that here, g's type is
// inferred.
fn ok_inferred(f: fn@(x: &uint)) {
    let mut g = fn@(x: &r.uint) { };
    g = f;
}

fn main() {
}
<|endoftext|>


<commit_before>use std::io;
use std::cmp;
use std::str;
use std::slice;
use std::io::IoResult;
use std::io::MemReader;

use colortype;
use hash::Crc32;
use zlib::ZlibDecoder;

use image;
use image::ImageResult;
use image::ImageDecoder;

use super::filter::unfilter;
use super::PNGSIGNATURE;

macro_rules! io_try(
    ($e:expr) => (
    	match $e {
    		Ok(e) => e,
    		Err(_) => return Err(image::IoError)
    	}
    )
)

#[deriving(PartialEq)]
enum PNGState {
	Start,
	HaveSignature,
	HaveIHDR,
	HavePLTE,
	HaveFirstIDat,
	HaveLastIDat,
	HaveIEND
}

/// The representation of a PNG decoder
///
/// Currently does not support decoding of interlaced images
pub struct PNGDecoder<R> {
	z: ZlibDecoder<IDATReader<R>>,
	crc: Crc32,
	previous: Vec<u8>,
	state: PNGState,

	width: u32,
	height: u32,

	bit_depth: u8,
	colour_type: u8,
	pixel_type: colortype::ColorType,

	palette: Option<Vec<(u8, u8, u8)>>,

	interlace_method: u8,

	chunk_length: u32,
	chunk_type: Vec<u8>,

	bpp: uint,
	rlength: uint,
	decoded_rows: u32,
}

impl<R: Reader> PNGDecoder<R> {
	/// Create a new decoder that decodes from the stream ```r```
	pub fn new(r: R) -> PNGDecoder<R> {
		let idat_reader = IDATReader::new(r);
		PNGDecoder {
			pixel_type: colortype::Grey(1),
			palette: None,

			previous: Vec::new(),
			state: Start,
			z: ZlibDecoder::new(idat_reader),
			crc: Crc32::new(),

			width: 0,
			height: 0,
			bit_depth: 0,
			colour_type: 0,
			interlace_method: 0,

			chunk_length: 0,
			chunk_type: Vec::new(),
			bpp: 0,
			rlength: 0,
			decoded_rows: 0,
		}
	}

	///Returns a reference to the color palette used for indexed
	///color images.
	///Each array element is a tuple of RGB values.
	pub fn palette<'a>(&'a self) -> &'a [(u8, u8, u8)] {
		match self.palette {
			Some(ref p) => p.as_slice(),
			None        => &[]
		}
	}

	fn read_signature(&mut self) -> ImageResult<bool> {
		let png = io_try!(self.z.inner().r.read_exact(8));

		Ok(png.as_slice() == PNGSIGNATURE)
	}

	fn parse_ihdr(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());
		let mut m = MemReader::new(buf);

		self.width = m.read_be_u32().unwrap();
		self.height = m.read_be_u32().unwrap();

		self.bit_depth = m.read_byte().unwrap();
		self.colour_type = m.read_byte().unwrap();

		self.pixel_type = match (self.colour_type, self.bit_depth) {
			(0, 1)  => colortype::Grey(1),
			(0, 2)  => colortype::Grey(2),
			(0, 4)  => colortype::Grey(4),
			(0, 8)  => colortype::Grey(8),
			(0, 16) => colortype::Grey(16),
			(2, 8)  => colortype::RGB(8),
			(2, 16) => colortype::RGB(16),
			(3, 1)  => colortype::RGB(8),
			(3, 2)  => colortype::RGB(8),
			(3, 4)  => colortype::RGB(8),
			(3, 8)  => colortype::RGB(8),
			(4, 8)  => colortype::GreyA(8),
			(4, 16) => colortype::GreyA(16),
			(6, 8)  => colortype::RGBA(8),
			(6, 16) => colortype::RGBA(16),
			(_, _)  => return Err(image::FormatError)
		};

		let compression_method = m.read_byte().unwrap();
		if compression_method != 0 {
			return Err(image::UnsupportedError)
		}

		let filter_method = m.read_byte().unwrap();
		if filter_method != 0 {
			return Err(image::UnsupportedError)
		}

		self.interlace_method = m.read_byte().unwrap();
		if self.interlace_method != 0 {
			return Err(image::UnsupportedError)
		}

		let channels = match self.colour_type {
			0 => 1,
			2 => 3,
			3 => 1,
			4 => 2,
			6 => 4,
			_ => return Err(image::FormatError)
		};

		let bits_per_pixel = channels * self.bit_depth as uint;

		self.rlength = (bits_per_pixel * self.width as uint + 7) / 8;
		self.bpp = (bits_per_pixel + 7) / 8;
		self.previous = Vec::from_elem(self.rlength as uint, 0u8);

		Ok(())
	}

	fn parse_plte(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());

		let len = buf.len() / 3;

		if len > 256 || len > (1 << self.bit_depth) || buf.len() % 3 != 0{
			return Err(image::FormatError)
		}

		let p = Vec::from_fn(256, |i| {
			if i < len {
				let r = buf.as_slice()[3 * i];
				let g = buf.as_slice()[3 * i + 1];
				let b = buf.as_slice()[3 * i + 2];

				(r, g, b)
			}
			else {
				(0, 0, 0)
			}
		});

		self.palette = Some(p);

		Ok(())
	}

	fn read_metadata(&mut self) -> ImageResult<()> {
		if !try!(self.read_signature()) {
			return Err(image::FormatError)
		}

		self.state = HaveSignature;

		loop {
			let length = io_try!(self.z.inner().r.read_be_u32());
			let chunk  = io_try!(self.z.inner().r.read_exact(4));

			self.chunk_length = length;
			self.chunk_type   = chunk.clone();

			self.crc.update(chunk);

			let s = {
				let a = str::from_utf8_owned(self.chunk_type.clone());
				a.unwrap()
			};

			match (s.as_slice(), self.state) {
				("IHDR", HaveSignature) => {
					if length != 13 {
						return Err(image::FormatError)
					}

					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_ihdr(d));

					self.state = HaveIHDR;
				}

				("PLTE", HaveIHDR) => {
					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_plte(d));
					self.state = HavePLTE;
				}

				("tRNS", HavePLTE) => {
					return Err(image::UnsupportedError)
				}

				("IDAT", HaveIHDR) if self.colour_type != 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				("IDAT", HavePLTE) if self.colour_type == 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				_ => {
					let b = io_try!(self.z.inner().r.read_exact(length as uint));
					self.crc.update(b);
				}
			}

			let chunk_crc = io_try!(self.z.inner().r.read_be_u32());
			let crc = self.crc.checksum();

			if crc != chunk_crc {
				return Err(image::FormatError)
			}

			self.crc.reset();
		}

		Ok(())
	}
}

impl<R: Reader> ImageDecoder for PNGDecoder<R> {
	fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok((self.width, self.height))
	}

	fn colortype(&mut self) -> ImageResult<colortype::ColorType> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok(self.pixel_type)
	}

	fn row_len(&mut self) -> ImageResult<uint> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let bits = colortype::bits_per_pixel(self.pixel_type);

		Ok((bits * self.width as uint + 7) / 8)
	}

	fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let filter_type = match FromPrimitive::from_u8(io_try!(self.z.read_byte())) {
			Some(v) => v,
			_ => return Err(image::FormatError)
		};

		let mut read = 0;
		while read < self.rlength {
			let r = io_try!(self.z.read(buf.mut_slice_from(read)));
			read += r;
		}

		unfilter(filter_type, self.bpp, self.previous.as_slice(), buf.mut_slice_to(self.rlength));
		slice::bytes::copy_memory(self.previous.as_mut_slice(), buf.slice_to(self.rlength));

		if self.palette.is_some() {
			let s = (*self.palette.get_ref()).as_slice();
			expand_palette(buf, s, self.rlength);
		}

		self.decoded_rows += 1;

		Ok(self.decoded_rows)
	}

	fn read_image(&mut self) -> ImageResult<Vec<u8>> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let rowlen  = try!(self.row_len());
		let mut buf = Vec::from_elem(rowlen * self.height as uint, 0u8);

		for chunk in buf.as_mut_slice().mut_chunks(rowlen) {
			let _ = try!(self.read_scanline(chunk));
		}

		Ok(buf)
	}
}

fn expand_palette(buf: &mut[u8], palette: &[(u8, u8, u8)], entries: uint) {
	assert!(buf.len() == entries * 3);
	let tmp = Vec::from_fn(entries, |i| buf[i]);

	for (chunk, &i) in buf.mut_chunks(3).zip(tmp.iter()) {
		let (r, g, b) = palette[i as uint];
		chunk[0] = r;
		chunk[1] = g;
		chunk[2] = b;
	}
}

pub struct IDATReader<R> {
	pub r: R,
	pub crc: Crc32,

	eof: bool,
	chunk_length: u32,
}

impl<R:Reader> IDATReader<R> {
	pub fn new(r: R) -> IDATReader<R> {
		IDATReader {
			r: r,
			crc: Crc32::new(),
			eof: false,
			chunk_length: 0,
		}
	}

	pub fn set_inital_length(&mut self, len: u32) {
		self.chunk_length = len;
	}
}

impl<R: Reader> Reader for IDATReader<R> {
	fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
		if self.eof {
			return Err(io::standard_error(io::EndOfFile))
		}

		let len = buf.len();
		let mut start = 0;

		while start < len {
			while self.chunk_length == 0 {
				let chunk_crc = try!(self.r.read_be_u32());
				let crc = self.crc.checksum();

				if crc != chunk_crc {
					return Err(io::standard_error(io::InvalidInput))
				}

				self.crc.reset();

				self.chunk_length = try!(self.r.read_be_u32());

				let v = try!(self.r.read_exact(4));
				self.crc.update(v.as_slice());

				match str::from_utf8(v.as_slice()) {
					Some("IDAT") => (),
					_ 	     => {
						self.eof = true;
						break
					}
				}
			}

			let m = cmp::min(len - start, self.chunk_length as uint);

			let slice = buf.mut_slice(start, start + m);
			let r = try!(self.r.read(slice));

			start += r;

			self.chunk_length -= r as u32;
			self.crc.update(slice.as_slice());
		}

		Ok(start)
	}
}
<commit_msg>Check CRC of last IDAT chunk<commit_after>use std::io;
use std::cmp;
use std::str;
use std::slice;
use std::io::IoResult;
use std::io::MemReader;

use colortype;
use hash::Crc32;
use zlib::ZlibDecoder;

use image;
use image::ImageResult;
use image::ImageDecoder;

use super::filter::unfilter;
use super::PNGSIGNATURE;

macro_rules! io_try(
    ($e:expr) => (
    	match $e {
    		Ok(e) => e,
    		Err(_) => return Err(image::IoError)
    	}
    )
)

#[deriving(PartialEq)]
enum PNGState {
	Start,
	HaveSignature,
	HaveIHDR,
	HavePLTE,
	HaveFirstIDat,
	HaveLastIDat,
	HaveIEND
}

/// The representation of a PNG decoder
///
/// Currently does not support decoding of interlaced images
pub struct PNGDecoder<R> {
	z: ZlibDecoder<IDATReader<R>>,
	crc: Crc32,
	previous: Vec<u8>,
	state: PNGState,

	width: u32,
	height: u32,

	bit_depth: u8,
	colour_type: u8,
	pixel_type: colortype::ColorType,

	palette: Option<Vec<(u8, u8, u8)>>,

	interlace_method: u8,

	chunk_length: u32,
	chunk_type: Vec<u8>,

	bpp: uint,
	rlength: uint,
	decoded_rows: u32,
}

impl<R: Reader> PNGDecoder<R> {
	/// Create a new decoder that decodes from the stream ```r```
	pub fn new(r: R) -> PNGDecoder<R> {
		let idat_reader = IDATReader::new(r);
		PNGDecoder {
			pixel_type: colortype::Grey(1),
			palette: None,

			previous: Vec::new(),
			state: Start,
			z: ZlibDecoder::new(idat_reader),
			crc: Crc32::new(),

			width: 0,
			height: 0,
			bit_depth: 0,
			colour_type: 0,
			interlace_method: 0,

			chunk_length: 0,
			chunk_type: Vec::new(),
			bpp: 0,
			rlength: 0,
			decoded_rows: 0,
		}
	}

	///Returns a reference to the color palette used for indexed
	///color images.
	///Each array element is a tuple of RGB values.
	pub fn palette<'a>(&'a self) -> &'a [(u8, u8, u8)] {
		match self.palette {
			Some(ref p) => p.as_slice(),
			None        => &[]
		}
	}

	fn read_signature(&mut self) -> ImageResult<bool> {
		let png = io_try!(self.z.inner().r.read_exact(8));

		Ok(png.as_slice() == PNGSIGNATURE)
	}

	fn parse_ihdr(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());
		let mut m = MemReader::new(buf);

		self.width = m.read_be_u32().unwrap();
		self.height = m.read_be_u32().unwrap();

		self.bit_depth = m.read_byte().unwrap();
		self.colour_type = m.read_byte().unwrap();

		self.pixel_type = match (self.colour_type, self.bit_depth) {
			(0, 1)  => colortype::Grey(1),
			(0, 2)  => colortype::Grey(2),
			(0, 4)  => colortype::Grey(4),
			(0, 8)  => colortype::Grey(8),
			(0, 16) => colortype::Grey(16),
			(2, 8)  => colortype::RGB(8),
			(2, 16) => colortype::RGB(16),
			(3, 1)  => colortype::RGB(8),
			(3, 2)  => colortype::RGB(8),
			(3, 4)  => colortype::RGB(8),
			(3, 8)  => colortype::RGB(8),
			(4, 8)  => colortype::GreyA(8),
			(4, 16) => colortype::GreyA(16),
			(6, 8)  => colortype::RGBA(8),
			(6, 16) => colortype::RGBA(16),
			(_, _)  => return Err(image::FormatError)
		};

		let compression_method = m.read_byte().unwrap();
		if compression_method != 0 {
			return Err(image::UnsupportedError)
		}

		let filter_method = m.read_byte().unwrap();
		if filter_method != 0 {
			return Err(image::UnsupportedError)
		}

		self.interlace_method = m.read_byte().unwrap();
		if self.interlace_method != 0 {
			return Err(image::UnsupportedError)
		}

		let channels = match self.colour_type {
			0 => 1,
			2 => 3,
			3 => 1,
			4 => 2,
			6 => 4,
			_ => return Err(image::FormatError)
		};

		let bits_per_pixel = channels * self.bit_depth as uint;

		self.rlength = (bits_per_pixel * self.width as uint + 7) / 8;
		self.bpp = (bits_per_pixel + 7) / 8;
		self.previous = Vec::from_elem(self.rlength as uint, 0u8);

		Ok(())
	}

	fn parse_plte(&mut self, buf: Vec<u8>) -> ImageResult<()> {
		self.crc.update(buf.as_slice());

		let len = buf.len() / 3;

		if len > 256 || len > (1 << self.bit_depth) || buf.len() % 3 != 0{
			return Err(image::FormatError)
		}

		let p = Vec::from_fn(256, |i| {
			if i < len {
				let r = buf.as_slice()[3 * i];
				let g = buf.as_slice()[3 * i + 1];
				let b = buf.as_slice()[3 * i + 2];

				(r, g, b)
			}
			else {
				(0, 0, 0)
			}
		});

		self.palette = Some(p);

		Ok(())
	}

	fn read_metadata(&mut self) -> ImageResult<()> {
		if !try!(self.read_signature()) {
			return Err(image::FormatError)
		}

		self.state = HaveSignature;

		loop {
			let length = io_try!(self.z.inner().r.read_be_u32());
			let chunk  = io_try!(self.z.inner().r.read_exact(4));

			self.chunk_length = length;
			self.chunk_type   = chunk.clone();

			self.crc.update(chunk);

			let s = {
				let a = str::from_utf8_owned(self.chunk_type.clone());
				a.unwrap()
			};

			match (s.as_slice(), self.state) {
				("IHDR", HaveSignature) => {
					if length != 13 {
						return Err(image::FormatError)
					}

					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_ihdr(d));

					self.state = HaveIHDR;
				}

				("PLTE", HaveIHDR) => {
					let d = io_try!(self.z.inner().r.read_exact(length as uint));
					try!(self.parse_plte(d));
					self.state = HavePLTE;
				}

				("tRNS", HavePLTE) => {
					return Err(image::UnsupportedError)
				}

				("IDAT", HaveIHDR) if self.colour_type != 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				("IDAT", HavePLTE) if self.colour_type == 3 => {
					self.state = HaveFirstIDat;
					self.z.inner().set_inital_length(self.chunk_length);
					self.z.inner().crc.update(self.chunk_type.as_slice());

					break;
				}

				_ => {
					let b = io_try!(self.z.inner().r.read_exact(length as uint));
					self.crc.update(b);
				}
			}

			let chunk_crc = io_try!(self.z.inner().r.read_be_u32());
			let crc = self.crc.checksum();

			if crc != chunk_crc {
				return Err(image::FormatError)
			}

			self.crc.reset();
		}

		Ok(())
	}
}

impl<R: Reader> ImageDecoder for PNGDecoder<R> {
	fn dimensions(&mut self) -> ImageResult<(u32, u32)> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok((self.width, self.height))
	}

	fn colortype(&mut self) -> ImageResult<colortype::ColorType> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		Ok(self.pixel_type)
	}

	fn row_len(&mut self) -> ImageResult<uint> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let bits = colortype::bits_per_pixel(self.pixel_type);

		Ok((bits * self.width as uint + 7) / 8)
	}

	fn read_scanline(&mut self, buf: &mut [u8]) -> ImageResult<u32> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let filter_type = match FromPrimitive::from_u8(io_try!(self.z.read_byte())) {
			Some(v) => v,
			_ => return Err(image::FormatError)
		};

		let mut read = 0;
		while read < self.rlength {
			let r = io_try!(self.z.read(buf.mut_slice_from(read)));
			read += r;
		}

		unfilter(filter_type, self.bpp, self.previous.as_slice(), buf.mut_slice_to(self.rlength));
		slice::bytes::copy_memory(self.previous.as_mut_slice(), buf.slice_to(self.rlength));

		if self.palette.is_some() {
			let s = (*self.palette.get_ref()).as_slice();
			expand_palette(buf, s, self.rlength);
		}

		self.decoded_rows += 1;

		Ok(self.decoded_rows)
	}

	fn read_image(&mut self) -> ImageResult<Vec<u8>> {
		if self.state == Start {
			let _ = try!(self.read_metadata());
		}

		let rowlen  = try!(self.row_len());
		let mut buf = Vec::from_elem(rowlen * self.height as uint, 0u8);

		for chunk in buf.as_mut_slice().mut_chunks(rowlen) {
			let _ = try!(self.read_scanline(chunk));
		}

		Ok(buf)
	}
}

fn expand_palette(buf: &mut[u8], palette: &[(u8, u8, u8)], entries: uint) {
	assert!(buf.len() == entries * 3);
	let tmp = Vec::from_fn(entries, |i| buf[i]);

	for (chunk, &i) in buf.mut_chunks(3).zip(tmp.iter()) {
		let (r, g, b) = palette[i as uint];
		chunk[0] = r;
		chunk[1] = g;
		chunk[2] = b;
	}
}

pub struct IDATReader<R> {
	pub r: R,
	pub crc: Crc32,

	eof: bool,
	chunk_length: u32,
}

impl<R:Reader> IDATReader<R> {
	pub fn new(r: R) -> IDATReader<R> {
		IDATReader {
			r: r,
			crc: Crc32::new(),
			eof: false,
			chunk_length: 0,
		}
	}

	pub fn set_inital_length(&mut self, len: u32) {
		self.chunk_length = len;
	}
}

impl<R: Reader> Reader for IDATReader<R> {
	fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
		if self.eof {
			return Err(io::standard_error(io::EndOfFile))
		}

		let len = buf.len();
		let mut start = 0;

		while start < len {
			let m = cmp::min(len - start, self.chunk_length as uint);

			let slice = buf.mut_slice(start, start + m);
			let r = try!(self.r.read(slice));

			start += r;

			self.chunk_length -= r as u32;
			self.crc.update(slice.as_slice());

			if self.chunk_length == 0 {
				let chunk_crc = try!(self.r.read_be_u32());
				let crc = self.crc.checksum();
				if crc != chunk_crc {
					return Err(io::standard_error(io::InvalidInput))
				}

				self.crc.reset();

				self.chunk_length = try!(self.r.read_be_u32());

				let v = try!(self.r.read_exact(4));
				self.crc.update(v.as_slice());

				match str::from_utf8(v.as_slice()) {
					Some("IDAT") => (),
					_ 	     => {
						self.eof = true;
						break
					}
				}
			}
		}
		Ok(start)
	}
}<|endoftext|>


<commit_before><commit_msg>ensure UTF-8 BOM is never written<commit_after>// Copyright (c) IxMilia.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

extern crate dxf;

use std::io::{Cursor, Seek, SeekFrom};
use self::dxf::*;

mod test_helpers;

#[test]
fn dont_write_utf8_bom() {
    let drawing = Drawing::default();
    let mut buf = Cursor::new(vec![]);
    drawing.save(&mut buf).ok().unwrap();
    buf.seek(SeekFrom::Start(0)).ok().unwrap();
    let vec = buf.into_inner();

    // file should start directly with a code, not a UTF-8 BOM
    assert_eq!(b' ', vec[0]);
    assert_eq!(b' ', vec[1]);
    assert_eq!(b'0', vec[2]);
}
<|endoftext|>


<commit_before>import lib.llvm.llvm;
import lib.llvm.llvm.ModuleRef;
import std._str;
import std._vec;
import std.os.target_os;
import util.common.istr;

const int wordsz = 4;

fn wstr(int i) -> str {
    ret istr(i * wordsz);
}

fn save_callee_saves() -> vec[str] {
    ret vec("pushl %ebp",
            "pushl %edi",
            "pushl %esi",
            "pushl %ebx");
}

fn restore_callee_saves() -> vec[str] {
    ret vec("popl  %ebx",
            "popl  %esi",
            "popl  %edi",
            "popl  %ebp");
}

fn load_esp_from_rust_sp() -> vec[str] {
    ret vec("movl  " + wstr(abi.task_field_rust_sp) + "(%edx), %esp");
}

fn load_esp_from_runtime_sp() -> vec[str] {
    ret vec("movl  " + wstr(abi.task_field_runtime_sp) + "(%edx), %esp");
}

fn store_esp_to_rust_sp() -> vec[str] {
    ret vec("movl  %esp, " + wstr(abi.task_field_rust_sp) + "(%edx)");
}

fn store_esp_to_runtime_sp() -> vec[str] {
    ret vec("movl  %esp, " + wstr(abi.task_field_runtime_sp) + "(%edx)");
}

fn rust_activate_glue() -> vec[str] {
    ret vec("movl  4(%esp), %edx    # edx = rust_task")
        + save_callee_saves()
        + store_esp_to_runtime_sp()
        + load_esp_from_rust_sp()

        // This 'add' instruction is a bit surprising.
        // See lengthy comment in boot/be/x86.ml activate_glue.
        + vec("addl  $20, " + wstr(abi.task_field_rust_sp) + "(%edx)")

        + restore_callee_saves()
        + vec("ret");
}

fn rust_yield_glue() -> vec[str] {
    ret vec("movl  0(%esp), %edx    # edx = rust_task")
        + load_esp_from_rust_sp()
        + save_callee_saves()
        + store_esp_to_rust_sp()
        + load_esp_from_runtime_sp()
        + restore_callee_saves()
        + vec("ret");
}

fn upcall_glue(int n_args) -> vec[str] {

    /*
     * 0, 4, 8, 12 are callee-saves
     * 16 is retpc
     * 20 is taskptr
     * 24 is callee
     * 28 .. (7+i) * 4 are args
     */

    fn copy_arg(uint i) -> str {
        auto src_off = wstr(7 + (i as int));
        auto dst_off = wstr(1 + (i as int));
        auto m = vec("movl  " + src_off + "(%ebp),%edx",
                     "movl  %edx," + dst_off + "(%esp)");
        ret _str.connect(m, "\n\t");
    }

    auto carg = copy_arg;

    ret
        save_callee_saves()

        + vec("movl  %esp, %ebp     # ebp = rust_sp",
              "movl  20(%esp), %edx # edx = rust_task")

        + store_esp_to_rust_sp()
        + load_esp_from_runtime_sp()

        + vec("subl  $" + wstr(n_args + 1) + ", %esp   # esp -= args",
              "andl  $~0xf, %esp    # align esp down",
              "movl  %edx, (%esp)   # arg[0] = rust_task ")

        + _vec.init_fn[str](carg, n_args as uint)

        +  vec("movl  24(%ebp), %edx # edx = callee",
               "call  *%edx          # call *%edx",
               "movl  20(%ebp), %edx # edx = rust_task")

        + load_esp_from_rust_sp()
        + restore_callee_saves()
        + vec("ret");

}

fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
    auto sym = prefix + name;
    ret "\t.globl " + sym + "\n" +
        "\t.balign " + istr(align) + "\n" +
        sym + ":\n" +
        "\t" + _str.connect(insns, "\n\t");
}

fn decl_upcall_glue(int align, str prefix, uint n) -> str {
    let int i = n as int;
    ret decl_glue(align, prefix,
                  abi.upcall_glue_name(i),
                  upcall_glue(i));
}

fn get_module_asm() -> str {
    auto align = 4;

    auto prefix = "";
    if (target_os() == "macos") {
        prefix = "_";
    }

    auto glues =
        vec(decl_glue(align, prefix,
                      abi.activate_glue_name(),
                      rust_activate_glue()),

            decl_glue(align, prefix,
                      abi.yield_glue_name(),
                      rust_yield_glue()))

        + _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
                            abi.n_upcall_glues as uint);

    ret _str.connect(glues, "\n\n");
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Don't use string == in x86.rs, doesn't work.<commit_after>import lib.llvm.llvm;
import lib.llvm.llvm.ModuleRef;
import std._str;
import std._vec;
import std.os.target_os;
import util.common.istr;

const int wordsz = 4;

fn wstr(int i) -> str {
    ret istr(i * wordsz);
}

fn save_callee_saves() -> vec[str] {
    ret vec("pushl %ebp",
            "pushl %edi",
            "pushl %esi",
            "pushl %ebx");
}

fn restore_callee_saves() -> vec[str] {
    ret vec("popl  %ebx",
            "popl  %esi",
            "popl  %edi",
            "popl  %ebp");
}

fn load_esp_from_rust_sp() -> vec[str] {
    ret vec("movl  " + wstr(abi.task_field_rust_sp) + "(%edx), %esp");
}

fn load_esp_from_runtime_sp() -> vec[str] {
    ret vec("movl  " + wstr(abi.task_field_runtime_sp) + "(%edx), %esp");
}

fn store_esp_to_rust_sp() -> vec[str] {
    ret vec("movl  %esp, " + wstr(abi.task_field_rust_sp) + "(%edx)");
}

fn store_esp_to_runtime_sp() -> vec[str] {
    ret vec("movl  %esp, " + wstr(abi.task_field_runtime_sp) + "(%edx)");
}

fn rust_activate_glue() -> vec[str] {
    ret vec("movl  4(%esp), %edx    # edx = rust_task")
        + save_callee_saves()
        + store_esp_to_runtime_sp()
        + load_esp_from_rust_sp()

        // This 'add' instruction is a bit surprising.
        // See lengthy comment in boot/be/x86.ml activate_glue.
        + vec("addl  $20, " + wstr(abi.task_field_rust_sp) + "(%edx)")

        + restore_callee_saves()
        + vec("ret");
}

fn rust_yield_glue() -> vec[str] {
    ret vec("movl  0(%esp), %edx    # edx = rust_task")
        + load_esp_from_rust_sp()
        + save_callee_saves()
        + store_esp_to_rust_sp()
        + load_esp_from_runtime_sp()
        + restore_callee_saves()
        + vec("ret");
}

fn upcall_glue(int n_args) -> vec[str] {

    /*
     * 0, 4, 8, 12 are callee-saves
     * 16 is retpc
     * 20 is taskptr
     * 24 is callee
     * 28 .. (7+i) * 4 are args
     */

    fn copy_arg(uint i) -> str {
        auto src_off = wstr(7 + (i as int));
        auto dst_off = wstr(1 + (i as int));
        auto m = vec("movl  " + src_off + "(%ebp),%edx",
                     "movl  %edx," + dst_off + "(%esp)");
        ret _str.connect(m, "\n\t");
    }

    auto carg = copy_arg;

    ret
        save_callee_saves()

        + vec("movl  %esp, %ebp     # ebp = rust_sp",
              "movl  20(%esp), %edx # edx = rust_task")

        + store_esp_to_rust_sp()
        + load_esp_from_runtime_sp()

        + vec("subl  $" + wstr(n_args + 1) + ", %esp   # esp -= args",
              "andl  $~0xf, %esp    # align esp down",
              "movl  %edx, (%esp)   # arg[0] = rust_task ")

        + _vec.init_fn[str](carg, n_args as uint)

        +  vec("movl  24(%ebp), %edx # edx = callee",
               "call  *%edx          # call *%edx",
               "movl  20(%ebp), %edx # edx = rust_task")

        + load_esp_from_rust_sp()
        + restore_callee_saves()
        + vec("ret");

}

fn decl_glue(int align, str prefix, str name, vec[str] insns) -> str {
    auto sym = prefix + name;
    ret "\t.globl " + sym + "\n" +
        "\t.balign " + istr(align) + "\n" +
        sym + ":\n" +
        "\t" + _str.connect(insns, "\n\t");
}

fn decl_upcall_glue(int align, str prefix, uint n) -> str {
    let int i = n as int;
    ret decl_glue(align, prefix,
                  abi.upcall_glue_name(i),
                  upcall_glue(i));
}

fn get_module_asm() -> str {
    auto align = 4;

    auto prefix = "";
    if (_str.eq(target_os(), "macos")) {
        prefix = "_";
    }

    auto glues =
        vec(decl_glue(align, prefix,
                      abi.activate_glue_name(),
                      rust_activate_glue()),

            decl_glue(align, prefix,
                      abi.yield_glue_name(),
                      rust_yield_glue()))

        + _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
                            abi.n_upcall_glues as uint);

    ret _str.connect(glues, "\n\n");
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before><commit_msg>Impl Display for MessageId<commit_after><|endoftext|>


<commit_before><commit_msg>Change GiB's name.<commit_after><|endoftext|>


<commit_before><commit_msg>mulitple trait bound added:<commit_after><|endoftext|>


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

//! Simple ANSI color library

#[allow(missing_doc)];

use core::prelude::*;

use core::io;
use core::os;

use terminfo::*;
use terminfo::searcher::open;
use terminfo::parser::compiled::parse;
use terminfo::parm::{expand, Number};

// FIXME (#2807): Windows support.

pub static color_black: u8 = 0u8;
pub static color_red: u8 = 1u8;
pub static color_green: u8 = 2u8;
pub static color_yellow: u8 = 3u8;
pub static color_blue: u8 = 4u8;
pub static color_magenta: u8 = 5u8;
pub static color_cyan: u8 = 6u8;
pub static color_light_gray: u8 = 7u8;
pub static color_light_grey: u8 = 7u8;
pub static color_dark_gray: u8 = 8u8;
pub static color_dark_grey: u8 = 8u8;
pub static color_bright_red: u8 = 9u8;
pub static color_bright_green: u8 = 10u8;
pub static color_bright_yellow: u8 = 11u8;
pub static color_bright_blue: u8 = 12u8;
pub static color_bright_magenta: u8 = 13u8;
pub static color_bright_cyan: u8 = 14u8;
pub static color_bright_white: u8 = 15u8;

pub fn esc(writer: @io::Writer) { writer.write([0x1bu8, '[' as u8]); }

pub struct Terminal {
    color_supported: bool,
    priv out: @io::Writer,
    priv ti: ~TermInfo
}

pub impl Terminal {
    pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
        let term = os::getenv("TERM");
        if term.is_none() {
            return Err(~"TERM environment variable undefined");
        }

        let entry = open(term.unwrap());
        if entry.is_err() {
            return Err(entry.get_err());
        }

        let ti = parse(entry.get(), false);
        if ti.is_err() {
            return Err(entry.get_err());
        }

        let mut inf = ti.get();
        let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16 && inf.strings.find(&~"setaf").is_some()
            && inf.strings.find(&~"setab").is_some();

        return Ok(Terminal {out: out, ti: inf, color_supported: cs});
    }
    fn fg(&self, color: u8) {
        self.out.write(expand(*self.ti.strings.find(&~"setaf").unwrap(), [Number(color as int)], [], []));
    }
    fn bg(&self, color: u8) {
        self.out.write(expand(*self.ti.strings.find(&~"setab").unwrap(), [Number(color as int)], [], []));
    }
    fn reset(&self) {
        self.out.write(expand(*self.ti.strings.find(&~"op").unwrap(), [], [], []));
    }
}
<commit_msg>Use find_equiv in term<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Simple ANSI color library

#[allow(missing_doc)];

use core::prelude::*;

use core::io;
use core::os;

use terminfo::*;
use terminfo::searcher::open;
use terminfo::parser::compiled::parse;
use terminfo::parm::{expand, Number};

// FIXME (#2807): Windows support.

pub static color_black: u8 = 0u8;
pub static color_red: u8 = 1u8;
pub static color_green: u8 = 2u8;
pub static color_yellow: u8 = 3u8;
pub static color_blue: u8 = 4u8;
pub static color_magenta: u8 = 5u8;
pub static color_cyan: u8 = 6u8;
pub static color_light_gray: u8 = 7u8;
pub static color_light_grey: u8 = 7u8;
pub static color_dark_gray: u8 = 8u8;
pub static color_dark_grey: u8 = 8u8;
pub static color_bright_red: u8 = 9u8;
pub static color_bright_green: u8 = 10u8;
pub static color_bright_yellow: u8 = 11u8;
pub static color_bright_blue: u8 = 12u8;
pub static color_bright_magenta: u8 = 13u8;
pub static color_bright_cyan: u8 = 14u8;
pub static color_bright_white: u8 = 15u8;

pub fn esc(writer: @io::Writer) { writer.write([0x1bu8, '[' as u8]); }

pub struct Terminal {
    color_supported: bool,
    priv out: @io::Writer,
    priv ti: ~TermInfo
}

pub impl Terminal {
    pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
        let term = os::getenv("TERM");
        if term.is_none() {
            return Err(~"TERM environment variable undefined");
        }

        let entry = open(term.unwrap());
        if entry.is_err() {
            return Err(entry.get_err());
        }

        let ti = parse(entry.get(), false);
        if ti.is_err() {
            return Err(entry.get_err());
        }

        let mut inf = ti.get();
        let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16 && inf.strings.find(&~"setaf").is_some()
            && inf.strings.find_equiv(&("setab")).is_some();

        return Ok(Terminal {out: out, ti: inf, color_supported: cs});
    }
    fn fg(&self, color: u8) {
        self.out.write(expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(), [Number(color as int)], [], []));
    }
    fn bg(&self, color: u8) {
        self.out.write(expand(*self.ti.strings.find_equiv(&("setab")).unwrap(), [Number(color as int)], [], []));
    }
    fn reset(&self) {
        self.out.write(expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], [], []));
    }
}
<|endoftext|>


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

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(plugin)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#![crate_name = "fourcc"]
#![deprecated = "This is now a cargo package located at: \
                 https://github.com/rust-lang/fourcc"]
#![allow(deprecated)]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/master/")]

#![feature(plugin_registrar, managed_boxes)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use rustc::plugin::Registry;

use std::gc::Gc;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("fourcc", expand_syntax_ext);
}

pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacExpr::new(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (Gc<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg().as_slice(), meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<commit_msg>fourcc: fix fallout from using ptr::P.<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!
Syntax extension to generate FourCCs.

Once loaded, fourcc!() is called with a single 4-character string,
and an optional ident that is either `big`, `little`, or `target`.
The ident represents endianness, and specifies in which direction
the characters should be read. If the ident is omitted, it is assumed
to be `big`, i.e. left-to-right order. It returns a u32.

# Examples

To load the extension and use it:

```rust,ignore
#[phase(plugin)]
extern crate fourcc;

fn main() {
    let val = fourcc!("\xC0\xFF\xEE!");
    assert_eq!(val, 0xC0FFEE21u32);
    let little_val = fourcc!("foo ", little);
    assert_eq!(little_val, 0x21EEFFC0u32);
}
```

# References

* [Wikipedia: FourCC](http://en.wikipedia.org/wiki/FourCC)

*/

#![crate_name = "fourcc"]
#![deprecated = "This is now a cargo package located at: \
                 https://github.com/rust-lang/fourcc"]
#![allow(deprecated)]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/master/")]

#![feature(plugin_registrar, managed_boxes)]

extern crate syntax;
extern crate rustc;

use syntax::ast;
use syntax::attr::contains;
use syntax::codemap::{Span, mk_sp};
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, MacExpr};
use syntax::ext::build::AstBuilder;
use syntax::parse::token;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
use rustc::plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("fourcc", expand_syntax_ext);
}

pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                              -> Box<base::MacResult+'cx> {
    let (expr, endian) = parse_tts(cx, tts);

    let little = match endian {
        None => false,
        Some(Ident{ident, span}) => match token::get_ident(ident).get() {
            "little" => true,
            "big" => false,
            "target" => target_endian_little(cx, sp),
            _ => {
                cx.span_err(span, "invalid endian directive in fourcc!");
                target_endian_little(cx, sp)
            }
        }
    };

    let s = match expr.node {
        // expression is a literal
        ast::ExprLit(ref lit) => match lit.node {
            // string literal
            ast::LitStr(ref s, _) => {
                if s.get().char_len() != 4 {
                    cx.span_err(expr.span, "string literal with len != 4 in fourcc!");
                }
                s
            }
            _ => {
                cx.span_err(expr.span, "unsupported literal in fourcc!");
                return base::DummyResult::expr(sp)
            }
        },
        _ => {
            cx.span_err(expr.span, "non-literal in fourcc!");
            return base::DummyResult::expr(sp)
        }
    };

    let mut val = 0u32;
    for codepoint in s.get().chars().take(4) {
        let byte = if codepoint as u32 > 0xFF {
            cx.span_err(expr.span, "fourcc! literal character out of range 0-255");
            0u8
        } else {
            codepoint as u8
        };

        val = if little {
            (val >> 8) | ((byte as u32) << 24)
        } else {
            (val << 8) | (byte as u32)
        };
    }
    let e = cx.expr_lit(sp, ast::LitInt(val as u64, ast::UnsignedIntLit(ast::TyU32)));
    MacExpr::new(e)
}

struct Ident {
    ident: ast::Ident,
    span: Span
}

fn parse_tts(cx: &ExtCtxt,
             tts: &[ast::TokenTree]) -> (P<ast::Expr>, Option<Ident>) {
    let p = &mut cx.new_parser_from_tts(tts);
    let ex = p.parse_expr();
    let id = if p.token == token::EOF {
        None
    } else {
        p.expect(&token::COMMA);
        let lo = p.span.lo;
        let ident = p.parse_ident();
        let hi = p.last_span.hi;
        Some(Ident{ident: ident, span: mk_sp(lo, hi)})
    };
    if p.token != token::EOF {
        p.unexpected();
    }
    (ex, id)
}

fn target_endian_little(cx: &ExtCtxt, sp: Span) -> bool {
    let meta = cx.meta_name_value(sp, InternedString::new("target_endian"),
        ast::LitStr(InternedString::new("little"), ast::CookedStr));
    contains(cx.cfg().as_slice(), &*meta)
}

// FIXME (10872): This is required to prevent an LLVM assert on Windows
#[test]
fn dummy_test() { }
<|endoftext|>


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

//! Base64 binary-to-text encoding

use core::old_iter;
use core::str;
use core::vec;

pub trait ToBase64 {
    fn to_base64(&self) -> ~str;
}

static CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     * }
     * ~~~~
     */
    fn to_base64(&self) -> ~str {
        let mut s = ~"";
        let len = self.len();
        str::reserve(&mut s, ((len + 3u) / 4u) * 3u);

        let mut i = 0u;

        while i < len - (len % 3u) {
            let n = (self[i] as uint) << 16u |
                    (self[i + 1u] as uint) << 8u |
                    (self[i + 2u] as uint);

            // This 24-bit number gets separated into four 6-bit numbers.
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, CHARS[n & 63u]);

            i += 3u;
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
          0 => (),
          1 => {
            let n = (self[i] as uint) << 16u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, '=');
            str::push_char(&mut s, '=');
          }
          2 => {
            let n = (self[i] as uint) << 16u |
                (self[i + 1u] as uint) << 8u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, '=');
          }
          _ => fail!(~"Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = "Hello, World".to_base64();
     *     println(fmt!("%s",str));
     * }
     * ~~~~
     *
     */
    fn to_base64(&self) -> ~str {
        str::to_bytes(*self).to_base64()
    }
}

pub trait FromBase64 {
    fn from_base64(&self) -> ~[u8];
}

impl FromBase64 for ~[u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, modulo padding.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        if self.len() % 4u != 0u { fail!(~"invalid base64 length"); }

        let len = self.len();
        let mut padding = 0u;

        if len != 0u {
            if self[len - 1u] == '=' as u8 { padding += 1u; }
            if self[len - 2u] == '=' as u8 { padding += 1u; }
        }

        let mut r = vec::with_capacity((len / 4u) * 3u - padding);

        let mut i = 0u;
        while i < len {
            let mut n = 0u;

            for old_iter::repeat(4u) {
                let ch = self[i] as char;
                n <<= 6u;

                if ch >= 'A' && ch <= 'Z' {
                    n |= (ch as uint) - 0x41u;
                } else if ch >= 'a' && ch <= 'z' {
                    n |= (ch as uint) - 0x47u;
                } else if ch >= '0' && ch <= '9' {
                    n |= (ch as uint) + 0x04u;
                } else if ch == '+' {
                    n |= 0x3Eu;
                } else if ch == '/' {
                    n |= 0x3Fu;
                } else if ch == '=' {
                    match len - i {
                      1u => {
                        r.push(((n >> 16u) & 0xFFu) as u8);
                        r.push(((n >> 8u ) & 0xFFu) as u8);
                        return copy r;
                      }
                      2u => {
                        r.push(((n >> 10u) & 0xFFu) as u8);
                        return copy r;
                      }
                      _ => fail!(~"invalid base64 padding")
                    }
                } else {
                    fail!(~"invalid base64 character");
                }

                i += 1u;
            };

            r.push(((n >> 16u) & 0xFFu) as u8);
            r.push(((n >> 8u ) & 0xFFu) as u8);
            r.push(((n       ) & 0xFFu) as u8);
        }
        r
    }
}

impl FromBase64 for ~str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `core::str`
     * to turn a `[u8]` into a string with characters corresponding to those values.
     *
     * *Example*:
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     * use core::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64();
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        str::to_bytes(*self).from_base64()
    }
}

#[cfg(test)]
mod tests {
    use core::str;

    #[test]
    fn test_to_base64() {
        assert!((~"").to_base64()       == ~"");
        assert!((~"f").to_base64()      == ~"Zg==");
        assert!((~"fo").to_base64()     == ~"Zm8=");
        assert!((~"foo").to_base64()    == ~"Zm9v");
        assert!((~"foob").to_base64()   == ~"Zm9vYg==");
        assert!((~"fooba").to_base64()  == ~"Zm9vYmE=");
        assert!((~"foobar").to_base64() == ~"Zm9vYmFy");
    }

    #[test]
    fn test_from_base64() {
        assert!((~"").from_base64() == str::to_bytes(~""));
        assert!((~"Zg==").from_base64() == str::to_bytes(~"f"));
        assert!((~"Zm8=").from_base64() == str::to_bytes(~"fo"));
        assert!((~"Zm9v").from_base64() == str::to_bytes(~"foo"));
        assert!((~"Zm9vYg==").from_base64() == str::to_bytes(~"foob"));
        assert!((~"Zm9vYmE=").from_base64() == str::to_bytes(~"fooba"));
        assert!((~"Zm9vYmFy").from_base64() == str::to_bytes(~"foobar"));
    }
}
<commit_msg>auto merge of #6332 : huonw/rust/std-base64-match, r=nikomatsakis<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Base64 binary-to-text encoding

use core::old_iter;
use core::str;
use core::vec;

pub trait ToBase64 {
    fn to_base64(&self) -> ~str;
}

static CHARS: [char, ..64] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
    'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
    'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
];

impl<'self> ToBase64 for &'self [u8] {
    /**
     * Turn a vector of `u8` bytes into a base64 string.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     * }
     * ~~~~
     */
    fn to_base64(&self) -> ~str {
        let mut s = ~"";
        let len = self.len();
        str::reserve(&mut s, ((len + 3u) / 4u) * 3u);

        let mut i = 0u;

        while i < len - (len % 3u) {
            let n = (self[i] as uint) << 16u |
                    (self[i + 1u] as uint) << 8u |
                    (self[i + 2u] as uint);

            // This 24-bit number gets separated into four 6-bit numbers.
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, CHARS[n & 63u]);

            i += 3u;
        }

        // Heh, would be cool if we knew this was exhaustive
        // (the dream of bounded integer types)
        match len % 3 {
          0 => (),
          1 => {
            let n = (self[i] as uint) << 16u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, '=');
            str::push_char(&mut s, '=');
          }
          2 => {
            let n = (self[i] as uint) << 16u |
                (self[i + 1u] as uint) << 8u;
            str::push_char(&mut s, CHARS[(n >> 18u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 12u) & 63u]);
            str::push_char(&mut s, CHARS[(n >> 6u) & 63u]);
            str::push_char(&mut s, '=');
          }
          _ => fail!(~"Algebra is broken, please alert the math police")
        }
        s
    }
}

impl<'self> ToBase64 for &'self str {
    /**
     * Convert any string (literal, `@`, `&`, or `~`) to base64 encoding.
     *
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     *
     * fn main () {
     *     let str = "Hello, World".to_base64();
     *     println(fmt!("%s",str));
     * }
     * ~~~~
     *
     */
    fn to_base64(&self) -> ~str {
        str::to_bytes(*self).to_base64()
    }
}

pub trait FromBase64 {
    fn from_base64(&self) -> ~[u8];
}

impl FromBase64 for ~[u8] {
    /**
     * Convert base64 `u8` vector into u8 byte values.
     * Every 4 encoded characters is converted into 3 octets, modulo padding.
     *
     * *Example*:
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     *
     * fn main () {
     *     let str = [52,32].to_base64();
     *     println(fmt!("%s", str));
     *     let bytes = str.from_base64();
     *     println(fmt!("%?",bytes));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        if self.len() % 4u != 0u { fail!(~"invalid base64 length"); }

        let len = self.len();
        let mut padding = 0u;

        if len != 0u {
            if self[len - 1u] == '=' as u8 { padding += 1u; }
            if self[len - 2u] == '=' as u8 { padding += 1u; }
        }

        let mut r = vec::with_capacity((len / 4u) * 3u - padding);

        let mut i = 0u;
        while i < len {
            let mut n = 0u;

            for old_iter::repeat(4u) {
                let ch = self[i] as char;
                n <<= 6u;

                match ch {
                    'A'..'Z' => n |= (ch as uint) - 0x41,
                    'a'..'z' => n |= (ch as uint) - 0x47,
                    '0'..'9' => n |= (ch as uint) + 0x04,
                    '+'      => n |= 0x3E,
                    '/'      => n |= 0x3F,
                    '='      => {
                        match len - i {
                            1u => {
                                r.push(((n >> 16u) & 0xFFu) as u8);
                                r.push(((n >> 8u ) & 0xFFu) as u8);
                                return copy r;
                            }
                            2u => {
                                r.push(((n >> 10u) & 0xFFu) as u8);
                                return copy r;
                            }
                            _ => fail!(~"invalid base64 padding")
                        }
                    }
                    _ => fail!(~"invalid base64 character")
                }

                i += 1u;
            };

            r.push(((n >> 16u) & 0xFFu) as u8);
            r.push(((n >> 8u ) & 0xFFu) as u8);
            r.push(((n       ) & 0xFFu) as u8);
        }
        r
    }
}

impl FromBase64 for ~str {
    /**
     * Convert any base64 encoded string (literal, `@`, `&`, or `~`)
     * to the byte values it encodes.
     *
     * You can use the `from_bytes` function in `core::str`
     * to turn a `[u8]` into a string with characters corresponding to those values.
     *
     * *Example*:
     *
     * This converts a string literal to base64 and back.
     *
     * ~~~~
     * extern mod std;
     * use std::base64::ToBase64;
     * use std::base64::FromBase64;
     * use core::str;
     *
     * fn main () {
     *     let hello_str = "Hello, World".to_base64();
     *     println(fmt!("%s",hello_str));
     *     let bytes = hello_str.from_base64();
     *     println(fmt!("%?",bytes));
     *     let result_str = str::from_bytes(bytes);
     *     println(fmt!("%s",result_str));
     * }
     * ~~~~
     */
    fn from_base64(&self) -> ~[u8] {
        str::to_bytes(*self).from_base64()
    }
}

#[cfg(test)]
mod tests {
    use core::str;

    #[test]
    fn test_to_base64() {
        assert!((~"").to_base64()       == ~"");
        assert!((~"f").to_base64()      == ~"Zg==");
        assert!((~"fo").to_base64()     == ~"Zm8=");
        assert!((~"foo").to_base64()    == ~"Zm9v");
        assert!((~"foob").to_base64()   == ~"Zm9vYg==");
        assert!((~"fooba").to_base64()  == ~"Zm9vYmE=");
        assert!((~"foobar").to_base64() == ~"Zm9vYmFy");
    }

    #[test]
    fn test_from_base64() {
        assert!((~"").from_base64() == str::to_bytes(~""));
        assert!((~"Zg==").from_base64() == str::to_bytes(~"f"));
        assert!((~"Zm8=").from_base64() == str::to_bytes(~"fo"));
        assert!((~"Zm9v").from_base64() == str::to_bytes(~"foo"));
        assert!((~"Zm9vYg==").from_base64() == str::to_bytes(~"foob"));
        assert!((~"Zm9vYmE=").from_base64() == str::to_bytes(~"fooba"));
        assert!((~"Zm9vYmFy").from_base64() == str::to_bytes(~"foobar"));
    }
}
<|endoftext|>


<commit_before><commit_msg>Feat(mutex): implement mutex on windows<commit_after><|endoftext|>


<commit_before><commit_msg>filter!() now use a global path<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for none-delimited attribute on an item<commit_after>#[macro_use]
mod macros;

use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
use quote::quote;
use std::iter::FromIterator;
use syn::Item;

#[test]
fn test_macro_variable_attr() {
    // mimics the token stream corresponding to `$attr fn f() {}`
    let tokens = TokenStream::from_iter(vec![
        TokenTree::Group(Group::new(Delimiter::None, quote! { #[test] })),
        TokenTree::Ident(Ident::new("fn", Span::call_site())),
        TokenTree::Ident(Ident::new("f", Span::call_site())),
        TokenTree::Group(Group::new(Delimiter::Parenthesis, TokenStream::new())),
        TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
    ]);

    snapshot!(tokens as Item, @r###"
    Item::Fn {
        attrs: [
            Attribute {
                style: Outer,
                path: Path {
                    segments: [
                        PathSegment {
                            ident: "test",
                            arguments: None,
                        },
                    ],
                },
                tokens: TokenStream(``),
            },
        ],
        vis: Inherited,
        sig: Signature {
            ident: "f",
            generics: Generics,
            output: Default,
        },
        block: Block,
    }
    "###);
}
<|endoftext|>


<commit_before><commit_msg>using where for bounding T rather than type itself<commit_after><|endoftext|>


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

/// Implement ncurses-compatible database discovery
/// Does not support hashed database, only filesystem!

use core::prelude::*;
use core::{os};
use core::os::getenv;
use core::io::{file_reader, Reader};
use core::iterator::IteratorUtil;
use path = core::path::Path;

/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
    if term.len() == 0 {
        return None;
    }

    let homedir = os::homedir();

    let mut dirs_to_search = ~[];
    let first_char = term.substr(0, 1);

    // Find search directory
    match getenv("TERMINFO") {
        Some(dir) => dirs_to_search.push(path(dir)),
        None => {
            if homedir.is_some() {
                dirs_to_search.push(homedir.unwrap().push(".terminfo")); // ncurses compatability
            }
            match getenv("TERMINFO_DIRS") {
                Some(dirs) => for dirs.split_iter(':').advance |i| {
                    if i == "" {
                        dirs_to_search.push(path("/usr/share/terminfo"));
                    } else {
                        dirs_to_search.push(path(i.to_owned()));
                    }
                },
                // Found nothing, use the default path
                None => dirs_to_search.push(path("/usr/share/terminfo"))
            }
        }
    };

    // Look for the terminal in all of the search directories
    for dirs_to_search.each |p| {
        let newp = ~p.push_many(&[first_char.to_owned(), term.to_owned()]);
        if os::path_exists(p) && os::path_exists(newp) {
            return Some(newp);
        }
    }
    None
}

/// Return open file for `term`
pub fn open(term: &str) -> Result<@Reader, ~str> {
    match get_dbpath_for_term(term) {
        Some(x) => file_reader(x),
        None => Err(fmt!("could not find terminfo entry for %s", term))
    }
}

#[test]
#[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    use std::os::{setenv, unsetenv};
    fn x(t: &str) -> ~str { get_dbpath_for_term(t).expect("no terminfo entry found").to_str() };
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    setenv("TERMINFO_DIRS", ":");
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    unsetenv("TERMINFO_DIRS");
}

#[test]
#[ignore(reason = "see test_get_dbpath_for_term")]
fn test_open() {
    open("screen");
    let t = open("nonexistent terminal that hopefully does not exist");
    assert!(t.is_err());
}
<commit_msg>terminfo: Support more terminfo directory structures<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// Implement ncurses-compatible database discovery
/// Does not support hashed database, only filesystem!

use core::prelude::*;
use core::{os};
use core::os::getenv;
use core::io::{file_reader, Reader};
use core::iterator::IteratorUtil;
use path = core::path::Path;

/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
    if term.len() == 0 {
        return None;
    }

    let homedir = os::homedir();

    let mut dirs_to_search = ~[];
    let first_char = term.substr(0, 1);

    // Find search directory
    match getenv("TERMINFO") {
        Some(dir) => dirs_to_search.push(path(dir)),
        None => {
            if homedir.is_some() {
                dirs_to_search.push(homedir.unwrap().push(".terminfo")); // ncurses compatability
            }
            match getenv("TERMINFO_DIRS") {
                Some(dirs) => for dirs.split_iter(':').advance |i| {
                    if i == "" {
                        dirs_to_search.push(path("/usr/share/terminfo"));
                    } else {
                        dirs_to_search.push(path(i.to_owned()));
                    }
                },
                // Found nothing, use the default paths
                // /usr/share/terminfo is the de facto location, but it seems
                // Ubuntu puts it in /lib/terminfo
                None => {
                    dirs_to_search.push(path("/usr/share/terminfo"));
                    dirs_to_search.push(path("/lib/terminfo"));
                }
            }
        }
    };

    // Look for the terminal in all of the search directories
    for dirs_to_search.each |p| {
        let newp = ~p.push_many(&[first_char.to_owned(), term.to_owned()]);
        if os::path_exists(p) && os::path_exists(newp) {
            return Some(newp);
        }
        // on some installations the dir is named after the hex of the char (e.g. OS X)
        let newp = ~p.push_many(&[fmt!("%x", first_char[0] as uint), term.to_owned()]);
        if os::path_exists(p) && os::path_exists(newp) {
            return Some(newp);
        }
    }
    None
}

/// Return open file for `term`
pub fn open(term: &str) -> Result<@Reader, ~str> {
    match get_dbpath_for_term(term) {
        Some(x) => file_reader(x),
        None => Err(fmt!("could not find terminfo entry for %s", term))
    }
}

#[test]
#[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
    use std::os::{setenv, unsetenv};
    fn x(t: &str) -> ~str { get_dbpath_for_term(t).expect("no terminfo entry found").to_str() };
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    setenv("TERMINFO_DIRS", ":");
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    unsetenv("TERMINFO_DIRS");
}

#[test]
#[ignore(reason = "see test_get_dbpath_for_term")]
fn test_open() {
    open("screen");
    let t = open("nonexistent terminal that hopefully does not exist");
    assert!(t.is_err());
}
<|endoftext|>