summaryrefslogtreecommitdiffstats
path: root/buildtools/qmake/scope.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch)
treeacaf47eb0fa12142d3896416a69e74cbf5a72242 /buildtools/qmake/scope.cpp
downloadtdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz
tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'buildtools/qmake/scope.cpp')
-rw-r--r--buildtools/qmake/scope.cpp1710
1 files changed, 1710 insertions, 0 deletions
diff --git a/buildtools/qmake/scope.cpp b/buildtools/qmake/scope.cpp
new file mode 100644
index 00000000..c090861b
--- /dev/null
+++ b/buildtools/qmake/scope.cpp
@@ -0,0 +1,1710 @@
+/***************************************************************************
+* Copyright (C) 2006 by Andreas Pakulat *
+* apaku@gmx.de *
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+***************************************************************************/
+
+#include "scope.h"
+
+#include <kdebug.h>
+
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qdir.h>
+#include <qpair.h>
+#include <qmakedriver.h>
+#include <qregexp.h>
+#include <qtimer.h>
+
+#include <kdirwatch.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <stdlib.h>
+
+#include "urlutil.h"
+#include "trollprojectpart.h"
+#include "qmakedefaultopts.h"
+
+const QStringList Scope::KnownVariables = QStringList() << "QT" << "CONFIG" << "TEMPLATE" << "SUBDIRS" << "VERSION" << "LIBS" << "target.path" << "INSTALLS" << "MAKEFILE" << "TARGETDEPS" << "INCLUDEPATH" << "TARGET" << "DESTDIR" << "DEFINES" << "QMAKE_CXXFLAGS_DEBUG" << "QMAKE_CXXFLAGS_RELEASE" << "OBJECTS_DIR" << "UI_DIR" << "MOC_DIR" << "IDL_COMPILER" << "IDL_OPTIONS" << "RCC_DIR" << "IDLS" << "RESOURCES" << "IMAGES" << "LEXSOURCES" << "DISTFILES" << "YACCSOURCES" << "TRANSLATIONS" << "HEADERS" << "SOURCES" << "INTERFACES" << "FORMS" ;
+
+const QStringList Scope::KnownConfigValues = QStringList() << "debug" << "release" << "debug_and_release" << "warn_on" << "warn_off" << "staticlib" << "dll" << "plugin" << "designer" << "create_pkgconf" << "create_libtool" << "qt" << "console" << "windows" << "x11" << "thread" << "exceptions" << "stl" << "rtti" << "opengl" << "thread" << "ordered" << "precompile_header" << "qtestlib" << "uitools" << "dbus" << "assistant" << "build_all" << "help";
+
+Scope::Scope( const QMap<QString, QString>& env, const QString &filename, TrollProjectPart* part )
+ : m_root( 0 ), m_incast( 0 ), m_parent( 0 ), m_num(0), m_isEnabled( true ), m_part(part), m_defaultopts(0), m_environment( env )
+{
+ if ( !loadFromFile( filename ) )
+ {
+ if( !QFileInfo( filename ).exists() )
+ {
+ m_root = new QMake::ProjectAST();
+ m_root->setFileName( filename );
+ }else
+ {
+ delete m_root;
+ m_root = 0;
+ }
+ }
+ loadDefaultOpts();
+ if( m_root )
+ {
+ m_part->dirWatch()->addFile(filename);
+ }
+ init();
+}
+
+Scope::~Scope()
+{
+ QMap<unsigned int, Scope*>::iterator it;
+ for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it )
+ {
+ Scope* s = it.data();
+ delete s;
+ }
+ m_scopes.clear();
+
+ m_customVariables.clear();
+ if ( m_root && m_root->isProject() && !m_incast )
+ {
+ delete m_root;
+ m_root = 0;
+ delete m_defaultopts;
+ m_defaultopts = 0;
+ }
+
+}
+
+// Simple/Function Scopes
+Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::ProjectAST* scope,
+ QMakeDefaultOpts* defaultopts, TrollProjectPart* part )
+ : m_root( scope ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( true ),
+ m_part(part), m_defaultopts(defaultopts), m_environment( env )
+{
+ init();
+}
+
+//Subdirs
+Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, const QString& filename,
+ TrollProjectPart* part, bool isEnabled )
+ : m_root( 0 ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( isEnabled ),
+ m_part(part), m_defaultopts(0), m_environment( env )
+{
+ if ( !loadFromFile( filename ) )
+ {
+ if( !QFileInfo( filename ).exists() && QFileInfo( QFileInfo( filename ).dirPath( true ) ).exists() )
+ {
+ m_root = new QMake::ProjectAST();
+ m_root->setFileName( filename );
+ }else
+ {
+ delete m_root;
+ m_root = 0;
+ m_isEnabled = false;
+ }
+ }
+ loadDefaultOpts();
+ if( m_root )
+ m_part->dirWatch()->addFile(filename);
+ init();
+}
+
+//Include Scope
+Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::IncludeAST* incast, const QString& path,
+ const QString& incfile, QMakeDefaultOpts* defaultopts, TrollProjectPart* part )
+ : m_root( 0 ), m_incast( incast ), m_parent( parent ), m_num(num), m_isEnabled( true ),
+ m_part(part), m_defaultopts(defaultopts), m_environment( env )
+{
+ QString absfilename;
+ QString tmp = incfile.stripWhiteSpace();
+ if( tmp.contains(")" ) )
+ tmp = tmp.mid(0, tmp.find(")") );
+
+ if( tmp.startsWith( "\"" ) )
+ tmp = tmp.mid( 1, tmp.length()-2 );
+
+ if( QFileInfo(tmp).isRelative() )
+ {
+ absfilename = QDir::cleanDirPath( path + QString( QChar( QDir::separator() ) ) + tmp );
+ }else
+ absfilename = QDir::cleanDirPath( tmp );
+ if ( !loadFromFile( absfilename ) )
+ {
+ if( !QFileInfo( absfilename ).exists() && QFileInfo( QFileInfo( absfilename ).dirPath( true ) ).exists() )
+ {
+ m_root = new QMake::ProjectAST();
+ m_root->setFileName( absfilename );
+ }else
+ {
+ delete m_root;
+ m_root = 0;
+ m_isEnabled = false;
+ }
+ }
+ if( m_root )
+ m_part->dirWatch()->addFile( m_root->fileName() );
+ init();
+}
+
+bool Scope::loadFromFile( const QString& filename )
+{
+ if ( !QFileInfo(filename).exists() || QMake::Driver::parseFile( filename, &m_root, 0 ) != 0 )
+ {
+ kdDebug( 9024 ) << "Couldn't parse project: " << filename << endl;
+ if( DomUtil::readBoolEntry( *m_part->projectDom(),
+ "/kdevtrollproject/qmake/showParseErrors", true ) )
+ {
+ KMessageBox::error( 0, i18n( "Could not parse project file: %1" ).arg( filename ),
+ i18n( "Could not parse project file" ) );
+ }
+ m_root = 0;
+ return false;
+ }
+// init();
+ return true;
+}
+
+void Scope::saveToFile() const
+{
+ if ( !m_root )
+ return ;
+
+ if ( scopeType() != ProjectScope && scopeType() != IncludeScope )
+ {
+ m_parent->saveToFile();
+ return;
+ }
+
+ QString filename;
+ if ( scopeType() == ProjectScope )
+ filename = m_root->fileName() ;
+ else if ( scopeType() == IncludeScope )
+ filename = m_parent->projectDir() + QString( QChar( QDir::separator() ) ) + m_incast->projectName;
+ if ( filename.isEmpty() )
+ return ;
+ m_part->dirWatch()->stopScan();
+ QFile file( filename );
+ if ( file.open( IO_WriteOnly ) )
+ {
+
+ QTextStream out( &file );
+ QString astbuffer;
+ m_root->writeBack( astbuffer );
+ out << astbuffer;
+ file.close();
+ }else
+ {
+ KMessageBox::error( 0, i18n( "Could not write project file: %1" ).arg( filename ),
+ i18n( "Could not write project file" ) );
+ }
+#ifdef DEBUG
+ Scope::PrintAST pa;
+ pa.processProject(m_root);
+#endif
+ m_part->dirWatch()->startScan();
+}
+
+void Scope::addToPlusOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "+=", values, false );
+}
+
+void Scope::removeFromPlusOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "+=", values, true );
+}
+
+
+void Scope::addToMinusOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "-=", values, false );
+}
+
+void Scope::removeFromMinusOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "-=", values, true );
+}
+
+void Scope::addToEqualOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "=", values, false );
+}
+
+void Scope::removeFromEqualOp( const QString& variable, const QStringList& values )
+{
+ if ( !m_root )
+ return ;
+
+ updateVariable( variable, "=", values, true );
+}
+
+void Scope::setPlusOp( const QString& variable, const QStringList& values )
+{
+ if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "+=") ) )
+ return;
+
+ updateVariable( variable, "+=", variableValuesForOp( variable, "+=" ), true );
+ updateVariable( variable, "+=", values, false );
+}
+
+void Scope::setEqualOp( const QString& variable, const QStringList& values )
+{
+ if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "=") ) )
+ return;
+
+ updateVariable( variable, "=", variableValuesForOp( variable, "=" ), true );
+ updateVariable( variable, "=", values, false );
+}
+
+void Scope::setMinusOp( const QString& variable, const QStringList& values )
+{
+ if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "-=") ) )
+ return;
+
+ updateVariable( variable, "-=", variableValuesForOp( variable, "-=" ), true );
+ updateVariable( variable, "-=", values, false );
+}
+
+QStringList Scope::variableValuesForOp( const QString& variable , const QString& op ) const
+{
+ QStringList result;
+
+ if( !m_root )
+ return result;
+
+ QValueList<QMake::AST*>::const_iterator it;
+ for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it )
+ {
+ QMake::AST* ast = *it;
+ if ( ast->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * assign = static_cast<QMake::AssignmentAST*>( ast );
+ if ( assign->scopedID == variable && assign->op == op )
+ {
+ result += assign->values;
+ }
+ }
+ }
+ result = cleanStringList(result);
+ return result;
+}
+
+QStringList Scope::variableValues( const QString& variable, bool checkIncParent, bool fetchFromParent, bool evaluateSubScopes )
+{
+ QStringList result;
+
+ if ( !m_root )
+ return result;
+
+ if( m_varCache.contains( variable ) && fetchFromParent && ( checkIncParent || scopeType() != Scope::IncludeScope ) )
+ {
+ return m_varCache[variable];
+ }
+
+ calcValuesFromStatements( variable, result, checkIncParent, 0, fetchFromParent, true, evaluateSubScopes );
+ result = cleanStringList(result);
+ if( ( scopeType() != Scope::IncludeScope || checkIncParent ) && fetchFromParent )
+ {
+ m_varCache[ variable ] = result;
+ }
+ return result;
+}
+
+void Scope::calcValuesFromStatements( const QString& variable, QStringList& result, bool checkIncParent, QMake::AST* stopHere, bool fetchFromParent, bool setDefault, bool evaluateSubScopes ) const
+{
+ if( !m_root )
+ return;
+
+ /* For variables that we don't know and which are not QT/CONFIG find the default value */
+ if( setDefault && m_defaultopts
+ && m_defaultopts->variables().findIndex(variable) != -1
+ && ( variable == "TEMPLATE" || variable == "QT" || KnownVariables.findIndex(variable) == -1 || variable == "CONFIG" ) )
+ {
+ result = m_defaultopts->variableValues(variable);
+ }
+
+ if ( ( scopeType() == FunctionScope || scopeType() == SimpleScope ) && fetchFromParent )
+ {
+ m_parent->calcValuesFromStatements( variable, result, checkIncParent, this->m_root, fetchFromParent, setDefault, evaluateSubScopes );
+ }
+ else if ( scopeType() == IncludeScope && checkIncParent && fetchFromParent )
+ {
+ m_parent->calcValuesFromStatements( variable, result, true, this->m_incast, fetchFromParent, setDefault, evaluateSubScopes );
+ }
+
+ QValueList<QMake::AST*>::const_iterator it;
+ for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it )
+ {
+ if ( stopHere && *it == stopHere )
+ return ;
+ QMake::AST* ast = *it;
+ if ( ast->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * assign = static_cast<QMake::AssignmentAST*>( ast );
+ if ( assign->scopedID == variable )
+ {
+ if ( assign->op == "=" )
+ {
+ result = assign->values;
+ }
+ else if ( assign->op == "+=" )
+ {
+ for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit )
+ {
+ if ( result.findIndex( *sit ) == -1 )
+ result.append( *sit );
+ }
+ }
+ else if ( assign->op == "-=" )
+ {
+ for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit )
+ {
+ if ( result.findIndex( *sit ) != -1 )
+ result.remove( *sit );
+ }
+ }
+ }
+ }else if( evaluateSubScopes )
+ {
+ if( ast->nodeType() == QMake::AST::IncludeAST )
+ {
+ QMake::IncludeAST* iast = static_cast<QMake::IncludeAST*>(ast);
+ QValueList<unsigned int> l = m_scopes.keys();
+ for( unsigned int i = 0; i < l.count(); ++i )
+ {
+ int num = l[ i ];
+ if( m_scopes.contains( num ) )
+ {
+ Scope* s = m_scopes[num];
+ if( s && s->scopeType() == IncludeScope && s->m_incast == iast )
+ {
+ s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes );
+ }
+ }
+ }
+
+ }
+ else if( ast->nodeType() == QMake::AST::ProjectAST )
+ {
+ QMake::ProjectAST* past = static_cast<QMake::ProjectAST*>(ast);
+ if( past->isFunctionScope() || past->isScope() )
+ {
+ QValueList<unsigned int> l = m_scopes.keys();
+ for( unsigned int i = 0; i < l.count(); ++i )
+ {
+ int num = l[ i ];
+ if( m_scopes.contains( num ) )
+ {
+ Scope* s = m_scopes[num];
+ if( s && s->m_root == past && s->m_root->scopedID == past->scopedID )
+ {
+ s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ result = cleanStringList( result );
+ return ;
+}
+
+Scope::ScopeType Scope::scopeType() const
+{
+ if ( !m_root )
+ return InvalidScope;
+ else if ( m_incast )
+ return IncludeScope;
+ else if ( m_root->isProject() )
+ return ProjectScope;
+ else if ( m_root->isScope() )
+ return SimpleScope;
+ else if ( m_root->isFunctionScope() )
+ return FunctionScope;
+ return InvalidScope;
+}
+
+QString Scope::scopeName() const
+{
+ if ( !m_root )
+ return "";
+ if ( m_incast )
+ return "include<" + m_incast->projectName + ">";
+ else if ( m_root->isFunctionScope() )
+ return funcScopeKey( m_root );
+ else if ( m_root->isScope() )
+ return m_root->scopedID;
+ else if ( m_root->isProject() )
+ {
+ if( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) != QDir::cleanDirPath( projectDir() ) )
+ {
+ return URLUtil::getRelativePath( m_parent->projectDir(), projectDir() );
+ }else if ( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) == QDir::cleanDirPath( projectDir() ) )
+ {
+ return fileName();
+ }else
+ return QFileInfo( projectDir() ).fileName() ;
+ }
+ return QString();
+}
+
+QString Scope::fileName() const
+{
+ if( !m_root )
+ return "";
+ if ( m_incast )
+ return m_incast->projectName;
+ else if ( m_root->isProject() )
+ return QFileInfo( m_root->fileName() ).fileName();
+ else
+ return m_parent->fileName();
+}
+
+Scope* Scope::createFunctionScope( const QString& funcName, const QString& args )
+{
+ if ( !m_root )
+ return 0;
+
+ QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::FunctionScope );
+ ast->scopedID = funcName;
+ ast->args = args;
+ ast->setDepth( m_root->depth() );
+ ast->addChildAST( new QMake::NewLineAST() );
+ m_root->addChildAST( ast );
+ m_root->addChildAST( new QMake::NewLineAST() );
+ Scope* funcScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part );
+ if( funcScope->scopeType() != Scope::InvalidScope )
+ {
+ m_scopes.insert( getNextScopeNum(), funcScope );
+ return funcScope;
+ }else
+ delete funcScope;
+ return 0;
+}
+
+Scope* Scope::createSimpleScope( const QString& scopename )
+{
+ if ( !m_root )
+ return 0;
+
+ QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::Scope );
+ ast->scopedID = scopename;
+ ast->addChildAST( new QMake::NewLineAST() );
+ ast->setDepth( m_root->depth() );
+ m_root->addChildAST( ast );
+ m_root->addChildAST( new QMake::NewLineAST() );
+ /* We can't unconditionally add the scope name to CONFIG, scope might be win32 which may only be in CONFIG under windows.
+ if ( m_part->isQt4Project() )
+ addToPlusOp( "CONFIG", QStringList( scopename ) );
+ */
+ Scope* simpleScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part );
+
+ if( simpleScope->scopeType() != Scope::InvalidScope )
+ {
+ m_scopes.insert( getNextScopeNum(), simpleScope );
+ return simpleScope;
+ }else
+ delete simpleScope;
+ return 0;
+
+}
+
+Scope* Scope::createIncludeScope( const QString& includeFile, bool negate )
+{
+ if ( !m_root )
+ return 0;
+
+ Scope* funcScope;
+ if ( negate )
+ {
+ funcScope = createFunctionScope( "!include", includeFile );
+ }
+ else
+ {
+ funcScope = createFunctionScope( "include", includeFile );
+ }
+ if( funcScope == 0 )
+ return 0;
+
+ QMake::IncludeAST* ast = new QMake::IncludeAST();
+ ast->setDepth( m_root->depth() );
+ ast->projectName = includeFile;
+ Scope* incScope = new Scope( m_environment, funcScope->getNextScopeNum(), funcScope, ast, projectDir(), resolveVariables( ast->projectName ), m_defaultopts, m_part );
+ if ( incScope->scopeType() != InvalidScope )
+ {
+ funcScope->m_root->addChildAST( ast );
+ funcScope->m_scopes.insert( funcScope->getNextScopeNum(), incScope );
+ return funcScope;
+ }
+ else
+ {
+ deleteFunctionScope( m_scopes.keys().last() );
+ delete incScope;
+ }
+ return 0;
+
+}
+
+Scope* Scope::createSubProject( const QString& projname )
+{
+ if( !m_root )
+ return 0;
+
+ if( variableValuesForOp( "SUBDIRS", "-=").findIndex( projname ) != -1 )
+ removeFromMinusOp( "SUBDIRS", projname );
+
+ QString realprojname = resolveVariables(projname);
+
+ if( variableValuesForOp( "SUBDIRS", "-=").findIndex( realprojname ) != -1 )
+ removeFromMinusOp( "SUBDIRS", realprojname );
+
+ QDir curdir( projectDir() );
+
+ if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 )
+ {
+ QString filename;
+ if( !realprojname.endsWith(".pro") )
+ {
+ if ( !curdir.exists( realprojname ) )
+ if ( !curdir.mkdir( realprojname ) )
+ return 0;
+ curdir.cd( realprojname );
+ QStringList entries = curdir.entryList("*.pro", QDir::Files);
+
+ if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) == -1 )
+ filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first();
+ else
+ filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro";
+ }else
+ filename = curdir.absPath() + QString(QChar(QDir::separator())) + realprojname;
+
+ kdDebug( 9024 ) << "Creating subproject with filename:" << filename << endl;
+
+ Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part );
+ s->loadDefaultOpts();
+ if ( s->scopeType() != InvalidScope )
+ {
+ if( s->variableValues("TEMPLATE").isEmpty() )
+ s->setEqualOp("TEMPLATE", QStringList("app"));
+ s->saveToFile();
+ addToPlusOp( "SUBDIRS", QStringList( realprojname ) );
+ m_scopes.insert( getNextScopeNum(), s );
+ return s;
+ } else
+ {
+ delete s;
+ }
+ }
+
+ return 0;
+}
+
+bool Scope::deleteFunctionScope( unsigned int num )
+{
+ if ( !m_root || !m_scopes.contains( num ) )
+ return false;
+
+ Scope* funcScope = m_scopes[ num ];
+ if ( funcScope )
+ {
+ QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( funcScope->m_root ) ];
+ if( !ast )
+ return false;
+ m_scopes.remove( num );
+ m_root->removeChildAST( funcScope->m_root );
+ delete funcScope;
+ delete ast;
+ return true;
+ }
+ return false;
+}
+
+bool Scope::deleteSimpleScope( unsigned int num )
+{
+ if ( !m_root || !m_scopes.contains( num ) )
+ return false;
+
+ Scope* simpleScope = m_scopes[ num ];
+ if ( simpleScope )
+ {
+ QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( simpleScope->m_root ) ];
+ if( !ast )
+ return false;
+ m_scopes.remove( num );
+ removeFromPlusOp( "CONFIG", simpleScope->m_root->scopedID );
+ m_root->removeChildAST( simpleScope->m_root );
+ delete simpleScope;
+ delete ast;
+ return true;
+ }
+ return false;
+}
+
+bool Scope::deleteIncludeScope( unsigned int num )
+{
+ if ( !m_root || !m_scopes.contains( num ) )
+ return false;
+
+ Scope * incScope = m_scopes[ num ];
+ if( !incScope )
+ return false;
+ QMake::AST* ast = incScope->m_incast;
+ if( !ast )
+ return false;
+ m_scopes.remove( num );
+ m_root->removeChildAST( incScope->m_incast);
+ delete incScope;
+ delete ast;
+
+ return m_parent->deleteFunctionScope( getNum() );
+}
+
+bool Scope::deleteSubProject( unsigned int num, bool deleteSubdir )
+{
+ if ( !m_root || !m_scopes.contains( num ) )
+ return false;
+
+ QValueList<QMake::AST*>::iterator it = findExistingVariable( "TEMPLATE" );
+ if ( it != m_root->m_children.end() )
+ {
+ QMake::AssignmentAST * tempast = static_cast<QMake::AssignmentAST*>( *it );
+ if ( tempast->values.findIndex( "subdirs" ) != -1 || findExistingVariable( "TEMPLATE" ) != m_root->m_children.end() )
+ {
+ Scope* project = m_scopes[ num ];
+ if( !project )
+ return false;
+
+ QString projdir = project->scopeName();
+ if ( deleteSubdir )
+ {
+ QDir projdir = QDir( projectDir() );
+ QString dir = project->scopeName();
+ if( !dir.endsWith(".pro") )
+ {
+ QDir subdir = QDir( projectDir() + QString( QChar( QDir::separator() ) ) + dir );
+ if ( subdir.exists() )
+ {
+ QStringList entries = subdir.entryList();
+ for ( QStringList::iterator eit = entries.begin() ; eit != entries.end() ; ++eit )
+ {
+ if( *eit == "." || *eit == ".." )
+ continue;
+ if( !subdir.remove( *eit ) )
+ kdDebug( 9024 ) << "Couldn't delete " << *eit << " from " << subdir.absPath() << endl;
+ }
+ if( !projdir.rmdir( dir ) )
+ kdDebug( 9024 ) << "Couldn't delete " << dir << " from " << projdir.absPath() << endl;
+ }
+ }else
+ {
+ QDir d( project->projectDir() );
+ kdDebug(9024) << "removed subproject?:" << d.remove( dir ) << endl;
+ }
+ }
+ QValueList<QMake::AST*>::iterator foundit = findExistingVariable( "SUBDIRS" );
+ if ( foundit != m_root->m_children.end() )
+ {
+ QMake::AssignmentAST * ast = static_cast<QMake::AssignmentAST*>( *foundit );
+ updateValues( ast->values, QStringList( projdir ), true, ast->indent );
+ if( m_varCache.contains( "SUBDIRS" ) )
+ m_varCache.erase( "SUBDIRS" );
+ }else
+ return false;
+ m_scopes.remove( num );
+ delete project;
+ return true;
+ }
+ }
+ return false;
+}
+
+void Scope::updateValues( QStringList& origValues, const QStringList& newValues, bool remove, QString indent )
+{
+ if( !m_root )
+ return;
+
+ for ( QStringList::const_iterator it = newValues.begin(); it != newValues.end() ; ++it )
+ {
+ if ( origValues.findIndex( *it ) == -1 && !remove )
+ {
+ while ( !origValues.isEmpty() && origValues.last() == getLineEndingString() )
+ origValues.pop_back();
+ if ( origValues.count() > 0 && !containsContinue( origValues.last() ) && !isComment( origValues.last() ) )
+ {
+ origValues.append( " " );
+ origValues.append( "\\"+getLineEndingString() );
+ if( indent != "" )
+ origValues.append( indent );
+ }else if ( !origValues.isEmpty() && containsContinue( origValues.last() ) && !isComment( origValues.last() ) )
+ {
+ if( indent != "" )
+ origValues.append( indent );
+ }else if ( !origValues.isEmpty() && isComment( origValues.last() ) )
+ {
+ origValues[origValues.count()-1] = "\\ "+origValues[origValues.count()-1];
+ if( indent != "" )
+ origValues.append( indent );
+ }else if ( origValues.isEmpty() )
+ origValues.append(" ");
+ QString newval = *it;
+ QRegExp re("([^$])\\$([^$\\(\\)\\{\\} /]*)( |\\)|/)");
+ newval.replace(re, "\\1$(\\2)\\3");
+ if( (newval).contains(" ") || (newval).contains("\t") || (newval).contains( getLineEndingString() ) || (newval).contains("#") )
+ origValues.append( "\""+newval+"\"" );
+ else
+ origValues.append( newval );
+ origValues.append( getLineEndingString() );
+ } else if ( origValues.findIndex( *it ) != -1 && remove )
+ {
+ QStringList::iterator posit = origValues.find( *it );
+ posit = origValues.remove( posit );
+ while( posit != origValues.end() && ( (*posit).find( QRegExp("\\\\[\\s]*"+getLineEndingString() ) ) != -1
+ || (*posit).stripWhiteSpace() == "" ) )
+ {
+ posit = origValues.remove( posit );
+ }
+ }
+ }
+ while( !origValues.isEmpty() && (origValues.last() == "\\"+getLineEndingString()
+ || origValues.last() == getLineEndingString()
+ || origValues.last().stripWhiteSpace() == "" ) && !origValues.isEmpty() )
+ origValues.pop_back();
+ if( !origValues.isEmpty() && origValues.last().find( QRegExp("\\\\[ \t]*#") ) != -1 )
+ origValues[origValues.count()-1] = origValues[origValues.count()-1].mid(origValues[origValues.count()-1].find( "#") );
+ if( !origValues.isEmpty() && origValues.last().find( getLineEndingString() ) == -1 )
+ origValues.append(getLineEndingString());
+}
+
+void Scope::updateVariable( const QString& variable, const QString& op, const QStringList& values, bool removeFromOp )
+{
+ if ( !m_root || listIsEmpty( values ) )
+ return ;
+
+ if( m_varCache.contains( variable ) )
+ m_varCache.erase( variable );
+
+ for ( int i = m_root->m_children.count() - 1; i >= 0; --i )
+ {
+ if ( m_root->m_children[ i ] ->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * assignment = static_cast<QMake::AssignmentAST*>( m_root->m_children[ i ] );
+ if ( assignment->scopedID == variable && Scope::isCompatible( assignment->op, op ) )
+ {
+ updateValues( assignment->values, values, removeFromOp, assignment->indent );
+ if ( removeFromOp && listIsEmpty( assignment->values ) )
+ {
+ m_root->removeChildAST( assignment );
+ delete assignment;
+ }
+ return ;
+ }
+ else if ( assignment->scopedID == variable && !Scope::isCompatible( assignment->op, op ) )
+ {
+ for ( QStringList::const_iterator it = values.begin() ; it != values.end() ; ++it )
+ {
+ if ( op == "+=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 )
+ {
+ if ( assignment->op == "=" )
+ {
+ updateValues( assignment->values, values, false, assignment->indent );
+ return ;
+ }
+ else if ( assignment->op == "-=" )
+ {
+ updateValues( assignment->values, QStringList( *it ), true, assignment->indent );
+ if ( listIsEmpty( assignment->values ) )
+ {
+ m_root->removeChildAST( assignment );
+ delete assignment;
+ break;
+ }
+ }
+ }
+ else if ( op == "-=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 )
+ {
+ updateValues( assignment->values, QStringList( *it ), true, assignment->indent );
+ if ( listIsEmpty( assignment->values ) )
+ {
+ m_root->removeChildAST( assignment );
+ delete assignment;
+ break;
+ }
+ }
+ else if ( op == "=" )
+ {
+ if ( !removeFromOp )
+ {
+ m_root->removeChildAST( assignment );
+ delete assignment;
+ }
+ else if ( assignment->op == "+=" && assignment->values.findIndex( *it ) != -1 )
+ {
+ updateValues( assignment->values, QStringList( *it ), true, assignment->indent );
+ if ( listIsEmpty( assignment->values ) )
+ {
+ m_root->removeChildAST( assignment );
+ delete assignment;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if ( !removeFromOp )
+ {
+ QMake::AssignmentAST * ast = new QMake::AssignmentAST();
+ ast->scopedID = variable;
+ ast->op = op;
+ updateValues( ast->values, values );
+ if( scopeType() == ProjectScope )
+ ast->setDepth( m_root->depth() );
+ else
+ ast->setDepth( m_root->depth()+1 );
+ m_root->addChildAST( ast );
+ if ( values.findIndex( getLineEndingString() ) == -1 )
+ {
+ ast->values.append( getLineEndingString() );
+ }
+ }
+}
+
+QValueList<QMake::AST*>::iterator Scope::findExistingVariable( const QString& variable )
+{
+ QValueList<QMake::AST*>::iterator it;
+ QStringList ops;
+ ops << "=" << "+=";
+
+ for ( it = m_root->m_children.begin(); it != m_root->m_children.end() ; ++it )
+ {
+ if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * assignment = static_cast<QMake::AssignmentAST*>( *it );
+ if ( assignment->scopedID == variable && ops.findIndex( assignment->op ) != -1 )
+ {
+ return it;
+ }
+ }
+ }
+ return m_root->m_children.end();
+}
+
+void Scope::init()
+{
+ if( !m_root )
+ return;
+
+ kdDebug(9024) << "Initializing Scope: " << scopeName() << this << endl;
+ m_maxCustomVarNum = 1;
+
+ QValueList<QMake::AST*>::const_iterator it;
+ for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it )
+ {
+ if ( ( *it ) ->nodeType() == QMake::AST::ProjectAST )
+ {
+ QMake::ProjectAST * p = static_cast<QMake::ProjectAST*>( *it );
+ m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, p, m_defaultopts, m_part ) );
+ }
+ else if ( ( *it ) ->nodeType() == QMake::AST::IncludeAST )
+ {
+ QMake::IncludeAST * i = static_cast<QMake::IncludeAST*>( *it );
+ QString filename = i->projectName;
+ if( i->projectName.stripWhiteSpace().startsWith("$") )
+ {
+ filename = resolveVariables(i->projectName, *it);
+ }
+ m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, i, projectDir(), filename, m_defaultopts, m_part ) );
+ }
+ else if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * m = static_cast<QMake::AssignmentAST*>( *it );
+ // Check wether TEMPLATE==subdirs here too!
+ if ( m->scopedID == "SUBDIRS" && variableValues("TEMPLATE").findIndex("subdirs") != -1 )
+ {
+ for ( QStringList::const_iterator sit = m->values.begin() ; sit != m->values.end(); ++sit )
+ {
+ QString str = *sit;
+ if ( containsContinue( str ) || isComment( str ) || str == getLineEndingString() || str == "." || str == "./" || (str).stripWhiteSpace() == "" )
+ continue;
+ QDir subproject;
+ QString projectfile;
+ kdDebug(9024) << "reading subproject: " << str << endl;
+ if( str.startsWith("$") )
+ str = resolveVariables(str, *it);
+ if( str.endsWith(".pro") )
+ {
+ subproject = QDir( projectDir(), "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files );
+ projectfile = str;
+ }else
+ {
+ QString dir = str;
+ if( QFileInfo( dir ).isRelative() )
+ dir = projectDir() + QString( QChar( QDir::separator() ) ) + dir;
+ subproject = QDir( dir,
+ "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files );
+ if( !subproject.exists() )
+ {
+ kdDebug(9024) << "Project Dir doesn't exist, trying to find name.subdir variable:" << str << endl;
+ if( !variableValues(str+".subdir").isEmpty() )
+ {
+ kdDebug(9024) << "Found name.subdir variable for " << str << endl;
+ subproject = QDir( projectDir() + QString( QChar( QDir::separator() ) )
+ + variableValues(str+".subdir").first(),
+ "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files );
+ }else
+ continue;
+ }
+ if ( subproject.entryList().isEmpty() || subproject.entryList().findIndex( str + ".pro" ) != -1 )
+ projectfile = (str) + ".pro";
+ else
+ projectfile = subproject.entryList().first();
+
+ }
+ kdDebug( 9024 ) << "Parsing subproject: " << projectfile << endl;
+ m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this,
+ subproject.absFilePath( projectfile ),
+ m_part, ( m->op != "-=" )) );
+ }
+ }
+ else
+ {
+ if ( !(
+ KnownVariables.findIndex( m->scopedID ) != -1
+ && ( m->op == "=" || m->op == "+=" || m->op == "-=")
+ )
+ && !(
+ ( m->scopedID.contains( ".files" ) || m->scopedID.contains( ".path" ) )
+ && variableValues("INSTALLS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) )
+ )
+ && !(
+ ( m->scopedID.contains( ".subdir" ) )
+ && variableValues("SUBDIRS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) )
+ )
+ )
+ {
+ m_customVariables[ m_maxCustomVarNum++ ] = m;
+ }
+ }
+ }
+ }
+}
+
+QString Scope::projectName() const
+{
+ if( !m_root )
+ return "";
+
+ return QFileInfo( projectDir() ).fileName();
+}
+
+QString Scope::projectDir() const
+{
+ if( !m_root )
+ return "";
+ if ( m_root->isProject() )
+ {
+ return QFileInfo( m_root->fileName() ).dirPath( true );
+ }
+ else
+ {
+ return m_parent->projectDir();
+ }
+}
+
+const QMap<unsigned int, QMap<QString, QString> > Scope::customVariables() const
+{
+ QMap<unsigned int, QMap<QString, QString> > result;
+ if( !m_root )
+ return result;
+
+ QMap<unsigned int, QMake::AssignmentAST*>::const_iterator it = m_customVariables.begin();
+ for ( ; it != m_customVariables.end(); ++it )
+ {
+ QMap<QString,QString> temp;
+ temp[ "var" ] = it.data()->scopedID;
+ temp[ "op" ] = it.data()->op;
+ temp[ "values" ] = it.data()->values.join("").stripWhiteSpace();
+ result[ it.key() ] = temp;
+ }
+ return result;
+}
+
+void Scope::updateCustomVariable( unsigned int id, const QString& name, const QString& newop, const QString& newvalues )
+{
+ if( !m_root )
+ return;
+ if ( id > 0 && m_customVariables.contains( id ) )
+ {
+ m_customVariables[ id ] ->values.clear();
+ updateValues( m_customVariables[ id ] ->values, newvalues.stripWhiteSpace() );
+ if( m_varCache.contains( m_customVariables[ id ]->scopedID ) )
+ m_varCache.erase( m_customVariables[ id ]->scopedID );
+ m_customVariables[ id ] ->op = newop;
+ m_customVariables[ id ] ->scopedID = name;
+ }
+}
+
+unsigned int Scope::addCustomVariable( const QString& var, const QString& op, const QString& values )
+{
+ QMake::AssignmentAST* newast = new QMake::AssignmentAST();
+ newast->scopedID = var;
+ newast->op = op;
+ newast->values.append(values.stripWhiteSpace());
+ if( scopeType() == ProjectScope )
+ newast->setDepth( m_root->depth() );
+ else
+ newast->setDepth( m_root->depth()+1 );
+ m_root->addChildAST( newast );
+ m_customVariables[ m_maxCustomVarNum++ ] = newast;
+ return (m_maxCustomVarNum-1);
+}
+
+void Scope::removeCustomVariable( unsigned int id )
+{
+ if( m_customVariables.contains(id) )
+ {
+ QMake::AssignmentAST* m = m_customVariables[id];
+ m_customVariables.remove(id);
+ m_root->m_children.remove( m );
+ }
+}
+
+bool Scope::isVariableReset( const QString& var )
+{
+ bool result = false;
+ if( !m_root )
+ return result;
+ QValueList<QMake::AST*>::const_iterator it = m_root->m_children.begin();
+ for ( ; it != m_root->m_children.end(); ++it )
+ {
+ if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST )
+ {
+ QMake::AssignmentAST * ast = static_cast<QMake::AssignmentAST*>( *it );
+ if ( ast->scopedID == var && ast->op == "=" )
+ {
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+void Scope::removeVariable( const QString& var, const QString& op )
+{
+ if ( !m_root )
+ return ;
+
+ QMake::AssignmentAST* ast = 0;
+
+ QValueList<QMake::AST*>::iterator it = m_root->m_children.begin();
+ for ( ; it != m_root->m_children.end(); ++it )
+ {
+ if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST )
+ {
+ ast = static_cast<QMake::AssignmentAST*>( *it );
+ if ( ast->scopedID == var && ast->op == op )
+ {
+ m_root->m_children.remove( ast );
+ it = m_root->m_children.begin();
+ }
+ }
+ }
+}
+
+bool Scope::listIsEmpty( const QStringList& values )
+{
+ if ( values.size() < 1 )
+ return true;
+ for ( QStringList::const_iterator it = values.begin(); it != values.end(); ++it )
+ {
+ if ( ( *it ).stripWhiteSpace() != "" && ( *it ).stripWhiteSpace() != "\\" )
+ return false;
+ }
+ return true;
+}
+
+bool Scope::isCompatible( const QString& op1, const QString& op2)
+{
+ if( op1 == "+=" )
+ return ( op2 == "+=" || op2 == "=" );
+ else if ( op1 == "-=" )
+ return ( op2 == "-=" );
+ else if ( op1 == "=" )
+ return ( op2 == "=" || op2 == "+=" );
+ return false;
+}
+
+bool Scope::listsEqual(const QStringList& l1, const QStringList& l2)
+{
+ QStringList left = l1;
+ QStringList right = l2;
+// left.sort();
+// right.sort();
+ return (left == right);
+}
+
+QStringList Scope::cleanStringList(const QStringList& list) const
+{
+ QStringList result;
+ for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it )
+ {
+ QString s = *it;
+ if( s.stripWhiteSpace() != ""
+ && !containsContinue(s)
+ && s.stripWhiteSpace() != getLineEndingString()
+ && !isComment(s) )
+ result.append(s);
+ }
+ return result;
+}
+
+bool Scope::isQt4Project() const
+{
+ return m_part->isQt4Project();
+}
+
+void Scope::reloadProject()
+{
+ if ( !m_root || !m_root->isProject() )
+ return;
+
+ QString filename = m_root->fileName();
+ QMap<unsigned int, Scope*>::iterator it;
+ for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it )
+ {
+ Scope* s = it.data();
+ delete s;
+ }
+ m_scopes.clear();
+
+ m_customVariables.clear();
+
+ m_varCache.clear();
+
+ if ( m_root->isProject() )
+ delete m_root;
+ if ( !loadFromFile( filename ) && !QFileInfo( filename ).exists() )
+ {
+ m_root = new QMake::ProjectAST();
+ m_root->setFileName( filename );
+ }
+ init();
+}
+
+Scope* Scope::disableSubproject( const QString& dir)
+{
+ if( !m_root || ( m_root->isProject() && !m_incast ) )
+ return 0;
+
+ if( scopeType() != Scope::IncludeScope && variableValuesForOp( "SUBDIRS", "+=").findIndex( dir ) != -1 )
+ removeFromPlusOp( "SUBDIRS", dir );
+ else if( scopeType() != Scope::IncludeScope )
+ removeFromPlusOp( "SUBDIRS", dir );
+
+ QDir curdir( projectDir() );
+
+ if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 )
+ {
+ curdir.cd(dir);
+ QString filename;
+ QStringList entries = curdir.entryList("*.pro", QDir::Files);
+
+ if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) != -1 )
+ filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first();
+ else
+ filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro";
+
+ kdDebug( 9024 ) << "Disabling subproject with filename:" << filename << endl;
+
+ Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part, false );
+ addToMinusOp( "SUBDIRS", QStringList( dir ) );
+ m_scopes.insert( getNextScopeNum(), s );
+ return s;
+ }
+
+ return 0;
+}
+
+QString Scope::resolveVariables( const QString& value ) const
+{
+ return resolveVariables(QStringList(value), 0).front();
+}
+
+
+QString Scope::resolveVariables( const QString& value, QMake::AST* stopHere ) const
+{
+ return resolveVariables(QStringList(value), stopHere).front();
+}
+
+QStringList Scope::variableValues( const QString& variable, QMake::AST* stopHere, bool fetchFromParent ) const
+{
+ QStringList result;
+
+ if ( !m_root )
+ return result;
+
+ calcValuesFromStatements( variable, result, true, stopHere, fetchFromParent );
+ result = cleanStringList(result);
+ return result;
+}
+
+QStringList Scope::resolveVariables( const QStringList& values, QMake::AST* stopHere ) const
+{
+ QStringList result = values;
+ QMap<QString, QStringList> variables;
+ for( QStringList::iterator it = result.begin(); it != result.end(); ++it )
+ {
+ QRegExp re("\\$\\$([^{}\\) /]*)( |\\)|/|$)");
+ int pos = 0;
+ while( pos >= 0 )
+ {
+ pos = re.search( (*it), pos );
+ if( pos > -1 )
+ {
+ if( !variables.contains( re.cap(1) ) )
+ {
+ variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) );
+ if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" )
+ {
+ variables[re.cap(1)] = QFileInfo( fileName() ).baseName();
+ }
+ }
+ pos += re.matchedLength();
+ }
+ }
+ re = QRegExp("\\$\\$\\{([^\\)\\}]*)\\}");
+ pos = 0;
+ while( pos >= 0 )
+ {
+ pos = re.search( (*it), pos );
+ if( pos > -1 )
+ {
+ if( !variables.contains( re.cap(1) ) )
+ {
+ variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) );
+ if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" )
+ {
+ variables[re.cap(1)] = QFileInfo( fileName() ).baseName();
+ }
+ }
+ pos += re.matchedLength();
+ }
+ }
+ re = QRegExp("\\$\\$\\(([^\\)\\}]*)\\)");
+ pos = 0;
+ QMap<QString, QString> envvars;
+ while( pos >= 0 )
+ {
+ pos = re.search( (*it), pos );
+ if( pos > -1 )
+ {
+ if( !envvars.contains( re.cap(1) ) )
+ if( m_environment.contains( re.cap(1) ) != -1 )
+ envvars[re.cap(1)] = m_environment[ re.cap(1) ];
+ else if ( ::getenv( re.cap(1).local8Bit() ) != 0 )
+ envvars[re.cap(1)] = QString::fromLocal8Bit( ::getenv( re.cap(1).local8Bit() ) );
+ pos += re.matchedLength();
+ }
+ }
+ for( QMap<QString, QString>::const_iterator it2 = envvars.begin(); it2 != envvars.end(); ++it2 )
+ {
+ (*it).replace("$$("+it2.key()+")", it2.data() );
+ }
+ for( QMap<QString, QStringList>::const_iterator it2 = variables.begin(); it2 != variables.end(); ++it2 )
+ {
+ for( QStringList::const_iterator it3 = it2.data().begin(); it3 != it2.data().end(); ++it3 )
+ {
+ (*it).replace("$$"+it2.key(), *it3 );
+ (*it).replace("$${"+it2.key()+"}", *it3 );
+ }
+ }
+ }
+ return result;
+}
+
+void Scope::allFiles( const QString& projectDirectory, std::set<QString>& res )
+{
+
+ QString myRelPath = URLUtil::getRelativePath( projectDirectory, projectDir() );
+ QString file;
+ QStringList values;
+ QString header = "";
+ if( variableValues("TEMPLATE",false ).findIndex("subdirs") == -1 )
+ {
+ values = variableValues( "INSTALLS" ,false, false );
+ QStringList::const_iterator it;
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ if ( ( *it ) == "target" )
+ continue;
+
+ QStringList files = variableValues( *it + ".files" ,false, false );
+ QStringList::iterator filesit = files.begin();
+ for ( ;filesit != files.end(); ++filesit )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *filesit;
+ file = resolveVariables( file );
+ if( file.contains("*") )
+ {
+ QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file );
+ QDir absDir = fi.dir( true );
+ absDir.setNameFilter( fi.fileName() );
+ absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks );
+ QStringList list = absDir.entryList();
+ for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it )
+ {
+ res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) );
+ }
+ }
+ else
+ {
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+ }
+ }
+
+ values = variableValues( "LEXSOURCES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ values = variableValues( "YACCSOURCES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ values = variableValues( "DISTFILES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ if( file.contains("*") )
+ {
+ QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file );
+ QDir absDir = fi.dir( true );
+ absDir.setNameFilter( fi.fileName() );
+ absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks );
+ QStringList list = absDir.entryList();
+ for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it )
+ {
+ res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) );
+ }
+ }
+ else
+ {
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+ }
+
+ if ( isQt4Project() )
+ {
+ values = variableValues( "RESOURCES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+ }
+ values = variableValues( "IMAGES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ values = variableValues( "TRANSLATIONS" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ values = variableValues( "IDLS" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ if ( m_part->isTMakeProject() )
+ {
+ values = variableValues( "INTERFACES" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ if( QFileInfo(projectDir()+QString(QChar(QDir::separator())) + *it+".h").exists() )
+ res.insert( QDir::cleanDirPath( file+".h" ) );
+ }
+ }
+ else
+ {
+ values = variableValues( "FORMS" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+
+ if( !m_part->isQt4Project())
+ {
+ header = projectDir()+QString(QChar(QDir::separator())) + *it+".h";
+ if( QFileInfo(header).exists() )
+ res.insert( QDir::cleanDirPath( header ) );
+ header = projectDir()+QString(QChar(QDir::separator())) + *it+".cpp";
+ if( QFileInfo(header).exists() )
+ res.insert( QDir::cleanDirPath( header ) );
+ }
+ else
+ {
+ header = projectDir()+QString(QChar(QDir::separator())) + "ui_" +*it;
+ header.replace(QRegExp("\\.ui$"),".h");
+ if( QFileInfo(header).exists() )
+ res.insert( QDir::cleanDirPath( header ) );
+ }
+ }
+ }
+
+ values = variableValues( "SOURCES" ,false, false );
+ kdDebug(9024) << "scope:" << scopeType() << " found values: " << values << endl;
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+
+ values = variableValues( "HEADERS" ,false, false );
+ for ( it = values.begin(); it != values.end(); ++it )
+ {
+ file = myRelPath + QString(QChar(QDir::separator())) + *it;
+ file = resolveVariables( file );
+ res.insert( QDir::cleanDirPath( file ) );
+ }
+ }
+ QMap<unsigned int, Scope*>::const_iterator it = m_scopes.begin();
+ for( ; it != m_scopes.end(); ++it )
+ {
+ it.data()->allFiles( projectDirectory, res );
+ }
+}
+
+QStringList Scope::allFiles( const QString& projectDir )
+{
+ QStringList result;
+ std::set<QString> files;
+ allFiles( projectDir, files );
+ for( std::set<QString>::const_iterator it = files.begin(); it != files.end() ; ++it )
+ result.append( *it );
+ kdDebug(9024) << "all files: " << result << endl;
+ return result;
+}
+
+QString Scope::findCustomVarForPath( const QString& path )
+{
+ QString result;
+ if( !m_root )
+ return result;
+
+ QMap<unsigned int, QMake::AssignmentAST*>::const_iterator it = m_customVariables.begin();
+ for( ; it != m_customVariables.end(); ++it )
+ {
+ kdDebug(9024) << "Checking " << path << " against " << cleanStringList(it.data()->values) << endl;
+ if( !it.data()->values.isEmpty() && cleanStringList(it.data()->values).front() == path )
+ {
+ return it.data()->scopedID;
+ }
+ }
+ if( scopeType() != ProjectScope )
+ {
+ return parent()->findCustomVarForPath( path );
+ }
+ return result;
+}
+
+void Scope::loadDefaultOpts()
+{
+ if( !m_defaultopts && m_root )
+ {
+ m_defaultopts = new QMakeDefaultOpts();
+ if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/disableDefaultOpts", true ) )
+ {
+ m_defaultopts->readVariables( m_part->qmakePath(), QFileInfo( m_root->fileName() ).dirPath( true ) );
+ }
+ }
+}
+
+QString Scope::getLineEndingString() const
+{
+
+ if( scopeType() == ProjectScope )
+ {
+ switch( m_root->lineEnding() )
+ {
+ case QMake::ProjectAST::Windows:
+ return QString("\r\n");
+ break;
+ case QMake::ProjectAST::MacOS:
+ return QString("\r");
+ break;
+ case QMake::ProjectAST::Unix:
+ return QString("\n");
+ break;
+ }
+ }else if( m_parent )
+ {
+ return m_parent->getLineEndingString();
+ }
+ return "\n";
+}
+
+QString Scope::replaceWs(QString s)
+{
+ return s.replace( getLineEndingString(), "%nl").replace("\t", "%tab").replace(" ", "%spc");
+}
+
+bool Scope::containsContinue(const QString& s ) const
+{
+ return( s.find( QRegExp( "\\\\\\s*"+getLineEndingString() ) ) != -1
+ || s.find( QRegExp( "\\\\\\s*#" ) ) != -1 );
+}
+
+bool Scope::isComment( const QString& s) const
+{
+ return s.startsWith("#");
+}
+
+#ifdef DEBUG
+void Scope::printTree()
+{
+ PrintAST p;
+ p.processProject(m_root);
+}
+
+Scope::PrintAST::PrintAST() : QMake::ASTVisitor()
+{
+ indent = 0;
+}
+
+void Scope::PrintAST::processProject( QMake::ProjectAST* p )
+{
+ QMake::ASTVisitor::processProject(p);
+}
+
+void Scope::PrintAST::enterRealProject( QMake::ProjectAST* p )
+{
+ kdDebug(9024) << getIndent() << "--------- Entering Project: " << replaceWs(p->fileName()) << " --------------" << endl;
+ indent += 4;
+ QMake::ASTVisitor::enterRealProject(p);
+}
+
+void Scope::PrintAST::leaveRealProject( QMake::ProjectAST* p )
+{
+ indent -= 4;
+ kdDebug(9024) << getIndent() << "--------- Leaving Project: " << replaceWs(p->fileName()) << " --------------" << endl;
+ QMake::ASTVisitor::leaveRealProject(p);
+}
+
+void Scope::PrintAST::enterScope( QMake::ProjectAST* p )
+{
+ kdDebug(9024) << getIndent() << "--------- Entering Scope: " << replaceWs(p->scopedID) << " --------------" << endl;
+ indent += 4;
+ QMake::ASTVisitor::enterScope(p);
+}
+
+void Scope::PrintAST::leaveScope( QMake::ProjectAST* p )
+{
+ indent -= 4;
+ kdDebug(9024) << getIndent() << "--------- Leaving Scope: " << replaceWs(p->scopedID) << " --------------" << endl;
+ QMake::ASTVisitor::leaveScope(p);
+}
+
+void Scope::PrintAST::enterFunctionScope( QMake::ProjectAST* p )
+{
+ kdDebug(9024) << getIndent() << "--------- Entering FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl;
+ indent += 4;
+ QMake::ASTVisitor::enterFunctionScope(p);
+}
+
+void Scope::PrintAST::leaveFunctionScope( QMake::ProjectAST* p )
+{
+ indent -= 4;
+ kdDebug(9024) << getIndent() << "--------- Leaving FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl;
+ QMake::ASTVisitor::leaveFunctionScope(p);
+}
+
+QString Scope::PrintAST::replaceWs(QString s)
+{
+ return s.replace("\n", "%nl").replace("\t", "%tab").replace(" ", "%spc");
+}
+
+void Scope::PrintAST::processAssignment( QMake::AssignmentAST* a)
+{
+ kdDebug(9024) << getIndent() << "Assignment: " << replaceWs(a->scopedID) << " " << replaceWs(a->op) << " "
+ << replaceWs(a->values.join("|"))<< endl;
+ QMake::ASTVisitor::processAssignment(a);
+}
+
+void Scope::PrintAST::processNewLine( QMake::NewLineAST* n)
+{
+ kdDebug(9024) << getIndent() << "Newline " << endl;
+ QMake::ASTVisitor::processNewLine(n);
+}
+
+void Scope::PrintAST::processComment( QMake::CommentAST* a)
+{
+ kdDebug(9024) << getIndent() << "Comment: " << replaceWs(a->comment) << endl;
+ QMake::ASTVisitor::processComment(a);
+}
+
+void Scope::PrintAST::processInclude( QMake::IncludeAST* a)
+{
+ kdDebug(9024) << getIndent() << "Include: " << replaceWs(a->projectName) << endl;
+ QMake::ASTVisitor::processInclude(a);
+}
+
+QString Scope::PrintAST::getIndent()
+{
+ QString ind;
+ for( int i = 0 ; i < indent ; i++)
+ ind += " ";
+ return ind;
+}
+#endif
+
+// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on