#include <locale.h>
#include "gettext.h"
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE,
LOCALEDIR);
textdomain (PACKAGE);
#include "gettext.h"
#define _(string) gettext (string)
$ for d in /usr/local/lib
/usr/lib /lib; do ls -l $d/libintl.*; done
$ grep
'\(INTLLIBS\|LIBINTL\)' config.status
$ gettext --version
$ gettext --help
$ ltrace ./myprog
...
setlocale(6,
"")
= "de_DE.UTF-8"
$ gdb ./myprog
(gdb) break main
(gdb) run
Breakpoint 1, main ()
(gdb) break setlocale
(gdb) continue
Breakpoint 2, setlocale ()
;; OK, the breakpoint has been hit, setlocale() is being
called.
$ ltrace ./myprog
...
textdomain("hello-c")
= "hello-c"
bindtextdomain("hello-c", "/opt/share"...) = "/opt/share"...
dcgettext(0, 0x08048691, 5, 0x0804a200, 0x08048689) =
0x4001721f
$ gdb ./myprog
(gdb) break main
(gdb) run
Breakpoint 1, main ()
(gdb) break textdomain
(gdb) break bindtextdomain
(gdb) break gettext
(gdb) break dgettext
(gdb) break dcgettext
(gdb) continue
Breakpoint 2, textdomain ()
(gdb) continue
Breakpoint 3, bindtextdomain ()
(gdb) continue
Breakpoint 6, dcgettext ()
$ strace ./myprog 2>&1
| grep '^open('
open("/etc/ld.so.preload", O_RDONLY) = -1
ENOENT (No such file or directory)
open("/etc/ld.so.cache",
O_RDONLY) = 5
open("/lib/libc.so.6",
O_RDONLY) = 5
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE)
= 5
open("/usr/share/locale/locale.alias", O_RDONLY) = 5
open("/opt/share/locale/de/LC_MESSAGES/hello-c.mo", O_RDONLY)
= 5
...
$ msgunfmt
localedir/lang/LC_MESSAGES/domain.mo
set LANG=de_DE
.\myprog.exe
$ env LANG=de_DE ./myprog.exe
#include <string.h>
#include <stdlib.h>
#if defined _WIN32
# include <windows.h>
#endif
int my_setenv (const char * name, const char * value) {
size_t namelen = strlen(name);
size_t valuelen = (value==NULL ? 0 : strlen(value));
#if defined _WIN32
/* On Woe32, each process has two copies of the
environment variables,
one managed by the OS and one
managed by the C library. We set
the value in both locations, so that
other software that looks in
one place or the other is guaranteed
to see the value. Even if it's
a bit slow. See also
<https://article.gmane.org/gmane.comp.gnu.mingw.user/8272>
<https://article.gmane.org/gmane.comp.gnu.mingw.user/8273>
<https://www.cygwin.com/ml/cygwin/1999-04/msg00478.html>
*/
if (!SetEnvironmentVariableA(name,value))
return -1;
#endif
#if defined(HAVE_PUTENV)
char* buffer = (char*)malloc(namelen+1+valuelen+1);
if (!buffer)
return -1; /* no need to set errno =
ENOMEM */
memcpy(buffer,name,namelen);
if (value != NULL) {
buffer[namelen] = '=';
memcpy(buffer+namelen+1,value,valuelen);
buffer[namelen+1+valuelen] = 0;
} else
buffer[namelen] = 0;
return putenv(buffer);
#elif defined(HAVE_SETENV)
return setenv(name,value,1);
#else
/* Uh oh, neither putenv() nor setenv() ... */
return -1;
#endif
}
setlocale (LC_MESSAGES, "");
then change it to
setlocale (LC_CTYPE, "");
setlocale (LC_MESSAGES, "");
setlocale (LC_ALL, "");
setlocale (LC_ALL, "");
In the LANGUAGE environment variable, but not in the LANG environment variable, LL_CC combinations can be abbreviated as LL to denote the language's main dialect.Why is LANG=en not allowed? Because LANG is a setting for the entire locale, including monetary information, and this depends on the country: en_GB, en_AU, en_ZA all have different currencies.
Last modified: 6 June 2020