| 1 | /**********************************************************************
|
|---|
| 2 | ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved.
|
|---|
| 3 | **
|
|---|
| 4 | ** This file is part of Qt Linguist.
|
|---|
| 5 | **
|
|---|
| 6 | ** This file may be distributed and/or modified under the terms of the
|
|---|
| 7 | ** GNU General Public License version 2 as published by the Free Software
|
|---|
| 8 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
|---|
| 9 | ** packaging of this file.
|
|---|
| 10 | **
|
|---|
| 11 | ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
|
|---|
| 12 | ** licenses may use this file in accordance with the Qt Commercial License
|
|---|
| 13 | ** Agreement provided with the Software.
|
|---|
| 14 | **
|
|---|
| 15 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|---|
| 16 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|---|
| 17 | **
|
|---|
| 18 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
|---|
| 19 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
|---|
| 20 | ** information about Qt Commercial License Agreements.
|
|---|
| 21 | **
|
|---|
| 22 | ** Contact info@trolltech.com if any conditions of this licensing are
|
|---|
| 23 | ** not clear to you.
|
|---|
| 24 | **
|
|---|
| 25 | **********************************************************************/
|
|---|
| 26 |
|
|---|
| 27 | #include <metatranslator.h>
|
|---|
| 28 | #include <proparser.h>
|
|---|
| 29 |
|
|---|
| 30 | #include <qdir.h>
|
|---|
| 31 | #include <qfile.h>
|
|---|
| 32 | #include <qfileinfo.h>
|
|---|
| 33 | #include <qstring.h>
|
|---|
| 34 | #include <qstringlist.h>
|
|---|
| 35 | #include <qtextstream.h>
|
|---|
| 36 |
|
|---|
| 37 | #include <errno.h>
|
|---|
| 38 | #include <string.h>
|
|---|
| 39 |
|
|---|
| 40 | // defined in fetchtr.cpp
|
|---|
| 41 | extern void fetchtr_cpp( const char *fileName, MetaTranslator *tor,
|
|---|
| 42 | const char *defaultContext, bool mustExist );
|
|---|
| 43 | extern void fetchtr_ui( const char *fileName, MetaTranslator *tor,
|
|---|
| 44 | const char *defaultContext, bool mustExist );
|
|---|
| 45 |
|
|---|
| 46 | // defined in merge.cpp
|
|---|
| 47 | extern void merge( MetaTranslator *tor, const MetaTranslator *virginTor,
|
|---|
| 48 | bool verbose );
|
|---|
| 49 |
|
|---|
| 50 | typedef QValueList<MetaTranslatorMessage> TML;
|
|---|
| 51 |
|
|---|
| 52 | static void printUsage()
|
|---|
| 53 | {
|
|---|
| 54 | fprintf( stderr, "Usage:\n"
|
|---|
| 55 | " lupdate [options] project-file\n"
|
|---|
| 56 | " lupdate [options] source-files -ts ts-files\n"
|
|---|
| 57 | "Options:\n"
|
|---|
| 58 | " -help Display this information and exit\n"
|
|---|
| 59 | " -noobsolete\n"
|
|---|
| 60 | " Drop all obsolete strings\n"
|
|---|
| 61 | " -verbose\n"
|
|---|
| 62 | " Explain what is being done\n"
|
|---|
| 63 | " -version\n"
|
|---|
| 64 | " Display the version of lupdate and exit\n" );
|
|---|
| 65 | }
|
|---|
| 66 |
|
|---|
| 67 | static void updateTsFiles( const MetaTranslator& fetchedTor,
|
|---|
| 68 | const QStringList& tsFileNames, const QString& codec,
|
|---|
| 69 | bool noObsolete, bool verbose )
|
|---|
| 70 | {
|
|---|
| 71 | QStringList::ConstIterator t = tsFileNames.begin();
|
|---|
| 72 | while ( t != tsFileNames.end() ) {
|
|---|
| 73 | MetaTranslator tor;
|
|---|
| 74 | tor.load( *t );
|
|---|
| 75 | if ( !codec.isEmpty() )
|
|---|
| 76 | tor.setCodec( codec );
|
|---|
| 77 | if ( verbose )
|
|---|
| 78 | fprintf( stderr, "Updating '%s'...\n", (*t).latin1() );
|
|---|
| 79 | merge( &tor, &fetchedTor, verbose );
|
|---|
| 80 | if ( noObsolete )
|
|---|
| 81 | tor.stripObsoleteMessages();
|
|---|
| 82 | tor.stripEmptyContexts();
|
|---|
| 83 | if ( !tor.save(*t) )
|
|---|
| 84 | fprintf( stderr, "lupdate error: Cannot save '%s': %s\n",
|
|---|
| 85 | (*t).latin1(), strerror(errno) );
|
|---|
| 86 | ++t;
|
|---|
| 87 | }
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | int main( int argc, char **argv )
|
|---|
| 91 | {
|
|---|
| 92 | QString defaultContext = "@default";
|
|---|
| 93 | MetaTranslator fetchedTor;
|
|---|
| 94 | QCString codec;
|
|---|
| 95 | QStringList tsFileNames;
|
|---|
| 96 |
|
|---|
| 97 | bool verbose = FALSE;
|
|---|
| 98 | bool noObsolete = FALSE;
|
|---|
| 99 | bool metSomething = FALSE;
|
|---|
| 100 | int numFiles = 0;
|
|---|
| 101 | bool standardSyntax = TRUE;
|
|---|
| 102 | bool metTsFlag = FALSE;
|
|---|
| 103 |
|
|---|
| 104 | int i;
|
|---|
| 105 |
|
|---|
| 106 | for ( i = 1; i < argc; i++ ) {
|
|---|
| 107 | if ( qstrcmp(argv[i], "-ts") == 0 )
|
|---|
| 108 | standardSyntax = FALSE;
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | for ( i = 1; i < argc; i++ ) {
|
|---|
| 112 | if ( qstrcmp(argv[i], "-help") == 0 ) {
|
|---|
| 113 | printUsage();
|
|---|
| 114 | return 0;
|
|---|
| 115 | } else if ( qstrcmp(argv[i], "-noobsolete") == 0 ) {
|
|---|
| 116 | noObsolete = TRUE;
|
|---|
| 117 | continue;
|
|---|
| 118 | } else if ( qstrcmp(argv[i], "-verbose") == 0 ) {
|
|---|
| 119 | verbose = TRUE;
|
|---|
| 120 | continue;
|
|---|
| 121 | } else if ( qstrcmp(argv[i], "-version") == 0 ) {
|
|---|
| 122 | fprintf( stderr, "lupdate version %s\n", QT_VERSION_STR );
|
|---|
| 123 | return 0;
|
|---|
| 124 | } else if ( qstrcmp(argv[i], "-ts") == 0 ) {
|
|---|
| 125 | metTsFlag = TRUE;
|
|---|
| 126 | continue;
|
|---|
| 127 | }
|
|---|
| 128 |
|
|---|
| 129 | numFiles++;
|
|---|
| 130 |
|
|---|
| 131 | QString fullText;
|
|---|
| 132 |
|
|---|
| 133 | if ( !metTsFlag ) {
|
|---|
| 134 | QFile f( argv[i] );
|
|---|
| 135 | if ( !f.open(IO_ReadOnly) ) {
|
|---|
| 136 | fprintf( stderr, "lupdate error: Cannot open file '%s': %s\n",
|
|---|
| 137 | argv[i], strerror(errno) );
|
|---|
| 138 | return 1;
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | QTextStream t( &f );
|
|---|
| 142 | fullText = t.read();
|
|---|
| 143 | f.close();
|
|---|
| 144 | }
|
|---|
| 145 |
|
|---|
| 146 | QString oldDir = QDir::currentDirPath();
|
|---|
| 147 | QDir::setCurrent( QFileInfo(argv[i]).dirPath() );
|
|---|
| 148 |
|
|---|
| 149 | if ( standardSyntax ) {
|
|---|
| 150 | fetchedTor = MetaTranslator();
|
|---|
| 151 | codec.truncate( 0 );
|
|---|
| 152 | tsFileNames.clear();
|
|---|
| 153 |
|
|---|
| 154 | QMap<QString, QString> tagMap = proFileTagMap( fullText );
|
|---|
| 155 | QMap<QString, QString>::Iterator it;
|
|---|
| 156 |
|
|---|
| 157 | for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
|
|---|
| 158 | QStringList toks = QStringList::split( ' ', it.data() );
|
|---|
| 159 | QStringList::Iterator t;
|
|---|
| 160 |
|
|---|
| 161 | for ( t = toks.begin(); t != toks.end(); ++t ) {
|
|---|
| 162 | if ( it.key() == "HEADERS" || it.key() == "SOURCES" ) {
|
|---|
| 163 | fetchtr_cpp( *t, &fetchedTor, defaultContext, TRUE );
|
|---|
| 164 | metSomething = TRUE;
|
|---|
| 165 | } else if ( it.key() == "INTERFACES" ||
|
|---|
| 166 | it.key() == "FORMS" ) {
|
|---|
| 167 | fetchtr_ui( *t, &fetchedTor, defaultContext, TRUE );
|
|---|
| 168 | fetchtr_cpp( *t + ".h", &fetchedTor, defaultContext,
|
|---|
| 169 | FALSE );
|
|---|
| 170 | metSomething = TRUE;
|
|---|
| 171 | } else if ( it.key() == "TRANSLATIONS" ) {
|
|---|
| 172 | tsFileNames.append( *t );
|
|---|
| 173 | metSomething = TRUE;
|
|---|
| 174 | } else if ( it.key() == "CODEC" ||
|
|---|
| 175 | it.key() == "DEFAULTCODEC" ) {
|
|---|
| 176 | codec = (*t).latin1();
|
|---|
| 177 | }
|
|---|
| 178 | }
|
|---|
| 179 | }
|
|---|
| 180 |
|
|---|
| 181 | updateTsFiles( fetchedTor, tsFileNames, codec, noObsolete,
|
|---|
| 182 | verbose );
|
|---|
| 183 |
|
|---|
| 184 | if ( !metSomething ) {
|
|---|
| 185 | fprintf( stderr,
|
|---|
| 186 | "lupdate warning: File '%s' does not look like a"
|
|---|
| 187 | " project file\n",
|
|---|
| 188 | argv[i] );
|
|---|
| 189 | } else if ( tsFileNames.isEmpty() ) {
|
|---|
| 190 | fprintf( stderr,
|
|---|
| 191 | "lupdate warning: Met no 'TRANSLATIONS' entry in"
|
|---|
| 192 | " project file '%s'\n",
|
|---|
| 193 | argv[i] );
|
|---|
| 194 | }
|
|---|
| 195 | } else {
|
|---|
| 196 | if ( metTsFlag ) {
|
|---|
| 197 | if ( QString(argv[i]).lower().endsWith(".ts") ) {
|
|---|
| 198 | QFileInfo fi( argv[i] );
|
|---|
| 199 | if ( !fi.exists() || fi.isWritable() ) {
|
|---|
| 200 | tsFileNames.append( argv[i] );
|
|---|
| 201 | } else {
|
|---|
| 202 | fprintf( stderr,
|
|---|
| 203 | "lupdate warning: For some reason, I cannot"
|
|---|
| 204 | " save '%s'\n",
|
|---|
| 205 | argv[i] );
|
|---|
| 206 | }
|
|---|
| 207 | } else {
|
|---|
| 208 | fprintf( stderr,
|
|---|
| 209 | "lupdate error: File '%s' lacks .ts extension\n",
|
|---|
| 210 | argv[i] );
|
|---|
| 211 | }
|
|---|
| 212 | } else {
|
|---|
| 213 | QFileInfo fi(argv[i]);
|
|---|
| 214 | if ( QString(argv[i]).lower().endsWith(".ui") ) {
|
|---|
| 215 | fetchtr_ui( fi.fileName(), &fetchedTor, defaultContext, TRUE );
|
|---|
| 216 | fetchtr_cpp( QString(fi.fileName()) + ".h", &fetchedTor,
|
|---|
| 217 | defaultContext, FALSE );
|
|---|
| 218 | } else {
|
|---|
| 219 | fetchtr_cpp( fi.fileName(), &fetchedTor, defaultContext, TRUE );
|
|---|
| 220 | }
|
|---|
| 221 | }
|
|---|
| 222 | }
|
|---|
| 223 | QDir::setCurrent( oldDir );
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | if ( !standardSyntax )
|
|---|
| 227 | updateTsFiles( fetchedTor, tsFileNames, codec, noObsolete, verbose );
|
|---|
| 228 |
|
|---|
| 229 | if ( numFiles == 0 ) {
|
|---|
| 230 | printUsage();
|
|---|
| 231 | return 1;
|
|---|
| 232 | }
|
|---|
| 233 | return 0;
|
|---|
| 234 | }
|
|---|