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

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//!
//! The rust standard library is available to all rust crates by
//! default, just as if contained an `extern crate std` import at the
//! crate root. Therefore the standard library can be accessed in
//! `use` statements through the path `std`, as in `use std::thread`,
//! or in expressions through the absolute path `::std`, as in
//! `::std::thread::sleep_ms(100)`.
//!
//! Furthermore, the standard library defines [The Rust
//! Prelude](prelude/index.html), a small collection of items, mostly
//! traits, that are imported into and available in every module.
//!
//! ## What is in the standard library
//!
//! The standard library is a set of minimal, battle-tested
//! core types and shared abstractions for the [broader Rust
//! ecosystem](https://crates.io) to build on.
//!
//! The [primitive types](#primitives), though not defined in the
//! standard library, are documented here, as are the predefined
//! [macros](#macros).
//!
//! ## Containers and collections
//!
//! The [`option`](option/index.html) and
//! [`result`](result/index.html) modules define optional and
//! error-handling types, `Option` and `Result`. The
//! [`iter`](iter/index.html) module defines Rust's iterator trait,
//! [`Iterator`](iter/trait.Iterator.html), which works with the `for`
//! loop to access collections.
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! Data may be shared by placing it in a reference-counted box or the
//! [`Rc`](rc/index.html) type, and if further contained in a [`Cell`
//! or `RefCell`](cell/index.html), may be mutated as well as shared.
//! Likewise, in a concurrent setting it is common to pair an
//! atomically-reference-counted box, [`Arc`](sync/struct.Arc.html),
//! with a [`Mutex`](sync/struct.Mutex.html) to get the same effect.
//!
//! The [`collections`](collections/index.html) module defines maps,
//! sets, linked lists and other typical collection types, including
//! the common [`HashMap`](collections/struct.HashMap.html).
//!
//! ## Platform abstractions and I/O
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives.
//!
//! Common types of I/O, including [files](fs/struct.File.html),
//! [TCP](net/struct.TcpStream.html),
//! [UDP](net/struct.UdpSocket.html), are defined in the
//! [`io`](io/index.html), [`fs`](fs/index.html), and
//! [`net`](net/index.html) modules.
//!
//! The [`thread`](thread/index.html) module contains Rust's threading
//! abstractions. [`sync`](sync/index.html) contains further
//! primitive shared memory types, including
//! [`atomic`](sync/atomic/index.html) and
//! [`mpsc`](sync/mpsc/index.html), which contains the channel types
//! for message passing.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(associated_consts)]
#![feature(borrow_state)]
#![feature(box_raw)]
#![feature(box_syntax)]
#![feature(char_internals)]
#![feature(clone_from_slice)]
#![feature(collections)]
#![feature(collections_bound)]
#![feature(const_fn)]
#![feature(core)]
#![feature(core_float)]
#![feature(core_intrinsics)]
#![feature(core_prelude)]
#![feature(core_simd)]
#![feature(fnbox)]
#![feature(heap_api)]
#![feature(int_error_internals)]
#![feature(into_cow)]
#![feature(iter_order)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(macro_reexport)]
#![feature(slice_concat_ext)]
#![feature(slice_position_elem)]
#![feature(no_std)]
#![feature(oom)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(raw)]
#![feature(reflect_marker)]
#![feature(slice_bytes)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(str_internals)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(vec_push_all)]
#![feature(wrapping)]
#![feature(zero_one)]
#![cfg_attr(windows, feature(str_utf16))]
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
#![cfg_attr(test, feature(test, rustc_private, float_consts))]

// Don't link to std. We are std.
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate rustc_unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use rustc_unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod path;
pub mod process;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;
mod rand;

// Some external utilities of the standard library rely on randomness (aka
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
// here. This module is not at all intended for stabilization as-is, however,
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand")]
pub mod __rand {
    pub use rand::{thread_rng, ThreadRng, Rng};
}

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use option; // used for thread_local!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<commit_msg>Fix capitalization in std docs<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//!
//! The Rust Standard Library is available to all Rust crates by
//! default, just as if contained an `extern crate std` import at the
//! crate root. Therefore the standard library can be accessed in
//! `use` statements through the path `std`, as in `use std::thread`,
//! or in expressions through the absolute path `::std`, as in
//! `::std::thread::sleep_ms(100)`.
//!
//! Furthermore, the standard library defines [The Rust
//! Prelude](prelude/index.html), a small collection of items, mostly
//! traits, that are imported into and available in every module.
//!
//! ## What is in the standard library
//!
//! The standard library is a set of minimal, battle-tested
//! core types and shared abstractions for the [broader Rust
//! ecosystem](https://crates.io) to build on.
//!
//! The [primitive types](#primitives), though not defined in the
//! standard library, are documented here, as are the predefined
//! [macros](#macros).
//!
//! ## Containers and collections
//!
//! The [`option`](option/index.html) and
//! [`result`](result/index.html) modules define optional and
//! error-handling types, `Option` and `Result`. The
//! [`iter`](iter/index.html) module defines Rust's iterator trait,
//! [`Iterator`](iter/trait.Iterator.html), which works with the `for`
//! loop to access collections.
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! Data may be shared by placing it in a reference-counted box or the
//! [`Rc`](rc/index.html) type, and if further contained in a [`Cell`
//! or `RefCell`](cell/index.html), may be mutated as well as shared.
//! Likewise, in a concurrent setting it is common to pair an
//! atomically-reference-counted box, [`Arc`](sync/struct.Arc.html),
//! with a [`Mutex`](sync/struct.Mutex.html) to get the same effect.
//!
//! The [`collections`](collections/index.html) module defines maps,
//! sets, linked lists and other typical collection types, including
//! the common [`HashMap`](collections/struct.HashMap.html).
//!
//! ## Platform abstractions and I/O
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives.
//!
//! Common types of I/O, including [files](fs/struct.File.html),
//! [TCP](net/struct.TcpStream.html),
//! [UDP](net/struct.UdpSocket.html), are defined in the
//! [`io`](io/index.html), [`fs`](fs/index.html), and
//! [`net`](net/index.html) modules.
//!
//! The [`thread`](thread/index.html) module contains Rust's threading
//! abstractions. [`sync`](sync/index.html) contains further
//! primitive shared memory types, including
//! [`atomic`](sync/atomic/index.html) and
//! [`mpsc`](sync/mpsc/index.html), which contains the channel types
//! for message passing.

// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/",
       test(no_crate_inject, attr(deny(warnings))),
       test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]

#![feature(alloc)]
#![feature(allow_internal_unstable)]
#![feature(associated_consts)]
#![feature(borrow_state)]
#![feature(box_raw)]
#![feature(box_syntax)]
#![feature(char_internals)]
#![feature(clone_from_slice)]
#![feature(collections)]
#![feature(collections_bound)]
#![feature(const_fn)]
#![feature(core)]
#![feature(core_float)]
#![feature(core_intrinsics)]
#![feature(core_prelude)]
#![feature(core_simd)]
#![feature(fnbox)]
#![feature(heap_api)]
#![feature(int_error_internals)]
#![feature(into_cow)]
#![feature(iter_order)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(macro_reexport)]
#![feature(slice_concat_ext)]
#![feature(slice_position_elem)]
#![feature(no_std)]
#![feature(oom)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(raw)]
#![feature(reflect_marker)]
#![feature(slice_bytes)]
#![feature(slice_patterns)]
#![feature(staged_api)]
#![feature(str_char)]
#![feature(str_internals)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(vec_push_all)]
#![feature(wrapping)]
#![feature(zero_one)]
#![cfg_attr(windows, feature(str_utf16))]
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
#![cfg_attr(test, feature(test, rustc_private, float_consts))]

// Don't link to std. We are std.
#![no_std]

#![allow(trivial_casts)]
#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;

#[allow(deprecated)] extern crate rand as core_rand;
extern crate alloc;
extern crate rustc_unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate std as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::convert;
pub use core::default;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub mod error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use rustc_unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

// NB: slice and str are primitive types too, but their module docs + primitive doc pages
// are inlined from the public re-exports of core_collections::{slice, str} above.

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod path;
pub mod process;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;
mod rand;

// Some external utilities of the standard library rely on randomness (aka
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
// here. This module is not at all intended for stabilization as-is, however,
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand")]
pub mod __rand {
    pub use rand::{thread_rng, ThreadRng, Rng};
}

// Modules that exist purely to document + host impl docs for primitive types

mod array;
mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use option; // used for thread_local!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread; // used for thread_local!
    pub use marker;  // used for tls!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<|endoftext|>


