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

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

#![allow(bad_style)]

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

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

use super::to_u16s;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#[derive(Debug)]
pub struct JoinPathsError;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#![allow(bad_style)]

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

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

use super::to_u16s;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#[derive(Debug)]
pub struct JoinPathsError;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


<commit_before><commit_msg>Add benchmarks for creating one-dimensional arrays.<commit_after>#![feature(test)]

extern crate test;
use test::{black_box, Bencher};

use std::ops::Range;

use numpy::PyArray1;
use pyo3::{Python, ToPyObject};

struct Iter(Range<usize>);

impl Iterator for Iter {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }
}

fn from_iter(bencher: &mut Bencher, size: usize) {
    bencher.iter(|| {
        let iter = black_box(Iter(0..size));

        Python::with_gil(|py| {
            PyArray1::from_iter(py, iter);
        });
    });
}

#[bench]
fn from_iter_small(bencher: &mut Bencher) {
    from_iter(bencher, 2_usize.pow(5));
}

#[bench]
fn from_iter_medium(bencher: &mut Bencher) {
    from_iter(bencher, 2_usize.pow(10));
}

#[bench]
fn from_iter_large(bencher: &mut Bencher) {
    from_iter(bencher, 2_usize.pow(15));
}

struct ExactIter(Range<usize>);

impl Iterator for ExactIter {
    type Item = usize;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.next()
    }

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

impl ExactSizeIterator for ExactIter {
    fn len(&self) -> usize {
        self.0.len()
    }
}

fn from_exact_iter(bencher: &mut Bencher, size: usize) {
    bencher.iter(|| {
        let iter = black_box(ExactIter(0..size));

        Python::with_gil(|py| {
            PyArray1::from_exact_iter(py, iter);
        });
    });
}

#[bench]
fn from_exact_iter_small(bencher: &mut Bencher) {
    from_exact_iter(bencher, 2_usize.pow(5));
}

#[bench]
fn from_exact_iter_medium(bencher: &mut Bencher) {
    from_exact_iter(bencher, 2_usize.pow(10));
}

#[bench]
fn from_exact_iter_large(bencher: &mut Bencher) {
    from_exact_iter(bencher, 2_usize.pow(15));
}

fn from_slice(bencher: &mut Bencher, size: usize) {
    let vec = (0..size).collect::<Vec<_>>();

    bencher.iter(|| {
        let slice = black_box(&vec);

        Python::with_gil(|py| {
            PyArray1::from_slice(py, slice);
        });
    });
}

#[bench]
fn from_slice_small(bencher: &mut Bencher) {
    from_slice(bencher, 2_usize.pow(5));
}

#[bench]
fn from_slice_medium(bencher: &mut Bencher) {
    from_slice(bencher, 2_usize.pow(10));
}

#[bench]
fn from_slice_large(bencher: &mut Bencher) {
    from_slice(bencher, 2_usize.pow(15));
}

fn from_object_slice(bencher: &mut Bencher, size: usize) {
    let vec = Python::with_gil(|py| (0..size).map(|val| val.to_object(py)).collect::<Vec<_>>());

    bencher.iter(|| {
        let slice = black_box(&vec);

        Python::with_gil(|py| {
            PyArray1::from_slice(py, slice);
        });
    });
}

#[bench]
fn from_object_slice_small(bencher: &mut Bencher) {
    from_object_slice(bencher, 2_usize.pow(5));
}

#[bench]
fn from_object_slice_medium(bencher: &mut Bencher) {
    from_object_slice(bencher, 2_usize.pow(10));
}

#[bench]
fn from_object_slice_large(bencher: &mut Bencher) {
    from_object_slice(bencher, 2_usize.pow(15));
}
<|endoftext|>


<commit_before><commit_msg>Fix: Header entry setting<commit_after><|endoftext|>


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

fn main() {
    let x = 0;
    match 1 {
        0 ... x => {} //~ ERROR non-constant path in constant expr
    };
}
<commit_msg>Fixed test<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

fn main() {
    let x = 0;
    match 1 {
        0 ... x => {}
        //~^ ERROR non-constant path in constant expr
        //~| ERROR paths in constants may only refer to constants or functions
    };
}
<|endoftext|>


<commit_before><commit_msg>Added an example of an unfilled star<commit_after>extern crate turtle;

use turtle::Turtle;

fn main() {
    let mut turtle = Turtle::new();

    let points = 5.0;
    let angle = 180.0 / points;

    turtle.set_background_color("#424242");
    turtle.set_pen_size(2.0);
    turtle.set_pen_color("yellow");

    turtle.pen_up();
    turtle.forward(150.0);
    turtle.right(180.0 - angle / 2.0);
    turtle.pen_down();

    for _ in 0..5 {
        turtle.forward(100.0);
        turtle.left(angle * 2.0);
        turtle.forward(100.0);
        turtle.right(180.0  - angle);
    }
}
<|endoftext|>


<commit_before><commit_msg>Starting to work on a logo for the library, with splines of course!<commit_after>extern crate image;
extern crate bspline;

use std::ops::{Mul, Add};
use std::iter;

#[derive(Copy, Clone, Debug)]
struct Point {
    x: f32,
    y: f32,
}
impl Point {
    fn new(x: f32, y: f32) -> Point {
        Point { x: x, y: y }
    }
}
impl Mul<f32> for Point {
    type Output = Point;
    fn mul(self, rhs: f32) -> Point {
        Point { x: self.x * rhs, y: self.y * rhs }
    }
}
impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Point) -> Point {
        Point { x: self.x + rhs.x, y: self.y + rhs.y }
    }
}

/// Evaluate the B-spline and plot it to the image buffer passed
fn plot_2d(spline: &bspline::BSpline<Point>, plot: &mut [u8], plot_dim: (usize, usize), scale: (f32, f32),
           offset: (f32, f32), t_range: (f32, f32)) {
    let step_size = 0.001;
    let steps = ((t_range.1 - t_range.0) / step_size) as usize;
    for s in 0..steps {
        let t = step_size * s as f32 + t_range.0;
        let pt = spline.point(t);
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        for y in iy - 1..iy + 1 {
            for x in ix - 1..ix + 1 {
                if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                    let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                    for i in 0..3 {
                        plot[px + i] = 0;
                    }
                }
            }
        }
    }
    // Draw the control points
    for pt in spline.control_points() {
        let ix = ((pt.x + offset.0) * scale.0) as isize;
        let iy = ((pt.y + offset.1) * scale.1) as isize;
        // Plot a 4x4 red marker for each control point
        for y in iy - 3..iy + 3 {
            for x in ix - 3..ix + 3 {
                if y >= 0 && y < plot_dim.1 as isize && x >= 0 && x < plot_dim.0 as isize {
                    let px = (plot_dim.1 - 1 - y as usize) * plot_dim.0 * 3 + x as usize * 3;
                    plot[px] = 255;
                    plot[px + 1] = 0;
                    plot[px + 2] = 0;
                }
            }
        }
    }
}

/// Plot the text 'bspline' to create the logo for the library
fn main() {
    let points = vec![Point::new(-4.0, 4.0), Point::new(-4.0, -1.0), Point::new(-4.0, -1.0),
                      Point::new(-2.0, 0.0), Point::new(-4.0, 1.0), Point::new(-4.0, 1.0),
                      Point::new(-2.0, 1.0)];
    let knots = vec![0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 3.0, 4.0, 4.0, 4.0, 4.0];
    let t_start = knots[0];
    let t_end = knots[knots.len() - 1];

    let plot_dim = (720, 540);
    let scale = (plot_dim.0 as f32 / 10.0, plot_dim.1 as f32 / 10.0);
    let offset = (5.0, 5.0);

    let mut plot: Vec<_> = iter::repeat(255u8).take(plot_dim.0 * plot_dim.1 * 3).collect();

    println!("Plotting Cubic B-spline with:\n\tpoints = {:?}\n\tknots = {:?}",
             points, knots);
    println!("\tStarting at {}, ending at {}", t_start, t_end);
    let spline = bspline::BSpline::new(3, points, knots);

    plot_2d(&spline, &mut plot[..], plot_dim, scale, offset, (t_start, t_end));
    match image::save_buffer("logo.png", &plot[..], plot_dim.0 as u32, plot_dim.1 as u32, image::RGB(8)) {
        Ok(_) => println!("B-spline logo saved to logo.png"),
        Err(e) => println!("Error saving logo.png,  {}", e),
    }
}

<|endoftext|>


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


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

#[macro_use]
extern crate gj;
extern crate gjio;
use gj::{EventLoop, Promise};
use gjio::{Read, Write};

