Skip to content

Commit

Permalink
LocaleRes: Set the LC_MESSAGE environment variable when the system do…
Browse files Browse the repository at this point in the history
…es not support the setlocale setting.

Gettext assumes usage through environment variables when the system is not POSIX compliant. This also defaults the language to English on a related issue, because when we can't figure out the default system language, we can't then select the proper font.

The user has more options to set their language locale. The ConfigAdv setting for locale will now work on non-POSIX settings. The environment variable SKMESSAGES is now available non-POSIX situations as well.

This patch also does more prepping for a future menu to select the language in game.
  • Loading branch information
the3dfxdude committed Jul 22, 2023
1 parent 182f6bb commit 5144976
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 27 deletions.
3 changes: 2 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ CXXFLAGS="$save_CXXFLAGS"

# Checks for header files.
dnl AC_CHECK_HEADERS([])
gt_LC_MESSAGES

# Checks for typedefs, structures, and compiler characteristics.
AC_CANONICAL_HOST
Expand All @@ -95,7 +96,7 @@ AC_TYPE_UINT64_T
AC_TYPE_UINT8_T

# Checks for library functions.
AC_CHECK_FUNCS([_NSGetExecutablePath])
AC_CHECK_FUNCS_ONCE([_NSGetExecutablePath setenv])

AX_STRING_STRCASECMP
if test x"$ac_cv_string_strcasecmp" = "xno" ; then
Expand Down
4 changes: 3 additions & 1 deletion include/LocaleRes.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,13 @@ class LocaleRes

void init();
void deinit();
void load();
void load(const char *locale);

#ifdef ENABLE_NLS
const char *conv_str(iconv_t cd, const char *s);
#endif
const char *get_locale_dir();
const char *get_messages_locale();
};

extern LocaleRes locale_res;
Expand Down
35 changes: 35 additions & 0 deletions m4/lcmessage.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# lcmessage.m4 serial 8
dnl Copyright (C) 1995-2002, 2004-2005, 2008-2014, 2016, 2019-2023 Free
dnl Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Lesser General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Lesser General Public License, and the rest of the GNU
dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.

dnl Authors:
dnl Ulrich Drepper <[email protected]>, 1995.

# Check whether LC_MESSAGES is available in <locale.h>.

AC_DEFUN([gt_LC_MESSAGES],
[
AC_CACHE_CHECK([for LC_MESSAGES], [gt_cv_val_LC_MESSAGES],
[AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[[#include <locale.h>]],
[[return LC_MESSAGES]])],
[gt_cv_val_LC_MESSAGES=yes],
[gt_cv_val_LC_MESSAGES=no])])
if test $gt_cv_val_LC_MESSAGES = yes; then
AC_DEFINE([HAVE_LC_MESSAGES], [1],
[Define if your <locale.h> file defines LC_MESSAGES.])
fi
])
2 changes: 1 addition & 1 deletion src/AM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ int main(int argc, char **argv)
}
config_adv.init();
if( config_adv.locale[0] )
locale_res.load();
locale_res.load(config_adv.locale);

//----- read command line arguments -----//

Expand Down
127 changes: 103 additions & 24 deletions src/LocaleRes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,32 @@
//Filename : LocaleRes.cpp
//Description : Locale Resources

#include <stdlib.h>
#ifdef ENABLE_NLS
#include <libintl.h>
#include <locale.h>
#endif

#include <ALL.h>
#include <ODB.h>
#include <ConfigAdv.h>
#include <LocaleRes.h>


#ifndef HAVE_SETENV
static String lc_all_str;
int setenv(const char *name, const char *value, int overwrite)
{
if( !value )
return putenv(name);

lc_all_str = name;
lc_all_str += "=";
lc_all_str += value;
return putenv(lc_all_str);
}
#endif


