<commit_before>
extern crate itertools;

use itertools::Itertools;

fn main() {
    let data = "abc12345abc".chars();

    // This example does something like .group_by().
    //
    // Instead of allocating, it just walks the iterator twice, and this
    // requires that the iterator is small and easy to clone, like for example
    // the slice or chars iterators.

    // using Itertools::batching
    //
    // Yield (key, iterator) for each run of identical keys.
    let key_func = |c: char| c.is_alphabetic();
    for (key, iter) in data.batching(|mut it| {
            let start = it.clone();
            match it.next() {
                None => return None,
                Some(elt) => {
                    let key = key_func(elt);
                    // using Itertools::take_while_ref
                    let n = 1 + it.take_while_ref(|elt| key_func(*elt) == key).count();
                    return Some((key, start.take(n)))
                }
            }
        })
    {
        for elt in iter {
            println!("Key={:?}, elt={:?}", key, elt);
        }
    }
}
<commit_msg>Remove example group.rs, it's silly<commit_after><|endoftext|>


<commit_before>#![allow(dead_code, unused_imports)]

extern crate fitsio_sys as sys;
extern crate libc;

use std::ptr;
use std::ffi;

mod stringutils;

/// Error type
#[derive(Debug, PartialEq, Eq)]
pub struct FitsError {
    status: i32,
    message: String,
}

pub type Result<T> = std::result::Result<T, FitsError>;

pub struct FitsFile {
    fptr: *mut sys::fitsfile,
    pub filename: String,
}

