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