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