#[test]
fn hello() {
    EventLoop::top_level(|wait_scope| -> Result<(), ::std::io::Error> {
        let mut event_port = try!(gjio::EventPort::new());
        let network = event_port.get_network();
        let addr = ::std::str::FromStr::from_str("127.0.0.1:10000").unwrap();
        let mut address = network.get_tcp_address(addr);
        let mut listener = try!(address.listen());

        let _write_promise = listener.accept().then(move |mut stream| {
            stream.write(vec![0,1,2,3,4,5])
        });

        let read_promise = address.connect().then(move |mut stream| {
            stream.read(vec![0u8; 6], 6)
        });

        let (buf, _) = try!(read_promise.wait(wait_scope, &mut event_port));

        assert_eq!(&buf[..], [0,1,2,3,4,5]);
        Ok(())
    }).expect("top level");
}

#[test]
fn echo() {
    EventLoop::top_level(|wait_scope| -> Result<(), ::std::io::Error> {
        let mut event_port = try!(gjio::EventPort::new());
        let network = event_port.get_network();
        let addr = ::std::str::FromStr::from_str("127.0.0.1:10001").unwrap();
        let mut address = network.get_tcp_address(addr);
        let mut listener = try!(address.listen());

        let _server_promise = listener.accept().then(move |mut stream| {
            stream.read(vec![0u8; 6], 6).lift().then(move |( mut v, _)| {
                assert_eq!(&v[..], [7,6,5,4,3,2]);
                for x in &mut v {
                    *x += 1;
                }
                stream.write(v).lift()
            })
        });

        let client_promise = address.connect().then(move |mut stream| {
            stream.write(vec![7,6,5,4,3,2]).then(move |v| {
                stream.read(v, 6)
            })
        });

        let (buf, _) = try!(client_promise.wait(wait_scope, &mut event_port));
        assert_eq!(&buf[..], [8,7,6,5,4,3]);
        Ok(())
    }).expect("top level");
}

/*
#[cfg(unix)]
#[test]
fn deregister_dupped_unix() {
    use gjmio::unix;
    // At one point, this panicked on Linux with "invalid handle idx".
    EventLoop::top_level(|wait_scope| -> Result<(), ::std::io::Error> {
        let mut event_port = try!(gjmio::EventPort::new());
        let (stream1, stream2) = try!(unix::Stream::new_pair());
        let stream1_dupped = try!(stream1.try_clone());
        drop(stream1);

        let promise1 = stream1_dupped.read(vec![0u8; 6], 6);
        let _promise2 = stream2.write(vec![1,2,3,4,5,6]);

        let _ = promise1.lift::<::std::io::Error>().wait(wait_scope, &mut event_port);
        Ok(())
    }).unwrap();
}

#[test]
fn deregister_dupped_tcp() {
    // At one point, this panicked on Linux with "invalid handle idx".
    EventLoop::top_level(|wait_scope| -> Result<(), ::std::io::Error> {
        let mut event_port = try!(gjmio::EventPort::new());
        let addr = ::std::str::FromStr::from_str("127.0.0.1:10002").unwrap();
        let listener = tcp::Listener::bind(addr).unwrap();

        let server_promise = listener.accept().lift::<::std::io::Error>().map(move |(_, stream1)| {
            Ok(Some(stream1))
        });
        let client_promise = tcp::Stream::connect(addr).lift::<::std::io::Error>().map(|stream2| Ok(Some(stream2)));
        let promise = Promise::all(vec![server_promise, client_promise].into_iter()).then(|mut streams| {
            let stream0 = streams[0].take().unwrap();
            let stream1 = streams[1].take().unwrap();
            let stream0_dupped = pry!(stream0.try_clone());
            drop(stream0);

            let promise1 = stream0_dupped.read(vec![0u8; 6], 6).lift();
            let promise2 = stream1.write(vec![1,2,3,4,5,6]).lift();

            promise2.then(|_| promise1)
        });

        let _ = promise.wait(wait_scope, &mut event_port);
        Ok(())
    }).unwrap();
}
*/
<|endoftext|>


<commit_before><commit_msg>Now root work<commit_after><|endoftext|>


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

trait SomeTrait {}
struct Meow;
impl SomeTrait for Meow {}

struct Foo<'a> {
    x: &'a SomeTrait,
    y: &'a SomeTrait,
}

impl<'a> Foo<'a> {
    pub fn new<'b>(x: &'b SomeTrait, y: &'b SomeTrait) -> Foo<'b> { Foo { x: x, y: y } }
}

fn main() {
    let r = Meow;
    let s = Meow;
    let q = Foo::new(&r as &SomeTrait, &s as &SomeTrait);
}
<|endoftext|>


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

use std::ops::*;

#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
struct Nil; // empty HList
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
struct Cons<H, T: HList>(H, T); // cons cell of HList

// trait to classify valid HLists
trait HList {}
impl HList for Nil {}
impl<H, T: HList> HList for Cons<H, T> {}

// term-level macro for HLists
macro_rules! hlist {
        {} => { Nil };
            { $head:expr } => { Cons($head, Nil) };
                { $head:expr, $($tail:expr),* } => { Cons($head, hlist!($($tail),*)) };
}

// type-level macro for HLists
macro_rules! HList {
        {} => { Nil };
            { $head:ty } => { Cons<$head, Nil> };
                { $head:ty, $($tail:ty),* } => { Cons<$head, HList!($($tail),*)> };
}

// nil case for HList append
impl<Ys: HList> Add<Ys> for Nil {
        type Output = Ys;

            fn add(self, rhs: Ys) -> Ys {
                        rhs
                                }
}

// cons case for HList append
impl<Rec: HList + Sized, X, Xs: HList, Ys: HList> Add<Ys> for Cons<X, Xs> where
    Xs: Add<Ys, Output = Rec>,
{
        type Output = Cons<X, Rec>;

            fn add(self, rhs: Ys) -> Cons<X, Rec> {
                        Cons(self.0, self.1 + rhs)
                                }
}

// type macro Expr allows us to expand the + operator appropriately
macro_rules! Expr {
        { ( $($LHS:tt)+ ) } => { Expr!($($LHS)+) };
            { HList ! [ $($LHS:tt)* ] + $($RHS:tt)+ } => { <Expr!(HList![$($LHS)*]) as Add<Expr!($($RHS)+)>>::Output };
                { $LHS:tt + $($RHS:tt)+ } => { <Expr!($LHS) as Add<Expr!($($RHS)+)>>::Output };
                    { $LHS:ty } => { $LHS };
}

// test demonstrating term level `xs + ys` and type level `Expr!(Xs + Ys)`
fn main() {
    fn aux<Xs: HList, Ys: HList>(xs: Xs, ys: Ys) -> Expr!(Xs + Ys)
        where Xs: Add<Ys> {
            xs + ys
        }

    let xs: HList![&str, bool, Vec<u64>] = hlist!["foo", false, vec![]];
    let ys: HList![u64, [u8; 3], ()] = hlist![0, [0, 1, 2], ()];

    // demonstrate recursive expansion of Expr!
    let zs: Expr!((HList![&str] + HList![bool] + HList![Vec<u64>]) +
                  (HList![u64] + HList![[u8; 3], ()]) +
                  HList![])
        = aux(xs, ys);
    assert_eq!(zs, hlist!["foo", false, vec![], 0, [0, 1, 2], ()])
}

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

use std::ops::*;

#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
struct Nil; // empty HList
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
struct Cons<H, T: HList>(H, T); // cons cell of HList

// trait to classify valid HLists
trait HList {}
impl HList for Nil {}
impl<H, T: HList> HList for Cons<H, T> {}

// term-level macro for HLists
macro_rules! hlist {
        {} => { Nil };
            { $head:expr } => { Cons($head, Nil) };
                { $head:expr, $($tail:expr),* } => { Cons($head, hlist!($($tail),*)) };
}

// type-level macro for HLists
macro_rules! HList {
        {} => { Nil };
            { $head:ty } => { Cons<$head, Nil> };
                { $head:ty, $($tail:ty),* } => { Cons<$head, HList!($($tail),*)> };
}

// nil case for HList append
impl<Ys: HList> Add<Ys> for Nil {
        type Output = Ys;

            fn add(self, rhs: Ys) -> Ys {
                        rhs
                                }
}

// cons case for HList append
impl<Rec: HList + Sized, X, Xs: HList, Ys: HList> Add<Ys> for Cons<X, Xs> where
    Xs: Add<Ys, Output = Rec>,
{
        type Output = Cons<X, Rec>;

            fn add(self, rhs: Ys) -> Cons<X, Rec> {
                        Cons(self.0, self.1 + rhs)
                                }
}

