1f8e2c85aSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3f8e2c85aSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4f8e2c85aSAndrew Rist * or more contributor license agreements. See the NOTICE file 5f8e2c85aSAndrew Rist * distributed with this work for additional information 6f8e2c85aSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7f8e2c85aSAndrew Rist * to you under the Apache License, Version 2.0 (the 8f8e2c85aSAndrew Rist * "License"); you may not use this file except in compliance 9f8e2c85aSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11f8e2c85aSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13f8e2c85aSAndrew Rist * Unless required by applicable law or agreed to in writing, 14f8e2c85aSAndrew Rist * software distributed under the License is distributed on an 15f8e2c85aSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16f8e2c85aSAndrew Rist * KIND, either express or implied. See the License for the 17f8e2c85aSAndrew Rist * specific language governing permissions and limitations 18f8e2c85aSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20f8e2c85aSAndrew Rist *************************************************************/ 21f8e2c85aSAndrew Rist 22f8e2c85aSAndrew 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 //########################################### 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 //########################################### 75cdf0e10cSrcweir inline OUString OStringToOUString(const OString& str) 76cdf0e10cSrcweir { return rtl::OStringToOUString(str, osl_getThreadTextEncoding()); } 77cdf0e10cSrcweir 78cdf0e10cSrcweir //########################################### 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 '\' */ 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 997950f2afSmseidel directory is absolute 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 */ 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 //########################################### 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: 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 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: 161cdf0e10cSrcweir iso_lang_identifier() {}; 162cdf0e10cSrcweir 163cdf0e10cSrcweir iso_lang_identifier(const OString& str) : 164cdf0e10cSrcweir lang_(str) 165cdf0e10cSrcweir { init(); } 166cdf0e10cSrcweir 167cdf0e10cSrcweir iso_lang_identifier(const std::string& str) : 168cdf0e10cSrcweir lang_(str.c_str()) 169cdf0e10cSrcweir { init(); } 170cdf0e10cSrcweir 171cdf0e10cSrcweir OString language() const 172cdf0e10cSrcweir { return lang_; } 173cdf0e10cSrcweir 174cdf0e10cSrcweir OString country() const 175cdf0e10cSrcweir { return country_; } 176cdf0e10cSrcweir 177cdf0e10cSrcweir OString make_OString() const 178cdf0e10cSrcweir { return lang_ + "-" + country_; } 179cdf0e10cSrcweir 180cdf0e10cSrcweir std::string make_std_string() const 181cdf0e10cSrcweir { 182cdf0e10cSrcweir OString tmp(lang_ + "-" + country_); 183cdf0e10cSrcweir return tmp.getStr(); 184cdf0e10cSrcweir } 185cdf0e10cSrcweir 186cdf0e10cSrcweir private: 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" */ 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 //########################################### 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 242cdf0e10cSrcweir iterator begin() 243cdf0e10cSrcweir { return iso_lang_replacement_table_.begin(); } 244cdf0e10cSrcweir 245cdf0e10cSrcweir iterator end() 246cdf0e10cSrcweir { return iso_lang_replacement_table_.end(); } 247cdf0e10cSrcweir 248cdf0e10cSrcweir public: 249cdf0e10cSrcweir 250cdf0e10cSrcweir Substitutor() {}; 251cdf0e10cSrcweir 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 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 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 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 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 //########################################### 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 //########################################### 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 //########################################### 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 */ 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 //########################################### 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 //########################################### 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); 472*2e3a1b6eSmseidel // Our resources are normally not sub language dependent. 473cdf0e10cSrcweir // Esp. for spanish we don't want to distinguish between trad. 474*2e3a1b6eSmseidel // and international 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 */ 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 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