#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) runBreakpoint 1, main ()(gdb) break setlocale(gdb) continueBreakpoint 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) runBreakpoint 1, main ()(gdb) break textdomain(gdb) break bindtextdomain(gdb) break gettext(gdb) break dgettext(gdb) break dcgettext(gdb) continueBreakpoint 2, textdomain ()(gdb) continueBreakpoint 3, bindtextdomain ()(gdb) continueBreakpoint 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)      = 5open("/lib/libc.so.6",
O_RDONLY)        = 5open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE)
= 5open("/usr/share/locale/locale.alias", O_RDONLY) = 5open("/opt/share/locale/de/LC_MESSAGES/hello-c.mo", O_RDONLY)
= 5...$ msgunfmt localedir/lang/LC_MESSAGES/domain.moset LANG=de_DE.\myprog.exe$ env LANG=de_DE ./myprog.exe#include <string.h>#include <stdlib.h>#if defined _WIN32# include <windows.h>#endifint 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, "");
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