// type macro Expr allows us to expand the + operator appropriately
macro_rules! Expr {
        { ( $($LHS:tt)+ ) } => { Expr!($($LHS)+) };
        { HList ! [ $($LHS:tt)* ] + $($RHS:tt)+ } => {
            <Expr!(HList![$($LHS)*]) as Add<Expr!($($RHS)+)>>::Output
        };
        { $LHS:tt + $($RHS:tt)+ } => { <Expr!($LHS) as Add<Expr!($($RHS)+)>>::Output };
        { $LHS:ty } => { $LHS };
}

// test demonstrating term level `xs + ys` and type level `Expr!(Xs + Ys)`
fn main() {
    fn aux<Xs: HList, Ys: HList>(xs: Xs, ys: Ys) -> Expr!(Xs + Ys)
        where Xs: Add<Ys> {
            xs + ys
        }

    let xs: HList![&str, bool, Vec<u64>] = hlist!["foo", false, vec![]];
    let ys: HList![u64, [u8; 3], ()] = hlist![0, [0, 1, 2], ()];

    // demonstrate recursive expansion of Expr!
    let zs: Expr!((HList![&str] + HList![bool] + HList![Vec<u64>]) +
                  (HList![u64] + HList![[u8; 3], ()]) +
                  HList![])
        = aux(xs, ys);
    assert_eq!(zs, hlist!["foo", false, vec![], 0, [0, 1, 2], ()])
}

<|endoftext|>


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

use collections::vec::Vec;

use core::intrinsics::{volatile_load, volatile_store};
use core::mem::size_of;
use core::ptr::{self, read, write};

use common::debug;
use common::memory;
use common::time::{self, Duration};

use drivers::pciconfig::PciConfig;

use schemes::KScheme;

use super::hci::{UsbHci, UsbMsg};
use super::setup::Setup;

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct Qtd {
    next: u32,
    next_alt: u32,
    token: u32,
    buffers: [u32; 5],
}

#[repr(packed)]
struct QueueHead {
    next: u32,
    characteristics: u32,
    capabilities: u32,
    qtd_ptr: u32,
    qtd: Qtd,
}

pub struct Ehci {
    pub pci: PciConfig,
    pub base: usize,
    pub irq: u8,
}

impl KScheme for Ehci {
    #[allow(non_snake_case)]
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            // debug::d("EHCI handle");

            unsafe {
                let CAPLENGTH = self.base as *mut u8;

                let opbase = self.base + read(CAPLENGTH) as usize;

                let USBSTS = (opbase + 4) as *mut u32;
                // debug::d(" USBSTS ");
                // debug::dh(*USBSTS as usize);

                write(USBSTS, 0b111111);

                // debug::d(" USBSTS ");
                // debug::dh(*USBSTS as usize);

                // let FRINDEX = (opbase + 0xC) as *mut u32;
                // debug::d(" FRINDEX ");
                // debug::dh(*FRINDEX as usize);
            }

            // debug::dl();
        }
    }
}

impl Ehci {
    pub unsafe fn new(mut pci: PciConfig) -> Box<Self> {
        let mut module = box Ehci {
            pci: pci,
            base: pci.read(0x10) as usize & 0xFFFFFFF0,
            irq: pci.read(0x3C) as u8 & 0xF,
        };

        module.init();

        module
    }

    #[allow(non_snake_case)]
    pub unsafe fn init(&mut self) {
        debug!("EHCI on: {:X}, IRQ {:X}", self.base, self.irq);

        self.pci.flag(4, 4, true); // Bus master

        let CAPLENGTH = self.base as *mut u8;
        let HCSPARAMS = (self.base + 4) as *mut u32;
        let HCCPARAMS = (self.base + 8) as *mut u32;

        debug::d(" CAPLENGTH ");
        debug::dd(read(CAPLENGTH) as usize);

        debug::d(" HCSPARAMS ");
        debug::dh(read(HCSPARAMS) as usize);

        debug::d(" HCCPARAMS ");
        debug::dh(read(HCCPARAMS) as usize);

        let ports = (read(HCSPARAMS) & 0b1111) as usize;
        debug::d(" PORTS ");
        debug::dd(ports);

        let eecp = ((read(HCCPARAMS) >> 8) & 0xFF) as u8;
        debug::d(" EECP ");
        debug::dh(eecp as usize);

        debug::dl();

        if eecp > 0 {
            if self.pci.read(eecp) & (1 << 24 | 1 << 16) == 1 << 16 {
                debug::d("Taking Ownership");
                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);

                self.pci.flag(eecp, 1 << 24, true);

                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);
                debug::dl();

                debug::d("Waiting");
                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);

                while self.pci.read(eecp) & (1 << 24 | 1 << 16) != 1 << 24 {}

                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);
                debug::dl();
            }
        }

        let opbase = self.base + *CAPLENGTH as usize;

        let USBCMD = opbase as *mut u32;
        let USBSTS = (opbase + 4) as *mut u32;
        let USBINTR = (opbase + 8) as *mut u32;
        let FRINDEX = (opbase + 0xC) as *mut u32;
        let CTRLDSSEGMENT = (opbase + 0x10) as *mut u32;
        let PERIODICLISTBASE = (opbase + 0x14) as *mut u32;
        let ASYNCLISTADDR = (opbase + 0x18) as *mut u32;
        let CONFIGFLAG = (opbase + 0x40) as *mut u32;
        let PORTSC = (opbase + 0x44) as *mut u32;

        if read(USBSTS) & (1 << 12) == 0 {
            debug::d("Halting");
            debug::d(" CMD ");
            debug::dh(read(USBCMD) as usize);

            debug::d(" STS ");
            debug::dh(read(USBSTS) as usize);

            write(USBCMD, read(USBCMD) & 0xFFFFFFF0);

            debug::d(" CMD ");
            debug::dh(*USBCMD as usize);

            debug::d(" STS ");
            debug::dh(*USBSTS as usize);
            debug::dl();

            debug::d("Waiting");
            while volatile_load(USBSTS) & (1 << 12) != (1 << 12) {}

            debug::d(" CMD ");
            debug::dh(read(USBCMD) as usize);

            debug::d(" STS ");
            debug::dh(read(USBSTS) as usize);
            debug::dl();
        }

        debug::d("Resetting");
        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);

        write(USBCMD, read(USBCMD) | (1 << 1));

        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);
        debug::dl();

        debug::d("Waiting");
        while volatile_load(USBCMD) & 1 << 1 == 1 << 1 {}

        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);
        debug::dl();

        debug::d("Enabling");
        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);

        write(USBINTR, 0b111111);

        write(USBCMD, read(USBCMD) | 1);
        write(CONFIGFLAG, 1);

        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);
        debug::dl();

        debug::d("Waiting");
        while volatile_load(USBSTS) & 1 << 12 == 1 << 12 {}

        debug::d(" CMD ");
        debug::dh(read(USBCMD) as usize);

        debug::d(" STS ");
        debug::dh(read(USBSTS) as usize);
        debug::dl();

        for i in 0..ports as isize {
            debug::dd(i as usize);
            debug::d(": ");
            debug::dh(read(PORTSC.offset(i)) as usize);
            debug::dl();

            if read(PORTSC.offset(i)) & 1 == 1 {
                debug::d("Device on port ");
                debug::dd(i as usize);
                debug::d(" ");
                debug::dh(read(PORTSC.offset(i)) as usize);
                debug::dl();

                if read(PORTSC.offset(i)) & 1 << 1 == 1 << 1 {
                    debug::d("Connection Change");
                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);

                    write(PORTSC.offset(i), read(PORTSC.offset(i)) | (1 << 1));

                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);
                    debug::dl();
                }

                if read(PORTSC.offset(i)) & 1 << 2 == 0 {
                    debug::d("Reset");
                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);

                    write(PORTSC.offset(i), read(PORTSC.offset(i)) | (1 << 8));

                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);

                    write(PORTSC.offset(i),
                    read(PORTSC.offset(i)) & 0xFFFFFEFF);

                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);
                    debug::dl();

                    debug::d("Wait");
                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);

                    while volatile_load(PORTSC.offset(i)) & 1 << 8 == 1 << 8 {
                        volatile_store(PORTSC.offset(i), volatile_load(PORTSC.offset(i)) & 0xFFFFFEFF);
                    }

                    debug::d(" ");
                    debug::dh(read(PORTSC.offset(i)) as usize);
                    debug::dl();
                }

                debug::d("Port Enabled ");
                debug::dh(read(PORTSC.offset(i)) as usize);
                debug::dl();

                self.device(i as u8 + 1);
            }
        }
    }
}

