<commit_before>use std::collections::HashMap;

use {Error, Result};
use reader::Reader;

/// A tag.
pub enum Tag {
    Path(Type, Attributes),
    Unknown(String, Type, Attributes),
}

/// The type of a tag.
///
/// http://www.w3.org/TR/REC-xml/#sec-starttags
pub enum Type {
    Start,
    End,
    EmptyElement,
}

/// The attributes of a tag.
pub type Attributes = HashMap<String, String>;

struct Parser<'s> {
    reader: Reader<'s>,
}

impl Tag {
    /// Parse the content between a pair of angle brackets.
    pub fn parse(text: &str) -> Result<Tag> {
        Parser::new(text).process()
    }
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => ({
        let (line, column) = $parser.reader.position();
        return Err(Error {
            line: line,
            column: column,
            message: format!($($arg)*),
        })
    });
);

impl<'s> Parser<'s> {
    #[inline]
    fn new(text: &'s str) -> Parser<'s> {
        Parser {
            reader: Reader::new(text),
        }
    }

    fn process(&mut self) -> Result<Tag> {
        if self.reader.consume_char('/') {
            self.read_end_tag()
        } else {
            self.read_start_or_empty_element_tag()
        }
    }

    fn read_attribute(&mut self) -> Result<Option<(String, String)>> {
        let attribute = self.reader.capture(|reader| {
            reader.consume_attribute();
        }).and_then(|attribute| Some(String::from_str(attribute)));

        match attribute {
            Some(attribute) => {
                let k = (&attribute).find('=').unwrap();
                let name = (&attribute[0..k]).trim_right();
                let value = (&attribute[(k+1)..]).trim_left();
                let value = &value[1..(value.len()-1)];
                Ok(Some((String::from_str(name), String::from_str(value))))
            },
            _ => Ok(None),
        }
    }

    fn read_attributes(&mut self) -> Result<Attributes> {
        let mut attributes = HashMap::new();

        loop {
            self.reader.consume_whitespace();

            match try!(self.read_attribute()) {
                Some((name, value)) => {
                    attributes.insert(name, value);
                },
                _ => break,
            }
        }

        Ok(attributes)
    }

    fn read_end_tag(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        let name = try!(self.read_name());

        self.reader.consume_whitespace();

        if !self.reader.is_done() {
            raise!(self, "found an end tag with excessive data");
        }

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(Type::End, HashMap::new()),
            _ => Tag::Unknown(name, Type::End, HashMap::new()),
        })
    }

    #[inline]
    fn read_name(&mut self) -> Result<String> {
        let name = self.reader.capture(|reader| {
            reader.consume_name();
        }).and_then(|name| Some(String::from_str(name)));

        match name {
            Some(name) => Ok(name),
            None => raise!(self, "expected a name"),
        }
    }

    fn read_start_or_empty_element_tag(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        let name = try!(self.read_name());
        let attributes = try!(self.read_attributes());

        self.reader.consume_whitespace();

        let tail = self.reader.capture(|reader| {
            reader.consume_all();
        }).and_then(|tail| Some(String::from_str(tail)));

        let typo = match tail {
            Some(tail) => match &tail[] {
                "/" => Type::EmptyElement,
                _ => raise!(self, "found an unexpected ending of a tag"),
            },
            _ => Type::Start,
        };

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(typo, attributes),
            _ => Tag::Unknown(name, typo, attributes),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::{Parser, Tag, Type};

    #[test]
    fn parser_process() {
        macro_rules! test(
            ($text:expr, $typo:ident) => ({
                let mut parser = Parser::new($text);
                match parser.process().unwrap() {
                    Tag::Unknown(_, Type::$typo, _) => {},
                    _ => assert!(false),
                }
            });
        );

        test!("foo", Start);
        test!("foo ", Start);
        test!("/foo", End);
        test!("/foo ", End);
        test!("foo/", EmptyElement);
        test!("foo /", EmptyElement);
    }

    #[test]
    fn parser_read_attribute() {
        macro_rules! test(
            ($text:expr, $name:expr, $value:expr) => ({
                let mut parser = Parser::new($text);
                let (name, value) = parser.read_attribute().unwrap().unwrap();
                assert_eq!(&name[], $name);
                assert_eq!(&value[], $value);
            });
        );

        test!("foo='bar'", "foo", "bar");
        test!("foo =\"bar\"", "foo", "bar");
        test!("foo= \"bar\"", "foo", "bar");
        test!("foo\t=\n'bar'  ", "foo", "bar");
    }
}
<commit_msg>Add a bit of documentation<commit_after>//! A tag.

use std::collections::HashMap;

use {Error, Result};
use reader::Reader;

/// A tag.
pub enum Tag {
    Path(Type, Attributes),
    Unknown(String, Type, Attributes),
}

/// The type of a tag.
///
/// http://www.w3.org/TR/REC-xml/#sec-starttags
pub enum Type {
    Start,
    End,
    EmptyElement,
}

/// The attributes of a tag.
pub type Attributes = HashMap<String, String>;

struct Parser<'s> {
    reader: Reader<'s>,
}

impl Tag {
    /// Parse the content between a pair of angle brackets.
    pub fn parse(text: &str) -> Result<Tag> {
        Parser::new(text).process()
    }
}

macro_rules! raise(
    ($parser:expr, $($arg:tt)*) => ({
        let (line, column) = $parser.reader.position();
        return Err(Error {
            line: line,
            column: column,
            message: format!($($arg)*),
        })
    });
);

impl<'s> Parser<'s> {
    #[inline]
    fn new(text: &'s str) -> Parser<'s> {
        Parser {
            reader: Reader::new(text),
        }
    }

    fn process(&mut self) -> Result<Tag> {
        if self.reader.consume_char('/') {
            self.read_end_tag()
        } else {
            self.read_start_or_empty_element_tag()
        }
    }

    fn read_attribute(&mut self) -> Result<Option<(String, String)>> {
        let attribute = self.reader.capture(|reader| {
            reader.consume_attribute();
        }).and_then(|attribute| Some(String::from_str(attribute)));

        match attribute {
            Some(attribute) => {
                let k = (&attribute).find('=').unwrap();
                let name = (&attribute[0..k]).trim_right();
                let value = (&attribute[(k+1)..]).trim_left();
                let value = &value[1..(value.len()-1)];
                Ok(Some((String::from_str(name), String::from_str(value))))
            },
            _ => Ok(None),
        }
    }

    fn read_attributes(&mut self) -> Result<Attributes> {
        let mut attributes = HashMap::new();

        loop {
            self.reader.consume_whitespace();

            match try!(self.read_attribute()) {
                Some((name, value)) => {
                    attributes.insert(name, value);
                },
                _ => break,
            }
        }

        Ok(attributes)
    }

    fn read_end_tag(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        let name = try!(self.read_name());

        self.reader.consume_whitespace();

        if !self.reader.is_done() {
            raise!(self, "found an end tag with excessive data");
        }

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(Type::End, HashMap::new()),
            _ => Tag::Unknown(name, Type::End, HashMap::new()),
        })
    }

    #[inline]
    fn read_name(&mut self) -> Result<String> {
        let name = self.reader.capture(|reader| {
            reader.consume_name();
        }).and_then(|name| Some(String::from_str(name)));

        match name {
            Some(name) => Ok(name),
            None => raise!(self, "expected a name"),
        }
    }

    fn read_start_or_empty_element_tag(&mut self) -> Result<Tag> {
        use std::ascii::OwnedAsciiExt;

        let name = try!(self.read_name());
        let attributes = try!(self.read_attributes());

        self.reader.consume_whitespace();

        let tail = self.reader.capture(|reader| {
            reader.consume_all();
        }).and_then(|tail| Some(String::from_str(tail)));

        let typo = match tail {
            Some(tail) => match &tail[] {
                "/" => Type::EmptyElement,
                _ => raise!(self, "found an unexpected ending of a tag"),
            },
            _ => Type::Start,
        };

        Ok(match &(name.clone().into_ascii_lowercase())[] {
            "path" => Tag::Path(typo, attributes),
            _ => Tag::Unknown(name, typo, attributes),
        })
    }
}

#[cfg(test)]
mod tests {
    use super::{Parser, Tag, Type};

    #[test]
    fn parser_process() {
        macro_rules! test(
            ($text:expr, $typo:ident) => ({
                let mut parser = Parser::new($text);
                match parser.process().unwrap() {
                    Tag::Unknown(_, Type::$typo, _) => {},
                    _ => assert!(false),
                }
            });
        );

        test!("foo", Start);
        test!("foo ", Start);
        test!("/foo", End);
        test!("/foo ", End);
        test!("foo/", EmptyElement);
        test!("foo /", EmptyElement);
    }