<commit_before>fn md4(msg: [u8]) -> {a: u32, b: u32, c: u32, d: u32} {
    let orig_len = vec::len(msg) * 8u;
    // pad message
    let msg = msg + [0x80u8];
    let bitlen = orig_len + 8u;
    while (bitlen + 64u) % 512u > 0u {
        msg += [0u8];
        bitlen += 8u;
    }
    // append length
    let i = 0u;
    while i < 8u {
        msg += [(orig_len >> (i * 8u)) as u8];
        i += 1u;
    }

    let a = 0x67452301u32;
    let b = 0xefcdab89u32;
    let c = 0x98badcfeu32;
    let d = 0x10325476u32;

    fn rot(r: int, x: u32) -> u32 {
        let r = r as u32;
        (x << r) | (x >> (32u32 - r))
    }

    let i = 0u, e = vec::len(msg);
    let x = vec::init_elt_mut(16u, 0u32);
    while i < e {
        let aa = a, bb = b, cc = c, dd = d;

        let j = 0u, base = i;
        while j < 16u {
            x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
                (msg[base + 2u] as u32 << 16u32) +
                (msg[base + 3u] as u32 << 24u32);
            j += 1u; base += 4u;
        }

        let j = 0u;
        while j < 16u {
            a = rot(3, a + ((b & c) | (!b & d)) + x[j]);
            j += 1u;
            d = rot(7, d + ((a & b) | (!a & c)) + x[j]);
            j += 1u;
            c = rot(11, c + ((d & a) | (!d & b)) + x[j]);
            j += 1u;
            b = rot(19, b + ((c & d) | (!c & a)) + x[j]);
            j += 1u;
        }

        let j = 0u, q = 0x5a827999u32;
        while j < 4u {
            a = rot(3, a + ((b & c) | ((b & d) | (c & d))) + x[j] + q);
            d = rot(5, d + ((a & b) | ((a & c) | (b & c))) + x[j + 4u] + q);
            c = rot(9, c + ((d & a) | ((d & b) | (a & b))) + x[j + 8u] + q);
            b = rot(13, b + ((c & d) | ((c & a) | (d & a))) + x[j + 12u] + q);
            j += 1u;
        }

        let j = 0u, q = 0x6ed9eba1u32;
        while j < 8u {
            let jj = j > 2u ? j - 3u : j;
            a = rot(3, a + (b ^ c ^ d) + x[jj] + q);
            d = rot(9, d + (a ^ b ^ c) + x[jj + 8u] + q);
            c = rot(11, c + (d ^ a ^ b) + x[jj + 4u] + q);
            b = rot(15, b + (c ^ d ^ a) + x[jj + 12u] + q);
            j += 2u;
        }

        a += aa; b += bb; c += cc; d += dd;
        i += 64u;
    }
    ret {a: a, b: b, c: c, d: d};
}

fn md4_str(msg: [u8]) -> str {
    let {a, b, c, d} = md4(msg);
    fn app(a: u32, b: u32, c: u32, d: u32, f: block(u32)) {
        f(a); f(b); f(c); f(d);
    }
    let result = "";
    app(a, b, c, d) {|u|
        let i = 0u32;
        while i < 4u32 {
            let byte = (u >> (i * 8u32)) as u8;
            if byte <= 16u8 { result += "0"; }
            result += uint::to_str(byte as uint, 16u);
            i += 1u32;
        }
    }
    result
}

fn md4_text(msg: str) -> str { md4_str(str::bytes(msg)) }

#[test]
fn test_md4() {
    assert md4_text("") == "31d6cfe0d16ae931b73c59d7e0c089c0";
    assert md4_text("a") == "bde52cb31de33e46245e05fbdbd6fb24";
    assert md4_text("abc") == "a448017aaf21d8525fc10ae87aa6729d";
    assert md4_text("message digest") == "d9130a8164549fe818874806e1c7014b";
    assert md4_text("abcdefghijklmnopqrstuvwxyz") ==
        "d79e1c308aa5bbcdeea8ed63df412da9";
    assert md4_text("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123\
                     456789") == "043f8582f241db351ce627e153e7f0e4";
    assert md4_text("12345678901234567890123456789012345678901234567890123456\
                     789012345678901234567890") ==
        "e33b4ddc9c38f2199c3e7b164fcc0536";
}
<commit_msg>update to use u64; u32 has undefined results<commit_after>fn md4(msg: [u8]) -> {a: u32, b: u32, c: u32, d: u32} {
    // subtle: if orig_len is merely uint, then the code below
    // which performs shifts by 32 bits or more has undefined
    // results.
    let orig_len: u64 = (vec::len(msg) * 8u) as u64;

    // pad message
    let msg = msg + [0x80u8];
    let bitlen = orig_len + 8u;
    while (bitlen + 64u) % 512u > 0u {
        msg += [0u8];
        bitlen += 8u;
    }

    // append length
    let i = 0u;
    while i < 8u {
        msg += [(orig_len >> (i * 8u)) as u8];
        i += 1u;
    }

    let a = 0x67452301u32;
    let b = 0xefcdab89u32;
    let c = 0x98badcfeu32;
    let d = 0x10325476u32;

    fn rot(r: int, x: u32) -> u32 {
        let r = r as u32;
        (x << r) | (x >> (32u32 - r))
    }

    let i = 0u, e = vec::len(msg);
    let x = vec::init_elt_mut(16u, 0u32);
    while i < e {
        let aa = a, bb = b, cc = c, dd = d;

        let j = 0u, base = i;
        while j < 16u {
            x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
                (msg[base + 2u] as u32 << 16u32) +
                (msg[base + 3u] as u32 << 24u32);
            j += 1u; base += 4u;
        }

        let j = 0u;
        while j < 16u {
            a = rot(3, a + ((b & c) | (!b & d)) + x[j]);
            j += 1u;
            d = rot(7, d + ((a & b) | (!a & c)) + x[j]);
            j += 1u;
            c = rot(11, c + ((d & a) | (!d & b)) + x[j]);
            j += 1u;
            b = rot(19, b + ((c & d) | (!c & a)) + x[j]);
            j += 1u;
        }

        let j = 0u, q = 0x5a827999u32;
        while j < 4u {
            a = rot(3, a + ((b & c) | ((b & d) | (c & d))) + x[j] + q);
            d = rot(5, d + ((a & b) | ((a & c) | (b & c))) + x[j + 4u] + q);
            c = rot(9, c + ((d & a) | ((d & b) | (a & b))) + x[j + 8u] + q);
            b = rot(13, b + ((c & d) | ((c & a) | (d & a))) + x[j + 12u] + q);
            j += 1u;
        }

        let j = 0u, q = 0x6ed9eba1u32;
        while j < 8u {
            let jj = j > 2u ? j - 3u : j;
            a = rot(3, a + (b ^ c ^ d) + x[jj] + q);
            d = rot(9, d + (a ^ b ^ c) + x[jj + 8u] + q);
            c = rot(11, c + (d ^ a ^ b) + x[jj + 4u] + q);
            b = rot(15, b + (c ^ d ^ a) + x[jj + 12u] + q);
            j += 2u;
        }

        a += aa; b += bb; c += cc; d += dd;
        i += 64u;
    }
    ret {a: a, b: b, c: c, d: d};
}

fn md4_str(msg: [u8]) -> str {
    let {a, b, c, d} = md4(msg);
    fn app(a: u32, b: u32, c: u32, d: u32, f: block(u32)) {
        f(a); f(b); f(c); f(d);
    }
    let result = "";
    app(a, b, c, d) {|u|
        let i = 0u32;
        while i < 4u32 {
            let byte = (u >> (i * 8u32)) as u8;
            if byte <= 16u8 { result += "0"; }
            result += uint::to_str(byte as uint, 16u);
            i += 1u32;
        }
    }
    result
}

fn md4_text(msg: str) -> str { md4_str(str::bytes(msg)) }

#[test]
fn test_md4() {
    assert md4_text("") == "31d6cfe0d16ae931b73c59d7e0c089c0";
    assert md4_text("a") == "bde52cb31de33e46245e05fbdbd6fb24";
    assert md4_text("abc") == "a448017aaf21d8525fc10ae87aa6729d";
    assert md4_text("message digest") == "d9130a8164549fe818874806e1c7014b";
    assert md4_text("abcdefghijklmnopqrstuvwxyz") ==
        "d79e1c308aa5bbcdeea8ed63df412da9";
    assert md4_text("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123\
                     456789") == "043f8582f241db351ce627e153e7f0e4";
    assert md4_text("12345678901234567890123456789012345678901234567890123456\
                     789012345678901234567890") ==
        "e33b4ddc9c38f2199c3e7b164fcc0536";
}
<|endoftext|>


<commit_before>// Copyright 2017 Dmytro Milinevskyi <dmilinevskyi@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std;

use levels::LogLevel;

/// The markers of the begging of the file and its end.
pub enum LineRangeBound {
    /// Beginning of the file.
    BOF,
    /// End of the file.
    EOF,
}

impl From<LineRangeBound> for u32 {
    #[inline(always)]
    fn from(orig: LineRangeBound) -> u32 {
        match orig {
            LineRangeBound::BOF => 0,
            LineRangeBound::EOF => std::u32::MAX,
        }
    }
}

#[doc(hidden)]
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug)]
pub struct LineRangeSpec {
    pub level: LogLevel,
    pub from: u32,
    pub to: u32,
}

#[doc(hidden)]
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug)]
pub enum LineRangeError {
    InvalidRange(u32, u32),
}

impl LineRangeSpec {
    #[doc(hidden)]
    #[inline(always)]
    pub fn new(level: LogLevel, from: u32, to: u32) -> Result<Self, LineRangeError> {
        if from > to {
            Err(LineRangeError::InvalidRange(from, to))
        } else {
            Ok(LineRangeSpec {
                level: level,
                from: from,
                to: to,
            })
        }
    }
}

