You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/buildtools/qmake/scope.h

303 lines
12 KiB

/***************************************************************************
* 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. *
* *
***************************************************************************/
#ifndef _SCOPE_H_
#define _SCOPE_H_
#include <tqstring.h>
#include <tqstringlist.h>
#include <tqmap.h>
#include <set>
#include "qmakeast.h"
#include "qmakedefaultopts.h"
#ifdef DEBUG
#include "qmakeastvisitor.h"
#endif
class Scope;
class TrollProjectPart;
class Scope
{
public:
enum ScopeType {
ProjectScope,
FunctionScope,
SimpleScope,
IncludeScope,
InvalidScope
};
static const TQStringList KnownVariables;
static const TQStringList KnownConfigValues;
Scope( const TQMap<TQString, TQString>& env, const TQString &filename, TrollProjectPart* part );
~Scope();
void saveToFile() const;
// Changing variable values
void addToPlusOp( const TQString& variable, const TQStringList& values );
void removeFromPlusOp( const TQString& variable, const TQStringList& values );
void addToMinusOp( const TQString& variable, const TQStringList& values );
void removeFromMinusOp( const TQString& variable, const TQStringList& values );
void addToEqualOp( const TQString& variable, const TQStringList& values );
void removeFromEqualOp( const TQString& variable, const TQStringList& values );
void setPlusOp( const TQString& variable, const TQStringList& values );
void setEqualOp( const TQString& variable, const TQStringList& values );
void setMinusOp( const TQString& variable, const TQStringList& values );
// Checks wether a line like VAR = exists in this subscope
bool isVariableReset( const TQString& var );
// Fetch the valuelist for the variable op combination inside this scope
TQStringList variableValuesForOp( const TQString& variable, const TQString& op ) const;
// Fetch the variable values by running over the statements and adding/removing/setting
// as the encountered op's say, begin with the parent projects variableValues list
TQStringList variableValues( const TQString& variable, bool checkIncParent = true, bool fetchFromParent = true, bool evaluateSubScopes = false );
// Remove a variable+Op combination from the scope, if existant
void removeVariable( const TQString& var, const TQString& op );
// Getting to know what type of scope this is
ScopeType scopeType() const;
// This returns the function+args, the scopename or the pro/pri file
// depending on the type of scope
TQString scopeName() const;
// Returns the projectName for this scope, this is equal to the last part of the projectDir()
TQString projectName() const;
// Returns just the filename of this project's .pro file
TQString fileName() const;
// Returns the absolute path of the dir containing the .pro file
TQString projectDir() const;
// get the parent Scope
Scope* parent() const { return m_parent; }
// Fetching sub-scopes
const TQValueList<Scope*> scopesInOrder() const { return m_scopes.values(); }
// Working on SubScopes
/*
* creates a new function scope at the end of this (Sub-)AST and returns the Scope wrapping it
*/
Scope* createFunctionScope( const TQString& funcName, const TQString& args );
/*
* creates a new simple scope at the end of this (Sub-)AST and returns the Scope wrapping it
*/
Scope* createSimpleScope( const TQString& scopename );
/*
* creates a new function scope at the end of this (Sub-)AST
* and a new include scope inside the new function scope.
* It returns the Scope wrapping the include-AST, the function scope AST
* can be accessed easily using the parent() method.
*/
Scope* createIncludeScope( const TQString& includeFile, bool negate = false );
/*
* creates a new subproject in dir (create's dir if necessary)
* If this scope is not a project scope the subproject will be added to this
* Scope only, i.e. it is not seen in the project-files list of subdirs
*/
Scope* createSubProject( const TQString& dir );
/* delete the given function scope */
bool deleteFunctionScope( unsigned int );
/* delete the given simple scope */
bool deleteSimpleScope( unsigned int );
/* delete the given include scope */
bool deleteIncludeScope( unsigned int );
/* deletes the subproject (including the subdir if deleteSubdir is true) */
bool deleteSubProject( unsigned int, bool deleteSubdir );
/* Provide a Map of Custom variables */
const TQMap<unsigned int, TQMap<TQString, TQString> > customVariables() const;
unsigned int addCustomVariable( const TQString& var, const TQString& op, const TQString& values );
/* Removes the variable with the given id if it exists */
void removeCustomVariable( unsigned int );
/* Update the values of the variable/operation combo var+op to values */
void updateCustomVariable( unsigned int, const TQString&, const TQString& , const TQString& );
// Checks wether a TQStringList contains any values that are not whitespace or \\n
static bool listIsEmpty( const TQStringList& values );
/* returns wether this is an enabled subproject or a disabled one */
bool isEnabled() { return m_isEnabled; }
TQStringList cleanStringList(const TQStringList& list) const;
/* Reload a project scope */
void reloadProject();
/* creates a new disabled Scope child and add SUBDIRS -= dir to this scope */
Scope* disableSubproject( const TQString& );
/* return the "position" of this scope in the list of scopes */
unsigned int getNum() { return m_num; }
TQStringList allFiles( const TQString& );
TQString resolveVariables( const TQString& ) const;
TQString findCustomVarForPath( const TQString& );
#ifdef DEBUG
void printTree();
#endif
private:
// Builds the scope-lists and the customVariables list
void init();
/*
* Updates the given Variable+op with the values, if removeFromOp is true it removes the values, else it adds them
* this works it's way back through the current scope and changes the last occurence of op to
* include all new values.
*
* Depending on "op" it might end the search earlier (if op is += it also stops at =)
*
* This also removes the values from other assignments if the operation is not op, i.e.
* if op is += removes values from any occurence of -=
* if op is -= removes values from any occurence of = and +=
* if op is = removes values frmo any occurence of -=
*/
void updateVariable( const TQString& variable, const TQString& op, const TQStringList& values, bool removeFromOp );
/*
* Helper Function to change the origValues list with the values from newValues
* depending on the state of "remove" either adds or removes all entries from newValues
* to origValues if they didn't exist there yet
*/
void updateValues( TQStringList& origValues, const TQStringList& newValues, bool remove = false, TQString indent = " " );
/*
* Finds an existing variable, returns the end() of the statemenst if it is not found
*/
TQValueList<TQMake::AST*>::iterator findExistingVariable( const TQString& variable );
// Private constructors for easier subscope creation
/*
* just initializes the lists from the scope
*/
Scope( const TQMap<TQString, TQString>& env, unsigned int num, Scope* parent, TQMake::ProjectAST* root, TQMakeDefaultOpts*, TrollProjectPart* part );
/*
* reads the given filename and parses it. If it doesn't exist creates an empty
* ProjectAST with the given filename
*/
Scope( const TQMap<TQString, TQString>& env, unsigned int num, Scope* parent, const TQString& filename, TrollProjectPart* part, bool isEnabled = true );
/*
* Creates a scope for an include statement, parses the file and initializes the Scope
* Create an empty ProjectAST if the file cannot be found or parsed.
*/
Scope( const TQMap<TQString, TQString>& env, unsigned int num, Scope* parent, TQMake::IncludeAST* incast, const TQString& path, const TQString& incfile, TQMakeDefaultOpts*, TrollProjectPart* part );
// runs through the statements until stopHere is found (or the end is reached, if stopHere is 0),
// using the given list as startvalue
// Changes the list using the +=, -=, = operations accordingly
void calcValuesFromStatements( const TQString& variable, TQStringList& result, bool, TQMake::AST* stopHere = 0, bool fetchFromParent = true, bool setDefault = true, bool evaluateSubScopes = false ) const;
// Check wether the two operators are compatible
static bool isCompatible( const TQString& op1, const TQString& op2);
// Check wether the 2 lists are equal, regardless of element order.
static bool listsEqual(const TQStringList& , const TQStringList& );
// Load and Save project files, these only work on ProjectScope's
bool loadFromFile( const TQString& filename );
TQString funcScopeKey( TQMake::ProjectAST* funcast ) const { return funcast->scopedID + "(" + funcast->args + ")"; }
unsigned int getNextScopeNum() { if( m_scopes.isEmpty() ) return 0; else return (m_scopes.keys().last()+1); }
TQStringList lookupVariable( const TQString& var );
TQStringList resolveVariables( const TQStringList&, TQMake::AST* = 0 ) const;
TQStringList variableValues( const TQString& variable, TQMake::AST*, bool fetchFromParent = true ) const;
TQString resolveVariables( const TQString& , TQMake::AST* ) const;
// This function determines the currently used String for fileending, it can be \n, \r or \r\n
TQString getLineEndingString() const;
bool isComment( const TQString& ) const;
bool containsContinue( const TQString& ) const;
void allFiles( const TQString&, std::set<TQString>& );
void loadDefaultOpts();
TQMake::ProjectAST* m_root;
TQMake::IncludeAST* m_incast;
TQMap<unsigned int, TQMake::AssignmentAST*> m_customVariables;
TQMap<unsigned int, Scope*> m_scopes;
Scope* m_parent;
unsigned int m_maxCustomVarNum;
TQString replaceWs(TQString);
// The "position" inside the parent scope that this scope starts at
unsigned int m_num;
bool m_isEnabled;
TrollProjectPart* m_part;
TQMakeDefaultOpts* m_defaultopts;
TQMap<TQString, TQStringList> m_varCache;
TQMap<TQString,TQString> m_environment;
#ifdef DEBUG
class PrintAST : TQMake::ASTVisitor
{
public:
PrintAST();
virtual void processProject( TQMake::ProjectAST* p );
virtual void enterRealProject( TQMake::ProjectAST* p );
virtual void leaveRealProject( TQMake::ProjectAST* p );
virtual void enterScope( TQMake::ProjectAST* p );
virtual void leaveScope( TQMake::ProjectAST* p );
virtual void enterFunctionScope( TQMake::ProjectAST* p );
virtual void leaveFunctionScope( TQMake::ProjectAST* p );
virtual void processAssignment( TQMake::AssignmentAST* a);
virtual void processNewLine( TQMake::NewLineAST* n);
virtual void processComment( TQMake::CommentAST* a);
virtual void processInclude( TQMake::IncludeAST* a);
TQString replaceWs(TQString);
private:
TQString getIndent();
int indent;
};
#endif
};
#endif