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