1 #![cfg(all(
2     feature = "with-system-locale",
3     unix,
4     any(
5         target_os = "dragonfly",
6         target_os = "freebsd",
7         target_os = "ios",
8         target_os = "macos",
9         target_os = "openbsd",
10         target_os = "netbsd"
11     )
12 ))]
13 
14 use libc::{c_char, c_int, c_void};
15 
16 use crate::error::Error;
17 use crate::system_locale::unix::{Encoding, Lconv, StaticCString, UTF_8};
18 
19 extern "C" {
localeconv_l(locale: *const c_void) -> *const libc::lconv20     fn localeconv_l(locale: *const c_void) -> *const libc::lconv;
nl_langinfo_l(item: libc::nl_item, locale: *const c_void) -> *const c_char21     fn nl_langinfo_l(item: libc::nl_item, locale: *const c_void) -> *const c_char;
querylocale(mask: c_int, locale: *const c_void) -> *const c_char22     fn querylocale(mask: c_int, locale: *const c_void) -> *const c_char;
23 }
24 
get_encoding(locale: *const c_void) -> Result<Encoding, Error>25 pub(crate) fn get_encoding(locale: *const c_void) -> Result<Encoding, Error> {
26     let encoding_ptr = unsafe { nl_langinfo_l(libc::CODESET, locale) };
27     let encoding_static_c_string = StaticCString::new(encoding_ptr, *UTF_8, "nl_langinfo_l")?;
28     let encoding_string = encoding_static_c_string.to_string()?;
29     let encoding = Encoding::from_bytes(encoding_string.as_bytes())?;
30     Ok(encoding)
31 }
32 
get_lconv(locale: *const c_void, encoding: Encoding) -> Result<Lconv, Error>33 pub(crate) fn get_lconv(locale: *const c_void, encoding: Encoding) -> Result<Lconv, Error> {
34     let lconv_ptr = unsafe { localeconv_l(locale) };
35     if lconv_ptr.is_null() {
36         return Err(Error::system_invalid_return(
37             "localeconv_l",
38             "localeconv_l unexpectedly returned a null pointer.",
39         ));
40     }
41     let lconv: &libc::lconv = unsafe { lconv_ptr.as_ref() }.unwrap();
42     let lconv = Lconv::new(lconv, encoding)?;
43     Ok(lconv)
44 }
45 
get_name(locale: *const c_void, encoding: Encoding) -> Result<String, Error>46 pub(crate) fn get_name(locale: *const c_void, encoding: Encoding) -> Result<String, Error> {
47     let mask = libc::LC_CTYPE_MASK | libc::LC_MONETARY_MASK | libc::LC_NUMERIC_MASK;
48     let name_ptr = unsafe { querylocale(mask, locale) };
49     let name_static_c_string = StaticCString::new(name_ptr, encoding, "querylocale")?;
50     let name = name_static_c_string.to_string()?;
51     Ok(name)
52 }
53