<commit_before>//! Query excecution moduleT
//!
//! This module takes the output of the SQL parser and executed that query
//! by calling the appropriate `storage` and `auth` methods.
//!

use super::parse::ast;
use super::parse::ast::{Query, CreateStmt, DefStmt, CreateTableStmt};
use super::storage::{Database, Column};

pub struct Executor {
    pub database: Option<Database>,

}

    pub fn execute_from_ast(query: ast::Query, dbase: Option<String>) {

        let mut executor = Executor::new();
         match dbase {
            None => (),
            Some(s) => executor.database =  Database::load(&s).ok(),
        };

        match query {
            Query::ManipulationStmt(_) => (),
            Query::DefStmt(stmt) => executor.execute_def_stmt(stmt),
            _ => (),

        }
    //info!("Not implemented! :-(");
    }

impl Executor{

    pub fn new() -> Executor {
        Executor { database: None }
    }

    fn execute_def_stmt(&mut self, query: ast::DefStmt) {
        match query {
            DefStmt::Create(stmt) => self.execute_create_stmt(stmt),
            _ => (),
            //Drop
            //Alter

        }

    }

    fn execute_create_stmt(&mut self, query: ast::CreateStmt) {
        match query {

            CreateStmt::Database(s) =>{
                let tmp = Database::create(&s);
                match tmp {
                    Ok(dbase) => self.database = Some(dbase),
                    _ => (),
                }
            }

            CreateStmt::Table(stmt) => self.execute_create_table_stmt(stmt),
        }

    }

    fn execute_create_table_stmt(&mut self, query: CreateTableStmt) {

        match self.database {
            Some(ref base) => {

                let tmp_vec : Vec<_> = query.cols.into_iter().map(|c| Column {
                    name: c.cid,
                    sql_type: c.datatype,
                    allow_null: false,
                    description: "this is a column".to_string(),
                    is_primary_key: true,
                }).collect();

                // TODO: Use the result!
                let _ = base.create_table(&query.tid, tmp_vec, 0);

            },
            None => (),
        }

    }
}
<commit_msg>Add Primary key too Columns and usage in query.rs<commit_after>//! Query excecution moduleT
//!
//! This module takes the output of the SQL parser and executed that query
//! by calling the appropriate `storage` and `auth` methods.
//!

use super::parse::ast;
use super::parse::ast::{Query, CreateStmt, DefStmt, CreateTableStmt};
use super::storage::{Database, Column};

pub struct Executor {
    pub database: Option<Database>,

}

    pub fn execute_from_ast(query: ast::Query, dbase: Option<String>) {

        let mut executor = Executor::new();
         match dbase {
            None => (),
            Some(s) => executor.database =  Database::load(&s).ok(),
        };

        match query {
            Query::ManipulationStmt(_) => (),
            Query::DefStmt(stmt) => executor.execute_def_stmt(stmt),
            _ => (),

        }
    //info!("Not implemented! :-(");
    }

impl Executor{

    pub fn new() -> Executor {
        Executor { database: None }
    }

    fn execute_def_stmt(&mut self, query: ast::DefStmt) {
        match query {
            DefStmt::Create(stmt) => self.execute_create_stmt(stmt),
            _ => (),
            //Drop
            //Alter

        }

    }

    fn execute_create_stmt(&mut self, query: ast::CreateStmt) {
        match query {

            CreateStmt::Database(s) =>{
                let tmp = Database::create(&s);
                match tmp {
                    Ok(dbase) => self.database = Some(dbase),
                    _ => (),
                }
            }

            CreateStmt::Table(stmt) => self.execute_create_table_stmt(stmt),
        }

    }

