Fix for 8.3 MSVC locale (Was [HACKERS] NLS on MSVC strikes back!)

From: "Gevik Babakhani" <pgdev(at)xs4all(dot)nl>
To: <pgsql-patches(at)postgresql(dot)org>
Subject: Fix for 8.3 MSVC locale (Was [HACKERS] NLS on MSVC strikes back!)
Date: 2008-02-14 15:47:09
Message-ID: 002001c86f20$dc8db450$0a01a8c0@gevmus
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-patches

Hereby a patch that fixes NLS support on PG 8.3 compiled with MSVC.

There problem:

NLS support does not work on PG 8.3 compiled with MSVC.
I encountered this bug when I was trying to show localized months and days
using TO_CHAR.

The main reason for this problem is because Gettext on Windows does not
respond to LC_MESSAGES environment variable. Changing this variable should
trigger Gettext to load a different messages catalog which unfortunately
does not work on Windows. Gettext uses the locale of the current thread in
execution to determine which message catalog should be loaded.

This is all discussed in:
http://archives.postgresql.org/pgsql-hackers/2008-02/msg00485.php

How it is fixed:

Changing the LC_MESSAGES is done in pg_locale.c::pg_perm_setlocale(int
category, const char *locale).
In order to force Gettext to load a messages catalog we have to call
WIN32API::SetThreadLocale(unsigned long locale_id)

(You probably see it coming)
Our input parameter for locale in pg_perm_setlocale is a string and there is
no unified way in Windows to translate a locale string to a locale_id for
SetThreadLocale to use. Therefore we will use a static table of values to
anticipate the locale name:

pg_win32_locale_database::{0x041b,{"sk","sk-SK","sk_SK","Slovak_Slovakia"}}

Given any of "sk","sk-SK","sk_SK".... the 0x041b is returned for
SetThreadLocale as input parameter.

(We are not quite done yet)
Gettext, internally uses a hack to force itself to reload. This hidden
feature is also explained in GetText docs. By incrementing a Gettext
internal variable (_nl_msg_cat_cntr) we force Gettext to reload on the next
LC_MESSAGES->MSGID query.

Tests:

- Tested on Win XP MSVC (VC++ 8.0)
- Just a routine "make check" test on my Linux box
- MINGW is not tested. (I do not have the installation)

Fix notes:

- Gettext behaves oddly when the env. variable LANGUAGE is set before
starting PG
- The locale names in the static table are case sensitive. 'nl_NL' !=
'NL_NL'
- At this moment I only have included locale names we actually support in PG
installation.
- Where are the JP locale .po and .mo files? These are not in sources!
- Even though there are 20+ locales in PG installation, does not mean those
are complete. Try TMMonth,TMDay on "nl_NL". You will get English names :)
(My fault, hee hee, I haven't completed nl.po translations yet.)

TODO:

- Provide/complete the day and month names for all supported locales.
- Create docs for supported locale names on Windows. (Values of the static
table)

Regards,
Gevik Babakhani
------------------------------------------------
PostgreSQL NL http://www.postgresql.nl
TrueSoftware BV http://www.truesoftware.nl
------------------------------------------------

Attachment Content-Type Size
1.pg_locale.c.patch application/octet-stream 4.7 KB
test_result.txt text/plain 2.2 KB

Responses

Browse pgsql-patches by date

  From Date Subject
Next Message Magnus Hagander 2008-02-14 16:09:14 Re: Fix for 8.3 MSVC locale (Was [HACKERS] NLS on MSVC strikes back!)
Previous Message Heikki Linnakangas 2008-02-14 15:40:23 Re: tzcode update