#[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<String> {
+ if s.is_null() {
+ None
+ } else {
+ Some(CStr::from_ptr(s).to_string_lossy().into())
+ }
+ }
- fn codeset() -> Option<String> {
+ fn set_locale(category: c_int, locale: Option<&str>) -> Option<String> {
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<String> {
- 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
+ }
}
}
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
}
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};
}
fn main() -> Result<()> {
+ println!("locale_charset={}", locale_charset());
let Args { max_cases, files } = Args::parse();
for file in files {