impl UsbHci for Ehci {
    fn msg(&mut self, address: u8, endpoint: u8, msgs: &[UsbMsg]) -> usize {
        let mut tds = Vec::new();
        for msg in msgs.iter().rev() {
            let link_ptr = match tds.last() {
                Some(td) => (td as *const Qtd) as u32,
                None => 1
            };

            match *msg {
                UsbMsg::Setup(setup) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: (size_of::<Setup>() as u32) << 16 | 0b10 << 8 | 1 << 7,
                    buffers: [(setup as *const Setup) as u32, 0, 0, 0, 0]
                }),
                UsbMsg::In(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b01 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::InIso(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b01 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::Out(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b00 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::OutIso(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b00 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                })
            }
        }

        let mut count = 0;

        if ! tds.is_empty() {
            unsafe {
                let CAPLENGTH = self.base as *mut u8;

                let opbase = self.base + *CAPLENGTH as usize;

                let USBCMD = opbase as *mut u32;
                let USBSTS = (opbase + 4) as *mut u32;
                let ASYNCLISTADDR = (opbase + 0x18) as *mut u32;

                let queuehead = box QueueHead {
                    next: 1,
                    characteristics: 1024 << 16 | 1 << 15 | 1 << 14 | 0b10 << 12 | (endpoint as u32) << 8 | address as u32,
                    capabilities: 0b01 << 30,
                    qtd_ptr: (tds.last().unwrap() as *const Qtd) as u32,
                    qtd: *tds.last().unwrap()
                };

                volatile_store(ASYNCLISTADDR, (&*queuehead as *const QueueHead) as u32 | 2);
                volatile_store(USBCMD, volatile_load(USBCMD) | 1 << 5 | 1);

                /*
                for td in tds.iter().rev() {
                    while unsafe { volatile_load(td as *const Qtd).token } & 1 << 7 == 1 << 7 {
                        //unsafe { context_switch(false) };
                    }
                }
                */

                while volatile_load(USBSTS) & 0xA000 == 0xA000 {}

                volatile_store(USBCMD, volatile_load(USBCMD) & (0xFFFFFFFF - (1 << 5 | 1)));
                volatile_store(ASYNCLISTADDR, 0);
            }
        }

        count
    }
}
<commit_msg>Get to the magical device descriptor<commit_after>use alloc::boxed::Box;

use collections::vec::Vec;

use core::intrinsics::{volatile_load, volatile_store};
use core::mem::size_of;
use core::ptr::{self, read, write};
use core::slice;

use common::debug;
use common::memory;
use common::time::{self, Duration};

use drivers::mmio::Mmio;
use drivers::pciconfig::PciConfig;

use schemes::KScheme;

use super::hci::{UsbHci, UsbMsg};
use super::setup::Setup;

#[repr(packed)]
#[derive(Copy, Clone, Debug, Default)]
struct Qtd {
    next: u32,
    next_alt: u32,
    token: u32,
    buffers: [u32; 5],
}

#[repr(packed)]
struct QueueHead {
    next: u32,
    characteristics: u32,
    capabilities: u32,
    qtd_ptr: u32,
    qtd: Qtd,
}

pub struct Ehci {
    pub pci: PciConfig,
    pub base: usize,
    pub irq: u8,
}

impl KScheme for Ehci {
    #[allow(non_snake_case)]
    fn on_irq(&mut self, irq: u8) {
        if irq == self.irq {
            // debug::d("EHCI handle");

            unsafe {
                let cap_length = &mut *(self.base as *mut Mmio<u8>);

                let op_base = self.base + cap_length.read() as usize;

                let usb_sts = &mut *((op_base + 4) as *mut Mmio<u32>);
                // debug::d(" usb_sts ");
                // debug::dh(*usb_sts as usize);

                usb_sts.writef(0b111111, true);

                // debug::d(" usb_sts ");
                // debug::dh(*usb_sts as usize);

                // let FRINDEX = (opbase + 0xC) as *mut Mmio<u32>;
                // debug::d(" FRINDEX ");
                // debug::dh(*FRINDEX as usize);
            }

            // debug::dl();
        }
    }
}

impl Ehci {
    pub unsafe fn new(mut pci: PciConfig) -> Box<Self> {
        let mut module = box Ehci {
            pci: pci,
            base: pci.read(0x10) as usize & 0xFFFFFFF0,
            irq: pci.read(0x3C) as u8 & 0xF,
        };

        module.init();

        module
    }

    #[allow(non_snake_case)]
    pub unsafe fn init(&mut self) {
        debug!("EHCI on: {:X}, IRQ {:X}", self.base, self.irq);

        self.pci.flag(4, 4, true); // Bus master

        let cap_length = &mut *(self.base as *mut Mmio<u8>);
        let hcs_params = &mut *((self.base + 4) as *mut Mmio<u32>);
        let hcc_params = &mut *((self.base + 8) as *mut Mmio<u32>);

        let ports = (hcs_params.read() & 0b1111) as usize;
        debug::d(" PORTS ");
        debug::dd(ports);

        let eecp = (hcc_params.read() >> 8) as u8;
        debug::d(" EECP ");
        debug::dh(eecp as usize);

        debug::dl();

        if eecp > 0 {
            if self.pci.read(eecp) & (1 << 24 | 1 << 16) == 1 << 16 {
                debug::d("Taking Ownership");
                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);

                self.pci.flag(eecp, 1 << 24, true);

                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);
                debug::dl();

                debug::d("Waiting");
                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);

                while self.pci.read(eecp) & (1 << 24 | 1 << 16) != 1 << 24 {}

                debug::d(" ");
                debug::dh(self.pci.read(eecp) as usize);
                debug::dl();
            }
        }

        let op_base = self.base + cap_length.read() as usize;

        let usb_cmd = &mut *(op_base as *mut Mmio<u32>);
        let usb_sts = &mut *((op_base + 4) as *mut Mmio<u32>);
        let usb_intr = &mut *((op_base + 8) as *mut Mmio<u32>);
        let config_flag = &mut *((op_base + 0x40) as *mut Mmio<u32>);
        let port_scs = &mut slice::from_raw_parts_mut((op_base + 0x44) as *mut Mmio<u32>, ports);

        /*
        let FRINDEX = (opbase + 0xC) as *mut Mmio<u32>;
        let CTRLDSSEGMENT = (opbase + 0x10) as *mut Mmio<u32>;
        let PERIODICLISTBASE = (opbase + 0x14) as *mut Mmio<u32>;
        let ASYNCLISTADDR = (opbase + 0x18) as *mut Mmio<u32>;
        */

        //Halt
        if usb_sts.read() & 1 << 12 == 0 {
            usb_cmd.writef(0xF, false);
            while ! usb_sts.readf(1 << 12) {}
        }

        //Reset
        usb_cmd.writef(1 << 1, true);
        while usb_cmd.readf(1 << 1) {}

        //Enable
        usb_intr.write(0b111111);
        usb_cmd.writef(1, true);
        config_flag.write(1);
        while usb_sts.readf(1 << 12) {}

        for i in 0..port_scs.len() {
            let port_sc = &mut port_scs[i];
            if port_sc.readf(1) {
                debugln!("Device on port {}: {:X}", i, port_sc.read());

                if port_sc.readf(1 << 1) {
                    debugln!("Connection Change");

                    port_sc.writef(1 << 1, true);
                }

                if ! port_sc.readf(1 << 2) {
                    debugln!("Reset");

                    while ! port_sc.readf(1 << 8) {
                        port_sc.writef(1 << 8, true);
                    }

                    let mut spin = 1000000000;
                    while spin > 0 {
                        spin -= 1;
                    }

                    while port_sc.readf(1 << 8) {
                        port_sc.writef(1 << 8, false);
                    }
                }

                debugln!("Port Enabled {:X}", port_sc.read());

                self.device(i as u8 + 1);
            }
        }
    }
}

impl UsbHci for Ehci {
    fn msg(&mut self, address: u8, endpoint: u8, msgs: &[UsbMsg]) -> usize {
        let mut tds = Vec::new();
        for msg in msgs.iter().rev() {
            let link_ptr = match tds.last() {
                Some(td) => (td as *const Qtd) as u32,
                None => 1
            };

            match *msg {
                UsbMsg::Setup(setup) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: (size_of::<Setup>() as u32) << 16 | 0b10 << 8 | 1 << 7,
                    buffers: [(setup as *const Setup) as u32, 0, 0, 0, 0]
                }),
                UsbMsg::In(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b01 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::InIso(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b01 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::Out(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b00 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                }),
                UsbMsg::OutIso(ref data) => tds.push(Qtd {
                    next: link_ptr,
                    next_alt: 1,
                    token: ((data.len() as u32) & 0x7FFF) << 16 | 0b00 << 8 | 1 << 7,
                    buffers: [data.as_ptr() as u32, 0, 0, 0, 0]
                })
            }
        }

