diff options
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/I18n.cc | 177 | ||||
-rw-r--r-- | src/FbTk/I18n.hh | 43 |
2 files changed, 102 insertions, 118 deletions
diff --git a/src/FbTk/I18n.cc b/src/FbTk/I18n.cc index a7ed338..f53e5ed 100644 --- a/src/FbTk/I18n.cc +++ b/src/FbTk/I18n.cc | |||
@@ -35,38 +35,96 @@ | |||
35 | 35 | ||
36 | #include <X11/Xlocale.h> | 36 | #include <X11/Xlocale.h> |
37 | 37 | ||
38 | #ifdef HAVE_CSTDLIB | 38 | #include <cstdlib> |
39 | #include <cstdlib> | 39 | #include <cstring> |
40 | #else | ||
41 | #include <stdlib.h> | ||
42 | #endif | ||
43 | #ifdef HAVE_CSTRING | ||
44 | #include <cstring> | ||
45 | #else | ||
46 | #include <string.h> | ||
47 | #endif | ||
48 | #ifdef HAVE_CSTDIO | ||
49 | #include <cstdio> | ||
50 | #else | ||
51 | #include <stdio.h> | ||
52 | #endif | ||
53 | |||
54 | #include <iostream> | 40 | #include <iostream> |
55 | 41 | ||
42 | #ifdef HAVE_LOCALE_H | ||
43 | #include <locale.h> | ||
44 | #endif // HAVE_LOCALE_H | ||
45 | |||
46 | #ifdef HAVE_NL_TYPES_H | ||
47 | // this is needed for linux libc5 systems | ||
48 | extern "C" { | ||
49 | #include <nl_types.h> | ||
50 | } | ||
51 | #elif defined(__CYGWIN__) || defined(__EMX__) || defined(__APPLE__) | ||
52 | extern "C" { | ||
53 | typedef int nl_catd; | ||
54 | char *catgets(nl_catd cat, int set_number, int message_number, char *message); | ||
55 | nl_catd catopen(char *name, int flag); | ||
56 | void catclose(nl_catd cat); | ||
57 | } | ||
58 | |||
59 | #endif // HAVE_NL_TYPES_H | ||
60 | |||
61 | |||
56 | using std::cerr; | 62 | using std::cerr; |
57 | using std::endl; | 63 | using std::endl; |
58 | using std::string; | 64 | using std::string; |
59 | 65 | ||
66 | namespace { | ||
67 | |||
68 | const nl_catd INVALID_CATALOG = ((nl_catd)(-1)); | ||
69 | nl_catd s_catalog_fd = INVALID_CATALOG; | ||
70 | |||
71 | } | ||
72 | |||
73 | |||
60 | namespace FbTk { | 74 | namespace FbTk { |
61 | 75 | ||
62 | void NLSInit(const char *catalog) { | 76 | void I18n::init(const char* catalog) { |
77 | static bool init = false; | ||
78 | if (init) { | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | #if defined(NLS) && defined(HAVE_CATOPEN) | ||
83 | |||
63 | FbStringUtil::init(); | 84 | FbStringUtil::init(); |
64 | I18n *i18n = I18n::instance(); | ||
65 | i18n->openCatalog(catalog); | ||
66 | } | ||
67 | 85 | ||
86 | I18n& i18n = I18n::instance(); | ||
87 | |||
88 | string filename = LOCALEPATH; | ||
89 | filename += '/'; | ||
90 | filename += i18n.m_locale; | ||
91 | filename += '/'; | ||
92 | filename += catalog; | ||
93 | |||
94 | if (!FileUtil::isRegularFile(filename.c_str()) && i18n.m_locale != "C" && FbStringUtil::haveUTF8()) { | ||
95 | // try the UTF-8 catalog, this also picks up situations where | ||
96 | // the codeset somehow isn't specified | ||
68 | 97 | ||
69 | I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd)(-1)) { | 98 | // remove everything after @ |
99 | string::size_type index = i18n.m_locale.find('.'); | ||
100 | // erase all characters starting at index | ||
101 | if (index != string::npos) | ||
102 | i18n.m_locale.erase(index); | ||
103 | |||
104 | i18n.m_locale.append(".UTF-8"); | ||
105 | i18n.m_utf8_translate = true; | ||
106 | |||
107 | filename = LOCALEPATH; | ||
108 | filename += '/'; | ||
109 | filename += i18n.m_locale; | ||
110 | filename += '/'; | ||
111 | filename += catalog; | ||
112 | } | ||
113 | |||
114 | #ifdef MCLoadBySet | ||
115 | s_catalog_fd = catopen(filename.c_str(), MCLoadBySet); | ||
116 | #else // !MCLoadBySet | ||
117 | s_catalog_fd = catopen(filename.c_str(), NL_CAT_LOCALE); | ||
118 | #endif // MCLoadBySet | ||
119 | |||
120 | if (s_catalog_fd == INVALID_CATALOG) { | ||
121 | cerr<<"Warning: Failed to open file("<<filename<<")"<<endl | ||
122 | <<"for translation, using default messages."<<endl; | ||
123 | } | ||
124 | #endif // HAVE_CATOPEN | ||
125 | } | ||
126 | |||
127 | I18n::I18n():m_multibyte(false), m_utf8_translate(false) { | ||
70 | #if defined(HAVE_SETLOCALE) && defined(NLS) | 128 | #if defined(HAVE_SETLOCALE) && defined(NLS) |
71 | //make sure we don't get 0 to m_locale string | 129 | //make sure we don't get 0 to m_locale string |
72 | char *temp = setlocale(LC_MESSAGES, ""); | 130 | char *temp = setlocale(LC_MESSAGES, ""); |
@@ -79,7 +137,7 @@ I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd) | |||
79 | 137 | ||
80 | #if defined(HAVE_SETLOCALE) && defined(NLS) | 138 | #if defined(HAVE_SETLOCALE) && defined(NLS) |
81 | 139 | ||
82 | } else { | 140 | } else { |
83 | 141 | ||
84 | setlocale(LC_TIME, ""); | 142 | setlocale(LC_TIME, ""); |
85 | // MB_CUR_MAX returns the size of a char in the current locale | 143 | // 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) | |||
91 | // remove everything after @ | 149 | // remove everything after @ |
92 | string::size_type index = m_locale.find('@'); | 150 | string::size_type index = m_locale.find('@'); |
93 | if (index != string::npos) | 151 | if (index != string::npos) |
94 | m_locale.erase(index); //erase all characters starting at index | 152 | m_locale.erase(index); //erase all characters starting at index |
95 | // remove everything before = | 153 | // remove everything before = |
96 | index = m_locale.find('='); | 154 | index = m_locale.find('='); |
97 | if (index != string::npos) | 155 | if (index != string::npos) |
98 | m_locale.erase(0,index+1); //erase all characters starting up to index | 156 | m_locale.erase(0,index+1); //erase all characters starting up to index |
99 | } | 157 | } |
100 | #endif // defined(HAVE_SETLOCALE) && defined(NLS) | 158 | #endif // defined(HAVE_SETLOCALE) && defined(NLS) |
101 | } | 159 | } |
@@ -104,83 +162,36 @@ I18n::I18n():m_multibyte(false), m_utf8_translate(false), m_catalog_fd((nl_catd) | |||
104 | I18n::~I18n() { | 162 | I18n::~I18n() { |
105 | 163 | ||
106 | #if defined(NLS) && defined(HAVE_CATCLOSE) | 164 | #if defined(NLS) && defined(HAVE_CATCLOSE) |
107 | if (m_catalog_fd != (nl_catd)-1) | 165 | if (s_catalog_fd != (nl_catd)-1) |
108 | catclose(m_catalog_fd); | 166 | catclose(s_catalog_fd); |
109 | #endif // HAVE_CATCLOSE | 167 | #endif // HAVE_CATCLOSE |
110 | } | 168 | } |
111 | 169 | ||
112 | I18n *I18n::instance() { | 170 | I18n& I18n::instance() { |
113 | static I18n singleton; //singleton object | 171 | static I18n singleton; //singleton object |
114 | return &singleton; | 172 | return singleton; |
115 | } | 173 | } |
116 | 174 | ||
117 | void I18n::openCatalog(const char *catalog) { | 175 | // Translate_FB means it'll become an FbString that goes to X for Fonts, |
118 | #if defined(NLS) && defined(HAVE_CATOPEN) | ||
119 | |||
120 | string catalog_filename = LOCALEPATH; | ||
121 | catalog_filename += '/'; | ||
122 | catalog_filename += m_locale; | ||
123 | catalog_filename += '/'; | ||
124 | catalog_filename += catalog; | ||
125 | |||
126 | if (!FileUtil::isRegularFile(catalog_filename.c_str()) && m_locale != "C" && FbStringUtil::haveUTF8()) { | ||
127 | // try the UTF-8 catalog, this also picks up situations where | ||
128 | // the codeset somehow isn't specified | ||
129 | |||
130 | // remove everything after @ | ||
131 | string::size_type index = m_locale.find('.'); | ||
132 | // erase all characters starting at index | ||
133 | if (index != string::npos) | ||
134 | m_locale.erase(index); | ||
135 | |||
136 | m_locale.append(".UTF-8"); | ||
137 | m_utf8_translate = true; | ||
138 | |||
139 | catalog_filename = LOCALEPATH; | ||
140 | catalog_filename += '/'; | ||
141 | catalog_filename += m_locale; | ||
142 | catalog_filename += '/'; | ||
143 | catalog_filename += catalog; | ||
144 | } | ||
145 | |||
146 | #ifdef MCLoadBySet | ||
147 | m_catalog_fd = catopen(catalog_filename.c_str(), MCLoadBySet); | ||
148 | #else // !MCLoadBySet | ||
149 | m_catalog_fd = catopen(catalog_filename.c_str(), NL_CAT_LOCALE); | ||
150 | #endif // MCLoadBySet | ||
151 | |||
152 | if (m_catalog_fd == (nl_catd)-1) { | ||
153 | cerr<<"Warning: Failed to open file("<<catalog_filename<<")"<<endl; | ||
154 | cerr<<"for translation, using default messages."<<endl; | ||
155 | } | ||
156 | |||
157 | #else // !HAVE_CATOPEN | ||
158 | |||
159 | m_catalog_fd = (nl_catd)-1; | ||
160 | #endif // HAVE_CATOPEN | ||
161 | } | ||
162 | |||
163 | |||
164 | // Translate_FB means it'll become an FbString that goes to X for Fonts, | ||
165 | // No translate means it stays in the local encoding, for printing to the | 176 | // No translate means it stays in the local encoding, for printing to the |
166 | // console. | 177 | // console. |
167 | FbString I18n::getMessage(int set_number, int message_number, | 178 | FbString I18n::getMessage(int set_number, int message_number, |
168 | const char *default_message, bool translate_fb) const { | 179 | const char *default_message, bool translate_fb) const { |
169 | 180 | ||
170 | #if defined(NLS) && defined(HAVE_CATGETS) | 181 | #if defined(NLS) && defined(HAVE_CATGETS) |
171 | if (m_catalog_fd != (nl_catd)-1) { | 182 | if (s_catalog_fd != INVALID_CATALOG) { |
172 | const char *ret = catgets(m_catalog_fd, set_number, message_number, default_message); | 183 | const char *ret = catgets(s_catalog_fd, set_number, message_number, default_message); |
173 | // can't translate, leave it in raw ascii (utf-8 compatible) | 184 | // can't translate, leave it in raw ascii (utf-8 compatible) |
174 | if (ret == default_message || ret == NULL) | 185 | if (ret == default_message || ret == NULL) |
175 | return default_message; | 186 | return default_message; |
176 | 187 | ||
177 | if (!m_utf8_translate && translate_fb) | 188 | if (!m_utf8_translate && translate_fb) |
178 | // Local input, UTF-8 output | 189 | // Local input, UTF-8 output |
179 | return FbStringUtil::LocaleStrToFb(ret); | 190 | return FbStringUtil::LocaleStrToFb(ret); |
180 | else if (m_utf8_translate && !translate_fb) | 191 | else if (m_utf8_translate && !translate_fb) |
181 | // UTF-8 input, local output | 192 | // UTF-8 input, local output |
182 | return FbStringUtil::FbStrToLocale(ret); | 193 | return FbStringUtil::FbStrToLocale(ret); |
183 | else | 194 | else |
184 | // UTF-8 input, UTF-8 output OR | 195 | // UTF-8 input, UTF-8 output OR |
185 | // local input, local output | 196 | // local input, local output |
186 | return ret; | 197 | return ret; |
diff --git a/src/FbTk/I18n.hh b/src/FbTk/I18n.hh index 4ff4b77..6de2b8c 100644 --- a/src/FbTk/I18n.hh +++ b/src/FbTk/I18n.hh | |||
@@ -30,33 +30,10 @@ | |||
30 | 30 | ||
31 | #include "FbString.hh" | 31 | #include "FbString.hh" |
32 | 32 | ||
33 | #ifdef HAVE_LOCALE_H | ||
34 | #include <locale.h> | ||
35 | #endif // HAVE_LOCALE_H | ||
36 | |||
37 | #ifdef HAVE_NL_TYPES_H | ||
38 | // this is needed for linux libc5 systems | ||
39 | extern "C" { | ||
40 | #include <nl_types.h> | ||
41 | } | ||
42 | #elif defined(__CYGWIN__) || defined(__EMX__) || defined(__APPLE__) | ||
43 | #ifdef __cplusplus | ||
44 | extern "C" { | ||
45 | #endif // __cplusplus | ||
46 | typedef int nl_catd; | ||
47 | char *catgets(nl_catd cat, int set_number, int message_number, char *message); | ||
48 | nl_catd catopen(char *name, int flag); | ||
49 | void catclose(nl_catd cat); | ||
50 | #ifdef __cplusplus | ||
51 | } | ||
52 | #endif // __cplusplus | ||
53 | |||
54 | #endif // HAVE_NL_TYPES_H | ||
55 | |||
56 | // Some defines to help out | 33 | // Some defines to help out |
57 | #ifdef NLS | 34 | #ifdef NLS |
58 | #define _FB_USES_NLS \ | 35 | #define _FB_USES_NLS \ |
59 | FbTk::I18n &i18n = *FbTk::I18n::instance() | 36 | FbTk::I18n &i18n = FbTk::I18n::instance() |
60 | 37 | ||
61 | // ignore the description, it's for helping translators | 38 | // ignore the description, it's for helping translators |
62 | 39 | ||
@@ -97,27 +74,23 @@ namespace FbTk { | |||
97 | 74 | ||
98 | class I18n { | 75 | class I18n { |
99 | public: | 76 | public: |
100 | static I18n *instance(); | 77 | |
78 | static void init(const char*); | ||
79 | static I18n& instance(); | ||
80 | |||
101 | const char *getLocale() const { return m_locale.c_str(); } | 81 | const char *getLocale() const { return m_locale.c_str(); } |
102 | bool multibyte() const { return m_multibyte; } | 82 | bool multibyte() const { return m_multibyte; } |
103 | const nl_catd &getCatalogFd() const { return m_catalog_fd; } | ||
104 | |||
105 | FbString getMessage(int set_number, int message_number, | 83 | FbString getMessage(int set_number, int message_number, |
106 | const char *default_messsage = 0, bool translate_fb = false) const; | 84 | const char *default_messsage = 0, bool translate_fb = false) const; |
107 | 85 | ||
108 | void openCatalog(const char *catalog); | ||
109 | private: | 86 | private: |
110 | I18n(); | 87 | I18n(); |
111 | ~I18n(); | 88 | ~I18n(); |
112 | std::string m_locale; | 89 | std::string m_locale; |
113 | bool m_multibyte, m_utf8_translate; | 90 | bool m_multibyte; |
114 | nl_catd m_catalog_fd; | 91 | bool m_utf8_translate; |
115 | |||
116 | |||
117 | }; | 92 | }; |
118 | 93 | ||
119 | void NLSInit(const char *); | ||
120 | |||
121 | } // end namespace FbTk | 94 | } // end namespace FbTk |
122 | 95 | ||
123 | #endif // I18N_HH | 96 | #endif // I18N_HH |