author | zecke <zecke> | 2004-01-09 19:13:35 (UTC) |
---|---|---|
committer | zecke <zecke> | 2004-01-09 19:13:35 (UTC) |
commit | 56bb9961db1158250bbfe971f4556b56c0bd6581 (patch) (side-by-side diff) | |
tree | a4f40da98f695b5aadd845b68aaab41ac3d81826 /development/translation/shared | |
parent | 6875988077013544246ae0df7cc2e5d538a7f152 (diff) | |
download | opie-56bb9961db1158250bbfe971f4556b56c0bd6581.zip opie-56bb9961db1158250bbfe971f4556b56c0bd6581.tar.gz opie-56bb9961db1158250bbfe971f4556b56c0bd6581.tar.bz2 |
Update lupdate and shared to Qt3.3 qt-copy sources
Some special replacement for $$(OPIEDIR) to make ar_* happy
Diffstat (limited to 'development/translation/shared') (more/less context) (ignore whitespace changes)
-rw-r--r-- | development/translation/shared/metatranslator.cpp | 34 | ||||
-rw-r--r-- | development/translation/shared/metatranslator.h | 16 | ||||
-rw-r--r-- | development/translation/shared/opie.h | 2 | ||||
-rw-r--r-- | development/translation/shared/proparser.cpp | 111 | ||||
-rw-r--r-- | development/translation/shared/proparser.h | 8 |
5 files changed, 144 insertions, 27 deletions
diff --git a/development/translation/shared/metatranslator.cpp b/development/translation/shared/metatranslator.cpp index a01e1eb..51270c5 100644 --- a/development/translation/shared/metatranslator.cpp +++ b/development/translation/shared/metatranslator.cpp @@ -1,586 +1,596 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of Qt Linguist. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** 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 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "metatranslator.h" #include <qapplication.h> #include <qcstring.h> #include <qfile.h> #include <qmessagebox.h> #include <qtextcodec.h> #include <qtextstream.h> #include <qxml.h> static bool encodingIsUtf8( const QXmlAttributes& atts ) { for ( int i = 0; i < atts.length(); i++ ) { // utf8="true" is a pre-3.0 syntax if ( atts.qName(i) == QString("utf8") ) { return ( atts.value(i) == QString("true") ); } else if ( atts.qName(i) == QString("encoding") ) { return ( atts.value(i) == QString("UTF-8") ); } } return FALSE; } class TsHandler : public QXmlDefaultHandler { public: TsHandler( MetaTranslator *translator ) : tor( translator ), type( MetaTranslatorMessage::Finished ), inMessage( FALSE ), ferrorCount( 0 ), contextIsUtf8( FALSE ), messageIsUtf8( FALSE ) { } virtual bool startElement( const QString& namespaceURI, const QString& localName, const QString& qName, const QXmlAttributes& atts ); virtual bool endElement( const QString& namespaceURI, const QString& localName, const QString& qName ); virtual bool characters( const QString& ch ); virtual bool fatalError( const QXmlParseException& exception ); private: MetaTranslator *tor; MetaTranslatorMessage::Type type; bool inMessage; QString context; QString source; QString comment; QString translation; QString accum; int ferrorCount; bool contextIsUtf8; bool messageIsUtf8; }; bool TsHandler::startElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName, const QXmlAttributes& atts ) { if ( qName == QString("byte") ) { for ( int i = 0; i < atts.length(); i++ ) { if ( atts.qName(i) == QString("value") ) { QString value = atts.value( i ); int base = 10; if ( value.startsWith("x") ) { base = 16; value = value.mid( 1 ); } int n = value.toUInt( 0, base ); if ( n != 0 ) accum += QChar( n ); } } } else { if ( qName == QString("context") ) { context.truncate( 0 ); source.truncate( 0 ); comment.truncate( 0 ); translation.truncate( 0 ); contextIsUtf8 = encodingIsUtf8( atts ); } else if ( qName == QString("message") ) { inMessage = TRUE; type = MetaTranslatorMessage::Finished; source.truncate( 0 ); comment.truncate( 0 ); translation.truncate( 0 ); messageIsUtf8 = encodingIsUtf8( atts ); } else if ( qName == QString("translation") ) { for ( int i = 0; i < atts.length(); i++ ) { if ( atts.qName(i) == QString("type") ) { if ( atts.value(i) == QString("unfinished") ) type = MetaTranslatorMessage::Unfinished; else if ( atts.value(i) == QString("obsolete") ) type = MetaTranslatorMessage::Obsolete; else type = MetaTranslatorMessage::Finished; } } } accum.truncate( 0 ); } return TRUE; } bool TsHandler::endElement( const QString& /* namespaceURI */, const QString& /* localName */, const QString& qName ) { if ( qName == QString("codec") || qName == QString("defaultcodec") ) { // "codec" is a pre-3.0 syntax tor->setCodec( accum ); } else if ( qName == QString("name") ) { context = accum; } else if ( qName == QString("source") ) { source = accum; } else if ( qName == QString("comment") ) { if ( inMessage ) { comment = accum; } else { if ( contextIsUtf8 ) - tor->insert( MetaTranslatorMessage(context.utf8(), "", + tor->insert( MetaTranslatorMessage(context.utf8(), + ContextComment, accum.utf8(), QString::null, TRUE, MetaTranslatorMessage::Unfinished) ); else - tor->insert( MetaTranslatorMessage(context.ascii(), "", + tor->insert( MetaTranslatorMessage(context.ascii(), + ContextComment, accum.ascii(), QString::null, FALSE, MetaTranslatorMessage::Unfinished) ); } } else if ( qName == QString("translation") ) { translation = accum; } else if ( qName == QString("message") ) { if ( messageIsUtf8 ) tor->insert( MetaTranslatorMessage(context.utf8(), source.utf8(), comment.utf8(), translation, TRUE, type) ); else tor->insert( MetaTranslatorMessage(context.ascii(), source.ascii(), comment.ascii(), translation, FALSE, type) ); inMessage = FALSE; } return TRUE; } bool TsHandler::characters( const QString& ch ) { QString t = ch; t.replace( "\r", "" ); accum += t; return TRUE; } bool TsHandler::fatalError( const QXmlParseException& exception ) { if ( ferrorCount++ == 0 ) { QString msg; msg.sprintf( "Parse error at line %d, column %d (%s).", exception.lineNumber(), exception.columnNumber(), exception.message().latin1() ); if ( qApp == 0 ) fprintf( stderr, "XML error: %s\n", msg.latin1() ); else QMessageBox::information( qApp->mainWidget(), QObject::tr("Qt Linguist"), msg ); } return FALSE; } static QString numericEntity( int ch ) { return QString( ch <= 0x20 ? "<byte value=\"x%1\"/>" : "&#x%1;" ) .arg( ch, 0, 16 ); } static QString protect( const QCString& str ) { QString result; int len = (int) str.length(); for ( int k = 0; k < len; k++ ) { switch( str[k] ) { case '\"': result += QString( """ ); break; case '&': result += QString( "&" ); break; case '>': result += QString( ">" ); break; case '<': result += QString( "<" ); break; case '\'': result += QString( "'" ); break; default: if ( (uchar) str[k] < 0x20 && str[k] != '\n' ) result += numericEntity( (uchar) str[k] ); else result += str[k]; } } return result; } static QString evilBytes( const QCString& str, bool utf8 ) { if ( utf8 ) { return protect( str ); } else { QString result; QCString t = protect( str ).latin1(); int len = (int) t.length(); for ( int k = 0; k < len; k++ ) { if ( (uchar) t[k] >= 0x7f ) result += numericEntity( (uchar) t[k] ); else result += QChar( t[k] ); } return result; } } MetaTranslatorMessage::MetaTranslatorMessage() : utfeight( FALSE ), ty( Unfinished ) { } MetaTranslatorMessage::MetaTranslatorMessage( const char *context, const char *sourceText, const char *comment, const QString& translation, bool utf8, Type type ) : QTranslatorMessage( context, sourceText, comment, translation ), utfeight( FALSE ), ty( type ) { /* Don't use UTF-8 if it makes no difference. UTF-8 should be reserved for the real problematic case: non-ASCII (possibly non-Latin-1) characters in .ui files. */ if ( utf8 ) { if ( sourceText != 0 ) { int i = 0; while ( sourceText[i] != '\0' ) { if ( (uchar) sourceText[i] >= 0x80 ) { utfeight = TRUE; break; } i++; } } if ( !utfeight && comment != 0 ) { int i = 0; while ( comment[i] != '\0' ) { if ( (uchar) comment[i] >= 0x80 ) { utfeight = TRUE; break; } i++; } } } } MetaTranslatorMessage::MetaTranslatorMessage( const MetaTranslatorMessage& m ) : QTranslatorMessage( m ), utfeight( m.utfeight ), ty( m.ty ) { } MetaTranslatorMessage& MetaTranslatorMessage::operator=( const MetaTranslatorMessage& m ) { QTranslatorMessage::operator=( m ); utfeight = m.utfeight; ty = m.ty; return *this; } bool MetaTranslatorMessage::operator==( const MetaTranslatorMessage& m ) const { return qstrcmp( context(), m.context() ) == 0 && qstrcmp( sourceText(), m.sourceText() ) == 0 && qstrcmp( comment(), m.comment() ) == 0; } bool MetaTranslatorMessage::operator<( const MetaTranslatorMessage& m ) const { int delta = qstrcmp( context(), m.context() ); if ( delta == 0 ) delta = qstrcmp( sourceText(), m.sourceText() ); if ( delta == 0 ) delta = qstrcmp( comment(), m.comment() ); return delta < 0; } MetaTranslator::MetaTranslator() - : codecName( "ISO-8859-1" ), codec( 0 ) { + clear(); } MetaTranslator::MetaTranslator( const MetaTranslator& tor ) : mm( tor.mm ), codecName( tor.codecName ), codec( tor.codec ) { - } MetaTranslator& MetaTranslator::operator=( const MetaTranslator& tor ) { mm = tor.mm; codecName = tor.codecName; codec = tor.codec; return *this; } -bool MetaTranslator::load( const QString& filename ) +void MetaTranslator::clear() { mm.clear(); + codecName = "ISO-8859-1"; + codec = 0; +} +bool MetaTranslator::load( const QString& filename ) +{ QFile f( filename ); if ( !f.open(IO_ReadOnly) ) return FALSE; QTextStream t( &f ); QXmlInputSource in( t ); QXmlSimpleReader reader; - // don't click on these! reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE ); reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE ); reader.setFeature( "http://trolltech.com/xml/features/report-whitespace" "-only-CharData", FALSE ); QXmlDefaultHandler *hand = new TsHandler( this ); reader.setContentHandler( hand ); reader.setErrorHandler( hand ); bool ok = reader.parse( in ); reader.setContentHandler( 0 ); reader.setErrorHandler( 0 ); delete hand; f.close(); - if ( !ok ) - mm.clear(); return ok; } bool MetaTranslator::save( const QString& filename ) const { QFile f( filename ); if ( !f.open(IO_WriteOnly) ) return FALSE; QTextStream t( &f ); t.setCodec( QTextCodec::codecForName("ISO-8859-1") ); t << "<!DOCTYPE TS><TS>\n"; if ( codecName != "ISO-8859-1" ) t << "<defaultcodec>" << codecName << "</defaultcodec>\n"; TMM::ConstIterator m = mm.begin(); while ( m != mm.end() ) { TMMInv inv; TMMInv::Iterator i; bool contextIsUtf8 = m.key().utf8(); QCString context = m.key().context(); QCString comment = ""; do { - if ( QCString(m.key().sourceText()).isEmpty() ) { + if ( QCString(m.key().sourceText()) == ContextComment ) { if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { contextIsUtf8 = m.key().utf8(); comment = QCString( m.key().comment() ); } } else { inv.insert( *m, m.key() ); } } while ( ++m != mm.end() && QCString(m.key().context()) == context ); t << "<context"; if ( contextIsUtf8 ) t << " encoding=\"UTF-8\""; t << ">\n"; t << " <name>" << evilBytes( context, contextIsUtf8 ) << "</name>\n"; if ( !comment.isEmpty() ) t << " <comment>" << evilBytes( comment, contextIsUtf8 ) << "</comment>\n"; for ( i = inv.begin(); i != inv.end(); ++i ) { // no need for such noise if ( (*i).type() == MetaTranslatorMessage::Obsolete && (*i).translation().isEmpty() ) continue; t << " <message"; if ( (*i).utf8() ) t << " encoding=\"UTF-8\""; t << ">\n" << " <source>" << evilBytes( (*i).sourceText(), (*i).utf8() ) << "</source>\n"; if ( !QCString((*i).comment()).isEmpty() ) t << " <comment>" << evilBytes( (*i).comment(), (*i).utf8() ) << "</comment>\n"; t << " <translation"; if ( (*i).type() == MetaTranslatorMessage::Unfinished ) t << " type=\"unfinished\""; else if ( (*i).type() == MetaTranslatorMessage::Obsolete ) t << " type=\"obsolete\""; t << ">" << protect( (*i).translation().utf8() ) << "</translation>\n"; t << " </message>\n"; } t << "</context>\n"; } t << "</TS>\n"; f.close(); return TRUE; } -bool MetaTranslator::release( const QString& filename, bool verbose ) const +bool MetaTranslator::release( const QString& filename, bool verbose, + QTranslator::SaveMode mode ) const { QTranslator tor( 0 ); int finished = 0; int unfinished = 0; int untranslated = 0; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) { if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { if ( m.key().translation().isEmpty() ) { untranslated++; } else { if ( m.key().type() == MetaTranslatorMessage::Unfinished ) unfinished++; else finished++; QCString context = m.key().context(); QCString sourceText = m.key().sourceText(); QCString comment = m.key().comment(); QString translation = m.key().translation(); /* Drop the comment in (context, sourceText, comment), unless (context, sourceText, "") already exists, or unless we already dropped the comment of (context, sourceText, comment0). */ if ( comment.isEmpty() || contains(context, sourceText, "") || !tor.findMessage(context, sourceText, "").translation() .isNull() ) { tor.insert( m.key() ); } else { tor.insert( QTranslatorMessage(context, sourceText, "", translation) ); } } } } - bool saved = tor.save( filename, QTranslator::Stripped ); + bool saved = tor.save( filename, mode ); if ( saved && verbose ) fprintf( stderr, " %d finished, %d unfinished and %d untranslated messages\n", finished, unfinished, untranslated ); return saved; } bool MetaTranslator::contains( const char *context, const char *sourceText, const char *comment ) const { return mm.find( MetaTranslatorMessage(context, sourceText, comment) ) != mm.end(); } void MetaTranslator::insert( const MetaTranslatorMessage& m ) { int pos = mm.count(); TMM::Iterator n = mm.find( m ); if ( n != mm.end() ) pos = *n; mm.replace( m, pos ); } void MetaTranslator::stripObsoleteMessages() { TMM newmm; TMM::Iterator m = mm.begin(); while ( m != mm.end() ) { if ( m.key().type() != MetaTranslatorMessage::Obsolete ) newmm.insert( m.key(), *m ); ++m; } mm = newmm; } void MetaTranslator::stripEmptyContexts() { TMM newmm; TMM::Iterator m = mm.begin(); while ( m != mm.end() ) { - if ( QCString(m.key().sourceText()).isEmpty() ) { + if ( QCString(m.key().sourceText()) == ContextComment ) { TMM::Iterator n = m; ++n; // the context comment is followed by other messages if ( n != newmm.end() && qstrcmp(m.key().context(), n.key().context()) == 0 ) newmm.insert( m.key(), *m ); } else { newmm.insert( m.key(), *m ); } ++m; } mm = newmm; } void MetaTranslator::setCodec( const char *name ) { const int latin1 = 4; codecName = name; codec = QTextCodec::codecForName( name ); if ( codec == 0 || codec->mibEnum() == latin1 ) codec = 0; } QString MetaTranslator::toUnicode( const char *str, bool utf8 ) const { if ( utf8 ) return QString::fromUtf8( str ); else if ( codec == 0 ) return QString( str ); else return codec->toUnicode( str ); } QValueList<MetaTranslatorMessage> MetaTranslator::messages() const { int n = mm.count(); TMM::ConstIterator *t = new TMM::ConstIterator[n + 1]; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) t[*m] = m; QValueList<MetaTranslatorMessage> val; for ( int i = 0; i < n; i++ ) val.append( t[i].key() ); delete[] t; return val; } QValueList<MetaTranslatorMessage> MetaTranslator::translatedMessages() const { QValueList<MetaTranslatorMessage> val; TMM::ConstIterator m; for ( m = mm.begin(); m != mm.end(); ++m ) { if ( m.key().type() == MetaTranslatorMessage::Finished ) val.append( m.key() ); } return val; } diff --git a/development/translation/shared/metatranslator.h b/development/translation/shared/metatranslator.h index d35b202..a13f462 100644 --- a/development/translation/shared/metatranslator.h +++ b/development/translation/shared/metatranslator.h @@ -1,99 +1,113 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of Qt Linguist. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** 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 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef METATRANSLATOR_H #define METATRANSLATOR_H #include <qmap.h> #include <qstring.h> #include <qtranslator.h> #include <qvaluelist.h> class QTextCodec; class MetaTranslatorMessage : public QTranslatorMessage { public: enum Type { Unfinished, Finished, Obsolete }; MetaTranslatorMessage(); MetaTranslatorMessage( const char *context, const char *sourceText, const char *comment, const QString& translation = QString::null, bool utf8 = FALSE, Type type = Unfinished ); MetaTranslatorMessage( const MetaTranslatorMessage& m ); MetaTranslatorMessage& operator=( const MetaTranslatorMessage& m ); void setType( Type nt ) { ty = nt; } Type type() const { return ty; } bool utf8() const { return utfeight; } bool operator==( const MetaTranslatorMessage& m ) const; bool operator!=( const MetaTranslatorMessage& m ) const { return !operator==( m ); } bool operator<( const MetaTranslatorMessage& m ) const; bool operator<=( const MetaTranslatorMessage& m ) { return !operator>( m ); } bool operator>( const MetaTranslatorMessage& m ) const { return this->operator<( m ); } bool operator>=( const MetaTranslatorMessage& m ) const { return !operator<( m ); } private: bool utfeight; Type ty; }; class MetaTranslator { public: MetaTranslator(); MetaTranslator( const MetaTranslator& tor ); MetaTranslator& operator=( const MetaTranslator& tor ); + void clear(); bool load( const QString& filename ); bool save( const QString& filename ) const; - bool release( const QString& filename, bool verbose = FALSE ) const; + bool release( const QString& filename, bool verbose = FALSE, + QTranslator::SaveMode mode = QTranslator::Stripped ) const; bool contains( const char *context, const char *sourceText, const char *comment ) const; void insert( const MetaTranslatorMessage& m ); void stripObsoleteMessages(); void stripEmptyContexts(); void setCodec( const char *name ); QString toUnicode( const char *str, bool utf8 ) const; QValueList<MetaTranslatorMessage> messages() const; QValueList<MetaTranslatorMessage> translatedMessages() const; private: typedef QMap<MetaTranslatorMessage, int> TMM; typedef QMap<int, MetaTranslatorMessage> TMMInv; TMM mm; QCString codecName; QTextCodec *codec; }; +/* + This is a quick hack. The proper way to handle this would be + to extend MetaTranslator's interface. +*/ +#define ContextComment "QT_LINGUIST_INTERNAL_CONTEXT_COMMENT" + #endif diff --git a/development/translation/shared/opie.h b/development/translation/shared/opie.h index 4646bb0..28b2a61 100644 --- a/development/translation/shared/opie.h +++ b/development/translation/shared/opie.h @@ -1,21 +1,21 @@ #ifndef OPIE_H #define OPIE_H #include <qstring.h> #include <qstringlist.h> class OPIE { public: static OPIE* self(); /** get the list of languages */ QStringList languageList(const QString& opiedir = QString::null)const; - QString opieDir(const QString& opieDir)const; + QString opieDir(const QString& opieDir = QString::null)const; private: OPIE(); ~OPIE(); static OPIE* m_self; }; #endif diff --git a/development/translation/shared/proparser.cpp b/development/translation/shared/proparser.cpp index 21d2f86..f616c5a 100644 --- a/development/translation/shared/proparser.cpp +++ b/development/translation/shared/proparser.cpp @@ -1,87 +1,174 @@ /********************************************************************** ** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. ** ** This file is part of Qt Linguist. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** 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 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #include "proparser.h" +#include <qfile.h> #include <qregexp.h> #include <qstringlist.h> +#include <qtextstream.h> + +#ifdef Q_OS_UNIX +#include <unistd.h> +#endif + +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + +QString loadFile( const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open(IO_ReadOnly) ) { + fprintf( stderr, "error: Cannot load '%s': %s\n", + file.name().latin1(), + file.errorString().latin1() ); + return QString(); + } + + QTextStream in( &file ); + return in.read(); +} -QMap<QString, QString> proFileTagMap( const QString& text ) +QMap<QString, QString> proFileTagMap( const QString& text, const QString& opieDir ) { QString t = text; /* + Process include() commands. + */ + QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)"); + int i = 0; + while ( (i = callToInclude.search(t, i)) != -1 ) { + QString after = loadFile( callToInclude.cap(1) ); + t.replace( i, callToInclude.matchedLength(), after ); + i += after.length(); + } + + /* Strip comments, merge lines ending with backslash, add spaces around '=' and '+=', replace '\n' with ';', and simplify white spaces. */ - t.replace( QRegExp(QString("#[^\n]$")), QString(" ") ); - t.replace( QRegExp(QString("\\\\\\s*\n")), QString(" ") ); + t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") ); + t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") ); t.replace( "=", QString(" = ") ); t.replace( "+ =", QString(" += ") ); t.replace( "\n", QString(";") ); t = t.simplifyWhiteSpace(); + /* + Populate tagMap with 'key = value' entries. + */ QMap<QString, QString> tagMap; - QStringList lines = QStringList::split( QChar(';'), t ); QStringList::Iterator line; for ( line = lines.begin(); line != lines.end(); ++line ) { QStringList toks = QStringList::split( QChar(' '), *line ); - if ( toks.count() >= 3 && + if ( toks.count() >= 3 && (toks[1] == QString("=") || toks[1] == QString("+=")) ) { QString tag = toks.first(); int k = tag.findRev( QChar(':') ); // as in 'unix:' if ( k != -1 ) tag = tag.mid( k + 1 ); toks.remove( toks.begin() ); QString action = toks.first(); toks.remove( toks.begin() ); if ( tagMap.contains(tag) ) { if ( action == QString("=") ) tagMap.replace( tag, toks.join(QChar(' ')) ); else tagMap[tag] += QChar( ' ' ) + toks.join( QChar(' ') ); } else { tagMap[tag] = toks.join( QChar(' ') ); } } } - QRegExp var( "\\$\\$[a-zA-Z0-9_]+" ); + /* + Expand $$variables within the 'value' part of a 'key = value' + pair. + */ + QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" ); QMap<QString, QString>::Iterator it; for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { int i = 0; - - while ( (i = var.search(it.data(), i)) != -1 ) { + while ( (i = var.search((*it), i)) != -1 ) { int len = var.matchedLength(); - QString invocation = (*it).mid( i + 2, len - 2 ); + QString invocation = var.cap(1); QString after; - if ( tagMap.contains(invocation) ) - after = tagMap[invocation]; - (*it).replace( i, len, after ); + + if ( invocation == "system" ) { + // skip system(); it will be handled in the next pass + ++i; + } else if ( invocation == "OPIEDIR") { + (*it).replace( i, len, opieDir ); + }else { + if ( tagMap.contains(invocation) ) + after = tagMap[invocation]; + (*it).replace( i, len, after ); + } + } + } + + /* + Execute system() calls. + */ + QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" ); + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + int i = 0; + while ( (i = callToSystem.search((*it), i)) != -1 ) { + /* + This code is stolen from qmake's project.cpp file. + Ideally we would use the same parser, so we wouldn't + have this code duplication. + */ + QString after; + char buff[256]; + FILE *proc = QT_POPEN( callToSystem.cap(1).latin1(), "r" ); + while ( proc && !feof(proc) ) { + int read_in = fread( buff, 1, 255, proc ); + if ( !read_in ) + break; + for ( int i = 0; i < read_in; i++ ) { + if ( buff[i] == '\n' || buff[i] == '\t' ) + buff[i] = ' '; + } + buff[read_in] = '\0'; + after += buff; + } + (*it).replace( i, callToSystem.matchedLength(), after ); i += after.length(); } } + return tagMap; } diff --git a/development/translation/shared/proparser.h b/development/translation/shared/proparser.h index 6a61d90..e5678d6 100644 --- a/development/translation/shared/proparser.h +++ b/development/translation/shared/proparser.h @@ -1,29 +1,35 @@ /********************************************************************** ** Copyright (C) 2000 Trolltech AS. All rights reserved. ** ** This file is part of Qt Linguist. ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. ** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** 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 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef PROPARSER_H #define PROPARSER_H #include <qmap.h> #include <qstring.h> -QMap<QString, QString> proFileTagMap( const QString& text ); +QMap<QString, QString> proFileTagMap( const QString& text, const QString& = QString::null ); #endif |