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