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

//! An implementation of `RocksDB` database.
use profiler;

use rocksdb::DB as _RocksDB;
use rocksdb::DBRawIterator;
use rocksdb::Snapshot as _Snapshot;
use rocksdb::Error as _Error;
use rocksdb::WriteBatch;

use std::mem;
use std::sync::Arc;
use std::path::Path;
use std::fmt;
use std::error;

pub use rocksdb::Options as RocksDBOptions;
pub use rocksdb::BlockBasedOptions as RocksBlockOptions;

use super::{Database, Iterator, Iter, Snapshot, Error, Patch, Change, Result};

impl From<_Error> for Error {
    fn from(err: _Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

/// Creates new RocksDB struct
#[derive(Clone)]
pub struct RocksDB {
    db: Arc<_RocksDB>,
}

pub struct RocksDBSnapshot {
    _db: Arc<_RocksDB>,
    snapshot: _Snapshot<'static>,
}

struct RocksDBIterator {
    iter: DBRawIterator,
    key: Option<Vec<u8>>,
    value: Option<Vec<u8>>,
}

impl RocksDB {
    /// Creates new rocksdb
    pub fn open(path: &Path, options: RocksDBOptions) -> Result<RocksDB> {
        let database = _RocksDB::open(&options, path)?;
        Ok(RocksDB { db: Arc::new(database) })
    }
}

impl Database for RocksDB {
    fn clone(&self) -> Box<Database> {
        Box::new(Clone::clone(self))
    }

    fn snapshot(&self) -> Box<Snapshot> {
        let _p = profiler::ProfilerSpan::new("RocksDB::snapshot");
        Box::new(RocksDBSnapshot {
            _db: self.db.clone(),
            snapshot: unsafe { mem::transmute(self.db.snapshot()) },
        })
    }

    fn merge(&mut self, patch: Patch) -> Result<()> {
        let _p = profiler::ProfilerSpan::new("RocksDB::merge");
        let mut batch = WriteBatch::default();
        for (key, change) in patch {
            match change {
                Change::Put(ref value) => batch.put(&key, value)?,
                Change::Delete => batch.delete(&key)?,
            }
        }
        self.db.write(batch).map_err(Into::into)
    }
}

impl Snapshot for RocksDBSnapshot {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        let _p = profiler::ProfilerSpan::new("RocksDBSnapshot::get");
        match self.snapshot.get(key) {
            Ok(value) => value.map(|v| v.to_vec()),
            Err(e) => panic!(e),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let _p = profiler::ProfilerSpan::new("RocksDBSnapshot::iter");
        let mut iter = self.snapshot.raw_iterator();
        iter.seek(from);
        Box::new(RocksDBIterator {
            iter: iter,
            key: None,
            value: None,
        })
    }
}

impl<'a> Iterator for RocksDBIterator {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("RocksDBIterator::next");
        let result = if self.iter.valid() {
            self.key = Some(unsafe { self.iter.key_inner().unwrap().to_vec() });
            self.value = Some(unsafe { self.iter.value_inner().unwrap().to_vec() });
            Some((
                self.key.as_ref().unwrap().as_ref(),
                self.value.as_ref().unwrap().as_ref(),
            ))
        } else {
            None
        };

        if result.is_some() {
            self.iter.next();
        }

        result
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("RocksDBIterator::peek");
        if self.iter.valid() {
            self.key = Some(unsafe { self.iter.key_inner().unwrap().to_vec() });
            self.value = Some(unsafe { self.iter.value_inner().unwrap().to_vec() });
            Some((
                self.key.as_ref().unwrap().as_ref(),
                self.value.as_ref().unwrap().as_ref(),
            ))
        } else {
            None
        }
    }
}

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

impl fmt::Debug for RocksDBSnapshot {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDBSnapshot(..)")
    }
}
<commit_msg>Doc format for clippy<commit_after>// Copyright 2017 The Exonum Team
//
// 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.

//! An implementation of `RocksDB` database.
use profiler;

use rocksdb::DB as _RocksDB;
use rocksdb::DBRawIterator;
use rocksdb::Snapshot as _Snapshot;
use rocksdb::Error as _Error;
use rocksdb::WriteBatch;

use std::mem;
use std::sync::Arc;
use std::path::Path;
use std::fmt;
use std::error;

pub use rocksdb::Options as RocksDBOptions;
pub use rocksdb::BlockBasedOptions as RocksBlockOptions;

use super::{Database, Iterator, Iter, Snapshot, Error, Patch, Change, Result};

impl From<_Error> for Error {
    fn from(err: _Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

/// Creates new `RocksDB` struct
#[derive(Clone)]
pub struct RocksDB {
    db: Arc<_RocksDB>,
}

pub struct RocksDBSnapshot {
    _db: Arc<_RocksDB>,
    snapshot: _Snapshot<'static>,
}

struct RocksDBIterator {
    iter: DBRawIterator,
    key: Option<Vec<u8>>,
    value: Option<Vec<u8>>,
}

impl RocksDB {
    /// Creates new rocksdb
    pub fn open(path: &Path, options: RocksDBOptions) -> Result<RocksDB> {
        let database = _RocksDB::open(&options, path)?;
        Ok(RocksDB { db: Arc::new(database) })
    }
}

impl Database for RocksDB {
    fn clone(&self) -> Box<Database> {
        Box::new(Clone::clone(self))
    }

    fn snapshot(&self) -> Box<Snapshot> {
        let _p = profiler::ProfilerSpan::new("RocksDB::snapshot");
        Box::new(RocksDBSnapshot {
            _db: self.db.clone(),
            snapshot: unsafe { mem::transmute(self.db.snapshot()) },
        })
    }

    fn merge(&mut self, patch: Patch) -> Result<()> {
        let _p = profiler::ProfilerSpan::new("RocksDB::merge");
        let mut batch = WriteBatch::default();
        for (key, change) in patch {
            match change {
                Change::Put(ref value) => batch.put(&key, value)?,
                Change::Delete => batch.delete(&key)?,
            }
        }
        self.db.write(batch).map_err(Into::into)
    }
}

impl Snapshot for RocksDBSnapshot {
    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
        let _p = profiler::ProfilerSpan::new("RocksDBSnapshot::get");
        match self.snapshot.get(key) {
            Ok(value) => value.map(|v| v.to_vec()),
            Err(e) => panic!(e),
        }
    }

    fn iter<'a>(&'a self, from: &[u8]) -> Iter<'a> {
        let _p = profiler::ProfilerSpan::new("RocksDBSnapshot::iter");
        let mut iter = self.snapshot.raw_iterator();
        iter.seek(from);
        Box::new(RocksDBIterator {
            iter: iter,
            key: None,
            value: None,
        })
    }
}

impl<'a> Iterator for RocksDBIterator {
    fn next(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("RocksDBIterator::next");
        let result = if self.iter.valid() {
            self.key = Some(unsafe { self.iter.key_inner().unwrap().to_vec() });
            self.value = Some(unsafe { self.iter.value_inner().unwrap().to_vec() });
            Some((
                self.key.as_ref().unwrap().as_ref(),
                self.value.as_ref().unwrap().as_ref(),
            ))
        } else {
            None
        };

        if result.is_some() {
            self.iter.next();
        }

        result
    }

    fn peek(&mut self) -> Option<(&[u8], &[u8])> {
        let _p = profiler::ProfilerSpan::new("RocksDBIterator::peek");
        if self.iter.valid() {
            self.key = Some(unsafe { self.iter.key_inner().unwrap().to_vec() });
            self.value = Some(unsafe { self.iter.value_inner().unwrap().to_vec() });
            Some((
                self.key.as_ref().unwrap().as_ref(),
                self.value.as_ref().unwrap().as_ref(),
            ))
        } else {
            None
        }
    }
}

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

impl fmt::Debug for RocksDBSnapshot {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "RocksDBSnapshot(..)")
    }
}
<|endoftext|>


<commit_before>extern crate thunderdome;

#[cfg(test)]
mod vertex_tests {
    use thunderdome::graph::*;
    use thunderdome::vertex::*;

    #[test]
    fn test_vertex_edge_traversals() {
        let mut g = Graph::new();
        let mut vertex = g.add_vertex();
        let mut vertex2 = g.add_vertex();

        g.add_edge(&mut vertex, &mut vertex2, "test");

        let result = vertex.read().unwrap().out_edges().len();
        assert_eq!(1, result);

        let result = vertex.read().unwrap().in_edges().len();
        assert_eq!(0, result);

        let result = vertex2.read().unwrap().out_edges().len();
        assert_eq!(0, result);

        let result = vertex2.read().unwrap().in_edges().len();
        assert_eq!(1, result);
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.read().unwrap().id, 1);

        let v2 = g.add_vertex();
        assert!(v2.read().unwrap().id == 2);
    }

}
<commit_msg>looking at edge ok<commit_after>extern crate thunderdome;

#[cfg(test)]
mod vertex_tests {
    use thunderdome::graph::*;
    use thunderdome::vertex::*;

    #[test]
    fn test_vertex_edge_traversals() {
        let mut g = Graph::new();
        let mut vertex = g.add_vertex();
        let mut vertex2 = g.add_vertex();

        g.add_edge(&mut vertex, &mut vertex2, "test");

        let result = vertex.read().unwrap().out_edges().len();
        assert_eq!(1, result);

        let result = vertex.read().unwrap().in_edges().len();
        assert_eq!(0, result);

        let result = vertex2.read().unwrap().out_edges().len();
        assert_eq!(0, result);

        let result = vertex2.read().unwrap().in_edges().len();
        assert_eq!(1, result);

        for edge in vertex.read().unwrap().out_edges().iter() {
            println!("hi {}", edge.read().unwrap().label);
        }
    }