        let mut count = 0;

        if ! tds.is_empty() {
            unsafe {
                let cap_length = &mut *(self.base as *mut Mmio<u8>);

                let op_base = self.base + cap_length.read() as usize;

                let usb_cmd = &mut *(op_base as *mut Mmio<u32>);
                let usb_sts = &mut *((op_base + 4) as *mut Mmio<u32>);
                let async_list = &mut *((op_base + 0x18) as *mut Mmio<u32>);

                let queuehead = box QueueHead {
                    next: 1,
                    characteristics: 1024 << 16 | 1 << 15 | 1 << 14 | 0b10 << 12 | (endpoint as u32) << 8 | address as u32,
                    capabilities: 0b01 << 30,
                    qtd_ptr: (tds.last().unwrap() as *const Qtd) as u32,
                    qtd: *tds.last().unwrap()
                };

                async_list.write((&*queuehead as *const QueueHead) as u32 | 2);
                usb_cmd.writef(1 << 5 | 1, true);

                /*
                for td in tds.iter().rev() {
                    while unsafe { volatile_load(td as *const Qtd).token } & 1 << 7 == 1 << 7 {
                        //unsafe { context_switch(false) };
                    }
                }
                */

                while usb_sts.readf(0xA000) {}

                usb_cmd.writef(1 << 5 | 1, false);
                async_list.write(0);
            }
        }

        count
    }
}
<|endoftext|>


<commit_before><commit_msg>create most complete example<commit_after>
extern crate cdrs;

use std::convert::Into;
use cdrs::IntoBytes;
use cdrs::client::{CDRS, Session};
use cdrs::consistency::Consistency;
use cdrs::query::{QueryBuilder, QueryParamsBuilder};
use cdrs::authenticators::NoneAuthenticator;
use cdrs::compression::Compression;
use cdrs::transport::TransportTcp;
use cdrs::types::{IntoRustByName, CBytesShort, AsRust};
use cdrs::types::value::{Value, Bytes};
use cdrs::types::list::List;
use cdrs::types::map::Map;
use cdrs::types::udt::UDT;
use std::collections::HashMap;

const _ADDR: &'static str = "127.0.0.1:9042";
const CREATE_KEY_SPACE: &'static str = "CREATE KEYSPACE IF NOT EXISTS my_ks WITH REPLICATION = { \
                                        'class' : 'SimpleStrategy', 'replication_factor' : 1 };";
const CREATE_UDT: &'static str = "CREATE TYPE IF NOT EXISTS my_ks.my_type (number int);";
const CREATE_TABLE_INT: &'static str = "CREATE TABLE IF NOT EXISTS my_ks.test_num (my_bigint \
                                        bigint PRIMARY KEY, my_int int, my_smallint smallint, \
                                        my_tinyint tinyint);";
const CREATE_TABLE_STR: &'static str = "CREATE TABLE IF NOT EXISTS my_ks.test_str (my_ascii \
                                        ascii PRIMARY KEY, my_text text, my_varchar varchar);";
const INSERT_STR: &'static str = "INSERT INTO my_ks.test_str (my_ascii, my_text, my_varchar) \
                                  VALUES (?, ?, ?);";
const SELECT_STR: &'static str = "SELECT * FROM my_ks.test_str;";
const CREATE_TABLE_LIST: &'static str = "CREATE TABLE IF NOT EXISTS my_ks.lists (my_string_list \
                                         frozen<list<text>> PRIMARY KEY, my_number_list \
                                         list<int>, my_complex_list list<frozen<list<smallint>>>);";
const INSERT_LIST: &'static str = "INSERT INTO my_ks.lists (my_string_list, \
                                   my_number_list, my_complex_list) VALUES (?, ?, ?);";
const SELECT_LIST: &'static str = "SELECT * FROM my_ks.lists;";
const CREATE_TABLE_MAP: &'static str =
    "CREATE TABLE IF NOT EXISTS my_ks.maps (my_string_map frozen<map<text, text>> PRIMARY KEY, \
     my_number_map map<text, int>, my_complex_map map<text, frozen<map<text, int>>>);";
const INSERT_MAP: &'static str = "INSERT INTO my_ks.maps (my_string_map, \
                                   my_number_map, my_complex_map) VALUES (?, ?, ?);";
const SELECT_MAP: &'static str = "SELECT * FROM my_ks.maps;";
const CREATE_TABLE_UDT: &'static str = "CREATE TABLE IF NOT EXISTS my_ks.udts (my_key int \
                                        PRIMARY KEY, my_udt my_type);";
const INSERT_UDT: &'static str = "INSERT INTO my_ks.udts (my_key, my_udt) VALUES (?, ?);";
const SELECT_UDT: &'static str = "SELECT * FROM my_ks.udts;";
const INSERT_INT: &'static str = "INSERT INTO my_ks.test_num (my_bigint, my_int, my_smallint, \
                                  my_tinyint) VALUES (?, ?, ?, ?)";
const SELECT_INT: &'static str = "SELECT * FROM my_ks.test_num";

// // select all
fn main() {
    let authenticator = NoneAuthenticator;
    let tcp_transport = TransportTcp::new(_ADDR).unwrap();
    let client = CDRS::new(tcp_transport, authenticator);
    let mut session = client.start(Compression::None).unwrap();

    if create_keyspace(&mut session) {
        println!("0. keyspace created");
    }

    if create_type(&mut session) {
        println!("1. user type created");
    }

    if create_table(&mut session) {
        println!("2. table created");
    }

    let ref prepared_id = prepare_query(&mut session, INSERT_INT);

    if insert_ints(&mut session, &prepared_id) {
        println!("3. integers inserted");
    }

    if select_all_ints(&mut session) {
        println!("4. integers selected");
    }

    if create_table_str(&mut session) {
        println!("5. str table created");
    }

    if insert_table_str(&mut session) {
        println!("6. str table created");
    }

    if insert_table_str(&mut session) {
        println!("7. str table inserted");
    }

    if insert_table_string(&mut session) {
        println!("8. string table inserted");
    }

    if select_table_str(&mut session) {
        println!("9. strings selected");
    }

    if create_table_list(&mut session) {
        println!("10. list table created");
    }

    if insert_table_list(&mut session) {
        println!("11. list inserted");
    }

    if select_table_list(&mut session) {
        println!("12. list selected");
    }

    if create_table_map(&mut session) {
        println!("13. map table created");
    }

    if insert_table_map(&mut session) {
        println!("14. map table inserted");
    }

    if select_table_map(&mut session) {
        println!("15. map table created");
    }

    if create_table_udt(&mut session) {
        println!("16. udt table select");
    }

    if insert_table_udt(&mut session) {
        println!("17. udt table inserted");
    }

    if select_table_udt(&mut session) {
        println!("18. udt table selected");
    }

}

fn create_keyspace(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_KEY_SPACE).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_keyspace {:?}", err),
        Ok(_) => true,
    }
}

fn create_type(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_UDT).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_type {:?}", err),
        Ok(_) => true,
    }
}

fn create_table(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_TABLE_INT).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_table {:?}", err),
        Ok(_) => true,
    }
}

fn prepare_query(session: &mut Session<NoneAuthenticator, TransportTcp>,
                 query: &'static str)
                 -> CBytesShort {
    session.prepare(query.to_string(), false, false).unwrap().get_body().into_prepared().unwrap().id
}

fn insert_ints(session: &mut Session<NoneAuthenticator, TransportTcp>,
               prepared_id: &CBytesShort)
               -> bool {
    let ints = Ints {
        bigint: 123,
        int: 234,
        smallint: 256,
        tinyint: 56,
    };
    let values_i: Vec<Value> =
        vec![ints.bigint.into(), ints.int.into(), ints.smallint.into(), ints.tinyint.into()];

    let execute_params = QueryParamsBuilder::new(Consistency::One).values(values_i).finalize();
    let executed = session.execute(prepared_id, execute_params, false, false);
    match executed {
        Err(ref err) => panic!("executed int {:?}", err),
        Ok(_) => true,
    }
}

fn select_all_ints(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let select_query = QueryBuilder::new(SELECT_INT).finalize();
    let all = session.query(select_query, false, false).unwrap().get_body().into_rows().unwrap();

    for row in all {
        let _ = Ints {
            bigint: row.get_by_name("my_bigint").expect("my_bigint").unwrap(),
            int: row.get_by_name("my_int").expect("my_int").unwrap(),
            smallint: row.get_by_name("my_smallint").expect("my_smallint").unwrap(),
            tinyint: row.get_by_name("my_tinyint").expect("my_tinyint").unwrap(),
        };
    }

    true
}

fn create_table_str(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_TABLE_STR).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_table str {:?}", err),
        Ok(_) => true,
    }
}

