aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/pg_locale.c68
-rw-r--r--src/bin/initdb/initdb.c12
-rw-r--r--src/port/chklocale.c43
-rw-r--r--src/port/win32env.c6
-rw-r--r--src/tools/msvc/MSBuildProject.pm44
-rw-r--r--src/tools/msvc/README9
-rw-r--r--src/tools/msvc/Solution.pm31
-rw-r--r--src/tools/msvc/VSObjectFactory.pm14
-rw-r--r--src/tools/msvc/build.pl2
-rw-r--r--src/tools/msvc/gendef.pl1
10 files changed, 200 insertions, 30 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 8fe824b426e..890aa198167 100644
--- a/src/backend/utils/adt/pg_locale.c
+++ b/src/backend/utils/adt/pg_locale.c
@@ -715,12 +715,41 @@ cache_locale_time(void)
#if defined(WIN32) && defined(LC_MESSAGES)
/*
- * Convert Windows locale name to the ISO formatted one
- * if possible.
+ * Convert a Windows setlocale() argument to a Unix-style one.
*
- * This function returns NULL if conversion is impossible,
- * otherwise returns the pointer to a static area which
- * contains the iso formatted locale name.
+ * Regardless of platform, we install message catalogs under a Unix-style
+ * LL[_CC][.ENCODING][@VARIANT] naming convention. Only LC_MESSAGES settings
+ * following that style will elicit localized interface strings.
+ *
+ * Before Visual Studio 2012 (msvcr110.dll), Windows setlocale() accepted "C"
+ * (but not "c") and strings of the form <Language>[_<Country>][.<CodePage>],
+ * case-insensitive. setlocale() returns the fully-qualified form; for
+ * example, setlocale("thaI") returns "Thai_Thailand.874". Internally,
+ * setlocale() and _create_locale() select a "locale identifier"[1] and store
+ * it in an undocumented _locale_t field. From that LCID, we can retrieve the
+ * ISO 639 language and the ISO 3166 country. Character encoding does not
+ * matter, because the server and client encodings govern that.
+ *
+ * Windows Vista introduced the "locale name" concept[2], closely following
+ * RFC 4646. Locale identifiers are now deprecated. Starting with Visual
+ * Studio 2012, setlocale() accepts locale names in addition to the strings it
+ * accepted historically. It does not standardize them; setlocale("Th-tH")
+ * returns "Th-tH". setlocale(category, "") still returns a traditional
+ * string. Furthermore, msvcr110.dll changed the undocumented _locale_t
+ * content to carry locale names instead of locale identifiers.
+ *
+ * MinGW headers declare _create_locale(), but msvcrt.dll lacks that symbol.
+ * IsoLocaleName() always fails in a MinGW-built postgres.exe, so only
+ * Unix-style values of the lc_messages GUC can elicit localized messages. In
+ * particular, every lc_messages setting that initdb can select automatically
+ * will yield only C-locale messages. XXX This could be fixed by running the
+ * fully-qualified locale name through a lookup table.
+ *
+ * This function returns a pointer to a static buffer bearing the converted
+ * name or NULL if conversion fails.
+ *
+ * [1] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373763.aspx
+ * [2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373814.aspx
*/
static char *
IsoLocaleName(const char *winlocname)
@@ -739,6 +768,34 @@ IsoLocaleName(const char *winlocname)
loct = _create_locale(LC_CTYPE, winlocname);
if (loct != NULL)
{
+#if (_MSC_VER >= 1700) /* Visual Studio 2012 or later */
+ size_t rc;
+ char *hyphen;
+
+ /* Locale names use only ASCII, any conversion locale suffices. */
+ rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE],
+ sizeof(iso_lc_messages), NULL);
+ _free_locale(loct);
+ if (rc == -1 || rc == sizeof(iso_lc_messages))
+ return NULL;
+
+ /*
+ * Since the message catalogs sit on a case-insensitive filesystem, we
+ * need not standardize letter case here. So long as we do not ship
+ * message catalogs for which it would matter, we also need not
+ * translate the script/variant portion, e.g. uz-Cyrl-UZ to
+ * uz_UZ@cyrillic. Simply replace the hyphen with an underscore.
+ *
+ * Note that the locale name can be less-specific than the value we
+ * would derive under earlier Visual Studio releases. For example,
+ * French_France.1252 yields just "fr". This does not affect any of
+ * the country-specific message catalogs available as of this writing
+ * (pt_BR, zh_CN, zh_TW).
+ */
+ hyphen = strchr(iso_lc_messages, '-');
+ if (hyphen)
+ *hyphen = '_';
+#else
char isolang[32],
isocrty[32];
LCID lcid;
@@ -753,6 +810,7 @@ IsoLocaleName(const char *winlocname)
if (!GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, isocrty, sizeof(isocrty)))
return NULL;
snprintf(iso_lc_messages, sizeof(iso_lc_messages) - 1, "%s_%s", isolang, isocrty);
+#endif
return iso_lc_messages;
}
return NULL;
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 1bba4268a5a..b75d9768561 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -935,14 +935,22 @@ find_matching_ts_config(const char *lc_type)
/*
* Convert lc_ctype to a language name by stripping everything after an
- * underscore. Just for paranoia, we also stop at '.' or '@'.
+ * underscore (usual case) or a hyphen (Windows "locale name"; see
+ * comments at IsoLocaleName()).
+ *
+ * XXX Should ' ' be a stop character? This would select "norwegian" for
+ * the Windows locale "Norwegian (Nynorsk)_Norway.1252". If we do so, we
+ * should also accept the "nn" and "nb" Unix locales.
+ *
+ * Just for paranoia, we also stop at '.' or '@'.
*/
if (lc_type == NULL)
langname = pg_strdup("");
else
{
ptr = langname = pg_strdup(lc_type);
- while (*ptr && *ptr != '_' && *ptr != '.' && *ptr != '@')
+ while (*ptr &&
+ *ptr != '_' && *ptr != '-' && *ptr != '.' && *ptr != '@')
ptr++;
*ptr = '\0';
}
diff --git a/src/port/chklocale.c b/src/port/chklocale.c
index 7e2062c6bb3..9e889383f26 100644
--- a/src/port/chklocale.c
+++ b/src/port/chklocale.c
@@ -189,26 +189,49 @@ static const struct encoding_match encoding_match_list[] = {
#ifdef WIN32
/*
- * On Windows, use CP<codepage number> instead of the nl_langinfo() result
+ * On Windows, use CP<code page number> instead of the nl_langinfo() result
+ *
+ * Visual Studio 2012 expanded the set of valid LC_CTYPE values, so have its
+ * locale machinery determine the code page. See comments at IsoLocaleName().
+ * For other compilers, follow the locale's predictable format.
+ *
+ * Returns a malloc()'d string for the caller to free.
*/
static char *
win32_langinfo(const char *ctype)
{
- char *r;
+ char *r = NULL;
+
+#if (_MSC_VER >= 1700)
+ _locale_t loct = NULL;
+
+ loct = _create_locale(LC_CTYPE, ctype);
+ if (loct != NULL)
+ {
+ r = malloc(16); /* excess */
+ if (r != NULL)
+ sprintf(r, "CP%u", loct->locinfo->lc_codepage);
+ _free_locale(loct);
+ }
+#else
char *codepage;
- int ln;
/*
* Locale format on Win32 is <Language>_<Country>.<CodePage> . For
- * example, English_USA.1252.
+ * example, English_United States.1252.
*/
codepage = strrchr(ctype, '.');
- if (!codepage)
- return NULL;
- codepage++;
- ln = strlen(codepage);
- r = malloc(ln + 3);
- sprintf(r, "CP%s", codepage);
+ if (codepage != NULL)
+ {
+ int ln;
+
+ codepage++;
+ ln = strlen(codepage);
+ r = malloc(ln + 3);
+ if (r != NULL)
+ sprintf(r, "CP%s", codepage);
+ }
+#endif
return r;
}
diff --git a/src/port/win32env.c b/src/port/win32env.c
index 5f0f6f98599..b5f4e8e6d66 100644
--- a/src/port/win32env.c
+++ b/src/port/win32env.c
@@ -61,6 +61,12 @@ pgwin32_putenv(const char *envval)
"msvcr90", 0, NULL
}, /* Visual Studio 2008 */
{
+ "msvcr100", 0, NULL
+ }, /* Visual Studio 2010 */
+ {
+ "msvcr110", 0, NULL
+ }, /* Visual Studio 2012 */
+ {
NULL, 0, NULL
}
};
diff --git a/src/tools/msvc/MSBuildProject.pm b/src/tools/msvc/MSBuildProject.pm
index 2e3eab6599d..0cafd717a2b 100644
--- a/src/tools/msvc/MSBuildProject.pm
+++ b/src/tools/msvc/MSBuildProject.pm
@@ -1,7 +1,7 @@
package MSBuildProject;
#
-# Package that encapsulates a MSBuild (Visual C++ 2010) project file
+# Package that encapsulates a MSBuild project file (Visual C++ 2010 or greater)
#
# src/tools/msvc/MSBuildProject.pm
#
@@ -397,4 +397,46 @@ sub new
return $self;
}
+package VC2012Project;
+
+#
+# Package that encapsulates a Visual C++ 2012 project file
+#
+
+use strict;
+use warnings;
+use base qw(MSBuildProject);
+
+sub new
+{
+ my $classname = shift;
+ my $self = $classname->SUPER::_new(@_);
+ bless($self, $classname);
+
+ $self->{vcver} = '11.00';
+
+ return $self;
+}
+
+# This override adds the <PlatformToolset> element
+# to the PropertyGroup labeled "Configuration"
+sub WriteConfigurationPropertyGroup
+{
+ my ($self, $f, $cfgname, $p) = @_;
+ my $cfgtype =
+ ($self->{type} eq "exe")
+ ?'Application'
+ :($self->{type} eq "dll"?'DynamicLibrary':'StaticLibrary');
+
+ print $f <<EOF;
+ <PropertyGroup Condition="'\$(Configuration)|\$(Platform)'=='$cfgname|$self->{platform}'" Label="Configuration">
+ <ConfigurationType>$cfgtype</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>$p->{wholeopt}</WholeProgramOptimization>
+ <PlatformToolset>v110</PlatformToolset>
+ </PropertyGroup>
+EOF
+}
+
1;
diff --git a/src/tools/msvc/README b/src/tools/msvc/README
index 3b2939ad686..b61ddb87913 100644
--- a/src/tools/msvc/README
+++ b/src/tools/msvc/README
@@ -92,10 +92,11 @@ These configuration arguments are passed over to Mkvcbuild::mkvcbuild
(Mkvcbuild.pm) which creates the Visual Studio project and solution files.
It does this by using VSObjectFactory::CreateSolution to create an object
implementing the Solution interface (this could be either a VS2005Solution,
-a VS2008Solution or a VS2010Solution, all in Solution.pm, depending on the
-user's build environment) and adding objects implementing the corresponding
-Project interface (VC2005Project or VC2008Project from VCBuildProject.pm or
-VC2010Project from MSBuildProject.pm) to it.
+a VS2008Solution, a VS2010Solution or a VS2012Solution, all in Solution.pm,
+depending on the user's build environment) and adding objects implementing
+the corresponding Project interface (VC2005Project or VC2008Project from
+VCBuildProject.pm or VC2010Project or VC2012Project from MSBuildProject.pm)
+to it.
When Solution::Save is called, the implementations of Solution and Project
save their content in the appropriate format.
The final step of starting the appropriate build program (msbuild or vcbuild)
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 850a1dfabcf..e271ac8d9be 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -63,13 +63,12 @@ sub DeterminePlatform
{
my $self = shift;
- # Determine if we are in 32 or 64-bit mode. Do this by seeing if CL has
- # 64-bit only parameters.
+ # Examine CL help output to determine if we are in 32 or 64-bit mode.
$self->{platform} = 'Win32';
- open(P, "cl /? 2>NUL|") || die "cl command not found";
+ open(P, "cl /? 2>&1 |") || die "cl command not found";
while (<P>)
{
- if (/^\/favor:</)
+ if (/^\/favor:<.+AMD64/)
{
$self->{platform} = 'x64';
last;
@@ -700,4 +699,28 @@ sub new
return $self;
}
+package VS2012Solution;
+
+#
+# Package that encapsulates a Visual Studio 2012 solution file
+#
+
+use Carp;
+use strict;
+use warnings;
+use base qw(Solution);
+
+sub new
+{
+ my $classname = shift;
+ my $self = $classname->SUPER::_new(@_);
+ bless($self, $classname);
+
+ $self->{solutionFileVersion} = '12.00';
+ $self->{vcver} = '11.00';
+ $self->{visualStudioName} = 'Visual Studio 2012';
+
+ return $self;
+}
+
1;
diff --git a/src/tools/msvc/VSObjectFactory.pm b/src/tools/msvc/VSObjectFactory.pm
index c3aa33ec24f..0fbf3faa0ed 100644
--- a/src/tools/msvc/VSObjectFactory.pm
+++ b/src/tools/msvc/VSObjectFactory.pm
@@ -41,6 +41,10 @@ sub CreateSolution
{
return new VS2010Solution(@_);
}
+ elsif ($visualStudioVersion eq '11.00')
+ {
+ return new VS2012Solution(@_);
+ }
else
{
croak "The requested Visual Studio version is not supported.";
@@ -68,6 +72,10 @@ sub CreateProject
{
return new VC2010Project(@_);
}
+ elsif ($visualStudioVersion eq '11.00')
+ {
+ return new VC2012Project(@_);
+ }
else
{
croak "The requested Visual Studio version is not supported.";
@@ -82,7 +90,7 @@ sub DetermineVisualStudioVersion
{
# Determine version of nmake command, to set proper version of visual studio
-# we use nmake as it has existed for a long time and still exists in visual studio 2010
+# we use nmake as it has existed for a long time and still exists in current visual studio versions
open(P, "nmake /? 2>&1 |")
|| croak
"Unable to determine Visual Studio version: The nmake command wasn't found.";
@@ -107,11 +115,11 @@ sub DetermineVisualStudioVersion
sub _GetVisualStudioVersion
{
my ($major, $minor) = @_;
- if ($major > 10)
+ if ($major > 11)
{
carp
"The determined version of Visual Studio is newer than the latest supported version. Returning the latest supported version instead.";
- return '10.00';
+ return '11.00';
}
elsif ($major < 6)
{
diff --git a/src/tools/msvc/build.pl b/src/tools/msvc/build.pl
index 8979402d4c1..c947bbe318e 100644
--- a/src/tools/msvc/build.pl
+++ b/src/tools/msvc/build.pl
@@ -50,7 +50,7 @@ elsif ($ARGV[0] ne "RELEASE")
# ... and do it
-if ($buildwhat and $vcver eq '10.00')
+if ($buildwhat and $vcver >= 10.00)
{
system(
"msbuild $buildwhat.vcxproj /verbosity:detailed /p:Configuration=$bconf");
diff --git a/src/tools/msvc/gendef.pl b/src/tools/msvc/gendef.pl
index ab65c46cfae..8ef0422df9d 100644
--- a/src/tools/msvc/gendef.pl
+++ b/src/tools/msvc/gendef.pl
@@ -40,6 +40,7 @@ while (<$ARGV[0]/*.obj>)
next if $pieces[6] =~ /^\(/;
next if $pieces[6] =~ /^__real/;
next if $pieces[6] =~ /^__imp/;
+ next if $pieces[6] =~ /^__xmm/;
next if $pieces[6] =~ /NULL_THUNK_DATA$/;
next if $pieces[6] =~ /^__IMPORT_DESCRIPTOR/;
next if $pieces[6] =~ /^__NULL_IMPORT/;