/*************************************************************************** * 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 #include #include #include #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& 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 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 ); /* find out wether the project is TQt4 or TQt3 */ bool isTQt4Project() const ; /* Provide a Map of Custom variables */ const TQMap > 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::iterator findExistingVariable( const TQString& variable ); // Private constructors for easier subscope creation /* * just initializes the lists from the scope */ Scope( const TQMap& 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& 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& 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& ); void loadDefaultOpts(); TQMake::ProjectAST* m_root; TQMake::IncludeAST* m_incast; TQMap m_customVariables; TQMap 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 m_varCache; TQMap 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 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on