Commit a2e2ee05 authored by John Hodge's avatar John Hodge

Rename the va_list type to VaList, update README and Cargo.toml

parent 52c2357f
......@@ -2,6 +2,11 @@
name = "va_list"
version = "0.0.1"
authors = [ "John Hodge <tpg@mutabah.net>" ]
description = "Provides a rust implementation of the 'va_list' type for a small set of ABIs. Allowing rust implementations of functions like vprintf."
repository = "https://github.com/thepowersgang/va_list-rs"
readme = "README.md"
keywords = ["unsafe", "va_list", "ffi", "c"]
license = "MIT"
[dev-dependencies.va_list-helper]
path = "deps/helper/"
The MIT License (MIT)
Copyright (c) 2015 John Hodge
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Rust implementation of C's `va_list` type
# Overview
This crate provides a rust `VaList`type, which is binary-compatible for the C type of the same name. It is intended to allow rust code to provide the complex logic of variable argument functions.
# Example
```rust
extern crate va_list;
use va_list::VaList;
extern "C" print_ints_va(count: u32, mut args: VaList)
{
for i in (0 .. count) {
println!("{}: {}", i, args.get::<i32>());
}
}
```
# Status
- x86-64 linux/ELF ABI (aka System-V) : Tested in the wild, works relatively well
- x86 linux/ELF ABI (sys-v) : Unit tested only
......
......@@ -7,9 +7,9 @@
use super::VaPrimitive;
#[allow(non_camel_case_types)]
pub struct va_list(*const u8);
pub struct VaList(*const u8);
impl va_list
impl VaList
{
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
T::get(self)
......@@ -26,20 +26,20 @@ impl va_list
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut va_list) -> Self {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
impl VaPrimitive for usize { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for isize { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for u64 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for i64 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for u32 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
//impl VaPrimitive for u16 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
//impl VaPrimitive for i16 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
//impl VaPrimitive for u8 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
//impl VaPrimitive for i8 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for f64 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for f32 { unsafe fn get(l: &mut va_list) -> Self { l.get_raw() } }
impl VaPrimitive for usize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for isize { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for u32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for i32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for u16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i16 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for u8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
//impl VaPrimitive for i8 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f64 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
impl VaPrimitive for f32 { unsafe fn get(l: &mut VaList) -> Self { l.get_raw() } }
......@@ -6,9 +6,9 @@ use super::VaPrimitive;
#[allow(non_camel_case_types)]
/// Core type as passed though the FFI
pub struct va_list(*mut VaListInner);
// /// Saves the state of the va_list, similar to va_copy
//impl Clone for va_list { fn clone(&self) -> Self { va_list(self.0) } }
pub struct VaList(*mut VaListInner);
// /// Saves the state of the VaList, similar to va_copy
//impl Clone for VaList { fn clone(&self) -> Self { va_list(self.0) } }
#[repr(C)]
#[derive(Debug)]
......@@ -22,9 +22,9 @@ pub struct VaListInner
reg_save_area: *const (),
}
impl va_list
impl VaList
{
/// Read a value from the va_list
/// Read a value from the VaList
///
/// Users should take care that they are reading the correct type
pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
......@@ -75,7 +75,7 @@ impl VaListInner
impl<T: 'static> VaPrimitive for *const T
{
unsafe fn get(list: &mut va_list) -> Self {
unsafe fn get(list: &mut VaList) -> Self {
<usize>::get(list) as *const T
}
}
......@@ -83,7 +83,7 @@ impl<T: 'static> VaPrimitive for *const T
macro_rules! impl_va_prim {
($u:ty, $s:ty) => {
impl VaPrimitive for $u {
unsafe fn get(list: &mut va_list) -> Self {
unsafe fn get(list: &mut VaList) -> Self {
let inner = list.inner();
// See the ELF AMD64 ABI document for a description of how this should act
if ! inner.check_space(1, 0) {
......@@ -95,7 +95,7 @@ macro_rules! impl_va_prim {
}
}
impl VaPrimitive for $s {
unsafe fn get(list: &mut va_list) -> Self {
unsafe fn get(list: &mut VaList) -> Self {
mem::transmute( <$u>::get(list) )
}
}
......@@ -105,6 +105,6 @@ macro_rules! impl_va_prim {
impl_va_prim!{ usize, isize }
impl_va_prim!{ u64, i64 }
impl_va_prim!{ u32, i32 }
impl_va_prim!{ u16, i16 }
impl_va_prim!{ u8, i8 }
//impl_va_prim!{ u16, i16 }
//impl_va_prim!{ u8, i8 }
......@@ -2,6 +2,19 @@
* C FFI - va_list support
*
* This crate provides an interface for rust code to read values passed in C's va_list type.
*
* ## Example
* ```rust
* extern crate va_list;
* use va_list::VaList;
*
* extern "C" print_ints_va(count: u32, mut args: VaList)
* {
* for i in (0 .. count) {
* println!("{}: {}", i, args.get::<i32>());
* }
* }
* ```
*/
#![cfg_attr(nightly,feature(no_std,core))]
#![cfg_attr(nightly,no_std)]
......@@ -22,12 +35,12 @@ extern crate core;
#[cfg(target_arch="x86")] #[cfg(target_family="unix")]
#[path="impl-x86-sysv.rs"] mod imp;
pub use imp::va_list;
pub use imp::VaList;
/// Trait implemented on types that can be read from a va_list
pub trait VaPrimitive: 'static
{
#[doc(hidden)]
unsafe fn get(&mut va_list) -> Self;
unsafe fn get(&mut VaList) -> Self;
}
......@@ -4,11 +4,11 @@ extern "C" {
fn dispatch(context: *mut (), count: u32, ...);
}
type CbType<'a> = &'a mut FnMut(u32, va_list::va_list);
type CbType<'a> = &'a mut FnMut(u32, va_list::VaList);
#[no_mangle]
/// Method called by 'dispatch'
pub extern "C" fn inbound(context: *mut (), count: u32, args: va_list::va_list) {
pub extern "C" fn inbound(context: *mut (), count: u32, args: va_list::VaList) {
let cb_ptr = unsafe { ::std::ptr::read(context as *mut CbType ) };
// call passed closure
(cb_ptr)(count, args);
......@@ -29,7 +29,7 @@ macro_rules! test_va_list {
fn trivial_values() {
// Trivial test: Pass four random-ish sized integers
test_va_list!(4, (123456u32, 2u64, 1i32, -23i64),
|_count, mut list: va_list::va_list| { unsafe {
|_count, mut list: va_list::VaList| { unsafe {
assert_eq!( list.get::<u32>(), 123456u32 );
assert_eq!( list.get::<u64>(), 2u64 );
assert_eq!( list.get::<i32>(), 1i32 );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment