Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

proparser.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2000-2002 Trolltech AS.  All rights reserved.
00003 **
00004 ** This file is part of Qt Linguist.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00012 ** licenses may use this file in accordance with the Qt Commercial License
00013 ** Agreement provided with the Software.
00014 **
00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017 **
00018 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00019 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00020 **   information about Qt Commercial License Agreements.
00021 **
00022 ** Contact info@trolltech.com if any conditions of this licensing are
00023 ** not clear to you.
00024 **
00025 **********************************************************************/
00026 
00027 #include "proparser.h"
00028 
00029 #include <qfile.h>
00030 #include <qregexp.h>
00031 #include <qstringlist.h>
00032 #include <qtextstream.h>
00033 
00034 #ifdef Q_OS_UNIX
00035 #include <unistd.h>
00036 #endif
00037 
00038 #ifdef Q_OS_WIN32
00039 #define QT_POPEN _popen
00040 #else
00041 #define QT_POPEN popen
00042 #endif
00043 
00044 QString loadFile( const QString &fileName )
00045 {
00046     QFile file( fileName );
00047     if ( !file.open(IO_ReadOnly) ) {
00048         fprintf( stderr, "error: Cannot load '%s': %s\n",
00049                  file.name().latin1(),
00050                  file.errorString().latin1() );
00051         return QString();
00052     }
00053 
00054     QTextStream in( &file );
00055     return in.read();
00056 }
00057 
00058 QMap<QString, QString> proFileTagMap( const QString& text, const QString& opieDir )
00059 {
00060     QString t = text;
00061 
00062     /*
00063       Process include() commands.
00064     */
00065     QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)");
00066     int i = 0;
00067     while ( (i = callToInclude.search(t, i)) != -1 ) {
00068         QString after = loadFile( callToInclude.cap(1) );
00069         t.replace( i, callToInclude.matchedLength(), after );
00070         i += after.length();
00071     }
00072 
00073     /*
00074       Strip comments, merge lines ending with backslash, add
00075       spaces around '=' and '+=', replace '\n' with ';', and
00076       simplify white spaces.
00077     */
00078     t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );
00079     t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") );
00080     t.replace( "=", QString(" = ") );
00081     t.replace( "+ =", QString(" += ") );
00082     t.replace( "\n", QString(";") );
00083     t = t.simplifyWhiteSpace();
00084 
00085     /*
00086       Populate tagMap with 'key = value' entries.
00087     */
00088     QMap<QString, QString> tagMap;
00089     QStringList lines = QStringList::split( QChar(';'), t );
00090     QStringList::Iterator line;
00091     for ( line = lines.begin(); line != lines.end(); ++line ) {
00092         QStringList toks = QStringList::split( QChar(' '), *line );
00093 
00094         if ( toks.count() >= 3 &&
00095              (toks[1] == QString("=") || toks[1] == QString("+=")) ) {
00096             QString tag = toks.first();
00097             int k = tag.findRev( QChar(':') ); // as in 'unix:'
00098             if ( k != -1 )
00099                 tag = tag.mid( k + 1 );
00100             toks.remove( toks.begin() );
00101 
00102             QString action = toks.first();
00103             toks.remove( toks.begin() );
00104 
00105             if ( tagMap.contains(tag) ) {
00106                 if ( action == QString("=") )
00107                     tagMap.replace( tag, toks.join(QChar(' ')) );
00108                 else
00109                     tagMap[tag] += QChar( ' ' ) + toks.join( QChar(' ') );
00110             } else {
00111                 tagMap[tag] = toks.join( QChar(' ') );
00112             }
00113         }
00114     }
00115 
00116     /*
00117       Expand $$variables within the 'value' part of a 'key = value'
00118       pair.
00119     */
00120     QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
00121     QMap<QString, QString>::Iterator it;
00122     for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
00123         int i = 0;
00124         while ( (i = var.search((*it), i)) != -1 ) {
00125             int len = var.matchedLength();
00126             QString invocation = var.cap(1);
00127             QString after;
00128 
00129             if ( invocation == "system" ) {
00130                 // skip system(); it will be handled in the next pass
00131                 ++i;
00132             } else if ( invocation == "OPIEDIR") {
00133                 (*it).replace( i, len, opieDir );
00134             }else {
00135                 if ( tagMap.contains(invocation) )
00136                     after = tagMap[invocation];
00137                 (*it).replace( i, len, after );
00138                 i += after.length();
00139             }
00140         }
00141     }
00142 
00143     /*
00144       Execute system() calls.
00145     */
00146     QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" );
00147     for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
00148         int i = 0;
00149         while ( (i = callToSystem.search((*it), i)) != -1 ) {
00150             /*
00151               This code is stolen from qmake's project.cpp file.
00152               Ideally we would use the same parser, so we wouldn't
00153               have this code duplication.
00154             */
00155             QString after;
00156             char buff[256];
00157             FILE *proc = QT_POPEN( callToSystem.cap(1).latin1(), "r" );
00158             while ( proc && !feof(proc) ) {
00159                 int read_in = fread( buff, 1, 255, proc );
00160                 if ( !read_in )
00161                     break;
00162                 for ( int i = 0; i < read_in; i++ ) {
00163                     if ( buff[i] == '\n' || buff[i] == '\t' )
00164                         buff[i] = ' ';
00165                 }
00166                 buff[read_in] = '\0';
00167                 after += buff;
00168             }
00169             (*it).replace( i, callToSystem.matchedLength(), after );
00170             i += after.length();
00171         }
00172     }
00173 
00174     return tagMap;
00175 }

Generated on Sat Nov 5 16:15:58 2005 for OPIE by  doxygen 1.4.2