Setting locale at runtime

T

Torsten Bronger

Hallöchen!

I have to generate excerpts in different human languages in a
program. In general, the language is not the locale's language, but
set at runtime. Nevertheless, GNU's gettext should be used for the
excerpts. This means that I have to wrap calls to gettext() in a
function that sets the locale temporarily.

The problem is how to do that. Let's assume I need to generate
German snippets. Then I could say

setlocale (LC_MESSAGES, "de");

and

setlocale (LC_MESSAGES, "");

to reset it. However, this doesn't work on my computer. It wants
to see "de_DE". This, however, doesn't work on another computer
which insists on a plain "de". Even worse, I have a report of an
American developer that on his computer none of these variants had
any effect, although German messages were definitely installed.

Is there a reliable way of setting the locale?

Thank you!

Tschö,
Torsten.
 
D

David Resnick

Torsten said:
Hallöchen!

I have to generate excerpts in different human languages in a
program. In general, the language is not the locale's language, but
set at runtime. Nevertheless, GNU's gettext should be used for the
excerpts. This means that I have to wrap calls to gettext() in a
function that sets the locale temporarily.

The problem is how to do that. Let's assume I need to generate
German snippets. Then I could say

setlocale (LC_MESSAGES, "de");

and

setlocale (LC_MESSAGES, "");

to reset it. However, this doesn't work on my computer. It wants
to see "de_DE". This, however, doesn't work on another computer
which insists on a plain "de". Even worse, I have a report of an
American developer that on his computer none of these variants had
any effect, although German messages were definitely installed.

Is there a reliable way of setting the locale?

Thank you!

Tschö,
Torsten.

I don't know how gnu's gettext works, asking in a gnu newsgroup would
probably get you help there if there are things you might do to avoid
setlocale.

As to your question of setting a locale, the answer is not really.
Since the locale string's content is implementation dependent, you need
to cater to all implementations you want to support. There are
numerous ways you might do that. For example, you could have a
configuration file that has the locale strings for that implementation
for the languages you support, say one config file per implementation.
For example, you might have in your file parameters of the form
LOCALE_STRING_<ISO 2 letter country code><ISO 2 letter language code>

For one implementation
LOCALE_STRING_DEAT = de_AT

For a different one
LOCALE_STRING_DEAT = de_AT.iso885915@euro

And for yet another (ugh)
LOCALE_STRING_DEAT = german-austrian_aut.1252

Or you could put this in your code. For example, something like this:
typedef struct locale_info {
const char* locale;
const char* windows_locale;
const char* unix_locale; /* split as needed if different supported
unices differ */
} locale_info;

static locale_info info[] = {
{ "deat", "german-austrian_aut.1252", "de_AT" },
{ "dech", "german-swiss_che.1252", "de_CH" }
};

const char *get_locale(const char *locale)
{
unsigned i;
for (i = 0; i < sizeof info/sizeof info[0]; i++) {
if (strcmp(info.locale, locale) == 0) {
#ifdef _WIN32
return info.windows_locale;
#else
return info.unix_locale;
#endif
}
}
return NULL;
}

In this method as in the param method, you need some platform neutral
way of specifying the language (e.g. ISO 2 letter language and country
code). I think this isn't as nice as the config file approach. There
are probably other ideas as well, but these might help get you
started...

-David
 
B

Ben Pfaff

Torsten Bronger said:
Is there a reliable way of setting the locale?

Unfortunately, no. Names of locales are system dependent from
the viewpoint of standard C.
 
P

Peter Nilsson

Torsten said:
... Let's assume I need to generate German snippets. Then I could
say

setlocale (LC_MESSAGES, "de");

and

setlocale (LC_MESSAGES, "");

to reset it. However, this doesn't work on my computer. It wants
to see "de_DE". This, however, doesn't work on another computer
which insists on a plain "de". Even worse, I have a report of an
American developer that on his computer none of these variants
had any effect, although German messages were definitely
installed.

Is there a reliable way of setting the locale?

You could make your program accept a runtime preference, either
via an environment variable, or via command line argument, or
something else.

#include <stdio.h>
#include <locale.h>

int main(int argc, char **argv)
{
char *x;

if (argc == 2 && argv[1][0] != 0)
{
printf("setlocale(LC_ALL, \"%s\") : ", argv[1]);
x = setlocale(LC_ALL, argv[1]);
puts(x ? "ok" : "failed");
}

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top