1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the linguist application of the Qt Toolkit.
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.
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.
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.
21
** Contact info@trolltech.com if any conditions of this licensing are
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.
27
****************************************************************************/
29
#include "proparser.h"
33
#include <qfileinfo.h>
35
#include <qstringlist.h>
36
#include <qtextstream.h>
43
#define QT_POPEN _popen
45
#define QT_POPEN popen
48
QString loadFile( const QString &fileName )
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() );
58
QTextStream in( &file );
62
QMap<QString, QString> proFileTagMap( const QString& text )
66
QMap<QString, QString> tagMap;
67
bool stillProcess = true; // If include() has a $$tag then we need to reprocess
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
76
t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") );
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.
83
QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)");
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_]+)[)}]?" );
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
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 );
112
Strip comments, merge lines ending with backslash, add
113
spaces around '=' and '+=', replace '\n' with ';', and
114
simplify white spaces.
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
125
Populate tagMap with 'key = value' entries.
127
QStringList lines = t.split(';');
128
QStringList::Iterator line;
129
for ( line = lines.begin(); line != lines.end(); ++line ) {
130
QStringList toks = (*line).split(' ');
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:'
138
tag = tag.mid( k + 1 );
139
toks.erase( toks.begin() );
141
QString action = toks.first();
142
toks.erase( toks.begin() );
144
if ( tagMap.contains(tag) ) {
145
if ( action == QString("=") )
146
tagMap.insert( tag, toks.join(" ") );
148
tagMap[tag] += QChar( ' ' ) + toks.join( " " );
150
tagMap[tag] = toks.join( " " );
155
Expand $$variables within the 'value' part of a 'key = value'
158
QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" );
159
QMap<QString, QString>::Iterator it;
160
for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
162
while ( (i = var.indexIn((*it), i)) != -1 ) {
163
int len = var.matchedLength();
164
QString invocation = var.cap(1);
167
if ( invocation == "system" ) {
168
// skip system(); it will be handled in the next pass
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 );
182
Execute system() calls.
184
QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" );
185
for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
187
while ( (i = callToSystem.indexIn((*it), i)) != -1 ) {
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.
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 );
200
for ( int i = 0; i < read_in; i++ ) {
201
if ( buff[i] == '\n' || buff[i] == '\t' )
204
buff[read_in] = '\0';
207
(*it).replace( i, callToSystem.matchedLength(), after );
211
stillProcess = callToInclude.indexIn(t) != -1;