impl ToString for LineRangeError {
    fn to_string(&self) -> String {
        match *self {
            LineRangeError::InvalidRange(from, to) => format!("Invalid range [{}; {}]", from, to),
        }
    }
}

#[doc(hidden)]
pub fn prepare_ranges(level: LogLevel, lranges: &[(u32, u32)]) -> Result<Vec<LineRangeSpec>, LineRangeError> {
    let (lranges, fails): (Vec<_>, Vec<_>) = lranges.iter()
        .map(|&(from, to)| LineRangeSpec::new(level, from, to))
        .partition(Result::is_ok);
    if !fails.is_empty() {
        let err = *fails.first().unwrap();
        return Err(err.unwrap_err());
    }

    let mut lranges: Vec<_> = lranges.into_iter().map(Result::unwrap).collect();
    lranges.sort_by_key(|k| k.from);

    // FIXME: merge the ranges

    if lranges.len() == 1 {
        let bof: u32 = LineRangeBound::BOF.into();
        let eof: u32 = LineRangeBound::EOF.into();
        let first = *lranges.first().unwrap();
        if first.from == bof && first.to == eof {
            lranges.clear();
        }
    }

    Ok(lranges)
}
<commit_msg>properly merge line ranges<commit_after>// Copyright 2017 Dmytro Milinevskyi <dmilinevskyi@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

// http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std;

use levels::LogLevel;

/// The markers of the begging of the file and its end.
pub enum LineRangeBound {
    /// Beginning of the file.
    BOF,
    /// End of the file.
    EOF,
}

impl From<LineRangeBound> for u32 {
    #[inline(always)]
    fn from(orig: LineRangeBound) -> u32 {
        match orig {
            LineRangeBound::BOF => 0,
            LineRangeBound::EOF => std::u32::MAX,
        }
    }
}

#[doc(hidden)]
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug)]
pub struct LineRangeSpec {
    pub level: LogLevel,
    pub from: u32,
    pub to: u32,
}

#[doc(hidden)]
#[derive(PartialEq, PartialOrd, Clone, Copy, Debug)]
pub enum LineRangeError {
    InvalidRange(u32, u32),
}

impl LineRangeSpec {
    #[doc(hidden)]
    #[inline(always)]
    pub fn new(level: LogLevel, from: u32, to: u32) -> Result<Self, LineRangeError> {
        if from > to {
            Err(LineRangeError::InvalidRange(from, to))
        } else {
            Ok(LineRangeSpec {
                level: level,
                from: from,
                to: to,
            })
        }
    }
}

impl ToString for LineRangeError {
    fn to_string(&self) -> String {
        match *self {
            LineRangeError::InvalidRange(from, to) => format!("Invalid range [{}; {}]", from, to),
        }
    }
}

#[doc(hidden)]
pub fn prepare_ranges(level: LogLevel, lranges: &[(u32, u32)]) -> Result<Vec<LineRangeSpec>, LineRangeError> {
    if lranges.is_empty() {
        return Ok(Vec::new());
    }

    let (lranges, fails): (Vec<_>, Vec<_>) = lranges.iter()
        .map(|&(from, to)| LineRangeSpec::new(level, from, to))
        .partition(Result::is_ok);
    if !fails.is_empty() {
        let err = *fails.first().unwrap();
        return Err(err.unwrap_err());
    }

    let mut lranges: Vec<_> = lranges.into_iter().map(Result::unwrap).collect();
    lranges.sort_by_key(|k| k.from);

    let mut merged = Vec::new();
    let mut iter = lranges.into_iter();
    let mut prev = iter.next().unwrap();
    while let Some(item) = iter.next() {
        if prev.to >= item.from {
            if prev.to < item.to {
                prev.to = item.to;
            }
        } else {
            merged.push(prev);
            prev = item;
        }
    }
    merged.push(prev);

    if merged.len() == 1 {
        let bof: u32 = LineRangeBound::BOF.into();
        let eof: u32 = LineRangeBound::EOF.into();
        let first = *merged.first().unwrap();
        if first.from == bof && first.to == eof {
            merged.clear();
        }
    }

    Ok(merged)
}

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

    #[test]
    fn test_line_ranges_merged() {
        // empty
        let output = prepare_ranges(LogLevel::TRACE, &Vec::new()).unwrap();
        let expected = Vec::<LineRangeSpec>::new();
        assert_eq!(expected, output);

        // invalid range
        let input = vec![(15, 30), (10, 20), (20, 10)];
        let output = prepare_ranges(LogLevel::TRACE, &input);
        let expected = Err(LineRangeError::InvalidRange(20, 10));
        assert_eq!(expected, output);

        // proper merge
        let input = vec![(15, 30), (10, 20)];
        let output = prepare_ranges(LogLevel::TRACE, &input).unwrap();
        let expected = vec![
            LineRangeSpec::new(LogLevel::TRACE, 10, 30).unwrap()
        ];
        assert_eq!(expected, output);

        // proper merge
        let input = vec![(15, 30), (10, 20), (40, 50)];
        let output = prepare_ranges(LogLevel::TRACE, &input).unwrap();
        let expected = vec![
            LineRangeSpec::new(LogLevel::TRACE, 10, 30).unwrap(),
            LineRangeSpec::new(LogLevel::TRACE, 40, 50).unwrap(),
        ];
        assert_eq!(expected, output);

        // proper merge [special case for RootLogger::set_level]
        let input = vec![(LineRangeBound::BOF.into(), 30), (10, 20), (30, LineRangeBound::EOF.into())];
        let output = prepare_ranges(LogLevel::TRACE, &input).unwrap();
        let expected = Vec::<LineRangeSpec>::new();
        assert_eq!(expected, output);
    }
}
<|endoftext|>


<commit_before>extern crate time;
extern crate log;
extern crate fern;

use iron::prelude::*;
use iron::{Handler, AroundMiddleware};

struct LogEnabler;

struct HandlerWithLog<H: Handler> {
  handler: H
}

impl AroundMiddleware for LogEnabler {

    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(HandlerWithLog { handler: handler } ) as Box<Handler>
    }
}

impl <H: Handler> Handler for HandlerWithLog<H> {

    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        debug!("{:?}", req);
        let entry = self::time::precise_time_ns();
        let res = self.handler.handle(req);
        trace!("{:?} - rt: {:?}", res, self::time::precise_time_ns() - entry);
        res
    }
}

pub fn init() {
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            // This is a fairly simple format, though it's possible to do more complicated ones.
            // This closure can contain any code, as long as it produces a String message.
            format!("[{}][{}] {}", self::time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(), level, msg)
        }),
        output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
        level: log::LogLevelFilter::Trace,
    };

    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }
}

pub fn get_log_enabled_handler(handler : Box<Handler>) -> Box<Handler> {

  let use_log = LogEnabler;

  use_log.around(handler)
}

<commit_msg>introduced the fern logger<commit_after>extern crate time;
extern crate log;
extern crate fern;

use iron::prelude::*;
use iron::{Handler, AroundMiddleware};

struct LogEnabler;

struct HandlerWithLog<H: Handler> {
  handler: H
}

impl AroundMiddleware for LogEnabler {

    fn around(self, handler: Box<Handler>) -> Box<Handler> {
        Box::new(HandlerWithLog { handler: handler } ) as Box<Handler>
    }
}

impl <H: Handler> Handler for HandlerWithLog<H> {

    fn handle(&self, req: &mut Request) -> IronResult<Response> {
        debug!("{:?}", req);
        let entry = self::time::precise_time_ns();
        let res = self.handler.handle(req);
        trace!("{:?} - rt: {:?}", res, self::time::precise_time_ns() - entry);
        res
    }
}

pub fn init() {
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            // This is a fairly simple format, though it's possible to do more complicated ones.
            // This closure can contain any code, as long as it produces a String message.
            format!("[{}][{}] {}", self::time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(), level, msg)
        }),
        output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
        level: log::LogLevelFilter::Trace,
    };

    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }
}

pub fn get_log_enabled_handler(handler : Box<Handler>) -> Box<Handler> {

  let use_log = LogEnabler;

  use_log.around(handler)
}

<|endoftext|>


<commit_before>use platform::Firestorm;
use process;
use process::Process;
use process::{AppSlice,AppId};
use common::Queue;
use hil;
use syscall;

