diff options
Diffstat (limited to 'pc/gawkmisc.pc')
-rw-r--r-- | pc/gawkmisc.pc | 58 |
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. |