Subject: Re: bug#65908: 29.1.50; Emacs 29 regresses on macOS

From: Gerd Möllmann <[email-masked]>
Date: Thu, 05 Oct 2023 15:18:42 +0200

Gerd Möllmann <[email-masked]> writes:

> It would be nice if I could get at least the right character encoding on
> my system...  On the plus side, I at least know now what's happening,
> although I don't know what to do.

I'd like to propose the attached patch for problem of invalid LANG
setting.  This simply falls back to "en_US.UTF-8" if LANG isn't valid,
or something valid can't be deduced from the locale.

I find this acceptable even in my setting ("en_DE") because even Apple's
Terminal doesn't get this right.  A closer looks at what is set in the
locale in Terminal shows that, for instance, date format and thousands
separator are en_US anyway.

>From 93457632cd5f17de01ec291d888d2d2fb0acffdf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gerd=20M=C3=B6llmann?= <[email-masked]>
Date: Thu, 5 Oct 2023 15:12:40 +0200
Subject: [PATCH] Handle LANG on macOS differntly (bug#bug#65908)

* src/nsterm.m (ns_init_locale): If LANG is set, try to use that,
otherwise try to deduce what LANG should be.  Check is the result is
valid, and use LANG="en_US.UTF-8" if not.
---
 src/nsterm.m | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/src/nsterm.m b/src/nsterm.m
index 4e0dfa58c63..09cb7236b6e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -554,29 +554,25 @@ - (unsigned long)unsignedLong
 /* macOS doesn't set any environment variables for the locale when run
    from the GUI. Get the locale from the OS and set LANG.  */
 {
-  NSLocale *locale = [NSLocale currentLocale];
-
   NSTRACE ("ns_init_locale");
 
-  /* If we were run from a terminal then assume an unset LANG variable
-     is intentional and don't try to "fix" it.  */
-  if (!isatty (STDIN_FILENO))
+  const char *lang = getenv ("LANG");
+  if (lang == NULL)
     {
-      char *oldLocale = setlocale (LC_ALL, NULL);
-      /* It seems macOS should probably use UTF-8 everywhere.
-         'localeIdentifier' does not specify the encoding, and I can't
-         find any way to get the OS to tell us which encoding to use,
-         so hard-code '.UTF-8'.  */
-      NSString *localeID = [NSString stringWithFormat:@"%@.UTF-8",
-                                     [locale localeIdentifier]];
+      const NSLocale *locale = [NSLocale currentLocale];
+      const NSString *localeID = [NSString stringWithFormat:@"%@.UTF-8",
+					   [locale localeIdentifier]];
+      lang = [localeID UTF8String];
+    }
 
-      /* Check the locale ID is valid and if so set LANG, but not if
-         it is already set.  */
-      if (setlocale (LC_ALL, [localeID UTF8String]))
-        setenv("LANG", [localeID UTF8String], 0);
+  /* Check if LANG can be used for initializing the locale.  If not,
+     use a default setting.  Note that Emacs' main will undo the
+     setlocale below, initializing the locale from the
+     environment.  */
+  if (setlocale (LC_ALL, lang) == NULL)
+    lang = "en_US.UTF-8";
 
-      setlocale (LC_ALL, oldLocale);
-    }
+  setenv ("LANG", lang, 1);
 }

-- 
2.39.3 (Apple Git-145)