<commit_before>use argparse::ArgumentStore;

pub struct HitIterator<'a> {
    args: ArgumentStore<'a>,
}

impl<'a> HitIterator<'a> {

    fn new(args: ArgumentStore) -> HitIterator {
        HitIterator {args: args}
    }
}

impl<'a> Iterator for HitIterator<'a> {

    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        //Some("hello")
        None
    }
}

//fn search(args: &ArgumentStore, callback: &Fn(&str)) {}

#[cfg(test)]
mod filesearchtest {

    use argparse::ArgumentStore;
    use std::path::PathBuf;
    use std::env;
    use std::io;
    use std::fs::remove_dir_all;
    use std::fs::create_dir;
    use std::fs::File;
    use filesearch::HitIterator;
    //use filesearch::search;

    fn createfile(path: &PathBuf, filename: &str) {
        let mut path = path.clone();
        path.push(filename);
        File::create(path).expect("Can not create file in temporary testing directory");
    }

    fn preparetestfiles() {
        let mut tempdir: PathBuf = env::temp_dir();
        tempdir.push("elicit_temporary_test_dir");
        if tempdir.exists() {
            remove_dir_all(&tempdir).expect("Can not remove old testing directory.");
        }
        create_dir(&tempdir).expect("Can not create temporary testing directory");

        createfile(&tempdir, "hello");
        createfile(&tempdir, "whatuphelloworld");
        createfile(&tempdir, "no_he_ll_o_in_this_file_name");
    }

    #[test]
    fn filesearch_by_pattern() {
        preparetestfiles();

        let mut tempdir: PathBuf = env::temp_dir();
        tempdir.push("elicit_temporary_test_dir");

        assert!(tempdir.exists());
        tempdir.push("hello");
        assert!(tempdir.exists());

        let args = ArgumentStore{pattern:Some("hello"), .. Default::default()};

        let mut hititer = HitIterator::new(args);

        let mut results : Vec<&str> = hititer.collect();

        assert_eq!(results.len(), 2);
        assert_eq!(results[0], "hello");
        assert_eq!(results[1], "whatuphelloworld");
    }

}
<commit_msg>basic implementation of the hit iterator without entering subdirs and matching the with given argumen<commit_after>use argparse::ArgumentStore;
use std::fs::{self, DirEntry, ReadDir};
use std::path::PathBuf;
use std::env;
use std::io::Result;
use std::ffi::OsString;

pub struct HitIterator<'a> {
    args: ArgumentStore<'a>,
    readdirs: Vec<ReadDir>,
}

// impl<'a> HitIterator<'a> {
//     fn new(args: ArgumentStore) -> HitIterator {
//     }
// }

impl<'a> Iterator for HitIterator<'a> {

    type Item = OsString;

    fn next(&mut self) -> Option<OsString> {
        if self.readdirs.len() == 0 {
            return None;
        }
        let mut readdir = self.readdirs.pop().unwrap();

        match readdir.next() {
            Some(v) => {
                // TODO check if dir
                let entrypath = v.unwrap().file_name();
                self.readdirs.push(readdir);
                return Some(entrypath);
            },
            None => {
                return self.next();
            }

        }

        //Some("hello")
        None
    }
}

fn find(args: ArgumentStore) -> Result<HitIterator> {

    let dir: PathBuf = if args.dir.is_some() {
        PathBuf::from(args.dir.unwrap())
    } else {
        env::current_dir().unwrap()
    };

    Ok(HitIterator {args: args, readdirs: vec![try!(fs::read_dir(dir))]})
}

//fn search(args: &ArgumentStore, callback: &Fn(&str)) {}

#[cfg(test)]
mod filesearchtest {

    use argparse::ArgumentStore;
    use std::path::PathBuf;
    use std::env;
    use std::io;
    use std::fs::remove_dir_all;
    use std::fs::create_dir;
    use std::fs::File;
    use filesearch::{self, HitIterator};
    //use filesearch::search;
    use std::ffi::OsString;

    fn createfile(path: &PathBuf, filename: &str) {
        let mut path = path.clone();
        path.push(filename);
        File::create(path).expect("Can not create file in temporary testing directory");
    }

    fn preparetestfiles() {
        let mut tempdir: PathBuf = env::temp_dir();
        tempdir.push("elicit_temporary_test_dir");
        if tempdir.exists() {
            remove_dir_all(&tempdir).expect("Can not remove old testing directory.");
        }
        create_dir(&tempdir).expect("Can not create temporary testing directory");

        createfile(&tempdir, "hello");
        createfile(&tempdir, "whatuphelloworld");
        createfile(&tempdir, "no_he_ll_o_in_this_file_name");
    }

    #[test]
    fn filesearch_by_pattern() {
        preparetestfiles();

        let mut tempdir: PathBuf = env::temp_dir();
        tempdir.push("elicit_temporary_test_dir");
        assert!(tempdir.exists());

        let args = ArgumentStore{pattern:Some("hello"), dir: tempdir.to_str(), isregex: false};

        let mut hititer = filesearch::find(args).unwrap();

        let mut results : Vec<OsString> = hititer.collect();

        assert_eq!(results.len(), 2);
        assert_eq!(results[0], OsString::from("hello"));
        assert_eq!(results[1], OsString::from("whatuphelloworld"));
    }

}
<|endoftext|>


<commit_before>// Copyright (c) 2018, Ben Boeckel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//       this list of conditions and the following disclaimer in the documentation
//       and/or other materials provided with the distribution.
//     * Neither the name of this project nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::{KeyPermissions, KeyringSerial, TimeoutSeconds};