    #[test]
    fn test_new_vertex() {
        let mut g = Graph::new();
        let v1 = g.add_vertex();

        assert_eq!(v1.read().unwrap().id, 1);

        let v2 = g.add_vertex();
        assert!(v2.read().unwrap().id == 2);
    }

}
<|endoftext|>


<commit_before>//! It's a tree!

use std::ptr;
use std::ops::{Deref, DerefMut};
use std::fmt::Debug;

#[derive(Debug, PartialEq, Eq)]
struct Node<T> {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node<T>,
    val: T,
    children: Vec<Node<T>>
}

impl<T> Node<T> {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: T) -> Node<T> {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: T) -> &mut Node<T> {
        let self_mut = self as *mut Node<T>;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        &mut self.children[last_ix]
    }

    /// Whether this node has a (currently-reachable) parent
    pub fn has_parent(&self) -> bool {
        self.parent.is_null()
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node<T>> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children(&self) -> &[Node<T>] {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_mut_children(&mut self) -> &mut[Node<T>] {
        &mut self.children
    }

    /// Remove a child at the given index
    pub fn remove_child_at(&mut self, index: usize) -> Node<T> {
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        child
    }

    /// Whether this node is a parent of another node
    pub fn is_parent_of(&self, other: &Node<T>) -> bool {
        self.parent == other.parent as *mut Node<T>
    }
}

impl <T: PartialEq> Node<T> {

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&mut self) {
        if self.get_parent().is_none() {
            return;
        }
        if let Some(index) = self.children.iter().position(|c| c == self) {
            self.parent = ptr::null_mut();
            self.children.remove(index);
        }
    }

    /// Removes a child from self
    pub fn remove_child(&mut self, other: &Node<T>) -> Option<Node<T>> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            let mut child = self.children.remove(index);
            child.parent = ptr::null_mut();
            Some(child)
        }
        else {
            None
        }
    }

    pub fn move_to(mut self, new_parent: &mut Node<T>) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node<T>;
        new_parent.children.push(self);
    }
}

impl<T> Drop for Node<T> {
    fn drop(&mut self) {
        println!("Dropping a node.");
        let children: &mut Vec<Node<T>> = &mut self.children;
        for mut child in children {
            child.parent = ptr::null_mut();
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Node;
    use log::LogLevelFilter;
    use env_logger::LogBuilder;

    /// Nodes can have children added to them
    #[test]
    fn test_add_child() {
        let mut root = Node::new(0);
        root.new_child(1);
        root.new_child(2); // This is okay
        {
            let mut third_child = root.new_child(3);
            //root.new_child(4); // Have to wait for 3rd child to drop
        }
        root.new_child(4); // Now this works yay standard borrowing
        assert_eq!(root.children.len(), 4);
        println!("Done with the test now.");
    }

    /// These operations will for example operate on the parent
    /// under an if let. `remove_from_parent` will not panic if the node
    /// already is parentless, for example.
    #[test]
    fn optional_operations() {

    }
}
<commit_msg>Pasted in some enums, Option remove_from_parent<commit_after>//! It's a tree!

use std::fmt::Debug;
use std::ops::{Deref, DerefMut};
use std::ptr;

use rustwlc::handle::{WlcView, WlcOutput};

/// A handle to either a view or output
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Handle {
    View(WlcView),
    Output(WlcOutput)
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ContainerType {
    /// Root container, only one exists
    Root,
    /// WlcOutput/Monitor
    Output,
    /// A workspace
    Workspace,
    /// A Container, houses views and other containers
    Container,
    /// A view (window)
    View
}

/// Layout mode for a container
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Layout {
    Horizontal,
    Vertical,
    Stacked,
    Tabbed,
    Floating
}

/// Represents an item in the container tree.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Container {
    Root,
    Output {
        handle: WlcOutput
    },
    Workspace {
        name: String,
        focused: bool
    },
    Container {
        layout: Layout,
        visible: bool,
        focused: bool,
        floating: bool,
    },
    View {
        handle: WlcView
    }
}

#[derive(Debug, PartialEq, Eq)]
struct Node<T> {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node<T>,
    val: T,
    children: Vec<Node<T>>
}

impl<T> Node<T> {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: T) -> Node<T> {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: T) -> &mut Node<T> {
        let self_mut = self as *mut Node<T>;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        &mut self.children[last_ix]
    }

    /// Whether this node has a (currently-reachable) parent
    pub fn has_parent(&self) -> bool {
        self.parent.is_null()
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node<T>> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children(&self) -> &[Node<T>] {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_mut_children(&mut self) -> &mut[Node<T>] {
        &mut self.children
    }

    /// Remove a child at the given index
    pub fn remove_child_at(&mut self, index: usize) -> Node<T> {
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        child
    }

    /// Whether this node is a parent of another node
    pub fn is_parent_of(&self, other: &Node<T>) -> bool {
        self.parent == other.parent as *mut Node<T>
    }
}

impl <T: PartialEq> Node<T> {

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&mut self) -> Option<Node<T>> {
        if self.get_parent().is_none() {
            return None;
        }
        if let Some(index) = self.children.iter().position(|c| c == self) {
            self.parent = ptr::null_mut();
            self.children.remove(index);
        }
        return None;
    }

    /// Removes a child from self
    pub fn remove_child(&mut self, other: &Node<T>) -> Option<Node<T>> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            let mut child = self.children.remove(index);
            child.parent = ptr::null_mut();
            Some(child)
        }
        else {
            None
        }
    }

    pub fn move_to(mut self, new_parent: &mut Node<T>) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node<T>;
        new_parent.children.push(self);
    }
}