fn insert_table_str(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let strs = Strs {
        my_ascii: "my_ascii",
        my_text: "my_text",
        my_varchar: "my_varchar",
    };
    let values_s: Vec<Value> =
        vec![strs.my_ascii.into(), strs.my_text.into(), strs.my_varchar.into()];

    let query = QueryBuilder::new(INSERT_STR).values(values_s).finalize();
    let inserted = session.query(query, false, false);
    match inserted {
        Err(ref err) => panic!("inserted str {:?}", err),
        Ok(_) => true,
    }
}

fn insert_table_string(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let strings = Strings {
        my_ascii: "my_ascii".to_string(),
        my_text: "my_text".to_string(),
        my_varchar: "my_varchar".to_string(),
    };
    let values_s: Vec<Value> =
        vec![strings.my_ascii.into(), strings.my_text.into(), strings.my_varchar.into()];

    let query = QueryBuilder::new(INSERT_STR).values(values_s).finalize();
    let inserted = session.query(query, false, false);
    match inserted {
        Err(ref err) => panic!("inserted strings {:?}", err),
        Ok(_) => true,
    }
}

fn select_table_str(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let select_query = QueryBuilder::new(SELECT_STR).finalize();
    let all = session.query(select_query, false, false).unwrap().get_body().into_rows().unwrap();

    for row in all {
        let _ = Strings {
            my_ascii: row.get_by_name("my_ascii").expect("my_ascii").unwrap(),
            my_text: row.get_by_name("my_text").expect("my_text").unwrap(),
            my_varchar: row.get_by_name("my_varchar").expect("my_ascii").unwrap(),
        };
    }

    true
}

fn create_table_list(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_TABLE_LIST).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_table list {:?}", err),
        Ok(_) => true,
    }
}

fn insert_table_list(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let lists = Lists {
        string_list: vec!["hello".to_string(), "world".to_string()],
        number_list: vec![1, 2, 3],
        complex_list: vec![vec![1, 3, 4], vec![4, 5, 6]],
    };

    let values: Vec<Value> =
        vec![lists.string_list.into(), lists.number_list.into(), lists.complex_list.into()];

    let query = QueryBuilder::new(INSERT_LIST).values(values).finalize();
    let inserted = session.query(query, false, false);
    match inserted {
        Err(ref err) => panic!("inserted lists {:?}", err),
        Ok(_) => true,
    }
}

fn select_table_list(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let select_query = QueryBuilder::new(SELECT_LIST).finalize();
    let all = session.query(select_query, false, false)
        .unwrap()
        .get_body()
        .into_rows()
        .unwrap();

    for row in all {
        let cl = CassandraLists {
            string_list: row.get_by_name("my_string_list").expect("string_list").unwrap(),
            number_list: row.get_by_name("my_number_list").expect("number_list").unwrap(),
            complex_list: row.get_by_name("my_complex_list").expect("complex_list").unwrap(),
        };
        let complex_list_c: Vec<List> = cl.complex_list.as_rust().expect("my_complex_list");
        let _ = Lists {
            string_list: cl.string_list.as_rust().expect("string_list"),
            number_list: cl.number_list.as_rust().expect("number_list"),
            complex_list: complex_list_c.iter()
                .map(|it| it.as_rust().expect("number_list_c"))
                .collect(),
        };
    }

    true
}

fn insert_table_map(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let mut string_map: HashMap<String, String> = HashMap::new();
    string_map.insert("a".to_string(), "A".to_string());
    let mut number_map: HashMap<String, i32> = HashMap::new();
    number_map.insert("one".to_string(), 1);
    let mut complex_map: HashMap<String, HashMap<String, i32>> = HashMap::new();
    complex_map.insert("nested".to_string(), number_map.clone());
    let maps = Maps {
        string_map: string_map,
        number_map: number_map,
        complex_map: complex_map,
    };

    let values: Vec<Value> =
        vec![maps.string_map.into(), maps.number_map.into(), maps.complex_map.into()];

    let query = QueryBuilder::new(INSERT_MAP).values(values).finalize();
    let inserted = session.query(query, false, false);
    match inserted {
        Err(ref err) => panic!("inserted maps {:?}", err),
        Ok(_) => true,
    }
}

fn select_table_map(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {

    let select_query = QueryBuilder::new(SELECT_MAP).finalize();
    let all = session.query(select_query, false, false)
        .unwrap()
        .get_body()
        .into_rows()
        .unwrap();

    for row in all {
        let cm = CassandraMaps {
            string_map: row.get_by_name("my_string_map").expect("string_map").unwrap(),
            number_map: row.get_by_name("my_number_map").expect("number_map").unwrap(),
            complex_map: row.get_by_name("my_complex_map").expect("complex_map").unwrap(),
        };
        let complex_map_c: HashMap<String, Map> = cm.complex_map.as_rust().expect("my_complex_map");
        let _ = Maps {
            string_map: cm.string_map.as_rust().expect("string_map"),
            number_map: cm.number_map.as_rust().expect("number_map"),
            complex_map: complex_map_c.iter()
                .fold(HashMap::new(), |mut hm, (k, v)| {
                    hm.insert(k.clone(), v.as_rust().expect("complex_map_c"));
                    hm
                }),
        };
    }

    true
}

fn create_table_map(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_TABLE_MAP).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_table map {:?}", err),
        Ok(_) => true,
    }
}

fn create_table_udt(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let q = QueryBuilder::new(CREATE_TABLE_UDT).finalize();
    match session.query(q, false, false) {
        Err(ref err) => panic!("create_table udt {:?}", err),
        Ok(_) => true,
    }
}

fn insert_table_udt(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {
    let udt = Udt { number: 12 };
    let values: Vec<Value> = vec![(1 as i32).into(), udt.into()];

    let query = QueryBuilder::new(INSERT_UDT).values(values).finalize();
    let inserted = session.query(query, false, false);
    match inserted {
        Err(ref err) => panic!("inserted udt {:?}", err),
        Ok(_) => true,
    }
}

fn select_table_udt(session: &mut Session<NoneAuthenticator, TransportTcp>) -> bool {

    let select_query = QueryBuilder::new(SELECT_UDT).finalize();
    let all = session.query(select_query, false, false)
        .unwrap()
        .get_body()
        .into_rows()
        .unwrap();

    for row in all {
        let udt_c: UDT = row.get_by_name("my_udt").expect("my_udt").unwrap();
        let _ = Udt { number: udt_c.get_by_name("number").expect("number").unwrap() };
    }

    true
}

struct Ints {
    pub bigint: i64,
    pub int: i32,
    pub smallint: i16,
    pub tinyint: i8,
}

struct Strs<'a> {
    pub my_ascii: &'a str,
    pub my_text: &'a str,
    pub my_varchar: &'a str,
}

struct Strings {
    pub my_ascii: String,
    pub my_text: String,
    pub my_varchar: String,
}

#[derive(Debug)]
struct Lists {
    pub string_list: Vec<String>,
    pub number_list: Vec<i32>,
    pub complex_list: Vec<Vec<i16>>,
}

#[derive(Debug)]
struct CassandraLists {
    pub string_list: List,
    pub number_list: List,
    pub complex_list: List,
}

#[derive(Debug)]
struct Maps {
    pub string_map: HashMap<String, String>,
    pub number_map: HashMap<String, i32>,
    pub complex_map: HashMap<String, HashMap<String, i32>>,
}

struct CassandraMaps {
    pub string_map: Map,
    pub number_map: Map,
    pub complex_map: Map,
}

#[derive(Debug)]
struct Udt {
    pub number: i32,
}