impl FitsFile {
    fn open(filename: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(filename).unwrap();

        unsafe {
            sys::ffopen(&mut fptr as *mut *mut sys::fitsfile,
                   c_filename.as_ptr(),
                   sys::FileOpenMode::READONLY as libc::c_int,
                   &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: filename.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }

    }

    fn create(path: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(path).unwrap();

        unsafe {
            sys::ffinit(&mut fptr as *mut *mut sys::fitsfile,
                        c_filename.as_ptr(),
                        &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: path.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }
    }
}

impl Drop for FitsFile {
    fn drop(&mut self) {
        let mut status = 0;
        unsafe {
            sys::ffclos(self.fptr, &mut status);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;
    use super::FitsFile;

    #[test]
    fn opening_an_existing_file() {
        match FitsFile::open("../testdata/full_example.fits") {
            Ok(_) => {}
            Err(e) => panic!("{:?}", e),
        }
    }

    #[test]
    fn creating_a_new_file() {
        let tdir = tempdir::TempDir::new("fitsio-").unwrap();
        let tdir_path = tdir.path();
        let filename = tdir_path.join("test.fits");
        assert!(!filename.exists());

        match FitsFile::create(filename.to_str().unwrap()) {
            Ok(_) => assert!(filename.exists()),
            Err(e) => panic!("Error: {:?}", e),
        }
    }

}
<commit_msg>Improve fetching hdu<commit_after>#![allow(dead_code, unused_imports)]

extern crate fitsio_sys as sys;
extern crate libc;

use std::ptr;
use std::ffi;

mod stringutils;

/// Error type
#[derive(Debug, PartialEq, Eq)]
pub struct FitsError {
    status: i32,
    message: String,
}

pub type Result<T> = std::result::Result<T, FitsError>;

/// Hdu description type
///
/// Any way of describing a HDU - number or string which either
/// changes the hdu by absolute number, or by name.
pub trait DescribesHdu {
    fn change_hdu(&self, fptr: &FitsFile) -> Result<()>;
}

impl DescribesHdu for usize {
    fn change_hdu(&self, f: &FitsFile) -> Result<()> {
        let mut _hdu_type = 0;
        let mut status = 0;
        unsafe {
            sys::ffmahd(f.fptr, (*self + 1) as i32, &mut _hdu_type, &mut status);
        }
        match status {
            0 => Ok(()),
            _ => Err(FitsError {
                status: status,
                message: stringutils::status_to_string(status).unwrap(),
            }),
        }
    }
}

impl<'a> DescribesHdu for &'a str {
    fn change_hdu(&self, f: &FitsFile) -> Result<()> {
        let mut _hdu_type = 0;
        let mut status = 0;
        let c_hdu_name = ffi::CString::new(*self).unwrap();

        unsafe {
            sys::ffmnhd(f.fptr,
                   sys::HduType::ANY_HDU as libc::c_int,
                   c_hdu_name.into_raw(),
                   0,
                   &mut status);
        }

        match status {
            0 => Ok(()),
            _ => Err(FitsError {
                status: status,
                message: stringutils::status_to_string(status).unwrap(),
            }),
        }
    }
}

pub struct FitsFile {
    fptr: *mut sys::fitsfile,
    pub filename: String,
}

pub struct FitsHdu<'a> {
    fits_file: &'a FitsFile,
    hdunum: usize,
}

impl FitsFile {
    pub fn open(filename: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(filename).unwrap();

        unsafe {
            sys::ffopen(&mut fptr as *mut *mut sys::fitsfile,
                   c_filename.as_ptr(),
                   sys::FileOpenMode::READONLY as libc::c_int,
                   &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: filename.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }

    }

    pub fn create(path: &str) -> Result<Self> {
        let mut fptr = ptr::null_mut();
        let mut status = 0;
        let c_filename = ffi::CString::new(path).unwrap();

        unsafe {
            sys::ffinit(&mut fptr as *mut *mut sys::fitsfile,
                        c_filename.as_ptr(),
                        &mut status);
        }

        match status {
            0 => {
                Ok(FitsFile {
                    fptr: fptr,
                    filename: path.to_string(),
                })
            }
            status => {
                Err(FitsError {
                    status: status,
                    message: stringutils::status_to_string(status).unwrap(),
                })
            }
        }
    }

    pub fn hdu<T: DescribesHdu>(&self, hdu_description: T) -> Result<FitsHdu> {
        try!(hdu_description.change_hdu(self));
        let hdu_number = self.hdu_number();

        Ok(FitsHdu {
            fits_file: self,
            hdunum: hdu_number,
        })
    }

    fn hdu_number(&self) -> usize {
        let mut hdu_num = 0;
        unsafe {
            sys::ffghdn(self.fptr, &mut hdu_num);
        }
        (hdu_num - 1) as usize
    }
}

impl Drop for FitsFile {
    fn drop(&mut self) {
        let mut status = 0;
        unsafe {
            sys::ffclos(self.fptr, &mut status);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate tempdir;
    use super::FitsFile;

    #[test]
    fn opening_an_existing_file() {
        match FitsFile::open("../testdata/full_example.fits") {
            Ok(_) => {}
            Err(e) => panic!("{:?}", e),
        }
    }

    #[test]
    fn creating_a_new_file() {
        let tdir = tempdir::TempDir::new("fitsio-").unwrap();
        let tdir_path = tdir.path();
        let filename = tdir_path.join("test.fits");
        assert!(!filename.exists());

        match FitsFile::create(filename.to_str().unwrap()) {
            Ok(_) => assert!(filename.exists()),
            Err(e) => panic!("Error: {:?}", e),
        }
    }

    #[test]
    fn fetching_a_hdu() {
        let f = FitsFile::open("../testdata/full_example.fits").unwrap();
        for i in 0..2 {
            assert_eq!(f.hdu(i).unwrap().hdunum, i);
        }
        match f.hdu(2) {
            Err(e) => assert_eq!(e.status, 107),
            _ => panic!("Error checking for failure"),
        }

        let tbl_hdu = f.hdu("TESTEXT").unwrap();
        assert_eq!(tbl_hdu.hdunum, 1);
    }
}
<|endoftext|>


<commit_before>pub use std::libc::*;
pub use std::libc::types::os::arch::extra::*;

pub type ATOM = WORD;
pub type UINT = c_uint;
pub type LONG = c_long;

// 32-bit specific
pub type UINT_PTR = c_uint;
pub type LONG_PTR = c_long;

pub type HANDLE = PVOID;

pub type HBRUSH = HANDLE;
pub type HCURSOR = HICON;
pub type HMENU = HANDLE;
pub type HICON = HANDLE;
pub type HINSTANCE = HANDLE;
pub type HWND = HANDLE;

pub type WPARAM = UINT_PTR;
pub type LPARAM = LONG_PTR;

pub type PVOID = *c_void;

// extern fn(HWND, UINT, WPARAM, LPARAM) -> LRESULT
pub type WNDPROC = *u8;

pub struct WNDCLASSEX {
    cbSize: UINT,
    style: UINT,
    lpfnWndProc: WNDPROC,
    cbClsExtra: c_int,
    cbWndExtra: c_int,
    hInstance: HINSTANCE,
    hIcon: HICON,
    hCursor: HCURSOR,
    hbrBackground: HBRUSH,
    lpszMenuName: LPCWSTR,
    lpszClassName: LPCWSTR,
    hIconSm: HICON,
}

pub struct POINT {
    x: LONG,
    y: LONG,
}

pub struct MSG {
    hwnd: HWND,
    message: UINT,
    wParam: WPARAM,
    lParam: LPARAM,
    time: DWORD,
    pt: POINT,
}

pub mod user32 {
    use ll::*;
    extern "stdcall" {
        unsafe fn CreateWindowExW(extrastyle: DWORD, classname: LPCWSTR,
                windowname: LPCWSTR, style: DWORD,
                x: c_int, y: c_int, width: c_int, height: c_int,
                parent: HWND, menu: HMENU, instance: HINSTANCE, param: LPVOID
        ) -> HWND;

        unsafe fn MessageBoxW(
                hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT
        ) -> c_int;

        unsafe fn RegisterClassExW(lpwcx: *WNDCLASSEX) -> ATOM;

        unsafe fn DefWindowProcW(
                hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM
        ) -> LRESULT;

        unsafe fn GetMessageW(
                lpMsg: *MSG, hWnd: HWND,
                wMsgFilterMin: UINT, wMsgFilterMAx: UINT
        ) -> BOOL;

        unsafe fn PeekMessageW(
                lpMsg: *MSG, hWnd: HWND,
                wMsgFilterMin: UINT, wMsgFilterMAx: UINT, wRemoveMsg: UINT
        ) -> BOOL;

        unsafe fn TranslateMessage(lpMsg: *MSG) -> BOOL;

        unsafe fn DispatchMessageW(lpMsg: *MSG) -> LRESULT;
    }
}
<commit_msg>ll: add some paint-related stuff<commit_after>pub use std::libc::*;
pub use std::libc::types::os::arch::extra::*;

pub type ATOM = WORD;
pub type UINT = c_uint;
pub type LONG = c_long;

// 32-bit specific
pub type UINT_PTR = c_uint;
pub type LONG_PTR = c_long;

pub type HANDLE = PVOID;

pub type HBRUSH = HANDLE;
pub type HCURSOR = HICON;
pub type HMENU = HANDLE;
pub type HICON = HANDLE;
pub type HINSTANCE = HANDLE;
pub type HWND = HANDLE;
pub type HDC = HANDLE;

pub type WPARAM = UINT_PTR;
pub type LPARAM = LONG_PTR;

pub type PVOID = *c_void;

// extern fn(HWND, UINT, WPARAM, LPARAM) -> LRESULT
pub type WNDPROC = *u8;

pub struct WNDCLASSEX {
    cbSize: UINT,
    style: UINT,
    lpfnWndProc: WNDPROC,
    cbClsExtra: c_int,
    cbWndExtra: c_int,
    hInstance: HINSTANCE,
    hIcon: HICON,
    hCursor: HCURSOR,
    hbrBackground: HBRUSH,
    lpszMenuName: LPCWSTR,
    lpszClassName: LPCWSTR,
    hIconSm: HICON,
}

pub struct POINT {
    x: LONG,
    y: LONG,
}

pub struct MSG {
    hwnd: HWND,
    message: UINT,
    wParam: WPARAM,
    lParam: LPARAM,
    time: DWORD,
    pt: POINT,
}

pub struct RECT {
    left: LONG,
    top: LONG,
    right: LONG,
    bottom: LONG,
}

pub struct PAINTSTRUCT {
    hdc: HDC,
    fErase: BOOL,
    rcPaint: RECT,
    fRestore: BOOL,
    fIncUpdate: BOOL,
    rgbReserved: *[BYTE, ..32],
}

pub mod user32 {
    use ll::*;
    extern "stdcall" {
        unsafe fn CreateWindowExW(extrastyle: DWORD, classname: LPCWSTR,
                windowname: LPCWSTR, style: DWORD,
                x: c_int, y: c_int, width: c_int, height: c_int,
                parent: HWND, menu: HMENU, instance: HINSTANCE, param: LPVOID
        ) -> HWND;

        unsafe fn ShowWindow(hwnd: HWND, nCmdShow: c_int) -> BOOL;

        unsafe fn UpdateWindow(hwnd: HWND) -> BOOL;

        unsafe fn BeginPaint(hwnd: HWND, lpPaint: *PAINTSTRUCT) -> HDC;

        unsafe fn EndPaint(hwnd: HWND, lpPaint: *PAINTSTRUCT) -> BOOL;

        unsafe fn MessageBoxW(
                hWnd: HWND, lpText: LPCWSTR, lpCaption: LPCWSTR, uType: UINT
        ) -> c_int;

        unsafe fn RegisterClassExW(lpwcx: *WNDCLASSEX) -> ATOM;

        unsafe fn DefWindowProcW(
                hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM
        ) -> LRESULT;

        unsafe fn GetMessageW(
                lpMsg: *MSG, hWnd: HWND,
                wMsgFilterMin: UINT, wMsgFilterMAx: UINT
        ) -> BOOL;

        unsafe fn PeekMessageW(
                lpMsg: *MSG, hWnd: HWND,
                wMsgFilterMin: UINT, wMsgFilterMAx: UINT, wRemoveMsg: UINT
        ) -> BOOL;

        unsafe fn TranslateMessage(lpMsg: *MSG) -> BOOL;

        unsafe fn DispatchMessageW(lpMsg: *MSG) -> LRESULT;
    }
}
<|endoftext|>


<commit_before>// https://doc.rust-lang.org/nightly/std/ops/trait.Try.html
// https://github.com/rust-lang/rfcs/blob/master/text/3058-try-trait-v2.md
// https://github.com/rust-lang/rust/issues/84277#issuecomment-905821708
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller

use fomat_macros::fomat;
use std::fmt;
use std::ops::{ControlFlow, FromResidual, Try};
use std::panic::Location;
use super::filename;

#[macro_export]
macro_rules! fail {($($args: tt)+) => (return $crate::re::Re::fail (fomat! ($($args)+)))}

#[derive(Debug)]
#[must_use = "this `Re` may be an `Err` variant, which should be handled"]
pub enum Re<T> {Ok (T), Err (String)}

impl<T> Try for Re<T> {
  type Output = T;
  type Residual = Re<!>;

  #[inline]
  fn from_output (c: T) -> Self {Re::Ok (c)}

  #[inline]
  fn branch (self) -> ControlFlow<Self::Residual, T> {
    match self {
      Re::Ok (c) => ControlFlow::Continue (c),
      Re::Err (e) => ControlFlow::Break (Re::Err (e))}}}

impl<T> FromResidual<Re<!>> for Re<T> {
  #[track_caller]
  fn from_residual (x: Re<!>) -> Self {
    let err = match x {Re::Ok (_) => unreachable!(), Re::Err (e) => e};
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (err));
    Re::Err (err)}}

impl<T, O, E> FromResidual<Result<O, E>> for Re<T> where E: fmt::Display {
  #[track_caller]
  fn from_residual (x: Result<O, E>) -> Self {
    let err = match x {Result::Ok (_) => unreachable!(), Result::Err (e) => e};
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (err));
    Re::Err (err)}}

impl<T> Re<T> {
  #[track_caller]
  pub fn fail<E: fmt::Display> (emsg: E) -> Re<T> {
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (emsg));
    Re::Err (err)}

  #[inline]
  pub fn err (self) -> Option<String> {
    match self {Re::Ok (_) => None, Re::Err (e) => Some (e)}}

  #[inline]
  #[track_caller]
  pub fn expect (self, msg: &str) -> T {
    match self {Re::Ok (k) => k, Re::Err (err) => panic! ("{}: {:?}", msg, err)}}

  #[inline]
  #[track_caller]
  pub fn unwrap (self) -> T {
    match self {Re::Ok (k) => k, Re::Err (err) => panic! ("called `Re::unwrap()` on an `Err` value: {:?}", err)}}

  #[inline]
  pub fn unwrap_or (self, default: T) -> T {
    match self {Re::Ok (k) => k, Re::Err (_) => default}}

  #[inline]
  pub fn map<U, F: FnOnce (T) -> U> (self, op: F) -> Re<U> {
    match self {Re::Ok (k) => Re::Ok (op (k)), Re::Err (e) => Re::Err (e)}}}

#[cfg(all(test, feature = "nightly"))] mod test {
  extern crate test;

  use super::*;

  // cargo bench --features nightly,re

  fn foobar (succ: bool) -> Re<bool> {
    if test::black_box (succ) {Re::Ok (true)} else {Re::fail ("!succ")}}

  fn bang (succ: bool) -> Re<()> {
    let b = test::black_box (foobar (succ)?);
    assert_eq! (true, b);
    Re::Ok(())}

  #[bench] fn err (bm: &mut test::Bencher) {
    bm.iter (|| {
      let e = bang (false) .err().unwrap();
      assert! (e.starts_with ("re:"));
      assert! (e.ends_with ("] !succ"))})}

  #[bench] fn ok (bm: &mut test::Bencher) {
    bm.iter (|| {bang (true) .expect ("!user")})}}