impl<T> Drop for Node<T> {
    fn drop(&mut self) {
        println!("Dropping a node.");
        let children: &mut Vec<Node<T>> = &mut self.children;
        for mut child in children {
            child.parent = ptr::null_mut();
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Node;
    use log::LogLevelFilter;
    use env_logger::LogBuilder;

    /// Nodes can have children added to them
    #[test]
    fn test_add_child() {
        let mut root = Node::new(0);
        root.new_child(1);
        root.new_child(2); // This is okay
        {
            let mut third_child = root.new_child(3);
            //root.new_child(4); // Have to wait for 3rd child to drop
        }
        root.new_child(4); // Now this works yay standard borrowing
        assert_eq!(root.children.len(), 4);
        println!("Done with the test now.");
    }

    /// These operations will for example operate on the parent
    /// under an if let. `remove_from_parent` will not panic if the node
    /// already is parentless, for example.
    #[test]
    fn optional_operations() {

    }
}
<|endoftext|>


<commit_before>s! {
    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t,
        pub shm_amp: *mut ::c_void,
        pub shm_lkcnt: ::c_ushort,
        pub shm_lpid: ::pid_t,
        pub shm_cpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        pub shm_cnattch: ::c_ulong,
        pub shm_atime: ::time_t,
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_pad4: [i64; 4],
    }
}

pub const AF_LOCAL: ::c_int = 1; // AF_UNIX
pub const AF_FILE: ::c_int = 1; // AF_UNIX

pub const EFD_SEMAPHORE: ::c_int = 0x1;
pub const EFD_NONBLOCK: ::c_int = 0x800;
pub const EFD_CLOEXEC: ::c_int = 0x80000;

pub const TCP_KEEPIDLE: ::c_int = 34;
pub const TCP_KEEPCNT: ::c_int = 35;
pub const TCP_KEEPINTVL: ::c_int = 36;
pub const TCP_CONGESTION: ::c_int = 37;

pub const F_OFD_GETLK: ::c_int = 50;
pub const F_OFD_SETLKL: ::c_int = 51;
pub const F_OFD_SETLKW: ::c_int = 52;
pub const F_FLOCK: ::c_int = 55;
pub const F_FLOCKW: ::c_int = 56;

extern "C" {
    pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;

    pub fn mincore(addr: ::caddr_t, len: ::size_t, vec: *mut ::c_char) -> ::c_int;

    pub fn pset_bind_lwp(
        pset: ::psetid_t,
        id: ::id_t,
        pid: ::pid_t,
        opset: *mut ::psetid_t,
    ) -> ::c_int;
    pub fn pset_getloadavg(pset: ::psetid_t, load: *mut ::c_double, num: ::c_int) -> ::c_int;
}
<commit_msg>Add preadv/pwritev for illumos.<commit_after>s! {
    pub struct shmid_ds {
        pub shm_perm: ::ipc_perm,
        pub shm_segsz: ::size_t,
        pub shm_amp: *mut ::c_void,
        pub shm_lkcnt: ::c_ushort,
        pub shm_lpid: ::pid_t,
        pub shm_cpid: ::pid_t,
        pub shm_nattch: ::shmatt_t,
        pub shm_cnattch: ::c_ulong,
        pub shm_atime: ::time_t,
        pub shm_dtime: ::time_t,
        pub shm_ctime: ::time_t,
        pub shm_pad4: [i64; 4],
    }
}

pub const AF_LOCAL: ::c_int = 1; // AF_UNIX
pub const AF_FILE: ::c_int = 1; // AF_UNIX

pub const EFD_SEMAPHORE: ::c_int = 0x1;
pub const EFD_NONBLOCK: ::c_int = 0x800;
pub const EFD_CLOEXEC: ::c_int = 0x80000;

pub const TCP_KEEPIDLE: ::c_int = 34;
pub const TCP_KEEPCNT: ::c_int = 35;
pub const TCP_KEEPINTVL: ::c_int = 36;
pub const TCP_CONGESTION: ::c_int = 37;

pub const F_OFD_GETLK: ::c_int = 50;
pub const F_OFD_SETLKL: ::c_int = 51;
pub const F_OFD_SETLKW: ::c_int = 52;
pub const F_FLOCK: ::c_int = 55;
pub const F_FLOCKW: ::c_int = 56;

extern "C" {
    pub fn eventfd(init: ::c_uint, flags: ::c_int) -> ::c_int;

    pub fn mincore(addr: ::caddr_t, len: ::size_t, vec: *mut ::c_char) -> ::c_int;

    pub fn pset_bind_lwp(
        pset: ::psetid_t,
        id: ::id_t,
        pid: ::pid_t,
        opset: *mut ::psetid_t,
    ) -> ::c_int;
    pub fn pset_getloadavg(pset: ::psetid_t, load: *mut ::c_double, num: ::c_int) -> ::c_int;

    pub fn preadv(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t) -> ::ssize_t;
    pub fn pwritev(fd: ::c_int, iov: *const ::iovec, iovcnt: ::c_int, offset: ::off_t)
        -> ::ssize_t;
}
<|endoftext|>


<commit_before>use clap::{Arg, ArgMatches, App, SubCommand, AppSettings};

pub fn create_arg_parser<'a, 'b>() -> App<'a, 'b> {
    App::new("A rust based clone of the all time classic xxd tool")
        .version("0.1.0")
        .author("Nicola Coretti <nicola.coretti@gmail.com>")
        .about("make a hexdump or the reverse")
        .global_settings(&[AppSettings::ColoredHelp])
        .arg(Arg::with_name("infile")
                 .short("i")
                 .long("input-file")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Input file which shall be used (default: stdin)"))
        .arg(Arg::with_name("outfile")
                 .short("o")
                 .long("output-file")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("File to which the output will be written (default: stdout)"))
        .arg(Arg::with_name("seek")
                 .short("s")
                 .long("seek")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Offset in the file where to start reading"))
        .arg(Arg::with_name("length")
                 .short("l")
                 .long("length")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Amount of bytes which shall be read"))
        .subcommand(SubCommand::with_name("dump")
                        .about("Dumps an input file in the appropriate output format")
                        .arg(Arg::with_name("plain_hexdump")
                                 .short("p")
                                 .long("plain-hexdump")
                                 .required(false)
                                 .help("output in postscript plain hexdump style."))
                        .arg(Arg::with_name("format")
                                 .short("f")
                                 .long("format")
                                 .required(false)
                                 .takes_value(true)
                                 .possible_value("Hex")
                                 .possible_value("hex")
                                 .possible_value("bin")
                                 .possible_value("oct")
                                 .possible_value("dec")
                                 .help("Specifies the output format for the value (default: hex)"))
                        .arg(Arg::with_name("group-size")
                                 .short("g")
                                 .long("group-size")
                                 .required(false)
                                 .takes_value(true)
                                 .help("Separate  the output of every <bytes> bytes (two hex characters or eight bit-digits each) by a whitespace."))
                        .arg(Arg::with_name("columns")
                                 .short("c")
                                 .long("columns")
                                 .required(false)
                                 .takes_value(true)
                                 .help("Specifies the amount of output columns")))
        .subcommand(SubCommand::with_name("convert")
                        .about("Converts input data to a file (e.g. hexstream -> binary file")
                        .arg(Arg::with_name("format")
                                 .short("f")
                                 .long("format")
                                 .required(false)
                                 .takes_value(true)
                                 .possible_value("binary")
                                 .possible_value("c-array")
                                 .possible_value("oct")
                                 .help("Specifies the output format (default: hex)")))
        .subcommand(SubCommand::with_name("generate")
                        .about("Generates a source file containing the specified file as array")
                        .arg(Arg::with_name("template")
                                 .short("t")
                                 .long("template")
                                 .required(false)
                                 .takes_value(true)
                                 .possible_value("c")
                                 .possible_value("cpp")
                                 .possible_value("rust")
                                 .possible_value("python")
                                 .help("Specifies a template file which shall be used for \
                                        generation (default: c)"))
                 )
}
<commit_msg>Update description of subcommand convert<commit_after>use clap::{Arg, ArgMatches, App, SubCommand, AppSettings};

pub fn create_arg_parser<'a, 'b>() -> App<'a, 'b> {
    App::new("A rust based clone of the all time classic xxd tool")
        .version("0.1.0")
        .author("Nicola Coretti <nicola.coretti@gmail.com>")
        .about("make a hexdump or the reverse")
        .global_settings(&[AppSettings::ColoredHelp])
        .arg(Arg::with_name("infile")
                 .short("i")
                 .long("input-file")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Input file which shall be used (default: stdin)"))
        .arg(Arg::with_name("outfile")
                 .short("o")
                 .long("output-file")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("File to which the output will be written (default: stdout)"))
        .arg(Arg::with_name("seek")
                 .short("s")
                 .long("seek")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Offset in the file where to start reading"))
        .arg(Arg::with_name("length")
                 .short("l")
                 .long("length")
                 .required(false)
                 .takes_value(true)
                 .global(true)
                 .help("Amount of bytes which shall be read"))
        .subcommand(SubCommand::with_name("dump")
                        .about("Dumps an input file in the appropriate output format")
                        .arg(Arg::with_name("plain_hexdump")
                                 .short("p")
                                 .long("plain-hexdump")
                                 .required(false)
                                 .help("output in postscript plain hexdump style."))
                        .arg(Arg::with_name("format")
                                 .short("f")
                                 .long("format")
                                 .required(false)
                                 .takes_value(true)
                                 .possible_value("Hex")
                                 .possible_value("hex")
                                 .possible_value("bin")
                                 .possible_value("oct")
                                 .possible_value("dec")
                                 .help("Specifies the output format for the value (default: hex)"))
                        .arg(Arg::with_name("group-size")
                                 .short("g")
                                 .long("group-size")
                                 .required(false)
                                 .takes_value(true)
                                 .help("Separate  the output of every <bytes> bytes (two hex characters or eight bit-digits each) by a whitespace."))
                        .arg(Arg::with_name("columns")
                                 .short("c")
                                 .long("columns")
                                 .required(false)
                                 .takes_value(true)
                                 .help("Specifies the amount of output columns")))
        .subcommand(SubCommand::with_name("convert")
                        .about("Converts a textual memory dump back into a binary blob.")
                        .before_help("Attention: currently only plain hexdumps are supported as input for this command. (see xxd-rs dump --plain-hexdump)")
                        )
        .subcommand(SubCommand::with_name("generate")
                        .about("Generates a source file containing the specified file as array")
                        .arg(Arg::with_name("template")
                                 .short("t")
                                 .long("template")
                                 .required(false)
                                 .takes_value(true)
                                 .possible_value("c")
                                 .possible_value("cpp")
                                 .possible_value("rust")
                                 .possible_value("python")
                                 .help("Specifies a template file which shall be used for \
                                        generation (default: c)"))
                 )
}
<|endoftext|>


<commit_before>extern crate gitters;

extern crate rustc_serialize;
extern crate docopt;

use docopt::Docopt;
use gitters::cli;
use gitters::commits;
use gitters::objects;
use gitters::pager;
use gitters::revisions;

const USAGE: &'static str = "
log - Show commit logs

Usage:
  log [<object>]
  log (-h | --help)

Options:
  -h --help  Show this screen.
";

#[derive(RustcDecodable)]
struct Args {
    arg_object: Option<String>,
}

fn print_full_commit(commit: &commits::Commit) {
    let &commits::Commit {
        name: objects::Name(ref name),
        author: commits::CommitUser { name: ref author_name, date: ref author_date },
        ref message,
        ..
    } = commit;

    println!("\x1B[33mcommit {}\x1B[0m", name);
    println!("Author: {}", author_name);
    println!("Date:   {}", author_date.format("%a %b %-d %H:%M:%S %Y %z"));
    println!("");
    println!("    {}", str::replace(&message, "\n", "\n    "));
    println!("");
}

fn print_history(commit_rev: String) -> cli::Result {
    println!("commit_rev: '{}'", commit_rev);

    let resolved = try!(cli::wrap_with_status(revisions::resolve(&commit_rev), 1));
    try!(cli::wrap_with_status(pager::setup(), 1));

    let mut current_commit_rev = Some(resolved);
    while current_commit_rev.is_some() {
        let name = current_commit_rev.unwrap();
        let obj = try!(cli::wrap_with_status(objects::read_object(&name), 1));

        match obj {
            objects::Object::Commit(commit) => {
                // In the future, print in the format specified by the command line arguments.
                print_full_commit(&commit);
                current_commit_rev = commit.parent;
            },
            _ => {
                return Err(cli::Error {
                    message: format!("object {} is not a commit", name),
                    status: 2
                });
            }
        }
    }

    return cli::success();
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    cli::exit_with(print_history(args.arg_object.unwrap_or("HEAD".to_string())))
}
<commit_msg>Remove unnecessary println from "log"<commit_after>extern crate gitters;

extern crate rustc_serialize;
extern crate docopt;

use docopt::Docopt;
use gitters::cli;
use gitters::commits;
use gitters::objects;
use gitters::pager;
use gitters::revisions;

const USAGE: &'static str = "
log - Show commit logs

Usage:
  log [<object>]
  log (-h | --help)

Options:
  -h --help  Show this screen.
";

#[derive(RustcDecodable)]
struct Args {
    arg_object: Option<String>,
}

fn print_full_commit(commit: &commits::Commit) {
    let &commits::Commit {
        name: objects::Name(ref name),
        author: commits::CommitUser { name: ref author_name, date: ref author_date },
        ref message,
        ..
    } = commit;

    println!("\x1B[33mcommit {}\x1B[0m", name);
    println!("Author: {}", author_name);
    println!("Date:   {}", author_date.format("%a %b %-d %H:%M:%S %Y %z"));
    println!("");
    println!("    {}", str::replace(&message, "\n", "\n    "));
    println!("");
}

fn print_history(commit_rev: String) -> cli::Result {
    let resolved = try!(cli::wrap_with_status(revisions::resolve(&commit_rev), 1));
    try!(cli::wrap_with_status(pager::setup(), 1));

    let mut current_commit_rev = Some(resolved);
    while current_commit_rev.is_some() {
        let name = current_commit_rev.unwrap();
        let obj = try!(cli::wrap_with_status(objects::read_object(&name), 1));

        match obj {
            objects::Object::Commit(commit) => {
                // In the future, print in the format specified by the command line arguments.
                print_full_commit(&commit);
                current_commit_rev = commit.parent;
            },
            _ => {
                return Err(cli::Error {
                    message: format!("object {} is not a commit", name),
                    status: 2
                });
            }
        }
    }

    return cli::success();
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.decode())
        .unwrap_or_else(|e| e.exit());

    cli::exit_with(print_history(args.arg_object.unwrap_or("HEAD".to_string())))
}
<|endoftext|>


<commit_before>use std::fs;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name = ".kic";
    if dir_exists(dir_name) {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(dir_name) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn dir_exists<P: AsRef<Path>>(path: P) -> bool {
    match fs::metadata(path) {
        Ok(m)    => m.is_dir(),
        Err(why) => {
            match why.raw_os_error() {
                Some(2) => false,
                _       => panic!("{:?}", why),
            }
        }
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<commit_msg>Create "config" file<commit_after>use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name = ".kic";
    if dir_exists(&dir_name) {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(dir_name) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config";
    let path_to_config = dir_name.to_string() + "/" + config_file;
    if file_exists(&path_to_config) {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                match fp.write(b"Hello, world!!\n") {
                    Ok(_)    => {},
                    Err(why) => panic!("{:?}", why),
                }
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn dir_exists<P: AsRef<Path>>(path: P) -> bool {
    match fs::metadata(path) {
        Ok(m)    => m.is_dir(),
        Err(why) => {
            match why.raw_os_error() {
                Some(2) => false,
                _       => panic!("{:?}", why),
            }
        }
    }
}

fn file_exists<P: AsRef<Path>>(path: P) -> bool {
    match fs::metadata(path) {
        Ok(m) => m.is_file(),
        Err(why) => {
            match why.raw_os_error() {
                Some(2) => false,
                _       => panic!("{:?}", why),
            }
        }
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
use core::prelude::*;
use core::marker::PhantomData;
use arch::Registers;
use stack;
use debug::StackId;

pub struct Context<'a, Stack: stack::Stack> {
  regs: Registers,
  _stack_id: StackId,
  stack: Stack,
  _ref: PhantomData<&'a ()>
}

impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
  #[inline]
  pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
    where F: FnOnce() + Send + 'a {
    let stack_id = StackId::register(&mut stack);
    let regs = Registers::new(&mut stack, f);
    Context {
      regs: regs,
      _stack_id: stack_id,
      stack: stack,
      _ref: PhantomData
    }
  }

  #[inline(always)]
  pub unsafe fn swap(&mut self) {
    self.regs.swap()
  }

  pub unsafe fn destroy(self) -> Stack {
    self.stack
  }
}
<commit_msg>make Context::destroy inlineable<commit_after>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
use core::prelude::*;
use core::marker::PhantomData;
use arch::Registers;
use stack;
use debug::StackId;

pub struct Context<'a, Stack: stack::Stack> {
  regs: Registers,
  _stack_id: StackId,
  stack: Stack,
  _ref: PhantomData<&'a ()>
}

impl<'a, Stack> Context<'a, Stack> where Stack: stack::Stack {
  #[inline]
  pub unsafe fn new<F>(mut stack: Stack, f: F) -> Context<'a, Stack>
    where F: FnOnce() + Send + 'a {
    let stack_id = StackId::register(&mut stack);
    let regs = Registers::new(&mut stack, f);
    Context {
      regs: regs,
      _stack_id: stack_id,
      stack: stack,
      _ref: PhantomData
    }
  }

  #[inline(always)]
  pub unsafe fn swap(&mut self) {
    self.regs.swap()
  }

  #[inline]
  pub unsafe fn destroy(self) -> Stack {
    self.stack
  }
}
<|endoftext|>


<commit_before>//! The initializer module parses arguments and verfies commands are valid
//! The creator module handles creating the muxed directory and project files.
#![allow(experimental)]

use std::io::File;
use std::path::posix::Path;
use editor;
use root;

#[cfg(test)] use test_helper::{random_name,cleanup_file,cleanup_dir};

static TEMPLATE: &'static str = include_str!("creator/template.toml");

pub fn new(name: &str) {
    let muxed_dir = root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), name));

    if !path.exists() {
        create_project_file(path);

        match editor::default_editor_set() {
            true  => editor::open_project_file(path),
            false => println!("Default editor is not set. Please define $EDITOR in your ~/.bashrc or similar file.")
        }
    } else {
        println!("Project already exists.");
    }
}

/// Copy and create the new project file from a template.
fn create_project_file(path: &Path) {
    let filename = project_filename(path);
    match File::create(path).write(modified_template(TEMPLATE, filename.as_slice()).as_bytes()) {
        Ok(())  => (),
        Err(_e) => println!("Failed to create project {}", filename),
    }
}

fn modified_template(template: &str, project_name: &str) -> String {
    template.replace("{file_name}", project_name)
}

fn project_filename(path: &Path) -> String {
    String::from_utf8(path.filename().unwrap().to_vec()).unwrap().replace(".toml", "")
}

#[test]
fn returns_filename_as_string() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker"));
  assert_eq!(project_filename(path), String::from_str("skywalker"))
}

#[test]
fn accepts_periods_in_filenames() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker1.2"));
  assert_eq!(project_filename(path), String::from_str("skywalker1.2"))
}

#[test]
fn accepts_dashes_in_filenames() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker1-2"));
  assert_eq!(project_filename(path), String::from_str("skywalker1-2"))
}

#[test]
fn populates_template_values() {
    let value = modified_template(TEMPLATE, "muxed project");
    let result = value.as_slice().contains("muxed project");
    assert!(result);
}

#[test]
fn removes_template_placeholders() {
    let value = modified_template(TEMPLATE, "muxed project");
    let result = !value.as_slice().contains("{file_name}");
    assert!(result);
}

#[test]
fn creates_project_file() {
    let muxed_dir = &root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), random_name()));
    create_project_file(path);
    assert!(path.exists());

    cleanup_dir(muxed_dir);
}

