summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2017-01-21 17:31:04 +0200
committerEli Zaretskii <eliz@gnu.org>2017-01-21 17:31:04 +0200
commit0d5d4035201e38c5d61031ee414ca41c6f1c8bd3 (patch)
treea6eb871855389b7be3f05337f933638592838e42
parente3e911b992f11a567cca0a0ed6ed04ef5f9e21f7 (diff)
downloadgawk-0d5d4035201e38c5d61031ee414ca41c6f1c8bd3.tar.gz
Support LC_* environment variables in the MinGW build.
-rw-r--r--nonposix.h3
-rw-r--r--pc/ChangeLog5
-rw-r--r--pc/Makefile.tst62
-rw-r--r--pc/gawkmisc.pc58
4 files changed, 96 insertions, 32 deletions
diff --git a/nonposix.h b/nonposix.h
index cbc4f499..9a722dd9 100644
--- a/nonposix.h
+++ b/nonposix.h
@@ -56,6 +56,9 @@ unsigned int getegid (void);
int unsetenv (const char *);
int setenv (const char *, const char *, int);
void w32_maybe_set_errno (void);
+char *w32_setlocale (int, const char *);
+#define setlocale(c,v) w32_setlocale(c,v)
+
#endif /* __MINGW32__ */
#if defined(VMS) || defined(__DJGPP__) || defined(__MINGW32__)
diff --git a/pc/ChangeLog b/pc/ChangeLog
index bc2d6f37..093beb10 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,5 +1,10 @@
2017-01-21 Eli Zaretskii <eliz@gnu.org>
+ * Makefile.tst: Modify the locale values to valid ones on Windows.
+
+ * gawkmisc.pc: Undef setlocale and include locale.h.
+ (lc_var, w32_setlocale): New functions.
+
* Makefile (VAPTH): Set to allow Make to find sources in the
'support' subdirectory.
(CFLAGS): Add "-I./support", as some headers are there.
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index 4b869917..de4028e9 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -277,7 +277,7 @@ unix-tests: $(UNIX_TESTS)
gawk-extensions: $(GAWK_EXT_TESTS)
charset-tests-all:
- $(MAKE) charset-msg-start charset-tests charset-msg-end; \
+ $(MAKE) charset-msg-start charset-tests charset-msg-end
charset-tests: $(LOCALE_CHARSET_TESTS)
@@ -346,9 +346,7 @@ charset-msg-start:
@echo "======== Starting tests that can vary based on character set or locale support ========"
@echo "**************************************************************************"
@echo "* Some or all of these tests may fail if you have inadequate or missing *"
- @echo "* locale support. At least en_US.UTF-8, ru_RU.UTF-8 and ja_JP.UTF-8 are *"
- @echo "* needed. However, if you see this message, the Makefile thinks you have *"
- @echo "* what you need ... *"
+ @echo "* locale support... *"
@echo "**************************************************************************"
charset-msg-end:
@@ -368,7 +366,7 @@ mpfr-msg-end:
lc_num1:
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -671,49 +669,49 @@ rsnulbig2::
wideidx::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
wideidx2::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub2::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub3::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
widesub4::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
ignrcas2::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
subamp::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -756,7 +754,7 @@ rtlen01::
rtlenmb::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
"$(srcdir)"/rtlen.sh >_$@ || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -790,12 +788,12 @@ binmode1::
subi18n::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
+ @GAWKLOCALE=ENU_USA.1252 ; $(AWK) -f "$(srcdir)"/$@.awk > _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
concat4::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
+ @GAWKLOCALE=ENU_USA.1252 ; $(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in > _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
devfd1::
@@ -818,13 +816,13 @@ mixed1::
mtchi18n::
@echo $@
- @GAWKLOCALE=ru_RU.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=RUS_RUS.1251 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
reint2::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) --re-interval -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -836,33 +834,33 @@ localenl::
mbprintf1::
@echo $@
@echo Expect mbprintf1 to fail with DJGPP and MinGW.
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf2::
@echo $@
- @GAWKLOCALE=ja_JP.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=JPN_JPN.932 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf3::
@echo $@
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbprintf4::
@echo $@
@echo Expect mbprintf4 to fail with MinGW and DJGPP
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbfw1::
@echo $@
@echo Expect mbfw1 to fail with DJGPP and MinGW.
- @GAWKLOCALE=en_US.UTF-8 ; export GAWKLOCALE ; \
+ @GAWKLOCALE=ENU_USA.1252 ; export GAWKLOCALE ; \
$(AWK) -f "$(srcdir)"/$@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >> _$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -874,14 +872,14 @@ gsubtst6::
mbstr1::
@echo $@
@echo Expect mbstr1 to fail with MinGW.
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
mbstr2::
@echo $@
@echo Expect mbstr2 to fail with MinGW.
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -995,7 +993,7 @@ exit:
rri1::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk < "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -1201,7 +1199,7 @@ charasbytes:
# @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
# AWKPATH="$(srcdir)" $(AWK) -b -f $@.awk "$(srcdir)"/$@.in | \
# od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -b -v BINMODE=2 -f $@.awk "$(srcdir)"/$@.in | \
od -c -t x1 | tr ' ' ' ' | sed -e 's/ */ /g' -e 's/ *$$//' >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -1244,7 +1242,7 @@ clos1way:
dfamb1:
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -1256,20 +1254,20 @@ randtest::
backbigs1:
@echo $@
@echo Expect backbigs1 to fail with MinGW and DJGPP
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
backsmalls1:
@echo $@
@echo Expect backsmalls1 to fail with MinGW and DJGPP
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
backsmalls2:
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk "$(srcdir)"/$@.in >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
@@ -1282,7 +1280,7 @@ dbugeval::
printhuge::
@echo $@
- @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=en_US.UTF-8; \
+ @[ -z "$$GAWKLOCALE" ] && GAWKLOCALE=ENU_USA.1252; \
AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 817e8167..526c49ff 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, comlain
+ 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.