Clean up FbTk::I18n API

Move private stuff into FbTk/I18n.cc.
This commit is contained in:
Mathias Gumz 2015-01-31 12:04:30 +01:00
parent f8b9c9a211
commit 0a87632032
5 changed files with 109 additions and 137 deletions

View file

@ -35,38 +35,96 @@
#include <X11/Xlocale.h> #include <X11/Xlocale.h>
#ifdef HAVE_CSTDLIB #include <cstdlib>
#include <cstdlib> #include <cstring>
#else
#include <stdlib.h>
#endif
#ifdef HAVE_CSTRING
#include <cstring>
#else
#include <string.h>
#endif
#ifdef HAVE_CSTDIO
#include <cstdio>
#else
#include <stdio.h>
#endif
#include <iostream> #include <iostream>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif // HAVE_LOCALE_H
#ifdef HAVE_NL_TYPES_H
// this is needed for linux libc5 systems
extern "C" {
#include <nl_types.h>
}
#elif defined(__CYGWIN__) || defined(__EMX__) || defined(__APPLE__)
extern "C" {
typedef int nl_catd;
char *catgets(nl_catd cat, int set_number, int message_number, char *message);
nl_catd catopen(char *name, int flag);
void catclose(nl_catd cat);
}
#endif // HAVE_NL_TYPES_H
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using std::string; using std::string;
namespace FbTk { namespace {
const nl_catd INVALID_CATALOG = ((nl_catd)(-1));
nl_catd s_catalog_fd = INVALID_CATALOG;
void NLSInit(const char *catalog) {
FbStringUtil::init();
I18n *i18n = I18n::instance();
i18n->openCatalog(catalog);
} }
I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd)(-1)) { namespace FbTk {
void I18n::init(const char* catalog) {
static bool init = false;
if (init) {
return;
}
#if defined(NLS) && defined(HAVE_CATOPEN)
FbStringUtil::init();
I18n& i18n = I18n::instance();
string filename = LOCALEPATH;
filename += '/';
filename += i18n.m_locale;
filename += '/';
filename += catalog;
if (!FileUtil::isRegularFile(filename.c_str()) && i18n.m_locale != "C" && FbStringUtil::haveUTF8()) {
// try the UTF-8 catalog, this also picks up situations where
// the codeset somehow isn't specified
// remove everything after @
string::size_type index = i18n.m_locale.find('.');
// erase all characters starting at index
if (index != string::npos)
i18n.m_locale.erase(index);
i18n.m_locale.append(".UTF-8");
i18n.m_utf8_translate = true;
filename = LOCALEPATH;
filename += '/';
filename += i18n.m_locale;
filename += '/';
filename += catalog;
}
#ifdef MCLoadBySet
s_catalog_fd = catopen(filename.c_str(), MCLoadBySet);
#else // !MCLoadBySet
s_catalog_fd = catopen(filename.c_str(), NL_CAT_LOCALE);
#endif // MCLoadBySet
if (s_catalog_fd == INVALID_CATALOG) {
cerr<<"Warning: Failed to open file("<<filename<<")"<<endl
<<"for translation, using default messages."<<endl;
}
#endif // HAVE_CATOPEN
}
I18n::I18n():m_multibyte(false), m_utf8_translate(false) {
#if defined(HAVE_SETLOCALE) && defined(NLS) #if defined(HAVE_SETLOCALE) && defined(NLS)
//make sure we don't get 0 to m_locale string //make sure we don't get 0 to m_locale string
char *temp = setlocale(LC_MESSAGES, ""); char *temp = setlocale(LC_MESSAGES, "");
@ -79,7 +137,7 @@ I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd)
#if defined(HAVE_SETLOCALE) && defined(NLS) #if defined(HAVE_SETLOCALE) && defined(NLS)
} else { } else {
setlocale(LC_TIME, ""); setlocale(LC_TIME, "");
// MB_CUR_MAX returns the size of a char in the current locale // MB_CUR_MAX returns the size of a char in the current locale
@ -91,11 +149,11 @@ I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd)
// remove everything after @ // remove everything after @
string::size_type index = m_locale.find('@'); string::size_type index = m_locale.find('@');
if (index != string::npos) if (index != string::npos)
m_locale.erase(index); //erase all characters starting at index m_locale.erase(index); //erase all characters starting at index
// remove everything before = // remove everything before =
index = m_locale.find('='); index = m_locale.find('=');
if (index != string::npos) if (index != string::npos)
m_locale.erase(0,index+1); //erase all characters starting up to index m_locale.erase(0,index+1); //erase all characters starting up to index
} }
#endif // defined(HAVE_SETLOCALE) && defined(NLS) #endif // defined(HAVE_SETLOCALE) && defined(NLS)
} }
@ -104,83 +162,36 @@ I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd)
I18n::~I18n() { I18n::~I18n() {
#if defined(NLS) && defined(HAVE_CATCLOSE) #if defined(NLS) && defined(HAVE_CATCLOSE)
if (m_catalog_fd != (nl_catd)-1) if (s_catalog_fd != (nl_catd)-1)
catclose(m_catalog_fd); catclose(s_catalog_fd);
#endif // HAVE_CATCLOSE #endif // HAVE_CATCLOSE
} }
I18n *I18n::instance() { I18n& I18n::instance() {
static I18n singleton; //singleton object static I18n singleton; //singleton object
return &singleton; return singleton;
} }
void I18n::openCatalog(const char *catalog) { // Translate_FB means it'll become an FbString that goes to X for Fonts,
#if defined(NLS) && defined(HAVE_CATOPEN)
string catalog_filename = LOCALEPATH;
catalog_filename += '/';
catalog_filename += m_locale;
catalog_filename += '/';
catalog_filename += catalog;
if (!FileUtil::isRegularFile(catalog_filename.c_str()) && m_locale != "C" && FbStringUtil::haveUTF8()) {
// try the UTF-8 catalog, this also picks up situations where
// the codeset somehow isn't specified
// remove everything after @
string::size_type index = m_locale.find('.');
// erase all characters starting at index
if (index != string::npos)
m_locale.erase(index);
m_locale.append(".UTF-8");
m_utf8_translate = true;
catalog_filename = LOCALEPATH;
catalog_filename += '/';
catalog_filename += m_locale;
catalog_filename += '/';
catalog_filename += catalog;
}
#ifdef MCLoadBySet
m_catalog_fd = catopen(catalog_filename.c_str(), MCLoadBySet);
#else // !MCLoadBySet
m_catalog_fd = catopen(catalog_filename.c_str(), NL_CAT_LOCALE);
#endif // MCLoadBySet
if (m_catalog_fd == (nl_catd)-1) {
cerr<<"Warning: Failed to open file("<<catalog_filename<<")"<<endl;
cerr<<"for translation, using default messages."<<endl;
}
#else // !HAVE_CATOPEN
m_catalog_fd = (nl_catd)-1;
#endif // HAVE_CATOPEN
}
// Translate_FB means it'll become an FbString that goes to X for Fonts,
// No translate means it stays in the local encoding, for printing to the // No translate means it stays in the local encoding, for printing to the
// console. // console.
FbString I18n::getMessage(int set_number, int message_number, FbString I18n::getMessage(int set_number, int message_number,
const char *default_message, bool translate_fb) const { const char *default_message, bool translate_fb) const {
#if defined(NLS) && defined(HAVE_CATGETS) #if defined(NLS) && defined(HAVE_CATGETS)
if (m_catalog_fd != (nl_catd)-1) { if (s_catalog_fd != INVALID_CATALOG) {
const char *ret = catgets(m_catalog_fd, set_number, message_number, default_message); const char *ret = catgets(s_catalog_fd, set_number, message_number, default_message);
// can't translate, leave it in raw ascii (utf-8 compatible) // can't translate, leave it in raw ascii (utf-8 compatible)
if (ret == default_message || ret == NULL) if (ret == default_message || ret == NULL)
return default_message; return default_message;
if (!m_utf8_translate && translate_fb) if (!m_utf8_translate && translate_fb)
// Local input, UTF-8 output // Local input, UTF-8 output
return FbStringUtil::LocaleStrToFb(ret); return FbStringUtil::LocaleStrToFb(ret);
else if (m_utf8_translate && !translate_fb) else if (m_utf8_translate && !translate_fb)
// UTF-8 input, local output // UTF-8 input, local output
return FbStringUtil::FbStrToLocale(ret); return FbStringUtil::FbStrToLocale(ret);
else else
// UTF-8 input, UTF-8 output OR // UTF-8 input, UTF-8 output OR
// local input, local output // local input, local output
return ret; return ret;

View file

@ -30,33 +30,10 @@
#include "FbString.hh" #include "FbString.hh"
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif // HAVE_LOCALE_H
#ifdef HAVE_NL_TYPES_H
// this is needed for linux libc5 systems
extern "C" {
#include <nl_types.h>
}
#elif defined(__CYGWIN__) || defined(__EMX__) || defined(__APPLE__)
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef int nl_catd;
char *catgets(nl_catd cat, int set_number, int message_number, char *message);
nl_catd catopen(char *name, int flag);
void catclose(nl_catd cat);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // HAVE_NL_TYPES_H
// Some defines to help out // Some defines to help out
#ifdef NLS #ifdef NLS
#define _FB_USES_NLS \ #define _FB_USES_NLS \
FbTk::I18n &i18n = *FbTk::I18n::instance() FbTk::I18n &i18n = FbTk::I18n::instance()
// ignore the description, it's for helping translators // ignore the description, it's for helping translators
@ -97,27 +74,23 @@ namespace FbTk {
class I18n { class I18n {
public: public:
static I18n *instance();
static void init(const char*);
static I18n& instance();
const char *getLocale() const { return m_locale.c_str(); } const char *getLocale() const { return m_locale.c_str(); }
bool multibyte() const { return m_multibyte; } bool multibyte() const { return m_multibyte; }
const nl_catd &getCatalogFd() const { return m_catalog_fd; }
FbString getMessage(int set_number, int message_number, FbString getMessage(int set_number, int message_number,
const char *default_messsage = 0, bool translate_fb = false) const; const char *default_messsage = 0, bool translate_fb = false) const;
void openCatalog(const char *catalog);
private: private:
I18n(); I18n();
~I18n(); ~I18n();
std::string m_locale; std::string m_locale;
bool m_multibyte, m_utf8_translate; bool m_multibyte;
nl_catd m_catalog_fd; bool m_utf8_translate;
}; };
void NLSInit(const char *);
} // end namespace FbTk } // end namespace FbTk
#endif // I18N_HH #endif // I18N_HH

View file

@ -158,7 +158,7 @@ void setupSignalHandling() {
int main(int argc, char **argv) { int main(int argc, char **argv) {
FbTk::NLSInit("fluxbox.cat"); FbTk::I18n::init("fluxbox.cat");
FluxboxCli::Options opts; FluxboxCli::Options opts;
int exitcode = opts.parse(argc, argv); int exitcode = opts.parse(argc, argv);

View file

@ -28,21 +28,9 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#ifdef HAVE_CSTRING #include <cstring>
#include <cstring> #include <cstdlib>
#else #include <cstdio>
#include <string.h>
#endif
#ifdef HAVE_CSTDLIB
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#ifdef HAVE_CSTDIO
#include <cstdio>
#else
#include <stdio.h>
#endif
#include <iostream> #include <iostream>
using std::cout; using std::cout;
@ -382,7 +370,7 @@ int main(int argc, char **argv) {
char *display_name = (char *) 0; char *display_name = (char *) 0;
int i = 1; int i = 1;
FbTk::NLSInit("fluxbox.cat"); FbTk::I18n::init("fluxbox.cat");
for (; i < argc; i++) { for (; i < argc; i++) {
if (!strcmp(argv[i], "-display") || !strcmp(argv[i], "--display")) { if (!strcmp(argv[i], "-display") || !strcmp(argv[i], "--display")) {

View file

@ -565,7 +565,7 @@ int main(int argc, char **argv) {
bool check = 0; bool check = 0;
pid_t fb_pid = 0; pid_t fb_pid = 0;
FbTk::NLSInit("fluxbox.cat"); FbTk::I18n::init("fluxbox.cat");
_FB_USES_NLS; _FB_USES_NLS;
for (; i < argc; i++) { for (; i < argc; i++) {