Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit bfa0f01

Browse files
phip1611nicholasbishop
authored andcommitted
macros: allow to create empty cstr8/16 slices
1 parent ec9ffa3 commit bfa0f01

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

‎CHANGELOG.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
any effect.
5353
- The `unsafe_protocol` macro now accepts the path of a `Guid` constant in
5454
addition to a string literal.
55+
- The `cstr8` and the `cstr16` macros now both accept `(nothing)` and `""`
56+
(empty inputs) to create valid empty strings. They include the null-byte.
5557

5658
## uefi-services - [Unreleased]
5759

‎uefi-macros/src/lib.rs‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,26 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
258258
/// # Example
259259
/// ```
260260
/// # use uefi_macros::cstr8;
261+
/// // Empty string
262+
/// assert_eq!(cstr8!().to_u16_slice_with_nul(), [0]);
263+
/// assert_eq!(cstr8!("").to_u16_slice_with_nul(), [0]);
264+
/// // Non-empty string
261265
/// assert_eq!(cstr8!("test").to_bytes_with_nul(), [116, 101, 115, 116, 0]);
262266
/// ```
263267
#[proc_macro]
264268
pub fn cstr8(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
269+
// Accept empty input.
270+
if input.is_empty() {
271+
return quote!(unsafe { ::uefi::CStr16::from_u16_with_nul_unchecked(&[0]) }).into();
272+
}
265273
let input: LitStr = parse_macro_input!(input);
266274
let input = input.value();
275+
// Accept "" input.
276+
if input.is_empty() {
277+
return quote!(unsafe { ::uefi::CStr16::from_u16_with_nul_unchecked(&[0]) }).into();
278+
}
279+
280+
// Accept any non-empty string input.
267281
match input
268282
.chars()
269283
.map(u8::try_from)
@@ -283,14 +297,28 @@ pub fn cstr8(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
283297
/// This will throw a compile error if an invalid character is in the passed string.
284298
///
285299
/// # Example
286-
/// ```
300+
/// ```rust
287301
/// # use uefi_macros::cstr16;
302+
/// // Empty string
303+
/// assert_eq!(cstr16!().to_u16_slice_with_nul(), [0]);
304+
/// assert_eq!(cstr16!("").to_u16_slice_with_nul(), [0]);
305+
/// // Non-empty string
288306
/// assert_eq!(cstr16!("test €").to_u16_slice_with_nul(), [116, 101, 115, 116, 32, 8364, 0]);
289307
/// ```
290308
#[proc_macro]
291309
pub fn cstr16(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
310+
// Accept empty input.
311+
if input.is_empty() {
312+
return quote!(unsafe { ::uefi::CStr16::from_u16_with_nul_unchecked(&[0]) }).into();
313+
}
292314
let input: LitStr = parse_macro_input!(input);
293315
let input = input.value();
316+
// Accept "" input.
317+
if input.is_empty() {
318+
return quote!(unsafe { ::uefi::CStr16::from_u16_with_nul_unchecked(&[0]) }).into();
319+
}
320+
321+
// Accept any non-empty string input.
294322
match input
295323
.chars()
296324
.map(|c| u16::try_from(c as u32))
@@ -299,8 +327,11 @@ pub fn cstr16(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
299327
Ok(c) => {
300328
quote!(unsafe { ::uefi::CStr16::from_u16_with_nul_unchecked(&[ #(#c),* , 0 ]) }).into()
301329
}
302-
Err(_) => syn::Error::new_spanned(input, "invalid character in string")
303-
.into_compile_error()
304-
.into(),
330+
Err(_) => syn::Error::new_spanned(
331+
input,
332+
"There are UTF-8 characters that can't be transformed to UCS-2 character",
333+
)
334+
.into_compile_error()
335+
.into(),
305336
}
306337
}

‎uefi/src/lib.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,24 @@ pub(crate) mod mem;
127127
pub(crate) mod polyfill;
128128

129129
mod util;
130+
131+
#[cfg(test)]
132+
// Crates that create procedural macros can't unit test the macros they export.
133+
// Therefore, we do some tests here.
134+
mod macro_tests {
135+
use uefi_macros::{cstr16, cstr8};
136+
137+
#[test]
138+
fn cstr8_macro_literal() {
139+
let _empty1 = cstr8!();
140+
let _empty2 = cstr8!("");
141+
let _regular = cstr8!("foobar");
142+
}
143+
144+
#[test]
145+
fn cstr16_macro_literal() {
146+
let _empty1 = cstr16!();
147+
let _empty2 = cstr16!("");
148+
let _regular = cstr16!("foobar");
149+
}
150+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /