summaryrefslogtreecommitdiffstats
path: root/tools/mergetr/mergetr.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:24:15 -0500
commitbd0f3345a938b35ce6a12f6150373b0955b8dd12 (patch)
tree7a520322212d48ebcb9fbe1087e7fca28b76185c /tools/mergetr/mergetr.cpp
downloadqt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.tar.gz
qt3-bd0f3345a938b35ce6a12f6150373b0955b8dd12.zip
Add Qt3 development HEAD version
Diffstat (limited to 'tools/mergetr/mergetr.cpp')
-rw-r--r--tools/mergetr/mergetr.cpp347
1 files changed, 347 insertions, 0 deletions
diff --git a/tools/mergetr/mergetr.cpp b/tools/mergetr/mergetr.cpp
new file mode 100644
index 0000000..c286a84
--- /dev/null
+++ b/tools/mergetr/mergetr.cpp
@@ -0,0 +1,347 @@
+/**********************************************************************
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This is a utility program for merging findtr msgfiles
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <qfile.h>
+#include <qbuffer.h>
+#include <qtextstream.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+bool isEmpty( const QString& line )
+{
+ int i = 0;
+ while ( i < int(line.length()) ) {
+ if ( !line[i].isSpace() )
+ return FALSE;
+ i++;
+ }
+ return TRUE;
+}
+
+
+bool hasHandle( const QString& line, const QString& handle)
+{
+ return line.left(handle.length()) == handle;
+}
+
+bool isUserComment( const QString& line )
+{
+ return line.length() > 2 && line[0] == '#' && line[1].isSpace();
+}
+
+bool isSystemComment( const QString& line )
+{
+ return line.length() > 1 && line[0] == '#' && !line[1].isSpace();
+}
+
+
+QString extractContents( const QString& line )
+{
+ QString contents;
+ int pos = 0;
+ bool inStr = FALSE;
+ while ( pos < int(line.length()) ) {
+ if ( line[pos] == '"' ) {
+ inStr = !inStr;
+ pos++;
+ } else {
+ if ( inStr ) {
+ if ( line[pos] == '\\') {
+ pos++;
+ switch (char(line[pos]) ) {
+ case 'n':
+ contents += '\n';
+ break;
+ case 't':
+ contents += '\t';
+ break;
+ case 'r':
+ contents += '\r';
+ break;
+ case 'a':
+ contents += '\a';
+ break;
+ case 'f':
+ contents += '\f';
+ break;
+ case 'v':
+ contents += '\v';
+ break;
+ case 'b':
+ contents += '\b';
+ break;
+ default:
+ contents += char(line[pos]);
+ break;
+ }
+ } else {
+ contents += line[pos];
+ }
+ }
+ pos++;
+ }
+ }
+ return contents;
+}
+
+struct Item
+{
+ Item() {}
+ Item( const Item &i ) :usercomments(i.usercomments),
+ systemcomments(i.systemcomments), msgid(i.msgid), msgstr(i.msgstr){}
+ Item &operator=( const Item &i ) {
+ usercomments = i.usercomments; systemcomments = i.systemcomments;
+ msgid = i.msgid; msgstr = i.msgstr;
+ return *this;
+ }
+ bool isNull() const { return usercomments.isNull()&&systemcomments.isNull()
+ &&msgstr.isNull() &&msgid.isNull(); }
+
+ QString usercomments;
+ QString systemcomments;
+ QString msgid;
+ QString msgstr;
+};
+
+enum Status { Equal, First, Second, FirstJunk, SecondJunk };
+
+Item getItem( QTextStream &str, QString &s )
+{
+ Item i;
+ while ( !str.atEnd() && s.isEmpty() ) {
+ s = str.readLine().stripWhiteSpace();
+ }
+ while ( !str.atEnd() && !s.isEmpty() ) {
+ if ( isSystemComment(s) ) {
+ i.systemcomments += s + "\n";
+ s = str.readLine().stripWhiteSpace();
+ } else if ( isUserComment(s) ) {
+ i.usercomments += s + "\n";
+ s = str.readLine().stripWhiteSpace();
+ } else if ( hasHandle( s, "msgid" ) ) {
+ QString r = s + "\n";
+ s = str.readLine().stripWhiteSpace();
+ while ( !str.atEnd() && hasHandle(s, "\"") ) {
+ r += s;
+ s = str.readLine().stripWhiteSpace();
+ r += "\n";
+ }
+ i.msgid = r;
+ } else if ( hasHandle( s, "msgstr" ) ) {
+ QString r = s + "\n";
+ s = str.readLine().stripWhiteSpace();
+ while ( hasHandle(s, "\"") ) {
+ r += s;
+ s = str.readLine().stripWhiteSpace();
+ r += "\n";
+ }
+ i.msgstr = r;
+ } else {
+ s = str.readLine().stripWhiteSpace();
+ }
+ }
+ return i;
+}
+
+static int nMerge, nNew, nOld, nJunk;
+
+
+void writecomment( QTextStream &str, const QString &s )
+{
+ if ( s.isEmpty() )
+ return;
+ int idx = 0;
+ int len = s.length();
+ while ( idx < len ) {
+ int nl = s.find( '\n', idx );
+ if ( nl < 0 ) {
+ qWarning( "writecomment: string lacks newline" );
+ str << "# " << s.mid( idx ) << '\n';
+ return;
+ }
+ str << "# " << s.mid( idx, nl-idx+1 );
+ idx = nl+1;
+ }
+}
+
+void writemerge( QTextStream &str, const Item &i1, const Item &i2 )
+{
+ nMerge++;
+ if ( !i2.usercomments.isEmpty() )
+ str << i2.usercomments;
+ if ( !i1.systemcomments.isEmpty() )
+ str << i1.systemcomments;
+ str << i1.msgid;
+ str << i2.msgstr;
+ str << "\n";
+}
+void writenew( QTextStream &str, const Item &i1 )
+{
+ nNew++;
+ if ( !i1.usercomments.isEmpty() )
+ str << i1.usercomments;
+ if ( !i1.systemcomments.isEmpty() )
+ str << i1.systemcomments;
+ str << i1.msgid;
+ str << i1.msgstr;
+ str << "\n";
+}
+
+void writeold( QTextStream &str, const Item &i2 )
+{
+ nOld++;
+ writecomment( str, i2.usercomments );
+ writecomment( str, i2.systemcomments );
+ writecomment( str, i2.msgid );
+ writecomment( str, i2.msgstr );
+ str << "\n";
+}
+
+void writejunk( QTextStream &str, const Item &it )
+{
+ nJunk++;
+ if ( !it.usercomments.isEmpty() )
+ str << it.usercomments;
+ writecomment( str, it.systemcomments );
+ writecomment( str, it.msgid );
+ writecomment( str, it.msgstr );
+ str << "\n";
+}
+
+Status compare( const Item &i1, const Item &i2 )
+{
+ if ( i1.isNull() && i2.isNull() )
+ return Equal;
+ if ( i1.isNull() )
+ return Second;
+ if ( i2.isNull() )
+ return First;
+ if ( i1.msgid.isEmpty() )
+ return FirstJunk;
+ if ( i2.msgid.isEmpty() )
+ return SecondJunk;
+ QString s1 = extractContents( i1.msgid );
+ QString s2 = extractContents( i2.msgid );
+ if ( !s1 && !s2 )
+ return Equal;
+ if ( !s1 )
+ return First;
+ if ( !s2 )
+ return Second;
+ int i = strcmp( s1.ascii(), s2.ascii() );
+ if ( i < 0 )
+ return First;
+ if ( i == 0 )
+ return Equal;
+ // i > 0
+ return Second;
+}
+
+void merge( const QString& newname, const QString& oldname,
+ const QString& resname )
+{
+ QFile f1(newname);
+ if ( !f1.open( IO_ReadOnly) )
+ return;
+
+ QFile f2(oldname);
+ if ( !f2.open( IO_ReadOnly) )
+ return;
+
+ QBuffer fout;
+ fout.open(IO_WriteOnly);
+
+ QTextStream in1( &f1 );
+ QTextStream in2( &f2 );
+ QTextStream out( &fout );
+
+ QString buf1 = in1.readLine().stripWhiteSpace();
+ QString buf2 = in2.readLine().stripWhiteSpace();
+
+ Item i1 = getItem( in1, buf1 );
+ Item i2 = getItem( in2, buf2 );
+ while ( !i1.isNull() || !i2.isNull() ) {
+ Status s = compare( i1, i2 );
+ if ( s == Equal ) {
+ writemerge(out,i1,i2);
+ i1 = getItem( in1, buf1 );
+ i2 = getItem( in2, buf2 );
+ } else if ( s == First ) {
+ writenew( out, i1 );
+ i1 = getItem( in1, buf1 );
+ } else if ( s == FirstJunk ) {
+ //solitary comment
+ writejunk( out, i1 );
+ i1 = getItem( in1, buf1 );
+ } else if ( s == Second ) {
+ writeold( out, i2 );
+ i2 = getItem( in2, buf2 );
+ } else if ( s == SecondJunk ) {
+ //solitary comment
+ writejunk( out, i2 );
+ i2 = getItem( in2, buf2 );
+ }
+ }
+
+ f1.close();
+ f2.close();
+ fout.close();
+ QFile fileout(resname);
+ if ( !fileout.open( IO_WriteOnly | IO_Translate ) )
+ return;
+ fileout.writeBlock(fout.buffer());
+ fileout.close();
+}
+
+
+int main( int argc, char* argv[] )
+{
+
+ int orgfile = 1;
+ int newfile = 2;
+
+ if ( argc <= newfile || argc > 1 && argv[1][0] == '-') {
+ printf("usage: %s orgfile newfile [outfile]\n", argv[0]);
+ exit(1);
+ }
+
+ merge( argv[newfile], argv[orgfile],
+ argc > newfile+1 ? argv[newfile+1] : argv[orgfile] );
+
+ printf( "Merged %d entries, added %d new entries and removed %d entries\n",
+ nMerge, nNew, nOld );
+ if ( nJunk > 0 )
+ printf( "Found %d junk entries\n", nJunk );
+ return 0;
+}