//#[test]
//fn errors_when_creating_project_file() {
//    //assert!(false);
//}

#[test]
fn create_copies_the_template_file() {
    let muxed_dir = &root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), random_name()));
    let filename = project_filename(path);
    create_project_file(path);
    let data = File::open(path).read_to_end().unwrap();
    let template_expectation = modified_template(TEMPLATE, filename.as_slice());
    assert_eq!(data.as_slice(), template_expectation.as_bytes());

    cleanup_dir(muxed_dir);
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = random_name();
    let muxed_dir = &root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), name));
    println!("{}", path.display())
    new(name.as_slice());
    assert!(path.exists());

    cleanup_dir(path);
}
<commit_msg>Re-write the test just a little bit.<commit_after>//! The initializer module parses arguments and verfies commands are valid
//! The creator module handles creating the muxed directory and project files.
#![allow(experimental)]

use std::io::File;
use std::path::posix::Path;
use editor;
use root;

#[cfg(test)] use test_helper::{random_name,cleanup_file,cleanup_dir};

static TEMPLATE: &'static str = include_str!("creator/template.toml");

pub fn new(name: &str) {
    let muxed_dir = root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), name));

    if !path.exists() {
        create_project_file(path);

        match editor::default_editor_set() {
            true  => editor::open_project_file(path),
            false => println!("Default editor is not set. Please define $EDITOR in your ~/.bashrc or similar file.")
        }
    } else {
        println!("Project already exists.");
    }
}

/// Copy and create the new project file from a template.
fn create_project_file(path: &Path) {
    let filename = project_filename(path);
    match File::create(path).write(modified_template(TEMPLATE, filename.as_slice()).as_bytes()) {
        Ok(())  => (),
        Err(_e) => println!("Failed to create project {}", filename),
    }
}

fn modified_template(template: &str, project_name: &str) -> String {
    template.replace("{file_name}", project_name)
}

fn project_filename(path: &Path) -> String {
    String::from_utf8(path.filename().unwrap().to_vec()).unwrap().replace(".toml", "")
}

#[test]
fn returns_filename_as_string() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker"));
  assert_eq!(project_filename(path), String::from_str("skywalker"))
}

#[test]
fn accepts_periods_in_filenames() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker1.2"));
  assert_eq!(project_filename(path), String::from_str("skywalker1.2"))
}

#[test]
fn accepts_dashes_in_filenames() {
  let path = &Path::new(format!("{}/{}", "luke", "skywalker1-2"));
  assert_eq!(project_filename(path), String::from_str("skywalker1-2"))
}

#[test]
fn populates_template_values() {
    let value = modified_template(TEMPLATE, "muxed project");
    let result = value.as_slice().contains("muxed project");
    assert!(result);
}

#[test]
fn removes_template_placeholders() {
    let value = modified_template(TEMPLATE, "muxed project");
    let result = !value.as_slice().contains("{file_name}");
    assert!(result);
}

#[test]
fn creates_project_file() {
    let muxed_dir = &root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), random_name()));
    create_project_file(path);
    assert!(path.exists());

    cleanup_dir(muxed_dir);
}

//#[test]
//fn errors_when_creating_project_file() {
//    //assert!(false);
//}

#[test]
fn create_copies_the_template_file() {
    let muxed_dir = &root::muxed_dir();
    let path = &Path::new(format!("{}/{}.toml", muxed_dir.display(), random_name()));
    let filename = project_filename(path);
    create_project_file(path);
    let data = File::open(path).read_to_end().unwrap();
    let template_expectation = modified_template(TEMPLATE, filename.as_slice());
    assert_eq!(data.as_slice(), template_expectation.as_bytes());

    cleanup_dir(muxed_dir);
}

#[test]
fn new_writes_file_to_muxed_dir() {
    let name = random_name();
    let muxed_dir = root::muxed_dir();
    let path = &Path::new(format!("{}/{}", muxed_dir.display(), name));

    println!("{}", path.display());

    new(name.as_slice());
    assert!(path.exists());

    cleanup_dir(path);
}
<|endoftext|>


<commit_before>use std::c_str::CString;
use std::fmt;
use libc::{c_int,c_char};

#[allow(non_camel_case_types)]

#[repr(C)]
pub enum ErrCode {
    OK = 0,
    UNSUPPORTED_PROTOCOL,    /* 1 */
    FAILED_INIT,             /* 2 */
    URL_MALFORMAT,           /* 3 */
    NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
                                7.17.0, reused in April 2011 for 7.21.5] */
    COULDNT_RESOLVE_PROXY,   /* 5 */
    COULDNT_RESOLVE_HOST,    /* 6 */
    COULDNT_CONNECT,         /* 7 */
    FTP_WEIRD_SERVER_REPLY,  /* 8 */
    REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
                                due to lack of access - when login fails
                                this is not returned. */
    FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
                                7.15.4, reused in Dec 2011 for 7.24.0]*/
    FTP_WEIRD_PASS_REPLY,    /* 11 */
    FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
                                [was obsoleted in August 2007 for 7.17.0,
                                reused in Dec 2011 for 7.24.0]*/
    FTP_WEIRD_PASV_REPLY,    /* 13 */
    FTP_WEIRD_227_FORMAT,    /* 14 */
    FTP_CANT_GET_HOST,       /* 15 */
    OBSOLETE16,              /* 16 - NOT USED */
    FTP_COULDNT_SET_TYPE,    /* 17 */
    PARTIAL_FILE,            /* 18 */
    FTP_COULDNT_RETR_FILE,   /* 19 */
    OBSOLETE20,              /* 20 - NOT USED */
    QUOTE_ERROR,             /* 21 - quote command failure */
    HTTP_RETURNED_ERROR,     /* 22 */
    WRITE_ERROR,             /* 23 */
    OBSOLETE24,              /* 24 - NOT USED */
    UPLOAD_FAILED,           /* 25 - failed upload "command" */
    READ_ERROR,              /* 26 - couldn't open/read from file */
    OUT_OF_MEMORY,           /* 27 */
    /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
       instead of a memory allocation error if CURL_DOES_CONVERSIONS
       is defined
       */
    OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
    OBSOLETE29,              /* 29 - NOT USED */
    FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
    FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
    OBSOLETE32,              /* 32 - NOT USED */
    RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
    HTTP_POST_ERROR,         /* 34 */
    SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
    BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
    FILE_COULDNT_READ_FILE,  /* 37 */
    LDAP_CANNOT_BIND,        /* 38 */
    LDAP_SEARCH_FAILED,      /* 39 */
    OBSOLETE40,              /* 40 - NOT USED */
    FUNCTION_NOT_FOUND,      /* 41 */
    ABORTED_BY_CALLBACK,     /* 42 */
    BAD_FUNCTION_ARGUMENT,   /* 43 */
    OBSOLETE44,              /* 44 - NOT USED */
    INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
    OBSOLETE46,              /* 46 - NOT USED */
    TOO_MANY_REDIRECTS ,     /* 47 - catch endless re-direct loops */
    UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
    TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */
    OBSOLETE50,              /* 50 - NOT USED */
    PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
                                 wasn't verified fine */
    GOT_NOTHING,             /* 52 - when this is a specific error */
    SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
    SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
                                default */
    SEND_ERROR,              /* 55 - failed sending network data */
    RECV_ERROR,              /* 56 - failure in receiving network data */
    OBSOLETE57,              /* 57 - NOT IN USE */
    SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
    SSL_CIPHER,              /* 59 - couldn't use specified cipher */
    SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
    BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
    LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
    FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
    USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
    SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
                                that failed */
    SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
    LOGIN_DENIED,            /* 67 - user, password or similar was not
                                accepted and we failed to login */
    TFTP_NOTFOUND,           /* 68 - file not found on server */
    TFTP_PERM,               /* 69 - permission problem on server */
    REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
    TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
    TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
    REMOTE_FILE_EXISTS,      /* 73 - File already exists */
    TFTP_NOSUCHUSER,         /* 74 - No such user */
    CONV_FAILED,             /* 75 - conversion failed */
    CONV_REQD,               /* 76 - caller must register conversion
                                callbacks using curl_easy_setopt options
                                CURLOPT_CONV_FROM_NETWORK_FUNCTION,
                                CURLOPT_CONV_TO_NETWORK_FUNCTION, and
                                CURLOPT_CONV_FROM_UTF8_FUNCTION */
    SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
                                or wrong format */
    REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
    SSH,                     /* 79 - error from the SSH layer, somewhat
                                generic so the error message will be of
                                interest when this has happened */

    SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
                                connection */
    AGAIN,                   /* 81 - socket is not ready for send/recv,
                                wait till it's ready and try again (Added
                                in 7.18.2) */
    SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
                                wrong format (Added in 7.19.0) */
    SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
                                7.19.0) */
    FTP_PRET_FAILED,         /* 84 - a PRET command failed */
    RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
    RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
    FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
    CHUNK_FAILED,            /* 88 - chunk callback reported error */
    NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
                                session will be queued */
    LAST /* never use! */
}

#[link(name = "curl")]
extern {
    fn curl_easy_strerror(code: ErrCode) -> *const c_char;
}

impl ErrCode {
    pub fn is_success(self) -> bool {
        (self as c_int) == 0
    }
}

impl fmt::Show for ErrCode {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        let c_str = unsafe { CString::new(curl_easy_strerror(*self), false) };

        match c_str.as_str() {
            Some(s) => write!(fmt, "{}", s),
            None => write!(fmt, "<unknown err>")
        }
    }
}
<commit_msg>Implements `std::error::Error` for `ErrCode`.<commit_after>use std::c_str::CString;
use std::{error, fmt, str};
use libc::{c_int,c_char};

#[allow(non_camel_case_types)]

#[repr(C)]
pub enum ErrCode {
    OK = 0,
    UNSUPPORTED_PROTOCOL,    /* 1 */
    FAILED_INIT,             /* 2 */
    URL_MALFORMAT,           /* 3 */
    NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
                                7.17.0, reused in April 2011 for 7.21.5] */
    COULDNT_RESOLVE_PROXY,   /* 5 */
    COULDNT_RESOLVE_HOST,    /* 6 */
    COULDNT_CONNECT,         /* 7 */
    FTP_WEIRD_SERVER_REPLY,  /* 8 */
    REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
                                due to lack of access - when login fails
                                this is not returned. */
    FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
                                7.15.4, reused in Dec 2011 for 7.24.0]*/
    FTP_WEIRD_PASS_REPLY,    /* 11 */
    FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
                                [was obsoleted in August 2007 for 7.17.0,
                                reused in Dec 2011 for 7.24.0]*/
    FTP_WEIRD_PASV_REPLY,    /* 13 */
    FTP_WEIRD_227_FORMAT,    /* 14 */
    FTP_CANT_GET_HOST,       /* 15 */
    OBSOLETE16,              /* 16 - NOT USED */
    FTP_COULDNT_SET_TYPE,    /* 17 */
    PARTIAL_FILE,            /* 18 */
    FTP_COULDNT_RETR_FILE,   /* 19 */
    OBSOLETE20,              /* 20 - NOT USED */
    QUOTE_ERROR,             /* 21 - quote command failure */
    HTTP_RETURNED_ERROR,     /* 22 */
    WRITE_ERROR,             /* 23 */
    OBSOLETE24,              /* 24 - NOT USED */
    UPLOAD_FAILED,           /* 25 - failed upload "command" */
    READ_ERROR,              /* 26 - couldn't open/read from file */
    OUT_OF_MEMORY,           /* 27 */
    /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
       instead of a memory allocation error if CURL_DOES_CONVERSIONS
       is defined
       */
    OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
    OBSOLETE29,              /* 29 - NOT USED */
    FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
    FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
    OBSOLETE32,              /* 32 - NOT USED */
    RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
    HTTP_POST_ERROR,         /* 34 */
    SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
    BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
    FILE_COULDNT_READ_FILE,  /* 37 */
    LDAP_CANNOT_BIND,        /* 38 */
    LDAP_SEARCH_FAILED,      /* 39 */
    OBSOLETE40,              /* 40 - NOT USED */
    FUNCTION_NOT_FOUND,      /* 41 */
    ABORTED_BY_CALLBACK,     /* 42 */
    BAD_FUNCTION_ARGUMENT,   /* 43 */
    OBSOLETE44,              /* 44 - NOT USED */
    INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
    OBSOLETE46,              /* 46 - NOT USED */
    TOO_MANY_REDIRECTS ,     /* 47 - catch endless re-direct loops */
    UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
    TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */
    OBSOLETE50,              /* 50 - NOT USED */
    PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
                                 wasn't verified fine */
    GOT_NOTHING,             /* 52 - when this is a specific error */
    SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
    SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
                                default */
    SEND_ERROR,              /* 55 - failed sending network data */
    RECV_ERROR,              /* 56 - failure in receiving network data */
    OBSOLETE57,              /* 57 - NOT IN USE */
    SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
    SSL_CIPHER,              /* 59 - couldn't use specified cipher */
    SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
    BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
    LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
    FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
    USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
    SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
                                that failed */
    SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
    LOGIN_DENIED,            /* 67 - user, password or similar was not
                                accepted and we failed to login */
    TFTP_NOTFOUND,           /* 68 - file not found on server */
    TFTP_PERM,               /* 69 - permission problem on server */
    REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
    TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
    TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
    REMOTE_FILE_EXISTS,      /* 73 - File already exists */
    TFTP_NOSUCHUSER,         /* 74 - No such user */
    CONV_FAILED,             /* 75 - conversion failed */
    CONV_REQD,               /* 76 - caller must register conversion
                                callbacks using curl_easy_setopt options
                                CURLOPT_CONV_FROM_NETWORK_FUNCTION,
                                CURLOPT_CONV_TO_NETWORK_FUNCTION, and
                                CURLOPT_CONV_FROM_UTF8_FUNCTION */
    SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
                                or wrong format */
    REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
    SSH,                     /* 79 - error from the SSH layer, somewhat
                                generic so the error message will be of
                                interest when this has happened */

    SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
                                connection */
    AGAIN,                   /* 81 - socket is not ready for send/recv,
                                wait till it's ready and try again (Added
                                in 7.18.2) */
    SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
                                wrong format (Added in 7.19.0) */
    SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
                                7.19.0) */
    FTP_PRET_FAILED,         /* 84 - a PRET command failed */
    RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
    RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
    FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
    CHUNK_FAILED,            /* 88 - chunk callback reported error */
    NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
                                session will be queued */
    LAST /* never use! */
}

