printf-compat

Crates.io Docs.rs

printf reimplemented in Rust

This is a complete reimplementation of printf in Rust, using the unstable (i.e. requires a Nightly compiler) c_variadic feature.

Benefits

⚒ Modular

printf-compat lets you pick how you want to output a message. Use pre-written adapters for fmt::Write (like a [String]) or io::Write (like io::stdout()), or implement your own.

🔬 Small

This crate is no_std compatible (printf-compat = { version = "0.1", default-features = false } in your Cargo.toml). The main machinery doesn't require the use of [core::fmt], and it can't panic.

🔒 Safe (as can be)

Of course, printf is completely unsafe, as it requires the use of va_list. However, outside of that, all of the actual string parsing is written in completely safe Rust. No buffer overflow attacks!

The n format specifier, which writes to a user-provided pointer, is considered a serious security vulnerability if a user-provided string is ever passed to printf. It is supported by this crate; however, it doesn't do anything by default, and you'll have to explicitly do the writing yourself.

🧹 Tested

A wide [test suite] is used to ensure that many different possibilities are identical to glibc's printf. Differences are documented.

Getting Started

Start by adding the unstable feature:

```rust

![feature(c_variadic)]

```

Now, add your function signature:

```rust use cty::{cchar, cint};

[no_mangle]

unsafe extern "C" fn clibraryprint(str: *const cchar, mut args: ...) -> cint { todo!() } ```

If you have access to [std], i.e. not an embedded platform, you can use [std::os::raw] instead of [cty]. Also, think about what you're doing:

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)); println!("{}", s); bytes_written

Of course, replace [output::fmt_write] with whatever you like—some are provided for you in [output]. If you'd like to write your own, follow their function signature: you need to provide a function to [format()] that takes an [Argument] and returns the number of bytes written (although you don't need to if your C library doesn't use it) or -1 if there was an error.

License: MIT OR Apache-2.0