<commit_msg>Try Option<commit_after>// https://doc.rust-lang.org/nightly/std/ops/trait.Try.html
// https://github.com/rust-lang/rfcs/blob/master/text/3058-try-trait-v2.md
// https://github.com/rust-lang/rust/issues/84277#issuecomment-905821708
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller

use fomat_macros::fomat;
use std::fmt;
use std::ops::{ControlFlow, FromResidual, Try};
use std::panic::Location;
use super::filename;

#[macro_export]
macro_rules! fail {($($args: tt)+) => (return $crate::re::Re::fail (fomat! ($($args)+)))}

#[derive(Debug, PartialEq)]
#[must_use = "this `Re` may be an `Err` variant, which should be handled"]
pub enum Re<T> {Ok (T), Err (String)}

impl<T> Try for Re<T> {
  type Output = T;
  type Residual = Re<!>;

  #[inline]
  fn from_output (c: T) -> Self {Re::Ok (c)}

  #[inline]
  fn branch (self) -> ControlFlow<Self::Residual, T> {
    match self {
      Re::Ok (c) => ControlFlow::Continue (c),
      Re::Err (e) => ControlFlow::Break (Re::Err (e))}}}

impl<T> FromResidual<Re<!>> for Re<T> {
  #[track_caller]
  fn from_residual (x: Re<!>) -> Self {
    let err = match x {Re::Ok (_) => unreachable!(), Re::Err (e) => e};
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (err));
    Re::Err (err)}}

impl<T, O, E> FromResidual<Result<O, E>> for Re<T> where E: fmt::Display {
  #[track_caller]
  fn from_residual (x: Result<O, E>) -> Self {
    let err = match x {Result::Ok (_) => unreachable!(), Result::Err (e) => e};
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (err));
    Re::Err (err)}}

impl<T, O> FromResidual<Option<O>> for Re<T> {
  #[track_caller]
  fn from_residual (_: Option<O>) -> Self {
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] Option is None");
    Re::Err (err)}}

impl<T> Re<T> {
  #[track_caller]
  pub fn fail<E: fmt::Display> (emsg: E) -> Re<T> {
    let loc = Location::caller();
    let err = fomat! ((filename (loc.file())) ':' (loc.line()) "] " (emsg));
    Re::Err (err)}

  #[inline]
  pub fn err (self) -> Option<String> {
    match self {Re::Ok (_) => None, Re::Err (e) => Some (e)}}

  #[inline]
  #[track_caller]
  pub fn expect (self, msg: &str) -> T {
    match self {Re::Ok (k) => k, Re::Err (err) => panic! ("{}: {:?}", msg, err)}}

  #[inline]
  #[track_caller]
  pub fn unwrap (self) -> T {
    match self {Re::Ok (k) => k, Re::Err (err) => panic! ("called `Re::unwrap()` on an `Err` value: {:?}", err)}}

  #[inline]
  pub fn unwrap_or (self, default: T) -> T {
    match self {Re::Ok (k) => k, Re::Err (_) => default}}

  #[inline]
  pub fn map<U, F: FnOnce (T) -> U> (self, op: F) -> Re<U> {
    match self {Re::Ok (k) => Re::Ok (op (k)), Re::Err (e) => Re::Err (e)}}}

#[cfg(all(test, feature = "nightly"))] mod test {
  extern crate test;

  use super::*;

  #[test] fn opt() {
    fn foo() -> Re<()> {
      let bar: Option<String> = None;
      bar?;
      Re::Ok(())}
    assert_eq! (foo(), Re::Err ("re:92] Option is None".into()))}

  // cargo bench --features nightly,re

  fn foobar (succ: bool) -> Re<bool> {
    if test::black_box (succ) {Re::Ok (true)} else {Re::fail ("!succ")}}

  fn bang (succ: bool) -> Re<()> {
    let b = test::black_box (foobar (succ)?);
    assert_eq! (true, b);
    Re::Ok(())}

  #[bench] fn err (bm: &mut test::Bencher) {
    bm.iter (|| {
      let e = bang (false) .err().unwrap();
      assert! (e.starts_with ("re:"));
      assert! (e.ends_with ("] !succ"))})}

  #[bench] fn ok (bm: &mut test::Bencher) {
    bm.iter (|| {bang (true) .expect ("!bang")})}}
<|endoftext|>


<commit_before>#[crate_id = "main#0.2.1"];
#[crate_type = "lib"];
#[no_std];
#[feature(asm, macro_rules)];

extern crate core;

#[cfg(target_arch = "x86")]
pub use platform::runtime::{memset, memcpy, memmove};
#[cfg(target_arch = "arm")]
pub use support::{memcpy, memmove};

use platform::{cpu, io, drivers};
use kernel::util;

mod macros;

pub mod kernel;

#[cfg(target_arch = "arm")]
#[path = "rust-core/support.rs"]
mod support;

#[allow(dead_code)]
#[cfg(target_arch = "x86")]
#[path = "arch/x86/"]
mod platform {
    pub mod cpu;
    pub mod io;
    pub mod drivers;
    pub mod runtime;
}

#[allow(dead_code)]
#[cfg(target_arch = "arm")]
#[path = "arch/arm/"]
mod platform {
    pub mod cpu;
    pub mod io;
    pub mod drivers;
}
<commit_msg>version 0.2.2<commit_after>#[crate_id = "main#0.2.2"];
#[crate_type = "lib"];
#[no_std];
#[feature(asm, macro_rules)];

extern crate core;

#[cfg(target_arch = "x86")]
pub use platform::runtime::{memset, memcpy, memmove};
#[cfg(target_arch = "arm")]
pub use support::{memcpy, memmove};

use platform::{cpu, io, drivers};
use kernel::util;

mod macros;

pub mod kernel;

#[cfg(target_arch = "arm")]
#[path = "rust-core/support.rs"]
mod support;

#[allow(dead_code)]
#[cfg(target_arch = "x86")]
#[path = "arch/x86/"]
mod platform {
    pub mod cpu;
    pub mod io;
    pub mod drivers;
    pub mod runtime;
}

#[allow(dead_code)]
#[cfg(target_arch = "arm")]
#[path = "arch/arm/"]
mod platform {
    pub mod cpu;
    pub mod io;
    pub mod drivers;
}
<|endoftext|>


<commit_before>extern crate syn;
use syn::*;