#[link(name = "curl")]
extern {
    fn curl_easy_strerror(code: ErrCode) -> *const c_char;
}

impl ErrCode {
    pub fn is_success(self) -> bool {
        (self as c_int) == 0
    }
}

impl fmt::Show for ErrCode {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::FormatError> {
        let c_str = unsafe { CString::new(curl_easy_strerror(*self), false) };

        match c_str.as_str() {
            Some(s) => write!(fmt, "{}", s),
            None => write!(fmt, "<unknown err>")
        }
    }
}

impl error::Error for ErrCode {
    fn description(&self) -> &str {
        unsafe { str::raw::c_str_to_static_slice(curl_easy_strerror(*self)) }
    }
}
<|endoftext|>


<commit_before>use std::mem::swap;
use std::ptr;
use std::sync::Mutex;

use ctxt::SemContext;
use driver::cmd::Args;
use gc::Collector;
use gc::root::{get_rootset, IndirectObj};
use mem;
use object::Obj;
use os;
use timer::{in_ms, Timer};

pub struct CopyCollector {
    spaces: Mutex<Spaces>,
}

struct Spaces {
    from_space: SemiSpace,
    to_space: SemiSpace,
}

impl Spaces {
    fn new(size: usize) -> Spaces {
        Spaces {
            from_space: SemiSpace::new(size),
            to_space: SemiSpace::new(size),
        }
    }
}

impl CopyCollector {
    pub fn new(args: &Args) -> CopyCollector {
        let heap_size = args.flag_heap_size.map(|s| *s).unwrap_or(32 * 1024 * 1024) / 2;

        CopyCollector {
            spaces: Mutex::new(Spaces::new(heap_size)),
        }
    }
}

impl Collector for CopyCollector {
    fn alloc(&self, ctxt: &SemContext, size: usize) -> *const u8 {
        let mut spaces = self.spaces.lock().unwrap();
        let mut spaces = &mut *spaces;

        if ctxt.args.flag_gc_stress {
            let rootset = get_rootset(ctxt);
            minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);
        }

        let mut ptr = spaces.to_space.allocate(size);

        if ptr.is_null() {
            let rootset = get_rootset(ctxt);
            minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);

            ptr = spaces.to_space.allocate(size);
        }

        ptr
    }

    fn collect(&self, ctxt: &SemContext) {
        let mut spaces = self.spaces.lock().unwrap();
        let mut spaces = &mut *spaces;

        let rootset = get_rootset(ctxt);
        minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);
    }
}

pub struct SemiSpace {
    start: *const u8,
    end: *const u8,

    scan: *const u8,
    next: *const u8,
}

impl SemiSpace {
    pub fn new(size: usize) -> SemiSpace {
        let size = mem::align_usize(size, os::page_size() as usize);
        let ptr = os::mmap(size, os::Writable);

        if ptr.is_null() {
            panic!("could not allocate semi space of size {} bytes", size);
        }

        SemiSpace {
            start: ptr,
            end: unsafe { ptr.offset(size as isize) },
            scan: ptr,
            next: ptr,
        }
    }

    pub fn allocate(&mut self, size: usize) -> *const u8 {
        debug_assert!(size % (mem::ptr_width() as usize) == 0);

        if self.end as usize - self.next as usize > size {
            let next = unsafe { self.next.offset(size as isize) };

            let addr = self.next;
            unsafe {
                ptr::write_bytes(addr as *mut u8, 0, size);
            }

            self.next = next;

            addr
        } else {
            ptr::null()
        }
    }

    pub fn includes(&self, ptr: *const u8) -> bool {
        self.start <= ptr && ptr < self.end
    }

    pub fn reset(&mut self) {
        self.scan = self.start;
        self.next = self.start;
    }

    pub fn size(&self) -> usize {
        self.end as usize - self.start as usize
    }
}

impl Drop for SemiSpace {
    fn drop(&mut self) {
        let size = self.end as usize - self.start as usize;
        os::munmap(self.start, size);
    }
}

pub fn minor_collect(
    ctxt: &SemContext,
    from_space: &mut SemiSpace,
    to_space: &mut SemiSpace,
    rootset: Vec<IndirectObj>,
) {
    let mut timer = Timer::new(ctxt.args.flag_gc_events);
    swap(from_space, to_space);

    // empty to-space
    to_space.reset();

    for &root in &rootset {
        let root_ptr = root.get();

        if from_space.includes(root_ptr as *const u8) {
            root.set(copy(root_ptr, to_space));
        }
    }

    while to_space.scan < to_space.next {
        let object = unsafe { &mut *(to_space.scan as *mut Obj) };

        object.visit_reference_fields(|child| {
            let child_ptr = child.get();

            if from_space.includes(child_ptr as *const u8) {
                child.set(copy(child_ptr, to_space));
            }
        });

        to_space.scan = unsafe { to_space.scan.offset(object.size() as isize) };
    }

    // memset from-space to garbage data for debug builds
    // makes sure that no pointer into from-space is left
    if cfg!(debug_assertions) {
        unsafe {
            ptr::write_bytes(from_space.start as *mut u8, 0xcc, from_space.size());
        }
    }

    timer.stop_with(|dur| {
        // self.collect_duration += dur;

        if ctxt.args.flag_gc_events {
            println!("GC minor: collect garbage ({} ms)", in_ms(dur));
        }
    });
}

pub fn copy(obj: *mut Obj, to_space: &mut SemiSpace) -> *mut Obj {
    let obj = unsafe { &mut *obj };
    let addr = get_forwarding_address(obj);

    if is_forwarding_address(addr) {
        unmark_forwarding_address(addr) as *mut Obj
    } else {
        let addr = to_space.next;
        let obj_size = obj.size();

        unsafe {
            ptr::copy_nonoverlapping(obj as *const Obj as *const u8, addr as *mut u8, obj_size);
            to_space.next = to_space.next.offset(obj_size as isize);
        }

        set_forwarding_address(obj, addr);

        addr as *mut Obj
    }
}

pub fn is_forwarding_address(obj: *const u8) -> bool {
    (obj as usize) & 1 == 1
}

pub fn mark_forwarding_address(obj: *const u8) -> *const u8 {
    ((obj as usize) | 1) as *const u8
}

pub fn unmark_forwarding_address(obj: *const u8) -> *const u8 {
    ((obj as usize) & !1) as *const u8
}

pub fn get_forwarding_address(obj: &Obj) -> *const u8 {
    unsafe { *(obj as *const Obj as *const *const u8) }
}

pub fn set_forwarding_address(obj: &mut Obj, addr: *const u8) {
    unsafe {
        *(obj as *mut Obj as *mut *const u8) = mark_forwarding_address(addr);
    }
}

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

    #[test]
    fn test_mark_forwarding_address() {
        assert_eq!(9 as *const u8, mark_forwarding_address(8 as *const u8));
        assert_eq!(13 as *const u8, mark_forwarding_address(12 as *const u8));
    }

    #[test]
    fn test_unmark_forwarding_address() {
        assert_eq!(8 as *const u8, unmark_forwarding_address(9 as *const u8));
        assert_eq!(12 as *const u8, unmark_forwarding_address(13 as *const u8));
    }

    #[test]
    fn test_is_forwarding_address() {
        assert_eq!(false, is_forwarding_address(8 as *const u8));
        assert_eq!(true, is_forwarding_address(9 as *const u8));
        assert_eq!(false, is_forwarding_address(12 as *const u8));
        assert_eq!(true, is_forwarding_address(13 as *const u8));
    }
}
<commit_msg>gc: fix warnings<commit_after>use std::mem::swap;
use std::ptr;
use std::sync::Mutex;

use ctxt::SemContext;
use driver::cmd::Args;
use gc::Collector;
use gc::root::{get_rootset, IndirectObj};
use mem;
use object::Obj;
use os;
use timer::{in_ms, Timer};

