source: trunk/tools/linguist/lconvert/main.cpp@ 846

Last change on this file since 846 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 11.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt Linguist of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "translator.h"
43
44#include <QtCore/QCoreApplication>
45#include <QtCore/QDebug>
46#include <QtCore/QString>
47#include <QtCore/QStringList>
48#include <QtCore/QTranslator>
49#include <QtCore/QLibraryInfo>
50
51#include <iostream>
52
53QT_USE_NAMESPACE
54
55class LC {
56 Q_DECLARE_TR_FUNCTIONS(LConvert)
57};
58
59static int usage(const QStringList &args)
60{
61 Q_UNUSED(args);
62
63 QString loaders;
64 QString line(QLatin1String(" %1 - %2\n"));
65 foreach (Translator::FileFormat format, Translator::registeredFileFormats())
66 loaders += line.arg(format.extension, -5).arg(format.description);
67
68 std::cerr << qPrintable(LC::tr("\nUsage:\n"
69 " lconvert [options] <infile> [<infile>...]\n\n"
70 "lconvert is part of Qt's Linguist tool chain. It can be used as a\n"
71 "stand-alone tool to convert and filter translation data files.\n"
72 "The following file formats are supported:\n\n%1\n"
73 "If multiple input files are specified, they are merged with\n"
74 "translations from later files taking precedence.\n\n"
75 "Options:\n"
76 " -h\n"
77 " --help Display this information and exit.\n\n"
78 " -i <infile>\n"
79 " --input-file <infile>\n"
80 " Specify input file. Use if <infile> might start with a dash.\n"
81 " This option can be used several times to merge inputs.\n"
82 " May be '-' (standard input) for use in a pipe.\n\n"
83 " -o <outfile>\n"
84 " --output-file <outfile>\n"
85 " Specify output file. Default is '-' (standard output).\n\n"
86 " -if <informat>\n"
87 " --input-format <format>\n"
88 " Specify input format for subsequent <infile>s.\n"
89 " The format is auto-detected from the file name and defaults to 'ts'.\n\n"
90 " -of <outformat>\n"
91 " --output-format <outformat>\n"
92 " Specify output format. See -if.\n\n"
93 " --input-codec <codec>\n"
94 " Specify encoding for QM and PO input files. Default is 'Latin1'\n"
95 " for QM and 'UTF-8' for PO files. UTF-8 is always tried as well for\n"
96 " QM, corresponding to the possible use of the trUtf8() function.\n\n"
97 " --output-codec <codec>\n"
98 " Specify encoding for PO output files. Default is 'UTF-8'.\n\n"
99 " --drop-tags <regexp>\n"
100 " Drop named extra tags when writing TS or XLIFF files.\n"
101 " May be specified repeatedly.\n\n"
102 " --drop-translations\n"
103 " Drop existing translations and reset the status to 'unfinished'.\n"
104 " Note: this implies --no-obsolete.\n\n"
105 " --source-language <language>[_<region>]\n"
106 " Specify/override the language of the source strings. Defaults to\n"
107 " POSIX if not specified and the file does not name it yet.\n\n"
108 " --target-language <language>[_<region>]\n"
109 " Specify/override the language of the translation.\n"
110 " The target language is guessed from the file name if this option\n"
111 " is not specified and the file contents name no language yet.\n\n"
112 " --no-obsolete\n"
113 " Drop obsolete messages.\n\n"
114 " --no-finished\n"
115 " Drop finished messages.\n\n"
116 " --sort-contexts\n"
117 " Sort contexts in output TS file alphabetically.\n\n"
118 " --locations {absolute|relative|none}\n"
119 " Override how source code references are saved in TS files.\n"
120 " Default is absolute.\n\n"
121 " --no-ui-lines\n"
122 " Drop line numbers from references to UI files.\n\n"
123 " --verbose\n"
124 " be a bit more verbose\n\n"
125 "Long options can be specified with only one leading dash, too.\n\n"
126 "Return value:\n"
127 " 0 on success\n"
128 " 1 on command line parse failures\n"
129 " 2 on read failures\n"
130 " 3 on write failures\n").arg(loaders));
131 return 1;
132}
133
134struct File
135{
136 QString name;
137 QString format;
138};
139
140int main(int argc, char *argv[])
141{
142 QCoreApplication app(argc, argv);
143#ifndef Q_OS_WIN32
144 QTranslator translator;
145 QTranslator qtTranslator;
146 QString sysLocale = QLocale::system().name();
147 QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
148 if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
149 && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
150 app.installTranslator(&translator);
151 app.installTranslator(&qtTranslator);
152 }
153#endif // Q_OS_WIN32
154
155 QStringList args = app.arguments();
156 QList<File> inFiles;
157 QString inFormat(QLatin1String("auto"));
158 QString outFileName;
159 QString outFormat(QLatin1String("auto"));
160 QString targetLanguage;
161 QString sourceLanguage;
162 bool dropTranslations = false;
163 bool noObsolete = false;
164 bool noFinished = false;
165 bool verbose = false;
166 bool noUiLines = false;
167 Translator::LocationsType locations = Translator::DefaultLocations;
168
169 ConversionData cd;
170 Translator tr;
171
172 for (int i = 1; i < args.size(); ++i) {
173 if (args[i].startsWith(QLatin1String("--")))
174 args[i].remove(0, 1);
175 if (args[i] == QLatin1String("-o")
176 || args[i] == QLatin1String("-output-file")) {
177 if (++i >= args.size())
178 return usage(args);
179 outFileName = args[i];
180 } else if (args[i] == QLatin1String("-of")
181 || args[i] == QLatin1String("-output-format")) {
182 if (++i >= args.size())
183 return usage(args);
184 outFormat = args[i];
185 } else if (args[i] == QLatin1String("-i")
186 || args[i] == QLatin1String("-input-file")) {
187 if (++i >= args.size())
188 return usage(args);
189 File file;
190 file.name = args[i];
191 file.format = inFormat;
192 inFiles.append(file);
193 } else if (args[i] == QLatin1String("-if")
194 || args[i] == QLatin1String("-input-format")) {
195 if (++i >= args.size())
196 return usage(args);
197 inFormat = args[i];
198 } else if (args[i] == QLatin1String("-input-codec")) {
199 if (++i >= args.size())
200 return usage(args);
201 cd.m_codecForSource = args[i].toLatin1();
202 } else if (args[i] == QLatin1String("-output-codec")) {
203 if (++i >= args.size())
204 return usage(args);
205 cd.m_outputCodec = args[i].toLatin1();
206 } else if (args[i] == QLatin1String("-drop-tag")) {
207 if (++i >= args.size())
208 return usage(args);
209 cd.m_dropTags.append(args[i]);
210 } else if (args[i] == QLatin1String("-drop-translations")) {
211 dropTranslations = true;
212 } else if (args[i] == QLatin1String("-target-language")) {
213 if (++i >= args.size())
214 return usage(args);
215 targetLanguage = args[i];
216 } else if (args[i] == QLatin1String("-source-language")) {
217 if (++i >= args.size())
218 return usage(args);
219 sourceLanguage = args[i];
220 } else if (args[i].startsWith(QLatin1String("-h"))) {
221 usage(args);
222 return 0;
223 } else if (args[i] == QLatin1String("-no-obsolete")) {
224 noObsolete = true;
225 } else if (args[i] == QLatin1String("-no-finished")) {
226 noFinished = true;
227 } else if (args[i] == QLatin1String("-sort-contexts")) {
228 cd.m_sortContexts = true;
229 } else if (args[i] == QLatin1String("-locations")) {
230 if (++i >= args.size())
231 return usage(args);
232 if (args[i] == QLatin1String("none"))
233 locations = Translator::NoLocations;
234 else if (args[i] == QLatin1String("relative"))
235 locations = Translator::RelativeLocations;
236 else if (args[i] == QLatin1String("absolute"))
237 locations = Translator::AbsoluteLocations;
238 else
239 return usage(args);
240 } else if (args[i] == QLatin1String("-no-ui-lines")) {
241 noUiLines = true;
242 } else if (args[i] == QLatin1String("-verbose")) {
243 verbose = true;
244 } else if (args[i].startsWith(QLatin1Char('-'))) {
245 return usage(args);
246 } else {
247 File file;
248 file.name = args[i];
249 file.format = inFormat;
250 inFiles.append(file);
251 }
252 }
253
254 if (inFiles.isEmpty())
255 return usage(args);
256
257 tr.setLanguageCode(Translator::guessLanguageCodeFromFileName(inFiles[0].name));
258
259 if (!tr.load(inFiles[0].name, cd, inFiles[0].format)) {
260 std::cerr << qPrintable(cd.error());
261 return 2;
262 }
263 tr.reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose);
264
265 for (int i = 1; i < inFiles.size(); ++i) {
266 Translator tr2;
267 if (!tr2.load(inFiles[i].name, cd, inFiles[i].format)) {
268 std::cerr << qPrintable(cd.error());
269 return 2;
270 }
271 tr2.reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose);
272 for (int j = 0; j < tr2.messageCount(); ++j)
273 tr.replaceSorted(tr2.message(j));
274 }
275
276 if (!targetLanguage.isEmpty())
277 tr.setLanguageCode(targetLanguage);
278 if (!sourceLanguage.isEmpty())
279 tr.setSourceLanguageCode(sourceLanguage);
280 if (noObsolete)
281 tr.stripObsoleteMessages();
282 if (noFinished)
283 tr.stripFinishedMessages();
284 if (dropTranslations)
285 tr.dropTranslations();
286 if (noUiLines)
287 tr.dropUiLines();
288 if (locations != Translator::DefaultLocations)
289 tr.setLocationsType(locations);
290
291 tr.normalizeTranslations(cd);
292 if (!cd.errors().isEmpty()) {
293 std::cerr << qPrintable(cd.error());
294 cd.clearErrors();
295 }
296 if (!tr.save(outFileName, cd, outFormat)) {
297 std::cerr << qPrintable(cd.error());
298 return 3;
299 }
300 return 0;
301}
Note: See TracBrowser for help on using the repository browser.