impl Into<Bytes> for Udt {
    fn into(self) -> Bytes {
        let mut bytes: Vec<u8> = vec![];
        let val_bytes: Bytes = self.number.into();
        bytes.extend_from_slice(Value::new_normal(val_bytes).into_cbytes().as_slice());
        Bytes::new(bytes)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add problem #63<commit_after>use std::bigint::{ BigUint };

use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 63,
    answer: "49",
    solver: solve
};

fn solve() -> ~str {
    let mut cnt = 1u; // a == 1
    for uint::range(2, 10) |a_uint| {
        let mut a = BigUint::from_uint(a_uint);
        let mut n = 0;
        let mut an = BigUint::from_uint(1);
        loop {
            n += 1;
            an = an * a;
            let an_str = an.to_str();
            if an_str.len() != n { break; }

            cnt += 1;
        }
    }

    return cnt.to_str();
}

<|endoftext|>


<commit_before><commit_msg>Add problem #75<commit_after>use common::arith::{ isqrt };
use common::calc::{ get_gcd };
use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 75,
    answer: "161667",
    solver: solve
};

fn each_prim_pythagorean(m: uint, f: &fn(uint, uint, uint) -> bool) {
    let n0 = if m % 2 == 0 { 1 } else { 2 };
    for uint::range_step(n0, m, 2) |n| {
        if get_gcd(m, n) == 1 {
            let a = m * m - n * n;
            let b = 2 * m * n;
            let c = m * m + n * n;
            if a < b {
                if !f(a, b, c) { return; }
            } else {
                if !f(b, a, c) { return; }
            }
        }
    }
}

fn solve() -> ~str {
    let limit = 1500000;
    let mut v = vec::from_elem(limit + 1, 0);
    for uint::range(2, isqrt(limit / 2)) |m| {
        for each_prim_pythagorean(m) |a, b, c| {
            let sum = a + b + c;
            for uint::range_step(sum, limit + 1, sum as int) |s| {
                v[s] += 1;
            }
        }
    }

    return v.count(&1).to_str();
}
<|endoftext|>


<commit_before><commit_msg>Add problem #77<commit_after>use core::hashmap::{ HashMap };

use common::prime::{ Prime };
use common::problem::{ Problem };

pub static problem: Problem<'static> = Problem {
    id: 77,
    answer: "71",
    solver: solve
};

fn count_way(
    sum: uint, map: &mut HashMap<(uint, uint), uint>, ps: &mut Prime
) -> uint {

    let cnt = count_sub(sum, 0, map, ps);
    if ps.is_prime(sum) {
        return cnt - 1;
    } else {
        return cnt;
    }

    fn count_sub(
        sum: uint, min_idx: uint, map: &mut HashMap<(uint, uint), uint>,
        ps: &mut Prime
    ) -> uint {
        let mut cnt = 0;
        let mut i = min_idx;
        loop {
            let mut p = ps.get_at(i);
            if p == sum {
                map.insert((p, i), 1);
                cnt += 1;
                break;
            }
            if sum < 2 * p { break; }

            cnt += match map.find(&(sum - p, i)).map(|v| **v) {
                Some(n) => n,
                None    => count_sub(sum - p, i, map, ps)
            };
            i += 1;
        }

        map.insert((sum, i), cnt);
        return cnt;
    }
}

fn solve() -> ~str {
    let mut ps = Prime::new();
    let mut map = HashMap::new();
    let mut n = 1;
    loop {
        let cnt = count_way(n, &mut map, &mut ps);
        if cnt > 5000 { return n.to_str(); }
        n += 1;
    }
}
<|endoftext|>


<commit_before>use std::io::fs;
use std::io;

use colours::{Plain, Style, Black, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
use column::{Column, Permissions, FileName, FileSize, User, Group};
use format::{format_metric_bytes, format_IEC_bytes};
use unix::{get_user_name, get_group_name};
use sort::SortPart;

static MEDIA_TYPES: &'static [&'static str] = &[
    "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
    "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
    "svg", "pdf", "stl", "eps", "dvi", "ps" ];

static COMPRESSED_TYPES: &'static [&'static str] = &[
    "zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
    "iso", "dmg", "tc", "rar", "par" ];

// Instead of working with Rust's Paths, we have our own File object
// that holds the Path and various cached information. Each file is
// definitely going to have its filename used at least once, its stat
// information queried at least once, and its file extension extracted
// at least once, so we may as well carry around that information with
// the actual path.

pub struct File<'a> {
    pub name: &'a str,
    pub ext:  Option<&'a str>,
    pub path: &'a Path,
    pub stat: io::FileStat,
    pub parts: Vec<SortPart>,
}

impl<'a> File<'a> {
    pub fn from_path(path: &'a Path) -> File<'a> {
        // Getting the string from a filename fails whenever it's not
        // UTF-8 representable - just assume it is for now.
        let filename: &str = path.filename_str().unwrap();

        // Use lstat here instead of file.stat(), as it doesn't follow
        // symbolic links. Otherwise, the stat() call will fail if it
        // encounters a link that's target is non-existent.
        let stat: io::FileStat = match fs::lstat(path) {
            Ok(stat) => stat,
            Err(e) => fail!("Couldn't stat {}: {}", filename, e),
        };

        return File {
            path:  path,
            stat:  stat,
            name:  filename,
            ext:   File::ext(filename),
            parts: SortPart::split_into_parts(filename),
        };
    }

    fn ext(name: &'a str) -> Option<&'a str> {
        // The extension is the series of characters after a dot at
        // the end of a filename. This deliberately also counts
        // dotfiles - the ".git" folder has the extension "git".
        let re = regex!(r"\.([^.]+)$");
        re.captures(name).map(|caps| caps.at(1))
    }

    pub fn is_dotfile(&self) -> bool {
        self.name.starts_with(".")
    }

    fn is_tmpfile(&self) -> bool {
        self.name.ends_with("~") || (self.name.starts_with("#") && self.name.ends_with("#"))
    }

    pub fn display(&self, column: &Column) -> String {
        match *column {
            Permissions => self.permissions_string(),
            FileName => self.file_colour().paint(self.name),
            FileSize(use_iec) => self.file_size(use_iec),

            // Display the ID if the user/group doesn't exist, which
            // usually means it was deleted but its files weren't.
            User(uid) => {
                let style = if uid == self.stat.unstable.uid { Yellow.bold() } else { Plain };
                let string = get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str());
                return style.paint(string.as_slice());
            },
            Group => get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
        }
    }

    fn file_size(&self, use_iec_prefixes: bool) -> String {
        // Don't report file sizes for directories. I've never looked
        // at one of those numbers and gained any information from it.
        if self.stat.kind == io::TypeDirectory {
            Black.bold().paint("-")
        } else {
            let (size, suffix) = if use_iec_prefixes {
                format_IEC_bytes(self.stat.size)
            } else {
                format_metric_bytes(self.stat.size)
            };

            return format!("{}{}", Green.bold().paint(size.as_slice()), Green.paint(suffix.as_slice()));
        }
    }

    fn type_char(&self) -> String {
        return match self.stat.kind {
            io::TypeFile         => ".".to_string(),
            io::TypeDirectory    => Blue.paint("d"),
            io::TypeNamedPipe    => Yellow.paint("|"),
            io::TypeBlockSpecial => Purple.paint("s"),
            io::TypeSymlink      => Cyan.paint("l"),
            _                    => "?".to_string(),
        }
    }

    fn file_colour(&self) -> Style {
        if self.stat.kind == io::TypeDirectory {
            Blue.bold()
        }
        else if self.stat.perm.contains(io::UserExecute) {
            Green.bold()
        }
        else if self.is_tmpfile() {
            Fixed(244).normal()  // midway between white and black - should show up as grey on all terminals
        }
        else if self.name.starts_with("README") {
            Yellow.bold().underline()
        }
        else if self.ext.is_some() && MEDIA_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Purple.normal()
        }
        else if self.ext.is_some() && COMPRESSED_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Red.normal()
        }
        else {
            Plain
        }
    }

    fn permissions_string(&self) -> String {
        let bits = self.stat.perm;
        return format!("{}{}{}{}{}{}{}{}{}{}",
            self.type_char(),

            // The first three are bold because they're the ones used
            // most often.
            File::permission_bit(bits, io::UserRead,     "r", Yellow.bold()),
            File::permission_bit(bits, io::UserWrite,    "w", Red.bold()),
            File::permission_bit(bits, io::UserExecute,  "x", Green.bold().underline()),
            File::permission_bit(bits, io::GroupRead,    "r", Yellow.normal()),
            File::permission_bit(bits, io::GroupWrite,   "w", Red.normal()),
            File::permission_bit(bits, io::GroupExecute, "x", Green.normal()),
            File::permission_bit(bits, io::OtherRead,    "r", Yellow.normal()),
            File::permission_bit(bits, io::OtherWrite,   "w", Red.normal()),
            File::permission_bit(bits, io::OtherExecute, "x", Green.normal()),
       );
    }

    fn permission_bit(bits: io::FilePermission, bit: io::FilePermission, character: &'static str, style: Style) -> String {
        if bits.contains(bit) {
            style.paint(character.as_slice())
        } else {
            Black.bold().paint("-".as_slice())
        }
    }
}
<commit_msg>Highlight compiled files if their source is present<commit_after>use std::io::fs;
use std::io;

