Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <cstdlib>
11 : #include <cassert>
12 : #include <iostream>
13 : #include <fstream>
14 : #include <iomanip>
15 :
16 : #include "export.hxx"
17 : #include "common.hxx"
18 : #include "propmerge.hxx"
19 :
20 : namespace
21 : {
22 : //Find ascii escaped unicode
23 0 : static sal_Int32 lcl_IndexOfUnicode(
24 : const OString& rSource, const sal_Int32 nFrom = 0 )
25 : {
26 0 : const OString sHexDigits = "0123456789abcdefABCDEF";
27 0 : sal_Int32 nIndex = rSource.indexOf( "\\u", nFrom );
28 0 : if( nIndex == -1 )
29 : {
30 0 : return -1;
31 : }
32 0 : bool bIsUnicode = true;
33 0 : for( short nDist = 2; nDist <= 5; ++nDist )
34 : {
35 0 : if( sHexDigits.indexOf( rSource[nIndex + nDist] ) == -1 )
36 : {
37 0 : bIsUnicode = false;
38 : }
39 : }
40 0 : return bIsUnicode ? nIndex : -1;
41 : }
42 :
43 : //Convert ascii escaped unicode to utf-8
44 0 : static OString lcl_ConvertToUTF8( const OString& rText )
45 : {
46 0 : OString sResult = rText;
47 0 : sal_Int32 nIndex = lcl_IndexOfUnicode( sResult );
48 0 : while( nIndex != -1 && nIndex < rText.getLength() )
49 : {
50 0 : const OString sHex = sResult.copy( nIndex + 2, 4 );
51 : const sal_Unicode cDec =
52 0 : static_cast<sal_Unicode>( strtol( sHex.getStr(), NULL, 16 ) );
53 : const OString sNewChar =
54 0 : OString( &cDec, 1, RTL_TEXTENCODING_UTF8 );
55 0 : sResult = sResult.replaceAll( "\\u" + sHex, sNewChar );
56 0 : nIndex = lcl_IndexOfUnicode( sResult, nIndex );
57 0 : }
58 0 : return sResult;
59 : }
60 :
61 : //Escape unicode characters
62 0 : static void lcl_PrintJavaStyle( const OString& rText, std::ofstream &rOfstream )
63 : {
64 : const OUString sTemp =
65 0 : OStringToOUString( rText, RTL_TEXTENCODING_UTF8 );
66 0 : for ( sal_Int32 nIndex = 0; nIndex < sTemp.getLength(); ++nIndex )
67 : {
68 0 : sal_Unicode cUniCode = sTemp[nIndex];
69 0 : if( cUniCode < 128 )
70 : {
71 0 : rOfstream << static_cast<char>( cUniCode );
72 : }
73 : else
74 : {
75 : rOfstream
76 0 : << "\\u"
77 0 : << std::setfill('0') << std::setw(2) << std::uppercase
78 0 : << std::hex << (cUniCode >> 8)
79 0 : << std::setfill('0') << std::setw(2) << std::uppercase
80 0 : << std::hex << (cUniCode & 0xFF);
81 : }
82 0 : }
83 0 : }
84 : }
85 :
86 : //Open source file and store its lines
87 0 : PropParser::PropParser(
88 : const OString& rInputFile, const OString& rLang,
89 : const bool bMergeMode )
90 : : m_vLines( std::vector<OString>() )
91 : , m_sSource( rInputFile )
92 : , m_sLang( rLang )
93 0 : , m_bIsInitialized( false )
94 : {
95 0 : std::ifstream aIfstream( m_sSource.getStr() );
96 0 : if( aIfstream.is_open() )
97 : {
98 0 : std::string s;
99 0 : std::getline( aIfstream, s );
100 0 : while( !aIfstream.eof() )
101 : {
102 0 : OString sLine( s.data(), s.length() );
103 0 : if( bMergeMode ||
104 0 : ( !sLine.startsWith(" *") && !sLine.startsWith("/*") ) )
105 : {
106 0 : m_vLines.push_back( sLine );
107 : }
108 0 : std::getline( aIfstream, s );
109 0 : }
110 : }
111 : else
112 : {
113 : std::cerr
114 0 : << "Propex error: Cannot open source file: "
115 0 : << m_sSource.getStr() << std::endl;
116 0 : return;
117 : }
118 0 : m_bIsInitialized = true;
119 : }
120 :
121 0 : PropParser::~PropParser()
122 : {
123 0 : }
124 :
125 : //Extract strings form source file
126 0 : void PropParser::Extract( const OString& rPOFile )
127 : {
128 : assert( m_bIsInitialized );
129 0 : PoOfstream aPOStream( rPOFile, PoOfstream::APP );
130 0 : if( !aPOStream.isOpen() )
131 : {
132 : std::cerr
133 0 : << "Propex error: Cannot open pofile for extract: "
134 0 : << rPOFile.getStr() << std::endl;
135 0 : return;
136 : }
137 :
138 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
139 : {
140 0 : const OString sLine = m_vLines[nIndex];
141 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
142 0 : if( nEqualSign != -1 )
143 : {
144 0 : OString sID = sLine.copy( 0, nEqualSign ).trim();
145 0 : OString sText = lcl_ConvertToUTF8( sLine.copy( nEqualSign + 1 ).trim() );
146 :
147 : common::writePoEntry(
148 : "Propex", aPOStream, m_sSource, "property",
149 0 : sID, OString(), OString(), sText);
150 : }
151 0 : }
152 :
153 0 : aPOStream.close();
154 : }
155 :
156 : //Merge strings to source file
157 0 : void PropParser::Merge( const OString &rMergeSrc, const OString &rDestinationFile )
158 : {
159 : assert( m_bIsInitialized );
160 : std::ofstream aDestination(
161 0 : rDestinationFile.getStr(), std::ios_base::out | std::ios_base::trunc );
162 0 : if( !aDestination.is_open() ) {
163 : std::cerr
164 0 : << "Propex error: Cannot open source file for merge: "
165 0 : << rDestinationFile.getStr() << std::endl;
166 0 : return;
167 : }
168 :
169 0 : MergeDataFile* pMergeDataFile = 0;
170 0 : if( m_sLang != "qtz" )
171 : {
172 0 : pMergeDataFile = new MergeDataFile( rMergeSrc, m_sSource, false, false );
173 :
174 0 : const std::vector<OString> vLanguages = pMergeDataFile->GetLanguages();
175 0 : if( vLanguages.size()>=1 && vLanguages[0] != m_sLang )
176 : {
177 : std::cerr
178 0 : << "Propex error: given language conflicts with "
179 0 : << "language of Mergedata file: "
180 0 : << m_sLang.getStr() << " - "
181 0 : << vLanguages[0].getStr() << std::endl;
182 0 : delete pMergeDataFile;
183 0 : return;
184 0 : }
185 : }
186 :
187 0 : for( unsigned nIndex = 0; nIndex < m_vLines.size(); ++nIndex )
188 : {
189 0 : const OString sLine = m_vLines[nIndex];
190 0 : const sal_Int32 nEqualSign = sLine.indexOf('=');
191 0 : if( !sLine.startsWith(" *") && !sLine.startsWith("/*") &&
192 : nEqualSign != -1 )
193 : {
194 0 : const OString sID( sLine.copy( 0, sLine.indexOf('=') ).trim() );
195 0 : ResData aResData( sID, m_sSource );
196 0 : aResData.sResTyp = "property";
197 0 : OString sNewText;
198 0 : if( m_sLang == "qtz" )
199 : {
200 0 : const OString sOriginText = lcl_ConvertToUTF8(sLine.copy( nEqualSign + 1 ).trim());
201 0 : sNewText = MergeEntrys::GetQTZText(aResData, sOriginText);
202 : }
203 0 : else if( pMergeDataFile )
204 : {
205 0 : MergeEntrys* pEntrys = pMergeDataFile->GetMergeEntrys( &aResData );
206 0 : if( pEntrys )
207 : {
208 0 : pEntrys->GetText( sNewText, STRING_TYP_TEXT, m_sLang );
209 : }
210 : }
211 0 : if( !sNewText.isEmpty() )
212 : {
213 0 : aDestination << OString(sID + "=").getStr();
214 0 : lcl_PrintJavaStyle( sNewText, aDestination );
215 0 : aDestination << std::endl;
216 : }
217 : else
218 : {
219 0 : aDestination << sLine.getStr() << std::endl;
220 0 : }
221 : }
222 : else
223 : {
224 0 : aDestination << sLine.getStr() << std::endl;
225 : }
226 0 : }
227 0 : aDestination.close();
228 0 : delete pMergeDataFile;
229 0 : }
230 :
231 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|