#[rustfmt::skip]
extern "C" {
    pub fn add_key(
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        payload:        *const libc::c_void,
        plen:           libc::size_t,
        keyring:        KeyringSerial)
        -> KeyringSerial;
    pub fn request_key(
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        callout_info:   *const libc::c_char,
        keyring:        Option<KeyringSerial>)
        -> KeyringSerial;

    pub fn keyctl_get_keyring_ID(
        id:     KeyringSerial,
        create: libc::c_int)
        -> KeyringSerial;
    pub fn keyctl_join_session_keyring(
        name:   *const libc::c_char)
        -> KeyringSerial;
    pub fn keyctl_update(
        id:         KeyringSerial,
        payload:    *const libc::c_void,
        plen:       libc::size_t)
        -> libc::c_long;
    pub fn keyctl_revoke(
        id: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_chown(
        id:     KeyringSerial,
        uid:    libc::uid_t,
        gid:    libc::gid_t)
        -> libc::c_long;
    pub fn keyctl_setperm(
        id:     KeyringSerial,
        perm:   KeyPermissions)
        -> libc::c_long;
    pub fn keyctl_describe(
        id:     KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    pub fn keyctl_clear(
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_link(
        id:     KeyringSerial,
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_unlink(
        id:     KeyringSerial,
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_search(
        ringid:         KeyringSerial,
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        destringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_read(
        id:     KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    pub fn keyctl_instantiate(
        id:         KeyringSerial,
        payload:    *const libc::c_void,
        plen:       libc::size_t,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_negate(
        id:         KeyringSerial,
        timeout:    TimeoutSeconds,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_set_reqkey_keyring(
        reqkey_defl:    libc::c_int)
        -> libc::c_long;
    pub fn keyctl_set_timeout(
        key:        KeyringSerial,
        timeout:    TimeoutSeconds)
        -> libc::c_long;
    pub fn keyctl_assume_authority(
        key:    Option<KeyringSerial>)
        -> libc::c_long;
    pub fn keyctl_get_security(
        key:    KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    //pub fn keyctl_session_to_parent()
    //    -> libc::c_long;
    pub fn keyctl_reject(
        id:         KeyringSerial,
        timeout:    TimeoutSeconds,
        error:      libc::c_uint,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_invalidate(
        id: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_get_persistent(
        uid:    libc::uid_t,
        id:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_dh_compute(
        private:    KeyringSerial,
        prime:      KeyringSerial,
        base:       KeyringSerial,
        buffer:     *mut libc::c_char,
        buflen:     libc::size_t)
        -> libc::c_long;
}
<commit_msg>Silence buggy improper_ctypes warning<commit_after>// Copyright (c) 2018, Ben Boeckel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice,
//       this list of conditions and the following disclaimer in the documentation
//       and/or other materials provided with the distribution.
//     * Neither the name of this project nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

use crate::{KeyPermissions, KeyringSerial, TimeoutSeconds};

// Remove when rust-lang/rust#60300 is in stable
#[allow(improper_ctypes)]

#[rustfmt::skip]
extern "C" {
    pub fn add_key(
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        payload:        *const libc::c_void,
        plen:           libc::size_t,
        keyring:        KeyringSerial)
        -> KeyringSerial;
    pub fn request_key(
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        callout_info:   *const libc::c_char,
        keyring:        Option<KeyringSerial>)
        -> KeyringSerial;

    pub fn keyctl_get_keyring_ID(
        id:     KeyringSerial,
        create: libc::c_int)
        -> KeyringSerial;
    pub fn keyctl_join_session_keyring(
        name:   *const libc::c_char)
        -> KeyringSerial;
    pub fn keyctl_update(
        id:         KeyringSerial,
        payload:    *const libc::c_void,
        plen:       libc::size_t)
        -> libc::c_long;
    pub fn keyctl_revoke(
        id: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_chown(
        id:     KeyringSerial,
        uid:    libc::uid_t,
        gid:    libc::gid_t)
        -> libc::c_long;
    pub fn keyctl_setperm(
        id:     KeyringSerial,
        perm:   KeyPermissions)
        -> libc::c_long;
    pub fn keyctl_describe(
        id:     KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    pub fn keyctl_clear(
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_link(
        id:     KeyringSerial,
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_unlink(
        id:     KeyringSerial,
        ringid: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_search(
        ringid:         KeyringSerial,
        type_:          *const libc::c_char,
        description:    *const libc::c_char,
        destringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_read(
        id:     KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    pub fn keyctl_instantiate(
        id:         KeyringSerial,
        payload:    *const libc::c_void,
        plen:       libc::size_t,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_negate(
        id:         KeyringSerial,
        timeout:    TimeoutSeconds,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_set_reqkey_keyring(
        reqkey_defl:    libc::c_int)
        -> libc::c_long;
    pub fn keyctl_set_timeout(
        key:        KeyringSerial,
        timeout:    TimeoutSeconds)
        -> libc::c_long;
    pub fn keyctl_assume_authority(
        key:    Option<KeyringSerial>)
        -> libc::c_long;
    pub fn keyctl_get_security(
        key:    KeyringSerial,
        buffer: *mut libc::c_char,
        buflen: libc::size_t)
        -> libc::c_long;
    //pub fn keyctl_session_to_parent()
    //    -> libc::c_long;
    pub fn keyctl_reject(
        id:         KeyringSerial,
        timeout:    TimeoutSeconds,
        error:      libc::c_uint,
        ringid:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_invalidate(
        id: KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_get_persistent(
        uid:    libc::uid_t,
        id:     KeyringSerial)
        -> libc::c_long;
    pub fn keyctl_dh_compute(
        private:    KeyringSerial,
        prime:      KeyringSerial,
        base:       KeyringSerial,
        buffer:     *mut libc::c_char,
        buflen:     libc::size_t)
        -> libc::c_long;
}
<|endoftext|>


<commit_before>/*
  Copyright (c) 2015, Al Poole <netstar@gmail.com>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  PERFORMANCE OF THIS SOFTWARE.
*/

//   This is a HTTPS CONNECT proxy!

use std::string::{String};
use std::net::{SocketAddrV4,Ipv4Addr,TcpListener,TcpStream};
use std::io::{Write, Read};

const REQUEST_LEN: usize = 65535;

fn substr(buf: [u8;REQUEST_LEN], needle: &str, byte: u8) -> String
{
	let mut i = 0;
	let mut x = 0;
	let mut request = String::new();

	let srch = needle.as_bytes();

	if srch.len() == 0 {
		return request;
	}

	while buf[i] as char != '\0'  {
		if buf[i] as char == srch[0] as char {
			while x < srch.len() && buf[i] as char  == srch[x] as char {
				i = i + 1;
				x = x + 1;
			}
			break;
		} else {
			i = i + 1;
		}
	}

	if x == srch.len() {
		let mut end = i;
		while buf[end] as char != byte as char && buf[end] as char != '\n'
		{
			end = end + 1;

		}

		for y in i..end {
			request.push(buf[y] as char);
		}
	}

	return request;
}

const CHUNK: usize = 4096; // PAGESIZEish

fn talk_to_me(mut instream: &TcpStream, mut outstream: &TcpStream, mut headers: &Header) -> bool
{

	let mut buf = [0u8; CHUNK];

	println!("top");
	let bytes = outstream.read(&mut buf).unwrap();
	if bytes <= 0 {
		return false;
	}

	println!("recv {}", bytes);

	for i in 0..bytes {
		print!("{}", buf[i] as char);
	}

	let mut chunk = 0;

	while chunk < bytes {
		let sent = instream.write(&mut buf[0..bytes]).unwrap();
		if sent <= 0 {
			return false;
		}
		println!("sent {}", sent);
		chunk = chunk + sent;
	}
	true
}

struct Header {
	pub hostname: String,
	pub connection: String,
	pub proxy: String,
	pub agent: String,
}

impl Header {

pub fn new() -> Header
{
	let hostname	 = String::new();
	let connection   = String::new();
	let proxy	 = String::new();
	let agent	 = String::new();

	let h = Header
	{
		hostname: hostname,
		connection: connection,
		proxy: proxy,
		agent: agent
	};

	return h;
}

}

fn http_connect_request(instream: TcpStream, headers: Header)
{
	let bogus_fix = &format!("{}", headers.hostname);

	let mut outstream = TcpStream::connect::<(&str)>(bogus_fix).unwrap();
	let mut disconnected = false;

	let response = format!("HTTP/1.1 200 Connection established\r\nUser-Agent: {}\r\nProxy-Connection: {}\r\nConnection: {}\r\nHost: {}\r\n\r\n",
			headers.agent, headers.proxy, headers.connection, headers.hostname);
	println!("sending: \n\n{}", response);
	let mut s = &instream;
	s.write(response.as_bytes()).unwrap(); // tell client the connection is made

	while ! disconnected {
		disconnected = talk_to_me(&instream, &outstream, &headers);
	}

}

fn check_headers(buffer: [u8;REQUEST_LEN], headers: &mut Header) -> bool
{
	let mut i = 0;

	while buffer[i] != '\0' as u8
	{
		print!("{}", buffer[i] as char);
		i+=1;
	}
	print!("\n");

	if headers.hostname.is_empty()
	{
		headers.hostname = substr(buffer, "Host: ", '\r' as u8);
	}

	if headers.connection.is_empty()
	{
		headers.connection = substr(buffer, "Connection: ", '\r' as u8);
	}

	if headers.proxy.is_empty()
	{
		headers.proxy = substr(buffer, "Proxy-Connection: ", '\r' as u8);
	}

	if headers.agent.is_empty()
	{
		headers.agent = substr(buffer, "User-Agent: ", '\r' as u8);
	}

	if ! headers.hostname.is_empty() && ! headers.connection.is_empty()
		&& ! headers.proxy.is_empty() && ! headers.agent.is_empty()
	{

		return true;
	}

	return false;
}

fn request_headers(mut instream: &TcpStream, headers: &mut Header)
{
	 loop
	{
		let mut buffer = [0u8; REQUEST_LEN];
		let mut byte = [0u8; 1];
		let mut len = 0;

		while byte[0] as char != '\n'
		{
			let bytes = instream.read(&mut byte).unwrap();
			buffer[len] = byte[0];
			len += bytes;
		}

		buffer[len] = '\0' as u8;

		if check_headers(buffer, headers) && len == 2
		{
			let mut i = 0;

			while i < REQUEST_LEN
			{
				buffer[i] = 0;
				i += 1;
			}
			return;
		}
	}

}

fn request_method(mut instream: &TcpStream) -> String
{
	let mut byte = [0u8;1];

	let mut method: String = String::new();

	// bit better for now it'll do!
	while byte[0] as char != ' '
	{
		instream.read(&mut byte).unwrap();
		if byte[0] as char != ' '
		{
			method.push(byte[0] as char);
		}
	}

	match method.as_ref()
	{
		"CONNECT" =>
		{
			return method;
		}

		"GET" | "POST" | "OPTIONS" | "HEAD" =>
		{
			return "".to_string();
			// all good do not return!!!
		}

		_ =>
		{
			return "".to_string();
		}
	}
}

fn proxy(stream: TcpStream) {
	let method = request_method(&stream);

	match method.as_ref()
	{
		"CONNECT" =>
		{
			let mut headers = Header::new();
			request_headers(&stream, &mut headers);

			http_connect_request(stream, headers);
		}

		_ =>
		{
			println!("REQUEST UNKNOWN");
		}
	}
}

extern crate threadpool;
use threadpool::ThreadPool;

fn proxy_time(port: u16, threads: usize) {
	let ip = Ipv4Addr::new(127, 0, 0, 1);
	let host = SocketAddrV4::new(ip, port);
	let listener = TcpListener::bind(host).unwrap();

	let pool = ThreadPool::new(threads);

	for stream in listener.incoming()
	{
		match stream
		{
			Ok(stream) =>
			{
				pool.execute(move || { proxy(stream); });
			}

			Err(_) =>
			{
				println!("NET error");
				1 << 7;
			}
		}
	}

	drop (listener);
}

fn main () {
	let threads = 128;
	let port: u16 = 9998;

	proxy_time(port, threads);
	println!("Blocking all badness");
}

<commit_msg>ready for [INSERT PROPER ASYNC IO]<commit_after>/*
  Copyright (c) 2015, Al Poole <netstar@gmail.com>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  PERFORMANCE OF THIS SOFTWARE.
*/

//   This is a HTTPS CONNECT proxy!
//   it doesn't work yet as i don't know how to do this in Rust, is it
//   even possible yet???

use std::string::{String};
use std::net::{SocketAddrV4,Ipv4Addr,TcpListener,TcpStream};
use std::io::{Write, Read};

const REQUEST_LEN: usize = 65535;

fn substr(buf: [u8;REQUEST_LEN], needle: &str, byte: u8) -> String
{
	let mut i = 0;
	let mut x = 0;
	let mut request = String::new();

	let srch = needle.as_bytes();

	if srch.len() == 0 {
		return request;
	}

	while buf[i] as char != '\0'  {
		if buf[i] as char == srch[0] as char {
			while x < srch.len() && buf[i] as char  == srch[x] as char {
				i = i + 1;
				x = x + 1;
			}
			break;
		} else {
			i = i + 1;
		}
	}

	if x == srch.len() {
		let mut end = i;
		while buf[end] as char != byte as char && buf[end] as char != '\n'
		{
			end = end + 1;

		}

		for y in i..end {
			request.push(buf[y] as char);
		}
	}

	return request;
}

const CHUNK: usize = 4096; // PAGESIZEish

fn talk_to_me(mut instream: &TcpStream, mut outstream: &TcpStream) -> bool
{

	let mut buf = [0u8; CHUNK];

	println!("top");
	let bytes = outstream.read(&mut buf).unwrap();
	if bytes <= 0 {
		return false;
	}

	println!("recv {}", bytes);

	for i in 0..bytes {
		print!("{}", buf[i] as char);
	}

	let mut chunk = 0;

	while chunk < bytes {
		let sent = instream.write(&mut buf[0..bytes]).unwrap();
		if sent <= 0 {
			return false;
		}
		println!("sent {}", sent);
		chunk = chunk + sent;
	}
	true
}

struct Header {
	pub hostname: String,
	pub connection: String,
	pub proxy: String,
	pub agent: String,
}

impl Header {

pub fn new() -> Header
{
	let hostname	 = String::new();
	let connection   = String::new();
	let proxy	 = String::new();
	let agent	 = String::new();

	let h = Header
	{
		hostname: hostname,
		connection: connection,
		proxy: proxy,
		agent: agent
	};

	return h;
}

}

fn http_connect_request(instream: TcpStream, headers: Header)
{
	let bogus_fix = &format!("{}", headers.hostname);

	let outstream = TcpStream::connect::<(&str)>(bogus_fix).unwrap();
	let mut disconnected = false;

	let response = format!("HTTP/1.1 200 Connection established\r\nUser-Agent: {}\r\nProxy-Connection: {}\r\nConnection: {}\r\nHost: {}\r\n\r\n",
			headers.agent, headers.proxy, headers.connection, headers.hostname);
	println!("sending: \n\n{}", response);
	let mut s = &instream;
	s.write(response.as_bytes()).unwrap(); // tell client the connection is made

	// need to work out the best way to do this???
	// there is mio crate...
	// can we even do this in Rust yet???
	while ! disconnected {
		disconnected = talk_to_me(&instream, &outstream);
	}
}

fn check_headers(buffer: [u8;REQUEST_LEN], headers: &mut Header) -> bool
{
	let mut i = 0;

	while buffer[i] != '\0' as u8
	{
		print!("{}", buffer[i] as char);
		i+=1;
	}
	print!("\n");

	if headers.hostname.is_empty()
	{
		headers.hostname = substr(buffer, "Host: ", '\r' as u8);
	}

	if headers.connection.is_empty()
	{
		headers.connection = substr(buffer, "Connection: ", '\r' as u8);
	}

	if headers.proxy.is_empty()
	{
		headers.proxy = substr(buffer, "Proxy-Connection: ", '\r' as u8);
	}

	if headers.agent.is_empty()
	{
		headers.agent = substr(buffer, "User-Agent: ", '\r' as u8);
	}

	if ! headers.hostname.is_empty() && ! headers.connection.is_empty()
		&& ! headers.proxy.is_empty() && ! headers.agent.is_empty()
	{

		return true;
	}

	return false;
}

fn request_headers(mut instream: &TcpStream, headers: &mut Header)
{
	 loop
	{
		let mut buffer = [0u8; REQUEST_LEN];
		let mut byte = [0u8; 1];
		let mut len = 0;

		while byte[0] as char != '\n'
		{
			let bytes = instream.read(&mut byte).unwrap();
			buffer[len] = byte[0];
			len += bytes;
		}

		buffer[len] = '\0' as u8;

		if check_headers(buffer, headers) && len == 2
		{
			let mut i = 0;

			while i < REQUEST_LEN
			{
				buffer[i] = 0;
				i += 1;
			}
			return;
		}
	}

}

fn request_method(mut instream: &TcpStream) -> String
{
	let mut byte = [0u8;1];

	let mut method: String = String::new();

	// bit better for now it'll do!
	while byte[0] as char != ' '
	{
		instream.read(&mut byte).unwrap();
		if byte[0] as char != ' '
		{
			method.push(byte[0] as char);
		}
	}

	match method.as_ref()
	{
		"CONNECT" =>
		{
			return method;
		}

		"GET" | "POST" | "OPTIONS" | "HEAD" =>
		{
			return "".to_string();
			// all good do not return!!!
		}

		_ =>
		{
			return "".to_string();
		}
	}
}

fn proxy(stream: TcpStream) {
	let method = request_method(&stream);

	match method.as_ref()
	{
		"CONNECT" =>
		{
			let mut headers = Header::new();
			request_headers(&stream, &mut headers);

			http_connect_request(stream, headers);
		}

		_ =>
		{
			println!("REQUEST UNKNOWN");
		}
	}
}

extern crate threadpool;
use threadpool::ThreadPool;

fn proxy_time(port: u16, threads: usize) {
	let ip = Ipv4Addr::new(127, 0, 0, 1);
	let host = SocketAddrV4::new(ip, port);
	let listener = TcpListener::bind(host).unwrap();

	let pool = ThreadPool::new(threads);

	for stream in listener.incoming()
	{
		match stream
		{
			Ok(stream) =>
			{
				pool.execute(move || { proxy(stream); });
			}

			Err(_) =>
			{
				println!("NET error");
				1 << 7;
			}
		}
	}

	drop (listener);
}

fn main () {
	let threads = 128;
	let port: u16 = 9998;

	proxy_time(port, threads);
	println!("Blocking all badness");
}

<|endoftext|>


<commit_before>extern crate arguments;
extern crate configuration;
extern crate random;
extern crate sql;
extern crate sqlite;
extern crate term;
extern crate time;

#[macro_use]
extern crate log;

#[macro_use]
extern crate streamer;

use configuration::format::TOML;
use log::LogLevel;
use streamer::{platform, schedule, system, traffic, workload};

pub use streamer::{Config, Error, Result};

pub type System = system::System<platform::Thermal,
                                 schedule::Compact,
                                 traffic::Fractal,
                                 workload::Random>;

pub type Increment = (system::Event, (platform::Profile, platform::Profile));

const USAGE: &'static str = "
Usage: streamer [options]

Options:
    --config <path>          Configuration file (required).
    --length <time>          Time span to simulate in seconds [default: 10].
    --output <path>          Output file for power and temperature profiles.

    --verbose                Display progress information.
    --help                   Display this message.
";

macro_rules! some(
    ($option:expr, $($arg:tt)*) => (match $option {
        Some(value) => value,
        _ => raise!($($arg)*),
    });
);

mod logger;
mod output;

use output::Output;

fn main() {
    start().unwrap_or_else(|error| fail(error));
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));
    if arguments.get::<bool>("help").unwrap_or(false) {
        help();
    }
    if arguments.get::<bool>("verbose").unwrap_or(false) {
        logger::setup(LogLevel::Info);
    } else {
        logger::setup(LogLevel::Warn);
    }

    let config = ok!(TOML::open(some!(arguments.get::<String>("config"),
                                      "a configuration file is required")));

    let mut system = try!(construct_system(&config));
    let mut output = try!(output::new(&system, arguments.get::<String>("output")));

    let length = arguments.get::<f64>("length").unwrap_or(10.0);
    info!(target: "Streamer", "Simulating {} seconds...", length);
    let start = time::now();

    while let Some((event, (power, temperature))) = system.next() {
        let last = event.time > length;
        info!(target: "Streamer", "{} | {:2} queued", event,
              system.statistics().arrived - system.statistics().started);
        try!(output.next((event, (power, temperature))));
        if last {
            break;
        }
    }

    let elapsed = time::now() - start;
    info!(target: "Streamer", "Well done in {:.2} seconds.",
          elapsed.num_milliseconds() as f64 / 1000.0);

    Ok(())
}

fn construct_system(config: &Config) -> Result<System> {
    use streamer::platform::Platform;

    let source = {
        let seed = config.get::<i64>("seed").map(|&seed| seed as u64).unwrap_or(0);
        let seed = if seed > 0 { seed } else { time::now().to_timespec().sec as u64 };
        let seed = [0x12345678 & seed, 0x87654321 & seed];
        random::default().seed(seed)
    };

    macro_rules! branch(
        ($name:expr) => (config.branch($name).unwrap_or_else(|| Config::new()));
    );

    let platform = try!(platform::Thermal::new(&branch!("platform")));
    let schedule = try!(schedule::Compact::new(&branch!("schedule"), platform.elements()));
    let traffic = try!(traffic::Fractal::new(&branch!("traffic"), &source));
    let workload = try!(workload::Random::new(&branch!("workload"), &source));

    System::new(platform, schedule, traffic, workload)
}

fn help() -> ! {
    println!("{}", USAGE.trim());
    std::process::exit(0);
}

#[allow(unused_must_use)]
fn fail(error: Error) -> ! {
    use std::io::{stderr, Write};
    if let Some(mut output) = term::stderr() {
        output.fg(term::color::RED);
        output.write_all(format!("Error: {}.\n", error).as_bytes());
    }
    std::process::exit(1);
}
<commit_msg>Remove a redundant macro<commit_after>extern crate arguments;
extern crate configuration;
extern crate random;
extern crate sql;
extern crate sqlite;
extern crate term;
extern crate time;

#[macro_use]
extern crate log;

#[macro_use]
extern crate streamer;

use configuration::format::TOML;
use log::LogLevel;
use streamer::{platform, schedule, system, traffic, workload};

pub use streamer::{Config, Error, Result};

pub type System = system::System<platform::Thermal,
                                 schedule::Compact,
                                 traffic::Fractal,
                                 workload::Random>;

pub type Increment = (system::Event, (platform::Profile, platform::Profile));

const USAGE: &'static str = "
Usage: streamer [options]

Options:
    --config <path>          Configuration file (required).
    --length <time>          Time span to simulate in seconds [default: 10].
    --output <path>          Output file for power and temperature profiles.

    --verbose                Display progress information.
    --help                   Display this message.
";

mod logger;
mod output;

use output::Output;

fn main() {
    start().unwrap_or_else(|error| fail(error));
}

fn start() -> Result<()> {
    let arguments = ok!(arguments::parse(std::env::args()));
    if arguments.get::<bool>("help").unwrap_or(false) {
        help();
    }
    if arguments.get::<bool>("verbose").unwrap_or(false) {
        logger::setup(LogLevel::Info);
    } else {
        logger::setup(LogLevel::Warn);
    }

    let config = ok!(TOML::open(some!(arguments.get::<String>("config"),
                                      "a configuration file is required")));

    let mut system = try!(construct_system(&config));
    let mut output = try!(output::new(&system, arguments.get::<String>("output")));

    let length = arguments.get::<f64>("length").unwrap_or(10.0);
    info!(target: "Streamer", "Simulating {} seconds...", length);
    let start = time::now();

    while let Some((event, (power, temperature))) = system.next() {
        let last = event.time > length;
        info!(target: "Streamer", "{} | {:2} queued", event,
              system.statistics().arrived - system.statistics().started);
        try!(output.next((event, (power, temperature))));
        if last {
            break;
        }
    }

    let elapsed = time::now() - start;
    info!(target: "Streamer", "Well done in {:.2} seconds.",
          elapsed.num_milliseconds() as f64 / 1000.0);

    Ok(())
}

fn construct_system(config: &Config) -> Result<System> {
    use streamer::platform::Platform;

    let source = {
        let seed = config.get::<i64>("seed").map(|&seed| seed as u64).unwrap_or(0);
        let seed = if seed > 0 { seed } else { time::now().to_timespec().sec as u64 };
        let seed = [0x12345678 & seed, 0x87654321 & seed];
        random::default().seed(seed)
    };

    macro_rules! branch(
        ($name:expr) => (config.branch($name).unwrap_or_else(|| Config::new()));
    );

    let platform = try!(platform::Thermal::new(&branch!("platform")));
    let schedule = try!(schedule::Compact::new(&branch!("schedule"), platform.elements()));
    let traffic = try!(traffic::Fractal::new(&branch!("traffic"), &source));
    let workload = try!(workload::Random::new(&branch!("workload"), &source));

    System::new(platform, schedule, traffic, workload)
}

fn help() -> ! {
    println!("{}", USAGE.trim());
    std::process::exit(0);
}

#[allow(unused_must_use)]
fn fail(error: Error) -> ! {
    use std::io::{stderr, Write};
    if let Some(mut output) = term::stderr() {
        output.fg(term::color::RED);
        output.write_all(format!("Error: {}.\n", error).as_bytes());
    }
    std::process::exit(1);
}
<|endoftext|>


<commit_before>use super::Position;

pub struct Range {
    pub start: Position,
    pub end:   Position,
}

impl Range {
    pub fn is_valid(&self) -> bool {
        if self.start.line < self.end.line {
            true
        } else if self.start.line == self.end.line && self.start.offset < self.end.offset {
            true
        } else {
            false
        }
    }
}

pub struct LineRange {
    pub start: usize,
    pub end:   usize,
}

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

    #[test]
    fn range_is_valid_when_start_is_before_end() {
        let mut start = Position { line: 0, offset: 4 };
        let mut end = Position { line: 1, offset: 1 };
        let mut range = Range { start: start, end: end };

        assert!(range.is_valid());

        start = Position { line: 1, offset: 4 };
        end = Position { line: 1, offset: 5 };
        range = Range { start: start, end: end };

        assert!(range.is_valid());
    }

    #[test]
    fn range_is_invalid_when_start_is_equal_to_end() {
        let start = Position { line: 0, offset: 4 };
        let end = Position { line: 0, offset: 4 };
        let range = Range { start: start, end: end };

        assert!(!range.is_valid());
    }

    #[test]
    fn range_is_invalid_when_start_is_after_end() {
        let mut start = Position { line: 1, offset: 4 };
        let mut end = Position { line: 1, offset: 1 };
        let mut range = Range { start: start, end: end };

        assert!(!range.is_valid());

        start = Position { line: 2, offset: 4 };
        end = Position { line: 1, offset: 5 };
        range = Range { start: start, end: end };

        assert!(!range.is_valid());
    }
}
<commit_msg>Derive clone for range type.<commit_after>use super::Position;

#[derive(Clone)]
pub struct Range {
    pub start: Position,
    pub end:   Position,
}

impl Range {
    pub fn is_valid(&self) -> bool {
        if self.start.line < self.end.line {
            true
        } else if self.start.line == self.end.line && self.start.offset < self.end.offset {
            true
        } else {
            false
        }
    }
}

pub struct LineRange {
    pub start: usize,
    pub end:   usize,
}

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

    #[test]
    fn range_is_valid_when_start_is_before_end() {
        let mut start = Position { line: 0, offset: 4 };
        let mut end = Position { line: 1, offset: 1 };
        let mut range = Range { start: start, end: end };

        assert!(range.is_valid());

        start = Position { line: 1, offset: 4 };
        end = Position { line: 1, offset: 5 };
        range = Range { start: start, end: end };

        assert!(range.is_valid());
    }

    #[test]
    fn range_is_invalid_when_start_is_equal_to_end() {
        let start = Position { line: 0, offset: 4 };
        let end = Position { line: 0, offset: 4 };
        let range = Range { start: start, end: end };

        assert!(!range.is_valid());
    }

    #[test]
    fn range_is_invalid_when_start_is_after_end() {
        let mut start = Position { line: 1, offset: 4 };
        let mut end = Position { line: 1, offset: 1 };
        let mut range = Range { start: start, end: end };

        assert!(!range.is_valid());

        start = Position { line: 2, offset: 4 };
        end = Position { line: 1, offset: 5 };
        range = Range { start: start, end: end };

        assert!(!range.is_valid());
    }
}
<|endoftext|>


<commit_before>//! The memory module.
//! This module declares a single struct, the Memory Management Unit (MMU).
//! The MMU acts as the system bus, allowing components to communicate with each other, reaches
//! RAM, ROM, I/O registers and more.
use std::fmt;
use std::cell::Cell;

use jeebie::gpu::GPU;

/// The Memory Management Unit.
/// Provides access to all mapped memory in the system, including I/O and graphics.
pub struct MMU {
    pub loading_bios: Cell<bool>,
    data: [u8; 65536],
    gpu: GPU,
}

impl fmt::Debug for MMU {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "MMU 64k")
    }
}

impl MMU {
    pub fn new() -> MMU {
        MMU {
            loading_bios: Cell::new(true),
            data: [1; 65536],
            gpu: GPU::new(),
        }
    }

    /// reads a byte at the memory address specified
    pub fn read_b(&self, addr: u16) -> u8 {
        // when PC first reaches 0x100, the BIOS data is not addressable anymore.
        // using Cell sucks, but this is one of the few cases mentioned by official docs where
        // it is an option. Read is logically an immutable operation, but we need to make the
        // bios unaddressable after its first read.
        if self.loading_bios.get() && addr == 0x0100 {
            self.loading_bios.set(false);
        }

        match addr {
            // bios area, 256B long for regular gameboy.
            0...0x00FF if self.loading_bios.get() => unimplemented!(),
            // ROM0 area, this is banked memory, it will swap according to selected bank
            0x0000...0x3FFF if !self.loading_bios.get() => unimplemented!(),
            // ROM1 area, 16kB unbanked data
            0x4000...0x7FFF => unimplemented!(),
            // Graphics, 8kB VRAM
            0x8000...0x9FFF => self.gpu.read_vram((addr & 0x1FFF) as usize),
            // Switchable RAM bank, 8kB
            0xA000...0xBFFF => {
                // TODO: handle RAM banks
                self.data[addr as usize]
            }
            // Internal RAM, 8kB
            0xC000...0xDFFF => self.data[addr as usize],
            // Echo of internal RAM, this is less than 8k, up to 0xFDFF,
            0xE000...0xFDFF => self.data[(addr - 0x2000) as usize],
            // Sprite attribute memory, 160B
            0xFE00...0xFE9F => self.gpu.read_oam((addr - 0xFE00) as usize),
            // empty
            0xFEA0...0xFEFF | 0xFF4C...0xFF7F => 0,
            // I/O ports
            0xFF00...0xFF4B => 0,
            // High RAM (zero page), used with LDH instructions
            0xFF80...0xFFFE => 0,
            // Interrupt Enable register
            0xFFFF => 0,

            _ => panic!("tried to write at unkown address: {:4X}", addr),
        }
    }

    pub fn write_b(&mut self, addr: u16, data: u8) {
        // TODO: mapping like read
        self.data[addr as usize] = data;
    }
}
<commit_msg>Updated memory map<commit_after>//! The memory module.
//! This module declares a single struct, the Memory Management Unit (MMU).
//! The MMU acts as the system bus, allowing components to communicate with each other, reaches
//! RAM, ROM, I/O registers and more.
use std::fmt;
use std::cell::Cell;

use jeebie::gpu::GPU;

/// The Memory Management Unit.
/// Provides access to all mapped memory in the system, including I/O and graphics.
pub struct MMU {
    pub loading_bios: Cell<bool>,
    data: [u8; 65536],
    gpu: GPU,
}

impl fmt::Debug for MMU {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "MMU 64k")
    }
}

impl MMU {
    pub fn new() -> MMU {
        MMU {
            loading_bios: Cell::new(true),
            data: [0; 65536],
            gpu: GPU::new(),
        }
    }

    /// reads a byte at the memory address specified
    pub fn read_b(&self, addr: u16) -> u8 {
        // when PC first reaches 0x100, the BIOS data is not addressable anymore.
        // using Cell sucks, but this is one of the few cases mentioned by official docs where
        // it is an option. Read is logically an immutable operation, but we need to make the
        // bios unaddressable after its first read.
        if self.loading_bios.get() && addr == 0x0100 {
            self.loading_bios.set(false);
        }

        match addr {
            // bios area, 256B long for regular gameboy.
            0...0x00FF if self.loading_bios.get() => unimplemented!(),
            // ROM0 area, this is banked memory, it will swap according to selected bank
            0x0000...0x3FFF if !self.loading_bios.get() => unimplemented!(),
            // ROM1 area, 16kB unbanked data
            0x4000...0x7FFF => unimplemented!(),
            // Graphics, 8kB VRAM
            0x8000...0x9FFF => self.gpu.read_vram((addr & 0x1FFF) as usize),
            // Switchable RAM bank, 8kB
            0xA000...0xBFFF => {
                // TODO: handle RAM banks
                self.data[addr as usize]
            }
            // Internal RAM, 8kB
            0xC000...0xDFFF => self.data[addr as usize],
            // Echo of internal RAM, this is less than 8k, up to 0xFDFF,
            0xE000...0xFDFF => self.data[(addr - 0x2000) as usize],
            // Sprite attribute memory, 160B
            0xFE00...0xFE9F => self.gpu.read_oam((addr - 0xFE00) as usize),
            // empty
            0xFEA0...0xFEFF | 0xFF4C...0xFF7F => 0,
            // I/O ports
            0xFF00...0xFF4B => {
                match addr & 0xFF {
                    0x40 | 0x42 | 0x43 | 0x44 | 0x47 => self.gpu.read_register(addr as usize),
                    _ => 0,
                }
            },
            // High RAM (zero page), used with LDH instructions
            0xFF80...0xFFFE => 0,
            // Interrupt Enable register
            0xFFFF => 0,

            _ => panic!("tried to read at unknown address: {:4x}", addr),
        }
    }

    pub fn write_b(&mut self, addr: u16, data: u8) {
        match addr {
            // bios area, 256B long for regular gameboy.
            0...0x00FF if self.loading_bios.get() => unimplemented!(),
            // ROM0 area, this is banked memory, it will swap according to selected bank
            0x0000...0x3FFF if !self.loading_bios.get() => unimplemented!(),
            // ROM1 area, 16kB unbanked data
            0x4000...0x7FFF => unimplemented!(),
            // Graphics, 8kB VRAM
            0x8000...0x9FFF => self.gpu.write_vram((addr & 0x1FFF) as usize, data),
            // Switchable RAM bank, 8kB
            0xA000...0xBFFF => {
                // TODO: handle RAM banks
                self.data[addr as usize] = data;
            }
            // Internal RAM, 8kB
            0xC000...0xDFFF => {
                self.data[addr as usize] = data;
            },
            // Echo of internal RAM, this is less than 8k, up to 0xFDFF,
            0xE000...0xFDFF => {
                self.data[(addr - 0x2000) as usize] = data;
            },
            // Sprite attribute memory, 160B
            0xFE00...0xFE9F => {
                self.gpu.write_oam((addr - 0xFE00) as usize, data);
            }
            // empty
            0xFEA0...0xFEFF | 0xFF4C...0xFF7F => {},
            // I/O ports
            0xFF00...0xFF4B => {
                match addr & 0xFF {
                    0x40 | 0x42 | 0x43 | 0x44 | 0x47 => self.gpu.write_register(addr as usize, data),
                    _ => {},
                }
            },
            // High RAM (zero page), used with LDH instructions
            0xFF80...0xFFFE => unimplemented!(),
            // Interrupt Enable register
            0xFFFF => unimplemented!(),

            _ => panic!("tried to write at unknown address: {:4x}", addr),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 Dasein Phaos aka. Luxko
//
// 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 comptr::ComPtr;
use winapi::{ID3D12CommandList, ID3D12GraphicsCommandList};
use error::WinError;

bitflags!{
    /// type of a `CommandList`
    #[repr(C)]
    pub struct CommandListType: u32 {
        /// direct list doesn't inherit any GPU state.
        const COMMAND_LIST_TYPE_DIRECT = 0;
        /// bundle inherits all GPU state (except PSO and primitive topology)
        /// from the direct list, where it must be opearated on
        const COMMAND_LIST_TYPE_BUNDLE = 1;
        /// computing command list
        const COMMAND_LIST_TYPE_COMPUT = 2;
        /// copying(drawing) command list
        const COMMAND_LIST_TYPE_COPY = 3;
    }
}

impl Default for CommandListType {
    #[inline]
    fn default() -> Self {
        COMMAND_LIST_TYPE_DIRECT
    }
}

/// a list of graphics commands, including execution intrumenting APIs etc.
pub struct GraphicsCommandList {
    pub ptr: ComPtr<ID3D12GraphicsCommandList>,
}
<commit_msg>fix typo<commit_after>// Copyright 2017 Dasein Phaos aka. Luxko
//
// 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 comptr::ComPtr;
use winapi::{ID3D12CommandList, ID3D12GraphicsCommandList};
use error::WinError;

bitflags!{
    /// type of a `CommandList`
    #[repr(C)]
    pub struct CommandListType: u32 {
        /// direct list doesn't inherit any GPU state.
        const COMMAND_LIST_TYPE_DIRECT = 0;
        /// bundle inherits all GPU state (except PSO and primitive topology)
        /// from the direct list, where it must be opearated on
        const COMMAND_LIST_TYPE_BUNDLE = 1;
        /// computing command list
        const COMMAND_LIST_TYPE_COMPUTE = 2;
        /// copying(drawing) command list
        const COMMAND_LIST_TYPE_COPY = 3;
    }
}

impl Default for CommandListType {
    #[inline]
    fn default() -> Self {
        COMMAND_LIST_TYPE_DIRECT
    }
}

/// a list of graphics commands, including execution intrumenting APIs etc.
pub struct GraphicsCommandList {
    pub ptr: ComPtr<ID3D12GraphicsCommandList>,
}
<|endoftext|>


<commit_before>#![crate_id = "splice#0.1-pre"]
#![license = "MIT"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

use std::io::{TcpStream, IoResult};
use std::io::net::ip::{SocketAddr, Ipv4Addr};

pub mod conf;
pub mod proto;

pub fn connect(addr: &str, port: u16) -> IoResult<(Upstream, Downstream)> {
    let stream = try!(TcpStream::connect(addr, port));
    Ok((
        Upstream {
            sock: stream.clone()
        },
        Downstream {
            sock: stream
        }
    ))
}

pub struct Upstream {
    sock: TcpStream
}

impl Drop for Upstream {
    fn drop(&mut self) {
        self.sock.close_write();
    }
}

impl Upstream {
    pub fn send_request(&self, req: &Request) -> IoResult<()> {
        Ok(())
    }
}

pub struct Downstream {
    sock: TcpStream
}

impl Drop for Downstream {
    fn drop(&mut self) {
        self.sock.close_read();
    }
}

impl Downstream {
    pub fn get_response(&self) -> Option<Response> {
        None
    }
}

type Object = uint;

pub enum Response {
    BufferOpened(Object, Buffer),
    BufferChanged(Object, Differ),
    ConnectionClosed,
    Empty,
    Unknown
}

pub struct Buffer {
    path:   ~str,
    id:     Object,
    start:  uint,
    buf:    Vec<String>
}

impl Buffer {
    pub fn apply_diff(&mut self, diff: &Differ) {
    }
}

pub struct Differ;
pub struct Request;
<commit_msg>Make libsplice connections negotiate<commit_after>#![crate_id = "splice#0.1-pre"]
#![license = "MIT"]
#![crate_type = "rlib"]
#![crate_type = "dylib"]

use std::io::{TcpStream, IoResult};
use std::io::net::ip::{SocketAddr, Ipv4Addr};

pub mod conf;
pub mod proto;

pub fn connect(addr: &str, port: u16) -> Result<(Upstream, Downstream), proto::NegotiateError> {
     match TcpStream::connect(addr, port) {
        Ok(mut stream) => {
            match proto::negotiate(&mut stream).err() {
                Some(e) => Err(e),
                None => Ok((
                    Upstream {
                        sock: stream.clone()
                    },
                    Downstream {
                        sock: stream
                    }
                )),
            }
        },
        Err(..) => Err(proto::NegotiateFailed),
    }
}

pub struct Upstream {
    sock: TcpStream
}

impl Drop for Upstream {
    fn drop(&mut self) {
        self.sock.close_write();
    }
}

impl Upstream {
    pub fn send_request(&self, req: &Request) -> IoResult<()> {
        Ok(())
    }
}

pub struct Downstream {
    sock: TcpStream
}

impl Drop for Downstream {
    fn drop(&mut self) {
        self.sock.close_read();
    }
}

impl Downstream {
    pub fn get_response(&self) -> Option<Response> {
        None
    }
}

type Object = uint;

pub enum Response {
    BufferOpened(Object, Buffer),
    BufferChanged(Object, Differ),
    ConnectionClosed,
    Empty,
    Unknown
}

pub struct Buffer {
    path:   ~str,
    id:     Object,
    start:  uint,
    buf:    Vec<String>
}

impl Buffer {
    pub fn apply_diff(&mut self, diff: &Differ) {
    }
}

pub struct Differ;
pub struct Request;
<|endoftext|>


<commit_before>pub static RUSTUP_HELP: &'static str =
r"DISCUSSION:
    rustup installs The Rust Programming Language from the official
    release channels, enabling you to easily switch between stable,
    beta, and nightly compilers and keep them updated. It makes
    cross-compiling simpler with binary builds of the standard library
    for common platforms.

    If you are new to Rust consider running `rustup doc --book` to
    learn Rust.";

pub static SHOW_HELP: &'static str =
r"DISCUSSION:
    Shows the name of the active toolchain and the version of `rustc`.

    If the active toolchain has installed support for additional
    compilation targets, then they are listed as well.

    If there are multiple toolchains installed then all installed
    toolchains are listed as well.";

pub static UPDATE_HELP: &'static str =
r"DISCUSSION:
    With no toolchain specified, the `update` command updates each of
    the installed toolchains from the official release channels, then
    updates rustup itself.

    If given a toolchain argument then `update` updates that
    toolchain, the same as `rustup toolchain install`.

    'toolchain' specifies a toolchain name, such as 'stable',
    'nightly', or '1.8.0'. For more information see `rustup help
    toolchain`.";

pub static TOOLCHAIN_INSTALL_HELP: &'static str =
r"DISCUSSION:
    Installs a specific rust toolchain.

    The 'install' command is an alias for 'rustup update <toolchain>'.

    'toolchain' specifies a toolchain name, such as 'stable',
    'nightly', or '1.8.0'. For more information see `rustup help
    toolchain`.";

pub static DEFAULT_HELP: &'static str =
r"DISCUSSION:
    Sets the default toolchain to the one specified. If the toolchain
    is not already installed then it is installed first.";

pub static TOOLCHAIN_HELP: &'static str =
r"DISCUSSION:
    Many `rustup` commands deal with *toolchains*, a single
    installation of the Rust compiler. `rustup` supports multiple
    types of toolchains. The most basic track the official release
    channels: 'stable', 'beta' and 'nightly'; but `rustup` can also
    install toolchains from the official archives, for alternate host
    platforms, and from local builds.

    Standard release channel toolchain names have the following form:

        <channel>[-<date>][-<host>]

        <channel>       = stable|beta|nightly|<version>
        <date>          = YYYY-MM-DD
        <host>          = <target-triple>

    'channel' is either a named release channel or an explicit version
    number, such as '1.8.0'. Channel names can be optionally appended
    with an archive date, as in 'nightly-2014-12-18', in which case
    the toolchain is downloaded from the archive for that date.

    Finally, the host may be specified as a target triple. This is
    most useful for installing a 32-bit compiler on a 64-bit platform,
    or for installing the [MSVC-based toolchain] on Windows. For
    example:

        rustup toolchain install stable-x86_64-pc-windows-msvc

    For convenience, elements of the target triple that are omitted
    will be inferred, so the above could be written:

        $ rustup default stable-msvc

    Toolchain names that don't name a channel instead can be used to
    name custom toolchains with the `rustup toolchain link` command.";

pub static OVERRIDE_HELP: &'static str =
r"DISCUSSION:
    Overrides configure rustup to use a specific toolchain when
    running in a specific directory.

    Directories can be assigned their own Rust toolchain with `rustup
    override`. When a directory has an override then any time `rustc`
    or `cargo` is run inside that directory, or one of its child
    directories, the override toolchain will be invoked.

    To pin to a specific nightly:

        rustup override set nightly-2014-12-18

    Or a specific stable release:

        rustup override set 1.0.0

    To see the active toolchain use `rustup show`. To remove the
    override and use the default toolchain again, `rustup override
    unset`.";

pub static OVERRIDE_UNSET_HELP: &'static str =
r"DISCUSSION:
    If `--path` argument is present, removes the override toolchain
    for the specified directory. If `--nonexistent` argument is
    present, removes the override toolchain for all nonexistent
    directories. Otherwise, removes the override toolchain for the
    current directory.";

pub static RUN_HELP: &'static str =
r"DISCUSSION:
    Configures an environment to use the given toolchain and then runs
    the specified program. The command may be any program, not just
    rustc or cargo. This can be used for testing arbitrary toolchains
    without setting an override.

    Commands explicitly proxied by `rustup` (such as `rustc` and
    `cargo`) also have a shorthand for this available. The toolchain
    can be set by using `+toolchain` as the first argument. These are
    equivalent:

        cargo +nightly build

        rustup run nightly cargo build";

pub static DOC_HELP: &'static str =
r"DISCUSSION:
    Opens the documentation for the currently active toolchain with
    the default browser.

    By default, it opens the documentation index. Use the various
    flags to open specific pieces of documentation.";

pub static COMPLETIONS_HELP: &'static str =
r"DISCUSSION:
    One can generate a completion script for `rustup` that is
    compatible with a given shell. The script is output on `stdout`
    allowing one to re-direct the output to the file of their
    choosing. Where you place the file will depend on which shell, and
    which operating system you are using. Your particular
    configuration may also determine where these scripts need to be
    placed.

    Here are some common set ups for the three supported shells under
    Unix and similar operating systems (such as GNU/Linux).

    BASH:

    Completion files are commonly stored in `/etc/bash_completion.d/`

    Run the command:

    `rustup completions bash > /etc/bash_completion.d/rustup.bash-completion`

    This installs the completion script. You may have to log out and
    log back in to your shell session for the changes to take affect.

    BASH (macOS/Homebrew):

    Homebrew stores bash completion files within the Homebrew directory.
    With the `bash-completion` brew formula installed, run the command:

    `rustup completions bash > $(brew --prefix)/etc/bash_completion.d/rustup.bash-completion`

    FISH:

    Fish completion files are commonly stored in
    `$HOME/.config/fish/completions`

    Run the command:
    `rustup completions fish > ~/.config/fish/completions/rustup.fish`

    This installs the completion script. You may have to log out and
    log back in to your shell session for the changes to take affect.

    ZSH:

    ZSH completions are commonly stored in any directory listed in
    your `$fpath` variable. To use these completions, you must either
    add the generated script to one of those directories, or add your
    own to this list.

    Adding a custom directory is often the safest best if you're
    unsure of which directory to use. First create the directory, for
    this example we'll create a hidden directory inside our `$HOME`
    directory

    `mkdir ~/.zfunc`

    Then add the following lines to your `.zshrc` just before
    `compinit`

    `fpath+=~/.zfunc`

    Now you can install the completions script using the following
    command

    `rustup completions zsh > ~/.zfunc/_rustup`

    You must then either log out and log back in, or simply run

    `exec zsh`

    For the new completions to take affect.

    CUSTOM LOCATIONS:

    Alternatively, you could save these files to the place of your
    choosing, such as a custom directory inside your $HOME. Doing so
    will require you to add the proper directives, such as `source`ing
    inside your login script. Consult your shells documentation for
    how to add such directives.

    POWERSHELL:

    The powershell completion scripts require PowerShell v5.0+ (which
    comes Windows 10, but can be downloaded separately for windows 7
    or 8.1).

    First, check if a profile has already been set

    `PS C:\> Test-Path $profile`

    If the above command returns `False` run the following

    `PS C:\> New-Item -path $profile -type file --force`

    Now open the file provided by `$profile` (if you used the
    `New-Item` command it will be
    `%USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`

    Next, we either save the completions file into our profile, or
    into a separate file and source it inside our profile. To save the
    completions into our profile simply use

    `PS C:\> rustup completions powershell >> %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`";
<commit_msg>Fixes a typo in PowerShell completion script help<commit_after>pub static RUSTUP_HELP: &'static str =
r"DISCUSSION:
    rustup installs The Rust Programming Language from the official
    release channels, enabling you to easily switch between stable,
    beta, and nightly compilers and keep them updated. It makes
    cross-compiling simpler with binary builds of the standard library
    for common platforms.

    If you are new to Rust consider running `rustup doc --book` to
    learn Rust.";

pub static SHOW_HELP: &'static str =
r"DISCUSSION:
    Shows the name of the active toolchain and the version of `rustc`.

    If the active toolchain has installed support for additional
    compilation targets, then they are listed as well.

    If there are multiple toolchains installed then all installed
    toolchains are listed as well.";

pub static UPDATE_HELP: &'static str =
r"DISCUSSION:
    With no toolchain specified, the `update` command updates each of
    the installed toolchains from the official release channels, then
    updates rustup itself.

    If given a toolchain argument then `update` updates that
    toolchain, the same as `rustup toolchain install`.

    'toolchain' specifies a toolchain name, such as 'stable',
    'nightly', or '1.8.0'. For more information see `rustup help
    toolchain`.";

pub static TOOLCHAIN_INSTALL_HELP: &'static str =
r"DISCUSSION:
    Installs a specific rust toolchain.

    The 'install' command is an alias for 'rustup update <toolchain>'.

    'toolchain' specifies a toolchain name, such as 'stable',
    'nightly', or '1.8.0'. For more information see `rustup help
    toolchain`.";

pub static DEFAULT_HELP: &'static str =
r"DISCUSSION:
    Sets the default toolchain to the one specified. If the toolchain
    is not already installed then it is installed first.";

pub static TOOLCHAIN_HELP: &'static str =
r"DISCUSSION:
    Many `rustup` commands deal with *toolchains*, a single
    installation of the Rust compiler. `rustup` supports multiple
    types of toolchains. The most basic track the official release
    channels: 'stable', 'beta' and 'nightly'; but `rustup` can also
    install toolchains from the official archives, for alternate host
    platforms, and from local builds.

    Standard release channel toolchain names have the following form:

        <channel>[-<date>][-<host>]

        <channel>       = stable|beta|nightly|<version>
        <date>          = YYYY-MM-DD
        <host>          = <target-triple>

    'channel' is either a named release channel or an explicit version
    number, such as '1.8.0'. Channel names can be optionally appended
    with an archive date, as in 'nightly-2014-12-18', in which case
    the toolchain is downloaded from the archive for that date.

    Finally, the host may be specified as a target triple. This is
    most useful for installing a 32-bit compiler on a 64-bit platform,
    or for installing the [MSVC-based toolchain] on Windows. For
    example:

        rustup toolchain install stable-x86_64-pc-windows-msvc

    For convenience, elements of the target triple that are omitted
    will be inferred, so the above could be written:

        $ rustup default stable-msvc

    Toolchain names that don't name a channel instead can be used to
    name custom toolchains with the `rustup toolchain link` command.";

pub static OVERRIDE_HELP: &'static str =
r"DISCUSSION:
    Overrides configure rustup to use a specific toolchain when
    running in a specific directory.

    Directories can be assigned their own Rust toolchain with `rustup
    override`. When a directory has an override then any time `rustc`
    or `cargo` is run inside that directory, or one of its child
    directories, the override toolchain will be invoked.

    To pin to a specific nightly:

        rustup override set nightly-2014-12-18

    Or a specific stable release:

        rustup override set 1.0.0

    To see the active toolchain use `rustup show`. To remove the
    override and use the default toolchain again, `rustup override
    unset`.";

pub static OVERRIDE_UNSET_HELP: &'static str =
r"DISCUSSION:
    If `--path` argument is present, removes the override toolchain
    for the specified directory. If `--nonexistent` argument is
    present, removes the override toolchain for all nonexistent
    directories. Otherwise, removes the override toolchain for the
    current directory.";

pub static RUN_HELP: &'static str =
r"DISCUSSION:
    Configures an environment to use the given toolchain and then runs
    the specified program. The command may be any program, not just
    rustc or cargo. This can be used for testing arbitrary toolchains
    without setting an override.

    Commands explicitly proxied by `rustup` (such as `rustc` and
    `cargo`) also have a shorthand for this available. The toolchain
    can be set by using `+toolchain` as the first argument. These are
    equivalent:

        cargo +nightly build

        rustup run nightly cargo build";

pub static DOC_HELP: &'static str =
r"DISCUSSION:
    Opens the documentation for the currently active toolchain with
    the default browser.

    By default, it opens the documentation index. Use the various
    flags to open specific pieces of documentation.";

pub static COMPLETIONS_HELP: &'static str =
r"DISCUSSION:
    One can generate a completion script for `rustup` that is
    compatible with a given shell. The script is output on `stdout`
    allowing one to re-direct the output to the file of their
    choosing. Where you place the file will depend on which shell, and
    which operating system you are using. Your particular
    configuration may also determine where these scripts need to be
    placed.

    Here are some common set ups for the three supported shells under
    Unix and similar operating systems (such as GNU/Linux).

    BASH:

    Completion files are commonly stored in `/etc/bash_completion.d/`

    Run the command:

    `rustup completions bash > /etc/bash_completion.d/rustup.bash-completion`

    This installs the completion script. You may have to log out and
    log back in to your shell session for the changes to take affect.

    BASH (macOS/Homebrew):

    Homebrew stores bash completion files within the Homebrew directory.
    With the `bash-completion` brew formula installed, run the command:

    `rustup completions bash > $(brew --prefix)/etc/bash_completion.d/rustup.bash-completion`

    FISH:

    Fish completion files are commonly stored in
    `$HOME/.config/fish/completions`

    Run the command:
    `rustup completions fish > ~/.config/fish/completions/rustup.fish`

    This installs the completion script. You may have to log out and
    log back in to your shell session for the changes to take affect.

    ZSH:

    ZSH completions are commonly stored in any directory listed in
    your `$fpath` variable. To use these completions, you must either
    add the generated script to one of those directories, or add your
    own to this list.

    Adding a custom directory is often the safest best if you're
    unsure of which directory to use. First create the directory, for
    this example we'll create a hidden directory inside our `$HOME`
    directory

    `mkdir ~/.zfunc`

    Then add the following lines to your `.zshrc` just before
    `compinit`

    `fpath+=~/.zfunc`

    Now you can install the completions script using the following
    command

    `rustup completions zsh > ~/.zfunc/_rustup`

    You must then either log out and log back in, or simply run

    `exec zsh`

    For the new completions to take affect.

    CUSTOM LOCATIONS:

    Alternatively, you could save these files to the place of your
    choosing, such as a custom directory inside your $HOME. Doing so
    will require you to add the proper directives, such as `source`ing
    inside your login script. Consult your shells documentation for
    how to add such directives.

    POWERSHELL:

    The powershell completion scripts require PowerShell v5.0+ (which
    comes Windows 10, but can be downloaded separately for windows 7
    or 8.1).

    First, check if a profile has already been set

    `PS C:\> Test-Path $profile`

    If the above command returns `False` run the following

    `PS C:\> New-Item -path $profile -type file -force`

    Now open the file provided by `$profile` (if you used the
    `New-Item` command it will be
    `%USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`

    Next, we either save the completions file into our profile, or
    into a separate file and source it inside our profile. To save the
    completions into our profile simply use

    `PS C:\> rustup completions powershell >> %USERPROFILE%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1`";
<|endoftext|>


<commit_before>use std::{fmt, iter};
use std::rc::Rc;
use std::fmt::Write;

use seax::compiler_tools::ForkTable;

pub mod ast;
pub mod types;

use ast::*;
use self::types::{Annotated, Type};

/// A symbol table is a `ForkTable` mapping `String`s to `Type` annotations.
///
/// This table should be forked upon entering a new scope.
pub type SymbolTable<'a> = ForkTable<'a, String, Type>;

macro_rules! indent {
    ($to:expr) => ( iter::repeat('\t')
                        .take($to)
                        .collect::<String>() )
}

/// Trait for a node in the abstract syntax tree.
///
/// This provides a visitor method for semantic analysis (which may be split
/// into multiple transforms later), and a method for formatting the AST node
/// as an S-expression.
pub trait ASTNode: Sized {

    /// Pretty-print the AST node as an S-expression at the desired
    /// indentation level.
    ///
    /// Note that this prints the desugared form and may not be a perfect
    /// match for the original source code.
    fn to_sexpr(&self, level: usize) -> String;

    /// Analyse this node & annotate it with the appropriate type state.
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self>;

}

impl ASTNode for Form {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String {
        match self {
            &Form::Define(ref form) => form.to_sexpr(level),
        }
    }

    #[allow(unused_variables)]
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for Ident {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String { self.value.clone() }

    #[allow(unused_variables)]
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for DefForm {

    fn to_sexpr(&self, level: usize) -> String {
        match *self {
            DefForm::TopLevel { ref name, ref annot, ref value } =>
                format!("{}(define {} {} {})", indent!(level),
                    name.to_sexpr(level),
                    annot.to_sexpr(level),
                    value.to_sexpr(level+1)
                    ),
            DefForm::Function { ref name, ref annot, ref formals, ref body } =>
                format!("{}(define {} {} {}\n{})", indent!(level),
                    name.to_sexpr(level),
                    annot.to_sexpr(level),
                    formals.iter().fold(String::new(), |mut s, f| {
                        s.push_str(&f.to_sexpr(level)); s
                        }),
                    body.to_sexpr(level + 1)
                    )
        }
    }

    #[allow(unused_variables)]
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for Formal {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String {
        format!("{}: {}", *(self.name), *(self.annot))
    }

    #[allow(unused_variables)]
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}
<commit_msg>Renamed `ASTNode::analyze()` to `annotate_types()`, add docs<commit_after>use std::{fmt, iter};
use std::rc::Rc;
use std::fmt::Write;

use seax::compiler_tools::ForkTable;

pub mod ast;
pub mod types;

use ast::*;
use self::types::{Annotated, Type};

/// A symbol table is a `ForkTable` mapping `String`s to `Type` annotations.
///
/// This table should be forked upon entering a new scope.
pub type SymbolTable<'a> = ForkTable<'a, String, Type>;

macro_rules! indent {
    ($to:expr) => ( iter::repeat('\t')
                        .take($to)
                        .collect::<String>() )
}

/// Trait for a node in the abstract syntax tree.
///
/// This provides a visitor method for semantic analysis (which may be split
/// into multiple transforms later), and a method for formatting the AST node
/// as an S-expression.
pub trait ASTNode: Sized {

    /// Pretty-print the AST node as an S-expression at the desired
    /// indentation level.
    ///
    /// Note that this prints the desugared form and may not be a perfect
    /// match for the original source code.
    fn to_sexpr(&self, level: usize) -> String;

    /// Analyse this node & annotate it with the appropriate type state.
    ///
    /// The `Annotated` type stores a reference to an AST node along with
    /// the definitions visible at that node's scope.
    ///
    /// Essentially, this transforms our early IR (where type information
    /// is just stored in strings from the source program) into a working
    /// representation where types and symbol definitions are encoded in a
    /// way the compiler can analyze.
    fn annotate_types<'a>(self, scope: SymbolTable) -> Annotated<'a, Self>;

}

impl ASTNode for Form {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String {
        match self {
            &Form::Define(ref form) => form.to_sexpr(level),
        }
    }

    #[allow(unused_variables)]
    fn analyze<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for Ident {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String { self.value.clone() }

    #[allow(unused_variables)]
    fn annotate_types<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for DefForm {

    fn to_sexpr(&self, level: usize) -> String {
        match *self {
            DefForm::TopLevel { ref name, ref annot, ref value } =>
                format!("{}(define {} {} {})", indent!(level),
                    name.to_sexpr(level),
                    annot.to_sexpr(level),
                    value.to_sexpr(level+1)
                    ),
            DefForm::Function { ref name, ref annot, ref formals, ref body } =>
                format!("{}(define {} {} {}\n{})", indent!(level),
                    name.to_sexpr(level),
                    annot.to_sexpr(level),
                    formals.iter().fold(String::new(), |mut s, f| {
                        s.push_str(&f.to_sexpr(level)); s
                        }),
                    body.to_sexpr(level + 1)
                    )
        }
    }

    #[allow(unused_variables)]
    fn annotate_types<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}

impl ASTNode for Formal {
    #[allow(unused_variables)]
    fn to_sexpr(&self, level: usize) -> String {
        format!("{}: {}", *(self.name), *(self.annot))
    }

    #[allow(unused_variables)]
    fn annotate_types<'a>(self, scope: SymbolTable) -> Annotated<'a, Self> {
        unimplemented!() //TODO: implement
    }

}
<|endoftext|>


<commit_before>// Copyright 2017 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.

#![feature(global_asm)]
#![feature(naked_functions)]

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
global_asm!(r#"
    .global foo
foo:
    ret
"#);

extern {
    fn foo();
}

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
fn main() { unsafe { foo(); } }

#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
fn main() {}
<commit_msg>Comply with windows symbol name conventions<commit_after>// Copyright 2017 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.

#![feature(global_asm)]
#![feature(naked_functions)]

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
global_asm!(r#"
    .global foo
    .global _foo
foo:
_foo:
    ret
"#);

extern {
    fn foo();
}

#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
fn main() { unsafe { foo(); } }

#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
fn main() {}
<|endoftext|>


<commit_before>use std::str;
use types::{Frequency, Field, Message, Enumerator, MessageOrEnum, FileDescriptor, Syntax};
use nom::{multispace, digit};

fn is_word(b: u8) -> bool {
    match b {
        b'a'...b'z' | b'A'...b'Z' | b'0'...b'9' | b'_' => true,
        _ => false
    }
}

named!(word<&str>, map_res!(take_while!(is_word), str::from_utf8));

named!(comment<()>, do_parse!(tag!("//") >> take_until_and_consume!("\n") >> ()));

/// word break: multispace or comment
named!(br<()>, alt!(map!(multispace, |_| ()) | comment));

named!(syntax<Syntax>, do_parse!(tag!("syntax") >> many0!(br) >> tag!("=") >>
    proto: alt!(tag!("\"proto2\"") => { |_| Syntax::Proto2 } |
                tag!("\"proto3\"") => { |_| Syntax::Proto3 }) >> (proto)));

named!(default_value<&str>, do_parse!(
    tag!("[") >> many0!(br) >> tag!("default") >> many0!(br) >> tag!("=") >> many0!(br) >>
    default: word >> many0!(br) >> tag!("]") >>
    (default)));

named!(packed<bool>, do_parse!(
    tag!("[") >> many0!(br) >> tag!("packed") >> many0!(br) >> tag!("=") >> many0!(br) >>
    packed: map_res!(word, str::FromStr::from_str) >> many0!(br) >> tag!("]") >>
    (packed)));

named!(frequency<Frequency>,
       alt!(tag!("optional") => { |_| Frequency::Optional } |
            tag!("repeated") => { |_| Frequency::Repeated } |
            tag!("required") => { |_| Frequency::Required } ));

named!(message_field<Field>, do_parse!(
    frequency: opt!(frequency) >> many1!(br) >>
    typ: word >> many1!(br) >>
    name: word >> many0!(br) >>
    tag!("=") >> many0!(br) >>
    number: map_res!(map_res!(digit, str::from_utf8), str::FromStr::from_str) >> many0!(br) >>
    default: opt!(default_value) >> many0!(br) >>
    packed: opt!(packed) >> many0!(br) >> tag!(";") >> many0!(br) >>
    (Field {
       name: name,
       frequency: frequency.unwrap_or(Frequency::Optional),
       typ: typ,
       number: number,
       default: default,
       packed: packed,
       boxed: false,
    })));

named!(message<Message>, do_parse!(
    tag!("message") >> many0!(br) >>
    name: word >> many0!(br) >>
    tag!("{") >> many0!(br) >>
    fields: many0!(message_field) >>
    tag!("}") >> many0!(br) >>
    (Message { name: name, fields: fields })));

named!(enum_field<(&str, i32)>, do_parse!(
    name: word >> many0!(br) >>
    tag!("=") >> many0!(br) >>
    number: map_res!(map_res!(digit, str::from_utf8), str::FromStr::from_str) >> many0!(br) >>
    tag!(";") >> many0!(br) >>
    ((name, number))));

named!(enumerator<Enumerator>, do_parse!(
    tag!("enum") >> many1!(br) >>
    name: word >> many0!(br) >>
    tag!("{") >> many0!(br) >>
    fields: many0!(enum_field) >>
    tag!("}") >> many0!(br) >>
    (Enumerator { name: name, fields: fields })));

named!(ignore<()>, do_parse!(
    alt!(tag!("package") | tag!("option")) >> many1!(br) >>
    take_until_and_consume!(";") >> many0!(br) >> ()));

named!(message_or_enum<MessageOrEnum>, alt!(
         message => { |m| MessageOrEnum::Msg(m) } |
         enumerator => { |e| MessageOrEnum::Enum(e) } |
         ignore => { |_| MessageOrEnum::Ignore } ));

named!(pub file_descriptor<FileDescriptor>, do_parse!(
    many0!(br) >> syntax: opt!(syntax) >> many0!(br) >>
    message_and_enums: many0!(message_or_enum) >>
    (FileDescriptor {
        syntax: syntax.unwrap_or(Syntax::Proto2),
        message_and_enums: message_and_enums,
        messages: Vec::new(),
        enums: Vec::new(),
    })));

#[test]
fn test_message() {
    let msg = r#"message ReferenceData
{
    repeated ScenarioInfo  scenarioSet = 1;
    repeated CalculatedObjectInfo calculatedObjectSet = 2;
    repeated RiskFactorList riskFactorListSet = 3;
    repeated RiskMaturityInfo riskMaturitySet = 4;
    repeated IndicatorInfo indicatorSet = 5;
    repeated RiskStrikeInfo riskStrikeSet = 6;
    repeated FreeProjectionList freeProjectionListSet = 7;
    repeated ValidationProperty ValidationSet = 8;
    repeated CalcProperties calcPropertiesSet = 9;
    repeated MaturityInfo maturitySet = 10;
}"#;

    let mess = message(msg.as_bytes());
    if let ::nom::IResult::Done(_, mess) = mess {
        assert_eq!(10, mess.fields.len());
    }
}

#[test]
fn test_enum() {
    let msg = r#"enum PairingStatus {
            DEALPAIRED        = 0;
            INVENTORYORPHAN   = 1;
            CALCULATEDORPHAN  = 2;
            CANCELED          = 3;
}"#;

    let mess = enumerator(msg.as_bytes());
    if let ::nom::IResult::Done(_, mess) = mess {
        assert_eq!(4, mess.fields.len());
    }
}

#[test]
fn test_ignore() {
    let msg = r#"package com.test.v0;

option optimize_for = SPEED;
"#;

    match ignore(msg.as_bytes()) {
        ::nom::IResult::Done(_, _) => (),
        e => panic!("Expecting done {:?}", e),
    }
}
<commit_msg>discard block comments /* ... */<commit_after>use std::str;
use types::{Frequency, Field, Message, Enumerator, MessageOrEnum, FileDescriptor, Syntax};
use nom::{multispace, digit};

fn is_word(b: u8) -> bool {
    match b {
        b'a'...b'z' | b'A'...b'Z' | b'0'...b'9' | b'_' => true,
        _ => false
    }
}

named!(word<&str>, map_res!(take_while!(is_word), str::from_utf8));

named!(comment<()>, do_parse!(tag!("//") >> take_until_and_consume!("\n") >> ()));
named!(block_comment<()>, do_parse!(tag!("/*") >> take_until_and_consume!("*/") >> ()));

/// word break: multispace or comment
named!(br<()>, alt!(map!(multispace, |_| ()) | comment | block_comment));

named!(syntax<Syntax>, do_parse!(tag!("syntax") >> many0!(br) >> tag!("=") >>
    proto: alt!(tag!("\"proto2\"") => { |_| Syntax::Proto2 } |
                tag!("\"proto3\"") => { |_| Syntax::Proto3 }) >> (proto)));

named!(default_value<&str>, do_parse!(
    tag!("[") >> many0!(br) >> tag!("default") >> many0!(br) >> tag!("=") >> many0!(br) >>
    default: word >> many0!(br) >> tag!("]") >>
    (default)));

named!(packed<bool>, do_parse!(
    tag!("[") >> many0!(br) >> tag!("packed") >> many0!(br) >> tag!("=") >> many0!(br) >>
    packed: map_res!(word, str::FromStr::from_str) >> many0!(br) >> tag!("]") >>
    (packed)));

named!(frequency<Frequency>,
       alt!(tag!("optional") => { |_| Frequency::Optional } |
            tag!("repeated") => { |_| Frequency::Repeated } |
            tag!("required") => { |_| Frequency::Required } ));

named!(message_field<Field>, do_parse!(
    frequency: opt!(frequency) >> many1!(br) >>
    typ: word >> many1!(br) >>
    name: word >> many0!(br) >>
    tag!("=") >> many0!(br) >>
    number: map_res!(map_res!(digit, str::from_utf8), str::FromStr::from_str) >> many0!(br) >>
    default: opt!(default_value) >> many0!(br) >>
    packed: opt!(packed) >> many0!(br) >> tag!(";") >> many0!(br) >>
    (Field {
       name: name,
       frequency: frequency.unwrap_or(Frequency::Optional),
       typ: typ,
       number: number,
       default: default,
       packed: packed,
       boxed: false,
    })));

named!(message<Message>, do_parse!(
    tag!("message") >> many0!(br) >>
    name: word >> many0!(br) >>
    tag!("{") >> many0!(br) >>
    fields: many0!(message_field) >>
    tag!("}") >> many0!(br) >>
    (Message { name: name, fields: fields })));

named!(enum_field<(&str, i32)>, do_parse!(
    name: word >> many0!(br) >>
    tag!("=") >> many0!(br) >>
    number: map_res!(map_res!(digit, str::from_utf8), str::FromStr::from_str) >> many0!(br) >>
    tag!(";") >> many0!(br) >>
    ((name, number))));

named!(enumerator<Enumerator>, do_parse!(
    tag!("enum") >> many1!(br) >>
    name: word >> many0!(br) >>
    tag!("{") >> many0!(br) >>
    fields: many0!(enum_field) >>
    tag!("}") >> many0!(br) >>
    (Enumerator { name: name, fields: fields })));

named!(ignore<()>, do_parse!(
    alt!(tag!("package") | tag!("option")) >> many1!(br) >>
    take_until_and_consume!(";") >> many0!(br) >> ()));

named!(message_or_enum<MessageOrEnum>, alt!(
         message => { |m| MessageOrEnum::Msg(m) } |
         enumerator => { |e| MessageOrEnum::Enum(e) } |
         ignore => { |_| MessageOrEnum::Ignore } ));

named!(pub file_descriptor<FileDescriptor>, do_parse!(
    many0!(br) >> syntax: opt!(syntax) >> many0!(br) >>
    message_and_enums: many0!(message_or_enum) >>
    (FileDescriptor {
        syntax: syntax.unwrap_or(Syntax::Proto2),
        message_and_enums: message_and_enums,
        messages: Vec::new(),
        enums: Vec::new(),
    })));

#[test]
fn test_message() {
    let msg = r#"message ReferenceData
{
    repeated ScenarioInfo  scenarioSet = 1;
    repeated CalculatedObjectInfo calculatedObjectSet = 2;
    repeated RiskFactorList riskFactorListSet = 3;
    repeated RiskMaturityInfo riskMaturitySet = 4;
    repeated IndicatorInfo indicatorSet = 5;
    repeated RiskStrikeInfo riskStrikeSet = 6;
    repeated FreeProjectionList freeProjectionListSet = 7;
    repeated ValidationProperty ValidationSet = 8;
    repeated CalcProperties calcPropertiesSet = 9;
    repeated MaturityInfo maturitySet = 10;
}"#;

    let mess = message(msg.as_bytes());
    if let ::nom::IResult::Done(_, mess) = mess {
        assert_eq!(10, mess.fields.len());
    }
}

#[test]
fn test_enum() {
    let msg = r#"enum PairingStatus {
            DEALPAIRED        = 0;
            INVENTORYORPHAN   = 1;
            CALCULATEDORPHAN  = 2;
            CANCELED          = 3;
}"#;

    let mess = enumerator(msg.as_bytes());
    if let ::nom::IResult::Done(_, mess) = mess {
        assert_eq!(4, mess.fields.len());
    }
}

#[test]
fn test_ignore() {
    let msg = r#"package com.test.v0;

option optimize_for = SPEED;
"#;

    match ignore(msg.as_bytes()) {
        ::nom::IResult::Done(_, _) => (),
        e => panic!("Expecting done {:?}", e),
    }
}
<|endoftext|>


<commit_before>use cocoa::appkit::{NSPasteboard, NSPasteboardTypeString};
use cocoa::base::{id, nil};
use cocoa::foundation::{NSArray, NSData, NSFastEnumeration, NSString, NSUInteger};
use std::borrow::Cow;
use std::ffi::CStr;
use {Clipboard, Item, Result};

pub trait ClipboardExt: Clipboard {
    fn clipboard_with_name(&self, name: &str) -> Self;
    fn get_items_nsarray(&self) -> id;
    fn get_raw_clipboard(&self) -> id;
}

#[derive(Debug)]
pub struct CocoaClipboard(id);

impl Clipboard for CocoaClipboard {
    fn get() -> Result<Self> where Self: Sized {
        let pboard = unsafe { NSPasteboard::generalPasteboard(nil) };
        if pboard.is_null() {
            Err(From::from("could not get pasteboard"))
        } else {
            Ok(CocoaClipboard(pboard))
        }
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        self.copy_items(&[*item])
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        let items = items.iter().map(|i| i.native_representation()).collect::<Cow<[_]>>();
        let array = unsafe { NSArray::arrayWithObjects(nil, &items) };
        unsafe {
            self.0.clearContents();
            self.0.writeObjects(array);
        }
        Ok(())
    }

    fn get_paste_text(&self)  -> Result<&str> {
        unsafe {
            let text = NSPasteboard::stringForType(self.0, NSPasteboardTypeString);
            Ok(CStr::from_ptr(text.UTF8String()).to_str().unwrap_or(""))
        }
    }

    fn get_items(&self) -> Cow<[Item]> {
        unsafe {
            self.0.pasteboardItems()
                  .iter()
                  .map(|x| Item::Text(""))
                  .collect()
        }
    }
}

impl ClipboardExt for CocoaClipboard {
    fn clipboard_with_name(&self, name: &str) -> Self {
        unimplemented!();
    }

    fn get_items_nsarray(&self) -> id {
        unimplemented!();
    }

    fn get_raw_clipboard(&self) -> id {
        self.0
    }
}

impl<'a> Item<'a> {
    fn native_representation(&self) -> id {
        match *self {
            Item::Text(text) => unsafe { NSString::alloc(nil).init_str(text) },
            Item::Image(image) => unsafe {
                let slice = image.bytes();
                let _data = NSData::dataWithBytes_length_(nil,
                                                          slice.as_ptr() as *const _,
                                                          slice.len() as NSUInteger);
                unimplemented!();
            },
            Item::Sound(sound) => {
                unimplemented!();
            }
            _ => nil
        }
    }
}
<commit_msg>Small tidy<commit_after>use cocoa::appkit::{NSPasteboard, NSPasteboardTypeString};
use cocoa::base::{id, nil};
use cocoa::foundation::{NSArray, NSData, NSFastEnumeration, NSString, NSUInteger};
use std::borrow::Cow;
use std::ffi::CStr;
use {Clipboard, Item, Result};

pub trait ClipboardExt: Clipboard {
    fn clipboard_with_name(&self, name: &str) -> Self;
    fn get_items_nsarray(&self) -> id;
    fn get_raw_clipboard(&self) -> id;
}

#[derive(Debug)]
pub struct CocoaClipboard(id);

impl Clipboard for CocoaClipboard {
    fn get() -> Result<Self> {
        let pboard = unsafe { NSPasteboard::generalPasteboard(nil) };
        if pboard.is_null() {
            Err(From::from("could not get pasteboard"))
        } else {
            Ok(CocoaClipboard(pboard))
        }
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        self.copy_items(&[*item])
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        let items = items.iter().map(|i| i.native_representation()).collect::<Cow<[_]>>();
        let array = unsafe { NSArray::arrayWithObjects(nil, &items) };
        unsafe {
            self.0.clearContents();
            self.0.writeObjects(array);
        }
        Ok(())
    }

    fn get_paste_text(&self)  -> Result<&str> {
        unsafe {
            let text = NSPasteboard::stringForType(self.0, NSPasteboardTypeString);
            Ok(CStr::from_ptr(text.UTF8String()).to_str().unwrap_or(""))
        }
    }

    fn get_items(&self) -> Cow<[Item]> {
        unsafe {
            self.0.pasteboardItems()
                  .iter()
                  .map(|x| Item::Text(""))
                  .collect()
        }
    }
}

impl ClipboardExt for CocoaClipboard {
    fn clipboard_with_name(&self, name: &str) -> Self {
        unimplemented!();
    }

    fn get_items_nsarray(&self) -> id {
        unimplemented!();
    }

    fn get_raw_clipboard(&self) -> id {
        self.0
    }
}

impl<'a> Item<'a> {
    fn native_representation(&self) -> id {
        match *self {
            Item::Text(text) => unsafe { NSString::alloc(nil).init_str(text) },
            Item::Image(image) => unsafe {
                let slice = image.bytes();
                let _data = NSData::dataWithBytes_length_(nil,
                                                          slice.as_ptr() as *const _,
                                                          slice.len() as NSUInteger);
                unimplemented!();
            },
            Item::Sound(sound) => {
                unimplemented!();
            }
            _ => nil
        }
    }
}
<|endoftext|>