#[test]
fn test_unit() {
    let raw = "struct Unit;";

    let expected = MacroInput {
        ident: "Unit".into(),
        vis: Visibility::Inherited,
        attrs: Vec::new(),
        generics: Generics::default(),
        body: Body::Struct(VariantData::Unit),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}

#[test]
fn test_struct() {
    let raw = "
        #[derive(Debug, Clone)]
        pub struct Item {
            pub ident: Ident,
            pub attrs: Vec<Attribute>,
        }
    ";

    let expected = MacroInput {
        ident: "Item".into(),
        vis: Visibility::Public,
        attrs: vec![
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::List("derive".into(), vec![
                    MetaItem::Word("Debug".into()),
                    MetaItem::Word("Clone".into()),
                ]),
                is_sugared_doc: false,
            },
        ],
        generics: Generics::default(),
        body: Body::Struct(VariantData::Struct(vec![
            Field {
                ident: Some("ident".into()),
                vis: Visibility::Public,
                attrs: Vec::new(),
                ty: Ty::Path(None, "Ident".into()),
            },
            Field {
                ident: Some("attrs".into()),
                vis: Visibility::Public,
                attrs: Vec::new(),
                ty: Ty::Path(None, Path {
                    global: false,
                    segments: vec![
                        PathSegment {
                            ident: "Vec".into(),
                            parameters: PathParameters::AngleBracketed(
                                AngleBracketedParameterData {
                                    lifetimes: Vec::new(),
                                    types: vec![Ty::Path(None, "Attribute".into())],
                                    bindings: Vec::new(),
                                },
                            ),
                        }
                    ],
                }),
            },
        ])),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}

#[test]
fn test_enum() {
    let raw = "
        /// See the std::result module documentation for details.
        #[must_use]
        pub enum Result<T, E> {
            Ok(T),
            Err(E),
            Surprise = 0isize,
        }
    ";

    let expected = MacroInput {
        ident: "Result".into(),
        vis: Visibility::Public,
        attrs: vec![
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::NameValue(
                    "doc".into(),
                    Lit::Str(
                        "/// See the std::result module documentation for details.".into(),
                        StrStyle::Cooked,
                    ),
                ),
                is_sugared_doc: true,
            },
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::Word("must_use".into()),
                is_sugared_doc: false,
            },
        ],
        generics: Generics {
            lifetimes: Vec::new(),
            ty_params: vec![
                TyParam {
                    ident: "T".into(),
                    bounds: Vec::new(),
                    default: None,
                },
                TyParam {
                    ident: "E".into(),
                    bounds: Vec::new(),
                    default: None,
                },
            ],
            where_clause: WhereClause { predicates: Vec::new() },
        },
        body: Body::Enum(vec![
            Variant {
                ident: "Ok".into(),
                attrs: Vec::new(),
                data: VariantData::Tuple(vec![
                    Field {
                        ident: None,
                        vis: Visibility::Inherited,
                        attrs: Vec::new(),
                        ty: Ty::Path(None, "T".into()),
                    },
                ]),
                discriminant: None,
            },
            Variant {
                ident: "Err".into(),
                attrs: Vec::new(),
                data: VariantData::Tuple(vec![
                    Field {
                        ident: None,
                        vis: Visibility::Inherited,
                        attrs: Vec::new(),
                        ty: Ty::Path(None, "E".into()),
                    },
                ]),
                discriminant: None,
            },
            Variant {
                ident: "Surprise".into(),
                attrs: Vec::new(),
                data: VariantData::Unit,
                discriminant: Some(Discriminant {
                    value: 0,
                    ty: IntTy::Isize,
                }),
            },
        ]),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}
<commit_msg>Fix discriminant in test<commit_after>extern crate syn;
use syn::*;

#[test]
fn test_unit() {
    let raw = "struct Unit;";

    let expected = MacroInput {
        ident: "Unit".into(),
        vis: Visibility::Inherited,
        attrs: Vec::new(),
        generics: Generics::default(),
        body: Body::Struct(VariantData::Unit),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}

#[test]
fn test_struct() {
    let raw = "
        #[derive(Debug, Clone)]
        pub struct Item {
            pub ident: Ident,
            pub attrs: Vec<Attribute>,
        }
    ";

    let expected = MacroInput {
        ident: "Item".into(),
        vis: Visibility::Public,
        attrs: vec![
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::List("derive".into(), vec![
                    MetaItem::Word("Debug".into()),
                    MetaItem::Word("Clone".into()),
                ]),
                is_sugared_doc: false,
            },
        ],
        generics: Generics::default(),
        body: Body::Struct(VariantData::Struct(vec![
            Field {
                ident: Some("ident".into()),
                vis: Visibility::Public,
                attrs: Vec::new(),
                ty: Ty::Path(None, "Ident".into()),
            },
            Field {
                ident: Some("attrs".into()),
                vis: Visibility::Public,
                attrs: Vec::new(),
                ty: Ty::Path(None, Path {
                    global: false,
                    segments: vec![
                        PathSegment {
                            ident: "Vec".into(),
                            parameters: PathParameters::AngleBracketed(
                                AngleBracketedParameterData {
                                    lifetimes: Vec::new(),
                                    types: vec![Ty::Path(None, "Attribute".into())],
                                    bindings: Vec::new(),
                                },
                            ),
                        }
                    ],
                }),
            },
        ])),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}

#[test]
fn test_enum() {
    let raw = "
        /// See the std::result module documentation for details.
        #[must_use]
        pub enum Result<T, E> {
            Ok(T),
            Err(E),
            Surprise = 0isize,
        }
    ";

    let expected = MacroInput {
        ident: "Result".into(),
        vis: Visibility::Public,
        attrs: vec![
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::NameValue(
                    "doc".into(),
                    Lit::Str(
                        "/// See the std::result module documentation for details.".into(),
                        StrStyle::Cooked,
                    ),
                ),
                is_sugared_doc: true,
            },
            Attribute {
                style: AttrStyle::Outer,
                value: MetaItem::Word("must_use".into()),
                is_sugared_doc: false,
            },
        ],
        generics: Generics {
            lifetimes: Vec::new(),
            ty_params: vec![
                TyParam {
                    ident: "T".into(),
                    bounds: Vec::new(),
                    default: None,
                },
                TyParam {
                    ident: "E".into(),
                    bounds: Vec::new(),
                    default: None,
                },
            ],
            where_clause: WhereClause { predicates: Vec::new() },
        },
        body: Body::Enum(vec![
            Variant {
                ident: "Ok".into(),
                attrs: Vec::new(),
                data: VariantData::Tuple(vec![
                    Field {
                        ident: None,
                        vis: Visibility::Inherited,
                        attrs: Vec::new(),
                        ty: Ty::Path(None, "T".into()),
                    },
                ]),
                discriminant: None,
            },
            Variant {
                ident: "Err".into(),
                attrs: Vec::new(),
                data: VariantData::Tuple(vec![
                    Field {
                        ident: None,
                        vis: Visibility::Inherited,
                        attrs: Vec::new(),
                        ty: Ty::Path(None, "E".into()),
                    },
                ]),
                discriminant: None,
            },
            Variant {
                ident: "Surprise".into(),
                attrs: Vec::new(),
                data: VariantData::Unit,
                discriminant: Some(ConstExpr::Lit(Lit::Int(0, IntTy::Isize))),
            },
        ]),
    };

    assert_eq!(expected, parse_macro_input(raw).unwrap());
}
<|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);
                            }
                            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();
            }
        }
    }
}
<commit_msg>Debug to serial when orbital started<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() || ! self.draw {
                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|>


<commit_before>extern crate limonite;

use limonite::codegen::llvm::LLVMGenerator;
use limonite::syntax::expr::{Expr, ExprWrapper};
use limonite::syntax::op::InfixOp;
use limonite::syntax::literals::Literals;

use std::mem::transmute;

macro_rules! block {
    ($($args:tt)*) => {
        ExprWrapper::default(Expr::Block(vec![$($args)*]))
    }
}

macro_rules! var {
    ($arg:expr) => {
        ExprWrapper::default(Expr::Var($arg.into()))
    }
}

macro_rules! ret {
    () => {
        ExprWrapper::default(Expr::Return(None))
    };
    ($arg:expr) => {
        ExprWrapper::default(Expr::Return(Some($arg)))
    };
}

macro_rules! u8 {
    ($arg:tt) => {
        ExprWrapper::default(Expr::Literal(Literals::U8Num($arg)))
    }
}

macro_rules! string {
    ($arg:tt) => {
        ExprWrapper::default(Expr::Literal(Literals::UTF8String($arg.into())))
    }
}

macro_rules! op {
    ($left_arg:expr, + $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Add, $left_arg, $right_arg))
    };
    ($left_arg:expr, = $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, $right_arg))
    };
    ($left_arg:expr, < $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Lt, $left_arg, $right_arg))
    };
    ($left_arg:expr, > $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Gt, $left_arg, $right_arg))
    };
}

macro_rules! assign {
    ($left_arg:expr, = $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, $right_arg))
    };
    ($left_arg:expr, += $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, ExprWrapper::default(Expr::InfixOp(InfixOp::Add, $left_arg, $right_arg))))
    };
    ($left_arg:expr, -= $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, ExprWrapper::default(Expr::InfixOp(InfixOp::Sub, $left_arg, $right_arg))))
    };
}

#[test]
fn test_sum_function() {
    // Creates a limonite function that looks like:
    // fn add_two_ints(left: u64, right: u64) -> u64,
    //     return left + right;

    let ret = ret!(op!(var!("left"), + var!("right")));
    let fn_args = vec![("left".into(), "u64".into()), ("right".into(), "u64".into())];
    let ast = ExprWrapper::default(Expr::FnDecl("add_two_ints".into(), fn_args, Some("u64".into()), ret));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("add_two_ints").expect("Could not find function address");

    let add_two_ints: extern "C" fn(u64, u64) -> u64 = unsafe { transmute(address) };

    assert_eq!(add_two_ints(456, 987), 1443);
}

