blob: 8a5afd939affbbf9c9617dce9b8f230bc543139b [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! This crate contains the [`cstr`] macro for making `&'static CStr` types out of string literals.
#![deny(missing_docs)]
// Re-export libc to be used from the c_char macro
#[doc(hidden)]
pub mod __libc_reexport {
pub use libc::*;
}
/// Creates a `&'static CStr` from a string literal.
#[macro_export]
macro_rules! cstr {
($s:expr) => {
// `concat` macro always produces a static string literal.
// It is always safe to create a CStr from a null-terminated string.
// If there are interior null bytes, the string will just end early.
unsafe {
::std::ffi::CStr::from_ptr::<'static>(
concat!($s, "\0").as_ptr() as *const $crate::__libc_reexport::c_char
)
}
};
}
#[cfg(test)]
mod tests {
use {super::cstr, std::ffi};
#[test]
fn cstr() {
let cstring = ffi::CString::new("test string").expect("CString::new failed");
let cstring_cstr = cstring.as_c_str();
let cstr = cstr!("test string");
assert_eq!(cstring_cstr, cstr);
}
#[test]
fn cstr_not_equal() {
let cstring = ffi::CString::new("test string").expect("CString::new failed");
let cstring_cstr = cstring.as_c_str();
let cstr = cstr!("different test string");
assert_ne!(cstring_cstr, cstr);
}
#[test]
fn cstr_early_null() {
let cstring = ffi::CString::new("test").expect("CString::new failed");
let cstring_cstr = cstring.as_c_str();
let cstr = cstr!("test\0 string");
assert_eq!(cstring_cstr, cstr);
}
}