From c486040220e07f2d9fbf45fe6b74f46b669553dc Mon Sep 17 00:00:00 2001
From: Peter Stephenson
Date: Tue, 5 May 2020 20:28:31 +0100
Subject: 45772: Restore locale on parameter scope end.
Check if relevant parameters changes and if so restore system settings.
---
ChangeLog | 5 +++++
Src/params.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index c2cd48943..aa17d136a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2020-05-05 Peter Stephenson
+
+ * 45772: Src/params.c: Upon restoring locale variables, restore
+ the corresponding system settings.
+
2020-05-23 Jun-ichi Takimoto
* unposted: Src/Builtins/rlimits.c: add a comment about how to
diff --git a/Src/params.c b/Src/params.c
index 863b32600..122f5da7d 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -5569,6 +5569,14 @@ startparamscope(void)
locallevel++;
}
+#ifdef USE_LOCALE
+/*
+ * Flag that one of the special LC_ functions or LANG changed on scope
+ * end
+ */
+static int lc_update_needed;
+#endif /* USE_LOCALE */
+
/* End a parameter scope: delete the parameters local to the scope. */
/**/
@@ -5579,7 +5587,28 @@ endparamscope(void)
locallevel--;
/* This pops anything from a higher locallevel */
saveandpophiststack(0, HFILE_USE_OPTIONS);
+#ifdef USE_LOCALE
+ lc_update_needed = 0;
+#endif
scanhashtable(paramtab, 0, 0, 0, scanendscope, 0);
+#ifdef USE_LOCALE
+ if (lc_update_needed)
+ {
+ /* Locale changed --- ensure it is restored. */
+ char *val;
+ if ((val = getsparam_u("LC_ALL")) && *val) {
+ setlocale(LC_ALL, val);
+ } else {
+ struct localename *ln;
+ if ((val = getsparam_u("LANG")) && *val)
+ setlang(val);
+ for (ln = lc_names; ln->name; ln++) {
+ if ((val = getsparam_u(ln->name)) && *val)
+ setlocale(ln->category, val);
+ }
+ }
+ }
+#endif /* USE_LOCALE */
unqueue_signals();
}
@@ -5600,6 +5629,11 @@ scanendscope(HashNode hn, UNUSED(int flags))
*/
Param tpm = pm->old;
+#ifdef USE_LOCALE
+ if (!strncmp(pm->node.nam, "LC_", 3) ||
+ !strcmp(pm->node.nam, "LANG"))
+ lc_update_needed = 1;
+#endif
if (!strcmp(pm->node.nam, "SECONDS"))
{
setsecondstype(pm, PM_TYPE(tpm->node.flags), PM_TYPE(pm->node.flags));
--
cgit 1.4.1