pub unsafe fn do_process(platform: &mut Firestorm, process: &mut Process,
                  appid: AppId) {
    loop {
        match process.state {
            process::State::Running => {
                process.switch_to();
            }
            process::State::Waiting => {
                match process.callbacks.dequeue() {
                    None => { return },
                    Some(cb) => {
                        process.state = process::State::Running;
                        process.switch_to_callback(cb);
                    }
                }
            }
        }
        match process.svc_number() {
            Some(syscall::WAIT) => {
                process.state = process::State::Waiting;
                process.pop_syscall_stack();
                break;
            },
            Some(syscall::SUBSCRIBE) => {
                let driver_num = process.r0();
                let subdriver_num = process.r1();
                let callback_ptr = process.r2() as *mut ();
                let appdata = process.r3();

                let res = platform.with_driver(driver_num, |driver| {
                    let callback =
                        hil::Callback::new(appid, appdata, callback_ptr);
                    match driver {
                        Some(d) => d.subscribe(subdriver_num,
                                               callback),
                        None => -1
                    }
                });
                process.set_r0(res);
            },
            Some(syscall::COMMAND) => {
                let res = platform.with_driver(process.r0(), |driver| {
                    match driver {
                        Some(d) => d.command(process.r1(),
                                             process.r2()),
                        None => -1
                    }
                });
                process.set_r0(res);
            },
            Some(syscall::ALLOW) => {
                let res = platform.with_driver(process.r0(), |driver| {
                    match driver {
                        Some(d) => {
                            let start_addr = process.r2() as *mut u8;
                            let size = process.r3();
                            if process.in_exposed_bounds(start_addr, size) {
                                let slice = AppSlice::new(start_addr as *mut u8, size, appid);
                                d.allow(appid, process.r1(), slice)
                            } else {
                                -1
                            }
                        },
                        None => -1
                    }
                });
                process.set_r0(res);
            }
            _ => {}
        }
    }
}
<commit_msg>Get rid of useless indrection throug hil<commit_after>use platform::Firestorm;
use process;
use process::Process;
use process::{AppSlice,AppId};
use common::Queue;
use syscall;