use colours::{Plain, Style, Black, Red, Green, Yellow, Blue, Purple, Cyan, Fixed};
use column::{Column, Permissions, FileName, FileSize, User, Group};
use format::{format_metric_bytes, format_IEC_bytes};
use unix::{get_user_name, get_group_name};
use sort::SortPart;

static MEDIA_TYPES: &'static [&'static str] = &[
    "png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
    "ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
    "svg", "pdf", "stl", "eps", "dvi", "ps" ];

static COMPRESSED_TYPES: &'static [&'static str] = &[
    "zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
    "iso", "dmg", "tc", "rar", "par" ];

// Instead of working with Rust's Paths, we have our own File object
// that holds the Path and various cached information. Each file is
// definitely going to have its filename used at least once, its stat
// information queried at least once, and its file extension extracted
// at least once, so we may as well carry around that information with
// the actual path.

pub struct File<'a> {
    pub name: &'a str,
    pub ext:  Option<&'a str>,
    pub path: &'a Path,
    pub stat: io::FileStat,
    pub parts: Vec<SortPart>,
}

impl<'a> File<'a> {
    pub fn from_path(path: &'a Path) -> File<'a> {
        // Getting the string from a filename fails whenever it's not
        // UTF-8 representable - just assume it is for now.
        let filename: &str = path.filename_str().unwrap();

        // Use lstat here instead of file.stat(), as it doesn't follow
        // symbolic links. Otherwise, the stat() call will fail if it
        // encounters a link that's target is non-existent.
        let stat: io::FileStat = match fs::lstat(path) {
            Ok(stat) => stat,
            Err(e) => fail!("Couldn't stat {}: {}", filename, e),
        };

        return File {
            path:  path,
            stat:  stat,
            name:  filename,
            ext:   File::ext(filename),
            parts: SortPart::split_into_parts(filename),
        };
    }

    fn ext(name: &'a str) -> Option<&'a str> {
        // The extension is the series of characters after a dot at
        // the end of a filename. This deliberately also counts
        // dotfiles - the ".git" folder has the extension "git".
        let re = regex!(r"\.([^.]+)$");
        re.captures(name).map(|caps| caps.at(1))
    }

    pub fn is_dotfile(&self) -> bool {
        self.name.starts_with(".")
    }

    fn is_tmpfile(&self) -> bool {
        self.name.ends_with("~") || (self.name.starts_with("#") && self.name.ends_with("#"))
    }

    fn with_extension(&self, newext: &'static str) -> String {
        format!("{}.{}", self.path.filestem_str().unwrap(), newext)
    }

    fn get_source_files(&self) -> Vec<String> {
        match self.ext {
            Some("class") => vec![self.with_extension("java")],  // Java
            Some("elc") => vec![self.name.chop()],  // Emacs Lisp
            Some("hi") => vec![self.with_extension("hs")],  // Haskell
            Some("o") => vec![self.with_extension("c"), self.with_extension("cpp")],  // C, C++
            Some("pyc") => vec![self.name.chop()],  // Python
            _ => vec![],
        }
    }

    pub fn display(&self, column: &Column) -> String {
        match *column {
            Permissions => self.permissions_string(),
            FileName => self.file_colour().paint(self.name),
            FileSize(use_iec) => self.file_size(use_iec),

            // Display the ID if the user/group doesn't exist, which
            // usually means it was deleted but its files weren't.
            User(uid) => {
                let style = if uid == self.stat.unstable.uid { Yellow.bold() } else { Plain };
                let string = get_user_name(self.stat.unstable.uid as i32).unwrap_or(self.stat.unstable.uid.to_str());
                return style.paint(string.as_slice());
            },
            Group => get_group_name(self.stat.unstable.gid as u32).unwrap_or(self.stat.unstable.gid.to_str()),
        }
    }

    fn file_size(&self, use_iec_prefixes: bool) -> String {
        // Don't report file sizes for directories. I've never looked
        // at one of those numbers and gained any information from it.
        if self.stat.kind == io::TypeDirectory {
            Black.bold().paint("-")
        } else {
            let (size, suffix) = if use_iec_prefixes {
                format_IEC_bytes(self.stat.size)
            } else {
                format_metric_bytes(self.stat.size)
            };

            return format!("{}{}", Green.bold().paint(size.as_slice()), Green.paint(suffix.as_slice()));
        }
    }

    fn type_char(&self) -> String {
        return match self.stat.kind {
            io::TypeFile         => ".".to_string(),
            io::TypeDirectory    => Blue.paint("d"),
            io::TypeNamedPipe    => Yellow.paint("|"),
            io::TypeBlockSpecial => Purple.paint("s"),
            io::TypeSymlink      => Cyan.paint("l"),
            _                    => "?".to_string(),
        }
    }

    fn file_colour(&self) -> Style {
        if self.stat.kind == io::TypeDirectory {
            Blue.bold()
        }
        else if self.stat.perm.contains(io::UserExecute) {
            Green.bold()
        }
        else if self.is_tmpfile() {
            Fixed(244).normal()  // midway between white and black - should show up as grey on all terminals
        }
        else if self.name.starts_with("README") {
            Yellow.bold().underline()
        }
        else if self.ext.is_some() && MEDIA_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Purple.normal()
        }
        else if self.ext.is_some() && COMPRESSED_TYPES.iter().any(|&s| s == self.ext.unwrap()) {
            Red.normal()
        }
        else {
            let source_files = self.get_source_files();
            if source_files.len() == 0 {
                Plain
            }
            else if source_files.iter().any(|filename| Path::new(format!("{}/{}", self.path.dirname_str().unwrap(), filename)).exists()) {
                Fixed(244).normal()
            }
            else {
                Fixed(137).normal()
            }
        }
    }

    fn permissions_string(&self) -> String {
        let bits = self.stat.perm;
        return format!("{}{}{}{}{}{}{}{}{}{}",
            self.type_char(),

            // The first three are bold because they're the ones used
            // most often.
            File::permission_bit(bits, io::UserRead,     "r", Yellow.bold()),
            File::permission_bit(bits, io::UserWrite,    "w", Red.bold()),
            File::permission_bit(bits, io::UserExecute,  "x", Green.bold().underline()),
            File::permission_bit(bits, io::GroupRead,    "r", Yellow.normal()),
            File::permission_bit(bits, io::GroupWrite,   "w", Red.normal()),
            File::permission_bit(bits, io::GroupExecute, "x", Green.normal()),
            File::permission_bit(bits, io::OtherRead,    "r", Yellow.normal()),
            File::permission_bit(bits, io::OtherWrite,   "w", Red.normal()),
            File::permission_bit(bits, io::OtherExecute, "x", Green.normal()),
       );
    }

    fn permission_bit(bits: io::FilePermission, bit: io::FilePermission, character: &'static str, style: Style) -> String {
        if bits.contains(bit) {
            style.paint(character.as_slice())
        } else {
            Black.bold().paint("-".as_slice())
        }
    }
}

trait Chop {
    fn chop(&self) -> String;
}

impl<'a> Chop for &'a str {
    fn chop(&self) -> String {
        self.slice_to(self.len() - 1).to_string()
    }
}<|endoftext|>


<commit_before><commit_msg>Revert "genet-napi: add TypeId check in Env#upwrap"<commit_after><|endoftext|>


<commit_before><commit_msg>Add regression test for bad substs<commit_after>fn main() {
    let f: fn(i32) -> Option<i32> = Some::<i32>;
    f(42);
}
<|endoftext|>


<commit_before><commit_msg>exercise 10: grading (original amirite)<commit_after>fn main() {
	for g in range(1, 34) {
		let grade = g * 3;
		println!("{g}, {grade}",
			g = grade,
			grade = gradeBracket(grade)
			);
	}
}

fn gradeBracket(numericGrade: int) -> ~str {
	let grade = if numericGrade < 60 {
		~"F"
	} else if numericGrade < 70 {
		~"D"
	} else if numericGrade < 80 {
		~"C"
	} else if numericGrade < 90 {
		~"B"
	} else {
		~"A"
	};

	grade + if numericGrade % 10 <= 3 {
		"-"
	} else if numericGrade % 10 > 6 {
		"+"
	} else {
		""
	}
}
<|endoftext|>