Salome HOME
sources v1.2
[modules/kernel.git] / src / MSG2QM / msg2qm.cxx
1 //  SALOME MSG2QM : duplication of Qt tool
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : msg2qm.cxx
25 //  Module : SALOME
26
27 using namespace std;
28 /****************************************************************************
29 ** $Id$
30 **
31 ** This is a utility program for converting findtr msgfiles to
32 ** qtranslator message files
33 **
34 **
35 ** Copyright (C) 1998 by Trolltech AS.  All rights reserved.
36 **
37 *****************************************************************************/
38 #include <qfile.h>
39 #include <qtextstream.h>
40 #include <qtextcodec.h>
41 #include <qtranslator.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45
46 static QString* defaultScope = 0;
47
48 bool hasHandle( const QString& line, const QString& handle)
49 {
50     return line.left(handle.length()) == handle;
51 }
52
53
54 QString extractContents( const QString& line )
55 {
56     QString contents;
57     if ( line.contains('\"') < 2)
58         return contents;
59     int pos = 0;
60     while ( pos < int(line.length()) && line[pos] != '\"' )
61         pos++;
62     pos++;
63     while ( pos < int(line.length()) && line[pos] != '\"' ) {
64         if ( line[pos] == '\\') {
65             pos++;
66             switch (char(line[pos]) ) {
67             case 'n':
68                 contents += '\n';
69                 break;
70             case 't':
71                 contents += '\t';
72                 break;
73             case 'r':
74                 contents += '\r';
75                 break;
76             case 'a':
77                 contents += '\a';
78                 break;
79             case 'f':
80                 contents += '\f';
81                 break;
82             case 'v':
83                 contents += '\v';
84                 break;
85             case 'b':
86                 contents += '\b';
87                 break;
88             default:
89                 contents += char(line[pos]);
90                 break;
91             }
92         }
93         else
94             contents += line[pos];
95         pos++;
96     }
97     return contents;
98 }
99
100
101 void addTranslation( QTranslator* translator, const QString& msgid, const QString& msgstr)
102 {
103     if (!msgid.isNull() && !msgstr.isNull() ) {
104         QString scope = "";
105         QString id = msgid;
106         int coloncolon = msgid.find("::");
107         if (coloncolon != -1) {
108             scope = msgid.left( coloncolon );
109             id = msgid.right( msgid.length() - scope.length() - 2 );
110         }
111         else if (defaultScope)
112             scope = *defaultScope;
113
114         if (translator->contains( scope.ascii(), id.ascii() ) ) {
115             qWarning("Error: \"%s\" already in use", msgid.ascii() );
116         }
117         else {
118             translator->insert( scope.latin1(), id.latin1(), msgstr );
119         }
120     }
121 }
122
123
124
125 void translate( const QString& filename, const QString& qmfile )
126 {
127     QFile f(filename);
128     if ( !f.open( IO_ReadOnly) )
129         return;
130     QTranslator* translator = new QTranslator(0);
131     QTextCodec *codec = 0;
132     for (int pass =  0; pass < 2; pass++) {
133         f.at(0);
134         QTextStream t( &f );
135         QString line;
136         QString msgid;
137         QString msgstr;
138         if ( codec != 0 ) {
139             t.setCodec( codec );
140         }
141         while ( !t.atEnd() || !line.isEmpty() ) {
142             if (line.isEmpty()) {
143                 t.skipWhiteSpace();
144                 line = t.readLine();
145             }
146             if ( hasHandle( line, "msgid") ) {
147                 msgstr = QString::null;
148                 msgid = extractContents( line );
149                 if (!t.atEnd()) {
150                     t.skipWhiteSpace();
151                     line = t.readLine();
152                 }
153                 else
154                     line = QString::null;
155                 while ( hasHandle( line, "\"") ) {
156                     msgid += extractContents( line );
157                     if (!t.atEnd()) {
158                         t.skipWhiteSpace();
159                         line = t.readLine();
160                     }
161                     else
162                         line = QString::null;
163                 }
164             }
165             else if ( hasHandle( line, "msgstr") ) {
166                 msgstr = extractContents( line );
167                 if (!t.atEnd()) {
168                     t.skipWhiteSpace();
169                     line = t.readLine();
170                 }
171                 else
172                     line = QString::null;
173                 while ( hasHandle( line, "\"") ) {
174                     msgstr += extractContents( line );
175                     if (!t.atEnd()) {
176                         t.skipWhiteSpace();
177                         line = t.readLine();
178                     }
179                     else
180                         line = QString::null;
181                 }
182                 if ( pass == 1 )
183                     addTranslation( translator, msgid, msgstr);
184
185                 if ( pass == 0 && msgid.isEmpty() ) {
186                     // Check for the encoding.
187                     int cpos = msgstr.find( "charset=" );
188                     if ( cpos >= 0 ) {
189                         cpos = cpos + 8; //skip "charset="
190                         int i = cpos;
191                         int len = msgstr.length();
192                         while ( i < len && !msgstr[i].isSpace() )
193                             i++;
194                         QString charset = msgstr.mid( cpos, i-cpos );
195                         codec = QTextCodec::codecForName( charset.ascii() );
196                         if ( codec ) {
197                             debug( "PO file character set: %s. Codec: %s",
198                                    charset.ascii(), codec->name() );
199                         } else {
200                             debug( "No codec for %s", charset.ascii() );
201                         }
202                     }
203                     break;
204                 }
205             }
206             else
207                 line = QString::null;
208         }
209     }
210     f.close();
211     translator->save( qmfile );
212 }
213
214
215 // workaround for BCC problem, qtranslator.h includes qwindowdefs.h via qobject.h, see NEEDS_QMAIN
216 #if defined(main)
217 #undef main
218 #endif
219
220 int main( int argc, char* argv[] )
221 {
222
223     int infile = 1;
224     if (argc > 1) {
225         if ( QString("-scope") == argv[1] ) {
226             defaultScope = new QString(argv[2]);
227             infile += 2;
228         }
229     }
230
231     if ( argc <= infile ) {
232         printf("usage: %s [-scope default] infile [outfile]\n", argv[0]);
233         exit(1);
234     }
235
236     translate(argv[infile], argc > infile+1 ? argv[infile+1] : "tr.qm");
237     return 0;
238 }