source: trunk/tools/porting/src/proparser.cpp@ 1028

Last change on this file since 1028 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 7.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the qt3to4 porting application of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "proparser.h"
43
44#include <QDir>
45#include <QFile>
46#include <QFileInfo>
47#include <QRegExp>
48#include <QStringList>
49#include <QTextStream>
50
51#ifdef Q_OS_UNIX
52#include <unistd.h>
53#endif
54
55#ifdef Q_OS_WIN32
56#define QT_POPEN _popen
57#else
58#define QT_POPEN popen
59#endif
60
61QT_BEGIN_NAMESPACE
62
63QString loadFile( const QString &fileName )
64{
65 QFile file( fileName );
66 if ( !file.open(QIODevice::ReadOnly) ) {
67 fprintf( stderr, "error: Cannot load '%s': %s\n",
68 file.fileName().toLocal8Bit().constData(),
69 file.errorString().toLatin1().constData() );
70 return QString();
71 }
72
73 QTextStream in( &file );
74 return in.readAll();
75}
76
77QMap<QString, QString> proFileTagMap( const QString& text, QString currentPath )
78{
79 QString t = text;
80 if (currentPath.isEmpty())
81 currentPath = QDir::currentPath();
82
83
84 QMap<QString, QString> tagMap;
85 /*
86 Strip any commments before we try to include. We
87 still need to do it after we include to make sure the
88 included file does not have comments
89 */
90 t.replace( QRegExp(QLatin1String("#[^\n]*\n")), QLatin1String(" ") );
91 /*
92 Strip comments, merge lines ending with backslash, add
93 spaces around '=' and '+=', replace '\n' with ';', and
94 simplify white spaces.
95 */
96 t.replace( QRegExp(QLatin1String("#[^\n]*\n")), QLatin1String(" ") );
97 t.replace( QRegExp(QLatin1String("\\\\[^\n\\S]*\n")), QLatin1String(" ") );
98 t.replace( QLatin1String("="), QLatin1String(" = ") );
99 t.replace( QLatin1String("+ ="), QLatin1String(" += ") );
100 t.replace( QLatin1String("\n"), QLatin1String(";") );
101 t = t.simplified();
102
103 /*
104 Populate tagMap with 'key = value' entries.
105 */
106 QStringList lines = t.split(QLatin1Char(';'));
107 QStringList::Iterator line;
108 for ( line = lines.begin(); line != lines.end(); ++line ) {
109 QStringList toks = (*line).split(QLatin1Char(' '), QString::SkipEmptyParts);
110
111 if ( toks.count() >= 3 &&
112 (toks[1] == QLatin1String("=") || toks[1] == QLatin1String("+=") ||
113 toks[1] == QLatin1String("*=")) ) {
114 QString tag = toks.first();
115 int k = tag.lastIndexOf( QLatin1Char(':') ); // as in 'unix:'
116 if ( k != -1 )
117 tag = tag.mid( k + 1 );
118 toks.erase( toks.begin() );
119
120 QString action = toks.first();
121 toks.erase( toks.begin() );
122
123 if ( tagMap.contains(tag) ) {
124 if ( action == QLatin1String("=") )
125 tagMap.insert( tag, toks.join(QLatin1String(" ")) );
126 else
127 tagMap[tag] += QLatin1Char( ' ' ) + toks.join( QLatin1String(" ") );
128 } else {
129 tagMap[tag] = toks.join( QLatin1String(" ") );
130 }
131 }
132 }
133 /*
134 Expand $$variables within the 'value' part of a 'key = value'
135 pair.
136 */
137 QRegExp var( QLatin1String("\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?") );
138 QMap<QString, QString>::Iterator it;
139 for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
140 int i = 0;
141 while ( (i = var.indexIn((*it), i)) != -1 ) {
142 int len = var.matchedLength();
143 QString invocation = var.cap(1);
144 QString after;
145
146 if ( invocation == QLatin1String("system") ) {
147 // skip system(); it will be handled in the next pass
148 ++i;
149 } else {
150 if ( tagMap.contains(invocation) )
151 after = tagMap[invocation];
152 else if (invocation.toLower() == QLatin1String("pwd"))
153 after = currentPath;
154 (*it).replace( i, len, after );
155 i += after.length();
156 }
157 }
158 }
159
160 /*
161 Execute system() calls.
162 */
163 QRegExp callToSystem( QLatin1String("\\$\\$system\\s*\\(([^()]*)\\)") );
164 for ( it = tagMap.begin(); it != tagMap.end(); ++it ) {
165 int i = 0;
166 while ( (i = callToSystem.indexIn((*it), i)) != -1 ) {
167 /*
168 This code is stolen from qmake's project.cpp file.
169 Ideally we would use the same parser, so we wouldn't
170 have this code duplication.
171 */
172 QString after;
173 char buff[256];
174 FILE *proc = QT_POPEN( callToSystem.cap(1).toLatin1().constData(), "r" );
175 while ( proc && !feof(proc) ) {
176 int read_in = int(fread( buff, 1, 255, proc ));
177 if ( !read_in )
178 break;
179 for ( int i = 0; i < read_in; i++ ) {
180 if ( buff[i] == '\n' || buff[i] == '\t' )
181 buff[i] = ' ';
182 }
183 buff[read_in] = '\0';
184 after += QLatin1String(buff);
185 }
186 (*it).replace( i, callToSystem.matchedLength(), after );
187 i += after.length();
188 }
189 }
190 return tagMap;
191}
192
193QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.