pub unsafe fn do_process(platform: &mut Firestorm, process: &mut Process,
                  appid: AppId) {
    loop {
        match process.state {
            process::State::Running => {
                process.switch_to();
            }
            process::State::Waiting => {
                match process.callbacks.dequeue() {
                    None => { return },
                    Some(cb) => {
                        process.state = process::State::Running;
                        process.switch_to_callback(cb);
                    }
                }
            }
        }
        match process.svc_number() {
            Some(syscall::WAIT) => {
                process.state = process::State::Waiting;
                process.pop_syscall_stack();
                break;
            },
            Some(syscall::SUBSCRIBE) => {
                let driver_num = process.r0();
                let subdriver_num = process.r1();
                let callback_ptr = process.r2() as *mut ();
                let appdata = process.r3();

                let res = platform.with_driver(driver_num, |driver| {
                    let callback =
                        process::Callback::new(appid, appdata, callback_ptr);
                    match driver {
                        Some(d) => d.subscribe(subdriver_num,
                                               callback),
                        None => -1
                    }
                });
                process.set_r0(res);
            },
            Some(syscall::COMMAND) => {
                let res = platform.with_driver(process.r0(), |driver| {
                    match driver {
                        Some(d) => d.command(process.r1(),
                                             process.r2()),
                        None => -1
                    }
                });
                process.set_r0(res);
            },
            Some(syscall::ALLOW) => {
                let res = platform.with_driver(process.r0(), |driver| {
                    match driver {
                        Some(d) => {
                            let start_addr = process.r2() as *mut u8;
                            let size = process.r3();
                            if process.in_exposed_bounds(start_addr, size) {
                                let slice = AppSlice::new(start_addr as *mut u8, size, appid);
                                d.allow(appid, process.r1(), slice)
                            } else {
                                -1
                            }
                        },
                        None => -1
                    }
                });
                process.set_r0(res);
            }
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! This module is the main module for the Ligature project.
//! It represents to common types and traits used by Ligature.

#![deny(missing_docs)]
//#![deny(missing_doc_example)] <-- for later, when I'm swole

#[macro_use]
extern crate lazy_static;

use regex::Regex;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// A simple type alias for Bytes.
pub type Bytes = Vec<u8>;

/// A string that represents a Dataset by name.
/// Currently can only be ASCII text separated by /
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
pub struct Dataset(String);

impl Dataset {
    /// Creates a new Dataset and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Dataset, LigatureError> {
        lazy_static! {
            static ref RE: Regex =
                Regex::new(r"^([a-zA-Z_]{1}[a-zA-Z0-9_]*)(/[a-zA-Z_]{1}[a-zA-Z0-9_]*)*$").unwrap();
        }

        if RE.is_match(name) {
            Ok(Dataset(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Dataset name {}", name)))
        }
    }

    /// Returns the name of the given Dataset.
    pub fn name(&self) -> &str {
        &self.0
    }
}

/// Check if a given identifier is valid.
pub fn validate_identifier(id: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new(r"^[a-zA-Z_][a-zA-Z0-9-._~:/?#\[\]@!$&'()*+,;%=]*$").unwrap();
    }

    RE.is_match(id)
}

/// Check if a given str contains only valid identifier characters.
pub fn validate_identifier_characters(id: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new(r"^[a-zA-Z0-9-._~:/?#\[\]@!$&'()*+,;%=]*$").unwrap();
    }

    RE.is_match(id)
}

/// An Entity that is identified by a unique String id.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct Entity(String);

impl Entity {
    /// Creates a new Arrow and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Self, LigatureError> {
        if validate_identifier(name) {
            Ok(Self(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Entity id {}", name)))
        }
    }

    /// Returns the name of the given Arrow.
    pub fn id(&self) -> &str {
        &self.0
    }
}

/// Creates a new Entity with an optional prefix.
/// To assure this Entity is unique within a Dataset use the version located in WriteTx.
pub fn new_entity(prefix: Option<String>) -> Result<Entity, LigatureError> {
    let uuid = Uuid::new_v4().to_hyphenated().to_string();
    let p = match prefix {
        Some(s) => s + &uuid,
        None => String::from("_:") + &uuid,
    };
    Entity::new(p.as_str())
}

/// A named connection between an Entity and a Value.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct Attribute(String);

impl Attribute {
    /// Creates a new Arrow and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Self, LigatureError> {
        if validate_identifier(name) {
            Ok(Self(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Attribute name {}", name)))
        }
    }

    /// Returns the name of the given Arrow.
    pub fn name(&self) -> &str {
        &self.0
    }
}

/// An enum that represents all the currently supported Value types.
#[derive(Debug, Clone, PartialOrd, PartialEq)]
pub enum Value {
    /// An Entity.
    Entity(Entity),
    /// A String used for a Ligature literal
    StringLiteral(String),
    /// An i64 used for a Ligature literal
    IntegerLiteral(i64),
    /// An f64 used for a Ligature literal
    FloatLiteral(f64),
    /// An array of bytes
    BytesLiteral(Bytes),
}

/// A set of enums used to express range queries when it makes sense for that type.
#[derive(Debug)]
pub enum Range {
    /// Represents a String range using basic String comparisons.
    StringLiteralRange {
        /// The starting String (inclusive)
        start: String,
        /// The end String (exclusive)
        end: String,
    },
    /// Represents a String range using basic i64 comparisons.
    IntegerLiteralRange {
        /// The starting i64 (inclusive)
        start: i64,
        /// The end i64 (exclusive)
        end: i64,
    },
    /// Represents a String range using basic f64 comparisons.
    FloatLiteralRange {
        /// The starting f64 (inclusive)
        start: f64,
        /// The end f64 (exclusive)
        end: f64,
    },
    /// Represents a String range using basic Bytes comparisons.
    BytesLiteralRange {
        /// The starting Byte array (inclusive)
        start: Bytes,
        /// The end Byte array (exclusive)
        end: Bytes,
    },
}

/// A Statement is a grouping of an Entity, an Attribute, and a Value.
#[derive(Debug, Clone, PartialOrd, PartialEq)]
pub struct Statement {
    /// The Entity of a Statement
    pub entity: Entity,
    /// The Attribute of a Statement
    pub attribute: Attribute,
    /// The Value of a Statement
    pub value: Value,
    /// The Context of this Statement
    pub context: Entity,
}

/// A general struct for representing errors involving Ligature.
/// TODO should probably be an enum with a bunch of specific cases
#[derive(Debug, PartialEq, Eq)]
pub struct LigatureError(pub String);

/// A trait that all Ligature implementations implement.
pub trait Ligature {
    /// Returns all Datasets in a Ligature instance.
    fn all_datasets(&self) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Check if a given Dataset exists.
    fn dataset_exists(&self, dataset: &Dataset) -> Result<bool, LigatureError>;

    /// Returns all Datasets in a Ligature instance that start with the given prefix.
    fn match_datasets_prefix(
        &self,
        prefix: &str,
    ) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Returns all Datasets in a Ligature instance that are in a given range (inclusive, exclusive].
    fn match_datasets_range(
        &self,
        start: &str,
        end: &str,
    ) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Creates a dataset with the given name.
    /// TODO should probably return its own error type { InvalidDataset, DatasetExists, CouldNotCreateDataset }
    fn create_dataset(&self, dataset: &Dataset) -> Result<(), LigatureError>;

    /// Deletes a dataset with the given name.
    /// TODO should probably return its own error type { InvalidDataset, CouldNotDeleteDataset }
    fn delete_dataset(&self, dataset: &Dataset) -> Result<(), LigatureError>;

    /// Initializes a QueryTx
    /// TODO should probably return its own error type CouldNotInitializeQueryTx
    fn query<T>(&self, dataset: &Dataset, f: QueryFn<T>) -> Result<T, LigatureError>;

    /// Initializes a WriteTx
    /// TODO should probably return its own error type CouldNotInitializeWriteTx
    fn write<T>(&self, dataset: &Dataset, f: WriteFn<T>) -> Result<T, LigatureError>;
}

/// An Fn that is used when making a Query transaction.
pub type QueryFn<T> = Box<dyn Fn(Box<&dyn QueryTx>) -> Result<T, LigatureError>>;

/// An Fn that is used when making a Write transaction.
pub type WriteFn<T> = Box<dyn Fn(Box<&dyn WriteTx>) -> Result<T, LigatureError>>;

/// Represents a QueryTx within the context of a Ligature instance and a single Dataset
pub trait QueryTx {
    /// Returns all Statements in this Dataset.
    fn all_statements(&self) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns all Statements that match the given criteria.
    /// If a parameter is None then it matches all, so passing all Nones is the same as calling all_statements.
    fn match_statements(
        &self,
        source: Option<Entity>,
        arrow: Option<Attribute>,
        target: Option<Value>,
    ) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns all Statements that match the given criteria.
    /// If a parameter is None then it matches all.
    fn match_statements_range(
        &self,
        source: Option<Entity>,
        arrow: Option<Attribute>,
        target: Range,
    ) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns the Statement for the given context.
    fn statement_for_context(&self, context: &Entity) -> Result<Option<Statement>, LigatureError>;
}

/// Represents a WriteTx within the context of a Ligature instance and a single Dataset
pub trait WriteTx {
    /// Creates a new, unique Entity within this Dataset with an optional prefix.
    /// This version of the function enforces that the new entity is unique in this Dataset.
    fn new_entity(&self, prefix: Option<String>) -> Result<Entity, LigatureError>;

    /// Adds a given Statement to this Dataset.
    /// If the Statement already exists nothing happens (TODO maybe add it with a new context?).
    /// Note: Potentially could trigger a ValidationError
    fn add_statement(&self, statement: &Statement) -> Result<Statement, LigatureError>;

    /// Removes a given Statement from this Dataset.
    /// If the Statement doesn't exist nothing happens and returns Ok(false).
    /// This function returns Ok(true) only if the given Statement was found and removed.
    /// Note: Potentially could trigger a ValidationError.
    fn remove_statement(&self, persisted_statement: &Statement) -> Result<bool, LigatureError>;

    /// Cancels this transaction so that none of the changes made so far will be stored.
    /// This also closes this transaction so no other methods can be called without returning a LigatureError.
    fn cancel(&self) -> Result<(), LigatureError>;
}
<commit_msg>Removing floating point values, #209<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

//! This module is the main module for the Ligature project.
//! It represents to common types and traits used by Ligature.

#![deny(missing_docs)]
//#![deny(missing_doc_example)] <-- for later, when I'm swole

#[macro_use]
extern crate lazy_static;

use regex::Regex;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// A simple type alias for Bytes.
pub type Bytes = Vec<u8>;

/// A string that represents a Dataset by name.
/// Currently can only be ASCII text separated by /
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
pub struct Dataset(String);

impl Dataset {
    /// Creates a new Dataset and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Dataset, LigatureError> {
        lazy_static! {
            static ref RE: Regex =
                Regex::new(r"^([a-zA-Z_]{1}[a-zA-Z0-9_]*)(/[a-zA-Z_]{1}[a-zA-Z0-9_]*)*$").unwrap();
        }

        if RE.is_match(name) {
            Ok(Dataset(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Dataset name {}", name)))
        }
    }

    /// Returns the name of the given Dataset.
    pub fn name(&self) -> &str {
        &self.0
    }
}

/// Check if a given identifier is valid.
pub fn validate_identifier(id: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new(r"^[a-zA-Z_][a-zA-Z0-9-._~:/?#\[\]@!$&'()*+,;%=]*$").unwrap();
    }

    RE.is_match(id)
}

/// Check if a given str contains only valid identifier characters.
pub fn validate_identifier_characters(id: &str) -> bool {
    lazy_static! {
        static ref RE: Regex =
            Regex::new(r"^[a-zA-Z0-9-._~:/?#\[\]@!$&'()*+,;%=]*$").unwrap();
    }

    RE.is_match(id)
}

/// An Entity that is identified by a unique String id.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct Entity(String);

impl Entity {
    /// Creates a new Arrow and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Self, LigatureError> {
        if validate_identifier(name) {
            Ok(Self(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Entity id {}", name)))
        }
    }

    /// Returns the name of the given Arrow.
    pub fn id(&self) -> &str {
        &self.0
    }
}

/// Creates a new Entity with an optional prefix.
/// To assure this Entity is unique within a Dataset use the version located in WriteTx.
pub fn new_entity(prefix: Option<String>) -> Result<Entity, LigatureError> {
    let uuid = Uuid::new_v4().to_hyphenated().to_string();
    let p = match prefix {
        Some(s) => s + &uuid,
        None => String::from("_:") + &uuid,
    };
    Entity::new(p.as_str())
}

/// A named connection between an Entity and a Value.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct Attribute(String);

impl Attribute {
    /// Creates a new Arrow and returns a Result based on if it is valid or not.
    pub fn new(name: &str) -> Result<Self, LigatureError> {
        if validate_identifier(name) {
            Ok(Self(name.to_string()))
        } else {
            Err(LigatureError(format!("Invalid Attribute name {}", name)))
        }
    }

    /// Returns the name of the given Arrow.
    pub fn name(&self) -> &str {
        &self.0
    }
}

/// An enum that represents all the currently supported Value types.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub enum Value {
    /// An Entity.
    Entity(Entity),
    /// A String used for a Ligature literal
    StringLiteral(String),
    /// An i64 used for a Ligature literal
    IntegerLiteral(i64),
    // /// An f64 used for a Ligature literal
    // FloatLiteral(f64),
    /// An array of bytes
    BytesLiteral(Bytes),
}

/// A set of enums used to express range queries when it makes sense for that type.
#[derive(Debug)]
pub enum Range {
    /// Represents a String range using basic String comparisons.
    StringLiteralRange {
        /// The starting String (inclusive)
        start: String,
        /// The end String (exclusive)
        end: String,
    },
    /// Represents a String range using basic i64 comparisons.
    IntegerLiteralRange {
        /// The starting i64 (inclusive)
        start: i64,
        /// The end i64 (exclusive)
        end: i64,
    },
    // /// Represents a String range using basic f64 comparisons.
    // FloatLiteralRange {
    //     /// The starting f64 (inclusive)
    //     start: f64,
    //     /// The end f64 (exclusive)
    //     end: f64,
    // },
    /// Represents a String range using basic Bytes comparisons.
    BytesLiteralRange {
        /// The starting Byte array (inclusive)
        start: Bytes,
        /// The end Byte array (exclusive)
        end: Bytes,
    },
}

/// A Statement is a grouping of an Entity, an Attribute, and a Value.
#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)]
pub struct Statement {
    /// The Entity of a Statement
    pub entity: Entity,
    /// The Attribute of a Statement
    pub attribute: Attribute,
    /// The Value of a Statement
    pub value: Value,
    /// The Context of this Statement
    pub context: Entity,
}

/// A general struct for representing errors involving Ligature.
/// TODO should probably be an enum with a bunch of specific cases
#[derive(Debug, PartialEq, Eq)]
pub struct LigatureError(pub String);

/// A trait that all Ligature implementations implement.
pub trait Ligature {
    /// Returns all Datasets in a Ligature instance.
    fn all_datasets(&self) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Check if a given Dataset exists.
    fn dataset_exists(&self, dataset: &Dataset) -> Result<bool, LigatureError>;

    /// Returns all Datasets in a Ligature instance that start with the given prefix.
    fn match_datasets_prefix(
        &self,
        prefix: &str,
    ) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Returns all Datasets in a Ligature instance that are in a given range (inclusive, exclusive].
    fn match_datasets_range(
        &self,
        start: &str,
        end: &str,
    ) -> Box<dyn Iterator<Item = Result<Dataset, LigatureError>>>;

    /// Creates a dataset with the given name.
    /// TODO should probably return its own error type { InvalidDataset, DatasetExists, CouldNotCreateDataset }
    fn create_dataset(&self, dataset: &Dataset) -> Result<(), LigatureError>;

    /// Deletes a dataset with the given name.
    /// TODO should probably return its own error type { InvalidDataset, CouldNotDeleteDataset }
    fn delete_dataset(&self, dataset: &Dataset) -> Result<(), LigatureError>;

    /// Initializes a QueryTx
    /// TODO should probably return its own error type CouldNotInitializeQueryTx
    fn query<T>(&self, dataset: &Dataset, f: QueryFn<T>) -> Result<T, LigatureError>;

    /// Initializes a WriteTx
    /// TODO should probably return its own error type CouldNotInitializeWriteTx
    fn write<T>(&self, dataset: &Dataset, f: WriteFn<T>) -> Result<T, LigatureError>;
}

/// An Fn that is used when making a Query transaction.
pub type QueryFn<T> = Box<dyn Fn(Box<&dyn QueryTx>) -> Result<T, LigatureError>>;

/// An Fn that is used when making a Write transaction.
pub type WriteFn<T> = Box<dyn Fn(Box<&dyn WriteTx>) -> Result<T, LigatureError>>;

/// Represents a QueryTx within the context of a Ligature instance and a single Dataset
pub trait QueryTx {
    /// Returns all Statements in this Dataset.
    fn all_statements(&self) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns all Statements that match the given criteria.
    /// If a parameter is None then it matches all, so passing all Nones is the same as calling all_statements.
    fn match_statements(
        &self,
        source: Option<Entity>,
        arrow: Option<Attribute>,
        target: Option<Value>,
    ) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns all Statements that match the given criteria.
    /// If a parameter is None then it matches all.
    fn match_statements_range(
        &self,
        source: Option<Entity>,
        arrow: Option<Attribute>,
        target: Range,
    ) -> Box<dyn Iterator<Item = Result<Statement, LigatureError>> + '_>;

    /// Returns the Statement for the given context.
    fn statement_for_context(&self, context: &Entity) -> Result<Option<Statement>, LigatureError>;
}

/// Represents a WriteTx within the context of a Ligature instance and a single Dataset
pub trait WriteTx {
    /// Creates a new, unique Entity within this Dataset with an optional prefix.
    /// This version of the function enforces that the new entity is unique in this Dataset.
    fn new_entity(&self, prefix: Option<String>) -> Result<Entity, LigatureError>;

    /// Adds a given Statement to this Dataset.
    /// If the Statement already exists nothing happens (TODO maybe add it with a new context?).
    /// Note: Potentially could trigger a ValidationError
    fn add_statement(&self, statement: &Statement) -> Result<Statement, LigatureError>;

    /// Removes a given Statement from this Dataset.
    /// If the Statement doesn't exist nothing happens and returns Ok(false).
    /// This function returns Ok(true) only if the given Statement was found and removed.
    /// Note: Potentially could trigger a ValidationError.
    fn remove_statement(&self, persisted_statement: &Statement) -> Result<bool, LigatureError>;

    /// Cancels this transaction so that none of the changes made so far will be stored.
    /// This also closes this transaction so no other methods can be called without returning a LigatureError.
    fn cancel(&self) -> Result<(), LigatureError>;
}
<|endoftext|>


<commit_before>
use std::fmt::Write;

pub struct Person {
    first_name: String,
    last_name: String
}

impl Person {
    pub fn first_name(&self) -> &str { &self.first_name }
    pub fn last_name(&self) -> &str { &self.last_name }
}

macro_rules! data_struct_member {
    ($w: expr, $var: ident : $ty: ty) => ({
        write!($w, "\t{}: function() {{ return _d.{}; }},\n", stringify!($var), stringify!($var))
    })
}
macro_rules! data_struct_d_var {
    ($w: expr, $var: ident : $ty: ty) => ({
        write!($w, "\n\t\t{}: _args.shift(),", stringify!($var))
    })
}
macro_rules! data_struct_ctor_param {
    ($w: expr, $param: ident) => ({write!($w, "{}: _args[]")})
}
macro_rules! data_struct {
    (struct $name:ident {
        $($var: ident : $ty: ty),*
    }) => ({
                let mut cls = String::new();
                let mut members = String::new();
                $(data_struct_member!(members, $var: $ty);)*

                let mut params = vec![$(concat!('"', stringify!($var), '"')),*];
                //let mut d_members = concat!($({format!("\t\t\t_d.{} = _args.pop();\n", stringify!($var))}),*);
                let mut d_members = String::new();
                $(write!(d_members, "\t{}: _args.shift(),\n", stringify!($var)).unwrap();)*
                //$(data_struct_d_var!(d_members, $var: $ty);)*
                write!(cls, "\nfunction {}() {{\n{}\n{}\nreturn Object.create({{\n {}}});\n}}", stringify!($name),
                    concat!(
                        "var _args = [].slice.call(arguments);"),
                    format!("var _d = {{\n{}}}", d_members),
                    members);
                cls
    })
}

pub fn person_js() -> String {
    data_struct! {
        struct Person {
            first_name: String,
            last_name: String
        }
    }
}
<commit_msg>Cleanup macros in examples/demo/src/models.rs<commit_after>
use std::fmt::Write;

pub struct Person {
    first_name: String,
    last_name: String
}

impl Person {
    pub fn first_name(&self) -> &str { &self.first_name }
    pub fn last_name(&self) -> &str { &self.last_name }
}

macro_rules! data_struct_member {
    ($w: expr, $var: ident : $ty: ty) => ({
        write!($w, "\t{}: function() {{ return _d.{}; }},\n", stringify!($var), stringify!($var))
    })
}
macro_rules! data_struct {
    (struct $name:ident {
        $($var: ident : $ty: ty),*
    }) => ({
                let mut cls = String::new();
                let mut members = String::new();
                $(data_struct_member!(members, $var: $ty);)*

                let mut params = vec![$(concat!('"', stringify!($var), '"')),*];
                let mut d_members = String::new();
                $(write!(d_members, "\t{}: _args.shift(),\n", stringify!($var)).unwrap();)*
                write!(cls, "\nfunction {}() {{\n{}\n{}\nreturn Object.create({{\n {}}});\n}}", stringify!($name),
                    "var _args = [].slice.call(arguments);",
                    format!("var _d = {{\n{}}}", d_members),
                    members);
                cls
    })
}

pub fn person_js() -> String {
    data_struct! {
        struct Person {
            first_name: String,
            last_name: String
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate prodbg_api;
extern crate gdb_remote;
extern crate libc;
use prodbg_api::*;
use libc::c_void;
use gdb_remote::GdbRemote;

struct AmigaUaeBackend {
    capstone: Capstone,
    conn: GdbRemote,
    exception_location: u32,
}

impl AmigaUaeBackend {
    fn get_u32(data: &[u8]) -> u32 {
        let t0 = data[0] as u32;
        let t1 = data[1] as u32;
        let t2 = data[2] as u32;
        let t3 = data[3] as u32;
        (t0 << 24) | (t1 << 16) | (t2 << 8) | t3
    }

    fn write_register(writer: &mut Writer, name: &str, data: u32, read_only: bool) {
        writer.array_entry_begin();
        writer.write_string("name", name);
        writer.write_u8("size", 4);

        if read_only {
            writer.write_u8("read_only", 1);
        }

        writer.write_u32("register", data);

        writer.array_entry_end();
    }

    fn write_registers(&mut self, writer: &mut Writer, data: &[u8]) {
        let mut index = 0;

        writer.event_begin(EventType::SetRegisters as u16);
        writer.array_begin("registers");

        // d registers

        for i in 0..8 {
            let name = format!("d{}", i);
            let reg = Self::get_u32(&data[index..]);
            Self::write_register(writer, &name, reg, false);
            index += 4;
        }

        // a registers

        for i in 0..8 {
            let name = format!("a{}", i);
            let reg = Self::get_u32(&data[index..]);
            Self::write_register(writer, &name, reg, false);
            index += 4;
        }

        // Status registers & pc

        let sr = Self::get_u32(&data[index..]);
        let pc = Self::get_u32(&data[index + 4..]);

        self.exception_location = pc;

        Self::write_register(writer, "sr", sr, true);
        Self::write_register(writer, "pc", pc, true);

        writer.array_end();
        writer.event_end();
    }

    fn write_disassembly(&mut self, reader: &mut Reader, writer: &mut Writer) {
        match self.capstone.open(Arch::M68K, CS_MODE_M68K_000) {
            Err(e) => {
                println!("Unable to open Capstone {}", e as i32);
                return;
            }
            _ => (),
        }

        let mut scratch_string = String::with_capacity(256);

        let address = reader.find_u64("address_start").ok().unwrap();
        let count = reader.find_u32("instruction_count").ok().unwrap();

        let mut data = Vec::<u8>::with_capacity(256 * 1024);
        let memory_fetch_size = count * 4;

        if self.conn.get_memory(&mut data, address, memory_fetch_size as u64).is_err() {
            println!("Unable to fetch memory from {:x} - size {}", address, memory_fetch_size);
            return;
        }

        println!("disasm data address {:x} - len {}", address, data.len());

        if let Ok(insns) = self.capstone.disasm(&data, address as u64, 0) {
            writer.event_begin(EventType::SetDisassembly as u16);
            writer.array_begin("disassembly");
            let mut c = 0;

            for i in insns.iter() {
                let text = format!("{0: <10} {1: <10}", i.mnemonic().unwrap(), i.op_str().unwrap_or(""));
                writer.array_entry_begin();
                writer.write_u32("address", i.address as u32);
                writer.write_string("line", &text);

                scratch_string.clear();

                for register in i.regs_read().unwrap() {
                    let reg_name = self.capstone.reg_name(*register);
                    scratch_string.push_str(reg_name);
                    scratch_string.push(' ');
                }

                if scratch_string.len() > 0 {
                    let t = scratch_string.trim_right();
                    writer.write_string("registers_read", t);
                }

                scratch_string.clear();

                for register in i.regs_write().unwrap() {
                    let reg_name = self.capstone.reg_name(*register);
                    scratch_string.push_str(reg_name);
                    scratch_string.push(' ');
                }

                if scratch_string.len() > 0 {
                    let t = scratch_string.trim_right();
                    writer.write_string("registers_write", t);
                }

                writer.array_entry_end();

                c += 1;
            }

            println!("reported {} instructions", c);

            writer.array_end();
            writer.event_end();
        } else {
            println!("No instructions :(");
        }
    }

    fn get_memory(&mut self, reader: &mut Reader, writer: &mut Writer) {
        let mut data = Vec::<u8>::with_capacity(256 * 1024);

        let address = reader.find_u64("address_start").ok().unwrap();
        let size = reader.find_u32("size").ok().unwrap();

        if self.conn.get_memory(&mut data, address, size as u64).is_err() {
            println!("Unable to fetch memory from {:x} - size {}", address, size);
            return;
        }

        writer.event_begin(EventType::SetMemory as u16);
        writer.write_u64("address", address);
        writer.write_data("data", &data);
        writer.event_end();
    }

    //
    fn write_exception_location(&mut self, writer: &mut Writer) {
        writer.event_begin(EventType::SetExceptionLocation as u16);
        writer.write_u64("address", self.exception_location as u64);
        writer.write_u8("size", 4);
        writer.event_end();
    }

    fn toggle_breakpoint(&mut self, reader: &mut Reader, _writer: &mut Writer) {
       if let Some(address) = reader.find_u64("address").ok() {
           if self.conn.set_breakpoint_at_address(address).is_err() {
               println!("Unable to set breakpoint at 0x{:08x}", address);
           }
       }
    }
}

impl Backend for AmigaUaeBackend {
    fn new(service: &Service) -> Self {
        AmigaUaeBackend {
            capstone: service.get_capstone(),
            conn: GdbRemote::new(),
            exception_location: 0,
        }
    }

    fn update(&mut self, action: i32, reader: &mut Reader, writer: &mut Writer) {
        for event in reader.get_event() {
            match event {
                EVENT_MENU_EVENT => {
                    if self.conn.connect("127.0.0.1:6860").is_ok() {
                        if self.conn.request_no_ack_mode().is_ok() {
                            println!("Connected. Ready to go!");
                        } else {
                            println!("no ack request failed");
                        }
                    } else {
                        println!("Unable to connect to UAE");
                    }
                }
                EVENT_GET_DISASSEMBLY => {
                    self.write_disassembly(reader, writer);
                }

                EVENT_GET_MEMORY => {
                    self.get_memory(reader, writer);
                }

                EVENT_SET_BREAKPOINT => {
                    self.toggle_breakpoint(reader, writer);
                }

                _ => (),
            }
        }

        match action {
            ACTION_BREAK => {
                println!("Break");
            }

            ACTION_RUN => {
                if self.conn.cont().is_err() {
                    println!("Unable to run");
                }
            }

            ACTION_STEP => {
                let mut step_res = [0; 16];
                let mut register_data = [0; 1024];
                if self.conn.step(&mut step_res).is_ok() {
                    println!("steping ok!");
                    if self.conn.get_registers(&mut register_data).is_ok() {
                        println!("setting registers!");
                        self.write_registers(writer, &register_data);
                    }

                    self.write_exception_location(writer);
                }
            }
            _ => (),
        }
    }

    fn register_menu(&mut self, menu_funcs: &mut MenuFuncs) -> *mut c_void {
        let menu = menu_funcs.create_menu("Amiga UAE Debugger");
        menu_funcs.add_menu_item(menu, "Connect to UAE...", 0, 0, 0);
        menu
    }
}

#[no_mangle]
pub fn init_plugin(plugin_handler: &mut PluginHandler) {
    define_backend_plugin!(PLUGIN, b"Amiga UAE Debugger\0", AmigaUaeBackend);
    plugin_handler.register_backend(&PLUGIN);
}

<commit_msg>Support for toggling breakpoints off<commit_after>#[macro_use]
extern crate prodbg_api;
extern crate gdb_remote;
extern crate libc;
use prodbg_api::*;
use libc::c_void;
use gdb_remote::GdbRemote;

struct AmigaUaeBackend {
    capstone: Capstone,
    conn: GdbRemote,
    exception_location: u32,
}

impl AmigaUaeBackend {
    fn get_u32(data: &[u8]) -> u32 {
        let t0 = data[0] as u32;
        let t1 = data[1] as u32;
        let t2 = data[2] as u32;
        let t3 = data[3] as u32;
        (t0 << 24) | (t1 << 16) | (t2 << 8) | t3
    }

    fn write_register(writer: &mut Writer, name: &str, data: u32, read_only: bool) {
        writer.array_entry_begin();
        writer.write_string("name", name);
        writer.write_u8("size", 4);

        if read_only {
            writer.write_u8("read_only", 1);
        }

        writer.write_u32("register", data);

        writer.array_entry_end();
    }

    fn write_registers(&mut self, writer: &mut Writer, data: &[u8]) {
        let mut index = 0;

        writer.event_begin(EventType::SetRegisters as u16);
        writer.array_begin("registers");

        // d registers

        for i in 0..8 {
            let name = format!("d{}", i);
            let reg = Self::get_u32(&data[index..]);
            Self::write_register(writer, &name, reg, false);
            index += 4;
        }

        // a registers

        for i in 0..8 {
            let name = format!("a{}", i);
            let reg = Self::get_u32(&data[index..]);
            Self::write_register(writer, &name, reg, false);
            index += 4;
        }

        // Status registers & pc

        let sr = Self::get_u32(&data[index..]);
        let pc = Self::get_u32(&data[index + 4..]);

        self.exception_location = pc;

        Self::write_register(writer, "sr", sr, true);
        Self::write_register(writer, "pc", pc, true);

        writer.array_end();
        writer.event_end();
    }

    fn write_disassembly(&mut self, reader: &mut Reader, writer: &mut Writer) {
        match self.capstone.open(Arch::M68K, CS_MODE_M68K_000) {
            Err(e) => {
                println!("Unable to open Capstone {}", e as i32);
                return;
            }
            _ => (),
        }

        let mut scratch_string = String::with_capacity(256);

        let address = reader.find_u64("address_start").ok().unwrap();
        let count = reader.find_u32("instruction_count").ok().unwrap();

        let mut data = Vec::<u8>::with_capacity(256 * 1024);
        let memory_fetch_size = count * 4;

        if self.conn.get_memory(&mut data, address, memory_fetch_size as u64).is_err() {
            println!("Unable to fetch memory from {:x} - size {}", address, memory_fetch_size);
            return;
        }

        println!("disasm data address {:x} - len {}", address, data.len());

        if let Ok(insns) = self.capstone.disasm(&data, address as u64, 0) {
            writer.event_begin(EventType::SetDisassembly as u16);
            writer.array_begin("disassembly");
            let mut c = 0;

            for i in insns.iter() {
                let text = format!("{0: <10} {1: <10}", i.mnemonic().unwrap(), i.op_str().unwrap_or(""));
                writer.array_entry_begin();
                writer.write_u32("address", i.address as u32);
                writer.write_string("line", &text);

                scratch_string.clear();

                for register in i.regs_read().unwrap() {
                    let reg_name = self.capstone.reg_name(*register);
                    scratch_string.push_str(reg_name);
                    scratch_string.push(' ');
                }

                if scratch_string.len() > 0 {
                    let t = scratch_string.trim_right();
                    writer.write_string("registers_read", t);
                }

                scratch_string.clear();

                for register in i.regs_write().unwrap() {
                    let reg_name = self.capstone.reg_name(*register);
                    scratch_string.push_str(reg_name);
                    scratch_string.push(' ');
                }

                if scratch_string.len() > 0 {
                    let t = scratch_string.trim_right();
                    writer.write_string("registers_write", t);
                }

                writer.array_entry_end();

                c += 1;
            }

            println!("reported {} instructions", c);

            writer.array_end();
            writer.event_end();
        } else {
            println!("No instructions :(");
        }
    }

    fn get_memory(&mut self, reader: &mut Reader, writer: &mut Writer) {
        let mut data = Vec::<u8>::with_capacity(256 * 1024);

        let address = reader.find_u64("address_start").ok().unwrap();
        let size = reader.find_u32("size").ok().unwrap();

        if self.conn.get_memory(&mut data, address, size as u64).is_err() {
            println!("Unable to fetch memory from {:x} - size {}", address, size);
            return;
        }

        writer.event_begin(EventType::SetMemory as u16);
        writer.write_u64("address", address);
        writer.write_data("data", &data);
        writer.event_end();
    }

    //
    fn write_exception_location(&mut self, writer: &mut Writer) {
        writer.event_begin(EventType::SetExceptionLocation as u16);
        writer.write_u64("address", self.exception_location as u64);
        writer.write_u8("size", 4);
        writer.event_end();
    }

    fn set_breakpoint(&mut self, reader: &mut Reader, _writer: &mut Writer) {
       if let Some(address) = reader.find_u64("address").ok() {
           if self.conn.set_breakpoint_at_address(address).is_err() {
               println!("Unable to set breakpoint at 0x{:08x}", address);
           }
       }
    }

    fn delete_breakpoint(&mut self, reader: &mut Reader, _writer: &mut Writer) {
       if let Some(address) = reader.find_u64("address").ok() {
           if self.conn.remove_breakpoint_at_address(address).is_err() {
               println!("Unable to remove breakpoint at 0x{:08x}", address);
           }
       }
    }
}

impl Backend for AmigaUaeBackend {
    fn new(service: &Service) -> Self {
        AmigaUaeBackend {
            capstone: service.get_capstone(),
            conn: GdbRemote::new(),
            exception_location: 0,
        }
    }

    fn update(&mut self, action: i32, reader: &mut Reader, writer: &mut Writer) {
        for event in reader.get_event() {
            match event {
                EVENT_MENU_EVENT => {
                    if self.conn.connect("127.0.0.1:6860").is_ok() {
                        if self.conn.request_no_ack_mode().is_ok() {
                            println!("Connected. Ready to go!");
                        } else {
                            println!("no ack request failed");
                        }
                    } else {
                        println!("Unable to connect to UAE");
                    }
                }
                EVENT_GET_DISASSEMBLY => {
                    self.write_disassembly(reader, writer);
                }

                EVENT_GET_MEMORY => {
                    self.get_memory(reader, writer);
                }

                EVENT_SET_BREAKPOINT => {
                    self.set_breakpoint(reader, writer);
                }

                EVENT_DELETE_BREAKPOINT => {
                    self.delete_breakpoint(reader, writer);
                }

                EVENT_GET_EXCEPTION_LOCATION => {
                    self.write_exception_location(writer);
                }

                _ => (),
            }
        }

        match action {
            ACTION_BREAK => {
                println!("Break");
            }

            ACTION_RUN => {
                if self.conn.cont().is_err() {
                    println!("Unable to run");
                }
            }

            ACTION_STEP => {
                let mut step_res = [0; 16];
                let mut register_data = [0; 1024];
                self.conn.step(&mut step_res).unwrap();
                    println!("step res {:?}", step_res);
                    println!("steping ok!");
                    if self.conn.get_registers(&mut register_data).is_ok() {
                        println!("setting registers!");
                        self.write_registers(writer, &register_data);
                    }

                    self.write_exception_location(writer);
                }
            _ => (),
        }
    }

    fn register_menu(&mut self, menu_funcs: &mut MenuFuncs) -> *mut c_void {
        let menu = menu_funcs.create_menu("Amiga UAE Debugger");
        menu_funcs.add_menu_item(menu, "Connect to UAE...", 0, 0, 0);
        menu
    }
}

#[no_mangle]
pub fn init_plugin(plugin_handler: &mut PluginHandler) {
    define_backend_plugin!(PLUGIN, b"Amiga UAE Debugger\0", AmigaUaeBackend);
    plugin_handler.register_backend(&PLUGIN);
}

<|endoftext|>


<commit_before>/*!

This example demonstrates how to manually create a glium context with any backend you want, most
notably without glutin.

There are three concepts in play:

 - The `Backend` trait, which defines how glium interfaces with the OpenGL context
   provider (glutin, SDL, glfw, etc.).

 - The `Context` struct, which is the main object of glium. The context also provides
   OpenGL-related functions like `get_free_video_memory` or `get_supported_glsl_version`.

 - The `Facade` trait, which is the trait required to be implemented on objects that you pass
   to functions like `VertexBuffer::new`. This trait is implemented on `Rc<Context>`, which
   means that you can direct pass the context.

*/
extern crate libc;
extern crate glium;

use glium::Surface;
use glium::glutin;
use std::rc::Rc;

fn main() {
    // building the glutin window
    // note that it's just `build` and not `build_glium`
    let window = glutin::WindowBuilder::new().build().unwrap();
    let window = Rc::new(window);

    // in order to create our context, we will need to provide an object which implements
    // the `Backend` trait
    struct Backend {
        window: Rc<glutin::Window>,
    }

    unsafe impl glium::backend::Backend for Backend {
        fn swap_buffers(&self) -> Result<(), glium::SwapBuffersError> {
            match self.window.swap_buffers() {
                Ok(()) => Ok(()),
                Err(glutin::ContextError::IoError(_)) => panic!(),
                Err(glutin::ContextError::ContextLost) => Err(glium::SwapBuffersError::ContextLost),
            }
        }

        // this function is called only after the OpenGL context has been made current
        unsafe fn get_proc_address(&self, symbol: &str) -> *const libc::c_void {
            self.window.get_proc_address(symbol)
        }

        // this function is used to adjust the viewport when the user wants to draw or blit on
        // the whole window
        fn get_framebuffer_dimensions(&self) -> (u32, u32) {
            // we default to a dummy value is the window no longer exists
            self.window.get_inner_size().unwrap_or((128, 128))
        }

        fn is_current(&self) -> bool {
            // if you are using a library that doesn't provide an equivalent to `is_current`, you
            // can just put `unimplemented!` and pass `false` when you create
            // the `Context` (see below)
            self.window.is_current()
        }

        unsafe fn make_current(&self) {
            self.window.make_current().unwrap();
        }
    }

    // now building the context
    let context = unsafe {
        // The first parameter is our backend.
        //
        // The second parameter tells glium whether or not it should regularly call `is_current`
        // on the backend to make sure that the OpenGL context is still the current one.
        //
        // It is recommended to pass `true`, but you can pass `false` if you are sure that no
        // other OpenGL context will be made current in this thread.
        glium::backend::Context::new::<_, ()>(Backend { window: window.clone() }, true)
    }.unwrap();

    // drawing a frame to prove that it works
    // note that constructing a `Frame` object manually is a bit hacky and may be changed
    // in the future
    let mut target = glium::Frame::new(context.clone(), context.get_framebuffer_dimensions());
    target.clear_color(0.0, 1.0, 0.0, 1.0);
    target.finish().unwrap();

    // the window is still available
    for event in window.wait_events() {
        match event {
            glutin::Event::Closed => return,
            _ => ()
        }
    }
}
<commit_msg>Fix the example<commit_after>/*!

This example demonstrates how to manually create a glium context with any backend you want, most
notably without glutin.

There are three concepts in play:

 - The `Backend` trait, which defines how glium interfaces with the OpenGL context
   provider (glutin, SDL, glfw, etc.).

 - The `Context` struct, which is the main object of glium. The context also provides
   OpenGL-related functions like `get_free_video_memory` or `get_supported_glsl_version`.

 - The `Facade` trait, which is the trait required to be implemented on objects that you pass
   to functions like `VertexBuffer::new`. This trait is implemented on `Rc<Context>`, which
   means that you can direct pass the context.

*/
extern crate libc;
extern crate glium;

use glium::Surface;
use glium::glutin;
use std::rc::Rc;

fn main() {
    // building the glutin window
    // note that it's just `build` and not `build_glium`
    let window = glutin::WindowBuilder::new().build().unwrap();
    let window = Rc::new(window);

    // in order to create our context, we will need to provide an object which implements
    // the `Backend` trait
    struct Backend {
        window: Rc<glutin::Window>,
    }

    unsafe impl glium::backend::Backend for Backend {
        fn swap_buffers(&self) -> Result<(), glium::SwapBuffersError> {
            match self.window.swap_buffers() {
                Ok(()) => Ok(()),
                Err(glutin::ContextError::IoError(_)) => panic!(),
                Err(glutin::ContextError::ContextLost) => Err(glium::SwapBuffersError::ContextLost),
            }
        }

        // this function is called only after the OpenGL context has been made current
        unsafe fn get_proc_address(&self, symbol: &str) -> *const libc::c_void {
            self.window.get_proc_address(symbol)
        }

        // this function is used to adjust the viewport when the user wants to draw or blit on
        // the whole window
        fn get_framebuffer_dimensions(&self) -> (u32, u32) {
            // we default to a dummy value is the window no longer exists
            self.window.get_inner_size().unwrap_or((128, 128))
        }

        fn is_current(&self) -> bool {
            // if you are using a library that doesn't provide an equivalent to `is_current`, you
            // can just put `unimplemented!` and pass `false` when you create
            // the `Context` (see below)
            self.window.is_current()
        }

        unsafe fn make_current(&self) {
            self.window.make_current().unwrap();
        }
    }

    // now building the context
    let context = unsafe {
        // The first parameter is our backend.
        //
        // The second parameter tells glium whether or not it should regularly call `is_current`
        // on the backend to make sure that the OpenGL context is still the current one.
        //
        // It is recommended to pass `true`, but you can pass `false` if you are sure that no
        // other OpenGL context will be made current in this thread.
        glium::backend::Context::new::<_, ()>(Backend { window: window.clone() },
                                              true, Default::default())
    }.unwrap();

    // drawing a frame to prove that it works
    // note that constructing a `Frame` object manually is a bit hacky and may be changed
    // in the future
    let mut target = glium::Frame::new(context.clone(), context.get_framebuffer_dimensions());
    target.clear_color(0.0, 1.0, 0.0, 1.0);
    target.finish().unwrap();

    // the window is still available
    for event in window.wait_events() {
        match event {
            glutin::Event::Closed => return,
            _ => ()
        }
    }
}
<|endoftext|>