#[test]
fn test_while_lt_increment_u8() {
    // Creates a limonite function that looks like:
    // fn inc_until() -> u8,
    //     var i = 0u8;
    //
    //     while i < 10,
    //         i += 1
    //
    //     return i

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "i".into(), Some("u8".into()), u8!(0)));
    let loop_cond = op!(var!("i"), < u8!(10));
    let loop_body = assign!(var!("i"), += u8!(1));
    let while_loop = ExprWrapper::default(Expr::WhileLoop(loop_cond, loop_body));
    let ret = ret!(var!("i"));
    let body = block![
        var_decl,
        while_loop,
        ret
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("inc_until".into(), Vec::new(), Some("u8".into()), body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("inc_until").expect("Could not find function address");

    let inc_until: extern "C" fn() -> u8 = unsafe { transmute(address) };

    assert_eq!(inc_until(), 10);
}

#[test]
fn test_while_gt_decrement_u8() {
    // Creates a limonite function that looks like:
    // fn dec_until() -> u8,
    //     var i = 10u8;
    //
    //     while i > 0,
    //         i -= 1
    //
    //     return i

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "i".into(), Some("u8".into()), u8!(10)));
    let loop_cond = op!(var!("i"), > u8!(0));
    let loop_body = assign!(var!("i"), -= u8!(1));
    let while_loop = ExprWrapper::default(Expr::WhileLoop(loop_cond, loop_body));
    let ret = ret!(var!("i"));
    let body = block![
        var_decl,
        while_loop,
        ret
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("dec_until".into(), Vec::new(), Some("u8".into()), body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("dec_until").expect("Could not find function address");

    let dec_until: extern "C" fn() -> u8 = unsafe { transmute(address) };

    assert_eq!(dec_until(), 0);
}

#[test]
fn test_hello_world() {
    // Creates a limonite function that looks like:
    // fn hello_world(),
    //     var s = "Hello, World!";
    //     print(s)
    //     return

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "s".into(), Some("std.string.String".into()), string!("Hello, World!")));
    let print_call = ExprWrapper::default(Expr::FnCall("print".into(), vec![var!("s")]));

    let body = block![
        var_decl,
        print_call,
        ret!(),
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("hello_world".into(), Vec::new(), None, body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, true);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("hello_world").expect("Could not find function address");

    let hello_world: extern "C" fn() = unsafe { transmute(address) };

    // REVIEW: Is there a way to capture stdout to ensure the right text is being printed?

    hello_world();
}
<commit_msg>Small cleanup<commit_after>extern crate limonite;

use limonite::codegen::llvm::LLVMGenerator;
use limonite::syntax::expr::{Expr, ExprWrapper};
use limonite::syntax::op::InfixOp;
use limonite::syntax::literals::Literals;

use std::mem::transmute;

macro_rules! block {
    ($($args:tt)*) => {
        ExprWrapper::default(Expr::Block(vec![$($args)*]))
    }
}

macro_rules! var {
    ($arg:expr) => {
        ExprWrapper::default(Expr::Var($arg.into()))
    }
}

macro_rules! ret {
    () => {
        ExprWrapper::default(Expr::Return(None))
    };
    ($arg:expr) => {
        ExprWrapper::default(Expr::Return(Some($arg)))
    };
}

macro_rules! u8 {
    ($arg:tt) => {
        ExprWrapper::default(Expr::Literal(Literals::U8Num($arg)))
    }
}

macro_rules! string {
    ($arg:tt) => {
        ExprWrapper::default(Expr::Literal(Literals::UTF8String($arg.into())))
    }
}

macro_rules! op {
    ($left_arg:expr, + $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Add, $left_arg, $right_arg))
    };
    ($left_arg:expr, < $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Lt, $left_arg, $right_arg))
    };
    ($left_arg:expr, > $right_arg:expr) => {
        ExprWrapper::default(Expr::InfixOp(InfixOp::Gt, $left_arg, $right_arg))
    };
}

macro_rules! assign {
    ($left_arg:expr, = $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, $right_arg))
    };
    ($left_arg:expr, += $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, ExprWrapper::default(Expr::InfixOp(InfixOp::Add, $left_arg, $right_arg))))
    };
    ($left_arg:expr, -= $right_arg:expr) => {
        ExprWrapper::default(Expr::Assign($left_arg, ExprWrapper::default(Expr::InfixOp(InfixOp::Sub, $left_arg, $right_arg))))
    };
}

#[test]
fn test_sum_function() {
    // Creates a limonite function that looks like:
    // fn add_two_ints(left: u64, right: u64) -> u64,
    //     return left + right

    let ret = ret!(op!(var!("left"), + var!("right")));
    let fn_args = vec![("left".into(), "u64".into()), ("right".into(), "u64".into())];
    let ast = ExprWrapper::default(Expr::FnDecl("add_two_ints".into(), fn_args, Some("u64".into()), ret));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("add_two_ints").expect("Could not find function address");

    let add_two_ints: extern "C" fn(u64, u64) -> u64 = unsafe { transmute(address) };

    assert_eq!(add_two_ints(456, 987), 1443);
}

#[test]
fn test_while_lt_increment_u8() {
    // Creates a limonite function that looks like:
    // fn inc_until() -> u8,
    //     var i = 0u8
    //
    //     while i < 10,
    //         i += 1
    //
    //     return i

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "i".into(), Some("u8".into()), u8!(0)));
    let loop_cond = op!(var!("i"), < u8!(10));
    let loop_body = assign!(var!("i"), += u8!(1));
    let while_loop = ExprWrapper::default(Expr::WhileLoop(loop_cond, loop_body));
    let ret = ret!(var!("i"));
    let body = block![
        var_decl,
        while_loop,
        ret
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("inc_until".into(), Vec::new(), Some("u8".into()), body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("inc_until").expect("Could not find function address");

    let inc_until: extern "C" fn() -> u8 = unsafe { transmute(address) };

    assert_eq!(inc_until(), 10);
}

#[test]
fn test_while_gt_decrement_u8() {
    // Creates a limonite function that looks like:
    // fn dec_until() -> u8,
    //     var i = 10u8
    //
    //     while i > 0,
    //         i -= 1
    //
    //     return i

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "i".into(), Some("u8".into()), u8!(10)));
    let loop_cond = op!(var!("i"), > u8!(0));
    let loop_body = assign!(var!("i"), -= u8!(1));
    let while_loop = ExprWrapper::default(Expr::WhileLoop(loop_cond, loop_body));
    let ret = ret!(var!("i"));
    let body = block![
        var_decl,
        while_loop,
        ret
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("dec_until".into(), Vec::new(), Some("u8".into()), body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, false);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("dec_until").expect("Could not find function address");

    let dec_until: extern "C" fn() -> u8 = unsafe { transmute(address) };

    assert_eq!(dec_until(), 0);
}

#[test]
fn test_hello_world() {
    // Creates a limonite function that looks like:
    // fn hello_world(),
    //     var s = "Hello, World!"
    //     print(s)
    //     return

    let var_decl = ExprWrapper::default(Expr::VarDecl(false, "s".into(), Some("std.string.String".into()), string!("Hello, World!")));
    let print_call = ExprWrapper::default(Expr::FnCall("print".into(), vec![var!("s")]));

    let body = block![
        var_decl,
        print_call,
        ret!(),
    ];
    let ast = ExprWrapper::default(Expr::FnDecl("hello_world".into(), Vec::new(), None, body));

    let mut llvm_generator = LLVMGenerator::new();

    llvm_generator.add_module(ast, false, true);
    llvm_generator.initialize(true);

    let address = llvm_generator.get_function_address("hello_world").expect("Could not find function address");

    let hello_world: extern "C" fn() = unsafe { transmute(address) };

    // REVIEW: Is there a way to capture stdout to ensure the right text is being printed?

    hello_world();
}
<|endoftext|>


<commit_before>extern crate neli;
use neli::consts::{CtrlAttr, CtrlCmd, GenlId, NlFamily, NlmF, Nlmsg};
use neli::err::NlError;
use neli::genl::Genlmsghdr;
use neli::nl::Nlmsghdr;
use neli::nlattr::Nlattr;
use neli::socket::NlSocket;
use neli::Nl;
use neli::StreamReadBuffer;

const GENL_VERSION: u8 = 2;

// This example attempts to mimic the "genl ctrl list" command. For simplicity, it only outputs
// the name and identifier of each generic netlink family.