//------------- End of function Constructor -------//
//
LocaleRes::LocaleRes()
Expand Down Expand Up @@ -65,16 +81,15 @@ LocaleRes::~LocaleRes()
void LocaleRes::init()
{
#ifdef ENABLE_NLS
const char *env_locale_dir;
if( misc.is_file_exist("locale") )
bindtextdomain(PACKAGE, "locale");
else if( env_locale_dir = getenv("SKLOCALE") )
bindtextdomain(PACKAGE, env_locale_dir);
else
bindtextdomain(PACKAGE, LOCALE_DIR);
const char *locale_dir;
locale_dir = get_locale_dir();
if( locale_dir )
{
bindtextdomain(PACKAGE, locale_dir);
}
textdomain(PACKAGE);

load();
setlocale(LC_ALL, "");
load(getenv("SKMESSAGES"));

in_buf = mem_add(INIT_BUF_SIZE+1);
in_buf_size = INIT_BUF_SIZE;
Expand Down Expand Up @@ -110,24 +125,37 @@ void LocaleRes::deinit()
//------------- End of function LocaleRes::deinit ---------//


//----------- Start of function LocaleRes::change_locale ---------//
//----------- Start of function LocaleRes::load ---------//
//
// Performs setlocale and initializes codeset conversion.
//
void LocaleRes::load()
void LocaleRes::load(const char *locale)
{
#ifdef ENABLE_NLS
const char *ctype;
if( config_adv.locale[0] )
if( locale && locale[0] )
{
if( !setlocale(LC_ALL, config_adv.locale) )
return;
ctype = config_adv.locale;
setlocale(LC_MESSAGES, locale);
setlocale(LC_CTYPE, locale);
#ifndef HAVE_LC_MESSAGES
// Gettext fakes the setlocale for LC_MESSAGES above via a
// wrapper, set the env var the same way since the var is
// actually used by gettext instead of the real setlocale.
setenv("LC_MESSAGES", locale, 1);
#endif
}
else
locale = get_messages_locale();

if( !locale || !locale[0] )
{
setlocale(LC_ALL, "");
ctype = setlocale(LC_CTYPE, NULL);
if( !ctype )
return;
// The platform doesn't have full POSIX localization, and the
// user did not specify a locale in the game config. Default to
// English. The reason why to do this is if gettext does end up
// mapping the locale internally, we don't know what font to
// use. English is a safe choice.
locale = "en_US";
setlocale(LC_MESSAGES, locale);
setlocale(LC_CTYPE, locale);
setenv("LC_MESSAGES", locale, 1);
}

LocaleRec *localeRec;
Expand All @@ -147,7 +175,7 @@ void LocaleRes::load()
localeRec = (LocaleRec*) dbLocale->read(i+1);

misc.rtrim_fld( lang, localeRec->lang, localeRec->LANG_LEN );
if( !misc.str_icmpx(ctype, lang) )
if( !misc.str_icmpx(locale, lang) )
continue;

misc.rtrim_fld( fontset, localeRec->fontset, localeRec->FONTSET_LEN );
Expand All @@ -173,7 +201,7 @@ void LocaleRes::load()
cd_from_sdl = iconv_open("ISO-8859-1//TRANSLIT//IGNORE", "UTF-8");
#endif
}
//------------- End of function LocaleRes::change_locale ---------//
//------------- End of function LocaleRes::load ---------//


#ifdef ENABLE_NLS
Expand Down Expand Up @@ -216,3 +244,54 @@ const char *LocaleRes::conv_str(iconv_t cd, const char *s)
return out_buf;
}
#endif


//-------- Begin of function LocaleRes::get_locale_dir -----------//
//
const char *LocaleRes::get_locale_dir()
{
if( misc.is_file_exist("locale") )
return "locale";
if( misc.is_file_exist(getenv("SKLOCALE")) )
return getenv("SKLOCALE");
#ifdef LOCALE_DIR
if( misc.is_file_exist(LOCALE_DIR) )
return LOCALE_DIR;
#endif
return NULL;
}
//---------- End of function LocaleRes::get_locale_dir ----------//


//-------- Begin of function LocaleRes::get_messages_locale -----------//
//
const char *LocaleRes::get_messages_locale()
{
const char *locale;

#ifdef HAVE_LC_MESSAGES
/* setlocale(LC_ALL, "") has been done previously */
locale = setlocale(LC_MESSAGES, NULL);
if( locale && locale[0] )
return locale;
#else /* Missing LC_MESSAGES */
// gettext uses the env vars on this platform
locale = getenv("LC_ALL");
if( locale && locale[0] )
return locale;

locale = getenv("LC_MESSAGES");
if( locale && locale[0] )
return locale;

locale = getenv("LANG");
if( locale && locale[0] )
return locale;
#endif
// We don't spend the time to map what Windows uses for locales. And
// some platforms don't have a POSIX setlocale, so if the user does not
// manually set an option in this case, we don't know the locale.

return NULL;
}
//---------- End of function LocaleRes::get_messages_locale ----------//

0 comments on commit 5144976

Please sign in to comment.