~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to tools/linguist/shared/proparser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the linguist application of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "proparser.h"
 
30
 
 
31
#include <qdir.h>
 
32
#include <qfile.h>
 
33
#include <qfileinfo.h>
 
34
#include <qregexp.h>
 
35
#include <qstringlist.h>
 
36
#include <qtextstream.h>
 
37
 
 
38
#ifdef Q_OS_UNIX
 
39
#include <unistd.h>
 
40
#endif
 
41
 
 
42
#ifdef Q_OS_WIN32
 
43
#define QT_POPEN _popen
 
44
#else
 
45
#define QT_POPEN popen
 
46
#endif
 
47
 
 
48
QString loadFile( const QString &fileName )
 
49
{
 
50
    QFile file( fileName );
 
51
    if ( !file.open(QIODevice::ReadOnly) ) {
 
52
        fprintf( stderr, "error: Cannot load '%s': %s\n",
 
53
                 file.fileName().toLatin1().constData(),
 
54
                 file.errorString().toLatin1().constData() );
 
55
        return QString();
 
56
    }
 
57
 
 
58
    QTextStream in( &file );
 
59
    return in.readAll();
 
60
}
 
61
 
 
62
QMap<QString, QString> proFileTagMap( const QString& text )
 
63
{
 
64
    QString t = text;
 
65
 
 
66
    QMap<QString, QString> tagMap;
 
67
    bool stillProcess = true; // If include() has a $$tag then we need to reprocess
 
68
 
 
69
    while(stillProcess) {
 
70
 
 
71
        /*
 
72
            Strip any commments before we try to include.  We
 
73
            still need to do it after we include to make sure the
 
74
            included file does not have comments
 
75
        */
 
76
        t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );
 
77
 
 
78
        /*
 
79
            Process include() commands.
 
80
            $$PWD is a special case so we have to change it while
 
81
            we know where the included file is.
 
82
        */
 
83
        QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)");
 
84
        int i = 0;
 
85
        while ( (i = callToInclude.indexIn(t, i)) != -1 ) {
 
86
            bool doneWithVar = false;
 
87
            QString fileName = callToInclude.cap(1);
 
88
            QString after = fileName.replace("$$PWD", QDir::currentPath());
 
89
            if (!tagMap.isEmpty() && after.contains("$$")) {
 
90
                QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
 
91
                int ii = 0;
 
92
                while ((ii = after.indexOf(var, ii)) != -1) {
 
93
                    if (tagMap.contains(var.cap(1))) {
 
94
                        after.replace(ii, var.cap(0).length(), tagMap[var.cap(1)]);
 
95
                    } else { // Couldn't find it
 
96
                        doneWithVar = true;
 
97
                        break;
 
98
                    }
 
99
                }
 
100
 
 
101
            }
 
102
            if (doneWithVar || !after.contains("$$")) {
 
103
                after = loadFile(after);
 
104
                QFileInfo fi(callToInclude.cap(1));
 
105
                after.replace("$$PWD", fi.path());
 
106
                t.replace( i, callToInclude.matchedLength(), after );
 
107
            }
 
108
            i += after.length();
 
109
        }
 
110
 
 
111
        /*
 
112
            Strip comments, merge lines ending with backslash, add
 
113
            spaces around '=' and '+=', replace '\n' with ';', and
 
114
            simplify white spaces.
 
115
        */
 
116
        t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );
 
117
        t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") );
 
118
        t.replace( "=", QString(" = ") );
 
119
        t.replace( "+ =", QString(" += ") );
 
120
        t.replace( "\n", QString(";") );
 
121
        t.replace( "\r", QString("") ); // remove carriage return
 
122
        t = t.simplified();
 
123
 
 
124
        /*
 
125
            Populate tagMap with 'key = value' entries.
 
126
        */
 
127
        QStringList lines = t.split(';');
 
128
        QStringList::Iterator line;
 
129
        for ( line = lines.begin(); line != lines.end(); ++line ) {
 
130
            QStringList toks = (*line).split(' ');
 
131
 
 
132
            if ( toks.count() >= 3 &&
 
133
                (toks[1] == QString("=") || toks[1] == QString("+=") ||
 
134
                toks[1] == QString("*=")) ) {
 
135
                QString tag = toks.first();
 
136
                int k = tag.lastIndexOf( QChar(':') ); // as in 'unix:'
 
137
                if ( k != -1 )
 
138
                    tag = tag.mid( k + 1 );
 
139
                toks.erase( toks.begin() );
 
140
 
 
141
                QString action = toks.first();
 
142
                toks.erase( toks.begin() );
 
143
 
 
144
                if ( tagMap.contains(tag) ) {
 
145
                    if ( action == QString("=") )
 
146
                        tagMap.insert( tag, toks.join(" ") );
 
147
                    else
 
148
                        tagMap[tag] += QChar( ' ' ) + toks.join( " " );
 
149
                } else {
 
150
                    tagMap[tag] = toks.join( " " );
 
151
                }
 
152
            }
 
153
        }
 
154
        /*
 
155
            Expand $$variables within the 'value' part of a 'key = value'
 
156
            pair.
 
157
        */
 
158
        QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
 
159
        QMap<QString, QString>::Iterator it;
 
160
        for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
 
161
            int i = 0;
 
162
            while ( (i = var.indexIn((*it), i)) != -1 ) {
 
163
                int len = var.matchedLength();
 
164
                QString invocation = var.cap(1);
 
165
                QString after;
 
166
 
 
167
                if ( invocation == "system" ) {
 
168
                    // skip system(); it will be handled in the next pass
 
169
                    ++i;
 
170
                } else {
 
171
                    if ( tagMap.contains(invocation) )
 
172
                        after = tagMap[invocation];
 
173
                    else if (invocation.toLower() == "pwd")
 
174
                        after = QDir::currentPath();
 
175
                    (*it).replace( i, len, after );
 
176
                    i += after.length();
 
177
                }
 
178
            }
 
179
        }
 
180
 
 
181
        /*
 
182
          Execute system() calls.
 
183
        */
 
184
        QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" );
 
185
        for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
 
186
            int i = 0;
 
187
            while ( (i = callToSystem.indexIn((*it), i)) != -1 ) {
 
188
                /*
 
189
                  This code is stolen from qmake's project.cpp file.
 
190
                  Ideally we would use the same parser, so we wouldn't
 
191
                  have this code duplication.
 
192
                */
 
193
                QString after;
 
194
                char buff[256];
 
195
                FILE *proc = QT_POPEN( callToSystem.cap(1).toLatin1().constData(), "r" );
 
196
                while ( proc && !feof(proc) ) {
 
197
                    int read_in = fread( buff, 1, 255, proc );
 
198
                    if ( !read_in )
 
199
                        break;
 
200
                    for ( int i = 0; i < read_in; i++ ) {
 
201
                        if ( buff[i] == '\n' || buff[i] == '\t' )
 
202
                            buff[i] = ' ';
 
203
                    }
 
204
                    buff[read_in] = '\0';
 
205
                    after += buff;
 
206
                }
 
207
                (*it).replace( i, callToSystem.matchedLength(), after );
 
208
                i += after.length();
 
209
            }
 
210
        }
 
211
        stillProcess = callToInclude.indexIn(t) != -1;
 
212
    }
 
213
    return tagMap;
 
214
}