fn main() -> Result<(), NlError> {
    let mut socket = NlSocket::connect(NlFamily::Generic, None, None, true)?;

    let attrs: Vec<Nlattr<CtrlAttr>> = vec![];
    let genlhdr = Genlmsghdr::new(CtrlCmd::Getfamily, GENL_VERSION, attrs)?;
    let nlhdr = {
        let len = None;
        let nl_type = GenlId::Ctrl;
        let flags = vec![NlmF::Request, NlmF::Dump];
        let seq = None;
        let pid = None;
        let payload = genlhdr;
        Nlmsghdr::new(len, nl_type, flags, seq, pid, payload)
    };
    socket.send_nl(nlhdr)?;

    loop {
        let response = socket.recv_nl::<Nlmsg, Genlmsghdr<CtrlCmd>>(None)?;
        match response.nl_type {
            // This example could be improved by reinterpreting the payload as an Nlmsgerr struct
            // and printing the specific error encountered.
            Nlmsg::Error => panic!("An error occurred while retrieving available families."),
            Nlmsg::Done => break,
            _ => (),
        };

        let mut handle = response.nl_payload.get_attr_handle::<CtrlAttr>();
        handle.parse_nested_attributes()?;

        for attr in handle.iter().unwrap() {
            match &attr.nla_type {
                CtrlAttr::FamilyName => {
                    let mut mem = StreamReadBuffer::new(&attr.payload);
                    mem.set_size_hint(attr.payload.len() - 1);
                    let name = String::deserialize(&mut mem)?;
                    println!("{}", name);
                }
                CtrlAttr::FamilyId => {
                    let mut mem = StreamReadBuffer::new(&attr.payload);
                    let id = u16::deserialize(&mut mem)?;
                    println!("\tID: 0x{:x}", id);
                }
                _ => {}
            }
        }
    }

    Ok(())
}
<commit_msg>Use .iter() for parsing ctrl list packets<commit_after>extern crate neli;
use neli::consts::{CtrlAttr, CtrlCmd, GenlId, NlFamily, NlmF, Nlmsg};
use neli::err::NlError;
use neli::genl::Genlmsghdr;
use neli::nl::Nlmsghdr;
use neli::nlattr::Nlattr;
use neli::socket::NlSocket;
use neli::Nl;
use neli::StreamReadBuffer;

const GENL_VERSION: u8 = 2;

// This example attempts to mimic the "genl ctrl list" command. For simplicity, it only outputs
// the name and identifier of each generic netlink family.

fn main() -> Result<(), NlError> {
    let mut socket = NlSocket::connect(NlFamily::Generic, None, None, true)?;

    let attrs: Vec<Nlattr<CtrlAttr>> = vec![];
    let genlhdr = Genlmsghdr::new(CtrlCmd::Getfamily, GENL_VERSION, attrs)?;
    let nlhdr = {
        let len = None;
        let nl_type = GenlId::Ctrl;
        let flags = vec![NlmF::Request, NlmF::Dump];
        let seq = None;
        let pid = None;
        let payload = genlhdr;
        Nlmsghdr::new(len, nl_type, flags, seq, pid, payload)
    };
    socket.send_nl(nlhdr)?;

    let mut iter = socket.iter::<Nlmsg, Genlmsghdr<CtrlCmd>>();
    while let Some(Ok(response)) = iter.next() {
        match response.nl_type {
            // This example could be improved by reinterpreting the payload as an Nlmsgerr struct
            // and printing the specific error encountered.
            Nlmsg::Error => panic!("An error occurred while retrieving available families."),
            Nlmsg::Done => break,
            _ => (),
        };

        let mut handle = response.nl_payload.get_attr_handle::<CtrlAttr>();
        handle.parse_nested_attributes()?;

        for attr in handle.iter().unwrap() {
            match &attr.nla_type {
                CtrlAttr::FamilyName => {
                    let mut mem = StreamReadBuffer::new(&attr.payload);
                    mem.set_size_hint(attr.payload.len() - 1);
                    let name = String::deserialize(&mut mem)?;
                    println!("{}", name);
                }
                CtrlAttr::FamilyId => {
                    let mut mem = StreamReadBuffer::new(&attr.payload);
                    let id = u16::deserialize(&mut mem)?;
                    println!("\tID: 0x{:x}", id);
                }
                _ => {}
            }
        }
    }

    Ok(())
}
<|endoftext|>


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

use xmpp_send::XmppSend;
use xmpp_socket::XmppSocket;
use ns;

///
///
///
pub struct XmppServerHandler {
    pub socket: XmppSocket
}

///
///
///
impl XmppServerHandler {

    /// start XMPP stream from server side
    ///
    /// to be called after we've received <stream:stream> from client
    /// as defined in RFC3920
    /// http://xmpp.org/rfcs/rfc3920.html#streams
    ///
    /// domain is the domain served by this connection
    pub fn start_stream(&mut self, domain: &str) -> IoResult<()> {
        let start = format!(
            "<?xml version='1.0'?>\n\
            <stream:stream \
                xmlns:stream='{}'
                xmlns='{}' \
                version='1.0' \
                from='{}'\
                id='{}'
            >",
            ns::STREAMS,
            ns::JABBER_CLIENT,
            domain,
            "arandomid"
        );
        self.send(start)
    }

    /// advertize the security features provided by the server
    ///
    /// must be send right after the server has sent its own
    /// <stream:stream> (without waiting for client answer)
    /// and BEFORE non-security features are advertized, as define
    /// in RFC3920 section 4.6
    pub fn advertize_security_features(&mut self) -> IoResult<()> {

        // TODO the list of SASL mechanism provided should be extensible
        // rather than hardcoded
        let features = format!(
            "<stream:features>\
                <mechanisms xmlns='{sasl}'>\
                    <mechanism>PLAIN</mechanism>\
                </mechanisms>\
            </stream:features>",
            sasl= ns::FEATURE_SASL
        );

        self.send(features)
    }

    pub fn close_stream(&mut self) -> IoResult<()> {
        self.send("</stream:stream>")
    }

    pub fn send<T: XmppSend>(&mut self, data: T) -> IoResult<()> {
        let data = data.xmpp_str();
        println!("Out: {}", data);
        try!(self.socket.write(data.as_slice().as_bytes()));
        self.socket.flush()
    }
}

<commit_msg>forgot some backslash for multi-line string in start_stream<commit_after>use std::io::IoResult;

use xmpp_send::XmppSend;
use xmpp_socket::XmppSocket;
use ns;

///
///
///
pub struct XmppServerHandler {
    pub socket: XmppSocket
}

///
///
///
impl XmppServerHandler {

    /// start XMPP stream from server side
    ///
    /// to be called after we've received <stream:stream> from client
    /// as defined in RFC3920
    /// http://xmpp.org/rfcs/rfc3920.html#streams
    ///
    /// domain is the domain served by this connection
    pub fn start_stream(&mut self, domain: &str) -> IoResult<()> {
        let start = format!(
            "<?xml version='1.0'?>\n\
            <stream:stream \
                xmlns:stream='{}' \
                xmlns='{}' \
                version='1.0' \
                from='{}'\
                id='{}' \
            >",
            ns::STREAMS,
            ns::JABBER_CLIENT,
            domain,
            "arandomid"
        );
        self.send(start)
    }

    /// advertize the security features provided by the server
    ///
    /// must be send right after the server has sent its own
    /// <stream:stream> (without waiting for client answer)
    /// and BEFORE non-security features are advertized, as define
    /// in RFC3920 section 4.6
    pub fn advertize_security_features(&mut self) -> IoResult<()> {

        // TODO the list of SASL mechanism provided should be extensible
        // rather than hardcoded
        let features = format!(
            "<stream:features>\
                <mechanisms xmlns='{sasl}'>\
                    <mechanism>PLAIN</mechanism>\
                </mechanisms>\
            </stream:features>",
            sasl= ns::FEATURE_SASL
        );

        self.send(features)
    }

    pub fn close_stream(&mut self) -> IoResult<()> {
        self.send("</stream:stream>")
    }

    pub fn send<T: XmppSend>(&mut self, data: T) -> IoResult<()> {
        let data = data.xmpp_str();
        println!("Out: {}", data);
        try!(self.socket.write(data.as_slice().as_bytes()));
        self.socket.flush()
    }
}

<|endoftext|>


<commit_before>extern crate elf;
extern crate getopts;

use getopts::Options;
use std::cmp;
use std::env;
use std::fs::File;
use std::io;
use std::io::Write;
use std::mem;
use std::path::Path;
use std::slice;

