Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Now, add your function signature:
use core::ffi::{c_char, c_int};

#[no_mangle]
unsafe extern "C" fn c_library_print(str: *const c_char, mut args: ...) -> c_int {
unsafe extern "C" fn c_library_print(str: *const c_char, args: ...) -> c_int {
todo!()
}
```
Expand All @@ -91,7 +91,7 @@ Now, add your logic:
```rust
use printf_compat::{format, output};
let mut s = String::new();
let bytes_written = format(str, args.as_va_list(), output::fmt_write(&mut s));
let bytes_written = format(str, args, output::fmt_write(&mut s));
println!("{}", s);
bytes_written
```
Expand Down
6 changes: 3 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
//! use core::ffi::{c_char, c_int};
//!
//! #[no_mangle]
//! unsafe extern "C" fn c_library_print(str: *const c_char, mut args: ...) -> c_int {
//! unsafe extern "C" fn c_library_print(str: *const c_char, args: ...) -> c_int {
//! todo!()
//! }
//! ```
Expand All @@ -88,10 +88,10 @@
//! # #![feature(c_variadic)]
//! # use core::ffi::{c_char, c_int};
//! # #[no_mangle]
//! # unsafe extern "C" fn c_library_print(str: *const c_char, mut args: ...) -> c_int {
//! # unsafe extern "C" fn c_library_print(str: *const c_char, args: ...) -> c_int {
//! use printf_compat::{format, output};
//! let mut s = String::new();
//! let bytes_written = format(str, args.as_va_list(), output::fmt_write(&mut s));
//! let bytes_written = format(str, args, output::fmt_write(&mut s));
//! println!("{}", s);
//! bytes_written
//! # }
Expand Down
19 changes: 8 additions & 11 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,7 @@ pub fn fmt_write(w: &mut impl fmt::Write) -> impl FnMut(Argument) -> c_int + '_
/// # Safety
///
/// [`VaList`]s are *very* unsafe. The passed `format` and `args` parameter must be a valid [`printf` format string](http://www.cplusplus.com/reference/cstdio/printf/).
pub unsafe fn display<'a, 'b>(
format: *const c_char,
va_list: VaList<'a, 'b>,
) -> VaListDisplay<'a, 'b> {
pub unsafe fn display<'a>(format: *const c_char, va_list: VaList<'a>) -> VaListDisplay<'a> {
VaListDisplay {
format,
va_list,
Expand All @@ -327,29 +324,29 @@ pub unsafe fn display<'a, 'b>(
/// use core::ffi::{c_char, c_int};
///
/// #[no_mangle]
/// unsafe extern "C" fn c_library_print(str: *const c_char, mut args: ...) -> c_int {
/// let format = printf_compat::output::display(str, args.as_va_list());
/// unsafe extern "C" fn c_library_print(str: *const c_char, args: ...) -> c_int {
/// let format = printf_compat::output::display(str, args);
/// println!("{}", format);
/// format.bytes_written()
/// }
/// ```
pub struct VaListDisplay<'a, 'b> {
pub struct VaListDisplay<'a> {
format: *const c_char,
va_list: VaList<'a, 'b>,
va_list: VaList<'a>,
written: Cell<c_int>,
}

impl VaListDisplay<'_, '_> {
impl VaListDisplay<'_> {
/// Get the number of bytes written, or 0 if there was an error.
pub fn bytes_written(&self) -> c_int {
self.written.get()
}
}

impl<'a, 'b> fmt::Display for VaListDisplay<'a, 'b> {
impl<'a> fmt::Display for VaListDisplay<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe {
let bytes = crate::format(self.format, self.va_list.clone().as_va_list(), fmt_write(f));
let bytes = crate::format(self.format, self.va_list.clone(), fmt_write(f));
self.written.set(bytes);
if bytes < 0 {
Err(fmt::Error)
Expand Down
22 changes: 6 additions & 16 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,15 @@ extern "C" {
fn free(p: *mut c_void);
}

unsafe extern "C" fn rust_fmt(str: *const c_char, mut args: ...) -> Box<(c_int, String)> {
unsafe extern "C" fn rust_fmt(str: *const c_char, args: ...) -> Box<(c_int, String)> {
let mut s = String::new();
let bytes_written = printf_compat::format(
str,
args.clone().as_va_list(),
printf_compat::output::fmt_write(&mut s),
);
let bytes_written =
printf_compat::format(str, args.clone(), printf_compat::output::fmt_write(&mut s));
assert!(bytes_written >= 0);
let mut s2 = std::io::Cursor::new(vec![]);
assert_eq!(
bytes_written,
printf_compat::format(
str,
args.as_va_list(),
printf_compat::output::io_write(&mut s2),
)
printf_compat::format(str, args, printf_compat::output::io_write(&mut s2),)
);
assert_eq!(s.as_bytes(), s2.get_ref());
Box::new((bytes_written, s))
Expand Down Expand Up @@ -68,11 +61,8 @@ fn assert_fmt_err(fmt: &CStr) {

unsafe extern "C" fn format(str: *const c_char, args: ...) -> c_int {
let mut s = String::new();
let bytes_written = printf_compat::format(
str,
args.clone().as_va_list(),
printf_compat::output::fmt_write(&mut s),
);
let bytes_written =
printf_compat::format(str, args.clone(), printf_compat::output::fmt_write(&mut s));
bytes_written
}
let bytes_written = unsafe { format(fmt.as_ptr()) };
Expand Down