    fn execute_create_table_stmt(&mut self, query: CreateTableStmt) {

        match self.database {
            Some(ref base) => {

                let tmp_vec : Vec<_> = query.cols.into_iter().map(|c| Column {
                    name: c.cid,
                    sql_type: c.datatype,
                    allow_null: false,
                    description: "this is a column".to_string(),
                    is_primary_key: c.primary,
                }).collect();

                // TODO: Use the result!
                let _ = base.create_table(&query.tid, tmp_vec, 0);

            },
            None => (),
        }

    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2015, Alberto Corona <alberto@0x1a.us>
// All rights reserved. This file is part of rpf, distributed under the
// BSD 3-Clause license. For full terms please see the LICENSE file.

use std::path::{PathBuf,Path};

/// Adds some useful functions for manipulating and retrieving information from
/// paths
pub trait PathMod {
    /// Returns true if the path's file name starts with a "."
    ///
    /// # Example
    ///
    /// ```
    /// use rpf::PathMod;
    /// use std::path::Path;
    ///
    /// let path = Path::new("/test/dot/.dotfile");
    /// assert_eq!(path.is_dot(), true);
    fn is_dot(&self) -> bool;

    /// Returns a `PathBuf` of `&self`'s last component
    ///
    /// # Example
    ///
    /// ```
    /// use rpf::PathMod;
    /// use std::path::Path;
    ///
    /// let path = Path::new("/tmp/test/mod");
    /// let last = path.last_component().unwrap();
    /// ```
    fn last_component(&self) -> Option<PathBuf>;

    /// Returns a `PathBuf` of `&self`'s first component
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/tmp/test/mod");
    /// let first = path.first_component().unwrap();
    /// assert_eq!(first, PathBuf::from("/"));
    /// ```
    fn first_component(&self) -> Option<PathBuf>;

    /// Returns a `PathBuf` of `&self` relative from its parent
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/tmp/test/mod");
    /// assert_eq!(PathBuf::from("mod"), path.rel_to_parent().unwrap());
    /// ```
    fn rel_to_parent(&self) -> Option<PathBuf>;

    /// Returns a `&str` for a path, returns a blank string if unable to
    /// get a string for the path
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/usr/share");
    /// let path_str = &path.as_str();
    /// assert_eq!(path_str, &"/usr/share");
    /// ```
    fn as_str(&self) -> &str;

    /// Returns a `String` for a path, returns an empty string if unable to get
    /// a string for a path
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path_string = PathBuf::from("/var/log/test").as_string();
    /// assert_eq!(path_string, "/var/log/test".to_string());
    /// ```
    fn as_string(&self) -> String;
}

impl PathMod for PathBuf {
    fn is_dot(&self) -> bool {
        let file_name = match self.file_name() {
            Some(s) => {
                match s.to_str() {
                    Some(k) => { k },
                    None => { "" }
                }
            },
            None => { "" }
        };
        if file_name.starts_with(".") { return true; }
        else { return false; }
    }

    fn last_component(&self) -> Option<PathBuf> {
        match self.components().last() {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn first_component(&self) -> Option<PathBuf> {
        match self.components().nth(0) {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn rel_to_parent(&self) -> Option<PathBuf> {
        let parent = match self.parent() {
            Some(p) => { p },
            None => { return None }
        };
        match self.relative_from(parent) {
            Some(s) => { Some(PathBuf::from(s)) },
            None => { None }
        }
    }

    fn as_str(&self) -> &str {
        match self.to_str() {
            Some(s) => { s },
            None => { "" },
        }
    }

    fn as_string(&self) -> String {
        self.as_str().to_string()
    }
}

impl PathMod for Path {
    fn is_dot(&self) -> bool {
        let file_name = match self.file_name() {
            Some(s) => {
                match s.to_str() {
                    Some(k) => { k },
                    None => { "" }
                }
            },
            None => { "" }
        };
        if file_name.starts_with(".") { return true; }
        else { return false; }
    }

    fn last_component(&self) -> Option<PathBuf> {
        match self.components().last() {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn first_component(&self) -> Option<PathBuf> {
        match self.components().nth(0) {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn rel_to_parent(&self) -> Option<PathBuf> {
        let parent = match self.parent() {
            Some(p) => { p },
            None => { return None; }
        };
        match self.relative_from(parent) {
            Some(s) => { Some(PathBuf::from(s)) },
            None => { None }
        }
    }

    fn as_str(&self) -> &str {
        match self.to_str() {
            Some(s) => { s },
            None => { "" },
        }
    }

    fn as_string(&self) -> String {
        self.as_str().to_string()
    }
}

#[test]
fn test_pathmod_first_comp() {
    let comp = Path::new("/etc/test").first_component().unwrap();
    assert_eq!(comp, PathBuf::from("/"));
}

#[test]
fn test_pathmod_last_comp() {
    let comp = Path::new("/etc/test").last_component().unwrap();
    assert_eq!(comp, PathBuf::from("test"));
}

#[test]
fn test_pathmod_as_str() {
    let string = Path::new("/var/log/test").as_str();
    assert_eq!(string, "/var/log/test");
}

#[test]
fn test_pathmod_as_string() {
    let string = Path::new("/var/log/test").as_string();
    assert_eq!(string, "/var/log/test".to_string());
}

#[test]
fn test_pathmod_is_dot() {
    let path = Path::new("/dir/test/.test");
    assert_eq!(path.is_dot(), true);
}

#[test]
fn test_pathmod_rel_to_parent() {
    let path = PathBuf::from("/var/log/test");
    assert_eq!(PathBuf::from("test"), path.rel_to_parent().unwrap());
}
<commit_msg>pathmod: fix tests for functions<commit_after>// Copyright (C) 2015, Alberto Corona <alberto@0x1a.us>
// All rights reserved. This file is part of rpf, distributed under the
// BSD 3-Clause license. For full terms please see the LICENSE file.

use std::path::{PathBuf,Path};

/// Adds some useful functions for manipulating and retrieving information from
/// paths
pub trait PathMod {
    /// Returns true if the path's file name starts with a "."
    ///
    /// # Example
    ///
    /// ```
    /// use rpf::PathMod;
    /// use std::path::Path;
    ///
    /// let path = Path::new("/test/dot/.dotfile");
    /// assert_eq!(path.is_dot(), true);
    fn is_dot(&self) -> bool;

    /// Returns a `PathBuf` of `&self`'s last component
    ///
    /// # Example
    ///
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/tmp/test/mod");
    /// let last = path.last_component().unwrap();
    /// assert_eq!(last, PathBuf::from("mod"));
    /// ```
    fn last_component(&self) -> Option<PathBuf>;

    /// Returns a `PathBuf` of `&self`'s first component
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/tmp/test/mod");
    /// let first = path.first_component().unwrap();
    /// assert_eq!(first, PathBuf::from("/"));
    /// ```
    fn first_component(&self) -> Option<PathBuf>;

    /// Returns a `PathBuf` of `&self` relative from its parent
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/tmp/test/mod");
    /// assert_eq!(PathBuf::from("mod"), path.rel_to_parent().unwrap());
    /// ```
    fn rel_to_parent(&self) -> Option<PathBuf>;

    /// Returns a `&str` for a path, returns a blank string if unable to
    /// get a string for the path
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path = PathBuf::from("/usr/share");
    /// let path_str = &path.as_str();
    /// assert_eq!(path_str, &"/usr/share");
    /// ```
    fn as_str(&self) -> &str;

    /// Returns a `String` for a path, returns an empty string if unable to get
    /// a string for a path
    ///
    /// # Example
    /// ```
    /// use rpf::PathMod;
    /// use std::path::PathBuf;
    ///
    /// let path_string = PathBuf::from("/var/log/test").as_string();
    /// assert_eq!(path_string, "/var/log/test".to_string());
    /// ```
    fn as_string(&self) -> String;
}

impl PathMod for PathBuf {
    fn is_dot(&self) -> bool {
        let file_name = match self.file_name() {
            Some(s) => {
                match s.to_str() {
                    Some(k) => { k },
                    None => { return false; }
                }
            },
            None => { return false; }
        };
        if file_name.starts_with(".") { return true; }
        else { return false; }
    }

    fn last_component(&self) -> Option<PathBuf> {
        match self.components().last() {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn first_component(&self) -> Option<PathBuf> {
        match self.components().nth(0) {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn rel_to_parent(&self) -> Option<PathBuf> {
        let parent = match self.parent() {
            Some(p) => { p },
            None => { return None }
        };
        match self.relative_from(parent) {
            Some(s) => { Some(PathBuf::from(s)) },
            None => { None }
        }
    }

    fn as_str(&self) -> &str {
        match self.to_str() {
            Some(s) => { s },
            None => { "" },
        }
    }

    fn as_string(&self) -> String {
        self.as_str().to_string()
    }
}

impl PathMod for Path {
    fn is_dot(&self) -> bool {
        let file_name = match self.file_name() {
            Some(s) => {
                match s.to_str() {
                    Some(k) => { k },
                    None => { "" }
                }
            },
            None => { "" }
        };
        if file_name.starts_with(".") { return true; }
        else { return false; }
    }

    fn last_component(&self) -> Option<PathBuf> {
        match self.components().last() {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn first_component(&self) -> Option<PathBuf> {
        match self.components().nth(0) {
            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
            None => { None },
        }
    }

    fn rel_to_parent(&self) -> Option<PathBuf> {
        let parent = match self.parent() {
            Some(p) => { p },
            None => { return None; }
        };
        match self.relative_from(parent) {
            Some(s) => { Some(PathBuf::from(s)) },
            None => { None }
        }
    }

    fn as_str(&self) -> &str {
        match self.to_str() {
            Some(s) => { s },
            None => { "" },
        }
    }

    fn as_string(&self) -> String {
        self.as_str().to_string()
    }
}

#[test]
fn test_pathmod_first_comp() {
    let comp = Path::new("/etc/test").first_component().unwrap();
    assert_eq!(comp, PathBuf::from("/"));
}

#[test]
fn test_pathmod_last_comp() {
    let comp = Path::new("/etc/test").last_component().unwrap();
    assert_eq!(comp, PathBuf::from("test"));
}

#[test]
fn test_pathmod_as_str() {
    let string = Path::new("/var/log/test").as_str();
    assert_eq!(string, "/var/log/test");
}

#[test]
fn test_pathmod_as_string() {
    let string = Path::new("/var/log/test").as_string();
    assert_eq!(string, "/var/log/test".to_string());
}

#[test]
fn test_pathmod_is_dot_success() {
    let path = Path::new("/dir/test/.test");
    assert_eq!(path.is_dot(), true);
}

#[test]
#[should_panic]
fn test_pathmod_is_dot_fail() {
    let false_path = Path::new("/");
    assert_eq!(false_path.is_dot(), true);
}

#[test]
fn test_pathmod_rel_to_parent() {
    let path = PathBuf::from("/var/log/test");
    assert_eq!(PathBuf::from("test"), path.rel_to_parent().unwrap());
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;
use super::context::Context;
use super::vertex_data::{VertexData, VertexBytes, VertexAttribBinder};
use super::index_data::{IndexDatum};
use super::buffer::{Buffer, BufferBinding,
                    ArrayBufferBinding, ElementArrayBufferBinding};
use super::types::DrawingMode;

pub struct VertexBuffer<T: VertexData> {
    pub attrib_binder: Option<T::Binder>,
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: VertexData> VertexBuffer<T> {
    pub fn build_attrib_binder(&self)
        -> <T::Binder as VertexAttribBinder>::Builder
    {
        T::build_attrib_binder()
    }

    pub fn bind(&self, gl_buffer: &ArrayBufferBinding) -> Result<(), ()> {
        match self.attrib_binder {
            Some(ref binder) => {
                binder.bind(gl_buffer);
                Ok(())
            },
            None => { Err(()) }
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct VertexBufferBinding<'a, T: VertexData>
    where T: 'a, T::Binder: 'a
{
    gl_buffer: ArrayBufferBinding<'a>,
    vbo: &'a mut VertexBuffer<T>
}

impl<'a, T: VertexData> VertexBufferBinding<'a, T>
    where T: 'a, T::Binder: 'a
{
    pub fn new(gl_buffer: ArrayBufferBinding<'a>, vbo: &'a mut VertexBuffer<T>)
        -> Self
    {
        VertexBufferBinding {
            gl_buffer: gl_buffer,
            vbo: vbo
        }
    }

    pub fn buffer_data(&mut self, data: &[T], usage: super::BufferDataUsage)
        where [T]: VertexBytes
    {
        self.vbo.count = data.len();
        self.gl_buffer.buffer_bytes(data.vertex_bytes(), usage);
    }

    pub fn draw_arrays_range(&self,
                             mode: DrawingMode,
                             start: u32,
                             length: usize)
    {
        debug_assert!((start as usize) + length <= self.vbo.count);

        unsafe {
            self.gl_buffer.draw_arrays_range(mode, start, length);
        }
    }

    pub fn draw_arrays(&self, mode: DrawingMode) {
        unsafe {
            self.gl_buffer.draw_arrays_range(mode, 0, self.vbo.count);
        }
    }
}

impl Context {
    pub fn new_vertex_buffer<T: VertexData>(&self) -> VertexBuffer<T> {
        VertexBuffer {
            attrib_binder: None,
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

pub struct IndexBuffer<T: IndexDatum> {
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: IndexDatum> IndexBuffer<T> {
    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct IndexBufferBinding<'a, T: IndexDatum + 'a> {
    gl_buffer: ElementArrayBufferBinding<'a>,
    ibo: &'a mut IndexBuffer<T>
}

impl<'a, T: IndexDatum + 'a> IndexBufferBinding<'a, T> {
    pub fn new(gl_buffer: ElementArrayBufferBinding<'a>,
               ibo: &'a mut IndexBuffer<T>)
        -> Self
    {
        IndexBufferBinding {
            gl_buffer: gl_buffer,
            ibo: ibo
        }
    }
}

impl Context {
    pub fn new_index_buffer<T: IndexDatum>(&self) -> IndexBuffer<T> {
        IndexBuffer {
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

#[macro_export]
macro_rules! bind_attrib_pointers {
    ($gl:expr, $vbo:expr, {
        $($field_name:ident => $field_attrib:expr),*
    }) => {
        {
            let vbo = $vbo;
            let binder = vbo.build_attrib_binder()
                            $(.$field_name($field_attrib))*
                            .unwrap($gl);
            vbo.attrib_binder = Some(binder)
        }
    }
}

#[macro_export]
macro_rules! bind_vertex_buffer {
    ($gl:expr, $vbo:expr) => {
        {
            let vbo = $vbo;

            let gl_buffer = bind_array_buffer!($gl, vbo.buffer_mut());
            vbo.bind(&gl_buffer).unwrap();
            $crate::VertexBufferBinding::new(gl_buffer, vbo)
        }
    }
}
<commit_msg>Add `bind_index_buffer!` macro<commit_after>use std::marker::PhantomData;
use super::context::Context;
use super::vertex_data::{VertexData, VertexBytes, VertexAttribBinder};
use super::index_data::{IndexDatum};
use super::buffer::{Buffer, BufferBinding,
                    ArrayBufferBinding, ElementArrayBufferBinding};
use super::types::DrawingMode;

pub struct VertexBuffer<T: VertexData> {
    pub attrib_binder: Option<T::Binder>,
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: VertexData> VertexBuffer<T> {
    pub fn build_attrib_binder(&self)
        -> <T::Binder as VertexAttribBinder>::Builder
    {
        T::build_attrib_binder()
    }

    pub fn bind(&self, gl_buffer: &ArrayBufferBinding) -> Result<(), ()> {
        match self.attrib_binder {
            Some(ref binder) => {
                binder.bind(gl_buffer);
                Ok(())
            },
            None => { Err(()) }
        }
    }

    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct VertexBufferBinding<'a, T: VertexData>
    where T: 'a, T::Binder: 'a
{
    gl_buffer: ArrayBufferBinding<'a>,
    vbo: &'a mut VertexBuffer<T>
}

impl<'a, T: VertexData> VertexBufferBinding<'a, T>
    where T: 'a, T::Binder: 'a
{
    pub fn new(gl_buffer: ArrayBufferBinding<'a>, vbo: &'a mut VertexBuffer<T>)
        -> Self
    {
        VertexBufferBinding {
            gl_buffer: gl_buffer,
            vbo: vbo
        }
    }

    pub fn buffer_data(&mut self, data: &[T], usage: super::BufferDataUsage)
        where [T]: VertexBytes
    {
        self.vbo.count = data.len();
        self.gl_buffer.buffer_bytes(data.vertex_bytes(), usage);
    }

    pub fn draw_arrays_range(&self,
                             mode: DrawingMode,
                             start: u32,
                             length: usize)
    {
        debug_assert!((start as usize) + length <= self.vbo.count);

        unsafe {
            self.gl_buffer.draw_arrays_range(mode, start, length);
        }
    }

    pub fn draw_arrays(&self, mode: DrawingMode) {
        unsafe {
            self.gl_buffer.draw_arrays_range(mode, 0, self.vbo.count);
        }
    }
}

impl Context {
    pub fn new_vertex_buffer<T: VertexData>(&self) -> VertexBuffer<T> {
        VertexBuffer {
            attrib_binder: None,
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

pub struct IndexBuffer<T: IndexDatum> {
    buffer: Buffer,
    count: usize,
    phantom: PhantomData<*const T>
}

impl<T: IndexDatum> IndexBuffer<T> {
    pub fn buffer(&self) -> &Buffer {
        &self.buffer
    }

    pub fn buffer_mut(&mut self) -> &mut Buffer {
        &mut self.buffer
    }
}

pub struct IndexBufferBinding<'a, T: IndexDatum + 'a> {
    gl_buffer: ElementArrayBufferBinding<'a>,
    ibo: &'a mut IndexBuffer<T>
}

impl<'a, T: IndexDatum + 'a> IndexBufferBinding<'a, T> {
    pub fn new(gl_buffer: ElementArrayBufferBinding<'a>,
               ibo: &'a mut IndexBuffer<T>)
        -> Self
    {
        IndexBufferBinding {
            gl_buffer: gl_buffer,
            ibo: ibo
        }
    }
}

impl Context {
    pub fn new_index_buffer<T: IndexDatum>(&self) -> IndexBuffer<T> {
        IndexBuffer {
            buffer: self.gen_buffer(),
            count: 0,
            phantom: PhantomData
        }
    }
}

#[macro_export]
macro_rules! bind_attrib_pointers {
    ($gl:expr, $vbo:expr, {
        $($field_name:ident => $field_attrib:expr),*
    }) => {
        {
            let vbo = $vbo;
            let binder = vbo.build_attrib_binder()
                            $(.$field_name($field_attrib))*
                            .unwrap($gl);
            vbo.attrib_binder = Some(binder)
        }
    }
}

#[macro_export]
macro_rules! bind_vertex_buffer {
    ($gl:expr, $vbo:expr) => {
        {
            let vbo = $vbo;

            let gl_buffer = bind_array_buffer!($gl, vbo.buffer_mut());
            vbo.bind(&gl_buffer).unwrap();
            $crate::VertexBufferBinding::new(gl_buffer, vbo)
        }
    }
}

#[macro_export]
macro_rules! bind_index_buffer {
    ($gl:expr, $ibo:expr) => {
        {
            let ibo = $ibo;

            let gl_buffer = bind_element_array_buffer!($gl, ibo.buffer_mut());
            $crate::IndexBufferBinding::new(gl_buffer, ibo)
        }
    }
}
<|endoftext|>


<commit_before>use http;
use regex::Regex;
use video::Video;

lazy_static! {
    static ref DECRYPT_FUNC_NAME: Regex = Regex::new(r#"\.sig\|\|(.+?)\(.+?\)"#).unwrap();
}

enum CryptOp {
    Reverse,        // reverses entire string
    Swap(usize),    // swaps character at idx with first character
    Slice(usize),   // removes characters up to idx
}

impl CryptOp {
    fn swap(s: &str) -> CryptOp {
        unimplemented!()
    }

    fn slice(s: &str) -> CryptOp {
        unimplemented!()
    }

    fn apply(&self, sig: &mut Vec<char>) {
        unimplemented!()
    }
}

#[derive(Debug)]
pub struct YoutubeVideo {
    title: String,
    uri: String,
    js_player: String,
}

impl YoutubeVideo {
    pub fn new(title: &str, uri: &str, js_player: &str, signature: &Option<String>) -> YoutubeVideo {
        let mut uri = uri.to_owned();
        if let &Some(ref signature) = signature {
            uri = decrypt(&uri, js_player, signature);
        }

        YoutubeVideo {
            title: title.to_owned(),
            uri: uri,
            js_player: js_player.to_owned(),
        }
    }
}

impl Video for YoutubeVideo {
    fn title(&self) -> &str {
        &self.title
    }

    fn uri(&mut self) -> &str {
        &self.uri
    }
}

fn decrypt(uri: &str, js_player: &str, signature: &str) -> String {
    let js = http::download_string(js_player).expect("failed to download js");
    let operations = discover_operations(&js);

    let mut signature: Vec<_> = signature.chars().collect();
    for op in operations {
        op.apply(&mut signature);
    }

    let signature: String = signature.iter().cloned().collect();
    format!("{}&signature={}", uri, signature)
}

fn discover_operations(js: &str) -> Vec<CryptOp> {
    let function_pattern = Regex::new(&format!("{}=function\\(\\w\\){{(.*?)}}", decrypt_function(js))).expect("dynamic regex failed to compile");
    let function_body = function_pattern.captures(js).and_then(|cap| cap.at(1)).expect("unable to capture decrypt function");

    let mut reverse_id = None;
    let mut swap_id = None;
    let mut slice_id = None;

    function_body.split(';').skip(1).filter(|line| !line.starts_with("return")).map(|line| {
        let id = get_id(&line);

        match reverse_id {
            None => if is_reverse_id(&id) {
                reverse_id = Some(id.to_owned());
                return CryptOp::Reverse;
            },
            Some(ref reverse_id) => if reverse_id == id {
                return CryptOp::Reverse;
            }
        }

        match swap_id {
            None => if is_swap_id(&id) {
                swap_id = Some(id.to_owned());
                return CryptOp::swap(line);
            },
            Some(ref swap_id) => if swap_id == id {
                return CryptOp::swap(line);
            }
        }

        match slice_id {
            None => if is_slice_id(&id) {
                slice_id = Some(id.to_owned());
                return CryptOp::slice(line);
            },
            Some(ref slice_id) => if slice_id == id {
                return CryptOp::slice(line);
            }
        }

        panic!("unknown crypto transform");
    }).collect()
}

fn get_id(s: &str) -> &str {
    unimplemented!()
}

fn is_reverse_id(id: &str) -> bool {
    unimplemented!()
}

fn is_swap_id(id: &str) -> bool {
    unimplemented!()
}

fn is_slice_id(id: &str) -> bool {
    unimplemented!()
}

/// Returns the decryption function found in the javascript source code
fn decrypt_function(js: &str) -> &str {
    // the C# program I'm porting had a custom-build dfa or state machine or
    // whatever for this crap... I feel like rust's regex crate is good enough
    // I can just say fuck all that noise

    DECRYPT_FUNC_NAME.captures(js).and_then(|cap| cap.at(1)).expect("unable to find decrypt function")
}

#[cfg(test)]
mod tests {
    #[test]
    fn regex_patterns_work() {
        use video::youtube::{
            DECRYPT_FUNC_NAME
        };

        DECRYPT_FUNC_NAME.is_match("");
    }
}
<commit_msg>implement transforms<commit_after>use http;
use regex::Regex;
use video::Video;

lazy_static! {
    static ref DECRYPT_FUNC_NAME: Regex = Regex::new(r#"\.sig\|\|(.+?)\(.+?\)"#).unwrap();
}

enum CryptOp {
    Reverse,        // reverses entire string
    Swap(usize),    // swaps character at idx with first character
    Slice(usize),   // removes characters up to idx
}

impl CryptOp {
    fn swap(s: &str) -> CryptOp {
        unimplemented!()
    }

    fn slice(s: &str) -> CryptOp {
        unimplemented!()
    }

    fn apply(&self, sig: &mut Vec<char>) {
        match *self {
            CryptOp::Reverse => *sig = sig.iter().cloned().rev().collect(),
            CryptOp::Swap(idx) => sig.swap(0, idx),
            CryptOp::Slice(idx) => *sig = sig.split_off(idx),
        }
    }
}

#[derive(Debug)]
pub struct YoutubeVideo {
    title: String,
    uri: String,
    js_player: String,
}

impl YoutubeVideo {
    pub fn new(title: &str, uri: &str, js_player: &str, signature: &Option<String>) -> YoutubeVideo {
        let mut uri = uri.to_owned();
        if let &Some(ref signature) = signature {
            uri = decrypt(&uri, js_player, signature);
        }

        YoutubeVideo {
            title: title.to_owned(),
            uri: uri,
            js_player: js_player.to_owned(),
        }
    }
}

impl Video for YoutubeVideo {
    fn title(&self) -> &str {
        &self.title
    }

    fn uri(&mut self) -> &str {
        &self.uri
    }
}

fn decrypt(uri: &str, js_player: &str, signature: &str) -> String {
    let js = http::download_string(js_player).expect("failed to download js");
    let operations = discover_operations(&js);

    let mut signature: Vec<_> = signature.chars().collect();
    for op in operations {
        op.apply(&mut signature);
    }

    let signature: String = signature.iter().cloned().collect();
    format!("{}&signature={}", uri, signature)
}

fn discover_operations(js: &str) -> Vec<CryptOp> {
    let function_pattern = Regex::new(&format!("{}=function\\(\\w\\){{(.*?)}}", decrypt_function(js))).expect("dynamic regex failed to compile");
    let function_body = function_pattern.captures(js).and_then(|cap| cap.at(1)).expect("unable to capture decrypt function");

    let mut reverse_id = None;
    let mut swap_id = None;
    let mut slice_id = None;

    function_body.split(';').skip(1).filter(|line| !line.starts_with("return")).map(|line| {
        let id = get_id(&line);

        match reverse_id {
            None => if is_reverse_id(&id) {
                reverse_id = Some(id.to_owned());
                return CryptOp::Reverse;
            },
            Some(ref reverse_id) => if reverse_id == id {
                return CryptOp::Reverse;
            }
        }

        match swap_id {
            None => if is_swap_id(&id) {
                swap_id = Some(id.to_owned());
                return CryptOp::swap(line);
            },
            Some(ref swap_id) => if swap_id == id {
                return CryptOp::swap(line);
            }
        }

        match slice_id {
            None => if is_slice_id(&id) {
                slice_id = Some(id.to_owned());
                return CryptOp::slice(line);
            },
            Some(ref slice_id) => if slice_id == id {
                return CryptOp::slice(line);
            }
        }

        panic!("unknown crypto transform");
    }).collect()
}

fn get_id(s: &str) -> &str {
    unimplemented!()
}

fn is_reverse_id(id: &str) -> bool {
    unimplemented!()
}

fn is_swap_id(id: &str) -> bool {
    unimplemented!()
}

fn is_slice_id(id: &str) -> bool {
    unimplemented!()
}

/// Returns the decryption function found in the javascript source code
fn decrypt_function(js: &str) -> &str {
    // the C# program I'm porting had a custom-build dfa or state machine or
    // whatever for this crap... I feel like rust's regex crate is good enough
    // I can just say fuck all that noise

    DECRYPT_FUNC_NAME.captures(js).and_then(|cap| cap.at(1)).expect("unable to find decrypt function")
}

#[cfg(test)]
mod tests {
    #[test]
    fn regex_patterns_work() {
        use video::youtube::{
            DECRYPT_FUNC_NAME
        };

        DECRYPT_FUNC_NAME.is_match("");
    }
}
<|endoftext|>


<commit_before>pub enum HyperCalls {
    SetTrapTable = 0,
    MmuUpdate = 1,
    SetGdt = 2,
    StackSwitch = 3,
    SetCallbacks = 4,
    FpuTaskSwitch = 5,
    SchedOpCompat = 6,
    PlatformOp = 7,
    SetDebugReg = 8,
    GetDebugReg = 9,
    UpdateDescriptor = 10,
    MemoryOp = 12,
    MultiCall = 13,
    UpdateVaMapping = 14,
    SetTimerOp = 15,
    EventChannelOpCompat = 16,
    XenVersion = 17,
    ConsoleIo = 18,
    PhysdevOpCompat = 19,
    GrantTableOp = 20,
    VmAssist = 21,
    UpdateVaMappingOtherdomain = 22,
    Iret = 23,
    VcpuOp = 24,
    SetSegmentBase = 25,
    MmuextOp = 26,
    XsmOp = 27,
    NmiOp = 28,
    SchedOp = 29,
    CallbackOp = 30,
    XenoprofOp = 31,
    EventChannelOp = 32,
    PhysdevOp = 33,
    HvmOp = 34,
    Sysctl = 35,
    Domctl = 36,
    KexecOp = 37,
    TmemOp = 38,
    XcReservedOp = 39,
    XenpmuOp = 40,
}
<commit_msg>xen: Add hypercallX wrappers<commit_after>use ::arch::defs::Ulong;

pub enum HyperCalls {
    SetTrapTable = 0,
    MmuUpdate = 1,
    SetGdt = 2,
    StackSwitch = 3,
    SetCallbacks = 4,
    FpuTaskSwitch = 5,
    SchedOpCompat = 6,
    PlatformOp = 7,
    SetDebugReg = 8,
    GetDebugReg = 9,
    UpdateDescriptor = 10,
    MemoryOp = 12,
    MultiCall = 13,
    UpdateVaMapping = 14,
    SetTimerOp = 15,
    EventChannelOpCompat = 16,
    XenVersion = 17,
    ConsoleIo = 18,
    PhysdevOpCompat = 19,
    GrantTableOp = 20,
    VmAssist = 21,
    UpdateVaMappingOtherdomain = 22,
    Iret = 23,
    VcpuOp = 24,
    SetSegmentBase = 25,
    MmuextOp = 26,
    XsmOp = 27,
    NmiOp = 28,
    SchedOp = 29,
    CallbackOp = 30,
    XenoprofOp = 31,
    EventChannelOp = 32,
    PhysdevOp = 33,
    HvmOp = 34,
    Sysctl = 35,
    Domctl = 36,
    KexecOp = 37,
    TmemOp = 38,
    XcReservedOp = 39,
    XenpmuOp = 40,
}

pub fn hypercall0(id: HyperCalls) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, 0, 0, 0, 0, 0)
    }
}

pub fn hypercall1(id: HyperCalls, arg1: Ulong) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, arg1, 0, 0, 0, 0)
    }
}

pub fn hypercall2(id: HyperCalls, arg1: Ulong, arg2: Ulong) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, arg1, arg2, 0, 0, 0)
    }
}

pub fn hypercall3(id: HyperCalls, arg1: Ulong, arg2: Ulong,
                  arg3: Ulong) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, arg1, arg2, arg3, 0, 0)
    }
}

pub fn hypercall4(id: HyperCalls, arg1: Ulong, arg2: Ulong, arg3: Ulong,
                  arg4: Ulong) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, arg1, arg2, arg3, arg4, 0)
    }
}

pub fn hypercall5(id: HyperCalls, arg1: Ulong, arg2: Ulong, arg3: Ulong,
                  arg4: Ulong, arg5: Ulong) -> Ulong {
    unsafe {
        ::arch::xen::hypercall(id as u32, arg1, arg2, arg3, arg4, arg5)
    }
}
<|endoftext|>


<commit_before>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 7;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = canvas_size.width.min(canvas_size.height) as f64 - 2.0 * BORDER_MARGIN;
    let start_point_coord = -auto_size / 2.0;

    turtle.pen_up();
    turn_and_go_to(turtle, [start_point_coord, start_point_coord].into());
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());
}
<commit_msg>Hide turtle at end of Sierpinski Triangle example<commit_after>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 7;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = canvas_size.width.min(canvas_size.height) as f64 - 2.0 * BORDER_MARGIN;
    let start_point_coord = -auto_size / 2.0;

    turtle.pen_up();
    turn_and_go_to(turtle, [start_point_coord, start_point_coord].into());
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());

    turtle.hide();
}
<|endoftext|>


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

#![feature(rustc_private, plugin_registrar)]

extern crate syntax;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax::ext::deriving::generic::*;
use syntax::ext::deriving::generic::ty::*;
use syntax::parse::token;
use syntax::ptr::P;
use rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(token::intern("derive_Rand"),
                                  base::MultiDecorator(Box::new(expand_deriving_rand)));
}

pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable)) {
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("rand", "Rand")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "rand",
                is_unsafe: false,
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec!(("R",
                                  vec!( Path::new(vec!("rand", "Rng")) )))
                },
                explicit_self: None,
                args: vec!(
                    Ptr(Box::new(Literal(Path::new_local("R"))),
                        Borrowed(None, ast::MutMutable))
                ),
                ret_ty: Self_,
                attributes: Vec::new(),
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    rand_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, &item, &mut |i| push(i))
}

fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let rng = if substr.nonself_args.len() == 1 {
        &substr.nonself_args[0]
    } else {
        cx.bug("Incorrect number of arguments to `rand` in `derive(Rand)`")
    };
    let rand_ident = vec!(
        cx.ident_of("rand"),
        cx.ident_of("Rand"),
        cx.ident_of("rand")
    );
    let rand_call = |cx: &mut ExtCtxt, span| {
        cx.expr_call_global(span,
                            rand_ident.clone(),
                            vec!(rng.clone()))
    };

    return match *substr.fields {
        StaticStruct(_, ref summary) => {
            let path = cx.path_ident(trait_span, substr.type_ident);
            rand_thing(cx, trait_span, path, summary, rand_call)
        }
        StaticEnum(_, ref variants) => {
            if variants.is_empty() {
                cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants");
                // let compilation continue
                return cx.expr_usize(trait_span, 0);
            }

            let variant_count = cx.expr_usize(trait_span, variants.len());

            let rand_name = cx.path_all(trait_span,
                                        true,
                                        rand_ident.clone(),
                                        Vec::new(),
                                        Vec::new(),
                                        Vec::new());
            let rand_name = cx.expr_path(rand_name);

            // ::rand::Rand::rand(rng)
            let rv_call = cx.expr_call(trait_span,
                                       rand_name,
                                       vec!(rng.clone()));

            // need to specify the usize-ness of the random number
            let usize_ty = cx.ty_ident(trait_span, cx.ident_of("usize"));
            let value_ident = cx.ident_of("__value");
            let let_statement = cx.stmt_let_typed(trait_span,
                                                  false,
                                                  value_ident,
                                                  usize_ty,
                                                  rv_call);

            // rand() % variants.len()
            let value_ref = cx.expr_ident(trait_span, value_ident);
            let rand_variant = cx.expr_binary(trait_span,
                                              ast::BiRem,
                                              value_ref,
                                              variant_count);

            let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| {
                let i_expr = cx.expr_usize(v_span, i);
                let pat = cx.pat_lit(v_span, i_expr);

                let path = cx.path(v_span, vec![substr.type_ident, ident]);
                let thing = rand_thing(cx, v_span, path, summary, |cx, sp| rand_call(cx, sp));
                cx.arm(v_span, vec!( pat ), thing)
            }).collect::<Vec<ast::Arm> >();

            // _ => {} at the end. Should never occur
            arms.push(cx.arm_unreachable(trait_span));

            let match_expr = cx.expr_match(trait_span, rand_variant, arms);

            let block = cx.block(trait_span, vec!( let_statement ), Some(match_expr));
            cx.expr_block(block)
        }
        _ => cx.bug("Non-static method in `derive(Rand)`")
    };

    fn rand_thing<F>(cx: &mut ExtCtxt,
                     trait_span: Span,
                     ctor_path: ast::Path,
                     summary: &StaticFields,
                     mut rand_call: F)
                     -> P<Expr> where
        F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
    {
        let path = cx.expr_path(ctor_path.clone());
        match *summary {
            Unnamed(ref fields) => {
                if fields.is_empty() {
                    path
                } else {
                    let exprs = fields.iter().map(|span| rand_call(cx, *span)).collect();
                    cx.expr_call(trait_span, path, exprs)
                }
            }
            Named(ref fields) => {
                let rand_fields = fields.iter().map(|&(ident, span)| {
                    let e = rand_call(cx, span);
                    cx.field_imm(span, ident, e)
                }).collect();
                cx.expr_struct(trait_span, ctor_path, rand_fields)
            }
        }
    }
}
<commit_msg>Fix rand_macros for syntax/syntax_ext crate split<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(rustc_private, plugin_registrar)]

extern crate syntax;
extern crate syntax_ext;
extern crate rustc_plugin;

use syntax::ast::{MetaItem, Expr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base;
use syntax::ext::base::{ExtCtxt, Annotatable};
use syntax::ext::build::AstBuilder;
use syntax_ext::deriving::generic::*;
use syntax_ext::deriving::generic::ty::*;
use syntax::parse::token;
use syntax::ptr::P;
use rustc_plugin::Registry;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_syntax_extension(token::intern("derive_Rand"),
                                  base::MultiDecorator(Box::new(expand_deriving_rand)));
}

pub fn expand_deriving_rand(cx: &mut ExtCtxt,
                            span: Span,
                            mitem: &MetaItem,
                            item: &Annotatable,
                            push: &mut FnMut(Annotatable)) {
    let trait_def = TraitDef {
        span: span,
        attributes: Vec::new(),
        path: Path::new(vec!("rand", "Rand")),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        methods: vec!(
            MethodDef {
                name: "rand",
                is_unsafe: false,
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec!(("R",
                                  vec!( Path::new(vec!("rand", "Rng")) )))
                },
                explicit_self: None,
                args: vec!(
                    Ptr(Box::new(Literal(Path::new_local("R"))),
                        Borrowed(None, ast::MutMutable))
                ),
                ret_ty: Self_,
                attributes: Vec::new(),
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    rand_substructure(a, b, c)
                }))
            }
        ),
        associated_types: Vec::new(),
    };
    trait_def.expand(cx, mitem, &item, &mut |i| push(i))
}

fn rand_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
    let rng = if substr.nonself_args.len() == 1 {
        &substr.nonself_args[0]
    } else {
        cx.bug("Incorrect number of arguments to `rand` in `derive(Rand)`")
    };
    let rand_ident = vec!(
        cx.ident_of("rand"),
        cx.ident_of("Rand"),
        cx.ident_of("rand")
    );
    let rand_call = |cx: &mut ExtCtxt, span| {
        cx.expr_call_global(span,
                            rand_ident.clone(),
                            vec!(rng.clone()))
    };

    return match *substr.fields {
        StaticStruct(_, ref summary) => {
            let path = cx.path_ident(trait_span, substr.type_ident);
            rand_thing(cx, trait_span, path, summary, rand_call)
        }
        StaticEnum(_, ref variants) => {
            if variants.is_empty() {
                cx.span_err(trait_span, "`Rand` cannot be derived for enums with no variants");
                // let compilation continue
                return cx.expr_usize(trait_span, 0);
            }

            let variant_count = cx.expr_usize(trait_span, variants.len());

            let rand_name = cx.path_all(trait_span,
                                        true,
                                        rand_ident.clone(),
                                        Vec::new(),
                                        Vec::new(),
                                        Vec::new());
            let rand_name = cx.expr_path(rand_name);

            // ::rand::Rand::rand(rng)
            let rv_call = cx.expr_call(trait_span,
                                       rand_name,
                                       vec!(rng.clone()));

            // need to specify the usize-ness of the random number
            let usize_ty = cx.ty_ident(trait_span, cx.ident_of("usize"));
            let value_ident = cx.ident_of("__value");
            let let_statement = cx.stmt_let_typed(trait_span,
                                                  false,
                                                  value_ident,
                                                  usize_ty,
                                                  rv_call);

            // rand() % variants.len()
            let value_ref = cx.expr_ident(trait_span, value_ident);
            let rand_variant = cx.expr_binary(trait_span,
                                              ast::BiRem,
                                              value_ref,
                                              variant_count);

            let mut arms = variants.iter().enumerate().map(|(i, &(ident, v_span, ref summary))| {
                let i_expr = cx.expr_usize(v_span, i);
                let pat = cx.pat_lit(v_span, i_expr);

                let path = cx.path(v_span, vec![substr.type_ident, ident]);
                let thing = rand_thing(cx, v_span, path, summary, |cx, sp| rand_call(cx, sp));
                cx.arm(v_span, vec!( pat ), thing)
            }).collect::<Vec<ast::Arm> >();

            // _ => {} at the end. Should never occur
            arms.push(cx.arm_unreachable(trait_span));

            let match_expr = cx.expr_match(trait_span, rand_variant, arms);

            let block = cx.block(trait_span, vec!( let_statement ), Some(match_expr));
            cx.expr_block(block)
        }
        _ => cx.bug("Non-static method in `derive(Rand)`")
    };

    fn rand_thing<F>(cx: &mut ExtCtxt,
                     trait_span: Span,
                     ctor_path: ast::Path,
                     summary: &StaticFields,
                     mut rand_call: F)
                     -> P<Expr> where
        F: FnMut(&mut ExtCtxt, Span) -> P<Expr>,
    {
        let path = cx.expr_path(ctor_path.clone());
        match *summary {
            Unnamed(ref fields) => {
                if fields.is_empty() {
                    path
                } else {
                    let exprs = fields.iter().map(|span| rand_call(cx, *span)).collect();
                    cx.expr_call(trait_span, path, exprs)
                }
            }
            Named(ref fields) => {
                let rand_fields = fields.iter().map(|&(ident, span)| {
                    let e = rand_call(cx, span);
                    cx.field_imm(span, ident, e)
                }).collect();
                cx.expr_struct(trait_span, ctor_path, rand_fields)
            }
        }
    }
}
<|endoftext|>


<commit_before>#![no_std]

extern crate alloc;
extern crate lang_items;

use core::fmt::Write;
use libtock_drivers::console::Console;
use libtock_drivers::nfc::NfcTag;

#[allow(dead_code)]
/// Helper function to write a slice into a fixed
/// length transmission buffer.
fn write_tx_buffer(buf: &mut [u8], slice: &[u8]) {
    for (i, &byte) in slice.iter().enumerate() {
        buf[i] = byte;
    }
}

fn main() {
    let mut console = Console::new();

    writeln!(console, "****************************************").unwrap();
    writeln!(console, "nfct_test application is installed").unwrap();

    // 1. Configure Type 4 tag
    if NfcTag::configure(4) {
        writeln!(console, " -- TAG CONFIGURED").unwrap();
    }
    // 2. Subscribe to a SELECTED CALLBACK
    if NfcTag::selected() {
        writeln!(console, " -- TAG SELECTED").unwrap();
        // 0xfffff results in 1048575 / 13.56e6 = 77ms
        NfcTag::set_framedelaymax(0xfffff);
    }
    /*
    [_.] TODO: Enable Tag emulation (currently the tag is always activated)
    needs field detection support in the driver level.
    */
    let mut rx_buf = [0; 64];
    let mut unknown_cmd_cntr = 0;
    loop {
        NfcTag::receive(&mut rx_buf);
        match rx_buf[0] {
            0xe0 /* RATS */=> {
                let mut answer_to_select = [0x05, 0x78, 0x80, 0xB1, 0x00];
                let amount = answer_to_select.len();
                NfcTag::transmit(&mut answer_to_select, amount);
            }
            0xc2 /* DESELECT */ => {
                // Ignore the request
                let mut command_error = [0x6A, 0x81];
                let amount = command_error.len();
                NfcTag::transmit(&mut command_error, amount);
            }
            0x02 | 0x03 /* APDU Prefix */ => {
                let mut reply = [rx_buf[0], 0x90, 0x00];
                let amount = reply.len();
                NfcTag::transmit(&mut reply, amount);
            }
            _ => {
                unknown_cmd_cntr += 1;
            }
        }
        if unknown_cmd_cntr > 50 {
            break;
        }
    }
    writeln!(console, "****************************************").unwrap();
}
<commit_msg>Delete nfct_test.rs<commit_after><|endoftext|>


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

use collections::String;
use collections::Vec;

use common::event::{self, Event, EventOption};

use core::{cmp, mem};

use drivers::io::{Io, Pio};

use graphics::color::Color;
use graphics::display::Display;

use sync::WaitQueue;

fn ansi_color(value: u8) -> Color {
    match value {
        0 => Color::new(0x00, 0x00, 0x00),
        1 => Color::new(0x80, 0x00, 0x00),
        2 => Color::new(0x00, 0x80, 0x00),
        3 => Color::new(0x80, 0x80, 0x00),
        4 => Color::new(0x00, 0x00, 0x80),
        5 => Color::new(0x80, 0x00, 0x80),
        6 => Color::new(0x00, 0x80, 0x80),
        7 => Color::new(0xc0, 0xc0, 0xc0),
        8 => Color::new(0x80, 0x80, 0x80),
        9 => Color::new(0xff, 0x00, 0x00),
        10 => Color::new(0x00, 0xff, 0x00),
        11 => Color::new(0xff, 0xff, 0x00),
        12 => Color::new(0x00, 0x00, 0xff),
        13 => Color::new(0xff, 0x00, 0xff),
        14 => Color::new(0x00, 0xff, 0xff),
        15 => Color::new(0xff, 0xff, 0xff),
        16 ... 231 => {
            let convert = |value: u8| -> u8 {
                match value {
                    0 => 0,
                    _ => value * 0x28 + 0x28
                }
            };

            let r = convert((value - 16)/36 % 6);
            let g = convert((value - 16)/6 % 6);
            let b = convert((value - 16) % 6);
            Color::new(r, g, b)
        },
        232 ... 255 => {
            let gray = (value - 232) * 10 + 8;
            Color::new(gray, gray, gray)
        },
        _ => Color::new(0, 0, 0)
    }
}

pub struct Console {
    pub display: Option<Box<Display>>,
    pub point_x: usize,
    pub point_y: usize,
    pub foreground: Color,
    pub background: Color,
    pub draw: bool,
    pub redraw: bool,
    pub command: String,
    pub commands: WaitQueue<String>,
    pub escape: bool,
    pub escape_sequence: bool,
    pub sequence: Vec<String>,
    pub raw_mode: bool,
}

impl Console {
    pub fn new() -> Console {
        Console {
            display: Display::root(),
            point_x: 0,
            point_y: 0,
            foreground: ansi_color(7),
            background: ansi_color(0),
            draw: false,
            redraw: true,
            command: String::new(),
            commands: WaitQueue::new(),
            escape: false,
            escape_sequence: false,
            sequence: Vec::new(),
            raw_mode: false,
        }
    }

    pub fn code(&mut self, c: char) {
        if self.escape_sequence {
            match c {
                '0' ... '9' => {
                    // Add a number to the sequence list
                    if let Some(mut value) = self.sequence.last_mut() {
                        value.push(c);
                    }
                },
                ';' => {
                    // Split sequence into list
                    self.sequence.push(String::new());
                },
                'm' => {
                    // Display attributes
                    let mut value_iter = self.sequence.iter();
                    while let Some(value_str) = value_iter.next() {
                        let value = value_str.parse::<u8>().unwrap_or(0);
                        match value {
                            0 => {
                                self.foreground = ansi_color(7);
                                self.background = ansi_color(0);
                            },
                            30 ... 37 => self.foreground = ansi_color(value - 30),
                            38 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
                                2 => {
                                    //True color
                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.foreground = Color::new(r, g, b);
                                },
                                5 => {
                                    //256 color
                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.foreground = ansi_color(color_value);
                                },
                                _ => {}
                            },
                            40 ... 47 => self.background = ansi_color(value - 40),
                            48 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
                                2 => {
                                    //True color
                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.background = Color::new(r, g, b);
                                },
                                5 => {
                                    //256 color
                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.background = ansi_color(color_value);
                                },
                                _ => {}
                            },
                            _ => {},
                        }
                    }

                    self.escape_sequence = false;
                },
                'J' => {
                    match self.sequence.get(0).map_or("", |p| &p).parse::<usize>().unwrap_or(0) {
                        0 => {
                            //TODO: Erase down
                        },
                        1 => {
                            //TODO: Erase up
                        },
                        2 => {
                            // Erase all
                            self.point_x = 0;
                            self.point_y = 0;
                            if let Some(ref mut display) = self.display {
                                display.set(self.background);
                            }
                            self.redraw = true;
                        },
                        _ => {}
                    }

                    self.escape_sequence = false;
                },
                'H' | 'f' => {
                    if let Some(ref mut display) = self.display {
                        display.rect(self.point_x, self.point_y, 8, 16, self.background);
                    }

                    let row = self.sequence.get(0).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
                    self.point_y = cmp::max(0, row - 1) as usize * 16;

                    let col = self.sequence.get(1).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
                    self.point_x = cmp::max(0, col - 1) as usize * 8;

                    if let Some(ref mut display) = self.display {
                        display.rect(self.point_x, self.point_y, 8, 16, self.foreground);
                    }
                    self.redraw = true;

                    self.escape_sequence = false;
                },
/*
@MANSTART{terminal-raw-mode}
INTRODUCTION
    Since Redox has no ioctl syscall, it uses escape codes for switching to raw mode.

ENTERING AND EXITING RAW MODE
    Entering raw mode is done using CSI-r (^[r). Unsetting raw mode is done by CSI-R (^[R).

RAW MODE
    Raw mode means that the stdin must be handled solely by the program itself. It will not automatically be printed nor will it be modified in any way (modulo escape codes).

    This means that:
        - stdin is not printed.
        - newlines are interpreted as carriage returns in stdin.
        - stdin is not buffered, meaning that the stream of bytes goes directly to the program, without the user having to press enter.
@MANEND
*/
                'r' => {
                    self.raw_mode = true;
                    self.escape_sequence = false;
                },
                'R' => {
                    self.raw_mode = false;
                    self.escape_sequence = false;
                },
                _ => self.escape_sequence = false,
            }

            if !self.escape_sequence {
                self.sequence.clear();
                self.escape = false;
            }
        } else {
            match c {
                '[' => {
                    // Control sequence initiator

                    self.escape_sequence = true;
                    self.sequence.push(String::new());
                },
                'c' => {
                    // Reset
                    self.point_x = 0;
                    self.point_y = 0;
                    self.raw_mode = false;
                    self.foreground = ansi_color(7);
                    self.background = ansi_color(0);
                    if let Some(ref mut display) = self.display {
                        display.set(self.background);
                    }
                    self.redraw = true;

                    self.escape = false;
                }
                _ => self.escape = false,
            }
        }
    }

    pub fn character(&mut self, c: char) {
        let (width, height) = if let Some(ref mut display) = self.display {
            (display.width, display.height)
        } else {
            (80, 30)
        };

        if let Some(ref mut display) = self.display {
            display.rect(self.point_x, self.point_y, 8, 16, self.background);
        }

        match c {
            '\0' => {},
            '\x1B' => self.escape = true,
            '\n' => {
                self.point_x = 0;
                self.point_y += 16;
                self.redraw = true;
            },
            '\t' => self.point_x = ((self.point_x / 64) + 1) * 64,
            '\r' => self.point_x = 0,
            '\x08' => {
                if self.point_x >= 8 {
                    self.point_x -= 8;
                }

                if let Some(ref mut display) = self.display {
                    display.rect(self.point_x, self.point_y, 8, 16, self.background);
                }
            },
            _ => {
                if let Some(ref mut display) = self.display {
                    display.char(self.point_x, self.point_y, c, self.foreground);
                }

                self.point_x += 8;
            }
        }

        if self.point_x >= width {
            self.point_x = 0;
            self.point_y += 16;
        }

        while self.point_y + 16 > height {
            if let Some(ref mut display) = self.display {
                display.scroll(16, self.background);
            }
            self.point_y -= 16;
        }

        if let Some(ref mut display) = self.display {
            display.rect(self.point_x, self.point_y, 8, 16, self.foreground);
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Key(key_event) => {
                if key_event.pressed {
                    if self.raw_mode {
                        match key_event.scancode {
                            event::K_BKSP => self.command.push_str("\x08"),
                            event::K_UP => self.command.push_str("\x1B[A"),
                            event::K_DOWN => self.command.push_str("\x1B[B"),
                            event::K_RIGHT => self.command.push_str("\x1B[C"),
                            event::K_LEFT => self.command.push_str("\x1B[D"),
                            _ => match key_event.character {
                                '\0' => {},
                                c => {
                                    self.command.push(c);
                                }
                            },
                        }

                        if ! self.command.is_empty() {
                            let mut command = String::new();
                            mem::swap(&mut self.command, &mut command);
                            self.commands.send(command);
                        }
                    } else {
                        match key_event.scancode {
                            event::K_BKSP => if ! self.command.is_empty() {
                                self.redraw = true;

                                self.write(&[8]);
                                self.command.pop();
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                c => {
                                    self.redraw = true;

                                    self.write(&[c as u8]);
                                    self.command.push(c);

                                    if c == '\n' {
                                        let mut command = String::new();
                                        mem::swap(&mut self.command, &mut command);
                                        self.commands.send(command);
                                    }
                                }
                            },
                        }
                    }
                }
            }
            _ => (),
        }
    }

    pub fn write(&mut self, bytes: &[u8]) {
        for byte in bytes.iter() {
            let c = *byte as char;

            if self.escape {
                self.code(c);
            } else {
                self.character(c);
            }

            //if self.display.is_none()
            {
                let serial_status = Pio::<u8>::new(0x3F8 + 5);
                let mut serial_data = Pio::<u8>::new(0x3F8);

                while !serial_status.readf(0x20) {}
                serial_data.write(*byte);

                if *byte == 8 {
                    while !serial_status.readf(0x20) {}
                    serial_data.write(0x20);

                    while !serial_status.readf(0x20) {}
                    serial_data.write(8);
                }
            }
        }

        if self.draw && self.redraw {
            self.redraw = false;
            if let Some(ref mut display) = self.display {
                display.flip();
            }
        }
    }
}
<commit_msg>Faster screen draws in raw mode<commit_after>use alloc::boxed::Box;

use collections::String;
use collections::Vec;

use common::event::{self, Event, EventOption};

use core::{cmp, mem};

use drivers::io::{Io, Pio};

use graphics::color::Color;
use graphics::display::Display;

use sync::WaitQueue;

fn ansi_color(value: u8) -> Color {
    match value {
        0 => Color::new(0x00, 0x00, 0x00),
        1 => Color::new(0x80, 0x00, 0x00),
        2 => Color::new(0x00, 0x80, 0x00),
        3 => Color::new(0x80, 0x80, 0x00),
        4 => Color::new(0x00, 0x00, 0x80),
        5 => Color::new(0x80, 0x00, 0x80),
        6 => Color::new(0x00, 0x80, 0x80),
        7 => Color::new(0xc0, 0xc0, 0xc0),
        8 => Color::new(0x80, 0x80, 0x80),
        9 => Color::new(0xff, 0x00, 0x00),
        10 => Color::new(0x00, 0xff, 0x00),
        11 => Color::new(0xff, 0xff, 0x00),
        12 => Color::new(0x00, 0x00, 0xff),
        13 => Color::new(0xff, 0x00, 0xff),
        14 => Color::new(0x00, 0xff, 0xff),
        15 => Color::new(0xff, 0xff, 0xff),
        16 ... 231 => {
            let convert = |value: u8| -> u8 {
                match value {
                    0 => 0,
                    _ => value * 0x28 + 0x28
                }
            };

            let r = convert((value - 16)/36 % 6);
            let g = convert((value - 16)/6 % 6);
            let b = convert((value - 16) % 6);
            Color::new(r, g, b)
        },
        232 ... 255 => {
            let gray = (value - 232) * 10 + 8;
            Color::new(gray, gray, gray)
        },
        _ => Color::new(0, 0, 0)
    }
}

pub struct Console {
    pub display: Option<Box<Display>>,
    pub point_x: usize,
    pub point_y: usize,
    pub foreground: Color,
    pub background: Color,
    pub draw: bool,
    pub redraw: bool,
    pub command: String,
    pub commands: WaitQueue<String>,
    pub escape: bool,
    pub escape_sequence: bool,
    pub sequence: Vec<String>,
    pub raw_mode: bool,
}

impl Console {
    pub fn new() -> Console {
        Console {
            display: Display::root(),
            point_x: 0,
            point_y: 0,
            foreground: ansi_color(7),
            background: ansi_color(0),
            draw: false,
            redraw: true,
            command: String::new(),
            commands: WaitQueue::new(),
            escape: false,
            escape_sequence: false,
            sequence: Vec::new(),
            raw_mode: false,
        }
    }

    pub fn code(&mut self, c: char) {
        if self.escape_sequence {
            match c {
                '0' ... '9' => {
                    // Add a number to the sequence list
                    if let Some(mut value) = self.sequence.last_mut() {
                        value.push(c);
                    }
                },
                ';' => {
                    // Split sequence into list
                    self.sequence.push(String::new());
                },
                'm' => {
                    // Display attributes
                    let mut value_iter = self.sequence.iter();
                    while let Some(value_str) = value_iter.next() {
                        let value = value_str.parse::<u8>().unwrap_or(0);
                        match value {
                            0 => {
                                self.foreground = ansi_color(7);
                                self.background = ansi_color(0);
                            },
                            30 ... 37 => self.foreground = ansi_color(value - 30),
                            38 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
                                2 => {
                                    //True color
                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.foreground = Color::new(r, g, b);
                                },
                                5 => {
                                    //256 color
                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.foreground = ansi_color(color_value);
                                },
                                _ => {}
                            },
                            40 ... 47 => self.background = ansi_color(value - 40),
                            48 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
                                2 => {
                                    //True color
                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.background = Color::new(r, g, b);
                                },
                                5 => {
                                    //256 color
                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
                                    self.background = ansi_color(color_value);
                                },
                                _ => {}
                            },
                            _ => {},
                        }
                    }

                    self.escape_sequence = false;
                },
                'J' => {
                    match self.sequence.get(0).map_or("", |p| &p).parse::<usize>().unwrap_or(0) {
                        0 => {
                            //TODO: Erase down
                        },
                        1 => {
                            //TODO: Erase up
                        },
                        2 => {
                            // Erase all
                            self.point_x = 0;
                            self.point_y = 0;
                            if let Some(ref mut display) = self.display {
                                display.set(self.background);
                            }
                            if ! self.raw_mode {
                                self.redraw = true;
                            }
                        },
                        _ => {}
                    }

                    self.escape_sequence = false;
                },
                'H' | 'f' => {
                    if let Some(ref mut display) = self.display {
                        display.rect(self.point_x, self.point_y, 8, 16, self.background);
                    }

                    let row = self.sequence.get(0).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
                    self.point_y = cmp::max(0, row - 1) as usize * 16;

                    let col = self.sequence.get(1).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
                    self.point_x = cmp::max(0, col - 1) as usize * 8;

                    if let Some(ref mut display) = self.display {
                        display.rect(self.point_x, self.point_y, 8, 16, self.foreground);
                    }

                    self.escape_sequence = false;
                },
/*
@MANSTART{terminal-raw-mode}
INTRODUCTION
    Since Redox has no ioctl syscall, it uses escape codes for switching to raw mode.

ENTERING AND EXITING RAW MODE
    Entering raw mode is done using CSI-r (^[r). Unsetting raw mode is done by CSI-R (^[R).

RAW MODE
    Raw mode means that the stdin must be handled solely by the program itself. It will not automatically be printed nor will it be modified in any way (modulo escape codes).

    This means that:
        - stdin is not printed.
        - newlines are interpreted as carriage returns in stdin.
        - stdin is not buffered, meaning that the stream of bytes goes directly to the program, without the user having to press enter.
@MANEND
*/
                'r' => {
                    self.raw_mode = true;
                    self.escape_sequence = false;
                },
                'R' => {
                    self.raw_mode = false;
                    self.escape_sequence = false;
                },
                _ => self.escape_sequence = false,
            }

            if !self.escape_sequence {
                self.sequence.clear();
                self.escape = false;
            }
        } else {
            match c {
                '[' => {
                    // Control sequence initiator

                    self.escape_sequence = true;
                    self.sequence.push(String::new());
                },
                'c' => {
                    // Reset
                    self.point_x = 0;
                    self.point_y = 0;
                    self.raw_mode = false;
                    self.foreground = ansi_color(7);
                    self.background = ansi_color(0);
                    if let Some(ref mut display) = self.display {
                        display.set(self.background);
                    }
                    self.redraw = true;

                    self.escape = false;
                }
                _ => self.escape = false,
            }
        }
    }

    pub fn character(&mut self, c: char) {
        let (width, height) = if let Some(ref mut display) = self.display {
            (display.width, display.height)
        } else {
            (80, 30)
        };

        if let Some(ref mut display) = self.display {
            display.rect(self.point_x, self.point_y, 8, 16, self.background);
        }

        match c {
            '\0' => {},
            '\x1B' => self.escape = true,
            '\n' => {
                self.point_x = 0;
                self.point_y += 16;
                if ! self.raw_mode {
                    self.redraw = true;
                }
            },
            '\t' => self.point_x = ((self.point_x / 64) + 1) * 64,
            '\r' => self.point_x = 0,
            '\x08' => {
                if self.point_x >= 8 {
                    self.point_x -= 8;
                }

                if let Some(ref mut display) = self.display {
                    display.rect(self.point_x, self.point_y, 8, 16, self.background);
                }
            },
            _ => {
                if let Some(ref mut display) = self.display {
                    display.char(self.point_x, self.point_y, c, self.foreground);
                }

                self.point_x += 8;
            }
        }

        if self.point_x >= width {
            self.point_x = 0;
            self.point_y += 16;
        }

        while self.point_y + 16 > height {
            if let Some(ref mut display) = self.display {
                display.scroll(16, self.background);
            }
            self.point_y -= 16;
        }

        if let Some(ref mut display) = self.display {
            display.rect(self.point_x, self.point_y, 8, 16, self.foreground);
        }
    }