pub struct CopyCollector {
    spaces: Mutex<Spaces>,
}

struct Spaces {
    from_space: SemiSpace,
    to_space: SemiSpace,
}

impl Spaces {
    fn new(size: usize) -> Spaces {
        Spaces {
            from_space: SemiSpace::new(size),
            to_space: SemiSpace::new(size),
        }
    }
}

impl CopyCollector {
    pub fn new(args: &Args) -> CopyCollector {
        let heap_size = args.flag_heap_size.map(|s| *s).unwrap_or(32 * 1024 * 1024) / 2;

        CopyCollector {
            spaces: Mutex::new(Spaces::new(heap_size)),
        }
    }
}

impl Collector for CopyCollector {
    fn alloc(&self, ctxt: &SemContext, size: usize) -> *const u8 {
        let mut spaces = self.spaces.lock().unwrap();
        let spaces = &mut *spaces;

        if ctxt.args.flag_gc_stress {
            let rootset = get_rootset(ctxt);
            minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);
        }

        let mut ptr = spaces.to_space.allocate(size);

        if ptr.is_null() {
            let rootset = get_rootset(ctxt);
            minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);

            ptr = spaces.to_space.allocate(size);
        }

        ptr
    }

    fn collect(&self, ctxt: &SemContext) {
        let mut spaces = self.spaces.lock().unwrap();
        let spaces = &mut *spaces;

        let rootset = get_rootset(ctxt);
        minor_collect(ctxt, &mut spaces.from_space, &mut spaces.to_space, rootset);
    }
}

pub struct SemiSpace {
    start: *const u8,
    end: *const u8,

    scan: *const u8,
    next: *const u8,
}

impl SemiSpace {
    pub fn new(size: usize) -> SemiSpace {
        let size = mem::align_usize(size, os::page_size() as usize);
        let ptr = os::mmap(size, os::Writable);

        if ptr.is_null() {
            panic!("could not allocate semi space of size {} bytes", size);
        }

        SemiSpace {
            start: ptr,
            end: unsafe { ptr.offset(size as isize) },
            scan: ptr,
            next: ptr,
        }
    }

    pub fn allocate(&mut self, size: usize) -> *const u8 {
        debug_assert!(size % (mem::ptr_width() as usize) == 0);

        if self.end as usize - self.next as usize > size {
            let next = unsafe { self.next.offset(size as isize) };

            let addr = self.next;
            unsafe {
                ptr::write_bytes(addr as *mut u8, 0, size);
            }

            self.next = next;

            addr
        } else {
            ptr::null()
        }
    }

    pub fn includes(&self, ptr: *const u8) -> bool {
        self.start <= ptr && ptr < self.end
    }

    pub fn reset(&mut self) {
        self.scan = self.start;
        self.next = self.start;
    }

    pub fn size(&self) -> usize {
        self.end as usize - self.start as usize
    }
}

impl Drop for SemiSpace {
    fn drop(&mut self) {
        let size = self.end as usize - self.start as usize;
        os::munmap(self.start, size);
    }
}

pub fn minor_collect(
    ctxt: &SemContext,
    from_space: &mut SemiSpace,
    to_space: &mut SemiSpace,
    rootset: Vec<IndirectObj>,
) {
    let mut timer = Timer::new(ctxt.args.flag_gc_events);
    swap(from_space, to_space);

    // empty to-space
    to_space.reset();

    for &root in &rootset {
        let root_ptr = root.get();

        if from_space.includes(root_ptr as *const u8) {
            root.set(copy(root_ptr, to_space));
        }
    }

    while to_space.scan < to_space.next {
        let object = unsafe { &mut *(to_space.scan as *mut Obj) };

        object.visit_reference_fields(|child| {
            let child_ptr = child.get();

            if from_space.includes(child_ptr as *const u8) {
                child.set(copy(child_ptr, to_space));
            }
        });

        to_space.scan = unsafe { to_space.scan.offset(object.size() as isize) };
    }

    // memset from-space to garbage data for debug builds
    // makes sure that no pointer into from-space is left
    if cfg!(debug_assertions) {
        unsafe {
            ptr::write_bytes(from_space.start as *mut u8, 0xcc, from_space.size());
        }
    }

    timer.stop_with(|dur| {
        // self.collect_duration += dur;

        if ctxt.args.flag_gc_events {
            println!("GC minor: collect garbage ({} ms)", in_ms(dur));
        }
    });
}

pub fn copy(obj: *mut Obj, to_space: &mut SemiSpace) -> *mut Obj {
    let obj = unsafe { &mut *obj };
    let addr = get_forwarding_address(obj);

    if is_forwarding_address(addr) {
        unmark_forwarding_address(addr) as *mut Obj
    } else {
        let addr = to_space.next;
        let obj_size = obj.size();

        unsafe {
            ptr::copy_nonoverlapping(obj as *const Obj as *const u8, addr as *mut u8, obj_size);
            to_space.next = to_space.next.offset(obj_size as isize);
        }

        set_forwarding_address(obj, addr);

        addr as *mut Obj
    }
}

pub fn is_forwarding_address(obj: *const u8) -> bool {
    (obj as usize) & 1 == 1
}

pub fn mark_forwarding_address(obj: *const u8) -> *const u8 {
    ((obj as usize) | 1) as *const u8
}

pub fn unmark_forwarding_address(obj: *const u8) -> *const u8 {
    ((obj as usize) & !1) as *const u8
}

pub fn get_forwarding_address(obj: &Obj) -> *const u8 {
    unsafe { *(obj as *const Obj as *const *const u8) }
}

pub fn set_forwarding_address(obj: &mut Obj, addr: *const u8) {
    unsafe {
        *(obj as *mut Obj as *mut *const u8) = mark_forwarding_address(addr);
    }
}

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

    #[test]
    fn test_mark_forwarding_address() {
        assert_eq!(9 as *const u8, mark_forwarding_address(8 as *const u8));
        assert_eq!(13 as *const u8, mark_forwarding_address(12 as *const u8));
    }

    #[test]
    fn test_unmark_forwarding_address() {
        assert_eq!(8 as *const u8, unmark_forwarding_address(9 as *const u8));
        assert_eq!(12 as *const u8, unmark_forwarding_address(13 as *const u8));
    }

    #[test]
    fn test_is_forwarding_address() {
        assert_eq!(false, is_forwarding_address(8 as *const u8));
        assert_eq!(true, is_forwarding_address(9 as *const u8));
        assert_eq!(false, is_forwarding_address(12 as *const u8));
        assert_eq!(true, is_forwarding_address(13 as *const u8));
    }
}
<|endoftext|>


<commit_before>// pest. Smart PEGs in Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// 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/.

/// A `macro` that defines each rule as a method on a `Parser`.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate pest;
/// # use pest::Input;
/// # use pest::StringInput;
/// # use pest::Rdp;
///
/// # fn main() {
/// impl_rdp!(MyRdp);
///
/// impl MyRdp {
///     grammar! {
///         exp = { paren ~ exp | [""] }
///         paren = { ["("] ~ exp ~ [")"] }
///     }
/// }
///
/// let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())()")));
///
/// assert!(parser.exp());
/// assert!(parser.end());
/// # }
/// ```
#[macro_export]
macro_rules! grammar {
    // handle parens
    (@conv $slf:ident ( ( $( $head:tt )* ) $( $tail:tt )* ) ( $( $optail:tt )* )
     ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( $( $head )* @rp $( $tail )* ) ( @lp $( $optail )* )
                 ( $( $output )* ))
    };
    (@conv $slf:ident ( @rp $( $tail:tt )* ) ( @lp $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( $( $tail )* ) ( $( $optail )* ) ( $( $output )* ))
    };
    (@conv $slf:ident ( @rp $( $tail:tt )* ) ( $op:tt $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( @rp $( $tail )* ) ( $( $optail )* ) ( $( $output )* $op ))
    };

    // handle operands
    (@conv $slf:ident ( ~ $( $tail:tt )* ) ( ~ $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( ~ $( $tail )* ) ( $( $optail )* ) ( $( $output )* ~ ))
    };
    (@conv $slf:ident ( ~ $( $tail:tt )* ) ( $( $optail:tt )* ) $output:tt) => {
        grammar!(@conv $slf ( $( $tail )* ) ( ~ $( $optail )* ) $output)
    };
    (@conv $slf:ident ( | $( $tail:tt )* ) ( ~ $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( | $( $tail )* ) ( $( $optail )* ) ( $( $output )* ~ ))
    };
    (@conv $slf:ident ( | $( $tail:tt )* ) ( | $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( | $( $tail )* ) ( $( $optail )* ) ( $( $output )* | ))
    };
    (@conv $slf:ident ( | $( $tail:tt )* ) ( $( $optail:tt )* ) $output:tt) => {
        grammar!(@conv $slf ( $( $tail )* ) ( | $( $optail )* ) $output)
    };

    // handle everything else
    (@conv $slf:ident ( $head:tt $( $tail:tt )* ) $ops:tt ( $( $output:tt )* )) => {
        grammar!(@conv $slf ( $( $tail )* ) $ops ( $( $output )* $head ))
    };

    // output remaining operators
    (@conv $slf:ident () () ( $( $output:tt )* )) => {
        grammar!(@process $slf () ($( $output )*))
    };
    (@conv $slf:ident () ( $op:tt $( $optail:tt )* ) ( $( $output:tt )* )) => {
        grammar!(@conv $slf () ( $( $optail )* ) ( $( $output )* $op ))
    };

    // match
    (@mtc $slf:ident (( $exp:expr ))) => (($exp));
    (@mtc $slf:ident [ $str:expr ]) => ($slf.matches($str));
    (@mtc $slf:ident $rule:ident) => ($slf.$rule());

    // process postfix
    (@process $_slf:ident (( $result:expr )) ()) => ($result);
    (@process $slf:ident ( $b:tt $a:tt $( $tail:tt )* ) ( ~ $( $optail:tt )* )) => {
        {
            let try = $slf.try(Box::new(move |parser| {
                grammar!(@mtc parser $a) && grammar!(@mtc parser $b)
            }));

            grammar!(@process $slf ((( try )) $( $tail )* ) ( $( $optail )* ))
        }
    };
    (@process $slf:ident ( $b:tt $a:tt $( $tail:tt )* ) ( | $( $optail:tt )* )) => {
        {
            let a = grammar!(@mtc $slf $a);
            let b = grammar!(@mtc $slf $b);

            grammar!(@process $slf ((( a || b )) $( $tail )* ) ( $( $optail )* ))
        }
    };
    (@process $slf:ident () ( $single:tt )) => {
        grammar!(@mtc $slf $single)
    };
    (@process $slf:ident ( $( $optail:tt )* ) ( $head:tt $( $tail:tt )* )) => {
        grammar!(@process $slf ( $head $( $optail )* ) ( $( $tail )* ))
    };

    ( $( $name:ident = { $( $ts:tt )* } )* ) => {
        $(
            #[allow(unused_parens)]
            #[allow(unused_variables)]
            pub fn $name(&mut self) -> bool {
                grammar!(@conv self ( $( $ts )* ) () ())
            }
        )*
    };
}

