aboutsummaryrefslogtreecommitdiffstats
path: root/pc/gawkmisc.pc
diff options
context:
space:
mode:
Diffstat (limited to 'pc/gawkmisc.pc')
-rw-r--r--pc/gawkmisc.pc58
1 files changed, 58 insertions, 0 deletions
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 817e8167..c6c92a46 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -619,6 +619,64 @@ wctob (wint_t wc)
return EOF;
}
+
+#undef setlocale
+#include <locale.h>
+
+/* On Posix systems, 'setlocale' looks at LC_* variables in the
+ environment, and Gawk users might expect that on Windows as well.
+ The replacement implementation below does that, and also fixes a
+ few additional quirks with locales on Windows. */
+static const char *
+lc_var (int category)
+{
+ static const char *loc_name[LC_MAX - LC_MIN + 1] = {
+ "LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME"
+ };
+
+ /* This function assumes LC_* categories are small numbers between 0
+ and 5, as shown above, so if that changes at some point, complain
+ vociferously. */
+ if (LC_ALL != 0 || LC_CTYPE != 2 || LC_TIME != 5)
+ abort ();
+ /* Ensured by the caller, so should never happen. */
+ if (category < LC_MIN || category > LC_MAX)
+ return "????";
+ return loc_name[category];
+}
+
+char *
+w32_setlocale (int category, const char *value)
+{
+ const char *new_locale = value;
+
+ if (LC_MIN <= category && category <= LC_MAX
+ && value && *value == '\0')
+ {
+ const char *lc_val = getenv ("LC_ALL");
+
+ if (!lc_val)
+ lc_val = getenv (lc_var (category));
+ if (!lc_val)
+ lc_val = getenv ("LANG");
+ if (lc_val)
+ new_locale = lc_val;
+ }
+
+ /* If VALUE includes a codeset, i.e. a Windows codepage number, we
+ must also set the LC_CTYPE locale to the same value, because
+ LC_CTYPE is the only category which is documented to be able to
+ change the codepage. */
+ if (category != LC_ALL && category != LC_CTYPE)
+ {
+ const char *p = strchr (new_locale, '.');
+
+ if (p && isdigit (p[1]))
+ setlocale (LC_CTYPE, new_locale);
+ }
+ return setlocale (category, new_locale);
+}
+
/*
* On MS-Windows with MinGW, execvp causes the shell and the re-exec'ed
* dgawk to compete for the keyboard input.