From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- third_party/rust/cstr/src/lib.rs | 56 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 third_party/rust/cstr/src/lib.rs (limited to 'third_party/rust/cstr/src/lib.rs') diff --git a/third_party/rust/cstr/src/lib.rs b/third_party/rust/cstr/src/lib.rs new file mode 100644 index 0000000000..c9e69d924c --- /dev/null +++ b/third_party/rust/cstr/src/lib.rs @@ -0,0 +1,56 @@ +//! A macro for getting `&'static CStr` from literal or identifier. +//! +//! This macro checks whether the given literal is valid for `CStr` +//! at compile time, and returns a static reference of `CStr`. +//! +//! This macro can be used to to initialize constants on Rust 1.64 and above. +//! +//! ## Example +//! +//! ``` +//! use cstr::cstr; +//! use std::ffi::CStr; +//! +//! let test = cstr!(b"hello\xff"); +//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\xff\0").unwrap()); +//! let test = cstr!("hello"); +//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap()); +//! let test = cstr!(hello); +//! assert_eq!(test, CStr::from_bytes_with_nul(b"hello\0").unwrap()); +//! ``` + +// While this isn't necessary when using Cargo >= 1.42, omitting it actually requires path-less +// `--extern proc_macro` to be passed to `rustc` when building this crate. Some tools may not do +// this correctly. So it's added as a precaution. +extern crate proc_macro; + +use crate::parse::parse_input; +use proc_macro::TokenStream as RawTokenStream; +use proc_macro2::{Literal, Span, TokenStream}; +use quote::{quote, quote_spanned}; +use std::ffi::CString; + +mod parse; + +struct Error(Span, &'static str); + +#[proc_macro] +pub fn cstr(input: RawTokenStream) -> RawTokenStream { + let tokens = match build_byte_str(input.into()) { + Ok(s) => quote!(unsafe { ::core::ffi::CStr::from_bytes_with_nul_unchecked(#s) }), + Err(Error(span, msg)) => quote_spanned!(span => compile_error!(#msg)), + }; + tokens.into() +} + +fn build_byte_str(input: TokenStream) -> Result { + let (bytes, span) = parse_input(input)?; + match CString::new(bytes) { + Ok(s) => { + let mut lit = Literal::byte_string(s.as_bytes_with_nul()); + lit.set_span(span); + Ok(lit) + } + Err(_) => Err(Error(span, "nul byte found in the literal")), + } +} -- cgit v1.2.3