#[cfg(test)]
mod tests {
    use super::super::Rdp;
    use super::super::Parser;
    use super::super::Input;
    use super::super::StringInput;

    impl_rdp!(MyRdp);

    impl MyRdp {
        grammar! {
            exp = { paren ~ exp | [""] }
            paren = { ["("] ~ exp ~ [")"] }
        }
    }

    #[test]
    fn basic() {
        let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())()")));

        assert!(parser.exp());
        assert!(parser.end());
    }

    #[test]
    fn fail() {
        let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())(")));

        assert!(parser.exp());
        assert!(!parser.end());
    }
}
<commit_msg>Improved styling and fixed and issue with alternative rules.<commit_after>// pest. Smart PEGs in Rust
// Copyright (C) 2016  Dragoș Tiselice
//
// 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/.

/// A `macro` that defines each rule as a method on a `Parser`.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate pest;
/// # use pest::Input;
/// # use pest::StringInput;
/// # use pest::Rdp;
///
/// # fn main() {
/// impl_rdp!(MyRdp);
///
/// impl MyRdp {
///     grammar! {
///         exp = { paren ~ exp | [""] }
///         paren = { ["("] ~ exp ~ [")"] }
///     }
/// }
///
/// let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())()")));
///
/// assert!(parser.exp());
/// assert!(parser.end());
/// # }
/// ```
#[macro_export]
macro_rules! grammar {
    // handle parens
    ( @conv $slf:ident [ ( $( $head:tt )* ) $( $tail:tt )* ] [ $( $optail:tt )* ]
      [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ $( $head )* @rp $( $tail )* ] [ @lp $( $optail )* ]
                 [ $( $output )* ])
    };
    ( @conv $slf:ident [ @rp $( $tail:tt )* ] [ @lp $( $optail:tt )* ] [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ $( $tail )* ] [ $( $optail )* ] [ $( $output )* ])
    };
    ( @conv $slf:ident [ @rp $( $tail:tt )* ] [ $op:tt $( $optail:tt )* ]
      [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ @rp $( $tail )* ] [ $( $optail )* ] [ $( $output )* $op ])
    };

    // handle operands
    ( @conv $slf:ident [ ~ $( $tail:tt )* ] [ ~ $( $optail:tt )* ] [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ ~ $( $tail )* ] [ $( $optail )* ] [ $( $output )* ~ ])
    };
    ( @conv $slf:ident [ ~ $( $tail:tt )* ] [ $( $optail:tt )* ] $output:tt) => {
        grammar!(@conv $slf [ $( $tail )* ] [ ~ $( $optail )* ] $output)
    };
    ( @conv $slf:ident [ | $( $tail:tt )* ] [ ~ $( $optail:tt )* ] [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ | $( $tail )* ] [ $( $optail )* ] [ $( $output )* ~ ])
    };
    ( @conv $slf:ident [ | $( $tail:tt )* ] [ | $( $optail:tt )* ] [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ | $( $tail )* ] [ $( $optail )* ] [ $( $output )* | ])
    };
    ( @conv $slf:ident [ | $( $tail:tt )* ] [ $( $optail:tt )* ] $output:tt) => {
        grammar!(@conv $slf [ $( $tail )* ] [ | $( $optail )* ] $output)
    };

    // handle everything else
    ( @conv $slf:ident [ $head:tt $( $tail:tt )* ] $ops:tt [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [ $( $tail )* ] $ops [ $( $output )* $head ])
    };

    // output remaining operators
    ( @conv $slf:ident [] [] [ $( $output:tt )* ] ) => {
        grammar!(@process $slf [] [ $( $output )* ])
    };
    ( @conv $slf:ident [] [ $op:tt $( $optail:tt )* ] [ $( $output:tt )* ] ) => {
        grammar!(@conv $slf [] [ $( $optail )* ] [ $( $output )* $op ])
    };

    // match
    ( @mtc $slf:ident (( $exp:expr )) ) => (($exp));
    ( @mtc $slf:ident [ $str:expr ]) => ($slf.matches($str));
    ( @mtc $slf:ident $rule:ident) => ($slf.$rule());

    // process postfix
    ( @process $_slf:ident [( $result:expr )] [] ) => ($result);
    ( @process $slf:ident [ $b:tt $a:tt $( $tail:tt )* ] [ ~ $( $optail:tt )* ] ) => {
        {
            let result = $slf.try(Box::new(move |parser| {
                grammar!(@mtc parser $a) && grammar!(@mtc parser $b)
            }));

            grammar!(@process $slf [(( result )) $( $tail )* ] [ $( $optail )* ])
        }
    };
    ( @process $slf:ident [ $b:tt $a:tt $( $tail:tt )* ] [ | $( $optail:tt )* ] ) => {
        {
            let result = grammar!(@mtc $slf $a) || grammar!(@mtc $slf $b);

            grammar!(@process $slf [(( result )) $( $tail )* ] [ $( $optail )* ])
        }
    };
    ( @process $slf:ident [] [ $single:tt ] ) => {
        grammar!(@mtc $slf $single)
    };
    ( @process $slf:ident [ $( $optail:tt )* ] [ $head:tt $( $tail:tt )* ] ) => {
        grammar!(@process $slf [ $head $( $optail )* ] [ $( $tail )* ])
    };

    ( $( $name:ident = { $( $ts:tt )* } )* ) => {
        $(
            #[allow(unused_parens)]
            #[allow(unused_variables)]
            pub fn $name(&mut self) -> bool {
                grammar!(@conv self [ $( $ts )* ] [] [])
            }
        )*
    };
}

#[cfg(test)]
mod tests {
    use super::super::Rdp;
    use super::super::Parser;
    use super::super::Input;
    use super::super::StringInput;

    impl_rdp!(MyRdp);

    impl MyRdp {
        grammar! {
            exp = { paren ~ exp | [""] }
            paren = { ["("] ~ exp ~ [")"] }
        }
    }

    #[test]
    fn basic() {
        let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())()")));

        assert!(parser.exp());
        assert!(parser.end());
    }

    #[test]
    fn fail() {
        let mut parser = MyRdp::new(Box::new(StringInput::new("(())((())())(")));

        assert!(parser.exp());
        assert!(!parser.end());
    }
}
<|endoftext|>


<commit_before>//! Nadezhda's brain control program grammar
//!
//! The brain of our space cockroach is controlled by a program. The allowed
//! programs are described by the following grammar.
//!
//! ```plain
//! S -> forward S
//!    | backward S
//!    | ''
//! ```

/// A `Program` is either
///
/// 1. `Forward` followed by a `Program`
/// 2. `Backward` followed by a `Program`
/// 3. nothing, this is signified by `Stop`
pub enum Program {
    /// forward alternative of the grammar
    Forward(Box<Program>),
    /// backward alternative of the grammar
    Backward(Box<Program>),
    /// empty alternative of the grammar
    Stop,
}
<commit_msg>Provide an example for the grammar<commit_after>//! Nadezhda's brain control program grammar
//!
//! The brain of our space cockroach is controlled by a program. The allowed
//! programs are described by the following grammar.
//!
//! ```plain
//! S -> forward S
//!    | backward S
//!    | ''
//! ```
//!
//! # Examples
//! We  show how to create a `Program` by hand
//!
//! ```rust
//! extern crate nadezhda;
//!
//! use nadezhda::grammar::Program;
//!
//! fn main() {
//!     let program: Program = Program::Forward(
//!       Box::new(Program::Forward(
//!         Box::new(Program::Stop)
//!       ))
//!     );
//!
//!     let message = match program {
//!       Program::Forward(_)  => "right",
//!       Program::Backward(_) => "wrong",
//!       Program::Stop        => "not even close",
//!     };
//!
//!     assert_eq!(message, "right");
//! }
//! ```

/// A `Program` is either
///
/// 1. `Forward` followed by a `Program`
/// 2. `Backward` followed by a `Program`
/// 3. nothing, this is signified by `Stop`
pub enum Program {
    /// forward alternative of the grammar
    Forward(Box<Program>),
    /// backward alternative of the grammar
    Backward(Box<Program>),
    /// empty alternative of the grammar
    Stop,
}
<|endoftext|>