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>
#ifdef HAVE_CSTDLIB
#include <cstdlib>
#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 <cstdlib>
#include <cstring>
#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::endl;
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)
//make sure we don't get 0 to m_locale string
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)
} else {
} else {
setlocale(LC_TIME, "");
// 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 @
string::size_type index = m_locale.find('@');
if (index != string::npos)
m_locale.erase(index); //erase all characters starting at index
// remove everything before =
m_locale.erase(index); //erase all characters starting at index
// remove everything before =
index = m_locale.find('=');
if (index != string::npos)
m_locale.erase(0,index+1); //erase all characters starting up to index
if (index != string::npos)
m_locale.erase(0,index+1); //erase all characters starting up to index
}
#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() {
#if defined(NLS) && defined(HAVE_CATCLOSE)
if (m_catalog_fd != (nl_catd)-1)
catclose(m_catalog_fd);
if (s_catalog_fd != (nl_catd)-1)
catclose(s_catalog_fd);
#endif // HAVE_CATCLOSE
}
I18n *I18n::instance() {
I18n& I18n::instance() {
static I18n singleton; //singleton object
return &singleton;
return singleton;
}
void I18n::openCatalog(const char *catalog) {
#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,
// 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
// 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 {
#if defined(NLS) && defined(HAVE_CATGETS)
if (m_catalog_fd != (nl_catd)-1) {
const char *ret = catgets(m_catalog_fd, set_number, message_number, default_message);
if (s_catalog_fd != INVALID_CATALOG) {
const char *ret = catgets(s_catalog_fd, set_number, message_number, default_message);
// can't translate, leave it in raw ascii (utf-8 compatible)
if (ret == default_message || ret == NULL)
return default_message;
if (!m_utf8_translate && translate_fb)
if (!m_utf8_translate && translate_fb)
// Local input, UTF-8 output
return FbStringUtil::LocaleStrToFb(ret);
else if (m_utf8_translate && !translate_fb)
// UTF-8 input, local output
return FbStringUtil::FbStrToLocale(ret);
else
else
// UTF-8 input, UTF-8 output OR
// local input, local output
return ret;

View file

@ -30,33 +30,10 @@
#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
#ifdef 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
@ -97,27 +74,23 @@ namespace FbTk {
class I18n {
public:
static I18n *instance();
static void init(const char*);
static I18n& instance();
const char *getLocale() const { return m_locale.c_str(); }
bool multibyte() const { return m_multibyte; }
const nl_catd &getCatalogFd() const { return m_catalog_fd; }
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:
I18n();
~I18n();
std::string m_locale;
bool m_multibyte, m_utf8_translate;
nl_catd m_catalog_fd;
bool m_multibyte;
bool m_utf8_translate;
};
void NLSInit(const char *);
} // end namespace FbTk
#endif // I18N_HH

View file

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

View file

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

View file

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