source: cfg_oil/trunk/toppers/gettext.cpp@ 23

Last change on this file since 23 was 8, checked in by msugi, 14 years ago

ディレクトリ構造の作成,ソース一式とReleaseビルドのコミット.

File size: 7.0 KB
Line 
1/*
2 * TOPPERS Software
3 * Toyohashi Open Platform for Embedded Real-Time Systems
4 *
5 * Copyright (C) 2007-2008 by TAKAGI Nobuhisa
6 *
7 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
8 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
9 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
10 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
11 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
12 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
13 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
14 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
15ƒƒ“ƒgi—˜—p
16 * ŽÒƒ}ƒjƒ…
17ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
18 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
19 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
20 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
21 * ‚ƁD
22 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
23ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
24ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
25 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
26 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
27 * •ñ‚·‚邱‚ƁD
28 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
29 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
30 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
31 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
32 * –Ɛӂ·‚邱‚ƁD
33 *
34 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
35 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
36 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
37 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
38 * ‚̐ӔC‚𕉂í‚È‚¢D
39 *
40 */
41#include <cstdlib>
42#include <stdlib.h> // Cygwin‘΍ô
43#include <cstring>
44#include <clocale>
45#include <string>
46#include <map>
47#include <fstream>
48#include <stdexcept>
49#include "toppers/gettext.hpp"
50#include "toppers/cpp.hpp"
51#include "toppers/global.hpp"
52#include <boost/scoped_array.hpp>
53#include <boost/any.hpp>
54#include <boost/filesystem/path.hpp>
55#include <boost/filesystem/operations.hpp>
56
57namespace toppers
58{
59 namespace
60 {
61
62 std::map< std::string, std::string > msgcat;
63
64 void register_msgcat( std::string const& msgid, std::string const& msgstr )
65 {
66 std::string::size_type size = msgstr.size();
67 boost::scoped_array< wchar_t > wbuf( new wchar_t[ size + 1 ] );
68 boost::scoped_array< char > buf( new char[ size + 1 ] );
69 wchar_t* wcs = wbuf.get();
70 wchar_t wc = 0;
71 for ( std::string::const_iterator iter( msgstr.begin() ), last( msgstr.end() ); iter != last; ++iter )
72 {
73 int c = static_cast< unsigned char >( *iter );
74 if ( ( ( c & 0xc0 ) == 0xc0 ) || ( c < 0x80 ) ) // æsƒoƒCƒg
75 {
76 if ( wc != 0 )
77 {
78 *wcs++ = wc;
79 wc = 0;
80 }
81 if ( ( c & 0x80 ) == 0 )
82 {
83 wc = static_cast< wchar_t >( c );
84 }
85 else if ( ( c & 0xe0 ) == 0xc0 )
86 {
87 wc = static_cast< wchar_t >( c & 0x1f );
88 }
89 else if ( ( c & 0xf0 ) == 0xe0 )
90 {
91 wc = static_cast< wchar_t >( c & 0xf );
92 }
93 else
94 {
95 // ƒTƒƒQ[ƒg‚Í–¢‘Ήži‚±‚±‚őΉž‚µ‚½‚Æ‚µ‚Ä‚àA•¶ŽšƒR[ƒh•ÏŠ·Žž‚É‚µ‚­‚¶‚é‰Â”\«‘åj
96 }
97 }
98 else // Œã‘±ƒoƒCƒg
99 {
100 wc = static_cast< wchar_t >( ( wc << 6 ) | ( c & 0x3f ) );
101 }
102 }
103 if ( wc != 0 )
104 {
105 *wcs++ = wc;
106 }
107 *wcs = L'\0';
108
109 // « ‚±‚ÌŠÔ‚ÍŒˆ‚µ‚Ä—áŠO‚ª”­¶‚µ‚È‚¢
110 char const* locale = std::setlocale( LC_CTYPE, "" );
111 /* std:: */wcstombs( buf.get(), wbuf.get(), size + 1 ); // Unicode ‚©‚çŠÂ‹«ˆË‘¶‚Ì•¶ŽšƒR[ƒh‚Ö•ÏŠ·
112 std::setlocale( LC_CTYPE, locale );
113 // ª ‚±‚ÌŠÔ‚ÍŒˆ‚µ‚Ä—áŠO‚ª”­¶‚µ‚È‚¢
114
115 msgcat[ msgid ] = std::string( buf.get() );
116 }
117
118 bool msgcat_loaded = false;
119
120 }
121
122 /*!
123 * \brief ƒƒbƒZ[ƒWƒJƒ^ƒƒO‚̃[ƒh
124 * \param[in] dir *.po ƒtƒ@ƒCƒ‹‚ª‘¶Ý‚·‚éƒfƒBƒŒƒNƒgƒŠ
125 * \retval true ¬Œ÷
126 * \retval false Ž¸”s
127 *
128 * ŽÀ‘•‚ðŠÈ•Ö‰»‚·‚邽‚߁A.poƒtƒ@ƒCƒ‹‚Ì‹Lq•û–@‚ɂ͈ȉº‚̐§–ñ‚ª‚ ‚éB
129 * - msgid, msgstr ‚Í•K‚¸s‚̐擪‚É‹Lq‚·‚éB
130 * - msgid, msgstr ‚Ì’¼Œã‚ɂ́A•K‚¸‹ó”’—Þ•¶Žšˆê•¶Žš‚Æ‚µA‚»‚Ì’¼Œã‚É•¶Žš—ñ‚ð‹Lq‚·‚éB
131 * - •¶Žš—ñ‚Ì‚Ý‚ð‹Lq‚·‚és‚Í•K‚¸ " ‚ÅŽn‚ß‚éB
132 * - .poƒtƒ@ƒCƒ‹‚Í‚Ì•¶ŽšƒR[ƒh‚Í•K‚¸ UTF-8N ‚Æ‚·‚éB
133 */
134 bool load_msgcat( std::string const& dir )
135 {
136 namespace fs = boost::filesystem;
137 char const* env = std::getenv( "TOPPERS_CFG_LANG" );
138// env = "ja";
139 if ( env == 0 )
140 {
141 return false;
142 }
143 std::string lang( env );
144
145 fs::path cfg_dir( dir, fs::native );
146 fs::path po_file( cfg_dir/fs::path( lang + ".po", fs::native ) );
147 std::ifstream ifs( po_file.native_file_string().c_str() );
148 std::string msgid;
149 std::string msgstr;
150
151 while ( ifs )
152 {
153 std::string str;
154 std::getline( ifs, str );
155
156 // ‰üs•¶Žš‚̈Ⴂ‚ð‹zŽû
157 std::string::size_type pos = str.find_last_not_of( " \t\r\n" ); // ‚‚¢‚łɍs––‚Ì‹ó”’—Þ‚àœ‹Ž
158 if ( pos != std::string::npos && pos < str.size() - 1 )
159 {
160 char c = str[pos];
161 str.erase( pos + 1, std::string::npos );
162 }
163
164 if ( str.empty() || str[ 0 ] == '#' || str == "" )
165 {
166 ; // ‹ós‚Ü‚½‚̓Rƒƒ“ƒgs
167 }
168 else
169 {
170 try
171 {
172 if ( std::strncmp( str.c_str(), "msgid", sizeof( "msgid" )-1 ) == 0 )
173 {
174 str.erase( 0, sizeof( "msgid" )-1+1 );
175 msgid = expand_quote( str );
176 }
177 else if ( std::strncmp( str.c_str(), "msgstr", sizeof( "msgstr" )-1 ) == 0 )
178 {
179 str.erase( 0, sizeof( "msgstr" )-1+1 );
180 msgstr = expand_quote( str );
181 }
182 else
183 {
184 msgstr += expand_quote( str );
185 }
186 if ( !msgid.empty() && !msgstr.empty() ) // ’¼‘O‚Ì msgid / msgstr ‚ð“o˜^
187 {
188 register_msgcat( msgid, msgstr );
189 msgid.clear();
190 msgstr.clear();
191 }
192 }
193 catch ( std::invalid_argument& )
194 {
195 return false;
196 }
197 }
198 }
199 msgcat_loaded = true;
200 return true;
201 }
202
203 /*!
204 * \brief ƒƒbƒZ[ƒW‚Ì–|–ó
205 * \param[in] message ƒƒbƒZ[ƒWID
206 * \return –|–óŒã‚̃ƒbƒZ[ƒW
207 */
208 std::string const& gettext( std::string const& message )
209 {
210 static bool f = load_msgcat( get_global< std::string >( "cfg-directory" ) );
211 if ( !msgcat_loaded )
212 {
213 return message;
214 }
215
216 std::map< std::string, std::string >::const_iterator iter( msgcat.find( message ) ), last( msgcat.end() );
217 if ( iter != last )
218 {
219 std::string const& result( iter->second );
220 return result;
221 }
222 return message;
223 }
224
225}
Note: See TracBrowser for help on using the repository browser.