#[repr(C)]
#[derive(Clone, Copy, Debug)]
struct LoadInfo {
    total_size: u32,
    entry_offset: u32,
    rel_data_offset: u32,
    rel_data_size: u32,
    text_offset: u32,
    text_size: u32,
    got_offset: u32,
    got_size: u32,
    data_offset: u32,
    data_size: u32,
    bss_start_offset: u32,
    bss_size: u32,
    pkg_name_offset: u32,
    pkg_name_size: u32,
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("o", "", "set output file name", "OUTFILE");
    opts.optopt("n", "", "set package name", "PKG_NAME");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    let output = matches.opt_str("o");
    let pkg_name = matches.opt_str("n");
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    let path = Path::new(&input);
    let file = match elf::File::open_path(&path) {
        Ok(f) => f,
        Err(e) => panic!("Error: {:?}", e),
    };

    match output {
            None => {
                let mut out = io::stdout();
                do_work(&file, &mut out, pkg_name)
            }
            Some(name) => {
                match File::create(Path::new(&name)) {
                    Ok(mut f) => do_work(&file, &mut f, pkg_name),
                    Err(e) => panic!("Error: {:?}", e),
                }
            }
        }
        .expect("Failed to write output");
}

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [-o OUTFILE] FILE", program);
    print!("{}", opts.usage(&brief));
}

fn get_section<'a>(input: &'a elf::File, name: &str) -> elf::Section {
    match input.get_section(name) {
        Some(section) => {
            elf::Section {
                data: section.data.clone(),
                shdr: section.shdr.clone(),
            }
        }
        None => {
            elf::Section {
                data: Vec::new(),
                shdr: elf::types::SectionHeader {
                    name: String::from(name),
                    shtype: elf::types::SHT_NULL,
                    flags: elf::types::SHF_NONE,
                    addr: 0,
                    offset: 0,
                    size: 0,
                    link: 0,
                    info: 0,
                    addralign: 0,
                    entsize: 0,
                },
            }
        }
    }
}

unsafe fn as_byte_slice<'a, T: Copy>(input: &'a T) -> &'a [u8] {
    slice::from_raw_parts(input as *const T as *const u8, mem::size_of::<T>())
}

fn do_work(input: &elf::File, output: &mut Write, pkg_name: Option<String>) -> io::Result<()> {
    let pkg_name = pkg_name.unwrap_or(String::new());
    let (rel_data_size, rel_data) = match input.sections
        .iter()
        .find(|section| section.shdr.name == ".rel.data".as_ref()) {
        Some(section) => (section.shdr.size, section.data.as_ref()),
        None => (0 as u64, &[] as &[u8]),

    };
    let text = get_section(input, ".text");
    let got = get_section(input, ".got");
    let data = get_section(input, ".data");
    let bss = get_section(input, ".bss");

    let mut total_len = (mem::size_of::<LoadInfo>() + rel_data.len() + text.data.len() +
                         got.data.len() + data.data.len() +
                         pkg_name.len()) as u32;

    let pad = if total_len.count_ones() > 1 {
        let power2len = 1 << (32 - total_len.leading_zeros());
        power2len - total_len
    } else {
        0
    };
    total_len = total_len + pad;

    let rel_data_offset = mem::size_of::<LoadInfo>() as u32;
    let text_offset = rel_data_offset + (rel_data_size as u32);
    let text_size = text.shdr.size as u32;
    let entry_offset = (input.ehdr.entry ^ 0x80000000) as u32 + text_offset;
    let got_offset = text_offset + text_size;
    let got_size = got.shdr.size as u32;
    let data_offset = got_offset + got_size;
    let data_size = data.shdr.size as u32;
    let pkg_name_offset = got_offset + got_size;
    let pkg_name_size = pkg_name.len() as u32;

    let load_info = LoadInfo {
        total_size: total_len,
        entry_offset: entry_offset,
        rel_data_offset: rel_data_offset,
        rel_data_size: rel_data_size as u32,
        text_offset: text_offset,
        text_size: text_size,
        got_offset: got_offset,
        got_size: got_size,
        data_offset: data_offset,
        data_size: data_size,
        bss_start_offset: bss.shdr.addr as u32,
        bss_size: bss.shdr.size as u32,
        pkg_name_offset: pkg_name_offset,
        pkg_name_size: pkg_name_size,
    };

    try!(output.write_all(unsafe { as_byte_slice(&load_info) }));
    try!(output.write_all(rel_data.as_ref()));
    try!(output.write_all(text.data.as_ref()));
    try!(output.write_all(got.data.as_ref()));
    try!(output.write_all(data.data.as_ref()));
    try!(output.write_all(pkg_name.as_ref()));

    let mut pad = pad as usize;
    let zero_buf = [0u8; 512];
    while pad > 0 {
        let amount_to_write = cmp::min(zero_buf.len(), pad);
        pad -= try!(output.write(&zero_buf[..amount_to_write]));
    }

    Ok(())
}
<commit_msg>Fix elf2bin pkg_name offset when got not empty<commit_after>extern crate elf;
extern crate getopts;

use getopts::Options;
use std::cmp;
use std::env;
use std::fs::File;
use std::io;
use std::io::Write;
use std::mem;
use std::path::Path;
use std::slice;

#[repr(C)]
#[derive(Clone, Copy, Debug)]
struct LoadInfo {
    total_size: u32,
    entry_offset: u32,
    rel_data_offset: u32,
    rel_data_size: u32,
    text_offset: u32,
    text_size: u32,
    got_offset: u32,
    got_size: u32,
    data_offset: u32,
    data_size: u32,
    bss_start_offset: u32,
    bss_size: u32,
    pkg_name_offset: u32,
    pkg_name_size: u32,
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();
    let mut opts = Options::new();
    opts.optopt("o", "", "set output file name", "OUTFILE");
    opts.optopt("n", "", "set package name", "PKG_NAME");

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string()),
    };
    let output = matches.opt_str("o");
    let pkg_name = matches.opt_str("n");
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };

    let path = Path::new(&input);
    let file = match elf::File::open_path(&path) {
        Ok(f) => f,
        Err(e) => panic!("Error: {:?}", e),
    };

    match output {
            None => {
                let mut out = io::stdout();
                do_work(&file, &mut out, pkg_name)
            }
            Some(name) => {
                match File::create(Path::new(&name)) {
                    Ok(mut f) => do_work(&file, &mut f, pkg_name),
                    Err(e) => panic!("Error: {:?}", e),
                }
            }
        }
        .expect("Failed to write output");
}

fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [-o OUTFILE] FILE", program);
    print!("{}", opts.usage(&brief));
}

fn get_section<'a>(input: &'a elf::File, name: &str) -> elf::Section {
    match input.get_section(name) {
        Some(section) => {
            elf::Section {
                data: section.data.clone(),
                shdr: section.shdr.clone(),
            }
        }
        None => {
            elf::Section {
                data: Vec::new(),
                shdr: elf::types::SectionHeader {
                    name: String::from(name),
                    shtype: elf::types::SHT_NULL,
                    flags: elf::types::SHF_NONE,
                    addr: 0,
                    offset: 0,
                    size: 0,
                    link: 0,
                    info: 0,
                    addralign: 0,
                    entsize: 0,
                },
            }
        }
    }
}

unsafe fn as_byte_slice<'a, T: Copy>(input: &'a T) -> &'a [u8] {
    slice::from_raw_parts(input as *const T as *const u8, mem::size_of::<T>())
}

