Add a gettext wrapper in Rust

This allows the wgettext! macro, which calls into C++.
This commit is contained in:
ridiculousfish 2023-01-15 13:18:52 -08:00
parent 681a165721
commit 55f655f003
5 changed files with 40 additions and 0 deletions

View file

@ -31,6 +31,7 @@ include_cpp! {
generate!("parse_util_unescape_wildcards") generate!("parse_util_unescape_wildcards")
generate!("wildcard_match") generate!("wildcard_match")
generate!("wgettext_ptr")
} }

View file

@ -0,0 +1,35 @@
use crate::ffi;
use crate::wchar::{wchar_t, wstr};
use crate::wchar_ffi::wcslen;
/// Support for wgettext.
/// Implementation detail for wgettext!.
pub fn wgettext_impl_do_not_use_directly(text: &[wchar_t]) -> &'static wstr {
assert!(
text.len() > 0 && text[text.len() - 1] == 0,
"should be nul-terminated"
);
let res: *const wchar_t = ffi::wgettext_ptr(text.as_ptr());
let slice = unsafe { std::slice::from_raw_parts(res as *const u32, wcslen(res)) };
wstr::from_slice(slice).expect("Invalid UTF-32")
}
/// Get a (possibly translated) string from a string literal.
/// This returns a &'static wstr.
#[allow(unused_macros)]
macro_rules! wgettext {
($string:literal) => {
crate::wutil::gettext::wgettext_impl_do_not_use_directly(
crate::wchar_ffi::u32cstr!($string).as_slice_with_nul(),
)
};
}
use crate::ffi_tests::add_test;
add_test!("test_untranslated", || {
let s: &'static wstr = wgettext!("abc");
assert_eq!(s, "abc");
let s2: &'static wstr = wgettext!("static");
assert_eq!(s2, "static");
});

View file

@ -1,3 +1,4 @@
pub mod gettext;
mod wcstoi; mod wcstoi;
pub use wcstoi::*; pub use wcstoi::*;

View file

@ -514,6 +514,8 @@ const wcstring &wgettext(const wchar_t *in) {
return val; return val;
} }
const wchar_t *wgettext_ptr(const wchar_t *in) { return wgettext(in).c_str(); }
int wmkdir(const wcstring &name, int mode) { int wmkdir(const wcstring &name, int mode) {
cstring name_narrow = wcs2string(name); cstring name_narrow = wcs2string(name);
return mkdir(name_narrow.c_str(), mode); return mkdir(name_narrow.c_str(), mode);

View file

@ -90,6 +90,7 @@ std::wstring wbasename(std::wstring path);
/// and bindtextdomain functions. This should probably be moved out of wgettext, so that wgettext /// and bindtextdomain functions. This should probably be moved out of wgettext, so that wgettext
/// will be nothing more than a wrapper around gettext, like all other functions in this file. /// will be nothing more than a wrapper around gettext, like all other functions in this file.
const wcstring &wgettext(const wchar_t *in); const wcstring &wgettext(const wchar_t *in);
const wchar_t *wgettext_ptr(const wchar_t *in);
/// Wide character version of mkdir. /// Wide character version of mkdir.
int wmkdir(const wcstring &name, int mode); int wmkdir(const wcstring &name, int mode);