<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/// The GdkPixbuf structure contains information that describes an image in memory.

use glib::translate::{FromGlibPtr, ToGlibPtr};
use gdk::{self, ffi};
use c_vec::CVec;
use std::ptr::Unique;

#[repr(C)]
#[derive(Copy)]
/// This is the main structure in the &gdk-pixbuf; library. It is used to represent images. It contains information about the image's pixel
/// data, its color space, bits per sample, width and height, and the rowstride (the number of bytes between the start of one row and the
/// start of the next).
pub struct Pixbuf {
    pointer: *mut ffi::C_GdkPixbuf
}

impl Pixbuf {
    pub fn get_colorspace(&self) -> gdk::ColorSpace {
        unsafe { ffi::gdk_pixbuf_get_colorspace(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_n_channels(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_n_channels(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_has_alpha(&self) -> bool {
        unsafe { ::glib::to_bool(ffi::gdk_pixbuf_get_has_alpha(self.pointer as *const ffi::C_GdkPixbuf)) }
    }

    pub fn get_bits_per_sample(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_bits_per_sample(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_pixels_with_length(&self, length: &mut u32) -> Option<CVec<u8>> {
        let tmp = unsafe { ffi::gdk_pixbuf_get_pixels_with_length(self.pointer as *const ffi::C_GdkPixbuf, length) };

        unsafe {
            if tmp.is_null() {
                None
            } else {
                Some(CVec::new(Unique::new(tmp), *length as usize))
            }
        }
    }

    pub fn get_width(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_width(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_height(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_height(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_rowstride(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_rowstride(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_byte_length(&self) -> u64 {
        unsafe { ffi::gdk_pixbuf_get_byte_length(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_option(&self, key: &str) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gdk_pixbuf_get_option(self.pointer as *const ffi::C_GdkPixbuf,
                                           key.borrow_to_glib().0))
        }
    }

    /// a convenient function
    /// It won't work for pixbufs with images that are other than 8 bits per sample or channel, but it will work for most of the
    /// pixbufs that GTK+ uses.
    pub fn put_pixel(&self, x: i32, y: i32, red: u8, green: u8, blue: u8, alpha: u8) {
        let n_channels = self.get_n_channels();
        let rowstride = self.get_rowstride();
        let mut length = 0u32;
        let pixels = self.get_pixels_with_length(&mut length);
        if pixels.is_none() {
            return;
        }
        let mut pixels = pixels.unwrap();
        let s_pixels = pixels.as_mut();
        let pos = (y * rowstride + x * n_channels) as usize;

        s_pixels[pos] = red;
        s_pixels[pos + 1] = green;
        s_pixels[pos + 2] = blue;
        s_pixels[pos + 3] = alpha;
    }
}

impl_GObjectFunctions!(Pixbuf, C_GdkPixbuf);<commit_msg>Make Pixbuf::get_byte_length more platform-flexible<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/// The GdkPixbuf structure contains information that describes an image in memory.

use glib::translate::{FromGlibPtr, ToGlibPtr};
use gdk::{self, ffi};
use c_vec::CVec;
use std::ptr::Unique;

#[repr(C)]
#[derive(Copy)]
/// This is the main structure in the &gdk-pixbuf; library. It is used to represent images. It contains information about the image's pixel
/// data, its color space, bits per sample, width and height, and the rowstride (the number of bytes between the start of one row and the
/// start of the next).
pub struct Pixbuf {
    pointer: *mut ffi::C_GdkPixbuf
}

impl Pixbuf {
    pub fn get_colorspace(&self) -> gdk::ColorSpace {
        unsafe { ffi::gdk_pixbuf_get_colorspace(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_n_channels(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_n_channels(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_has_alpha(&self) -> bool {
        unsafe { ::glib::to_bool(ffi::gdk_pixbuf_get_has_alpha(self.pointer as *const ffi::C_GdkPixbuf)) }
    }

    pub fn get_bits_per_sample(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_bits_per_sample(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_pixels_with_length(&self, length: &mut u32) -> Option<CVec<u8>> {
        let tmp = unsafe { ffi::gdk_pixbuf_get_pixels_with_length(self.pointer as *const ffi::C_GdkPixbuf, length) };

        unsafe {
            if tmp.is_null() {
                None
            } else {
                Some(CVec::new(Unique::new(tmp), *length as usize))
            }
        }
    }

    pub fn get_width(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_width(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_height(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_height(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_rowstride(&self) -> i32 {
        unsafe { ffi::gdk_pixbuf_get_rowstride(self.pointer as *const ffi::C_GdkPixbuf) }
    }

    pub fn get_byte_length(&self) -> usize {
        unsafe { ffi::gdk_pixbuf_get_byte_length(self.pointer as *const ffi::C_GdkPixbuf) as usize }
    }

    pub fn get_option(&self, key: &str) -> Option<String> {
        unsafe {
            FromGlibPtr::borrow(
                ffi::gdk_pixbuf_get_option(self.pointer as *const ffi::C_GdkPixbuf,
                                           key.borrow_to_glib().0))
        }
    }

    /// a convenient function
    /// It won't work for pixbufs with images that are other than 8 bits per sample or channel, but it will work for most of the
    /// pixbufs that GTK+ uses.
    pub fn put_pixel(&self, x: i32, y: i32, red: u8, green: u8, blue: u8, alpha: u8) {
        let n_channels = self.get_n_channels();
        let rowstride = self.get_rowstride();
        let mut length = 0u32;
        let pixels = self.get_pixels_with_length(&mut length);
        if pixels.is_none() {
            return;
        }
        let mut pixels = pixels.unwrap();
        let s_pixels = pixels.as_mut();
        let pos = (y * rowstride + x * n_channels) as usize;

        s_pixels[pos] = red;
        s_pixels[pos + 1] = green;
        s_pixels[pos + 2] = blue;
        s_pixels[pos + 3] = alpha;
    }
}

impl_GObjectFunctions!(Pixbuf, C_GdkPixbuf);<|endoftext|>


<commit_before>#![cfg(feature = "s3")]

extern crate env_logger;
#[macro_use]
extern crate log;
extern crate time;

#[macro_use]
extern crate rusoto;

use std::io::Read;
use std::fs::File;
use std::env::var;
use rusoto::{DefaultCredentialsProvider, Region};
use rusoto::s3::{S3Helper, S3Client, ListObjectsRequest, HeadObjectRequest};

fn test_bucket() -> String {
    match var("S3_TEST_BUCKET") {
        Ok(val) => val.to_owned(),
        Err(_) => "rusototester".to_owned()
    }
}

fn test_bucket_region() -> Region {
    match var("S3_TEST_BUCKET_REGION") {
        Ok(val) => val.parse().unwrap(),
        Err(_) => "us-west-2".parse().unwrap()
    }
}

#[test]
fn list_buckets_tests() {
    let _ = env_logger::init();
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let response = s3.list_buckets().unwrap();
    info!("Got list of buckets: {:?}", response);
    for q in response.buckets {
        info!("Existing bucket: {:?}", q.name);
    }
}

#[test]
fn object_lifecycle_test() {
    // PUT an object
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let mut f = File::open("tests/sample-data/no_credentials").unwrap();
    let mut contents : Vec<u8> = Vec::new();
    match f.read_to_end(&mut contents) {
        Err(why) => panic!("Error opening file to send to S3: {}", why),
        Ok(_) => {
            s3.put_object(&test_bucket(), "no_credentials", &contents).unwrap();
        }
    }

    let client = S3Client::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    // HEAD the object that was PUT
    let size_req = HeadObjectRequest{
      bucket: test_bucket(),
      key: "no_credentials".to_string(),
      ..Default::default()
    };

    println!("{:?}", client.head_object(&size_req).unwrap());

    // GET the object
    s3.get_object(&test_bucket(), "no_credentials").unwrap();

    // DELETE the object
    s3.delete_object(&test_bucket(), "no_credentials").unwrap();
}

#[test]
fn put_and_fetch_timestamp_named_object_test() {
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let mut f = File::open("tests/sample-data/no_credentials").unwrap();
    let mut contents : Vec<u8> = Vec::new();
    match f.read_to_end(&mut contents) {
        Err(why) => panic!("Error opening file to send to S3: {}", why),
        Ok(_) => {
            s3.put_object(&test_bucket(), "2016-10-07T23:30:38Z", &contents).unwrap();
        }
    }
    let get_response = s3.get_object(&test_bucket(), "2016-10-07T23:30:38Z").unwrap();
    println!("Got object back: {:?}", get_response);
}

#[test]
fn list_objects_test() {
    let _ = env_logger::init();
    let bare_s3 = S3Client::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let mut list_request = ListObjectsRequest::default(); // need to set bucket
    list_request.bucket = test_bucket();
    let result = bare_s3.list_objects(&list_request).unwrap();
    println!("result is {:?}", result);
}

<commit_msg>Adds back bucket creation integration test.<commit_after>#![cfg(feature = "s3")]

extern crate env_logger;
#[macro_use]
extern crate log;
extern crate time;

#[macro_use]
extern crate rusoto;

use std::io::Read;
use std::fs::File;
use std::env::var;
use rusoto::{DefaultCredentialsProvider, Region};
use rusoto::s3::{S3Helper, S3Client, ListObjectsRequest, HeadObjectRequest, CreateBucketRequest};

fn test_bucket() -> String {
    match var("S3_TEST_BUCKET") {
        Ok(val) => val.to_owned(),
        Err(_) => "rusototester".to_owned()
    }
}

fn test_bucket_region() -> Region {
    match var("S3_TEST_BUCKET_REGION") {
        Ok(val) => val.parse().unwrap(),
        Err(_) => "us-west-2".parse().unwrap()
    }
}

#[test]
fn list_buckets_tests() {
    let _ = env_logger::init();
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let response = s3.list_buckets().unwrap();
    info!("Got list of buckets: {:?}", response);
    for q in response.buckets {
        info!("Existing bucket: {:?}", q.name);
    }
}

#[test]
fn object_lifecycle_test() {
    // PUT an object
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());

    let mut f = File::open("tests/sample-data/no_credentials").unwrap();
    let mut contents : Vec<u8> = Vec::new();
    match f.read_to_end(&mut contents) {
        Err(why) => panic!("Error opening file to send to S3: {}", why),
        Ok(_) => {
            s3.put_object(&test_bucket(), "no_credentials", &contents).unwrap();
        }
    }

    let client = S3Client::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    // HEAD the object that was PUT
    let size_req = HeadObjectRequest{
      bucket: test_bucket(),
      key: "no_credentials".to_string(),
      ..Default::default()
    };

    println!("{:?}", client.head_object(&size_req).unwrap());

    // GET the object
    s3.get_object(&test_bucket(), "no_credentials").unwrap();

    // DELETE the object
    s3.delete_object(&test_bucket(), "no_credentials").unwrap();
}

#[test]
fn create_bucket_in_useast1_and_use_immediately() {
    let s3 = S3Client::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let create_bucket_request = CreateBucketRequest{
        bucket: "rusoto_foo_bucket".to_string(),
        ..Default::default()
    };
    let bucket_creation_result = s3.create_bucket(&create_bucket_request).unwrap();
    println!("bucket created: {:?}", bucket_creation_result);

    let mut f = File::open("tests/sample-data/no_credentials").unwrap();
    let mut contents : Vec<u8> = Vec::new();
    match f.read_to_end(&mut contents) {
        Err(why) => panic!("Error opening file to send to S3: {}", why),
        Ok(_) => {
            let s3_helper = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
            let put_response = s3_helper.put_object("rusoto_foo_bucket", "no_credentials", &contents).unwrap();
            println!("put_response is {:?}", put_response);
        }
    }

}

#[test]
fn put_and_fetch_timestamp_named_object_test() {
    let s3 = S3Helper::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let mut f = File::open("tests/sample-data/no_credentials").unwrap();
    let mut contents : Vec<u8> = Vec::new();
    match f.read_to_end(&mut contents) {
        Err(why) => panic!("Error opening file to send to S3: {}", why),
        Ok(_) => {
            s3.put_object(&test_bucket(), "2016-10-07T23:30:38Z", &contents).unwrap();
        }
    }
    let get_response = s3.get_object(&test_bucket(), "2016-10-07T23:30:38Z").unwrap();
    println!("Got object back: {:?}", get_response);
}

#[test]
fn list_objects_test() {
    let _ = env_logger::init();
    let bare_s3 = S3Client::new(DefaultCredentialsProvider::new().unwrap(), test_bucket_region());
    let mut list_request = ListObjectsRequest::default(); // need to set bucket
    list_request.bucket = test_bucket();
    let result = bare_s3.list_objects(&list_request).unwrap();
    println!("result is {:?}", result);
}

<|endoftext|>


<commit_before><commit_msg>forgot to add main.rs back in<commit_after>#![feature(test)]
#![feature(scoped)]
#![allow(dead_code)]

extern crate test;
extern crate columnar;
extern crate byteorder;
extern crate docopt;

extern crate timely;

use docopt::Docopt;

use std::hash::Hash;
use std::fmt::Debug;
use std::thread;

use test::Bencher;

use columnar::Columnar;

use timely::progress::graph::Root;
use timely::progress::{Graph, Scope};
use timely::progress::timestamp::RootTimestamp;
use timely::progress::nested::builder::Builder as SubgraphBuilder;
use timely::progress::nested::Summary::Local;
use timely::progress::nested::Source::ScopeOutput;
use timely::progress::nested::Target::ScopeInput;

use timely::communication::{Data, ThreadCommunicator, ProcessCommunicator, Communicator};

use timely::example::*;
use timely::example::distinct::DistinctExtensionTrait;
use timely::example::barrier::BarrierScope;

use timely::networking::initialize_networking;

// mod progress;
// mod example;
// mod networking;
// mod communication;

static USAGE: &'static str = "
Usage: timely distinct [options] [<arguments>...]
       timely barrier [options] [<arguments>...]
       timely command [options] [<arguments>...]

Options:
    -w <arg>, --workers <arg>    number of workers per process [default: 1]
    -p <arg>, --processid <arg>  identity of this process      [default: 0]
    -n <arg>, --processes <arg>  number of processes involved  [default: 1]
";

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

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

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

    // vector holding communicators to use; one per local worker.
    if processes > 1 {
        println!("Initializing BinaryCommunicator");
        let addresses = (0..processes).map(|index| format!("localhost:{}", 2101 + index).to_string()).collect();
        let communicators = initialize_networking(addresses, process_id, workers).ok().expect("error initializing networking");
        if args.get_bool("distinct") { _distinct_multi(communicators); }
        else if args.get_bool("barrier") { _barrier_multi(communicators); }
        else if args.get_bool("command") { _command_multi(communicators); }
    }
    else if workers > 1 {
        println!("Initializing ProcessCommunicator");
        let communicators = ProcessCommunicator::new_vector(workers);
        if args.get_bool("distinct") { _distinct_multi(communicators); }
        else if args.get_bool("barrier") { _barrier_multi(communicators); }
        else if args.get_bool("command") { _command_multi(communicators); }
    }
    else {
        println!("Initializing ThreadCommunicator");
        let communicators = vec![ThreadCommunicator];
        if args.get_bool("distinct") { _distinct_multi(communicators); }
        else if args.get_bool("barrier") { _barrier_multi(communicators); }
        else if args.get_bool("command") { _command_multi(communicators); }
    };
}

#[bench]
fn distinct_bench(bencher: &mut Bencher) { _distinct(ProcessCommunicator::new_vector(1).swap_remove(0), Some(bencher)); }
fn _distinct_multi<C: Communicator+Send>(communicators: Vec<C>) {
    let mut guards = Vec::new();
    for communicator in communicators.into_iter() {
        guards.push(thread::Builder::new().name(format!("worker thread {}", communicator.index()))
                                          .scoped(move || _distinct(communicator, None))
                                          .unwrap());
    }
}

// #[bench]
// fn command_bench(bencher: &mut Bencher) { _command(ProcessCommunicator::new_vector(1).swap_remove(0).unwrap(), Some(bencher)); }
fn _command_multi<C: Communicator+Send>(_communicators: Vec<C>) {
    println!("command currently disabled awaiting io reform");
    // let mut guards = Vec::new();
    // for communicator in communicators.into_iter() {
    //     guards.push(thread::scoped(move || _command(communicator, None)));
    // }
}

#[bench]
fn barrier_bench(bencher: &mut Bencher) { _barrier(ProcessCommunicator::new_vector(1).swap_remove(0), Some(bencher)); }
fn _barrier_multi<C: Communicator+Send>(communicators: Vec<C>) {
    let mut guards = Vec::new();
    for communicator in communicators.into_iter() {
        guards.push(thread::scoped(move || _barrier(communicator, None)));
    }
}

fn _create_subgraph<'a, G, D>(source1: &mut Stream<'a, G, D>, source2: &mut Stream<'a, G, D>) ->
    (Stream<'a, G, D>, Stream<'a, G, D>)
where G: Graph+'a, D: Data+Hash+Eq+Debug+Columnar {

    let mut subgraph = SubgraphBuilder::<_, u64>::new(source1.graph);
    let result = {
        let subgraph_builder = subgraph.builder();

        (
            source1.enter(&subgraph_builder).distinct().leave(),
            source2.enter(&subgraph_builder).leave()
        )
    };
    subgraph.seal();

    result
}

fn _distinct<C: Communicator>(communicator: C, bencher: Option<&mut Bencher>) {

    let mut root = Root::new(communicator);

    let (mut input1, mut input2) = {
        let borrow = root.builder();
        let mut graph = SubgraphBuilder::new(&borrow);
        let (input1, input2) = {
            let builder = graph.builder();

            // try building some input scopes
            let (input1, mut stream1) = builder.new_input::<u64>();
            let (input2, mut stream2) = builder.new_input::<u64>();

            // prepare some feedback edges
            let (mut feedback1, mut feedback1_output) = builder.feedback(RootTimestamp::new(1000000), Local(1));
            let (mut feedback2, mut feedback2_output) = builder.feedback(RootTimestamp::new(1000000), Local(1));

            // build up a subgraph using the concatenated inputs/feedbacks
            let (mut egress1, mut egress2) = _create_subgraph(&mut stream1.concat(&mut feedback1_output),
                                                              &mut stream2.concat(&mut feedback2_output));

            // connect feedback sources. notice that we have swapped indices ...
            feedback1.connect_input(&mut egress2);
            feedback2.connect_input(&mut egress1);

            (input1, input2)
        };
        graph.seal();

        (input1, input2)
    };

    root.step();

    // move some data into the dataflow graph.
    input1.send_messages(&RootTimestamp::new(0), vec![1u64]);
    input2.send_messages(&RootTimestamp::new(0), vec![2u64]);

    // see what everyone thinks about that ...
    root.step();

    input1.advance(&RootTimestamp::new(0), &RootTimestamp::new(1000000));
    input2.advance(&RootTimestamp::new(0), &RootTimestamp::new(1000000));
    input1.close_at(&RootTimestamp::new(1000000));
    input2.close_at(&RootTimestamp::new(1000000));

    // spin
    match bencher {
        Some(b) => b.iter(|| { root.step(); }),
        None    => while root.step() { }
    }
}

// fn _command<C: Communicator>(communicator: C, bencher: Option<&mut Bencher>) {
//     let communicator = Rc::new(RefCell::new(communicator));
//
//     // no "base scopes" yet, so the root pretends to be a subscope of some parent with a () timestamp type.
//     let mut graph = new_graph(Progcaster::new(&mut (*communicator.borrow_mut())));
//     let mut input = graph.new_input::<u64>(communicator);
//     let mut feedback = input.1.feedback(((), 1000), Local(1));
//     let mut result: Stream<_, u64, _> = input.1.concat(&mut feedback.1)
//                                                .command("./target/release/command".to_string());
//
//     feedback.0.connect_input(&mut result);
//
//     // start things up!
//     graph.borrow_mut().get_internal_summary();
//     graph.borrow_mut().set_external_summary(Vec::new(), &mut []);
//     graph.borrow_mut().push_external_progress(&mut []);
//
//     input.0.close_at(&((), 0));
//
//     // spin
//     match bencher {
//         Some(b) => b.iter(|| { graph.borrow_mut().pull_internal_progress(&mut [], &mut [], &mut []); }),
//         None    => while graph.borrow_mut().pull_internal_progress(&mut [], &mut [], &mut []) { },
//     }
// }

fn _barrier<C: Communicator>(communicator: C, bencher: Option<&mut Bencher>) {

    let mut root = Root::new(communicator);

    {
        let borrow = root.builder();
        let mut graph = SubgraphBuilder::new(&borrow);

        let peers = graph.with_communicator(|x| x.peers());
        {
            let builder = &graph.builder();

            builder.borrow_mut().add_scope(BarrierScope { epoch: 0, ready: true, degree: peers, ttl: 1000000 });
            builder.borrow_mut().connect(ScopeOutput(0, 0), ScopeInput(0, 0));
        }

        graph.seal();
    }

    // spin
    match bencher {
        Some(b) => b.iter(|| { root.step(); }),
        None    => while root.step() { },
    }
}
<|endoftext|>


<commit_before><commit_msg>Simple version of DwemthysArray<commit_after>struct Monster {
  health: int,
  attack: int
}

impl Monster {
  fn attack(&self) {
    println(fmt!("The monster attacks for %d damage.", self.attack));
  }

  fn count() {
    println("There are a bunch of monsters out tonight.");
  }

  fn new(health: int, attack: int) -> Monster {
    Monster { health:health, attack:attack }
  }
}

fn main() {
  Monster::new(20, 40).attack();
}
<|endoftext|>


<commit_before><commit_msg>Rename event_type when deserializing custom events<commit_after><|endoftext|>


<commit_before>/*
 * A SHA-1 implementation derived from Paul E. Jones's reference
 * implementation, which is written for clarity, not speed. At some
 * point this will want to be rewritten.
 */

export sha1;
export mk_sha1;

state type sha1 = state obj {
                        // Provide message input as bytes
                        fn input(&vec[u8]);

                        // Provide message input as string
                        fn input_str(&str);

                        // Read the digest as a vector of 20 bytes. After
                        // calling this no further input may provided
                        // until reset is called
                        fn result() -> vec[u8];

                        // Same as above, just a hex-string version.
                        fn result_str() -> str;

                        // Reset the sha1 state for reuse. This is called
                        // automatically during construction
                        fn reset();
};

// Some unexported constants
const uint digest_buf_len = 5;
const uint msg_block_len = 64;
const uint work_buf_len = 80;

const u32 k0 = 0x5A827999u32;
const u32 k1 = 0x6ED9EBA1u32;
const u32 k2 = 0x8F1BBCDCu32;
const u32 k3 = 0xCA62C1D6u32;

// Builds a sha1 object
fn mk_sha1() -> sha1 {

    state type sha1state = rec(vec[mutable u32] h,
                               mutable u32 len_low,
                               mutable u32 len_high,
                               vec[mutable u8] msg_block,
                               mutable uint msg_block_idx,
                               mutable bool computed,
                               vec[mutable u32] work_buf);

    fn add_input(&sha1state st, &vec[u8] msg) {
        // FIXME: Should be typestate precondition
        assert (!st.computed);

        for (u8 element in msg) {
            st.msg_block.(st.msg_block_idx) = element;
            st.msg_block_idx += 1u;

            st.len_low += 8u32;
            if (st.len_low == 0u32) {
                st.len_high += 1u32;
                if (st.len_high == 0u32) {
                    // FIXME: Need better failure mode
                    fail;
                }
            }

            if (st.msg_block_idx == msg_block_len) {
                process_msg_block(st);
            }
        }
    }

    fn process_msg_block(&sha1state st) {

        // FIXME: Make precondition
        assert (vec::len(st.h) == digest_buf_len);
        assert (vec::len(st.work_buf) == work_buf_len);

        let int t; // Loop counter
        auto w = st.work_buf;

        // Initialize the first 16 words of the vector w
        t = 0;
        while (t < 16) {
            auto tmp;
            tmp = (st.msg_block.(t * 4) as u32) << 24u32;
            tmp = tmp | ((st.msg_block.(t * 4 + 1) as u32) << 16u32);
            tmp = tmp | ((st.msg_block.(t * 4 + 2) as u32) << 8u32);
            tmp = tmp | (st.msg_block.(t * 4 + 3) as u32);
            w.(t) = tmp;
            t += 1;
        }

        // Initialize the rest of vector w
        while (t < 80) {
            auto val = w.(t-3) ^ w.(t-8) ^ w.(t-14) ^ w.(t-16);
            w.(t) = circular_shift(1u32, val);
            t += 1;
        }

        auto a = st.h.(0);
        auto b = st.h.(1);
        auto c = st.h.(2);
        auto d = st.h.(3);
        auto e = st.h.(4);

        let u32 temp;

        t = 0;
        while (t < 20) {
            temp = circular_shift(5u32, a)
                + ((b & c) | ((~b) & d)) + e + w.(t) + k0;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 40) {
            temp = circular_shift(5u32, a)
                + (b ^ c ^ d) + e + w.(t) + k1;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 60) {
            temp = circular_shift(5u32, a)
                + ((b & c) | (b & d) | (c & d)) + e + w.(t) + k2;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 80) {
            temp = circular_shift(5u32, a)
                + (b ^ c ^ d) + e + w.(t) + k3;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        st.h.(0) = st.h.(0) + a;
        st.h.(1) = st.h.(1) + b;
        st.h.(2) = st.h.(2) + c;
        st.h.(3) = st.h.(3) + d;
        st.h.(4) = st.h.(4) + e;

        st.msg_block_idx = 0u;
    }

    fn circular_shift(u32 bits, u32 word) -> u32 {
        // FIXME: This is a workaround for a rustboot
        // "unrecognized quads" codegen bug
        auto bits_hack = bits;
        ret (word << bits_hack) | (word >> (32u32 - bits));
    }

    fn mk_result(&sha1state st) -> vec[u8] {
        if (!st.computed) {
            pad_msg(st);
            st.computed = true;
        }

        let vec[u8] res = [];
        for (u32 hpart in st.h) {
            auto a = (hpart >> 24u32) & 0xFFu32 as u8;
            auto b = (hpart >> 16u32) & 0xFFu32 as u8;
            auto c = (hpart >> 8u32) & 0xFFu32 as u8;
            auto d = (hpart & 0xFFu32 as u8);
            res += [a,b,c,d];
        }
        ret res;
    }

    /*
     * According to the standard, the message must be padded to an even
     * 512 bits.  The first padding bit must be a '1'.  The last 64 bits
     * represent the length of the original message.  All bits in between
     * should be 0.  This function will pad the message according to those
     * rules by filling the msg_block vector accordingly.  It will also
     * call process_msg_block() appropriately.  When it returns, it
     * can be assumed that the message digest has been computed.
     */
    fn pad_msg(&sha1state st) {
        // FIXME: Should be a precondition
        assert (vec::len(st.msg_block) == msg_block_len);

        /*
         * Check to see if the current message block is too small to hold
         * the initial padding bits and length.  If so, we will pad the
         * block, process it, and then continue padding into a second block.
         */
        if (st.msg_block_idx > 55u) {
            st.msg_block.(st.msg_block_idx) = 0x80u8;
            st.msg_block_idx += 1u;

            while (st.msg_block_idx < msg_block_len) {
                st.msg_block.(st.msg_block_idx) = 0u8;
                st.msg_block_idx += 1u;
            }

            process_msg_block(st);
        } else {
            st.msg_block.(st.msg_block_idx) = 0x80u8;
            st.msg_block_idx += 1u;
        }

        while (st.msg_block_idx < 56u) {
            st.msg_block.(st.msg_block_idx) = 0u8;
            st.msg_block_idx += 1u;
        }

        // Store the message length as the last 8 octets
        st.msg_block.(56) = (st.len_high >> 24u32) & 0xFFu32 as u8;
        st.msg_block.(57) = (st.len_high >> 16u32) & 0xFFu32 as u8;
        st.msg_block.(58) = (st.len_high >> 8u32) & 0xFFu32 as u8;
        st.msg_block.(59) = st.len_high & 0xFFu32 as u8;
        st.msg_block.(60) = (st.len_low >> 24u32) & 0xFFu32 as u8;
        st.msg_block.(61) = (st.len_low >> 16u32) & 0xFFu32 as u8;
        st.msg_block.(62) = (st.len_low >> 8u32) & 0xFFu32 as u8;
        st.msg_block.(63) = st.len_low & 0xFFu32 as u8;

        process_msg_block(st);
    }

    state obj sha1(sha1state st) {

        fn reset() {
            // FIXME: Should be typestate precondition
            assert (vec::len(st.h) == digest_buf_len);

            st.len_low = 0u32;
            st.len_high = 0u32;
            st.msg_block_idx = 0u;

            st.h.(0) = 0x67452301u32;
            st.h.(1) = 0xEFCDAB89u32;
            st.h.(2) = 0x98BADCFEu32;
            st.h.(3) = 0x10325476u32;
            st.h.(4) = 0xC3D2E1F0u32;

            st.computed = false;
        }

        fn input(&vec[u8] msg) {
            add_input(st, msg);
        }

        fn input_str(&str msg) {
            add_input(st, str::bytes(msg));
        }

        fn result() -> vec[u8] {
            ret mk_result(st);
        }

        fn result_str() -> str {
            auto r = mk_result(st);
            auto s = "";
            for (u8 b in r) {
                s += uint::to_str(b as uint, 16u);
            }
            ret s;
        }
    }

    auto st = rec(h = vec::init_elt_mut[u32](0u32, digest_buf_len),
                  mutable len_low = 0u32,
                  mutable len_high = 0u32,
                  msg_block = vec::init_elt_mut[u8](0u8, msg_block_len),
                  mutable msg_block_idx = 0u,
                  mutable computed = false,
                  work_buf = vec::init_elt_mut[u32](0u32, work_buf_len));
    auto sh = sha1(st);
    sh.reset();
    ret sh;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>rustc: Fix type mismatch in lib/sha1.rs constants<commit_after>/*
 * A SHA-1 implementation derived from Paul E. Jones's reference
 * implementation, which is written for clarity, not speed. At some
 * point this will want to be rewritten.
 */

export sha1;
export mk_sha1;

state type sha1 = state obj {
                        // Provide message input as bytes
                        fn input(&vec[u8]);

                        // Provide message input as string
                        fn input_str(&str);

                        // Read the digest as a vector of 20 bytes. After
                        // calling this no further input may provided
                        // until reset is called
                        fn result() -> vec[u8];

                        // Same as above, just a hex-string version.
                        fn result_str() -> str;

                        // Reset the sha1 state for reuse. This is called
                        // automatically during construction
                        fn reset();
};

// Some unexported constants
const uint digest_buf_len = 5u;
const uint msg_block_len = 64u;
const uint work_buf_len = 80u;

const u32 k0 = 0x5A827999u32;
const u32 k1 = 0x6ED9EBA1u32;
const u32 k2 = 0x8F1BBCDCu32;
const u32 k3 = 0xCA62C1D6u32;

// Builds a sha1 object
fn mk_sha1() -> sha1 {

    state type sha1state = rec(vec[mutable u32] h,
                               mutable u32 len_low,
                               mutable u32 len_high,
                               vec[mutable u8] msg_block,
                               mutable uint msg_block_idx,
                               mutable bool computed,
                               vec[mutable u32] work_buf);

    fn add_input(&sha1state st, &vec[u8] msg) {
        // FIXME: Should be typestate precondition
        assert (!st.computed);

        for (u8 element in msg) {
            st.msg_block.(st.msg_block_idx) = element;
            st.msg_block_idx += 1u;

            st.len_low += 8u32;
            if (st.len_low == 0u32) {
                st.len_high += 1u32;
                if (st.len_high == 0u32) {
                    // FIXME: Need better failure mode
                    fail;
                }
            }

            if (st.msg_block_idx == msg_block_len) {
                process_msg_block(st);
            }
        }
    }

    fn process_msg_block(&sha1state st) {

        // FIXME: Make precondition
        assert (vec::len(st.h) == digest_buf_len);
        assert (vec::len(st.work_buf) == work_buf_len);

        let int t; // Loop counter
        auto w = st.work_buf;

        // Initialize the first 16 words of the vector w
        t = 0;
        while (t < 16) {
            auto tmp;
            tmp = (st.msg_block.(t * 4) as u32) << 24u32;
            tmp = tmp | ((st.msg_block.(t * 4 + 1) as u32) << 16u32);
            tmp = tmp | ((st.msg_block.(t * 4 + 2) as u32) << 8u32);
            tmp = tmp | (st.msg_block.(t * 4 + 3) as u32);
            w.(t) = tmp;
            t += 1;
        }

        // Initialize the rest of vector w
        while (t < 80) {
            auto val = w.(t-3) ^ w.(t-8) ^ w.(t-14) ^ w.(t-16);
            w.(t) = circular_shift(1u32, val);
            t += 1;
        }

        auto a = st.h.(0);
        auto b = st.h.(1);
        auto c = st.h.(2);
        auto d = st.h.(3);
        auto e = st.h.(4);

        let u32 temp;

        t = 0;
        while (t < 20) {
            temp = circular_shift(5u32, a)
                + ((b & c) | ((~b) & d)) + e + w.(t) + k0;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 40) {
            temp = circular_shift(5u32, a)
                + (b ^ c ^ d) + e + w.(t) + k1;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 60) {
            temp = circular_shift(5u32, a)
                + ((b & c) | (b & d) | (c & d)) + e + w.(t) + k2;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        while (t < 80) {
            temp = circular_shift(5u32, a)
                + (b ^ c ^ d) + e + w.(t) + k3;
            e = d;
            d = c;
            c = circular_shift(30u32, b);
            b = a;
            a = temp;
            t += 1;
        }

        st.h.(0) = st.h.(0) + a;
        st.h.(1) = st.h.(1) + b;
        st.h.(2) = st.h.(2) + c;
        st.h.(3) = st.h.(3) + d;
        st.h.(4) = st.h.(4) + e;

        st.msg_block_idx = 0u;
    }

    fn circular_shift(u32 bits, u32 word) -> u32 {
        // FIXME: This is a workaround for a rustboot
        // "unrecognized quads" codegen bug
        auto bits_hack = bits;
        ret (word << bits_hack) | (word >> (32u32 - bits));
    }

    fn mk_result(&sha1state st) -> vec[u8] {
        if (!st.computed) {
            pad_msg(st);
            st.computed = true;
        }

        let vec[u8] res = [];
        for (u32 hpart in st.h) {
            auto a = (hpart >> 24u32) & 0xFFu32 as u8;
            auto b = (hpart >> 16u32) & 0xFFu32 as u8;
            auto c = (hpart >> 8u32) & 0xFFu32 as u8;
            auto d = (hpart & 0xFFu32 as u8);
            res += [a,b,c,d];
        }
        ret res;
    }

    /*
     * According to the standard, the message must be padded to an even
     * 512 bits.  The first padding bit must be a '1'.  The last 64 bits
     * represent the length of the original message.  All bits in between
     * should be 0.  This function will pad the message according to those
     * rules by filling the msg_block vector accordingly.  It will also
     * call process_msg_block() appropriately.  When it returns, it
     * can be assumed that the message digest has been computed.
     */
    fn pad_msg(&sha1state st) {
        // FIXME: Should be a precondition
        assert (vec::len(st.msg_block) == msg_block_len);

        /*
         * Check to see if the current message block is too small to hold
         * the initial padding bits and length.  If so, we will pad the
         * block, process it, and then continue padding into a second block.
         */
        if (st.msg_block_idx > 55u) {
            st.msg_block.(st.msg_block_idx) = 0x80u8;
            st.msg_block_idx += 1u;

            while (st.msg_block_idx < msg_block_len) {
                st.msg_block.(st.msg_block_idx) = 0u8;
                st.msg_block_idx += 1u;
            }

            process_msg_block(st);
        } else {
            st.msg_block.(st.msg_block_idx) = 0x80u8;
            st.msg_block_idx += 1u;
        }

        while (st.msg_block_idx < 56u) {
            st.msg_block.(st.msg_block_idx) = 0u8;
            st.msg_block_idx += 1u;
        }

        // Store the message length as the last 8 octets
        st.msg_block.(56) = (st.len_high >> 24u32) & 0xFFu32 as u8;
        st.msg_block.(57) = (st.len_high >> 16u32) & 0xFFu32 as u8;
        st.msg_block.(58) = (st.len_high >> 8u32) & 0xFFu32 as u8;
        st.msg_block.(59) = st.len_high & 0xFFu32 as u8;
        st.msg_block.(60) = (st.len_low >> 24u32) & 0xFFu32 as u8;
        st.msg_block.(61) = (st.len_low >> 16u32) & 0xFFu32 as u8;
        st.msg_block.(62) = (st.len_low >> 8u32) & 0xFFu32 as u8;
        st.msg_block.(63) = st.len_low & 0xFFu32 as u8;

        process_msg_block(st);
    }

    state obj sha1(sha1state st) {

        fn reset() {
            // FIXME: Should be typestate precondition
            assert (vec::len(st.h) == digest_buf_len);

            st.len_low = 0u32;
            st.len_high = 0u32;
            st.msg_block_idx = 0u;

            st.h.(0) = 0x67452301u32;
            st.h.(1) = 0xEFCDAB89u32;
            st.h.(2) = 0x98BADCFEu32;
            st.h.(3) = 0x10325476u32;
            st.h.(4) = 0xC3D2E1F0u32;

            st.computed = false;
        }

        fn input(&vec[u8] msg) {
            add_input(st, msg);
        }

        fn input_str(&str msg) {
            add_input(st, str::bytes(msg));
        }

        fn result() -> vec[u8] {
            ret mk_result(st);
        }

        fn result_str() -> str {
            auto r = mk_result(st);
            auto s = "";
            for (u8 b in r) {
                s += uint::to_str(b as uint, 16u);
            }
            ret s;
        }
    }

    auto st = rec(h = vec::init_elt_mut[u32](0u32, digest_buf_len),
                  mutable len_low = 0u32,
                  mutable len_high = 0u32,
                  msg_block = vec::init_elt_mut[u8](0u8, msg_block_len),
                  mutable msg_block_idx = 0u,
                  mutable computed = false,
                  work_buf = vec::init_elt_mut[u32](0u32, work_buf_len));
    auto sh = sha1(st);
    sh.reset();
    ret sh;
}

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


<commit_before>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

import sort = sort::ivector;
import generic_os::getenv;

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_tests_console;
export run_tests_console_;
export run_test;
export filter_tests;
export parse_opts;
export test_to_task;
export default_test_to_task;
export configure_test_task;

native "rust" mod rustrt {
    fn hack_allow_leaks();
    fn sched_threads() -> uint;
}

// The name of a test. By convention this follows the rules for rust
// paths, i.e it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// heirarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn() ;

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = {name: test_name, fn: test_fn, ignore: bool};

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(args: &vec[str], tests: &test_desc[]) {
    let ivec_args =
        { let iargs = ~[]; for arg: str  in args { iargs += ~[arg] } iargs };
    check (ivec::is_not_empty(ivec_args));
    let opts =
        alt parse_opts(ivec_args) {
          either::left(o) { o }
          either::right(m) { fail m }
        };
    if !run_tests_console(opts, tests) { fail "Some tests failed"; }
}

type test_opts = {filter: option::t[str], run_ignored: bool};

type opt_res = either::t[test_opts, str];

// Parses command line arguments into test options
fn parse_opts(args: &str[]) : ivec::is_not_empty(args) -> opt_res {

    // FIXME (#649): Shouldn't have to check here
    check (ivec::is_not_empty(args));
    let args_ = ivec::tail(args);
    let opts = ~[getopts::optflag("ignored")];
    let match =
        alt getopts::getopts_ivec(args_, opts) {
          getopts::success(m) { m }
          getopts::failure(f) { ret either::right(getopts::fail_str(f)) }
        };

    let filter =
        if vec::len(match.free) > 0u {
            option::some(match.free.(0))
        } else { option::none };

    let run_ignored = getopts::opt_present(match, "ignored");

    let test_opts = {filter: filter, run_ignored: run_ignored};

    ret either::left(test_opts);
}

tag test_result { tr_ok; tr_failed; tr_ignored; }

// To get isolation and concurrency tests have to be run in their own tasks.
// In cases where test functions and closures it is not ok to just dump them
// into a task and run them, so this transformation gives the caller a chance
// to create the test task.
type test_to_task = fn(&fn()) -> task ;

// A simple console test runner
fn run_tests_console(opts: &test_opts, tests: &test_desc[]) -> bool {
    run_tests_console_(opts, tests, default_test_to_task)
}

fn run_tests_console_(opts: &test_opts, tests: &test_desc[],
                      to_task: &test_to_task) -> bool {

    type test_state = @{
        out: io::writer,
        use_color: bool,
        mutable total: uint,
        mutable passed: uint,
        mutable failed: uint,
        mutable ignored: uint,
        mutable failures: test_desc[]
    };

    fn callback(event: testevent, st: test_state) {
        alt event {
          te_filtered(filtered_tests) {
            st.total = ivec::len(filtered_tests);
            st.out.write_line(#fmt("\nrunning %u tests", st.total));
          }
          te_result(test, result) {
            st.out.write_str(#fmt("test %s ... ", test.name));
            alt result {
              tr_ok. {
                st.passed += 1u;
                write_ok(st.out, st.use_color);
                st.out.write_line("");
              }
              tr_failed. {
                st.failed += 1u;
                write_failed(st.out, st.use_color);
                st.out.write_line("");
                st.failures += ~[test];
              }
              tr_ignored. {
                st.ignored += 1u;
                write_ignored(st.out, st.use_color);
                st.out.write_line("");
              }
            }
          }
        }
    }

    let st = @{
        out: io::stdout(),
        use_color: use_color(),
        mutable total: 0u,
        mutable passed: 0u,
        mutable failed: 0u,
        mutable ignored: 0u,
        mutable failures: ~[]
    };

    run_tests(opts, tests, to_task,
              bind callback(_, st));

    assert st.passed + st.failed + st.ignored == st.total;
    let success = st.failed == 0u;

    if !success {
        st.out.write_line("\nfailures:");
        for test: test_desc in st.failures {
            let testname = test.name; // Satisfy alias analysis
            st.out.write_line(#fmt("    %s", testname));
        }
    }

    st.out.write_str(#fmt("\nresult: "));
    if success {
        // There's no parallelism at this point so it's safe to use color
        write_ok(st.out, true);
    } else { write_failed(st.out, true); }
    st.out.write_str(#fmt(". %u passed; %u failed; %u ignored\n\n",
                       st.passed, st.failed, st.ignored));

    ret success;

    fn write_ok(out: &io::writer, use_color: bool) {
        write_pretty(out, "ok", term::color_green, use_color);
    }

    fn write_failed(out: &io::writer, use_color: bool) {
        write_pretty(out, "FAILED", term::color_red, use_color);
    }

    fn write_ignored(out: &io::writer, use_color: bool) {
        write_pretty(out, "ignored", term::color_yellow, use_color);
    }

    fn write_pretty(out: &io::writer, word: &str, color: u8,
                    use_color: bool) {
        if use_color && term::color_supported() {
            term::fg(out.get_buf_writer(), color);
        }
        out.write_str(word);
        if use_color && term::color_supported() {
            term::reset(out.get_buf_writer());
        }
    }
}

fn use_color() -> bool {
    ret get_concurrency() == 1u;
}

tag testevent {
    te_filtered(test_desc[]);
    te_result(test_desc, test_result);
}

fn run_tests(opts: &test_opts, tests: &test_desc[],
             to_task: &test_to_task, callback: fn(testevent)) {

    let filtered_tests = filter_tests(opts, tests);

    callback(te_filtered(filtered_tests));

    // It's tempting to just spawn all the tests at once but that doesn't
    // provide a great user experience because you might sit waiting for the
    // result of a particular test for an unusually long amount of time.
    let concurrency = get_concurrency();
    log #fmt("using %u test tasks", concurrency);
    let total = ivec::len(filtered_tests);
    let run_idx = 0u;
    let wait_idx = 0u;
    let futures = ~[];

    while wait_idx < total {
        while ivec::len(futures) < concurrency && run_idx < total {
            futures += ~[run_test(filtered_tests.(run_idx), to_task)];
            run_idx += 1u;
        }

        let future = futures.(0);
        let result = future.wait();
        callback(te_result(future.test, result));
        futures = ivec::slice(futures, 1u, ivec::len(futures));
        wait_idx += 1u;
    }
}

fn get_concurrency() -> uint { rustrt::sched_threads() }

fn filter_tests(opts: &test_opts, tests: &test_desc[]) -> test_desc[] {
    let filtered = tests;

    // Remove tests that don't match the test filter
    filtered =
        if option::is_none(opts.filter) {
            filtered
        } else {
            let filter_str =
                alt opts.filter {
                  option::some(f) { f }
                  option::none. { "" }
                };

            let filter =
                bind fn (test: &test_desc, filter_str: str) ->
                        option::t[test_desc] {
                         if str::find(test.name, filter_str) >= 0 {
                             ret option::some(test);
                         } else { ret option::none; }
                     }(_, filter_str);

            ivec::filter_map(filter, filtered)
        };

    // Maybe pull out the ignored test and unignore them
    filtered =
        if !opts.run_ignored {
            filtered
        } else {
            let filter =
                fn (test: &test_desc) -> option::t[test_desc] {
                    if test.ignore {
                        ret option::some({name: test.name,
                                          fn: test.fn,
                                          ignore: false});
                    } else { ret option::none; }
                };

            ivec::filter_map(filter, filtered)
        };

    // Sort the tests alphabetically
    filtered =
        {
            fn lteq(t1: &test_desc, t2: &test_desc) -> bool {
                str::lteq(t1.name, t2.name)
            }
            sort::merge_sort(lteq, filtered)
        };

    ret filtered;
}

type test_future =
    {test: test_desc, fnref: @fn() , wait: fn() -> test_result };

fn run_test(test: &test_desc, to_task: &test_to_task) -> test_future {
    // FIXME: Because of the unsafe way we're passing the test function
    // to the test task, we need to make sure we keep a reference to that
    // function around for longer than the lifetime of the task. To that end
    // we keep the function boxed in the test future.
    let fnref = @test.fn;
    if !test.ignore {
        let test_task = to_task(*fnref);
        ret {test: test,
             fnref: fnref,
             wait:
                 bind fn (test_task: &task) -> test_result {
                          alt task::join(test_task) {
                            task::tr_success. { tr_ok }
                            task::tr_failure. { tr_failed }
                          }
                      }(test_task)};
    } else {
        ret {test: test,
             fnref: fnref,
             wait: fn () -> test_result { tr_ignored }};
    }
}

// We need to run our tests in another task in order to trap test failures.
// But, at least currently, functions can't be used as spawn arguments so
// we've got to treat our test functions as unsafe pointers.  This function
// only works with functions that don't contain closures.
fn default_test_to_task(f: &fn()) -> task {
    fn run_task(fptr: *mutable fn() ) {
        configure_test_task();
        // Run the test
        (*fptr)()
    }
    let fptr = ptr::addr_of(f);
    ret spawn run_task(fptr);
}

// Call from within a test task to make sure it's set up correctly
fn configure_test_task() {
    // If this task fails we don't want that failure to propagate to the
    // test runner or else we couldn't keep running tests
    task::unsupervise();

    // FIXME (236): Hack supreme - unwinding doesn't work yet so if this
    // task fails memory will not be freed correctly. This turns off the
    // sanity checks in the runtime's memory region for the task, so that
    // the test runner can continue.
    rustrt::hack_allow_leaks();
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Display the name of the test being waited for before the result is in<commit_after>// Support code for rustc's built in test runner generator. Currently,
// none of this is meant for users. It is intended to support the
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.

import sort = sort::ivector;
import generic_os::getenv;

export test_name;
export test_fn;
export test_desc;
export test_main;
export test_result;
export test_opts;
export tr_ok;
export tr_failed;
export tr_ignored;
export run_tests_console;
export run_tests_console_;
export run_test;
export filter_tests;
export parse_opts;
export test_to_task;
export default_test_to_task;
export configure_test_task;

native "rust" mod rustrt {
    fn hack_allow_leaks();
    fn sched_threads() -> uint;
}

// The name of a test. By convention this follows the rules for rust
// paths, i.e it should be a series of identifiers seperated by double
// colons. This way if some test runner wants to arrange the tests
// heirarchically it may.
type test_name = str;

// A function that runs a test. If the function returns successfully,
// the test succeeds; if the function fails then the test fails. We
// may need to come up with a more clever definition of test in order
// to support isolation of tests into tasks.
type test_fn = fn() ;

// The definition of a single test. A test runner will run a list of
// these.
type test_desc = {name: test_name, fn: test_fn, ignore: bool};

// The default console test runner. It accepts the command line
// arguments and a vector of test_descs (generated at compile time).
fn test_main(args: &vec[str], tests: &test_desc[]) {
    let ivec_args =
        { let iargs = ~[]; for arg: str  in args { iargs += ~[arg] } iargs };
    check (ivec::is_not_empty(ivec_args));
    let opts =
        alt parse_opts(ivec_args) {
          either::left(o) { o }
          either::right(m) { fail m }
        };
    if !run_tests_console(opts, tests) { fail "Some tests failed"; }
}

type test_opts = {filter: option::t[str], run_ignored: bool};

type opt_res = either::t[test_opts, str];

// Parses command line arguments into test options
fn parse_opts(args: &str[]) : ivec::is_not_empty(args) -> opt_res {

    // FIXME (#649): Shouldn't have to check here
    check (ivec::is_not_empty(args));
    let args_ = ivec::tail(args);
    let opts = ~[getopts::optflag("ignored")];
    let match =
        alt getopts::getopts_ivec(args_, opts) {
          getopts::success(m) { m }
          getopts::failure(f) { ret either::right(getopts::fail_str(f)) }
        };

    let filter =
        if vec::len(match.free) > 0u {
            option::some(match.free.(0))
        } else { option::none };

    let run_ignored = getopts::opt_present(match, "ignored");

    let test_opts = {filter: filter, run_ignored: run_ignored};

    ret either::left(test_opts);
}

tag test_result { tr_ok; tr_failed; tr_ignored; }

// To get isolation and concurrency tests have to be run in their own tasks.
// In cases where test functions and closures it is not ok to just dump them
// into a task and run them, so this transformation gives the caller a chance
// to create the test task.
type test_to_task = fn(&fn()) -> task ;

// A simple console test runner
fn run_tests_console(opts: &test_opts, tests: &test_desc[]) -> bool {
    run_tests_console_(opts, tests, default_test_to_task)
}

fn run_tests_console_(opts: &test_opts, tests: &test_desc[],
                      to_task: &test_to_task) -> bool {

    type test_state = @{
        out: io::writer,
        use_color: bool,
        mutable total: uint,
        mutable passed: uint,
        mutable failed: uint,
        mutable ignored: uint,
        mutable failures: test_desc[]
    };

    fn callback(event: testevent, st: test_state) {
        alt event {
          te_filtered(filtered_tests) {
            st.total = ivec::len(filtered_tests);
            st.out.write_line(#fmt("\nrunning %u tests", st.total));
          }
          te_wait(test) {
            st.out.write_str(#fmt("test %s ... ", test.name));
          }
          te_result(test, result) {
            alt result {
              tr_ok. {
                st.passed += 1u;
                write_ok(st.out, st.use_color);
                st.out.write_line("");
              }
              tr_failed. {
                st.failed += 1u;
                write_failed(st.out, st.use_color);
                st.out.write_line("");
                st.failures += ~[test];
              }
              tr_ignored. {
                st.ignored += 1u;
                write_ignored(st.out, st.use_color);
                st.out.write_line("");
              }
            }
          }
        }
    }

    let st = @{
        out: io::stdout(),
        use_color: use_color(),
        mutable total: 0u,
        mutable passed: 0u,
        mutable failed: 0u,
        mutable ignored: 0u,
        mutable failures: ~[]
    };

    run_tests(opts, tests, to_task,
              bind callback(_, st));

    assert st.passed + st.failed + st.ignored == st.total;
    let success = st.failed == 0u;

    if !success {
        st.out.write_line("\nfailures:");
        for test: test_desc in st.failures {
            let testname = test.name; // Satisfy alias analysis
            st.out.write_line(#fmt("    %s", testname));
        }
    }

    st.out.write_str(#fmt("\nresult: "));
    if success {
        // There's no parallelism at this point so it's safe to use color
        write_ok(st.out, true);
    } else { write_failed(st.out, true); }
    st.out.write_str(#fmt(". %u passed; %u failed; %u ignored\n\n",
                       st.passed, st.failed, st.ignored));

    ret success;

    fn write_ok(out: &io::writer, use_color: bool) {
        write_pretty(out, "ok", term::color_green, use_color);
    }

    fn write_failed(out: &io::writer, use_color: bool) {
        write_pretty(out, "FAILED", term::color_red, use_color);
    }

    fn write_ignored(out: &io::writer, use_color: bool) {
        write_pretty(out, "ignored", term::color_yellow, use_color);
    }

    fn write_pretty(out: &io::writer, word: &str, color: u8,
                    use_color: bool) {
        if use_color && term::color_supported() {
            term::fg(out.get_buf_writer(), color);
        }
        out.write_str(word);
        if use_color && term::color_supported() {
            term::reset(out.get_buf_writer());
        }
    }
}

fn use_color() -> bool {
    ret get_concurrency() == 1u;
}

tag testevent {
    te_filtered(test_desc[]);
    te_wait(test_desc);
    te_result(test_desc, test_result);
}

fn run_tests(opts: &test_opts, tests: &test_desc[],
             to_task: &test_to_task, callback: fn(testevent)) {

    let filtered_tests = filter_tests(opts, tests);

    callback(te_filtered(filtered_tests));

    // It's tempting to just spawn all the tests at once but that doesn't
    // provide a great user experience because you might sit waiting for the
    // result of a particular test for an unusually long amount of time.
    let concurrency = get_concurrency();
    log #fmt("using %u test tasks", concurrency);
    let total = ivec::len(filtered_tests);
    let run_idx = 0u;
    let wait_idx = 0u;
    let futures = ~[];

    while wait_idx < total {
        while ivec::len(futures) < concurrency && run_idx < total {
            futures += ~[run_test(filtered_tests.(run_idx), to_task)];
            run_idx += 1u;
        }

        let future = futures.(0);
        callback(te_wait(future.test));
        let result = future.wait();
        callback(te_result(future.test, result));
        futures = ivec::slice(futures, 1u, ivec::len(futures));
        wait_idx += 1u;
    }
}

fn get_concurrency() -> uint { rustrt::sched_threads() }

fn filter_tests(opts: &test_opts, tests: &test_desc[]) -> test_desc[] {
    let filtered = tests;

    // Remove tests that don't match the test filter
    filtered =
        if option::is_none(opts.filter) {
            filtered
        } else {
            let filter_str =
                alt opts.filter {
                  option::some(f) { f }
                  option::none. { "" }
                };

            let filter =
                bind fn (test: &test_desc, filter_str: str) ->
                        option::t[test_desc] {
                         if str::find(test.name, filter_str) >= 0 {
                             ret option::some(test);
                         } else { ret option::none; }
                     }(_, filter_str);

            ivec::filter_map(filter, filtered)
        };

    // Maybe pull out the ignored test and unignore them
    filtered =
        if !opts.run_ignored {
            filtered
        } else {
            let filter =
                fn (test: &test_desc) -> option::t[test_desc] {
                    if test.ignore {
                        ret option::some({name: test.name,
                                          fn: test.fn,
                                          ignore: false});
                    } else { ret option::none; }
                };

            ivec::filter_map(filter, filtered)
        };

    // Sort the tests alphabetically
    filtered =
        {
            fn lteq(t1: &test_desc, t2: &test_desc) -> bool {
                str::lteq(t1.name, t2.name)
            }
            sort::merge_sort(lteq, filtered)
        };

    ret filtered;
}

type test_future =
    {test: test_desc, fnref: @fn() , wait: fn() -> test_result };

fn run_test(test: &test_desc, to_task: &test_to_task) -> test_future {
    // FIXME: Because of the unsafe way we're passing the test function
    // to the test task, we need to make sure we keep a reference to that
    // function around for longer than the lifetime of the task. To that end
    // we keep the function boxed in the test future.
    let fnref = @test.fn;
    if !test.ignore {
        let test_task = to_task(*fnref);
        ret {test: test,
             fnref: fnref,
             wait:
                 bind fn (test_task: &task) -> test_result {
                          alt task::join(test_task) {
                            task::tr_success. { tr_ok }
                            task::tr_failure. { tr_failed }
                          }
                      }(test_task)};
    } else {
        ret {test: test,
             fnref: fnref,
             wait: fn () -> test_result { tr_ignored }};
    }
}

// We need to run our tests in another task in order to trap test failures.
// But, at least currently, functions can't be used as spawn arguments so
// we've got to treat our test functions as unsafe pointers.  This function
// only works with functions that don't contain closures.
fn default_test_to_task(f: &fn()) -> task {
    fn run_task(fptr: *mutable fn() ) {
        configure_test_task();
        // Run the test
        (*fptr)()
    }
    let fptr = ptr::addr_of(f);
    ret spawn run_task(fptr);
}

// Call from within a test task to make sure it's set up correctly
fn configure_test_task() {
    // If this task fails we don't want that failure to propagate to the
    // test runner or else we couldn't keep running tests
    task::unsupervise();

    // FIXME (236): Hack supreme - unwinding doesn't work yet so if this
    // task fails memory will not be freed correctly. This turns off the
    // sanity checks in the runtime's memory region for the task, so that
    // the test runner can continue.
    rustrt::hack_allow_leaks();
}

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


<commit_before>#![feature(phase)]

#[phase(plugin)]
extern crate glium_macros;

extern crate glutin;
extern crate glium;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[vertex_format]
        struct Vertex {
            position: [f32, ..2],
            color: [f32, ..3],
        }

        glium::VertexBuffer::new(&display,
            vec![
                Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
                Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
                Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
            ]
        )
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, glium::TrianglesList,
        &[ 0u16, 1, 2 ]);

    // compiling shaders and linking them together
    let program = glium::Program::new(&display,
        // vertex shader
        "
            #version 110

            uniform mat4 matrix;

            attribute vec2 position;
            attribute vec3 color;

            varying vec3 vColor;

            void main() {
                gl_Position = vec4(position, 0.0, 1.0) * matrix;
                vColor = color;
            }
        ",

        // fragment shader
        "
            #version 110
            varying vec3 vColor;

            void main() {
                gl_FragColor = vec4(vColor, 1.0);
            }
        ",

        // geometry shader
        None)
        .unwrap();

    // creating the uniforms structure
    #[uniforms]
    struct Uniforms {
        matrix: [[f32, ..4], ..4],
    }

    // the main loop
    // each cycle will draw once
    'main: loop {
        use std::io::timer;
        use std::time::Duration;

        // building the uniforms
        let uniforms = Uniforms {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ]
        };

        // drawing a frame
        let mut target = display.draw();
        target.draw(glium::BasicDraw(&vertex_buffer, &index_buffer, &program, &uniforms, &std::default::Default::default()));
        target.finish();

        // sleeping for some time in order not to use up too much CPU
        timer::sleep(Duration::milliseconds(17));

        // polling and handling the events received by the window
        for event in display.poll_events().into_iter() {
            match event {
                glutin::Closed => break 'main,
                _ => ()
            }
        }
    }
}
<commit_msg>Triangle example now shows a black background<commit_after>#![feature(phase)]

#[phase(plugin)]
extern crate glium_macros;

extern crate glutin;
extern crate glium;

fn main() {
    use glium::DisplayBuild;

    // building the display, ie. the main object
    let display = glutin::WindowBuilder::new()
        .build_glium()
        .unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[vertex_format]
        struct Vertex {
            position: [f32, ..2],
            color: [f32, ..3],
        }

        glium::VertexBuffer::new(&display,
            vec![
                Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
                Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
                Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
            ]
        )
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, glium::TrianglesList,
        &[ 0u16, 1, 2 ]);

    // compiling shaders and linking them together
    let program = glium::Program::new(&display,
        // vertex shader
        "
            #version 110

            uniform mat4 matrix;

            attribute vec2 position;
            attribute vec3 color;

            varying vec3 vColor;

            void main() {
                gl_Position = vec4(position, 0.0, 1.0) * matrix;
                vColor = color;
            }
        ",

        // fragment shader
        "
            #version 110
            varying vec3 vColor;

            void main() {
                gl_FragColor = vec4(vColor, 1.0);
            }
        ",

        // geometry shader
        None)
        .unwrap();

    // creating the uniforms structure
    #[uniforms]
    struct Uniforms {
        matrix: [[f32, ..4], ..4],
    }

    // the main loop
    // each cycle will draw once
    'main: loop {
        use std::io::timer;
        use std::time::Duration;

        // building the uniforms
        let uniforms = Uniforms {
            matrix: [
                [1.0, 0.0, 0.0, 0.0],
                [0.0, 1.0, 0.0, 0.0],
                [0.0, 0.0, 1.0, 0.0],
                [0.0, 0.0, 0.0, 1.0f32]
            ]
        };

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(glium::BasicDraw(&vertex_buffer, &index_buffer, &program, &uniforms, &std::default::Default::default()));
        target.finish();

        // sleeping for some time in order not to use up too much CPU
        timer::sleep(Duration::milliseconds(17));

        // polling and handling the events received by the window
        for event in display.poll_events().into_iter() {
            match event {
                glutin::Closed => break 'main,
                _ => ()
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>move single_char_add_str to its own module<commit_after>use crate::methods::{single_char_insert_string, single_char_push_string};
use crate::utils::match_def_path;
use crate::utils::paths;
use rustc_hir as hir;
use rustc_lint::LateContext;

pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
    if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
        if match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
            single_char_push_string::check(cx, expr, args);
        } else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) {
            single_char_insert_string::check(cx, expr, args);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Problem 18<commit_after>fn slice<'a, T>(list: &'a [T], i: uint, k: uint) -> &'a [T] {
    list.slice(i-1, k)
}

fn main() {
    let list = ~['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
    println!("{:?}", slice(list, 3, 7));
    println!("{:?}", slice(list, 3, 7));
}

<|endoftext|>


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

use common::memory::*;
use common::pci::*;

use programs::common::*;

struct STE {
    pub ptr: u64,
    pub length: u64
}

struct TRB {
    pub data: u64,
    pub status: u32,
    pub control: u32
}

impl TRB {
    pub fn new() -> TRB {
        TRB {
           data: 0,
           status: 0,
           control: 0
        }
    }

    pub fn from_type(trb_type: u32) -> TRB {
        TRB {
            data: 0,
            status: 0,
            control: (trb_type & 0x3F) << 10
        }
    }
}

pub struct EHCI {
    pub bus: usize,
    pub slot: usize,
    pub func: usize,
    pub base: usize,
    pub memory_mapped: bool,
    pub irq: u8
}

impl SessionModule for EHCI {
    fn on_irq(&mut self, irq: u8){
        if irq == self.irq {
            //d("EHCI handle");

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

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

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

                *USBSTS = 0b111111;

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

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

            //dl();
        }
    }
}

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

        pci_write(self.bus, self.slot, self.func, 0x04, pci_read(self.bus, self.slot, self.func, 0x04) | 4); // Bus master

        let CAPLENGTH = self.base as *mut u8;

        d(" CAPLENGTH ");
        dd(*CAPLENGTH as usize);

        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;

        *USBCMD &= 0xFFFFFFFE;
        d(" CMD ");
        dh(*USBCMD as usize);

        d(" STS ");
        dh(*USBSTS as usize);

        //*CTRLDSSEGMENT = 0;

        *USBINTR = 0b111111;

        let periodiclist = alloc(4096) as *mut u32;

        for i in 0..1024 {
            *periodiclist.offset(i) = periodiclist as u32 | 1;
        }
        *PERIODICLISTBASE = periodiclist as u32;

        *USBCMD |= 1;
        *CONFIGFLAG = 1;

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

        d(" STS ");
        dh(*USBSTS as usize);

        dl();

        for i in 0..16 {
            if *PORTSC.offset(i) & 1 == 1 {
                d("Device on port ");
                dd(i as usize);
                dl();
            }
        }
    }
}
<commit_msg>WIP USB<commit_after>use core::mem::size_of;
use core::ptr;

use common::memory::*;
use common::pci::*;

use programs::common::*;

struct SETUP {
    request_type: u8,
    request: u8,
    value: u16,
    index: u16,
    len: u16
}

struct QTD {
    next: u32,
    next_alt: u32,
    token: u32,
    buffers: [u32; 5]
}

struct QueueHead {
    next: u32,
    characteristics: u32,
    capabilities: u32,
    qtd_ptr: u32,
    qtd: QTD
}

pub struct EHCI {
    pub bus: usize,
    pub slot: usize,
    pub func: usize,
    pub base: usize,
    pub memory_mapped: bool,
    pub irq: u8
}

impl SessionModule for EHCI {
    fn on_irq(&mut self, irq: u8){
        if irq == self.irq {
            //d("EHCI handle");

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

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

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

                *USBSTS = 0b111111;

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

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

            //dl();
        }
    }
}

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

        pci_write(self.bus, self.slot, self.func, 0x04, pci_read(self.bus, self.slot, self.func, 0x04) | 4); // Bus master

        let CAPLENGTH = self.base as *mut u8;

        d(" CAPLENGTH ");
        dd(*CAPLENGTH as usize);

        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;

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

        d(" STS ");
        dh(*USBSTS as usize);

        *USBCMD &= 0xFFFFFFF0;

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

        d(" STS ");
        dh(*USBSTS as usize);

        //*CTRLDSSEGMENT = 0;

        *USBINTR = 0b111111;

        *USBCMD |= 1;
        *CONFIGFLAG = 1;

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

        d(" STS ");
        dh(*USBSTS as usize);

        dl();

        for i in 0..16 {
            if *PORTSC.offset(i) & 1 == 1 {
                d("Device on port ");
                dd(i as usize);
                d(" ");
                dh(*PORTSC.offset(i) as usize);
                dl();

                let out_qtd = alloc(size_of::<QTD>()) as *mut QTD;
                ptr::write(out_qtd, QTD {
                    next: 1,
                    next_alt: 1,
                    token: (1 << 31) | (0b11 << 10) | 0x80,
                    buffers: [0, 0, 0, 0, 0]
                });

                let in_data = alloc(64) as *mut u8;
                for i in 0..64{
                    *in_data.offset(i) = 0;
                }

                let in_qtd = alloc(size_of::<QTD>()) as *mut QTD;
                ptr::write(in_qtd, QTD {
                    next: out_qtd as u32,
                    next_alt: 1,
                    token: (1 << 31) | (64 << 16) | (0b11 << 10) | (0b01 << 8) | 0x80,
                    buffers: [in_data as u32, 0, 0, 0, 0]
                });

                let setup_packet = alloc(size_of::<SETUP>()) as *mut SETUP;
                ptr::write(setup_packet, SETUP {
                    request_type: 0b10000000,
                    request: 6,
                    value: 1 << 8,
                    index: 0,
                    len: 64
                });

                let setup_qtd = alloc(size_of::<QTD>()) as *mut QTD;
                ptr::write(setup_qtd, QTD {
                    next: in_qtd as u32,
                    next_alt: 1,
                    token: ((size_of::<SETUP>() as u32) << 16) | (0b11 << 10) | (0b10 << 8) | 0x80,
                    buffers: [setup_packet as u32, 0, 0, 0, 0]
                });

                let queuehead = alloc(size_of::<QueueHead>()) as *mut QueueHead;
                ptr::write(queuehead, QueueHead {
                    next: 1,
                    characteristics: (64 << 16) | (1 << 15) | (1 << 14) | (0b10 << 12),
                    capabilities: (0b11 << 30),
                    qtd_ptr: setup_qtd as u32,
                    qtd: ptr::read(setup_qtd)
                });

                d("Prepare");
                    d(" CMD ");
                    dh(*USBCMD as usize);

                    d(" PTR ");
                    dh(queuehead as usize);
                dl();

                d("Send");
                    *ASYNCLISTADDR = queuehead as u32;

                    *USBCMD |= (1 << 5);

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

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

                loop {
                    d("Wait");
                        if *USBSTS & 0xA000  == 0 {
                            break;
                        }

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

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

                d(" Stop");
                    *USBCMD &= 0xFFFFFFFF - (1 << 5);

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

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

                d("Data");
                for i in 0..64 {
                    d(" ");
                    db(*in_data.offset(i));
                }
                dl();

                //Only detect one device for testing
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>ComfyCafé search produces 'No results.' correctly now.<commit_after><|endoftext|>


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

#[derive(Debug)]
struct SearchTree<T> {
    left: Option<Box<SearchTree<T>>>,
    right: Option<Box<SearchTree<T>>>,
    key: T,
}

impl<T> SearchTree<T> where T: std::fmt::Debug {
    fn inorder_tree(self) {
        self.left.map(|x| x.inorder_tree());
        println!("self.key = {:#?}", self.key);
        self.right.map(|x| x.inorder_tree());
    }
}

fn main() {
    println!("Hello, world!");
    let left = SearchTree {
        left: None,
        right: None,
        key: 32,
    };

    let right = SearchTree {
        left: None,
        right: None,
        key: 43,
    };

    let root = SearchTree {
        left: Some(Box::new(left)),
        right: Some(Box::new(right)),
        key: 40,
    };
    root.inorder_tree();

}
<commit_msg>add search<commit_after>use std::boxed::Box;

#[derive(Debug)]
struct SearchTree<T> {
    left: Option<Box<SearchTree<T>>>,
    right: Option<Box<SearchTree<T>>>,
    key: T,
}

impl<T> SearchTree<T> where T: std::fmt::Debug + std::cmp::Eq + std::cmp::PartialOrd {
    fn inorder_tree(self) {
        self.left.map(|x| x.inorder_tree());
        println!("self.key = {:#?}", self.key);
        self.right.map(|x| x.inorder_tree());
    }

    fn search_tree(self, key: T ) -> Option<SearchTree<T>> {
        if self.key == key {
            return Some(self);
        }

        if key < self.key {
            match self.left {
                Some(tree) => tree.search_tree(key),
                None => None
            }
        } else {
            match self.right {
                Some(tree) => tree.search_tree(key),
                None => None
            }
        }
    }
}

fn main() {
    let left = SearchTree {
        left: None,
        right: None,
        key: 32,
    };

    let right = SearchTree {
        left: None,
        right: None,
        key: 43,
    };

    let root = SearchTree {
        left: Some(Box::new(left)),
        right: Some(Box::new(right)),
        key: 40,
    };

//    root.inorder_tree();

    let tree = root.search_tree(43);
    match tree {
        Some(t) => println!("t.key = {:#?}", t.key),
        None => println!(" None "),

    }

}
<|endoftext|>


<commit_before><commit_msg>	modified:   src/main.rs<commit_after><|endoftext|>