From 7b8c7d8e8e05793f456be2b4cd0a6aedf445439a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 1 Nov 2023 07:24:32 -0700 Subject: [PATCH] Get locale_charset() working. --- rust/src/locale_charset.rs | 37 ++++++++++++++++++++++++++----------- rust/src/main.rs | 3 ++- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/rust/src/locale_charset.rs b/rust/src/locale_charset.rs index fdcb685f18..e967c1d46d 100644 --- a/rust/src/locale_charset.rs +++ b/rust/src/locale_charset.rs @@ -220,23 +220,37 @@ fn map_aliases(s: &str) -> &'static str { #[cfg(unix)] mod inner { - use std::ffi::CStr; + use std::{ + ffi::{c_int, CStr, CString}, + ptr::null, + }; + + use libc::{self, nl_langinfo, setlocale, CODESET, LC_CTYPE}; - use libc::{self, nl_langinfo, CODESET}; + unsafe fn string_from_pointer(s: *const i8) -> Option { + if s.is_null() { + None + } else { + Some(CStr::from_ptr(s).to_string_lossy().into()) + } + } - fn codeset() -> Option { + fn set_locale(category: c_int, locale: Option<&str>) -> Option { unsafe { - let codeset = nl_langinfo(CODESET); - if codeset.is_null() { - None - } else { - Some(CStr::from_ptr(codeset).to_string_lossy().into()) - } + let locale = locale.map(|s| CString::new(s).unwrap()); + let locale_ptr = locale.as_ref().map_or(null(), |s| s.as_ptr()); + string_from_pointer(setlocale(category, locale_ptr)) } } pub fn locale_charset() -> Option { - codeset() + unsafe { + let saved_locale = set_locale(LC_CTYPE, None); + set_locale(LC_CTYPE, Some("")); + let codeset = string_from_pointer(nl_langinfo(CODESET)); + set_locale(LC_CTYPE, saved_locale.as_ref().map(|x| x.as_str())); + codeset + } } } @@ -283,7 +297,8 @@ mod inner { pub fn locale_charset() -> &'static str { lazy_static! { - static ref LOCALE_CHARSET: &'static str = map_aliases(&inner::locale_charset().unwrap_or(String::from("UTF-8"))); + static ref LOCALE_CHARSET: &'static str = + map_aliases(&inner::locale_charset().unwrap_or(String::from("UTF-8"))); } &LOCALE_CHARSET } diff --git a/rust/src/main.rs b/rust/src/main.rs index 6024b67f2d..8085957daa 100644 --- a/rust/src/main.rs +++ b/rust/src/main.rs @@ -16,7 +16,7 @@ use anyhow::Result; use clap::Parser; -use pspp::raw::{Reader, Record}; +use pspp::{raw::{Reader, Record}, locale_charset::locale_charset}; use std::fs::File; use std::io::BufReader; use std::path::{Path, PathBuf}; @@ -36,6 +36,7 @@ struct Args { } fn main() -> Result<()> { + println!("locale_charset={}", locale_charset()); let Args { max_cases, files } = Args::parse(); for file in files { -- 2.30.2