fn do_work(input: &elf::File, output: &mut Write, pkg_name: Option<String>) -> io::Result<()> {
    let pkg_name = pkg_name.unwrap_or(String::new());
    let (rel_data_size, rel_data) = match input.sections
        .iter()
        .find(|section| section.shdr.name == ".rel.data".as_ref()) {
        Some(section) => (section.shdr.size, section.data.as_ref()),
        None => (0 as u64, &[] as &[u8]),

    };
    let text = get_section(input, ".text");
    let got = get_section(input, ".got");
    let data = get_section(input, ".data");
    let bss = get_section(input, ".bss");

    let mut total_len = (mem::size_of::<LoadInfo>() + rel_data.len() + text.data.len() +
                         got.data.len() + data.data.len() +
                         pkg_name.len()) as u32;

    let pad = if total_len.count_ones() > 1 {
        let power2len = 1 << (32 - total_len.leading_zeros());
        power2len - total_len
    } else {
        0
    };
    total_len = total_len + pad;

    let rel_data_offset = mem::size_of::<LoadInfo>() as u32;
    let text_offset = rel_data_offset + (rel_data_size as u32);
    let text_size = text.shdr.size as u32;
    let entry_offset = (input.ehdr.entry ^ 0x80000000) as u32 + text_offset;
    let got_offset = text_offset + text_size;
    let got_size = got.shdr.size as u32;
    let data_offset = got_offset + got_size;
    let data_size = data.shdr.size as u32;
    let pkg_name_offset = data_offset + data_size;
    let pkg_name_size = pkg_name.len() as u32;

    let load_info = LoadInfo {
        total_size: total_len,
        entry_offset: entry_offset,
        rel_data_offset: rel_data_offset,
        rel_data_size: rel_data_size as u32,
        text_offset: text_offset,
        text_size: text_size,
        got_offset: got_offset,
        got_size: got_size,
        data_offset: data_offset,
        data_size: data_size,
        bss_start_offset: bss.shdr.addr as u32,
        bss_size: bss.shdr.size as u32,
        pkg_name_offset: pkg_name_offset,
        pkg_name_size: pkg_name_size,
    };

    try!(output.write_all(unsafe { as_byte_slice(&load_info) }));
    try!(output.write_all(rel_data.as_ref()));
    try!(output.write_all(text.data.as_ref()));
    try!(output.write_all(got.data.as_ref()));
    try!(output.write_all(data.data.as_ref()));
    try!(output.write_all(pkg_name.as_ref()));

    let mut pad = pad as usize;
    let zero_buf = [0u8; 512];
    while pad > 0 {
        let amount_to_write = cmp::min(zero_buf.len(), pad);
        pad -= try!(output.write(&zero_buf[..amount_to_write]));
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate rosc;
extern crate byteorder;

use byteorder::{ByteOrder, BigEndian};
use std::mem;
use rosc::{types, errors, decoder, utils};

#[test]
fn test_decode_no_args() {
    // message to build: /some/valid/address/4 ,
    let raw_addr = "/some/valid/address/4";
    let addr = pad(raw_addr.as_bytes());
    // args
    let type_tags = pad(b",");
    let merged: Vec<u8> = addr.into_iter()
        .chain(type_tags.into_iter())
        .collect();
    let osc_packet: Result<types::OscPacket, errors::OscError> = decoder::decode(&merged);
    assert!(osc_packet.is_ok());
    match osc_packet {
        Ok(types::OscPacket::Message(msg)) => {
                assert_eq!(raw_addr, msg.addr);
                assert!(msg.args.is_none());
        },
        Ok(_) => panic!("OscMessage was expected!"),
        Err(e) => panic!(e)
    }
}

#[test]
fn test_decode_args() {
    // /another/valid/address/123 ,fdih 3.1415 3.14159265359 12345678i32
    // -1234567891011
    let raw_addr = "/another/valid/address/123";
    let addr = pad(raw_addr.as_bytes());
    // args
    let f = 3.1415f32;
    let mut f_bytes: [u8; 4] = [0u8; 4];
    BigEndian::write_f32(&mut f_bytes, f);
    assert_eq!(BigEndian::read_f32(&f_bytes), f);

    let d = 3.14159265359f64;
    let mut d_bytes: [u8; 8] = [0u8; 8];
    BigEndian::write_f64(&mut d_bytes, d);
    assert_eq!(BigEndian::read_f64(&d_bytes), d);

    let i = 12345678i32;
    let i_bytes: [u8; 4] = unsafe {mem::transmute(i.to_be())};

    let l = -1234567891011i64;
    let h_bytes: [u8; 8] = unsafe {mem::transmute(l.to_be())};

    let type_tags = pad(b",fdih");

    let args: Vec<u8> = f_bytes.iter()
        .chain(d_bytes.iter())
        .chain(i_bytes.iter())
        .chain(h_bytes.iter())
        .map(|x| *x)
        .collect::<Vec<u8>>();

    let merged: Vec<u8> = addr.into_iter()
        .chain(type_tags.into_iter())
        .chain(args)
        .collect::<Vec<u8>>();
    let osc_packet: Result<types::OscPacket, errors::OscError> = decoder::decode(&merged);
    assert!(osc_packet.is_ok());
    match osc_packet {
        Ok(packet) => match packet {
            types::OscPacket::Message(msg) => {
                assert_eq!(raw_addr, msg.addr);
                match msg.args {
                    Some(args) => {
                        for arg in args {
                            match arg {
                                types::OscType::OscInt(x) => assert_eq!(i,x),
                                types::OscType::OscLong(x) => assert_eq!(l,x),
                                types::OscType::OscFloat(x) => assert_eq!(f, x),
                                types::OscType::OscDouble(x) => assert_eq!(d, x),
                                _ => panic!()
                            }
                        }
                    },
                    None => panic!()
                }
            },
            _ => panic!()
        },
        Err(e) => panic!(e)
    }
}

fn pad(data: &[u8]) -> Vec<u8> {
    let pad_len: usize = utils::pad(data.len() as u64) as usize;
    let mut v: Vec<u8> = data.iter().cloned().collect();
    while v.len() < pad_len {
        v.push(0u8);
    }
    v
}<commit_msg>Refactor deep nested test<commit_after>extern crate rosc;
extern crate byteorder;

use byteorder::{ByteOrder, BigEndian};
use std::mem;
use rosc::{types, errors, decoder, utils};

#[test]
fn test_decode_no_args() {
    // message to build: /some/valid/address/4 ,
    let raw_addr = "/some/valid/address/4";
    let addr = pad(raw_addr.as_bytes());
    // args
    let type_tags = pad(b",");
    let merged: Vec<u8> = addr.into_iter()
        .chain(type_tags.into_iter())
        .collect();
    let osc_packet: Result<types::OscPacket, errors::OscError> = decoder::decode(&merged);
    assert!(osc_packet.is_ok());
    match osc_packet {
        Ok(types::OscPacket::Message(msg)) => {
                assert_eq!(raw_addr, msg.addr);
                assert!(msg.args.is_none());
        },
        Ok(_) => panic!("OscMessage was expected!"),
        Err(e) => panic!(e)
    }
}

#[test]
fn test_decode_args() {
    // /another/valid/address/123 ,fdih 3.1415 3.14159265359 12345678i32
    // -1234567891011
    let raw_addr = "/another/valid/address/123";
    let addr = pad(raw_addr.as_bytes());
    // args
    let f = 3.1415f32;
    let mut f_bytes: [u8; 4] = [0u8; 4];
    BigEndian::write_f32(&mut f_bytes, f);
    assert_eq!(BigEndian::read_f32(&f_bytes), f);

    let d = 3.14159265359f64;
    let mut d_bytes: [u8; 8] = [0u8; 8];
    BigEndian::write_f64(&mut d_bytes, d);
    assert_eq!(BigEndian::read_f64(&d_bytes), d);

    let i = 12345678i32;
    let i_bytes: [u8; 4] = unsafe {mem::transmute(i.to_be())};

    let l = -1234567891011i64;
    let h_bytes: [u8; 8] = unsafe {mem::transmute(l.to_be())};

    let type_tags = pad(b",fdih");

    let args: Vec<u8> = f_bytes.iter()
        .chain(d_bytes.iter())
        .chain(i_bytes.iter())
        .chain(h_bytes.iter())
        .map(|x| *x)
        .collect::<Vec<u8>>();

    let merged: Vec<u8> = addr.into_iter()
        .chain(type_tags.into_iter())
        .chain(args)
        .collect::<Vec<u8>>();
    let osc_packet: Result<types::OscPacket, errors::OscError> = decoder::decode(&merged);
    match osc_packet {
        Ok(types::OscPacket::Message(msg)) => {
            assert_eq!(raw_addr, msg.addr);
            for arg in msg.args.unwrap() {
                match arg {
                    types::OscType::OscInt(x) => assert_eq!(i, x),
                    types::OscType::OscLong(x) => assert_eq!(l, x),
                    types::OscType::OscFloat(x) => assert_eq!(f, x),
                    types::OscType::OscDouble(x) => assert_eq!(d, x),
                    _ => panic!(),
                }
            }
        }
        Ok(_) => panic!("Expected an OscMessage!"),
        Err(e) => panic!(e),
    }
}

fn pad(data: &[u8]) -> Vec<u8> {
    let pad_len: usize = utils::pad(data.len() as u64) as usize;
    let mut v: Vec<u8> = data.iter().cloned().collect();
    while v.len() < pad_len {
        v.push(0u8);
    }
    v
}<|endoftext|>