    #[test]
    fn parser_read_attribute() {
        macro_rules! test(
            ($text:expr, $name:expr, $value:expr) => ({
                let mut parser = Parser::new($text);
                let (name, value) = parser.read_attribute().unwrap().unwrap();
                assert_eq!(&name[], $name);
                assert_eq!(&value[], $value);
            });
        );

        test!("foo='bar'", "foo", "bar");
        test!("foo =\"bar\"", "foo", "bar");
        test!("foo= \"bar\"", "foo", "bar");
        test!("foo\t=\n'bar'  ", "foo", "bar");
    }
}
<|endoftext|>


<commit_before>#![feature(asm, const_fn, dropck_parametricity)]

#![no_std]

use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};

pub struct Slot {
    next: AtomicPtr<AtomicBool>
}

pub struct Guard<'a, T: ?Sized + 'a> {
    lock: &'a Lock<T>,
    slot: &'a Slot
}

pub struct Lock<T: ?Sized> {
    queue: AtomicPtr<Slot>,
    data: UnsafeCell<T>
}

unsafe impl<T: Send> Sync for Lock<T> { }
unsafe impl<T: Send> Send for Lock<T> { }

/// Do something to wait in spinlocks and use less CPU
#[inline(always)]

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn pause() {
    unsafe { asm!("pause" :::: "volatile"); }
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn pause() { }

impl Slot {
    pub const fn new() -> Slot {
        Slot {
            next: AtomicPtr::new(ptr::null_mut())
        }
    }
}

impl<T> Lock<T> {
    pub const fn new(value: T) -> Lock<T> {
        Lock {
            queue: AtomicPtr::new(ptr::null_mut()),
            data: UnsafeCell::new(value)
        }
    }

    pub fn into_inner(self) -> T {
        unsafe {
            self.data.into_inner()
        }
    }
}

impl<T: ?Sized> Lock<T> {
    pub fn try_lock<'a>(&'a self, slot: &'a mut Slot) -> Option<Guard<'a, T>> {
        slot.next = AtomicPtr::new(ptr::null_mut());

        if self.queue.compare_and_swap(ptr::null_mut(), slot, Ordering::SeqCst).is_null() {
            Some(Guard {
                lock: self,
                slot: slot
            })
        } else {
            None
        }
    }

    pub fn lock<'a>(&'a self, slot: &'a mut Slot) -> Guard<'a, T> {
        slot.next = AtomicPtr::new(ptr::null_mut());
        let pred = self.queue.swap(slot, Ordering::SeqCst);
        if !pred.is_null() {
            let pred = unsafe { &*pred };
            let locked = AtomicBool::new(true);
            pred.next.store(&locked as *const _ as *mut _, Ordering::SeqCst);
            while locked.load(Ordering::SeqCst) {
                pause();
            }
        }

        Guard {
            lock: self,
            slot: slot
        }
    }

    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T: ?Sized> Deref for Guard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> DerefMut for Guard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> Drop for Guard<'a, T> {
    #[unsafe_destructor_blind_to_params]
    fn drop(&mut self) {
        let succ = self.slot.next.load(Ordering::SeqCst);
        if succ.is_null() {
            let slot_ptr = self.slot as *const _ as *mut _;
            if self.lock.queue.compare_and_swap(slot_ptr, ptr::null_mut(), Ordering::SeqCst) != slot_ptr {
                let mut succ;
                loop {
                    succ = self.slot.next.load(Ordering::SeqCst);
                    if !succ.is_null() {
                        break;
                    }
                    pause();
                }
                let succ = unsafe { &*succ };
                succ.store(false, Ordering::SeqCst);
            }
        } else {
            let succ = unsafe { &*succ };
            succ.store(false, Ordering::SeqCst);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate std;

    use super::{Lock, Slot};

    // Mostly stoled from the Rust standard Mutex implementation's tests, so

    // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
    // file 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.

    use self::std::sync::Arc;
    use self::std::sync::mpsc::channel;
    use self::std::sync::atomic::{AtomicUsize, Ordering};
    use self::std::thread;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let mut slot = Slot::new();
        let m = Lock::new(());
        drop(m.lock(&mut slot));
        drop(m.lock(&mut slot));
    }

    #[test]
    fn lots_and_lots() {
        static LOCK: Lock<u32> = Lock::new(0);
        const ITERS: u32 = 1000;
        const CONCURRENCY: u32 = 3;

        fn inc() {
            let mut slot = Slot::new();
            for _ in 0..ITERS {
                let mut g = LOCK.lock(&mut slot);
                *g += 1;
            }
        };

        let (tx, rx) = channel();
        for _ in 0..CONCURRENCY {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * CONCURRENCY {
            rx.recv().unwrap();
        }
        let mut slot = Slot::new();
        assert_eq!(*LOCK.lock(&mut slot), ITERS * CONCURRENCY * 2);
    }

    #[test]
    fn try_lock() {
        let mut slot = Slot::new();
        let m = Lock::new(());
        *m.try_lock(&mut slot).unwrap() = ();
    }

    #[test]
    fn test_into_inner() {
        let m = Lock::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Lock::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_get_mut() {
        let mut m = Lock::new(NonCopy(10));
        *m.get_mut() = NonCopy(20);
        assert_eq!(m.into_inner(), NonCopy(20));
    }

    #[test]
    fn test_lock_arc_nested() {
        // Tests nested locks and access
        // to underlying data.
        let arc = Arc::new(Lock::new(1));
        let arc2 = Arc::new(Lock::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let mut slot1 = Slot::new();
            let mut slot2 = Slot::new();

            let lock = arc2.lock(&mut slot1);
            let lock2 = lock.lock(&mut slot2);
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_lock_arc_access_in_unwind() {
        let arc = Arc::new(Lock::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Lock<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    let mut slot = Slot::new();
                    *self.i.lock(&mut slot) += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let mut slot = Slot::new();
        let lock = arc.lock(&mut slot);
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_lock_unsized() {
        let mut slot = Slot::new();
        let lock: &Lock<[i32]> = &Lock::new([1, 2, 3]);
        {
            let b = &mut *lock.lock(&mut slot);
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*lock.lock(&mut slot), comp);
    }
}
<commit_msg>Rename Lock to Mutex<commit_after>#![feature(asm, const_fn, dropck_parametricity)]

#![no_std]

use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::ptr;
use core::sync::atomic::{AtomicBool, AtomicPtr, Ordering};

pub struct Slot {
    next: AtomicPtr<AtomicBool>
}

pub struct Guard<'a, T: ?Sized + 'a> {
    lock: &'a Mutex<T>,
    slot: &'a Slot
}

pub struct Mutex<T: ?Sized> {
    queue: AtomicPtr<Slot>,
    data: UnsafeCell<T>
}

unsafe impl<T: Send> Sync for Mutex<T> { }
unsafe impl<T: Send> Send for Mutex<T> { }

/// Do something to wait in spinlocks and use less CPU
#[inline(always)]

#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
fn pause() {
    unsafe { asm!("pause" :::: "volatile"); }
}

#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
fn pause() { }

impl Slot {
    pub const fn new() -> Slot {
        Slot {
            next: AtomicPtr::new(ptr::null_mut())
        }
    }
}

impl<T> Mutex<T> {
    pub const fn new(value: T) -> Mutex<T> {
        Mutex {
            queue: AtomicPtr::new(ptr::null_mut()),
            data: UnsafeCell::new(value)
        }
    }

    pub fn into_inner(self) -> T {
        unsafe {
            self.data.into_inner()
        }
    }
}

impl<T: ?Sized> Mutex<T> {
    pub fn try_lock<'a>(&'a self, slot: &'a mut Slot) -> Option<Guard<'a, T>> {
        slot.next = AtomicPtr::new(ptr::null_mut());

        if self.queue.compare_and_swap(ptr::null_mut(), slot, Ordering::SeqCst).is_null() {
            Some(Guard {
                lock: self,
                slot: slot
            })
        } else {
            None
        }
    }

    pub fn lock<'a>(&'a self, slot: &'a mut Slot) -> Guard<'a, T> {
        slot.next = AtomicPtr::new(ptr::null_mut());
        let pred = self.queue.swap(slot, Ordering::SeqCst);
        if !pred.is_null() {
            let pred = unsafe { &*pred };
            let locked = AtomicBool::new(true);
            pred.next.store(&locked as *const _ as *mut _, Ordering::SeqCst);
            while locked.load(Ordering::SeqCst) {
                pause();
            }
        }

        Guard {
            lock: self,
            slot: slot
        }
    }

    pub fn get_mut(&mut self) -> &mut T {
        unsafe { &mut *self.data.get() }
    }
}

impl<'a, T: ?Sized> Deref for Guard<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> DerefMut for Guard<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.lock.data.get() }
    }
}

impl<'a, T: ?Sized> Drop for Guard<'a, T> {
    #[unsafe_destructor_blind_to_params]
    fn drop(&mut self) {
        let succ = self.slot.next.load(Ordering::SeqCst);
        if succ.is_null() {
            let slot_ptr = self.slot as *const _ as *mut _;
            if self.lock.queue.compare_and_swap(slot_ptr, ptr::null_mut(), Ordering::SeqCst) != slot_ptr {
                let mut succ;
                loop {
                    succ = self.slot.next.load(Ordering::SeqCst);
                    if !succ.is_null() {
                        break;
                    }
                    pause();
                }
                let succ = unsafe { &*succ };
                succ.store(false, Ordering::SeqCst);
            }
        } else {
            let succ = unsafe { &*succ };
            succ.store(false, Ordering::SeqCst);
        }
    }
}

#[cfg(test)]
mod test {
    extern crate std;

    use super::{Mutex, Slot};

    // Mostly stoled from the Rust standard Mutex implementation's tests, so

    // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
    // file 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.

    use self::std::sync::Arc;
    use self::std::sync::mpsc::channel;
    use self::std::sync::atomic::{AtomicUsize, Ordering};
    use self::std::thread;

    #[derive(Eq, PartialEq, Debug)]
    struct NonCopy(i32);

    #[test]
    fn smoke() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        drop(m.lock(&mut slot));
        drop(m.lock(&mut slot));
    }

    #[test]
    fn lots_and_lots() {
        static LOCK: Mutex<u32> = Mutex::new(0);
        const ITERS: u32 = 1000;
        const CONCURRENCY: u32 = 3;

        fn inc() {
            let mut slot = Slot::new();
            for _ in 0..ITERS {
                let mut g = LOCK.lock(&mut slot);
                *g += 1;
            }
        };

        let (tx, rx) = channel();
        for _ in 0..CONCURRENCY {
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
            let tx2 = tx.clone();
            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
        }

        drop(tx);
        for _ in 0..2 * CONCURRENCY {
            rx.recv().unwrap();
        }
        let mut slot = Slot::new();
        assert_eq!(*LOCK.lock(&mut slot), ITERS * CONCURRENCY * 2);
    }

    #[test]
    fn try_lock() {
        let mut slot = Slot::new();
        let m = Mutex::new(());
        *m.try_lock(&mut slot).unwrap() = ();
    }

    #[test]
    fn test_into_inner() {
        let m = Mutex::new(NonCopy(10));
        assert_eq!(m.into_inner(), NonCopy(10));
    }

    #[test]
    fn test_into_inner_drop() {
        struct Foo(Arc<AtomicUsize>);
        impl Drop for Foo {
            fn drop(&mut self) {
                self.0.fetch_add(1, Ordering::SeqCst);
            }
        }
        let num_drops = Arc::new(AtomicUsize::new(0));
        let m = Mutex::new(Foo(num_drops.clone()));
        assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        {
            let _inner = m.into_inner();
            assert_eq!(num_drops.load(Ordering::SeqCst), 0);
        }
        assert_eq!(num_drops.load(Ordering::SeqCst), 1);
    }

    #[test]
    fn test_get_mut() {
        let mut m = Mutex::new(NonCopy(10));
        *m.get_mut() = NonCopy(20);
        assert_eq!(m.into_inner(), NonCopy(20));
    }

    #[test]
    fn test_lock_arc_nested() {
        // Tests nested locks and access
        // to underlying data.
        let arc = Arc::new(Mutex::new(1));
        let arc2 = Arc::new(Mutex::new(arc));
        let (tx, rx) = channel();
        let _t = thread::spawn(move|| {
            let mut slot1 = Slot::new();
            let mut slot2 = Slot::new();

            let lock = arc2.lock(&mut slot1);
            let lock2 = lock.lock(&mut slot2);
            assert_eq!(*lock2, 1);
            tx.send(()).unwrap();
        });
        rx.recv().unwrap();
    }

    #[test]
    fn test_lock_arc_access_in_unwind() {
        let arc = Arc::new(Mutex::new(1));
        let arc2 = arc.clone();
        let _ = thread::spawn(move|| -> () {
            struct Unwinder {
                i: Arc<Mutex<i32>>,
            }
            impl Drop for Unwinder {
                fn drop(&mut self) {
                    let mut slot = Slot::new();
                    *self.i.lock(&mut slot) += 1;
                }
            }
            let _u = Unwinder { i: arc2 };
            panic!();
        }).join();
        let mut slot = Slot::new();
        let lock = arc.lock(&mut slot);
        assert_eq!(*lock, 2);
    }

    #[test]
    fn test_lock_unsized() {
        let mut slot = Slot::new();
        let lock: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
        {
            let b = &mut *lock.lock(&mut slot);
            b[0] = 4;
            b[2] = 5;
        }
        let comp: &[i32] = &[4, 2, 5];
        assert_eq!(&*lock.lock(&mut slot), comp);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//!
//! A library for interning things that are `AsRef<str>`.
//!
//! Some strings may be interned at compile time using the `string-cache-codegen` crate, or the
//! `EmptyStaticAtomSet` may be used that has no compile-time interned strings. An `Atom` is an
//! interned string for a given set (either `EmptyStaticAtomSet` or a generated `StaticAtomSet`).
//!
//! Generated `Atom`s will have assocated macros to intern static strings at compile-time.
//!
//! # Examples
//!
//! Here are two examples, one with compile-time `Atom`s, and one without.
//!
//! ## With compile-time atoms
//!
//! In `Cargo.toml`:
//! ```toml
//! [dependencies]
//! string_cache = "0.8"
//!
//! [dev-dependencies]
//! string_cache_codegen = "0.5"
//! ```
//!
//! In `build.rs`:
//!
//! ```ignore
//! extern crate string_cache_codegen;
//!
//! use std::env;
//! use std::path::Path;
//!
//! fn main() {
//!     string_cache_codegen::AtomType::new("foo::FooAtom", "foo_atom!")
//!         .atoms(&["foo", "bar"])
//!         .write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("foo_atom.rs"))
//!         .unwrap()
//! }
//! ```
//!
//! In `lib.rs`:
//!
//! ```ignore
//! extern crate string_cache;
//!
//! mod foo {
//!     include!(concat!(env!("OUT_DIR"), "/foo_atom.rs"));
//! }
//!
//! fn use_the_atom(t: &str) {
//!     match *t {
//!         foo_atom!("foo") => println!("Found foo!"),
//!         foo_atom!("bar") => println!("Found bar!"),
//!         // foo_atom!("baz") => println!("Found baz!"), - would be a compile time error
//!         _ => {
//!             println!("String not interned");
//!             // We can intern strings at runtime as well
//!             foo::FooAtom::from(t)
//!         }
//!     }
//! }
//! ```
//!
//! ## No compile-time atoms
//!
//! ```
//! # extern crate string_cache;
//! use string_cache::DefaultAtom;
//!
//! # fn main() {
//! let mut interned_stuff = Vec::new();
//! let text = "here is a sentence of text that will be tokenised and
//!             interned and some repeated tokens is of text and";
//! for word in text.split_whitespace() {
//!     let seen_before = interned_stuff.iter()
//!         // We can use impl PartialEq<T> where T is anything string-like
//!         // to compare to interned strings to either other interned strings,
//!         // or actual strings  Comparing two interned strings is very fast
//!         // (normally a single cpu operation).
//!         .filter(|interned_word| interned_word == &word)
//!         .count();
//!     if seen_before > 0 {
//!         println!(r#"Seen the word "{}" {} times"#, word, seen_before);
//!     } else {
//!         println!(r#"Not seen the word "{}" before"#, word);
//!     }
//!     // We use the impl From<(Cow<'a, str>, or &'a str, or String)> for
//!     // Atom<Static> to intern a new string.
//!     interned_stuff.push(DefaultAtom::from(word));
//! }
//! # }
//! ```
//!

#![crate_name = "string_cache"]
#![crate_type = "rlib"]
#![cfg_attr(test, deny(warnings))]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate debug_unreachable;
extern crate phf_shared;
extern crate precomputed_hash;
extern crate serde;

pub use atom::{Atom, DefaultAtom, EmptyStaticAtomSet, PhfStrSet, StaticAtomSet};

pub mod atom;

// Make test_atom! macro work in this crate.
// `$crate` would not be appropriate for other crates creating such macros
mod string_cache {
    pub use {Atom, PhfStrSet, StaticAtomSet};
}
<commit_msg>test_atom! is in another crate now<commit_after>// Copyright 2014 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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.

//!
//! A library for interning things that are `AsRef<str>`.
//!
//! Some strings may be interned at compile time using the `string-cache-codegen` crate, or the
//! `EmptyStaticAtomSet` may be used that has no compile-time interned strings. An `Atom` is an
//! interned string for a given set (either `EmptyStaticAtomSet` or a generated `StaticAtomSet`).
//!
//! Generated `Atom`s will have assocated macros to intern static strings at compile-time.
//!
//! # Examples
//!
//! Here are two examples, one with compile-time `Atom`s, and one without.
//!
//! ## With compile-time atoms
//!
//! In `Cargo.toml`:
//! ```toml
//! [dependencies]
//! string_cache = "0.8"
//!
//! [dev-dependencies]
//! string_cache_codegen = "0.5"
//! ```
//!
//! In `build.rs`:
//!
//! ```ignore
//! extern crate string_cache_codegen;
//!
//! use std::env;
//! use std::path::Path;
//!
//! fn main() {
//!     string_cache_codegen::AtomType::new("foo::FooAtom", "foo_atom!")
//!         .atoms(&["foo", "bar"])
//!         .write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("foo_atom.rs"))
//!         .unwrap()
//! }
//! ```
//!
//! In `lib.rs`:
//!
//! ```ignore
//! extern crate string_cache;
//!
//! mod foo {
//!     include!(concat!(env!("OUT_DIR"), "/foo_atom.rs"));
//! }
//!
//! fn use_the_atom(t: &str) {
//!     match *t {
//!         foo_atom!("foo") => println!("Found foo!"),
//!         foo_atom!("bar") => println!("Found bar!"),
//!         // foo_atom!("baz") => println!("Found baz!"), - would be a compile time error
//!         _ => {
//!             println!("String not interned");
//!             // We can intern strings at runtime as well
//!             foo::FooAtom::from(t)
//!         }
//!     }
//! }
//! ```
//!
//! ## No compile-time atoms
//!
//! ```
//! # extern crate string_cache;
//! use string_cache::DefaultAtom;
//!
//! # fn main() {
//! let mut interned_stuff = Vec::new();
//! let text = "here is a sentence of text that will be tokenised and
//!             interned and some repeated tokens is of text and";
//! for word in text.split_whitespace() {
//!     let seen_before = interned_stuff.iter()
//!         // We can use impl PartialEq<T> where T is anything string-like
//!         // to compare to interned strings to either other interned strings,
//!         // or actual strings  Comparing two interned strings is very fast
//!         // (normally a single cpu operation).
//!         .filter(|interned_word| interned_word == &word)
//!         .count();
//!     if seen_before > 0 {
//!         println!(r#"Seen the word "{}" {} times"#, word, seen_before);
//!     } else {
//!         println!(r#"Not seen the word "{}" before"#, word);
//!     }
//!     // We use the impl From<(Cow<'a, str>, or &'a str, or String)> for
//!     // Atom<Static> to intern a new string.
//!     interned_stuff.push(DefaultAtom::from(word));
//! }
//! # }
//! ```
//!

#![crate_name = "string_cache"]
#![crate_type = "rlib"]
#![cfg_attr(test, deny(warnings))]

#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate debug_unreachable;
extern crate phf_shared;
extern crate precomputed_hash;
extern crate serde;

pub use atom::{Atom, DefaultAtom, EmptyStaticAtomSet, PhfStrSet, StaticAtomSet};

pub mod atom;
<|endoftext|>


<commit_before>//! # Salted Challenge Response Authentication Mechanism (SCRAM)
//!
//! This implementation currently provides a client and a server for the SCRAM-SHA-256 mechanism
//! according to RFC5802 and RFC7677. It doesn't support channel-binding.
//!
//! # Usage
//!
//! ## Client
//! A typical usage scenario is shown below. For a detailed explanation of the methods please
//! consider their documentation. In productive code you should replace the unwrapping by proper
//! error handling.
//!
//! At first the user and the password must be supplied using either of the methods
//! [`ClientFirst::new`](client/struct.ClientFirst.html#method.new) or
//! [`ClientFirst::with_rng`](client/struct.ClientFirst.html#method.with_rng). These methods return
//! a SCRAM state you can use to compute the first client message.
//!
//! The server and the client exchange four messages using the SCRAM mechanism. There is a rust type
//! for each one of them. Calling the methods
//! [`client_first`](client/struct.ClientFirst.html#method.client_first),
//! [`handle_server_first`](client/struct.ServerFirst.html#method.handle_server_first),
//! [`client_final`](client/struct.ClientFinal.html#method.client_final) and
//! [`handle_server_final`](client/struct.ServerFinal.html#method.handle_server_final) on the
//! different types advances the SCRAM handshake step by step. Computing client messages never fails
//! but processing server messages can result in failure.
//!
//! ``` rust,no_run
//! use scram::ScramClient;
//!
//! // This function represents your I/O implementation.
//! # #[allow(unused_variables)]
//! fn send_and_receive(message: &str) -> String {
//!     unimplemented!()
//! }
//!
//! // Create a SCRAM state from the credentials.
//! let scram = ScramClient::new("user", "password", None).unwrap();
//!
//! // Get the client message and reassign the SCRAM state.
//! let (scram, client_first) = scram.client_first();
//!
//! // Send the client first message and receive the servers reply.
//! let server_first = send_and_receive(&client_first);
//!
//! // Process the reply and again reassign the SCRAM state. You can add error handling to
//! // abort the authentication attempt.
//! let scram = scram.handle_server_first(&server_first).unwrap();
//!
//! // Get the client final message and reassign the SCRAM state.
//! let (scram, client_final) = scram.client_final();
//!
//! // Send the client final message and receive the servers reply.
//! let server_final = send_and_receive(&client_final);
//!
//! // Process the last message. Any error returned means that the authentication attempt
//! // wasn't successful.
//! let () = scram.handle_server_final(&server_final).unwrap();
//! ```
//!
//! ## Server
//!
//! The server is created to respond to incoming challenges from a client. A typical usage pattern,
//! with a default provider is shown below. In production, you would implement an
//! `AuthenticationProvider` that could look up user credentials based on a username
//!
//! The server and the client exchange four messages using the SCRAM mechanism. There is a rust type
//! for each one of them. Calling the methods
//! [`handle_client_first`](server/struct.ScramServer.html#method.handle_client_first),
//! [`server_first`](server/struct.ServerFirst.html#method.server_first),
//! [`handle_client_final`](server/struct.ClientFinal.html#method.handle_client_final) and
//! [`server_final`](server/struct.ServerFinal.html#method.server_final) on the different
//! types advances the SCRAM handshake step by step. Computing server messages never fails (unless
//! the source of randomness for the nonce fails), but processing client messages can result in
//! failure.
//!
//! The final step will not return an error if authentication failed, but will return an
//! [`AuthenticationStatus`](server/enum.AuthenticationStatus/html) which you can use to determine
//! if authentication was successful or not.
//!
//! ```rust,no_run
//! use scram::{ScramServer, AuthenticationStatus, AuthenticationProvider, PasswordInfo};
//!
//! // Create a dummy authentication provider
//! struct ExampleProvider;
//! impl AuthenticationProvider for ExampleProvider {
//!     // Here you would look up password information for the the given username
//!     fn get_password_for(&self, username: &str) -> Option<PasswordInfo> {
//!        unimplemented!()
//!     }
//!
//! }
//! // These functions represent your I/O implementation.
//! # #[allow(unused_variables)]
//! fn receive() -> String {
//!     unimplemented!()
//! }
//! # #[allow(unused_variables)]
//! fn send(message: &str) {
//!     unimplemented!()
//! }
//!
//! // Create a new ScramServer using the example authenication provider
//! let scram_server = ScramServer::new(ExampleProvider{});
//!
//! // Receive a message from the client
//! let client_first = receive();
//!
//! // Create a SCRAM state from the client's first message
//! let scram_server = scram_server.handle_client_first(&client_first).unwrap();
//! // Craft a response to the client's message and advance the SCRAM state
//! // We could use our own source of randomness here, with `server_first_with_rng()`
//! let (scram_server, server_first) = scram_server.server_first().unwrap();
//! // Send our message to the client and read the response
//! send(&server_first);
//! let client_final = receive();
//!
//! // Process the client's challenge and re-assign the SCRAM state.  This could fail if the
//! // message was poorly formatted
//! let scram_server = scram_server.handle_client_final(&client_final).unwrap();
//!
//! // Prepare the final message and get the authentication status
//! let(status, server_final) = scram_server.server_final();
//! // Send our final message to the client
//! send(&server_final);
//!
//! // Check if the client successfully authenticated
//! assert_eq!(status, AuthenticationStatus::Authenticated);
//! ```
extern crate base64;
extern crate rand;
extern crate ring;

/// The length of the client nonce in characters/bytes.
const NONCE_LENGTH: usize = 24;

#[macro_use]
mod utils;
mod error;
pub mod client;
pub mod server;

pub use client::ScramClient;
pub use error::{Error, Kind, Field};
pub use server::{ScramServer, AuthenticationProvider, PasswordInfo, AuthenticationStatus};
pub use utils::hash_password;
<commit_msg>Add hyperlinks for RFC5802 and RFC7677<commit_after>//! # Salted Challenge Response Authentication Mechanism (SCRAM)
//!
//! This implementation currently provides a client and a server for the SCRAM-SHA-256 mechanism
//! according to [RFC5802](https://tools.ietf.org/html/rfc5802) and
//! [RFC7677](https://tools.ietf.org/html/rfc7677). It doesn't support channel-binding.
//!
//! # Usage
//!
//! ## Client
//! A typical usage scenario is shown below. For a detailed explanation of the methods please
//! consider their documentation. In productive code you should replace the unwrapping by proper
//! error handling.
//!
//! At first the user and the password must be supplied using either of the methods
//! [`ClientFirst::new`](client/struct.ClientFirst.html#method.new) or
//! [`ClientFirst::with_rng`](client/struct.ClientFirst.html#method.with_rng). These methods return
//! a SCRAM state you can use to compute the first client message.
//!
//! The server and the client exchange four messages using the SCRAM mechanism. There is a rust type
//! for each one of them. Calling the methods
//! [`client_first`](client/struct.ClientFirst.html#method.client_first),
//! [`handle_server_first`](client/struct.ServerFirst.html#method.handle_server_first),
//! [`client_final`](client/struct.ClientFinal.html#method.client_final) and
//! [`handle_server_final`](client/struct.ServerFinal.html#method.handle_server_final) on the
//! different types advances the SCRAM handshake step by step. Computing client messages never fails
//! but processing server messages can result in failure.
//!
//! ``` rust,no_run
//! use scram::ScramClient;
//!
//! // This function represents your I/O implementation.
//! # #[allow(unused_variables)]
//! fn send_and_receive(message: &str) -> String {
//!     unimplemented!()
//! }
//!
//! // Create a SCRAM state from the credentials.
//! let scram = ScramClient::new("user", "password", None).unwrap();
//!
//! // Get the client message and reassign the SCRAM state.
//! let (scram, client_first) = scram.client_first();
//!
//! // Send the client first message and receive the servers reply.
//! let server_first = send_and_receive(&client_first);
//!
//! // Process the reply and again reassign the SCRAM state. You can add error handling to
//! // abort the authentication attempt.
//! let scram = scram.handle_server_first(&server_first).unwrap();
//!
//! // Get the client final message and reassign the SCRAM state.
//! let (scram, client_final) = scram.client_final();
//!
//! // Send the client final message and receive the servers reply.
//! let server_final = send_and_receive(&client_final);
//!
//! // Process the last message. Any error returned means that the authentication attempt
//! // wasn't successful.
//! let () = scram.handle_server_final(&server_final).unwrap();
//! ```
//!
//! ## Server
//!
//! The server is created to respond to incoming challenges from a client. A typical usage pattern,
//! with a default provider is shown below. In production, you would implement an
//! `AuthenticationProvider` that could look up user credentials based on a username
//!
//! The server and the client exchange four messages using the SCRAM mechanism. There is a rust type
//! for each one of them. Calling the methods
//! [`handle_client_first`](server/struct.ScramServer.html#method.handle_client_first),
//! [`server_first`](server/struct.ServerFirst.html#method.server_first),
//! [`handle_client_final`](server/struct.ClientFinal.html#method.handle_client_final) and
//! [`server_final`](server/struct.ServerFinal.html#method.server_final) on the different
//! types advances the SCRAM handshake step by step. Computing server messages never fails (unless
//! the source of randomness for the nonce fails), but processing client messages can result in
//! failure.
//!
//! The final step will not return an error if authentication failed, but will return an
//! [`AuthenticationStatus`](server/enum.AuthenticationStatus/html) which you can use to determine
//! if authentication was successful or not.
//!
//! ```rust,no_run
//! use scram::{ScramServer, AuthenticationStatus, AuthenticationProvider, PasswordInfo};
//!
//! // Create a dummy authentication provider
//! struct ExampleProvider;
//! impl AuthenticationProvider for ExampleProvider {
//!     // Here you would look up password information for the the given username
//!     fn get_password_for(&self, username: &str) -> Option<PasswordInfo> {
//!        unimplemented!()
//!     }
//!
//! }
//! // These functions represent your I/O implementation.
//! # #[allow(unused_variables)]
//! fn receive() -> String {
//!     unimplemented!()
//! }
//! # #[allow(unused_variables)]
//! fn send(message: &str) {
//!     unimplemented!()
//! }
//!
//! // Create a new ScramServer using the example authenication provider
//! let scram_server = ScramServer::new(ExampleProvider{});
//!
//! // Receive a message from the client
//! let client_first = receive();
//!
//! // Create a SCRAM state from the client's first message
//! let scram_server = scram_server.handle_client_first(&client_first).unwrap();
//! // Craft a response to the client's message and advance the SCRAM state
//! // We could use our own source of randomness here, with `server_first_with_rng()`
//! let (scram_server, server_first) = scram_server.server_first().unwrap();
//! // Send our message to the client and read the response
//! send(&server_first);
//! let client_final = receive();
//!
//! // Process the client's challenge and re-assign the SCRAM state.  This could fail if the
//! // message was poorly formatted
//! let scram_server = scram_server.handle_client_final(&client_final).unwrap();
//!
//! // Prepare the final message and get the authentication status
//! let(status, server_final) = scram_server.server_final();
//! // Send our final message to the client
//! send(&server_final);
//!
//! // Check if the client successfully authenticated
//! assert_eq!(status, AuthenticationStatus::Authenticated);
//! ```
extern crate base64;
extern crate rand;
extern crate ring;

/// The length of the client nonce in characters/bytes.
const NONCE_LENGTH: usize = 24;

#[macro_use]
mod utils;
mod error;
pub mod client;
pub mod server;

pub use client::ScramClient;
pub use error::{Error, Kind, Field};
pub use server::{ScramServer, AuthenticationProvider, PasswordInfo, AuthenticationStatus};
pub use utils::hash_password;
<|endoftext|>


<commit_before>#![crate_name = "ui"]
#![deny(missing_doc)]

//! A flexible standard for user interactions
//! to be used in window frameworks and widgets libraries.

/// Time difference in seconds.
pub struct DeltaTime(pub f64);

/// Describes a device.
///
/// To create a custom device, use `Device::new`.
pub struct Device(&'static str);

pub static MOUSE: Device = Device("_mouse");
pub static KEYBOARD: Device = Device("_keyboard");

impl Device {
    /// Creates a new custom device.
    ///
    /// Returns `Err(String)` if the id is reserved.
    pub fn new(id: &'static str) -> Result<Device, String> {
        let device = Device(id);
        match device {
              MOUSE
            | KEYBOARD
            => Err(format!("The device id '{}' is reserved", id)),
            _ => Ok(device)
        }
    }
}

/// Describes a button on a device.
pub struct Button {
    /// The device that contains the button.
    pub device: Device,
    /// The key that identifies the button.
    pub key: &'static str,
    /// A non-zero id if device contains more than one.
    pub axis_id: uint,
    /// The user id.
    pub user_id: uint,
}

/// A user input signal is a 3D data of some sort.
///
/// This can be absolute or relative depending on the usage.
pub struct Signal {
    /// The device where the signal came from.
    pub device: Device,
    /// The coordinates received from signal.
    pub xyz: [f64, ..3],
    /// A non-zero id if device contains more than one.
    pub id: uint,
}

impl Signal {
    /// Gets the `x` and `y` component.
    pub fn xy(&self) -> (f64, f64) {
        (self.xyz[0], self.xyz[1])
    }
}

/// Can be sent to a widget from window or parent widget.
pub enum Input {
    /// Press button or key.
    Press(Button),
    /// Release button or key.
    Release(Button),
    /// Repeat button or key.
    ///
    /// The frequency of repeating is implementation dependent.
    Repeat(Button),
    /// Position input event from device.
    Position(Device, [f64, ..3]),
    /// Move input event from device.
    Move(Device, [f64, ..3]),
    /// Scroll input event from device.
    Scroll(Device, [f64, ..3]),
    /// Resize input event from device.
    Resize(Device, [f64, ..3]),
    /// Orient input event from device.
    Orient(Device, [f64, ..3]),
    /// Rotate input event from device.
    Rotate(Device, [f64, ..3]),
    /// Scale input event from device.
    Scale(Device, [f64, ..3]),
    /// Select all items.
    SelectAll,
    /// Deselect all items.
    SelectNone,
    /// Select an item.
    Select(uint),
    /// Deselect an item.
    Deselect(uint),
    /// Select range of items.
    SelectRange(uint, uint),
    /// Navigate to item.
    NavigateTo(uint),
    /// Focus attention on widget.
    Focus,
    /// Shift focus away from widget.
    Defocus,
    /// Enable the widget for handling user input.
    Enable,
    /// Disable the widget from handling user input.
    Disable,
    /// Shw the child widgets.
    Expand,
    /// Hide the child widgets.
    Collapse,
    /// Play video/audio content.
    Play,
    /// Pause video/audio content.
    Pause,
    /// Skip seconds of video/audio content.
    ///
    /// This can be negative.
    Skip(DeltaTime),
    /// Set the current time of video/audio content.
    SetTime(DeltaTime),
    /// Update widget with delta time in seconds.
    Update(DeltaTime),
    /// Render the widget with computed extrapolated time for smoothness.
    Render(DeltaTime),
    /// Pastes a string in widget.
    PasteString(String),
    /// Pastes a blob of data in widget.
    PasteBlob(Vec<u8>),
    /// A unicode character, usually handled by text widgets.
    UnicodeChar(char),
}

/// Can be sent to parent of a widget.
pub enum Output {
    /// Capture a device.
    ///
    /// This is used by games to hide mouse cursor.
    Capture(Device),
    /// Free the captured device.
    Free(Device),
    /// Put a string on the clipboard.
    CopyString(String),
    /// Put a blob of data on the clipboard.
    CopyBlob(Vec<u8>),
    /// Request a size for the widget content to fit on screen.
    RequestSize([f64, ..3]),
    /// Ask to go to full screen mode.
    RequestFullscreen,
    /// Ask to go to window mode.
    RequestWindow,
    /// The number of items in widget has changed.
    ///
    /// This is used by widgets that streams data.
    Count(uint),
    /// The length of video/audio content in seconds.
    Length(DeltaTime),
    /// A warning message.
    Warning(String),
    /// A critical message.
    Alert(String),
    /// A message to notify the user.
    Notify(String),
    /// An error occured.
    Error(String),
    /// Invalid input, used by widgets that require specific format.
    Invalid(String),
}

pub mod mouse;
pub mod keyboard;
<commit_msg>Changed from "standard" to "structure"<commit_after>#![crate_name = "ui"]
#![deny(missing_doc)]

//! A flexible structure for user interactions
//! to be used in window frameworks and widgets libraries.

/// Time difference in seconds.
pub struct DeltaTime(pub f64);

/// Describes a device.
///
/// To create a custom device, use `Device::new`.
pub struct Device(&'static str);

pub static MOUSE: Device = Device("_mouse");
pub static KEYBOARD: Device = Device("_keyboard");

impl Device {
    /// Creates a new custom device.
    ///
    /// Returns `Err(String)` if the id is reserved.
    pub fn new(id: &'static str) -> Result<Device, String> {
        let device = Device(id);
        match device {
              MOUSE
            | KEYBOARD
            => Err(format!("The device id '{}' is reserved", id)),
            _ => Ok(device)
        }
    }
}

/// Describes a button on a device.
pub struct Button {
    /// The device that contains the button.
    pub device: Device,
    /// The key that identifies the button.
    pub key: &'static str,
    /// A non-zero id if device contains more than one.
    pub axis_id: uint,
    /// The user id.
    pub user_id: uint,
}

/// A user input signal is a 3D data of some sort.
///
/// This can be absolute or relative depending on the usage.
pub struct Signal {
    /// The device where the signal came from.
    pub device: Device,
    /// The coordinates received from signal.
    pub xyz: [f64, ..3],
    /// A non-zero id if device contains more than one.
    pub id: uint,
}

impl Signal {
    /// Gets the `x` and `y` component.
    pub fn xy(&self) -> (f64, f64) {
        (self.xyz[0], self.xyz[1])
    }
}

/// Can be sent to a widget from window or parent widget.
pub enum Input {
    /// Press button or key.
    Press(Button),
    /// Release button or key.
    Release(Button),
    /// Repeat button or key.
    ///
    /// The frequency of repeating is implementation dependent.
    Repeat(Button),
    /// Position input event from device.
    Position(Device, [f64, ..3]),
    /// Move input event from device.
    Move(Device, [f64, ..3]),
    /// Scroll input event from device.
    Scroll(Device, [f64, ..3]),
    /// Resize input event from device.
    Resize(Device, [f64, ..3]),
    /// Orient input event from device.
    Orient(Device, [f64, ..3]),
    /// Rotate input event from device.
    Rotate(Device, [f64, ..3]),
    /// Scale input event from device.
    Scale(Device, [f64, ..3]),
    /// Select all items.
    SelectAll,
    /// Deselect all items.
    SelectNone,
    /// Select an item.
    Select(uint),
    /// Deselect an item.
    Deselect(uint),
    /// Select range of items.
    SelectRange(uint, uint),
    /// Navigate to item.
    NavigateTo(uint),
    /// Focus attention on widget.
    Focus,
    /// Shift focus away from widget.
    Defocus,
    /// Enable the widget for handling user input.
    Enable,
    /// Disable the widget from handling user input.
    Disable,
    /// Shw the child widgets.
    Expand,
    /// Hide the child widgets.
    Collapse,
    /// Play video/audio content.
    Play,
    /// Pause video/audio content.
    Pause,
    /// Skip seconds of video/audio content.
    ///
    /// This can be negative.
    Skip(DeltaTime),
    /// Set the current time of video/audio content.
    SetTime(DeltaTime),
    /// Update widget with delta time in seconds.
    Update(DeltaTime),
    /// Render the widget with computed extrapolated time for smoothness.
    Render(DeltaTime),
    /// Pastes a string in widget.
    PasteString(String),
    /// Pastes a blob of data in widget.
    PasteBlob(Vec<u8>),
    /// A unicode character, usually handled by text widgets.
    UnicodeChar(char),
}

/// Can be sent to parent of a widget.
pub enum Output {
    /// Capture a device.
    ///
    /// This is used by games to hide mouse cursor.
    Capture(Device),
    /// Free the captured device.
    Free(Device),
    /// Put a string on the clipboard.
    CopyString(String),
    /// Put a blob of data on the clipboard.
    CopyBlob(Vec<u8>),
    /// Request a size for the widget content to fit on screen.
    RequestSize([f64, ..3]),
    /// Ask to go to full screen mode.
    RequestFullscreen,
    /// Ask to go to window mode.
    RequestWindow,
    /// The number of items in widget has changed.
    ///
    /// This is used by widgets that streams data.
    Count(uint),
    /// The length of video/audio content in seconds.
    Length(DeltaTime),
    /// A warning message.
    Warning(String),
    /// A critical message.
    Alert(String),
    /// A message to notify the user.
    Notify(String),
    /// An error occured.
    Error(String),
    /// Invalid input, used by widgets that require specific format.
    Invalid(String),
}

pub mod mouse;
pub mod keyboard;
<|endoftext|>


<commit_before>//! A database access library for leveldb
//!
//! Usage:
//!
//! ```rust,ignore
//! extern crate tempdir;
//! extern crate leveldb;
//!
//! use tempdir::TempDir;
//! use leveldb::database::Database;
//! use leveldb::kv::KV;
//! use leveldb::options::{Options,WriteOptions,ReadOptions};
//!
//! let tempdir = TempDir::new("demo").unwrap();
//! let path = tempdir.path();
//!
//! let mut options = Options::new();
//! options.create_if_missing = true;
//! let mut database = match Database::open(path, options) {
//!     Ok(db) => { db },
//!     Err(e) => { panic!("failed to open database: {:?}", e) }
//! };
//!
//! let write_opts = WriteOptions::new();
//! match database.put(write_opts, 1, &[1]) {
//!     Ok(_) => { () },
//!     Err(e) => { panic!("failed to write to database: {:?}", e) }
//! };
//!
//! let read_opts = ReadOptions::new();
//! let res = database.get(read_opts,
//!                        1);
//! match res {
//!   Ok(data) => {
//!     assert!(data.is_some());
//!     assert_eq!(data, Some(vec![1]));
//!   }
//!   Err(e) => { panic!("failed reading data: {:?}", e) }
//! }
//! ```

#![crate_type = "lib"]
#![crate_name = "leveldb"]
#![deny(missing_docs)]

extern crate libc;

use cbits::leveldb::{leveldb_major_version,leveldb_minor_version};
pub use database::options as options;
pub use database::error as error;
pub use database::iterator as iterator;
pub use database::snapshots as snapshots;
pub use database::comparator as comparator;
pub use database::kv as kv;
pub use database::batch as batch;
pub use database::management as management;

use std::marker::PhantomFn;

#[allow(missing_docs)]
pub mod cbits;
pub mod database;

/// Library version information
///
/// Need a recent version of leveldb to be used.

pub trait Version : PhantomFn<Self, ()> {
    /// The major version.
    fn major() -> isize {
        unsafe { leveldb_major_version() as isize }
    }

    /// The minor version
    fn minor() -> isize {
        unsafe { leveldb_minor_version() as isize }
    }
}
<commit_msg>Stop using PhantomFn<commit_after>//! A database access library for leveldb
//!
//! Usage:
//!
//! ```rust,ignore
//! extern crate tempdir;
//! extern crate leveldb;
//!
//! use tempdir::TempDir;
//! use leveldb::database::Database;
//! use leveldb::kv::KV;
//! use leveldb::options::{Options,WriteOptions,ReadOptions};
//!
//! let tempdir = TempDir::new("demo").unwrap();
//! let path = tempdir.path();
//!
//! let mut options = Options::new();
//! options.create_if_missing = true;
//! let mut database = match Database::open(path, options) {
//!     Ok(db) => { db },
//!     Err(e) => { panic!("failed to open database: {:?}", e) }
//! };
//!
//! let write_opts = WriteOptions::new();
//! match database.put(write_opts, 1, &[1]) {
//!     Ok(_) => { () },
//!     Err(e) => { panic!("failed to write to database: {:?}", e) }
//! };
//!
//! let read_opts = ReadOptions::new();
//! let res = database.get(read_opts,
//!                        1);
//! match res {
//!   Ok(data) => {
//!     assert!(data.is_some());
//!     assert_eq!(data, Some(vec![1]));
//!   }
//!   Err(e) => { panic!("failed reading data: {:?}", e) }
//! }
//! ```

#![crate_type = "lib"]
#![crate_name = "leveldb"]
#![deny(missing_docs)]

extern crate libc;

use cbits::leveldb::{leveldb_major_version,leveldb_minor_version};
pub use database::options as options;
pub use database::error as error;
pub use database::iterator as iterator;
pub use database::snapshots as snapshots;
pub use database::comparator as comparator;
pub use database::kv as kv;
pub use database::batch as batch;
pub use database::management as management;

#[allow(missing_docs)]
pub mod cbits;
pub mod database;

/// Library version information
///
/// Need a recent version of leveldb to be used.

pub trait Version {
    /// The major version.
    fn major() -> isize {
        unsafe { leveldb_major_version() as isize }
    }

    /// The minor version
    fn minor() -> isize {
        unsafe { leveldb_minor_version() as isize }
    }
}
<|endoftext|>


<commit_before>//! A toolkit for building command-line programs in Rust.
//!
//! `cli` aims to
//!
//! - reduce boilerplate
//! - canonicalize output formatting
//! - encourage adherence to the conventions of standard streams
//!   (e.g. when to print to stderr vs stdout)
//! - encourage appropriate use of exit statuses
//!
//! Concretely, `cli` is a collection of simple functions for formatting
//! command-line output, defining flags, and (eventually) things like
//! integrating with sysexits.
//!
//! It uses [getopts](http://doc.rust-lang.org/getopts/) for argument parsing
//! and thus currently inherits `getopt`'s `experimental` stability level.
//!
//! ## Usage
//!
//! The following example shows how to integrate `cli` functions into a program's
//! `main` function in order to avoid `getopts` boilerplate. Sane defaults are
//! provided for help and version output without forcing consuming code to buy into
//! an application framework.
//!
//!     extern crate cli;
//!     extern crate getopts;
//!
//!     fn main() {
//!         let opts = &[
//!             cli::helpopt(),
//!             cli::versionopt(),
//!             getopts::optopt("o", "", "Set output file name", "FILENAME"),
//!         ];
//!
//!         let matches = cli::parse_args(opts);
//!         if matches.opt_present("h") {
//!             println!("{}", cli::usage_string(opts));
//!             return;
//!         }
//!         if matches.opt_present("version") {
//!             println!("{}", cli::version_string("0.0.1"));
//!             return;
//!         }
//!
//!         ...
//!     }
//!
//! When compiled to a binary named `foo`, this program emits the following output.
//!
//!     $ foo -h
//!     Usage: foo [-h] [--version] [-o FILENAME]
//!
//!     Options:
//!         -h --help           Print this help menu
//!         --version           Print the version of target/cli being run
//!         -o FILENAME         Set output file name
//!
//!     $ foo --version
//!     foo version 0.0.1

#![crate_name = "cli"]
#![experimental]
#![crate_type="rlib"]

extern crate getopts;
use getopts::{Matches, OptGroup, getopts, optflag, short_usage, usage};
use std::{io, os};
use std::io::fs;

mod test;

/// A collection of predefined exit codes cribbed from
/// [sysexits.h](http://www.freebsd.org/cgi/man.cgi?query=sysexits).
///
/// From `sysexits.h`:
///
/// > According to style(9), it is not a good practice to call exit(3) with
/// > arbitrary values to indicate a failure condition when ending a
/// > program.  Instead, the pre-defined exit codes from sysexits should be
/// > used, so the caller of the process can get a rough estimation about
/// > the failure class without looking up the source code.
///
/// Intended for use with `std::os::set_exit_status` prior to process exit.
///
/// # Example
///
/// ```
/// fn main() {
///   ...
///   os::set_exit_status(cli::sysexits::USAGE);
///   return
/// ```
pub mod sysexits {
    /// Successful termination
    pub const OK: int = 0;
    /// Command line usage error
    pub const USAGE: int = 64;
    /// Data format error
    pub const DATA_ERR: int = 65;
    /// Cannot open input
    pub const NO_INPUT: int = 66;
    /// Addressee unknown
    pub const NO_USER: int = 67;
    /// Host name unknown
    pub const NO_HOST: int = 68;
    /// Service unavailable
    pub const UNAVAILABLE: int = 6;
    /// Internal software error
    pub const SOFTWARE_ERR: int = 70;
    /// System error (e.g. can't fork)
    pub const OS_ERR: int = 71;
    /// Critical OS file missing
    pub const  OS_FILE: int = 72;
    /// Can't create (user) output file
    pub const CANT_CREAT: int = 73;
    /// Input/output error
    pub const IO_ERR: int = 74;
    /// Temp failure; user is invited to retry
    pub const TEMP_FAIL: int = 75;
    /// Remote error in protocol
    pub const PROTOCOL: int = 76;
    /// Permission denied
    pub const NO_PERM: int = 77;
    /// Configuration error
    pub const CONFIG: int = 78;
}

/// The file path of the executed program.
///
/// Typically the file path of the invoked executable. If the invocation target
/// is a symlink, then it will be resolved to the executable it links to.
pub fn exec_path() -> Path {
    let path = Path::new(os::args()[0].clone());
    fs::readlink(&path).unwrap_or(path)
}

/// Construct a canonical usage string from a collection of `OptGroup`s.
///
/// Usage string format:
///
/// ```ignore
/// Usage: <program name> [option synopsis]...
///
/// Options:
///     [option description]...
/// ```
pub fn usage_string(opts: &[OptGroup]) -> String {
    let exec_path = exec_path();
    let exec_path = exec_path.as_str().unwrap_or_else(|| "");
    format!("{}", usage(short_usage(exec_path, opts).as_slice(), opts))
}

/// Construct a version string.
///
/// Intended for use as output in response to `--version` as defined by
/// `cli::versionopt`.
///
/// Version string format:
///
/// ```ignore
/// <program name> version <version>
/// ```
pub fn version_string(version: &str) -> String {
    format!("{} version {}", exec_path().display(), version)
}

/// Parse the command-line arguments with which the program was executed
/// according to a collection of `OptGroup`s.
///
/// Any flag parsing failure results in task panic. The program's usage string
/// is printed to stderr prior to panic. Panic is induced in order to avoid
/// program execution with undefined configuration. In such cases, the presence
/// of unrecognized flags or invalid flag values implies confusion on the part
/// of the executor. While perhaps overbearing, it is preferable to halt
/// execution abruptly than to continue with the risk of unwanted behavior.
pub fn parse_args(opts: &[OptGroup]) -> Matches {
    match getopts(os::args().tail(), opts) {
        Ok(matches) => matches,
        Err(getopts_error) => {
            // Write usage string to stderr, then panic.
            match io::stderr().write_str(usage_string(opts).as_slice()) {
                Ok(()) => panic!(getopts_error.to_string()),
                Err(write_error) =>
                    // Write to stderr failed -- panic with both error messages.
                    panic!("{}\n{}", getopts_error.to_string(), write_error.to_string())
            }
        }
    }
}

/// Create a help flag `OptGroup`.
///
/// The returned `OptGroup` is an optional long option for the input `-h`
/// and `--help`.
pub fn helpopt() -> OptGroup {
    optflag("h", "help", "Print this help menu")
}

/// Create a version flag `OptGroup`.
///
/// The returned `OptGroup` is an optional long option for the input
/// `--version`. `-v` and `-V` are avoided in order to prevent confusion in the
/// event when a flag is needed for enabling verbose output.
pub fn versionopt() -> OptGroup {
    optflag(
        "",
        "version",
        format!("Print the version of {} being run", exec_path().display()).as_slice()
    )
}
<commit_msg>Fix rustdoc test failures<commit_after>//! A toolkit for building command-line programs in Rust.
//!
//! `cli` aims to
//!
//! - reduce boilerplate
//! - canonicalize output formatting
//! - encourage adherence to the conventions of standard streams
//!   (e.g. when to print to stderr vs stdout)
//! - encourage appropriate use of exit statuses
//!
//! Concretely, `cli` is a collection of simple functions for formatting
//! command-line output, defining flags, and (eventually) things like
//! integrating with sysexits.
//!
//! It uses [getopts](http://doc.rust-lang.org/getopts/) for argument parsing
//! and thus currently inherits `getopt`'s `experimental` stability level.
//!
//! ## Usage
//!
//! The following example shows how to integrate `cli` functions into a program's
//! `main` function in order to avoid `getopts` boilerplate. Sane defaults are
//! provided for help and version output without forcing consuming code to buy into
//! an application framework.
//!
//!     extern crate cli;
//!     extern crate getopts;
//!
//!     fn main() {
//!         let opts = &[
//!             cli::helpopt(),
//!             cli::versionopt(),
//!             getopts::optopt("o", "", "Set output file name", "FILENAME"),
//!         ];
//!
//!         let matches = cli::parse_args(opts);
//!         if matches.opt_present("h") {
//!             println!("{}", cli::usage_string(opts));
//!             return;
//!         }
//!         if matches.opt_present("version") {
//!             println!("{}", cli::version_string("0.0.1"));
//!             return;
//!         }
//!
//!         // ...
//!     }
//!
//! When compiled to a binary named `foo`, this program emits the following output.
//!
//! ```ignore
//! $ foo -h
//! Usage: foo [-h] [--version] [-o FILENAME]
//!
//! Options:
//!     -h --help           Print this help menu
//!     --version           Print the version of target/cli being run
//!     -o FILENAME         Set output file name
//!
//! $ foo --version
//! foo version 0.0.1
//! ```

#![crate_name = "cli"]
#![experimental]
#![crate_type="rlib"]

extern crate getopts;
use getopts::{Matches, OptGroup, getopts, optflag, short_usage, usage};
use std::{io, os};
use std::io::fs;

mod test;

/// A collection of predefined exit codes cribbed from
/// [sysexits.h](http://www.freebsd.org/cgi/man.cgi?query=sysexits).
///
/// From `sysexits.h`:
///
/// > According to style(9), it is not a good practice to call exit(3) with
/// > arbitrary values to indicate a failure condition when ending a
/// > program.  Instead, the pre-defined exit codes from sysexits should be
/// > used, so the caller of the process can get a rough estimation about
/// > the failure class without looking up the source code.
///
/// Intended for use with `std::os::set_exit_status` prior to process exit.
///
/// # Example
///
/// ```ignore
/// use std::os;
/// fn main() {
///   // ...
///   os::set_exit_status(cli::sysexits::USAGE);
///   return;
/// }
/// ```
pub mod sysexits {
    /// Successful termination
    pub const OK: int = 0;
    /// Command line usage error
    pub const USAGE: int = 64;
    /// Data format error
    pub const DATA_ERR: int = 65;
    /// Cannot open input
    pub const NO_INPUT: int = 66;
    /// Addressee unknown
    pub const NO_USER: int = 67;
    /// Host name unknown
    pub const NO_HOST: int = 68;
    /// Service unavailable
    pub const UNAVAILABLE: int = 6;
    /// Internal software error
    pub const SOFTWARE_ERR: int = 70;
    /// System error (e.g. can't fork)
    pub const OS_ERR: int = 71;
    /// Critical OS file missing
    pub const  OS_FILE: int = 72;
    /// Can't create (user) output file
    pub const CANT_CREAT: int = 73;
    /// Input/output error
    pub const IO_ERR: int = 74;
    /// Temp failure; user is invited to retry
    pub const TEMP_FAIL: int = 75;
    /// Remote error in protocol
    pub const PROTOCOL: int = 76;
    /// Permission denied
    pub const NO_PERM: int = 77;
    /// Configuration error
    pub const CONFIG: int = 78;
}

/// The file path of the executed program.
///
/// Typically the file path of the invoked executable. If the invocation target
/// is a symlink, then it will be resolved to the executable it links to.
pub fn exec_path() -> Path {
    let path = Path::new(os::args()[0].clone());
    fs::readlink(&path).unwrap_or(path)
}

/// Construct a canonical usage string from a collection of `OptGroup`s.
///
/// Usage string format:
///
/// ```ignore
/// Usage: <program name> [option synopsis]...
///
/// Options:
///     [option description]...
/// ```
pub fn usage_string(opts: &[OptGroup]) -> String {
    let exec_path = exec_path();
    let exec_path = exec_path.as_str().unwrap_or_else(|| "");
    format!("{}", usage(short_usage(exec_path, opts).as_slice(), opts))
}

/// Construct a version string.
///
/// Intended for use as output in response to `--version` as defined by
/// `cli::versionopt`.
///
/// Version string format:
///
/// ```ignore
/// <program name> version <version>
/// ```
pub fn version_string(version: &str) -> String {
    format!("{} version {}", exec_path().display(), version)
}

/// Parse the command-line arguments with which the program was executed
/// according to a collection of `OptGroup`s.
///
/// Any flag parsing failure results in task panic. The program's usage string
/// is printed to stderr prior to panic. Panic is induced in order to avoid
/// program execution with undefined configuration. In such cases, the presence
/// of unrecognized flags or invalid flag values implies confusion on the part
/// of the executor. While perhaps overbearing, it is preferable to halt
/// execution abruptly than to continue with the risk of unwanted behavior.
pub fn parse_args(opts: &[OptGroup]) -> Matches {
    match getopts(os::args().tail(), opts) {
        Ok(matches) => matches,
        Err(getopts_error) => {
            // Write usage string to stderr, then panic.
            match io::stderr().write_str(usage_string(opts).as_slice()) {
                Ok(()) => panic!(getopts_error.to_string()),
                Err(write_error) =>
                    // Write to stderr failed -- panic with both error messages.
                    panic!("{}\n{}", getopts_error.to_string(), write_error.to_string())
            }
        }
    }
}

/// Create a help flag `OptGroup`.
///
/// The returned `OptGroup` is an optional long option for the input `-h`
/// and `--help`.
pub fn helpopt() -> OptGroup {
    optflag("h", "help", "Print this help menu")
}

/// Create a version flag `OptGroup`.
///
/// The returned `OptGroup` is an optional long option for the input
/// `--version`. `-v` and `-V` are avoided in order to prevent confusion in the
/// event when a flag is needed for enabling verbose output.
pub fn versionopt() -> OptGroup {
    optflag(
        "",
        "version",
        format!("Print the version of {} being run", exec_path().display()).as_slice()
    )
}
<|endoftext|>


<commit_before>extern crate libc;

use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const libc::c_void, length: libc::size_t, name: *const libc::c_char);
}

pub fn any(data: *const libc::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), length, name_cstr.as_ptr());
  }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::ffi::CString;
use std::mem::transmute;

#[link(name = "rust")]
extern {
  fn klee_make_symbolic(data: *const libc::c_void, length: libc::size_t, name: *const libc::c_char);
}

pub fn any(data: *const libc::c_void, length: usize, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(data, length, name_cstr.as_ptr());
  }
}

pub fn i32(data: *const i32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}

pub fn u32(data: *const u32, name: &str) {
  let name_cstr = CString::new(name).unwrap();
  unsafe {
    klee_make_symbolic(transmute(data), 4, name_cstr.as_ptr());
  }
}
<|endoftext|>