1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_shell.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include <tools/presys.h>
28*b1cdbd2cSJim Jagielski #if defined _MSC_VER
29*b1cdbd2cSJim Jagielski #pragma warning(push, 1)
30*b1cdbd2cSJim Jagielski #endif
31*b1cdbd2cSJim Jagielski #include <windows.h>
32*b1cdbd2cSJim Jagielski #if defined _MSC_VER
33*b1cdbd2cSJim Jagielski #pragma warning(pop)
34*b1cdbd2cSJim Jagielski #endif
35*b1cdbd2cSJim Jagielski #include <tools/postsys.h>
36*b1cdbd2cSJim Jagielski
37*b1cdbd2cSJim Jagielski #define VCL_NEED_BASETSD
38*b1cdbd2cSJim Jagielski
39*b1cdbd2cSJim Jagielski #include "cmdline.hxx"
40*b1cdbd2cSJim Jagielski
41*b1cdbd2cSJim Jagielski #include "osl/thread.h"
42*b1cdbd2cSJim Jagielski #include "osl/process.h"
43*b1cdbd2cSJim Jagielski #include "osl/file.hxx"
44*b1cdbd2cSJim Jagielski #include "sal/main.h"
45*b1cdbd2cSJim Jagielski
46*b1cdbd2cSJim Jagielski #include "tools/config.hxx"
47*b1cdbd2cSJim Jagielski #include "i18npool/mslangid.hxx"
48*b1cdbd2cSJim Jagielski
49*b1cdbd2cSJim Jagielski #include <iostream>
50*b1cdbd2cSJim Jagielski #include <fstream>
51*b1cdbd2cSJim Jagielski #include <map>
52*b1cdbd2cSJim Jagielski #include <sstream>
53*b1cdbd2cSJim Jagielski #include <iterator>
54*b1cdbd2cSJim Jagielski #include <algorithm>
55*b1cdbd2cSJim Jagielski #include <string>
56*b1cdbd2cSJim Jagielski
57*b1cdbd2cSJim Jagielski namespace /* private */
58*b1cdbd2cSJim Jagielski {
59*b1cdbd2cSJim Jagielski
60*b1cdbd2cSJim Jagielski using rtl::OUString;
61*b1cdbd2cSJim Jagielski using rtl::OString;
62*b1cdbd2cSJim Jagielski
63*b1cdbd2cSJim Jagielski //###########################################
ShowUsage()64*b1cdbd2cSJim Jagielski void ShowUsage()
65*b1cdbd2cSJim Jagielski {
66*b1cdbd2cSJim Jagielski std::cout << "Usage: -ulf ulf_file -rc rc_output_file -rct rc_template_file -rch rch_file -rcf rcf_file" << std::endl;
67*b1cdbd2cSJim Jagielski std::cout << "-ulf Name of the ulf file" << std::endl;
68*b1cdbd2cSJim Jagielski std::cout << "-rc Name of the resulting resource file" << std::endl;
69*b1cdbd2cSJim Jagielski std::cout << "-rct Name of the resource template file" << std::endl;
70*b1cdbd2cSJim Jagielski std::cout << "-rch Name of the resource file header" << std::endl;
71*b1cdbd2cSJim Jagielski std::cout << "-rcf Name of the resource file footer" << std::endl;
72*b1cdbd2cSJim Jagielski }
73*b1cdbd2cSJim Jagielski
74*b1cdbd2cSJim Jagielski //###########################################
OStringToOUString(const OString & str)75*b1cdbd2cSJim Jagielski inline OUString OStringToOUString(const OString& str)
76*b1cdbd2cSJim Jagielski { return rtl::OStringToOUString(str, osl_getThreadTextEncoding()); }
77*b1cdbd2cSJim Jagielski
78*b1cdbd2cSJim Jagielski //###########################################
OUStringToOString(const OUString & str)79*b1cdbd2cSJim Jagielski inline OString OUStringToOString(const OUString& str)
80*b1cdbd2cSJim Jagielski { return rtl::OUStringToOString(str, osl_getThreadTextEncoding()); }
81*b1cdbd2cSJim Jagielski
82*b1cdbd2cSJim Jagielski //###########################################
83*b1cdbd2cSJim Jagielski /** Get the directory where the module
84*b1cdbd2cSJim Jagielski is located as system directory, the
85*b1cdbd2cSJim Jagielski returned directory has a trailing '\' */
get_module_path()86*b1cdbd2cSJim Jagielski OUString get_module_path()
87*b1cdbd2cSJim Jagielski {
88*b1cdbd2cSJim Jagielski OUString cwd_url;
89*b1cdbd2cSJim Jagielski OUString module_path;
90*b1cdbd2cSJim Jagielski if (osl_Process_E_None == osl_getProcessWorkingDir(&cwd_url.pData))
91*b1cdbd2cSJim Jagielski osl::FileBase::getSystemPathFromFileURL(cwd_url, module_path);
92*b1cdbd2cSJim Jagielski
93*b1cdbd2cSJim Jagielski return module_path;
94*b1cdbd2cSJim Jagielski }
95*b1cdbd2cSJim Jagielski
96*b1cdbd2cSJim Jagielski //###########################################
97*b1cdbd2cSJim Jagielski /** Make the absolute directory of a base and
98*b1cdbd2cSJim Jagielski a relative directory, if the relative
99*b1cdbd2cSJim Jagielski directory is absolute the the relative
100*b1cdbd2cSJim Jagielski directory will be returned unchanged.
101*b1cdbd2cSJim Jagielski Base and relative directory should be
102*b1cdbd2cSJim Jagielski system paths the returned directory is
103*b1cdbd2cSJim Jagielski a system path too */
get_absolute_path(const OUString & BaseDir,const OUString & RelDir)104*b1cdbd2cSJim Jagielski OUString get_absolute_path(
105*b1cdbd2cSJim Jagielski const OUString& BaseDir, const OUString& RelDir)
106*b1cdbd2cSJim Jagielski {
107*b1cdbd2cSJim Jagielski OUString base_url;
108*b1cdbd2cSJim Jagielski OUString rel_url;
109*b1cdbd2cSJim Jagielski
110*b1cdbd2cSJim Jagielski osl::FileBase::getFileURLFromSystemPath(BaseDir, base_url);
111*b1cdbd2cSJim Jagielski osl::FileBase::getFileURLFromSystemPath(RelDir, rel_url);
112*b1cdbd2cSJim Jagielski
113*b1cdbd2cSJim Jagielski OUString abs_url;
114*b1cdbd2cSJim Jagielski osl::FileBase::getAbsoluteFileURL(base_url, rel_url, abs_url);
115*b1cdbd2cSJim Jagielski
116*b1cdbd2cSJim Jagielski OUString abs_sys_path;
117*b1cdbd2cSJim Jagielski osl::FileBase::getSystemPathFromFileURL(abs_url, abs_sys_path);
118*b1cdbd2cSJim Jagielski
119*b1cdbd2cSJim Jagielski return abs_sys_path;
120*b1cdbd2cSJim Jagielski }
121*b1cdbd2cSJim Jagielski
122*b1cdbd2cSJim Jagielski //###########################################
get_absolute_file_path(const std::string & file_name)123*b1cdbd2cSJim Jagielski OString get_absolute_file_path(const std::string& file_name)
124*b1cdbd2cSJim Jagielski {
125*b1cdbd2cSJim Jagielski OUString fp = get_absolute_path(
126*b1cdbd2cSJim Jagielski get_module_path(), OStringToOUString(file_name.c_str()));
127*b1cdbd2cSJim Jagielski return OUStringToOString(fp);
128*b1cdbd2cSJim Jagielski }
129*b1cdbd2cSJim Jagielski
130*b1cdbd2cSJim Jagielski //###########################################
131*b1cdbd2cSJim Jagielski /** A helper class, enables stream exceptions
132*b1cdbd2cSJim Jagielski on construction, restors the old exception
133*b1cdbd2cSJim Jagielski state on destruction */
134*b1cdbd2cSJim Jagielski class StreamExceptionsEnabler
135*b1cdbd2cSJim Jagielski {
136*b1cdbd2cSJim Jagielski public:
StreamExceptionsEnabler(std::ios & iostrm,std::ios::iostate NewIos=std::ios::failbit|std::ios::badbit)137*b1cdbd2cSJim Jagielski explicit StreamExceptionsEnabler(
138*b1cdbd2cSJim Jagielski std::ios& iostrm,
139*b1cdbd2cSJim Jagielski std::ios::iostate NewIos = std::ios::failbit | std::ios::badbit) :
140*b1cdbd2cSJim Jagielski m_IoStrm(iostrm),
141*b1cdbd2cSJim Jagielski m_OldIos(m_IoStrm.exceptions())
142*b1cdbd2cSJim Jagielski {
143*b1cdbd2cSJim Jagielski m_IoStrm.exceptions(NewIos);
144*b1cdbd2cSJim Jagielski }
145*b1cdbd2cSJim Jagielski
~StreamExceptionsEnabler()146*b1cdbd2cSJim Jagielski ~StreamExceptionsEnabler()
147*b1cdbd2cSJim Jagielski {
148*b1cdbd2cSJim Jagielski m_IoStrm.exceptions(m_OldIos);
149*b1cdbd2cSJim Jagielski }
150*b1cdbd2cSJim Jagielski private:
151*b1cdbd2cSJim Jagielski std::ios& m_IoStrm;
152*b1cdbd2cSJim Jagielski std::ios::iostate m_OldIos;
153*b1cdbd2cSJim Jagielski };
154*b1cdbd2cSJim Jagielski
155*b1cdbd2cSJim Jagielski typedef std::vector<std::string> string_container_t;
156*b1cdbd2cSJim Jagielski
157*b1cdbd2cSJim Jagielski //###########################################
158*b1cdbd2cSJim Jagielski class iso_lang_identifier
159*b1cdbd2cSJim Jagielski {
160*b1cdbd2cSJim Jagielski public:
iso_lang_identifier()161*b1cdbd2cSJim Jagielski iso_lang_identifier() {};
162*b1cdbd2cSJim Jagielski
iso_lang_identifier(const OString & str)163*b1cdbd2cSJim Jagielski iso_lang_identifier(const OString& str) :
164*b1cdbd2cSJim Jagielski lang_(str)
165*b1cdbd2cSJim Jagielski { init(); }
166*b1cdbd2cSJim Jagielski
iso_lang_identifier(const std::string & str)167*b1cdbd2cSJim Jagielski iso_lang_identifier(const std::string& str) :
168*b1cdbd2cSJim Jagielski lang_(str.c_str())
169*b1cdbd2cSJim Jagielski { init(); }
170*b1cdbd2cSJim Jagielski
language() const171*b1cdbd2cSJim Jagielski OString language() const
172*b1cdbd2cSJim Jagielski { return lang_; }
173*b1cdbd2cSJim Jagielski
country() const174*b1cdbd2cSJim Jagielski OString country() const
175*b1cdbd2cSJim Jagielski { return country_; }
176*b1cdbd2cSJim Jagielski
make_OString() const177*b1cdbd2cSJim Jagielski OString make_OString() const
178*b1cdbd2cSJim Jagielski { return lang_ + "-" + country_; }
179*b1cdbd2cSJim Jagielski
make_std_string() const180*b1cdbd2cSJim Jagielski std::string make_std_string() const
181*b1cdbd2cSJim Jagielski {
182*b1cdbd2cSJim Jagielski OString tmp(lang_ + "-" + country_);
183*b1cdbd2cSJim Jagielski return tmp.getStr();
184*b1cdbd2cSJim Jagielski }
185*b1cdbd2cSJim Jagielski
186*b1cdbd2cSJim Jagielski private:
init()187*b1cdbd2cSJim Jagielski void init()
188*b1cdbd2cSJim Jagielski {
189*b1cdbd2cSJim Jagielski sal_Int32 idx = lang_.indexOf("-");
190*b1cdbd2cSJim Jagielski
191*b1cdbd2cSJim Jagielski if (idx > -1)
192*b1cdbd2cSJim Jagielski {
193*b1cdbd2cSJim Jagielski country_ = lang_.copy(idx + 1);
194*b1cdbd2cSJim Jagielski lang_ = lang_.copy(0, idx);
195*b1cdbd2cSJim Jagielski }
196*b1cdbd2cSJim Jagielski }
197*b1cdbd2cSJim Jagielski
198*b1cdbd2cSJim Jagielski private:
199*b1cdbd2cSJim Jagielski OString lang_;
200*b1cdbd2cSJim Jagielski OString country_;
201*b1cdbd2cSJim Jagielski };
202*b1cdbd2cSJim Jagielski
203*b1cdbd2cSJim Jagielski //###########################################
204*b1cdbd2cSJim Jagielski /** Convert a OUString to the MS resource
205*b1cdbd2cSJim Jagielski file format string e.g.
206*b1cdbd2cSJim Jagielski OUString -> L"\x1A00\x2200\x3400" */
make_winrc_unicode_string(const OUString & str)207*b1cdbd2cSJim Jagielski std::string make_winrc_unicode_string(const OUString& str)
208*b1cdbd2cSJim Jagielski {
209*b1cdbd2cSJim Jagielski std::ostringstream oss;
210*b1cdbd2cSJim Jagielski oss << "L\"";
211*b1cdbd2cSJim Jagielski
212*b1cdbd2cSJim Jagielski size_t length = str.getLength();
213*b1cdbd2cSJim Jagielski const sal_Unicode* pchr = str.getStr();
214*b1cdbd2cSJim Jagielski
215*b1cdbd2cSJim Jagielski for (size_t i = 0; i < length; i++)
216*b1cdbd2cSJim Jagielski oss << "\\x" << std::hex << (int)*pchr++;
217*b1cdbd2cSJim Jagielski
218*b1cdbd2cSJim Jagielski oss << "\"";
219*b1cdbd2cSJim Jagielski return oss.str();
220*b1cdbd2cSJim Jagielski }
221*b1cdbd2cSJim Jagielski
222*b1cdbd2cSJim Jagielski //###########################################
make_winrc_unicode_string(const std::string & str)223*b1cdbd2cSJim Jagielski std::string make_winrc_unicode_string(const std::string& str)
224*b1cdbd2cSJim Jagielski {
225*b1cdbd2cSJim Jagielski return make_winrc_unicode_string(
226*b1cdbd2cSJim Jagielski OUString::createFromAscii(str.c_str()));
227*b1cdbd2cSJim Jagielski }
228*b1cdbd2cSJim Jagielski
229*b1cdbd2cSJim Jagielski //################################################
230*b1cdbd2cSJim Jagielski /** A replacement table contains pairs of
231*b1cdbd2cSJim Jagielski placeholders and the appropriate substitute */
232*b1cdbd2cSJim Jagielski class Substitutor
233*b1cdbd2cSJim Jagielski {
234*b1cdbd2cSJim Jagielski private:
235*b1cdbd2cSJim Jagielski typedef std::map<std::string, std::string> replacement_table_t;
236*b1cdbd2cSJim Jagielski typedef std::map<std::string, replacement_table_t*> iso_lang_replacement_table_t;
237*b1cdbd2cSJim Jagielski
238*b1cdbd2cSJim Jagielski public:
239*b1cdbd2cSJim Jagielski typedef iso_lang_replacement_table_t::iterator iterator;
240*b1cdbd2cSJim Jagielski typedef iso_lang_replacement_table_t::const_iterator const_iterator;
241*b1cdbd2cSJim Jagielski
begin()242*b1cdbd2cSJim Jagielski iterator begin()
243*b1cdbd2cSJim Jagielski { return iso_lang_replacement_table_.begin(); }
244*b1cdbd2cSJim Jagielski
end()245*b1cdbd2cSJim Jagielski iterator end()
246*b1cdbd2cSJim Jagielski { return iso_lang_replacement_table_.end(); }
247*b1cdbd2cSJim Jagielski
248*b1cdbd2cSJim Jagielski public:
249*b1cdbd2cSJim Jagielski
Substitutor()250*b1cdbd2cSJim Jagielski Substitutor() {};
251*b1cdbd2cSJim Jagielski
~Substitutor()252*b1cdbd2cSJim Jagielski ~Substitutor()
253*b1cdbd2cSJim Jagielski {
254*b1cdbd2cSJim Jagielski iso_lang_replacement_table_t::iterator iter_end = iso_lang_replacement_table_.end();
255*b1cdbd2cSJim Jagielski iso_lang_replacement_table_t::iterator iter = iso_lang_replacement_table_.begin();
256*b1cdbd2cSJim Jagielski
257*b1cdbd2cSJim Jagielski for( /* no init */; iter != iter_end; ++iter)
258*b1cdbd2cSJim Jagielski delete iter->second;
259*b1cdbd2cSJim Jagielski
260*b1cdbd2cSJim Jagielski iso_lang_replacement_table_.clear();
261*b1cdbd2cSJim Jagielski }
262*b1cdbd2cSJim Jagielski
set_language(const iso_lang_identifier & iso_lang)263*b1cdbd2cSJim Jagielski void set_language(const iso_lang_identifier& iso_lang)
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski active_iso_lang_ = iso_lang;
266*b1cdbd2cSJim Jagielski }
267*b1cdbd2cSJim Jagielski
268*b1cdbd2cSJim Jagielski // If Text is a placeholder substitute it with
269*b1cdbd2cSJim Jagielski //its substitute else leave it unchanged
substitute(std::string & Text)270*b1cdbd2cSJim Jagielski void substitute(std::string& Text)
271*b1cdbd2cSJim Jagielski {
272*b1cdbd2cSJim Jagielski replacement_table_t* prt = get_replacement_table(active_iso_lang_.make_std_string());
273*b1cdbd2cSJim Jagielski OSL_ASSERT(prt);
274*b1cdbd2cSJim Jagielski replacement_table_t::iterator iter = prt->find(Text);
275*b1cdbd2cSJim Jagielski if (iter != prt->end())
276*b1cdbd2cSJim Jagielski Text = iter->second;
277*b1cdbd2cSJim Jagielski }
278*b1cdbd2cSJim Jagielski
add_substitution(const std::string & Placeholder,const std::string & Substitute)279*b1cdbd2cSJim Jagielski void add_substitution(
280*b1cdbd2cSJim Jagielski const std::string& Placeholder, const std::string& Substitute)
281*b1cdbd2cSJim Jagielski {
282*b1cdbd2cSJim Jagielski replacement_table_t* prt = get_replacement_table(active_iso_lang_.make_std_string());
283*b1cdbd2cSJim Jagielski OSL_ASSERT(prt);
284*b1cdbd2cSJim Jagielski prt->insert(std::make_pair(Placeholder, Substitute));
285*b1cdbd2cSJim Jagielski }
286*b1cdbd2cSJim Jagielski
287*b1cdbd2cSJim Jagielski
288*b1cdbd2cSJim Jagielski private:
289*b1cdbd2cSJim Jagielski // Return the replacement table for the iso lang id
290*b1cdbd2cSJim Jagielski // create a new one if not already present
get_replacement_table(const std::string & iso_lang)291*b1cdbd2cSJim Jagielski replacement_table_t* get_replacement_table(const std::string& iso_lang)
292*b1cdbd2cSJim Jagielski {
293*b1cdbd2cSJim Jagielski iso_lang_replacement_table_t::iterator iter =
294*b1cdbd2cSJim Jagielski iso_lang_replacement_table_.find(iso_lang);
295*b1cdbd2cSJim Jagielski
296*b1cdbd2cSJim Jagielski replacement_table_t* prt = NULL;
297*b1cdbd2cSJim Jagielski
298*b1cdbd2cSJim Jagielski if (iso_lang_replacement_table_.end() == iter)
299*b1cdbd2cSJim Jagielski {
300*b1cdbd2cSJim Jagielski prt = new replacement_table_t();
301*b1cdbd2cSJim Jagielski iso_lang_replacement_table_.insert(std::make_pair(iso_lang, prt));
302*b1cdbd2cSJim Jagielski }
303*b1cdbd2cSJim Jagielski else
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski prt = iter->second;
306*b1cdbd2cSJim Jagielski }
307*b1cdbd2cSJim Jagielski return prt;
308*b1cdbd2cSJim Jagielski }
309*b1cdbd2cSJim Jagielski
310*b1cdbd2cSJim Jagielski private:
311*b1cdbd2cSJim Jagielski iso_lang_replacement_table_t iso_lang_replacement_table_;
312*b1cdbd2cSJim Jagielski iso_lang_identifier active_iso_lang_;
313*b1cdbd2cSJim Jagielski };
314*b1cdbd2cSJim Jagielski
315*b1cdbd2cSJim Jagielski typedef std::map< unsigned short , std::string , std::less< unsigned short > > shortmap;
316*b1cdbd2cSJim Jagielski
317*b1cdbd2cSJim Jagielski //###########################################
add_group_entries(Config & aConfig,const ByteString & GroupName,Substitutor & Substitutor)318*b1cdbd2cSJim Jagielski void add_group_entries(
319*b1cdbd2cSJim Jagielski Config& aConfig,
320*b1cdbd2cSJim Jagielski const ByteString& GroupName,
321*b1cdbd2cSJim Jagielski Substitutor& Substitutor)
322*b1cdbd2cSJim Jagielski {
323*b1cdbd2cSJim Jagielski OSL_ASSERT(aConfig.HasGroup(GroupName));
324*b1cdbd2cSJim Jagielski
325*b1cdbd2cSJim Jagielski aConfig.SetGroup(GroupName);
326*b1cdbd2cSJim Jagielski size_t key_count = aConfig.GetKeyCount();
327*b1cdbd2cSJim Jagielski shortmap map;
328*b1cdbd2cSJim Jagielski
329*b1cdbd2cSJim Jagielski for (size_t i = 0; i < key_count; i++)
330*b1cdbd2cSJim Jagielski {
331*b1cdbd2cSJim Jagielski ByteString iso_lang = aConfig.GetKeyName(sal::static_int_cast<USHORT>(i));
332*b1cdbd2cSJim Jagielski ByteString key_value_utf8 = aConfig.ReadKey(sal::static_int_cast<USHORT>(i));
333*b1cdbd2cSJim Jagielski iso_lang_identifier myiso_lang( iso_lang );
334*b1cdbd2cSJim Jagielski LanguageType ltype = MsLangId::convertIsoNamesToLanguage(myiso_lang.language(), myiso_lang.country());
335*b1cdbd2cSJim Jagielski if( ( ltype & 0x0200 ) == 0 && map[ ltype ].empty() )
336*b1cdbd2cSJim Jagielski {
337*b1cdbd2cSJim Jagielski Substitutor.set_language(iso_lang_identifier(iso_lang));
338*b1cdbd2cSJim Jagielski
339*b1cdbd2cSJim Jagielski key_value_utf8.EraseLeadingAndTrailingChars('\"');
340*b1cdbd2cSJim Jagielski
341*b1cdbd2cSJim Jagielski OUString key_value_utf16 =
342*b1cdbd2cSJim Jagielski rtl::OStringToOUString(key_value_utf8, RTL_TEXTENCODING_UTF8);
343*b1cdbd2cSJim Jagielski
344*b1cdbd2cSJim Jagielski Substitutor.add_substitution(
345*b1cdbd2cSJim Jagielski GroupName.GetBuffer(), make_winrc_unicode_string(key_value_utf16));
346*b1cdbd2cSJim Jagielski map[ static_cast<unsigned short>(ltype) ] = std::string( iso_lang.GetBuffer() );
347*b1cdbd2cSJim Jagielski }
348*b1cdbd2cSJim Jagielski else
349*b1cdbd2cSJim Jagielski {
350*b1cdbd2cSJim Jagielski if( !map[ ltype ].empty() )
351*b1cdbd2cSJim Jagielski {
352*b1cdbd2cSJim Jagielski printf("ERROR: Duplicated ms id %d found for the languages %s and %s !!!! This does not work in microsoft resources\nPlease remove one!\n", ltype , map[ ltype ].c_str() , iso_lang.GetBuffer());
353*b1cdbd2cSJim Jagielski exit( -1 );
354*b1cdbd2cSJim Jagielski }
355*b1cdbd2cSJim Jagielski }
356*b1cdbd2cSJim Jagielski }
357*b1cdbd2cSJim Jagielski }
358*b1cdbd2cSJim Jagielski
359*b1cdbd2cSJim Jagielski //###########################################
read_ulf_file(const std::string & FileName,Substitutor & Substitutor)360*b1cdbd2cSJim Jagielski void read_ulf_file(const std::string& FileName, Substitutor& Substitutor)
361*b1cdbd2cSJim Jagielski {
362*b1cdbd2cSJim Jagielski // work-around for #i32420#
363*b1cdbd2cSJim Jagielski
364*b1cdbd2cSJim Jagielski // as the Config class is currently not able to deal correctly with
365*b1cdbd2cSJim Jagielski // UTF8 files starting with a byte-order-mark we create a copy of the
366*b1cdbd2cSJim Jagielski // original file without the byte-order-mark
367*b1cdbd2cSJim Jagielski rtl::OUString tmpfile_url;
368*b1cdbd2cSJim Jagielski osl_createTempFile(NULL, NULL, &tmpfile_url.pData);
369*b1cdbd2cSJim Jagielski
370*b1cdbd2cSJim Jagielski rtl::OUString tmpfile_sys;
371*b1cdbd2cSJim Jagielski osl::FileBase::getSystemPathFromFileURL(tmpfile_url, tmpfile_sys);
372*b1cdbd2cSJim Jagielski
373*b1cdbd2cSJim Jagielski std::ifstream in(FileName.c_str());
374*b1cdbd2cSJim Jagielski std::ofstream out(OUStringToOString(tmpfile_sys).getStr());
375*b1cdbd2cSJim Jagielski
376*b1cdbd2cSJim Jagielski try
377*b1cdbd2cSJim Jagielski {
378*b1cdbd2cSJim Jagielski StreamExceptionsEnabler sexc_out(out);
379*b1cdbd2cSJim Jagielski StreamExceptionsEnabler sexc_in(in);
380*b1cdbd2cSJim Jagielski
381*b1cdbd2cSJim Jagielski //skip the byte-order-mark 0xEF 0xBB 0xBF, identifying UTF8 files
382*b1cdbd2cSJim Jagielski unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
383*b1cdbd2cSJim Jagielski char buff[3];
384*b1cdbd2cSJim Jagielski in.read(&buff[0], 3);
385*b1cdbd2cSJim Jagielski
386*b1cdbd2cSJim Jagielski if (memcmp(buff, BOM, 3) != 0)
387*b1cdbd2cSJim Jagielski in.seekg(0);
388*b1cdbd2cSJim Jagielski
389*b1cdbd2cSJim Jagielski std::string line;
390*b1cdbd2cSJim Jagielski while (std::getline(in, line))
391*b1cdbd2cSJim Jagielski out << line << std::endl;
392*b1cdbd2cSJim Jagielski }
393*b1cdbd2cSJim Jagielski catch (const std::ios::failure&)
394*b1cdbd2cSJim Jagielski {
395*b1cdbd2cSJim Jagielski if (!in.eof())
396*b1cdbd2cSJim Jagielski throw;
397*b1cdbd2cSJim Jagielski }
398*b1cdbd2cSJim Jagielski
399*b1cdbd2cSJim Jagielski //Config config(OStringToOUString(FileName.c_str()).getStr());
400*b1cdbd2cSJim Jagielski
401*b1cdbd2cSJim Jagielski // end work-around for #i32420#
402*b1cdbd2cSJim Jagielski
403*b1cdbd2cSJim Jagielski Config config(tmpfile_url.getStr());
404*b1cdbd2cSJim Jagielski size_t grpcnt = config.GetGroupCount();
405*b1cdbd2cSJim Jagielski for (size_t i = 0; i < grpcnt; i++)
406*b1cdbd2cSJim Jagielski add_group_entries(config, config.GetGroupName(sal::static_int_cast<USHORT>(i)), Substitutor);
407*b1cdbd2cSJim Jagielski }
408*b1cdbd2cSJim Jagielski
409*b1cdbd2cSJim Jagielski //###########################################
read_file(const std::string & fname,string_container_t & string_container)410*b1cdbd2cSJim Jagielski void read_file(
411*b1cdbd2cSJim Jagielski const std::string& fname,
412*b1cdbd2cSJim Jagielski string_container_t& string_container)
413*b1cdbd2cSJim Jagielski {
414*b1cdbd2cSJim Jagielski std::ifstream file(fname.c_str());
415*b1cdbd2cSJim Jagielski StreamExceptionsEnabler sexc(file);
416*b1cdbd2cSJim Jagielski
417*b1cdbd2cSJim Jagielski try
418*b1cdbd2cSJim Jagielski {
419*b1cdbd2cSJim Jagielski std::string line;
420*b1cdbd2cSJim Jagielski while (std::getline(file, line))
421*b1cdbd2cSJim Jagielski string_container.push_back(line);
422*b1cdbd2cSJim Jagielski }
423*b1cdbd2cSJim Jagielski catch(const std::ios::failure&)
424*b1cdbd2cSJim Jagielski {
425*b1cdbd2cSJim Jagielski if (!file.eof())
426*b1cdbd2cSJim Jagielski throw;
427*b1cdbd2cSJim Jagielski }
428*b1cdbd2cSJim Jagielski }
429*b1cdbd2cSJim Jagielski
430*b1cdbd2cSJim Jagielski //###########################################
431*b1cdbd2cSJim Jagielski /** A simple helper function that appens the
432*b1cdbd2cSJim Jagielski content of one file to another one */
concatenate_files(std::ostream & os,std::istream & is)433*b1cdbd2cSJim Jagielski void concatenate_files(std::ostream& os, std::istream& is)
434*b1cdbd2cSJim Jagielski {
435*b1cdbd2cSJim Jagielski StreamExceptionsEnabler os_sexc(os);
436*b1cdbd2cSJim Jagielski StreamExceptionsEnabler is_sexc(is);
437*b1cdbd2cSJim Jagielski
438*b1cdbd2cSJim Jagielski try
439*b1cdbd2cSJim Jagielski {
440*b1cdbd2cSJim Jagielski std::string line;
441*b1cdbd2cSJim Jagielski while (std::getline(is, line))
442*b1cdbd2cSJim Jagielski os << line << std::endl;
443*b1cdbd2cSJim Jagielski }
444*b1cdbd2cSJim Jagielski catch(const std::ios::failure&)
445*b1cdbd2cSJim Jagielski {
446*b1cdbd2cSJim Jagielski if (!is.eof())
447*b1cdbd2cSJim Jagielski throw;
448*b1cdbd2cSJim Jagielski }
449*b1cdbd2cSJim Jagielski }
450*b1cdbd2cSJim Jagielski
451*b1cdbd2cSJim Jagielski //###########################################
is_placeholder(const std::string & str)452*b1cdbd2cSJim Jagielski bool is_placeholder(const std::string& str)
453*b1cdbd2cSJim Jagielski {
454*b1cdbd2cSJim Jagielski return ((str.length() > 1) &&
455*b1cdbd2cSJim Jagielski ('%' == str[0]) &&
456*b1cdbd2cSJim Jagielski ('%' == str[str.length() - 1]));
457*b1cdbd2cSJim Jagielski }
458*b1cdbd2cSJim Jagielski
459*b1cdbd2cSJim Jagielski //###########################################
start_language_section(std::ostream_iterator<std::string> & ostream_iter,const iso_lang_identifier & iso_lang)460*b1cdbd2cSJim Jagielski void start_language_section(
461*b1cdbd2cSJim Jagielski std::ostream_iterator<std::string>& ostream_iter, const iso_lang_identifier& iso_lang)
462*b1cdbd2cSJim Jagielski {
463*b1cdbd2cSJim Jagielski ostream_iter = std::string();
464*b1cdbd2cSJim Jagielski
465*b1cdbd2cSJim Jagielski std::string lang_section("LANGUAGE ");
466*b1cdbd2cSJim Jagielski
467*b1cdbd2cSJim Jagielski LanguageType ltype = MsLangId::convertIsoNamesToLanguage(iso_lang.language(), iso_lang.country());
468*b1cdbd2cSJim Jagielski
469*b1cdbd2cSJim Jagielski char buff[10];
470*b1cdbd2cSJim Jagielski int primLangID = PRIMARYLANGID(ltype);
471*b1cdbd2cSJim Jagielski int subLangID = SUBLANGID(ltype);
472*b1cdbd2cSJim Jagielski // Our resources are normaly not sub language dependant.
473*b1cdbd2cSJim Jagielski // Esp. for spanish we don't want to distinguish between trad.
474*b1cdbd2cSJim Jagielski // and internatinal sorting ( which leads to two different sub languages )
475*b1cdbd2cSJim Jagielski // Setting the sub language to neutral allows us to use one
476*b1cdbd2cSJim Jagielski // stringlist for all spanish variants ( see #123126# )
477*b1cdbd2cSJim Jagielski if ( ( primLangID == LANG_SPANISH ) &&
478*b1cdbd2cSJim Jagielski ( subLangID == SUBLANG_SPANISH ) )
479*b1cdbd2cSJim Jagielski subLangID = SUBLANG_NEUTRAL;
480*b1cdbd2cSJim Jagielski
481*b1cdbd2cSJim Jagielski _itoa(primLangID, buff, 16);
482*b1cdbd2cSJim Jagielski lang_section += std::string("0x") + std::string(buff);
483*b1cdbd2cSJim Jagielski
484*b1cdbd2cSJim Jagielski lang_section += std::string(" , ");
485*b1cdbd2cSJim Jagielski
486*b1cdbd2cSJim Jagielski _itoa(subLangID, buff, 16);
487*b1cdbd2cSJim Jagielski
488*b1cdbd2cSJim Jagielski lang_section += std::string("0x") + std::string(buff);
489*b1cdbd2cSJim Jagielski ostream_iter = lang_section;
490*b1cdbd2cSJim Jagielski }
491*b1cdbd2cSJim Jagielski
492*b1cdbd2cSJim Jagielski //###########################################
493*b1cdbd2cSJim Jagielski /** Iterate all languages in the substitutor,
494*b1cdbd2cSJim Jagielski replace the all placeholder and append the
495*b1cdbd2cSJim Jagielski result to the output file */
inflate_rc_template_to_file(std::ostream & os,const string_container_t & rctmpl,Substitutor & substitutor)496*b1cdbd2cSJim Jagielski void inflate_rc_template_to_file(
497*b1cdbd2cSJim Jagielski std::ostream& os, const string_container_t& rctmpl, Substitutor& substitutor)
498*b1cdbd2cSJim Jagielski {
499*b1cdbd2cSJim Jagielski StreamExceptionsEnabler sexc(os);
500*b1cdbd2cSJim Jagielski
501*b1cdbd2cSJim Jagielski Substitutor::const_iterator iter = substitutor.begin();
502*b1cdbd2cSJim Jagielski Substitutor::const_iterator iter_end = substitutor.end();
503*b1cdbd2cSJim Jagielski
504*b1cdbd2cSJim Jagielski std::ostream_iterator<std::string> oi(os, "\n");
505*b1cdbd2cSJim Jagielski
506*b1cdbd2cSJim Jagielski for ( /**/ ;iter != iter_end; ++iter)
507*b1cdbd2cSJim Jagielski {
508*b1cdbd2cSJim Jagielski substitutor.set_language(iso_lang_identifier(iter->first));
509*b1cdbd2cSJim Jagielski
510*b1cdbd2cSJim Jagielski string_container_t::const_iterator rct_iter = rctmpl.begin();
511*b1cdbd2cSJim Jagielski string_container_t::const_iterator rct_iter_end = rctmpl.end();
512*b1cdbd2cSJim Jagielski
513*b1cdbd2cSJim Jagielski if (!rctmpl.empty())
514*b1cdbd2cSJim Jagielski start_language_section(oi, iter->first);
515*b1cdbd2cSJim Jagielski
516*b1cdbd2cSJim Jagielski for ( /**/ ;rct_iter != rct_iter_end; ++rct_iter)
517*b1cdbd2cSJim Jagielski {
518*b1cdbd2cSJim Jagielski std::istringstream iss(*rct_iter);
519*b1cdbd2cSJim Jagielski std::string line;
520*b1cdbd2cSJim Jagielski
521*b1cdbd2cSJim Jagielski while (iss)
522*b1cdbd2cSJim Jagielski {
523*b1cdbd2cSJim Jagielski std::string token;
524*b1cdbd2cSJim Jagielski iss >> token;
525*b1cdbd2cSJim Jagielski substitutor.substitute(token);
526*b1cdbd2cSJim Jagielski
527*b1cdbd2cSJim Jagielski // #110274# HACK for partially merged
528*b1cdbd2cSJim Jagielski // *.lng files where some strings have
529*b1cdbd2cSJim Jagielski // a particular language that others
530*b1cdbd2cSJim Jagielski // don't have in order to keep the
531*b1cdbd2cSJim Jagielski // build
532*b1cdbd2cSJim Jagielski if (is_placeholder(token))
533*b1cdbd2cSJim Jagielski token = make_winrc_unicode_string(token);
534*b1cdbd2cSJim Jagielski
535*b1cdbd2cSJim Jagielski line += token;
536*b1cdbd2cSJim Jagielski line += " ";
537*b1cdbd2cSJim Jagielski }
538*b1cdbd2cSJim Jagielski oi = line;
539*b1cdbd2cSJim Jagielski }
540*b1cdbd2cSJim Jagielski }
541*b1cdbd2cSJim Jagielski }
542*b1cdbd2cSJim Jagielski
543*b1cdbd2cSJim Jagielski } // namespace /* private */
544*b1cdbd2cSJim Jagielski
545*b1cdbd2cSJim Jagielski //####################################################
546*b1cdbd2cSJim Jagielski /* MAIN
547*b1cdbd2cSJim Jagielski The file names provided via command line should be
548*b1cdbd2cSJim Jagielski absolute or relative to the directory of this module.
549*b1cdbd2cSJim Jagielski
550*b1cdbd2cSJim Jagielski Algo:
551*b1cdbd2cSJim Jagielski 1. read the ulf file and initialize the substitutor
552*b1cdbd2cSJim Jagielski 2. read the resource template file
553*b1cdbd2cSJim Jagielski 3. create the output file and append the header
554*b1cdbd2cSJim Jagielski 4. inflate the resource template to the output file
555*b1cdbd2cSJim Jagielski for every language using the substitutor
556*b1cdbd2cSJim Jagielski 5. append the footer
557*b1cdbd2cSJim Jagielski */
558*b1cdbd2cSJim Jagielski #define MAKE_ABSOLUTE(s) (get_absolute_file_path((s)).getStr())
559*b1cdbd2cSJim Jagielski #define ULF_FILE(c) MAKE_ABSOLUTE((c).get_arg("-ulf"))
560*b1cdbd2cSJim Jagielski #define RC_TEMPLATE(c) MAKE_ABSOLUTE((c).get_arg("-rct"))
561*b1cdbd2cSJim Jagielski #define RC_FILE(c) MAKE_ABSOLUTE((c).get_arg("-rc"))
562*b1cdbd2cSJim Jagielski #define RC_HEADER(c) MAKE_ABSOLUTE((c).get_arg("-rch"))
563*b1cdbd2cSJim Jagielski #define RC_FOOTER(c) MAKE_ABSOLUTE((c).get_arg("-rcf"))
564*b1cdbd2cSJim Jagielski
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,argv)565*b1cdbd2cSJim Jagielski SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
566*b1cdbd2cSJim Jagielski {
567*b1cdbd2cSJim Jagielski try
568*b1cdbd2cSJim Jagielski {
569*b1cdbd2cSJim Jagielski CommandLine cmdline(argc, argv);
570*b1cdbd2cSJim Jagielski
571*b1cdbd2cSJim Jagielski Substitutor substitutor;
572*b1cdbd2cSJim Jagielski read_ulf_file(ULF_FILE(cmdline), substitutor);
573*b1cdbd2cSJim Jagielski
574*b1cdbd2cSJim Jagielski string_container_t rc_tmpl;
575*b1cdbd2cSJim Jagielski read_file(RC_TEMPLATE(cmdline), rc_tmpl);
576*b1cdbd2cSJim Jagielski
577*b1cdbd2cSJim Jagielski std::ofstream rc_file(RC_FILE(cmdline));
578*b1cdbd2cSJim Jagielski std::ifstream in_header(RC_HEADER(cmdline));
579*b1cdbd2cSJim Jagielski concatenate_files(rc_file, in_header);
580*b1cdbd2cSJim Jagielski
581*b1cdbd2cSJim Jagielski inflate_rc_template_to_file(rc_file, rc_tmpl, substitutor);
582*b1cdbd2cSJim Jagielski
583*b1cdbd2cSJim Jagielski std::ifstream in_footer(RC_FOOTER(cmdline));
584*b1cdbd2cSJim Jagielski concatenate_files(rc_file, in_footer);
585*b1cdbd2cSJim Jagielski }
586*b1cdbd2cSJim Jagielski catch(const std::ios::failure& ex)
587*b1cdbd2cSJim Jagielski {
588*b1cdbd2cSJim Jagielski std::cout << ex.what() << std::endl;
589*b1cdbd2cSJim Jagielski }
590*b1cdbd2cSJim Jagielski catch(std::exception& ex)
591*b1cdbd2cSJim Jagielski {
592*b1cdbd2cSJim Jagielski std::cout << ex.what() << std::endl;
593*b1cdbd2cSJim Jagielski ShowUsage();
594*b1cdbd2cSJim Jagielski }
595*b1cdbd2cSJim Jagielski catch(...)
596*b1cdbd2cSJim Jagielski {
597*b1cdbd2cSJim Jagielski std::cout << "Unexpected error..." << std::endl;
598*b1cdbd2cSJim Jagielski }
599*b1cdbd2cSJim Jagielski return 0;
600*b1cdbd2cSJim Jagielski }
601*b1cdbd2cSJim Jagielski
602