    pub fn event(&mut self, event: Event) {
        match event.to_option() {
            EventOption::Key(key_event) => {
                if key_event.pressed {
                    if self.raw_mode {
                        match key_event.scancode {
                            event::K_BKSP => self.command.push_str("\x08"),
                            event::K_UP => self.command.push_str("\x1B[A"),
                            event::K_DOWN => self.command.push_str("\x1B[B"),
                            event::K_RIGHT => self.command.push_str("\x1B[C"),
                            event::K_LEFT => self.command.push_str("\x1B[D"),
                            _ => match key_event.character {
                                '\0' => {},
                                c => {
                                    self.command.push(c);
                                }
                            },
                        }

                        if ! self.command.is_empty() {
                            let mut command = String::new();
                            mem::swap(&mut self.command, &mut command);
                            self.commands.send(command);
                        }
                    } else {
                        match key_event.scancode {
                            event::K_BKSP => if ! self.command.is_empty() {
                                self.redraw = true;

                                self.write(&[8]);
                                self.command.pop();
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                c => {
                                    self.redraw = true;

                                    self.write(&[c as u8]);
                                    self.command.push(c);

                                    if c == '\n' {
                                        let mut command = String::new();
                                        mem::swap(&mut self.command, &mut command);
                                        self.commands.send(command);
                                    }
                                }
                            },
                        }
                    }
                }
            }
            _ => (),
        }
    }

    pub fn write(&mut self, bytes: &[u8]) {
        for byte in bytes.iter() {
            let c = *byte as char;

            if self.escape {
                self.code(c);
            } else {
                self.character(c);
            }

            if self.display.is_none() {
                let serial_status = Pio::<u8>::new(0x3F8 + 5);
                let mut serial_data = Pio::<u8>::new(0x3F8);

                while !serial_status.readf(0x20) {}
                serial_data.write(*byte);

                if *byte == 8 {
                    while !serial_status.readf(0x20) {}
                    serial_data.write(0x20);

                    while !serial_status.readf(0x20) {}
                    serial_data.write(8);
                }
            }
        }

        if self.draw && self.redraw {
            self.redraw = false;
            if let Some(ref mut display) = self.display {
                display.flip();
            }
        }
    }
}
<|endoftext|>