Salome HOME
PR: modify makefiles to separate rules for libraries and binaries.
[modules/kernel.git] / src / MSG2QM / msg2qm.cxx
1 /////////////////////////////////////////////////////////////////////////////
2 // Module      : MSG2QM
3 // File        : msg2qm.cxx
4 // Description : This is a duplication of Qt tool for resources compiling 
5 /////////////////////////////////////////////////////////////////////////////
6
7 /****************************************************************************
8 ** $Id$
9 **
10 ** This is a utility program for converting findtr msgfiles to
11 ** qtranslator message files
12 **
13 **
14 ** Copyright (C) 1998 by Trolltech AS.  All rights reserved.
15 **
16 *****************************************************************************/
17
18 #include <qfile.h>
19 #include <qtextstream.h>
20 #include <qtextcodec.h>
21 #include <qtranslator.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 using namespace std;
26
27 static QString* defaultScope = 0;
28
29 bool hasHandle( const QString& line, const QString& handle)
30 {
31     return line.left(handle.length()) == handle;
32 }
33
34
35 QString extractContents( const QString& line )
36 {
37     QString contents;
38     if ( line.contains('\"') < 2)
39         return contents;
40     int pos = 0;
41     while ( pos < int(line.length()) && line[pos] != '\"' )
42         pos++;
43     pos++;
44     while ( pos < int(line.length()) && line[pos] != '\"' ) {
45         // 0xa5: the yen sign is the Japanese backslash
46         if ( line[pos] == '\\' || line[pos] == QChar(0xa5) ) {
47             pos++;
48             switch (char(line[pos]) ) {
49             case 'n':
50                 contents += '\n';
51                 break;
52             case 't':
53                 contents += '\t';
54                 break;
55             case 'r':
56                 contents += '\r';
57                 break;
58             case 'a':
59                 contents += '\a';
60                 break;
61             case 'f':
62                 contents += '\f';
63                 break;
64             case 'v':
65                 contents += '\v';
66                 break;
67             case 'b':
68                 contents += '\b';
69                 break;
70             default:
71                 contents += char(line[pos]);
72                 break;
73             }
74         }
75         else
76             contents += line[pos];
77         pos++;
78     }
79     return contents;
80 }
81
82
83 void addTranslation( QTranslator* translator, const QString& msgid, const QString& msgstr)
84 {
85     if (!msgid.isNull() && !msgstr.isNull() ) {
86         QString scope = "";
87         QString id = msgid;
88         int coloncolon = msgid.find("::");
89         if (coloncolon != -1) {
90             scope = msgid.left( coloncolon );
91             id = msgid.right( msgid.length() - scope.length() - 2 );
92         }
93         else if (defaultScope)
94             scope = *defaultScope;
95
96         if (translator->contains( scope.ascii(), id.ascii() ) ) {
97             qWarning("Error: \"%s\" already in use", msgid.ascii() );
98         }
99         else {
100             translator->insert( scope.latin1(), id.latin1(), msgstr );
101         }
102     }
103 }
104
105
106
107 void translate( const QString& filename, const QString& qmfile )
108 {
109     QFile f(filename);
110     if ( !f.open( IO_ReadOnly) )
111         return;
112     QTranslator* translator = new QTranslator(0);
113     QTextCodec *codec = 0;
114     for (int pass =  0; pass < 2; pass++) {
115         f.at(0);
116         QTextStream t( &f );
117         QString line;
118         QString msgid;
119         QString msgstr;
120         if ( codec != 0 ) {
121             t.setCodec( codec );
122         }
123         while ( !t.atEnd() || !line.isEmpty() ) {
124             if (line.isEmpty()) {
125                 t.skipWhiteSpace();
126                 line = t.readLine();
127             }
128             if ( hasHandle( line, "msgid") ) {
129                 msgstr = QString::null;
130                 msgid = extractContents( line );
131                 if (!t.atEnd()) {
132                     t.skipWhiteSpace();
133                     line = t.readLine();
134                 }
135                 else
136                     line = QString::null;
137                 while ( hasHandle( line, "\"") ) {
138                     msgid += extractContents( line );
139                     if (!t.atEnd()) {
140                         t.skipWhiteSpace();
141                         line = t.readLine();
142                     }
143                     else
144                         line = QString::null;
145                 }
146             }
147             else if ( hasHandle( line, "msgstr") ) {
148                 msgstr = 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                     msgstr += extractContents( line );
157                     if (!t.atEnd()) {
158                         t.skipWhiteSpace();
159                         line = t.readLine();
160                     }
161                     else
162                         line = QString::null;
163                 }
164                 if ( pass == 1 )
165                     addTranslation( translator, msgid, msgstr);
166
167                 if ( pass == 0 && msgid.isEmpty() ) {
168                     // Check for the encoding.
169                     int cpos = msgstr.find( "charset=" );
170                     if ( cpos >= 0 ) {
171                         cpos = cpos + 8; //skip "charset="
172                         int i = cpos;
173                         int len = msgstr.length();
174                         while ( i < len && !msgstr[i].isSpace() )
175                             i++;
176                         QString charset = msgstr.mid( cpos, i-cpos );
177                         codec = QTextCodec::codecForName( charset.ascii() );
178                         if ( codec ) {
179                             debug( "PO file character set: %s. Codec: %s",
180                                    charset.ascii(), codec->name() );
181                         } else {
182                             debug( "No codec for %s", charset.ascii() );
183                         }
184                     }
185                     break;
186                 }
187             }
188             else
189                 line = QString::null;
190         }
191     }
192     f.close();
193     translator->save( qmfile );
194 }
195
196
197 // workaround for BCC problem, qtranslator.h includes qwindowdefs.h via qobject.h, see NEEDS_QMAIN
198 #if defined(main)
199 #undef main
200 #endif
201
202 int main( int argc, char* argv[] )
203 {
204
205     int infile = 1;
206     if (argc > 1) {
207         if ( QString("-scope") == argv[1] ) {
208             defaultScope = new QString(argv[2]);
209             infile += 2;
210         }
211     }
212
213     if ( argc <= infile ) {
214         printf("usage: %s [-scope default] infile [outfile]\n", argv[0]);
215         exit(1);
216     }
217
218     translate(argv[infile], argc > infile+1 ? argv[infile+1] : "tr.qm");
219     return 0;
220 }