I am using an installed locale folder to get the messages for my application. When using an account name with international characters, the gettext library fails to load and convert the text strings.
Has anyone run into this before? Have a work-around?
I am using the UCRT64 environment in msys2.
Create a user account named: test Gergő and set up msys2.
In the test Gergő account:
cd "/c/Users/test Gergő"
mkdir -p locale/nl/LC_MESSAGES
cp /usr/share/locale/nl/LC_MESSAGES/sed.mo locale/nl/LC_MESSAGES/
cd
Using the following test code: ( I named it tt.c )
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <libintl.h>
#include <wchar.h>
#include <windows.h>
#define DOM "sed"
int
main (int argc, char *argv [])
{
wchar_t *wtmp;
char buff [512];
char tbuff [512];
char *tmp;
size_t len;
wtmp = _wgetenv (L"USERPROFILE");
// wtmp = _wgetenv (L"HOME");
len = WideCharToMultiByte (CP_UTF8, 0, wtmp, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte (CP_UTF8, 0, wtmp, -1, buff, len + 1, NULL, NULL);
wtmp [len] = L'\0';
sprintf (tbuff, "%s/locale", buff);
// or vice-versa. fails both ways.
// just to be sure the path is consistent.
for (int i = 0; i < strlen (tbuff); ++i) {
if (tbuff [i] == '\\') {
tbuff [i] = '/';
}
}
tmp = bindtextdomain (DOM, tbuff);
fprintf (stderr, "bind: %s\n", tmp);
tmp = textdomain (DOM);
fprintf (stderr, "text-dom: %s\n", tmp);
if (setlocale (LC_MESSAGES, tbuff) == NULL) {
fprintf (stderr, "set-locale failed\n");
}
_wputenv_s (L"LC_MESSAGES", L"nl.UTF-8");
tmp = gettext ("No match");
if (strcmp (tmp, "No match") == 0) {
fprintf (stderr, "NG %s\n", tmp);
} else {
fprintf (stderr, "OK %s\n", tmp);
}
return 0;
}
Compile:
cc -o tt tt.c -static -lintl -liconv
Run the program within a cmd.exe window:
C:\msys64\home\test Gergő\tt.exe
The string "No match" from sed.mo is not found.
bind: C:\Users\test Gergő\locale
text-dom: sed
NG No match
This works using account names of bll and test user .
The program can also be compiled to retrieve the HOME environment variable and run within msys2 (with the sample locale/ directory installed in the msys2 home). Again it fails with the test Gergő account and works with the bll and test user accounts.
Turns out that libintl includes a
wbindtextdomainfunction. I was digging through the gettext source code and found this. It is not documented in the manual pages, it is documented in the gettext info files.To get cmake to locate this function, I checked for the
libintl_wbindtextdomainfunction name.