qtmobility/tools/icheck/parsemanager.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "parsemanager.h"
       
    43 #include "cplusplus/CppDocument.h"
       
    44 #include "./parser/src/shared/cplusplus/Control.h"
       
    45 #include "TranslationUnit.h"
       
    46 #include "AST.h"
       
    47 #include "Symbols.h"
       
    48 #include <QDebug>
       
    49 #include "Name.h"
       
    50 #include "cpptools/cppmodelmanager.h"
       
    51 #include <QTextStream>
       
    52 
       
    53 using namespace CppTools;
       
    54 using namespace CppTools::Internal;
       
    55 
       
    56 
       
    57 using namespace CPlusPlus;
       
    58 
       
    59 //<------------------------------------------------------- Compare function for the internal structures
       
    60 /**********************************
       
    61 Compares function with function
       
    62 with return type, function name
       
    63 and their arguments and arguments
       
    64 types.
       
    65 **********************************/
       
    66 bool FUNCTIONITEM::isEqualTo(FUNCTIONITEM *cpfct, bool ignoreName/* = true*/)
       
    67 {
       
    68     if(ignoreName)
       
    69         return function->isEqualTo(cpfct->function, true);
       
    70     return function->isEqualTo(cpfct->function);
       
    71 }
       
    72 
       
    73 /*****************************************************************
       
    74 Compares two property regarding
       
    75 of their function definition,
       
    76 type definition, function arguments
       
    77 and function types.
       
    78 
       
    79 Q_PROPERTY( ConnectionState state READ state NOTIFY stateChanged);
       
    80 ******************************************************************/
       
    81 bool PROPERTYITEM::isEqualTo(PROPERTYITEM *cpppt)
       
    82 {
       
    83     QString thistype = this->trlUnit->spell(this->ast->type_token);
       
    84     QString cppttype = cpppt->trlUnit->spell(cpppt->ast->type_token);
       
    85 
       
    86     if(thistype != cppttype)
       
    87         return false;
       
    88 
       
    89     QString thistypename = this->trlUnit->spell(this->ast->type_name_token);
       
    90     QString cppttypename = cpppt->trlUnit->spell(cpppt->ast->type_name_token);
       
    91     if(thistypename != cppttypename)
       
    92         return false;
       
    93 
       
    94     if(this->readdefined != cpppt->readdefined)
       
    95         return false;
       
    96     if(this->writedefined != cpppt->writedefined)
       
    97         return false;
       
    98     if(this->resetdefined != cpppt->resetdefined)
       
    99         return false;
       
   100     if(this->notifydefined != cpppt->notifydefined)
       
   101         return false;
       
   102     //check for read function
       
   103     if(this->readdefined){
       
   104         if(!this->readFct || !cpppt->readFct)
       
   105             return false;
       
   106         if(!this->readFct->isEqualTo(cpppt->readFct))
       
   107             return false;
       
   108     }
       
   109     //check for write function
       
   110     if(this->writedefined){
       
   111         if(!this->writeFct || !cpppt->writeFct)
       
   112             return false;
       
   113         if(!this->writeFct->isEqualTo(cpppt->writeFct))
       
   114             return false;
       
   115     }
       
   116     //check for reset function
       
   117     if(this->resetdefined){
       
   118         if(!this->resetFct || !cpppt->resetFct)
       
   119             return false;
       
   120         if(!this->resetFct->isEqualTo(cpppt->resetFct))
       
   121             return false;
       
   122     }
       
   123     //check for notify function
       
   124     if(this->notifydefined){
       
   125         if(!this->notifyFct || !cpppt->notifyFct)
       
   126             return false;
       
   127         if(!this->notifyFct->isEqualTo(cpppt->notifyFct))
       
   128             return false;
       
   129     }
       
   130     return true;
       
   131 }
       
   132 
       
   133 /*****************************************************************
       
   134 Compares two enums regarding
       
   135 of their values created by the getEnumValueStringList function.
       
   136 *****************************************************************/
       
   137 bool QENUMITEM::isEqualTo(QENUMITEM *cpenum)
       
   138 {
       
   139     if(this->values.count() != cpenum->values.count())
       
   140         return false;
       
   141     foreach(QString str, this->values){
       
   142         if(!cpenum->values.contains(str))
       
   143             return false;
       
   144     }
       
   145     return true;
       
   146 }
       
   147 
       
   148 /*****************************************************************
       
   149 Compares two flags regarding
       
   150 of their enum definitions and their
       
   151 values created by the getEnumValueStringList function.
       
   152 *****************************************************************/
       
   153 bool QFLAGITEM::isEqualTo(QFLAGITEM *cpflag)
       
   154 {
       
   155     if(this->enumvalues.count() != cpflag->enumvalues.count())
       
   156         return false;
       
   157     foreach(QString str, this->enumvalues){
       
   158         if(!cpflag->enumvalues.contains(str))
       
   159             return false;
       
   160     }
       
   161     return true;
       
   162 }
       
   163 
       
   164 
       
   165 
       
   166 ParseManager::ParseManager()
       
   167 : pCppPreprocessor(0)
       
   168 {
       
   169 
       
   170 }
       
   171 
       
   172 ParseManager::~ParseManager()
       
   173 {
       
   174     if(pCppPreprocessor)
       
   175         delete pCppPreprocessor;
       
   176     if(::m_resultFile){
       
   177         ::m_resultFile->close();
       
   178         delete ::m_resultFile;
       
   179         ::m_resultFile = 0;
       
   180     }
       
   181 }
       
   182 
       
   183 /**************************************
       
   184 Function for setting the include
       
   185 Paths
       
   186 **************************************/
       
   187 void ParseManager::setIncludePath(const QStringList &includePath)
       
   188 {
       
   189     m_includePaths = includePath;
       
   190 }
       
   191 
       
   192 /**************************************
       
   193 public Function that starts the parsing
       
   194 all of the files in the sourceFiles
       
   195 string list.
       
   196 **************************************/
       
   197 void ParseManager::parse(const QStringList &sourceFiles)
       
   198 {
       
   199     m_errormsgs.clear();
       
   200     if(pCppPreprocessor){
       
   201         delete pCppPreprocessor;
       
   202         pCppPreprocessor = 0;
       
   203     }
       
   204 
       
   205     if (! sourceFiles.isEmpty()) {
       
   206         m_strHeaderFile = sourceFiles[0];
       
   207         pCppPreprocessor = new CppTools::Internal::CppPreprocessor(QPointer<CPlusPlus::ParseManager>(this));
       
   208         pCppPreprocessor->setIncludePaths(m_includePaths);
       
   209         pCppPreprocessor->setFrameworkPaths(m_frameworkPaths);
       
   210         parse(pCppPreprocessor, sourceFiles);
       
   211     }
       
   212 }
       
   213 
       
   214 /*********************************************
       
   215 private function that prepare the filelist
       
   216 to parse and starts the parser.
       
   217 *********************************************/
       
   218 void ParseManager::parse(CppTools::Internal::CppPreprocessor *preproc,
       
   219                             const QStringList &files)
       
   220 {
       
   221     if (files.isEmpty())
       
   222         return;
       
   223 
       
   224     //check if file is C++ header file
       
   225     QStringList headers;
       
   226     foreach (const QString &file, files) {
       
   227         const QFileInfo fileInfo(file);
       
   228         QString ext = fileInfo.suffix();
       
   229         if (ext.toLower() == "h")
       
   230             headers.append(file);
       
   231     }
       
   232 
       
   233     foreach (const QString &file, files) {
       
   234         preproc->snapshot.remove(file);
       
   235     }
       
   236     preproc->setTodo(headers);
       
   237     QString conf = QLatin1String("<configuration>");
       
   238 
       
   239     preproc->run(conf);
       
   240     for (int i = 0; i < headers.size(); ++i) {
       
   241         QString fileName = headers.at(i);
       
   242         preproc->run(fileName);
       
   243     }
       
   244 }
       
   245 
       
   246 //This function creates a class list for each class and its base classes in
       
   247 //the header file that needs to be checked.
       
   248 //e.g.
       
   249 //      Cl1          Cl2
       
   250 //     __|__        __|__
       
   251 //    |     |      |     |
       
   252 //   Cl11  Cl12   Cl21  Cl22
       
   253 //
       
   254 //==> list[0] = {Cl1, Cl11, Cl12}
       
   255 //    list[1] = {Cl2, Cl21, Cl22}
       
   256 
       
   257 QList<CLASSTREE*> ParseManager::CreateClassLists(bool isInterfaceHeader)
       
   258 {
       
   259     QList<CLASSTREE*>ret;
       
   260     QList<CLASSLISTITEM*> classlist;
       
   261     QList<CLASSLISTITEM*> allclasslist;
       
   262 
       
   263     Trace("Following classes scaned for header file: " + m_strHeaderFile);
       
   264     //Iteration over all parsed documents
       
   265     if(getPreProcessor()){
       
   266         for (Snapshot::const_iterator it = getPreProcessor()->snapshot.begin()
       
   267             ; it != getPreProcessor()->snapshot.end(); ++it)
       
   268         {
       
   269             Document::Ptr doc = (*it);
       
   270             if(doc){
       
   271                 QFileInfo fileinf(doc->fileName());
       
   272                 QFileInfo fileinf1(m_strHeaderFile);
       
   273                 //Get the Translated unit
       
   274                 Control* ctrl = doc->control();
       
   275                 TranslationUnit* trlUnit = ctrl->translationUnit();
       
   276                 AST* pAst = trlUnit->ast();
       
   277                 TranslationUnitAST *ptrAst = 0;
       
   278                 if(pAst && (ptrAst = pAst->asTranslationUnit())){
       
   279                     //iteration over all translated declaration in this document
       
   280                     for (DeclarationListAST *pDecllist = ptrAst->declaration_list; pDecllist; pDecllist = pDecllist->next) {
       
   281                         if(pDecllist->value){
       
   282                             SimpleDeclarationAST *pSimpleDec = pDecllist->value->asSimpleDeclaration();
       
   283                             if(pSimpleDec){
       
   284                                 //Iteration over class specifier
       
   285                                 for (SpecifierListAST *pSimpleDecDecllist = pSimpleDec->decl_specifier_list; pSimpleDecDecllist; pSimpleDecDecllist = pSimpleDecDecllist->next) {
       
   286                                     ClassSpecifierAST * pclassspec = pSimpleDecDecllist->value->asClassSpecifier();
       
   287                                     if(pclassspec){
       
   288                                         CLASSLISTITEM* item = new CLASSLISTITEM();
       
   289                                         item->classspec = pclassspec;
       
   290                                         item->trlUnit = trlUnit;
       
   291                                         allclasslist.push_back(item);
       
   292                                         QString classname = item->trlUnit->spell(item->classspec->name->firstToken());
       
   293                                         Trace("- " + classname + " class scaned");
       
   294 
       
   295                                         //We found a class that is defined in the header file that needs to be checked
       
   296                                         if(fileinf.fileName().toLower() == fileinf1.fileName().toLower()){
       
   297                                             CLASSTREE* cltree = new CLASSTREE();
       
   298                                             cltree->highestlevelclass = item;
       
   299                                             cltree->classlist.push_back(item);
       
   300                                             ret.push_back(cltree);
       
   301                                         }
       
   302                                     }
       
   303                                 }
       
   304                             }
       
   305                         }
       
   306                     }
       
   307                 }
       
   308             }
       
   309         }
       
   310     }
       
   311     //after we search for the classes we need to search for the baseclasses
       
   312     Trace("Following classes found in Header file: " + m_strHeaderFile);
       
   313     foreach(CLASSTREE *cltree, ret){
       
   314         QString classname = cltree->highestlevelclass->trlUnit->spell(cltree->highestlevelclass->classspec->name->firstToken());
       
   315         Trace("- " + classname + " class found");
       
   316         QList<CLASSLISTITEM*> baseclasslist;
       
   317         getBaseClasses(cltree->highestlevelclass, baseclasslist, allclasslist, 0, isInterfaceHeader);
       
   318         cltree->classlist.append(baseclasslist);
       
   319     }
       
   320     return ret;
       
   321 }
       
   322 
       
   323 /********************************************
       
   324 Gets all the baseclass from a class and 
       
   325 add those base classes into the baseclasslist
       
   326 ********************************************/
       
   327 void ParseManager::getBaseClasses(const CLASSLISTITEM* pclass
       
   328                                   , QList<CLASSLISTITEM*> &baseclasslist
       
   329                                   , const QList<CLASSLISTITEM*> &allclasslist
       
   330                                   , int level
       
   331                                   , bool isInterfaceHeader)
       
   332 {
       
   333     //iteration over the base_clause_list of the current class
       
   334     QString levelmarker = "  ";
       
   335     for(int i = 0; i < level; i++)
       
   336         levelmarker += "   ";
       
   337     levelmarker += "|- ";
       
   338     QList<CLASSLISTITEM*>child;
       
   339 
       
   340     for(BaseSpecifierListAST *pBaseSpecList = pclass->classspec->base_clause_list; pBaseSpecList; pBaseSpecList = pBaseSpecList->next)
       
   341     {
       
   342         BaseSpecifierAST *pBaseSpec = pBaseSpecList->value;
       
   343         bool found = false;
       
   344         foreach(CLASSLISTITEM* pclspec, allclasslist)
       
   345         {
       
   346             if(pclspec->classspec->symbol->name() 
       
   347                 && pBaseSpec->symbol->name() 
       
   348                 && pclspec->classspec->symbol->name()->isEqualTo(pBaseSpec->symbol->name()))
       
   349             {
       
   350                 child.push_back(pclspec);
       
   351                 baseclasslist.push_back(pclspec);
       
   352                 QString classname = pclspec->trlUnit->spell(pclspec->classspec->name->firstToken());
       
   353                 Trace(levelmarker + classname + " class found");
       
   354                 found = true;
       
   355                 break;
       
   356             }
       
   357         }
       
   358         if(!found && pBaseSpec->name){
       
   359             QString classname = pclass->trlUnit->spell(pBaseSpec->name->firstToken());
       
   360             if(isInterfaceHeader)
       
   361                 Trace(levelmarker + classname + " class not found! Interface classes should not be inherited from Qt Objects!");
       
   362             else
       
   363                 Trace(levelmarker + classname + " class not found!");
       
   364         }
       
   365     }
       
   366     //call the function recursive because all the basclasses can have other base classes
       
   367     foreach(CLASSLISTITEM* pchclass, child){
       
   368         getBaseClasses(pchclass, baseclasslist, allclasslist, ++level, isInterfaceHeader);
       
   369     }
       
   370 }
       
   371 
       
   372 /**************************************************
       
   373 This function finds and creates all Elements wich
       
   374 are significant for MetaDatas.
       
   375 Those element will be added in the aparameter 
       
   376 lists.
       
   377 **************************************************/
       
   378 void ParseManager::getElements(QList<FUNCTIONITEM*> &functionlist
       
   379                                , QList<PROPERTYITEM*> &propertylist
       
   380                                , QList<QENUMITEM*> &qenumlist
       
   381                                , QList<ENUMITEM*> &enumlist
       
   382                                , QList<QFLAGITEM*> &qflaglist
       
   383                                , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
       
   384                                , const QList<CLASSLISTITEM*> classitems
       
   385                                , const CLASSLISTITEM* highestlevelclass)
       
   386 {
       
   387     foreach(CLASSLISTITEM* classitem, classitems){
       
   388         QString classname = "";
       
   389         if(classitem->classspec->name)
       
   390             classname = classitem->trlUnit->spell(classitem->classspec->name->firstToken());
       
   391         for (DeclarationListAST *pmemberlist = classitem->classspec->member_specifier_list; pmemberlist; pmemberlist = pmemberlist->next) {
       
   392             /**********
       
   393             Functions
       
   394             **********/
       
   395             FunctionDefinitionAST *pfctdef = pmemberlist->value->asFunctionDefinition();
       
   396             if(pfctdef){
       
   397                 FUNCTIONITEM* item = new FUNCTIONITEM();
       
   398                 item->trlUnit = classitem->trlUnit;
       
   399                 item->function = pfctdef->symbol;
       
   400                 item->classAst = classitem->classspec;
       
   401                 item->highestlevelclass = highestlevelclass;
       
   402                 functionlist.push_back(item);
       
   403                 if(isMetaObjFunction(item))
       
   404                     Trace("  - " + getTraceFuntionString(item, classname) + " found");
       
   405             }
       
   406 
       
   407             SimpleDeclarationAST *pdecl = pmemberlist->value->asSimpleDeclaration();
       
   408             if(pdecl){
       
   409                 for(List<Declaration*>* decllist = pdecl->symbols; decllist; decllist = decllist->next)
       
   410                 {
       
   411                     Function* pfct = decllist->value->type()->asFunctionType();
       
   412                     if(pfct){
       
   413                         FUNCTIONITEM* item = new FUNCTIONITEM();
       
   414                         item->trlUnit = classitem->trlUnit;
       
   415                         item->function = pfct;
       
   416                         item->classAst = classitem->classspec;
       
   417                         item->highestlevelclass = highestlevelclass;
       
   418                         functionlist.push_back(item);
       
   419                         if(isMetaObjFunction(item))
       
   420                             Trace("  - " + getTraceFuntionString(item, classname) + " found");
       
   421                     }
       
   422                 }
       
   423                 /******
       
   424                 enum
       
   425                 ******/
       
   426                 for(List<SpecifierAST*>* decllist = pdecl->decl_specifier_list; decllist; decllist = decllist->next)
       
   427                 {
       
   428                     EnumSpecifierAST * penum = decllist->value->asEnumSpecifier();
       
   429                     if(penum){
       
   430                         ENUMITEM* item = new ENUMITEM();
       
   431                         item->ast = penum;
       
   432                         item->highestlevelclass = highestlevelclass;
       
   433                         item->trlUnit = classitem->trlUnit;
       
   434                         enumlist.push_back(item);
       
   435                     }
       
   436                 }
       
   437             }
       
   438             else{
       
   439                 /**********
       
   440                 Q_PROPERTY
       
   441                 **********/
       
   442                 QPropertyDeclarationAST *ppdecl = pmemberlist->value->asQPropertyDeclarationAST();
       
   443                 if(ppdecl){
       
   444                     PROPERTYITEM* item = new PROPERTYITEM();
       
   445                     item->ast = ppdecl;
       
   446                     item->highestlevelclass = highestlevelclass;
       
   447                     item->trlUnit = classitem->trlUnit;
       
   448                     item->readdefined = (ppdecl->read_token > 0);
       
   449                     item->writedefined = (ppdecl->write_token > 0);
       
   450                     item->resetdefined = (ppdecl->reset_token > 0);
       
   451                     item->notifydefined = (ppdecl->notify_token > 0);
       
   452                     propertylist.push_back(item);
       
   453                     if(item->ast->type_name_token > 0){
       
   454                         QString propertyname = item->trlUnit->spell(item->ast->type_name_token);
       
   455                         Trace("  - Q_PROPERTY: " + classname + "::" + propertyname + " found");
       
   456                     }
       
   457                 }
       
   458                 else{
       
   459                     /**********
       
   460                     Q_ENUM
       
   461                     **********/
       
   462                     QEnumDeclarationAST *pqenum = pmemberlist->value->asQEnumDeclarationAST();
       
   463                     if(pqenum){
       
   464                         if(pqenum->enumerator_list){
       
   465                             for (EnumeratorListAST *plist = pqenum->enumerator_list; plist; plist = plist->next) {
       
   466                                 QENUMITEM* item = new QENUMITEM();
       
   467                                 item->ast = plist->value;
       
   468                                 item->highestlevelclass = highestlevelclass;
       
   469                                 item->trlUnit = classitem->trlUnit;
       
   470                                 qenumlist.push_back(item);
       
   471                                 QString enumname = item->trlUnit->spell(item->ast->firstToken());
       
   472                                 Trace("  - Q_ENUM: " + classname + "::" + enumname + " found");
       
   473                             }
       
   474                         }
       
   475 
       
   476                     }
       
   477                     else{
       
   478                         /**********
       
   479                         Q_FLAGS
       
   480                         **********/
       
   481                         QFlagsDeclarationAST *pqflags = pmemberlist->value->asQFlagsDeclarationAST();
       
   482                         if(pqflags){
       
   483                             if(pqflags->enumerator_list){
       
   484                                 for (EnumeratorListAST *plist = pqflags->enumerator_list; plist; plist = plist->next) {
       
   485                                     QFLAGITEM* item = new QFLAGITEM();
       
   486                                     item->ast = plist->value;
       
   487                                     item->highestlevelclass = highestlevelclass;
       
   488                                     item->trlUnit = classitem->trlUnit;
       
   489                                     qflaglist.push_back(item);
       
   490                                     QString enumname = item->trlUnit->spell(plist->firstToken());
       
   491                                     Trace("  - Q_FLAGS: " + classname + "::" + enumname + " found");
       
   492                                 }
       
   493                             }
       
   494                         }
       
   495                         else {
       
   496                             /****************
       
   497                             Q_DECLARE_FLAGS
       
   498                             ****************/
       
   499                             QDeclareFlagsDeclarationAST *pqdeclflags = pmemberlist->value->asQDeclareFlagsDeclarationAST();
       
   500                             if(pqdeclflags){
       
   501                                 QDECLAREFLAGSITEM* item = new QDECLAREFLAGSITEM();
       
   502                                 item->ast = pqdeclflags;
       
   503                                 item->highestlevelclass = highestlevelclass;
       
   504                                 item->trlUnit = classitem->trlUnit;
       
   505                                 qdeclareflaglist.push_back(item);
       
   506                             }
       
   507                         }
       
   508                     }
       
   509                 }
       
   510             }
       
   511         }
       
   512     }
       
   513 }
       
   514 
       
   515 /*********************************************
       
   516 Function that starts the comare between the 
       
   517 parser result and their metadata content.
       
   518 *********************************************/
       
   519 bool ParseManager::checkAllMetadatas(ParseManager* pInterfaceParserManager, QString resultfile)
       
   520 {
       
   521     bool ret = true;
       
   522     
       
   523     //Create output file
       
   524     if(resultfile != "" && ::m_resultFile == 0){
       
   525         ::m_resultFile = new QFile(resultfile);
       
   526         if (!::m_resultFile->open(QFile::WriteOnly | QFile::Truncate)) {
       
   527             delete ::m_resultFile;
       
   528             ::m_resultFile = 0;
       
   529          }
       
   530     }
       
   531 
       
   532     /************************************************
       
   533     Get all elements from the interface header file
       
   534     ************************************************/
       
   535     Trace("### Get all elements from the interface header file ###");
       
   536     QList<CLASSTREE*> ilookuplist = pInterfaceParserManager->CreateClassLists(true);
       
   537     QList<QList<FUNCTIONITEM*> > ifunctionslookuplist;
       
   538     QList<QList<PROPERTYITEM*> > ipropertieslookuplist;
       
   539     QList<QList<QENUMITEM*> > iqenumlookuplist;
       
   540     QList<QList<ENUMITEM*> > ienumlookuplist;
       
   541     QList<QList<QFLAGITEM*> > iqflaglookuplist;
       
   542     QList<QList<QDECLAREFLAGSITEM*> > iqdeclareflaglookuplist;
       
   543     Trace("Following MetaData found:");
       
   544     foreach(CLASSTREE* iclasstree, ilookuplist){
       
   545         QList<FUNCTIONITEM*>functionlist;
       
   546         QList<PROPERTYITEM*>propertylist;
       
   547         QList<QENUMITEM*>qenumlist;
       
   548         QList<ENUMITEM*>enumlist;
       
   549         QList<QFLAGITEM*> qflaglist;
       
   550         QList<QDECLAREFLAGSITEM*> qdeclareflag;
       
   551         getElements(functionlist
       
   552             , propertylist
       
   553             , qenumlist
       
   554             , enumlist
       
   555             , qflaglist
       
   556             , qdeclareflag
       
   557             , iclasstree->classlist
       
   558             , iclasstree->highestlevelclass);
       
   559         if(functionlist.size() > 0)
       
   560             ifunctionslookuplist.append(functionlist);
       
   561         if(propertylist.size() > 0)
       
   562             ipropertieslookuplist.append(propertylist);
       
   563         if(qenumlist.size() > 0)
       
   564             iqenumlookuplist.append(qenumlist);
       
   565         if(enumlist.size() > 0)
       
   566             ienumlookuplist.append(enumlist);
       
   567         if(qflaglist.size() > 0)
       
   568             iqflaglookuplist.append(qflaglist);
       
   569         if(qdeclareflag.size() > 0)
       
   570             iqdeclareflaglookuplist.append(qdeclareflag);
       
   571     }
       
   572 
       
   573     /************************************************
       
   574     Get all elements from the compare header file
       
   575     ************************************************/
       
   576     Trace("\n");
       
   577     Trace("### Get all elements from the compare header file ###");
       
   578     QList<CLASSTREE*> lookuplist = CreateClassLists(false);
       
   579     QList<QList<FUNCTIONITEM*> > functionslookuplist;
       
   580     QList<QList<PROPERTYITEM*> > propertieslookuplist;
       
   581     QList<QList<QENUMITEM*> > qenumlookuplist;
       
   582     QList<QList<ENUMITEM*> > enumlookuplist;
       
   583     QList<QList<QFLAGITEM*> > qflaglookuplist;
       
   584     QList<QList<QDECLAREFLAGSITEM*> > qdeclareflaglookuplist;
       
   585     Trace("Following MetaData found:");
       
   586     foreach(CLASSTREE* classtree, lookuplist){
       
   587         QList<FUNCTIONITEM*>functionlist;
       
   588         QList<PROPERTYITEM*>propertylist;
       
   589         QList<QENUMITEM*>qenumlist;
       
   590         QList<ENUMITEM*>enumlist;
       
   591         QList<QFLAGITEM*> qflaglist;
       
   592         QList<QDECLAREFLAGSITEM*> qdeclareflag;
       
   593         getElements(functionlist
       
   594             , propertylist
       
   595             , qenumlist
       
   596             , enumlist
       
   597             , qflaglist
       
   598             , qdeclareflag
       
   599             , classtree->classlist
       
   600             , classtree->highestlevelclass);
       
   601         if(functionlist.size() > 0)
       
   602             functionslookuplist.append(functionlist);
       
   603         if(propertylist.size() > 0)
       
   604             propertieslookuplist.append(propertylist);
       
   605         if(qenumlist.size() > 0)
       
   606             qenumlookuplist.append(qenumlist);
       
   607         if(enumlist.size() > 0)
       
   608             enumlookuplist.append(enumlist);
       
   609         if(qflaglist.size() > 0)
       
   610             qflaglookuplist.append(qflaglist);
       
   611         if(qdeclareflag.size() > 0)
       
   612             qdeclareflaglookuplist.append(qdeclareflag);
       
   613     }
       
   614 
       
   615     Trace("\n");
       
   616     Trace("### Result: ###");
       
   617     /******************************
       
   618     Check for function
       
   619     ******************************/
       
   620     Trace("Compare all interface MetaData functions:");
       
   621     QList<FUNCTIONITEM*> missingifcts = checkMetadataFunctions(functionslookuplist, ifunctionslookuplist);
       
   622     if(missingifcts.size() > 0){
       
   623         foreach(FUNCTIONITEM* ifct, missingifcts){
       
   624             m_errormsgs.append(getErrorMessage(ifct));
       
   625         }
       
   626         ret =  false;
       
   627         Trace("- Failed!");
       
   628     }
       
   629     else{
       
   630         Trace("- OK");
       
   631     }
       
   632 
       
   633     /******************************
       
   634     Check for properies
       
   635     ******************************/
       
   636     Trace("Compare all interface MetaData properties:");
       
   637     QList<PROPERTYITEM*> missingippts = checkMetadataProperties(propertieslookuplist, functionslookuplist, ipropertieslookuplist, ifunctionslookuplist);
       
   638     if(missingippts.size() > 0){
       
   639         foreach(PROPERTYITEM* ippt, missingippts){
       
   640             m_errormsgs.append(getErrorMessage(ippt));
       
   641         }
       
   642         ret =  false;
       
   643         Trace("- Failed!");
       
   644     }
       
   645     else{
       
   646         Trace("- OK");
       
   647     }
       
   648 
       
   649     /******************************
       
   650     Check for enums
       
   651     ******************************/
       
   652     Trace("Compare all interface MetaData enums:");
       
   653     QList<QENUMITEM*> missingiqenums = checkMetadataEnums(qenumlookuplist, enumlookuplist, iqenumlookuplist, ienumlookuplist);
       
   654     if(missingiqenums.size() > 0){
       
   655         foreach(QENUMITEM* ienum, missingiqenums){
       
   656             m_errormsgs.append(getErrorMessage(ienum));
       
   657         }
       
   658         ret =  false;
       
   659         Trace("- Failed!");
       
   660     }
       
   661     else{
       
   662         Trace("- OK");
       
   663     }
       
   664 
       
   665     /******************************
       
   666     Check for flags
       
   667     ******************************/
       
   668     Trace("Compare all interface MetaData flags:");
       
   669     QList<QFLAGITEM*> missingiqflags = checkMetadataFlags(qflaglookuplist, qdeclareflaglookuplist, enumlookuplist
       
   670                                                         , iqflaglookuplist, iqdeclareflaglookuplist, ienumlookuplist);
       
   671     if(missingiqflags.size() > 0){
       
   672         foreach(QFLAGITEM* iflags, missingiqflags){
       
   673             m_errormsgs.append(getErrorMessage(iflags));
       
   674         }
       
   675         ret =  false;
       
   676         Trace("- Failed!");
       
   677     }
       
   678     else{
       
   679         Trace("- OK");
       
   680     }
       
   681 
       
   682     /******************************
       
   683     Add summary
       
   684     ******************************/
       
   685     Trace("\n");
       
   686     Trace("### summary ###");
       
   687     if(m_errormsgs.size() > 0){
       
   688         Trace("- Folowing interface items are missing:");
       
   689         foreach(QString msg, m_errormsgs)
       
   690             Trace("  - " + msg);
       
   691     }
       
   692     else
       
   693         Trace("Interface is full defined.");
       
   694 
       
   695     //now delet all Classitems
       
   696     foreach(CLASSTREE* l, ilookuplist){
       
   697         l->classlist.clear();
       
   698     }
       
   699     foreach(CLASSTREE* l, lookuplist){
       
   700         l->classlist.clear();
       
   701     }
       
   702     //delete all functionitems
       
   703     foreach(QList<FUNCTIONITEM*>l, ifunctionslookuplist){
       
   704         l.clear();
       
   705     }
       
   706     foreach(QList<FUNCTIONITEM*>l, functionslookuplist){
       
   707         l.clear();
       
   708     }
       
   709     //delete all properties
       
   710     foreach(QList<PROPERTYITEM*>l, ipropertieslookuplist){
       
   711         l.clear();
       
   712     }
       
   713     foreach(QList<PROPERTYITEM*>l, propertieslookuplist){
       
   714         l.clear();
       
   715     }
       
   716     //delete all qenums
       
   717     foreach(QList<QENUMITEM*>l, iqenumlookuplist){
       
   718         l.clear();
       
   719     }
       
   720     foreach(QList<QENUMITEM*>l, iqenumlookuplist){
       
   721         l.clear();
       
   722     }
       
   723     //delete all enums
       
   724     foreach(QList<ENUMITEM*>l, ienumlookuplist){
       
   725         l.clear();
       
   726     }
       
   727     foreach(QList<ENUMITEM*>l, enumlookuplist){
       
   728         l.clear();
       
   729     }
       
   730     //delete all qflags
       
   731     foreach(QList<QFLAGITEM*>l, iqflaglookuplist){
       
   732         l.clear();
       
   733     }
       
   734     foreach(QList<QFLAGITEM*>l, qflaglookuplist){
       
   735         l.clear();
       
   736     }
       
   737     //delete all qdeclareflags
       
   738     foreach(QList<QDECLAREFLAGSITEM*>l, iqdeclareflaglookuplist){
       
   739         l.clear();
       
   740     }
       
   741     foreach(QList<QDECLAREFLAGSITEM*>l, qdeclareflaglookuplist){
       
   742         l.clear();
       
   743     }
       
   744 
       
   745     return ret;
       
   746 }
       
   747 
       
   748 //<-------------------------------------------------------  Start of MetaData functions
       
   749 /***********************************
       
   750 Function that checks all functions
       
   751 which will occur in the MetaData
       
   752 ***********************************/
       
   753 QList<FUNCTIONITEM*> ParseManager::checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
       
   754 {
       
   755     QList<FUNCTIONITEM*> missingifcts;
       
   756     //Compare each function from interface with function from header (incl. baseclass functions)
       
   757     QList<FUNCTIONITEM*> ifcts;
       
   758     foreach(QList<FUNCTIONITEM*>ifunctionlist, iclassfctlist){
       
   759         ifcts.clear();
       
   760         //check if one header class contains all function from one interface header class
       
   761         if(classfctlist.count() > 0){
       
   762             foreach(QList<FUNCTIONITEM*>functionlist, classfctlist){
       
   763                 QList<FUNCTIONITEM*> tmpl = containsAllMetadataFunction(functionlist, ifunctionlist);
       
   764                 if(tmpl.size() == 0){
       
   765                     ifcts.clear();
       
   766                     break;
       
   767                 }
       
   768                 else
       
   769                     ifcts.append(tmpl);
       
   770             }
       
   771         }
       
   772         else {
       
   773             foreach(FUNCTIONITEM *pfct, ifunctionlist)
       
   774                 pfct->classWichIsNotFound << "<all classes>";
       
   775             ifcts.append(ifunctionlist);
       
   776         }
       
   777         missingifcts.append(ifcts);
       
   778     }
       
   779     return missingifcts;
       
   780 }
       
   781 
       
   782 /*********************************************
       
   783 Helper function to check if a function will 
       
   784 occure in the MetaData.
       
   785 *********************************************/
       
   786 bool ParseManager::isMetaObjFunction(FUNCTIONITEM* fct)
       
   787 {
       
   788     if(fct->function->isInvokable()
       
   789         || fct->function->isSignal()
       
   790         || fct->function->isSlot())
       
   791         return true;
       
   792     return false;
       
   793 }
       
   794 
       
   795 /****************************************************
       
   796 Check if all function from iclassfctlist are defined 
       
   797 in the classfctlist as well.
       
   798 It will return all the function they are missing.
       
   799 ****************************************************/
       
   800 QList<FUNCTIONITEM*> ParseManager::containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist)
       
   801 {
       
   802     QList<FUNCTIONITEM*> ret;
       
   803     foreach(FUNCTIONITEM* ifct, iclassfctlist){
       
   804         if(isMetaObjFunction(ifct)){
       
   805             bool found = false;
       
   806             QStringList missingimplinclasses;
       
   807             ClassSpecifierAST* clspec = 0;
       
   808             QString classname = "";
       
   809             foreach(FUNCTIONITEM* fct, classfctlist){
       
   810                 if(clspec != fct->highestlevelclass->classspec){
       
   811                     clspec = fct->highestlevelclass->classspec;
       
   812                     //get the classname
       
   813                     unsigned int firsttoken = clspec->name->firstToken();
       
   814                     classname += fct->trlUnit->spell(firsttoken);
       
   815                     if(missingimplinclasses.indexOf(classname) < 0)
       
   816                         missingimplinclasses.push_back(classname);
       
   817                 }
       
   818                 if(fct->isEqualTo(ifct, false)){
       
   819                     found = true;
       
   820                     missingimplinclasses.clear();
       
   821                     Trace("- " + getTraceFuntionString(fct, classname) + " implemented");
       
   822                     break;
       
   823                 }
       
   824             }
       
   825             if(!found){
       
   826                 ifct->classWichIsNotFound.append(missingimplinclasses);
       
   827                 ret.push_back(ifct);
       
   828                 QString classname = ifct->trlUnit->spell(ifct->highestlevelclass->classspec->name->firstToken());
       
   829                 Trace("- " + getTraceFuntionString(ifct, classname) + " not implemented!");
       
   830             }
       
   831         }
       
   832     }
       
   833     return ret;
       
   834 }
       
   835 
       
   836 /************************************
       
   837 Function that gives back an error 
       
   838 string for a MetaData function
       
   839 mismatch.
       
   840 ************************************/
       
   841 QStringList ParseManager::getErrorMessage(FUNCTIONITEM* fct)
       
   842 {
       
   843     QStringList ret;
       
   844     QString fctstring = "";
       
   845     QString fcttype = "";
       
   846 
       
   847     foreach(QString classname, fct->classWichIsNotFound){
       
   848         QString tmp;
       
   849         QTextStream out(&tmp);
       
   850 
       
   851         fcttype = "";
       
   852         fctstring = classname;
       
   853         fctstring += "::";
       
   854 
       
   855         unsigned int token = fct->function->sourceLocation() - 1;
       
   856         if(token >= 0){
       
   857             //tok.isNot(T_EOF_SYMBOL)
       
   858             while(fct->trlUnit->tokenAt(token).isNot(T_EOF_SYMBOL)){
       
   859                 fctstring += fct->trlUnit->tokenAt(token).spell();
       
   860                 if(*fct->trlUnit->tokenAt(token).spell() == ')')
       
   861                     break;
       
   862                 fctstring += " ";
       
   863                 token++;
       
   864             }
       
   865         }
       
   866 
       
   867         Function* pfct = fct->function;
       
   868         if(pfct){
       
   869             fcttype = "type: ";
       
   870             //Check for private, protected and public
       
   871             if(pfct->isPublic())
       
   872                 fcttype = "public ";
       
   873             if(pfct->isProtected())
       
   874                 fcttype = "protected ";
       
   875             if(pfct->isPrivate())
       
   876                 fcttype = "private ";
       
   877 
       
   878             if(pfct->isVirtual())
       
   879                 fcttype += "virtual ";
       
   880             if(pfct->isPureVirtual())
       
   881                 fcttype += "pure virtual ";
       
   882 
       
   883             if(pfct->isSignal())
       
   884                 fcttype += "Signal ";
       
   885             if(pfct->isSlot())
       
   886                 fcttype += "Slot ";
       
   887             if(pfct->isNormal())
       
   888                 fcttype += "Normal ";
       
   889             if(pfct->isInvokable())
       
   890                 fcttype += "Invokable ";
       
   891         }
       
   892         out << fcttype << fctstring;
       
   893         ret << tmp;
       
   894     }
       
   895     return ret;
       
   896 }
       
   897 //--->
       
   898 
       
   899 //<-------------------------------------------------------  Start of Q_PROPERTY checks
       
   900 /***********************************
       
   901 Function that checks all Property
       
   902 which will occur in the MetaData
       
   903 ***********************************/
       
   904 QList<PROPERTYITEM*> ParseManager::checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
       
   905                                                                          , const QList<QList<FUNCTIONITEM*> > &classfctlist
       
   906                                                                          , const QList<QList<PROPERTYITEM*> > &iclassproplist
       
   907                                                                          , const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
       
   908 {
       
   909     QList<PROPERTYITEM*> missingiprops;
       
   910     //assign the property functions
       
   911     foreach(QList<PROPERTYITEM*>proplist, classproplist){
       
   912         foreach(PROPERTYITEM* prop, proplist){
       
   913             assignPropertyFunctions(prop, classfctlist);
       
   914         }
       
   915     }
       
   916 
       
   917     foreach(QList<PROPERTYITEM*>proplist, iclassproplist){
       
   918         foreach(PROPERTYITEM* prop, proplist){
       
   919             assignPropertyFunctions(prop, iclassfctlist);
       
   920         }
       
   921     }
       
   922 
       
   923     //Compare each qproperty from interface with qproperty from header (incl. baseclass functions)
       
   924     QList<PROPERTYITEM*> ippts;
       
   925     foreach(QList<PROPERTYITEM*>ipropertylist, iclassproplist){
       
   926         ippts.clear();
       
   927         //check if one header class contains all function from one interface header class
       
   928         if(classproplist.count() > 0){
       
   929             foreach(QList<PROPERTYITEM*>propertylist, classproplist){
       
   930                 QList<PROPERTYITEM*> tmpl = containsAllPropertyFunction(propertylist, ipropertylist);
       
   931                 if(tmpl.size() == 0)
       
   932                     ippts.clear();
       
   933                 else
       
   934                     ippts.append(tmpl);
       
   935             }
       
   936         }
       
   937         else {
       
   938             foreach(PROPERTYITEM *pprop, ipropertylist){
       
   939                 pprop->classWichIsNotFound << "<all classes>";
       
   940                 QString name = pprop->trlUnit->spell(pprop->ast->type_name_token);
       
   941                 Trace("- Property: <all classes>::" + name + " not found!");
       
   942             }
       
   943             ippts.append(ipropertylist);
       
   944         }
       
   945         missingiprops.append(ippts);
       
   946     }
       
   947     return missingiprops;
       
   948 }
       
   949 
       
   950 /**************************************
       
   951 Function that resolves the dependensies
       
   952 between Q_PROPERTY
       
   953 and thier READ, WRITE, NOTIFY and RESET
       
   954 functions.
       
   955 ***************************************/
       
   956 void ParseManager::assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist)
       
   957 {
       
   958     //get the name of the needed functions
       
   959     QString type;
       
   960     QString readfctname;
       
   961     QString writefctname;
       
   962     QString resetfctname;
       
   963     QString notifyfctname;
       
   964 
       
   965     int needtofind = 0;
       
   966     type = prop->trlUnit->spell(prop->ast->type_token);
       
   967     if(prop->readdefined){
       
   968         readfctname = prop->trlUnit->spell(prop->ast->read_function_token);
       
   969         needtofind++;
       
   970     }
       
   971     if(prop->writedefined){
       
   972         writefctname = prop->trlUnit->spell(prop->ast->write_function_token);
       
   973         needtofind++;
       
   974     }
       
   975     if(prop->resetdefined){
       
   976         resetfctname = prop->trlUnit->spell(prop->ast->reset_function_token);
       
   977         needtofind++;
       
   978     }
       
   979     if(prop->notifydefined){
       
   980         notifyfctname = prop->trlUnit->spell(prop->ast->notify_function_token);
       
   981         needtofind++;
       
   982     }
       
   983     //Now iterate over all function to find all functions wich are defined in the Q_PROPERTY macro
       
   984     if(needtofind > 0){
       
   985         prop->foundalldefinedfct = false;
       
   986         foreach(QList<FUNCTIONITEM*> fctlist, fctlookuplist){
       
   987             foreach(FUNCTIONITEM* pfct, fctlist){
       
   988                 QString fctname = pfct->trlUnit->spell(pfct->function->sourceLocation());
       
   989                 //check the function type against the property type
       
   990                 QString fcttype =pfct->trlUnit->spell(pfct->function->sourceLocation() - 1);
       
   991 
       
   992                 if(fctname.length() > 0 && fcttype.length() > 0){
       
   993                     if(prop->readdefined && fctname == readfctname){
       
   994                         if(type != fcttype)
       
   995                             continue;
       
   996                         prop->readFct = pfct;
       
   997                         needtofind--;
       
   998                     }
       
   999                     if(prop->writedefined && fctname == writefctname){
       
  1000                         prop->writeFct = pfct;
       
  1001                         needtofind--;
       
  1002                     }
       
  1003                     if(prop->resetdefined && fctname == resetfctname){
       
  1004                         prop->resetFct = pfct;
       
  1005                         needtofind--;
       
  1006                     }
       
  1007                     if(prop->notifydefined && fctname == notifyfctname){
       
  1008                         prop->notifyFct = pfct;
       
  1009                         needtofind--;
       
  1010                     }
       
  1011                     if(needtofind <= 0){
       
  1012                         //a flag that indicates if a function was missing
       
  1013                         prop->foundalldefinedfct = true;
       
  1014                         return;
       
  1015                     }
       
  1016                 }
       
  1017             }
       
  1018         }
       
  1019     }
       
  1020 }
       
  1021 
       
  1022 /**************************************
       
  1023 Function that checks if all functions
       
  1024 dependencies in Q_PROPERTY have the
       
  1025 same arguments and retunr value.
       
  1026 ***************************************/
       
  1027 QList<PROPERTYITEM*> ParseManager::containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist)
       
  1028 {
       
  1029     QList<PROPERTYITEM*> ret;
       
  1030     foreach(PROPERTYITEM* ipropt, iclassproplist){
       
  1031         if(ipropt->foundalldefinedfct){
       
  1032             bool found = false;
       
  1033             QStringList missingimplinclasses;
       
  1034             ClassSpecifierAST* clspec = 0;
       
  1035             QString classname = "";
       
  1036             foreach(PROPERTYITEM* propt, classproplist){
       
  1037                 if(clspec != propt->highestlevelclass->classspec){
       
  1038                     clspec = propt->highestlevelclass->classspec;
       
  1039                     //get the classname
       
  1040                     unsigned int firsttoken = clspec->name->firstToken();
       
  1041                     classname += propt->trlUnit->spell(firsttoken);
       
  1042                     if(missingimplinclasses.indexOf(classname) < 0)
       
  1043                         missingimplinclasses.push_back(classname);
       
  1044                 }
       
  1045                 if(propt->isEqualTo(ipropt)){
       
  1046                     found = true;
       
  1047                     missingimplinclasses.clear();
       
  1048                     Trace("- Property: " + classname + "::" + propt->trlUnit->spell(propt->ast->type_name_token) + " found");
       
  1049                     break;
       
  1050                 }
       
  1051             }
       
  1052             if(!found){
       
  1053                 ipropt->classWichIsNotFound.append(missingimplinclasses);
       
  1054                 ret.push_back(ipropt);
       
  1055                 QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
       
  1056                 Trace("- Property: " + classname + "::" + ipropt->trlUnit->spell(ipropt->ast->type_name_token) + " not found!");
       
  1057             }
       
  1058         }
       
  1059         else{
       
  1060             QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
       
  1061             QString proptype = ipropt->trlUnit->spell(ipropt->ast->type_name_token);
       
  1062             Trace("- Property: " + classname + "::" + proptype + " functions are missing!");
       
  1063             ret.push_back(ipropt);
       
  1064         }
       
  1065     }
       
  1066     return ret;
       
  1067 }
       
  1068 
       
  1069 /************************************
       
  1070 Function that gives back an error 
       
  1071 string for a Q_PROPERTY mismatch.
       
  1072 ************************************/
       
  1073 QStringList ParseManager::getErrorMessage(PROPERTYITEM* ppt)
       
  1074 {
       
  1075     QStringList ret;
       
  1076     QString pptstring = "";
       
  1077 
       
  1078     if(!ppt->foundalldefinedfct)
       
  1079     {
       
  1080         QString tmp;
       
  1081         QTextStream out(&tmp);
       
  1082 
       
  1083         unsigned int firsttoken = ppt->highestlevelclass->classspec->name->firstToken();
       
  1084         unsigned int lasttoken = ppt->highestlevelclass->classspec->name->lastToken();
       
  1085         for(unsigned int i = firsttoken; i < lasttoken; i++){
       
  1086             out << ppt->trlUnit->spell(i);
       
  1087         }
       
  1088         out << "::";
       
  1089         firsttoken = ppt->ast->firstToken();
       
  1090         lasttoken = ppt->ast->lastToken();
       
  1091         for(unsigned int i = firsttoken; i <= lasttoken; i++){
       
  1092             out << ppt->trlUnit->spell(i) << " ";
       
  1093         }
       
  1094         out << endl << " -";
       
  1095         if(ppt->readdefined && !ppt->readFct)
       
  1096             out << "READ ";
       
  1097         if(ppt->writedefined && !ppt->writeFct)
       
  1098             out << "WRITE ";
       
  1099         if(ppt->resetdefined && !ppt->resetFct)
       
  1100             out << "RESET.";
       
  1101         if(ppt->notifydefined && !ppt->notifyFct)
       
  1102             out << "NOTIFY ";
       
  1103         out << "functions missing." << endl;
       
  1104         ret << tmp;
       
  1105     }
       
  1106     for(int i = 0; i < ppt->classWichIsNotFound.size(); i++){
       
  1107         QString tmp;
       
  1108         QTextStream out(&tmp);
       
  1109 
       
  1110         pptstring = ppt->classWichIsNotFound[i];
       
  1111         pptstring += "::";
       
  1112 
       
  1113         unsigned int firsttoken = ppt->ast->firstToken();
       
  1114         unsigned int lasttoken = ppt->ast->lastToken();
       
  1115         for(unsigned int i = firsttoken; i <= lasttoken; i++){
       
  1116             pptstring += ppt->trlUnit->spell(i);
       
  1117             pptstring += " ";
       
  1118         }
       
  1119 
       
  1120         out << pptstring;
       
  1121         ret << tmp;
       
  1122     }
       
  1123     return ret;
       
  1124 }
       
  1125 //--->
       
  1126 
       
  1127 
       
  1128 //<------------------------------------------------------- Start of Q_ENUMS checks
       
  1129 /***********************************
       
  1130 Function that checks all enums
       
  1131 which will occur in the MetaData
       
  1132 ***********************************/
       
  1133 QList<QENUMITEM*> ParseManager::checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
       
  1134                                                 , const QList<QList<ENUMITEM*> > &classenumlist
       
  1135                                                 , const QList<QList<QENUMITEM*> > &iclassqenumlist
       
  1136                                                 , const QList<QList<ENUMITEM*> > &iclassenumlist)
       
  1137 {
       
  1138     QList<QENUMITEM*> missingiqenums;
       
  1139     //assign the property functions
       
  1140     foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
       
  1141         foreach(QENUMITEM* qenum, qenumlist){
       
  1142             assignEnumValues(qenum, classenumlist);
       
  1143         }
       
  1144     }
       
  1145     foreach(QList<QENUMITEM*>qenumlist, iclassqenumlist){
       
  1146         foreach(QENUMITEM* qenum, qenumlist){
       
  1147             assignEnumValues(qenum, iclassenumlist);
       
  1148         }
       
  1149     }
       
  1150 
       
  1151     //Compare each qenum from interface with qenum from header (incl. baseclass functions)
       
  1152     QList<QENUMITEM*> iqenums;
       
  1153     foreach(QList<QENUMITEM*>iqenumlist, iclassqenumlist){
       
  1154         iqenums.clear();
       
  1155         //check if one header class contains all function from one interface header class
       
  1156         if(classqenumlist.count() > 0){
       
  1157             foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
       
  1158                 QList<QENUMITEM*> tmpl = containsAllEnums(qenumlist, iqenumlist);
       
  1159                 if(tmpl.size() == 0)
       
  1160                     iqenums.clear();
       
  1161                 else
       
  1162                     iqenums.append(tmpl);
       
  1163 
       
  1164             }
       
  1165         }
       
  1166         else {
       
  1167             foreach(QENUMITEM *qenum, iqenumlist){
       
  1168                 qenum->classWichIsNotFound << "<all classes>";
       
  1169                 QString name= qenum->trlUnit->spell(qenum->ast->firstToken());
       
  1170                 Trace("- Enum: <all classes>::" + name + " not found!");
       
  1171             }
       
  1172             iqenums.append(iqenumlist);
       
  1173         }
       
  1174         missingiqenums.append(iqenums);
       
  1175     }
       
  1176 
       
  1177     return missingiqenums;
       
  1178 }
       
  1179 
       
  1180 /*********************************************
       
  1181 Helper function which creates a string out of
       
  1182 an enumerator including its values.
       
  1183 *********************************************/
       
  1184 QStringList ParseManager::getEnumValueStringList(ENUMITEM *penum, QString mappedenumname/* = ""*/)
       
  1185 {
       
  1186     QStringList ret;
       
  1187     EnumSpecifierAST *penumsec = penum->ast;
       
  1188     QString enumname = penum->trlUnit->spell(penumsec->name->firstToken());
       
  1189     int enumvalue = 0;
       
  1190     //now iterrate over all enumitems and create a string like following:
       
  1191     //EnumName.EnumItemName.Value
       
  1192     //ConnectionState.disconnected.0
       
  1193     for (EnumeratorListAST *plist = penum->ast->enumerator_list; plist; plist = plist->next) {
       
  1194         QString value = enumname;
       
  1195         if(mappedenumname.size() > 0)
       
  1196             value = mappedenumname;
       
  1197         value += ".";
       
  1198         value += penum->trlUnit->spell(plist->value->identifier_token);
       
  1199         value += ".";
       
  1200         if(plist->value->equal_token > 0 && plist->value->expression){
       
  1201             QString v = penum->trlUnit->spell(plist->value->expression->firstToken());
       
  1202             bool ch;
       
  1203             int newval = enumvalue;
       
  1204             if(v.indexOf("0x") >= 0)
       
  1205                 newval = v.toInt(&ch, 16);
       
  1206             else
       
  1207                 newval = v.toInt(&ch, 10);
       
  1208             if(ch)
       
  1209                 enumvalue = newval;
       
  1210         }
       
  1211         value += QString::number(enumvalue);
       
  1212         enumvalue++;
       
  1213         // now add this enumitem string in the VALUE list
       
  1214         ret << value;
       
  1215     }
       
  1216     return ret;
       
  1217 }
       
  1218 
       
  1219 /**************************************
       
  1220 Function that resolves the dependensies
       
  1221 between Q_ENUMS and enums.
       
  1222 ***************************************/
       
  1223 void ParseManager::assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist)
       
  1224 {
       
  1225     QString enumname;
       
  1226     EnumeratorAST *penum = qenum->ast->asEnumerator();
       
  1227     if(penum){
       
  1228         //get the name of the enum definition
       
  1229         enumname = qenum->trlUnit->spell(penum->firstToken());
       
  1230         //iterate over all enums and find the one with the same name like enumname
       
  1231         bool found = false;
       
  1232         foreach (QList<ENUMITEM*> penumlist, enumlookuplist) {
       
  1233             foreach(ENUMITEM *penum, penumlist){
       
  1234                 EnumSpecifierAST *penumsec = penum->ast;
       
  1235                 QString enumname1 = penum->trlUnit->spell(penumsec->name->firstToken());
       
  1236                 if(enumname == enumname1){
       
  1237                     qenum->values << getEnumValueStringList(penum);
       
  1238                     found = true;
       
  1239                     break;
       
  1240                 }
       
  1241             }
       
  1242             if(!found)
       
  1243                 qenum->foundallenums = false;
       
  1244         }
       
  1245     }
       
  1246 }
       
  1247 
       
  1248 /***********************************
       
  1249 Function that checkt if the Q_ENUMS 
       
  1250 are completed defined and if the
       
  1251 Enum values are the same.
       
  1252 ***********************************/
       
  1253 QList<QENUMITEM*> ParseManager::containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist)
       
  1254 {
       
  1255     QList<QENUMITEM*> ret;
       
  1256     foreach(QENUMITEM* iqenum, iclassqenumlist){
       
  1257         bool found = false;
       
  1258         QStringList missingimplinclasses;
       
  1259         ClassSpecifierAST* clspec = 0;
       
  1260         QString classname = "";
       
  1261         foreach(QENUMITEM* qenum, classqenumlist){
       
  1262             if(clspec != qenum->highestlevelclass->classspec){
       
  1263                 clspec = qenum->highestlevelclass->classspec;
       
  1264                 //get the classname
       
  1265                 unsigned int firsttoken = clspec->name->firstToken();
       
  1266                 classname += qenum->trlUnit->spell(firsttoken);
       
  1267                 if(missingimplinclasses.indexOf(classname) < 0)
       
  1268                     missingimplinclasses.push_back(classname);
       
  1269             }
       
  1270             if(qenum->isEqualTo(iqenum)){
       
  1271                 found = true;
       
  1272                 missingimplinclasses.clear();
       
  1273                 Trace("- Enum: " + classname + "::" + qenum->trlUnit->spell(qenum->ast->firstToken()) + " found");
       
  1274                 break;
       
  1275             }
       
  1276         }
       
  1277         if(!found){
       
  1278             iqenum->classWichIsNotFound.append(missingimplinclasses);
       
  1279             ret.push_back(iqenum);
       
  1280             QString classname = iqenum->trlUnit->spell(iqenum->highestlevelclass->classspec->name->firstToken());
       
  1281             Trace("- Enum: " + classname + "::" + iqenum->trlUnit->spell(iqenum->ast->firstToken()) + " not found!");
       
  1282         }
       
  1283     }
       
  1284     return ret;
       
  1285 }
       
  1286 
       
  1287 /************************************
       
  1288 Function that gives back an error 
       
  1289 string for a Q_ENUMS mismatch.
       
  1290 ************************************/
       
  1291 QStringList ParseManager::getErrorMessage(QENUMITEM* qenum)
       
  1292 {
       
  1293     QStringList ret;
       
  1294 
       
  1295     if(!qenum->foundallenums)
       
  1296     {
       
  1297         QString tmp;
       
  1298         QTextStream out(&tmp);
       
  1299 
       
  1300         unsigned int firsttoken = qenum->highestlevelclass->classspec->name->firstToken();
       
  1301         unsigned int lasttoken = qenum->highestlevelclass->classspec->name->lastToken();
       
  1302         for(unsigned int i = firsttoken; i < lasttoken; i++){
       
  1303             out << qenum->trlUnit->spell(i);
       
  1304         }
       
  1305         out << "::Q_ENUMS ( ";
       
  1306         firsttoken = qenum->ast->firstToken();
       
  1307         lasttoken = qenum->ast->lastToken();
       
  1308         for(unsigned int i = firsttoken; i < lasttoken; i++)
       
  1309             out << qenum->trlUnit->spell(i) << " ";
       
  1310         out << ")";
       
  1311         out << endl << " - one or more Enums missing." << endl;
       
  1312         ret << tmp;
       
  1313     }
       
  1314 
       
  1315     for(int i = 0; i < qenum->classWichIsNotFound.size(); i++){
       
  1316         QString tmp;
       
  1317         QTextStream out(&tmp);
       
  1318 
       
  1319         out << qenum->classWichIsNotFound[i] << "::Q_ENUMS ( ";
       
  1320 
       
  1321         unsigned int firsttoken = qenum->ast->firstToken();
       
  1322         unsigned int lasttoken = qenum->ast->lastToken();
       
  1323         for(unsigned int i = firsttoken; i < lasttoken; i++)
       
  1324             out << qenum->trlUnit->spell(i) << " ";
       
  1325         out << ")";
       
  1326         ret << tmp;
       
  1327     }
       
  1328     return ret;
       
  1329 }
       
  1330 //--->
       
  1331 
       
  1332 //<------------------------------------------------------- Start of Q_FLAGS checks
       
  1333 /***********************************
       
  1334 Function that checks all flags
       
  1335 which will occur in the MetaData
       
  1336 ***********************************/
       
  1337 QList<QFLAGITEM*> ParseManager::checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
       
  1338                                             , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
       
  1339                                             , const QList<QList<ENUMITEM*> > &classenumlist
       
  1340                                             , const QList<QList<QFLAGITEM*> > &iclassqflaglist
       
  1341                                             , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
       
  1342                                             , const QList<QList<ENUMITEM*> > &iclassenumlist)
       
  1343 {
       
  1344     QList<QFLAGITEM*> missingqflags;
       
  1345     //assign the enums to the flags
       
  1346     foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){
       
  1347         foreach(QFLAGITEM* qflag, qflaglist){
       
  1348             assignFlagValues(qflag, classqdeclareflaglist, classenumlist);
       
  1349         }
       
  1350     }
       
  1351     foreach(QList<QFLAGITEM*>qflaglist, iclassqflaglist){
       
  1352         foreach(QFLAGITEM* qflag, qflaglist){
       
  1353             assignFlagValues(qflag, iclassqdeclareflaglist, iclassenumlist);
       
  1354         }
       
  1355     }
       
  1356 
       
  1357     //Compare each qenum from interface with qenum from header (incl. baseclass functions)
       
  1358     QList<QFLAGITEM*> iqflags;
       
  1359     foreach(QList<QFLAGITEM*>iqflaglist, iclassqflaglist){
       
  1360         iqflags.clear();
       
  1361         //check if one header class contains all function from one interface header class
       
  1362         if(classqflaglist.count() >0){
       
  1363             foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){
       
  1364                 QList<QFLAGITEM*> tmpl = containsAllFlags(qflaglist, iqflaglist);
       
  1365                 if(tmpl.size() == 0)
       
  1366                     iqflags.clear();
       
  1367                 else
       
  1368                     iqflags.append(tmpl);
       
  1369 
       
  1370             }
       
  1371         }
       
  1372         else {
       
  1373             foreach(QFLAGITEM *pflag, iqflaglist){
       
  1374                 pflag->classWichIsNotFound << "<all classes>";
       
  1375                 QString name= pflag->trlUnit->spell(pflag->ast->firstToken());
       
  1376                 Trace("- Flag: <all classes>::" + name + " not found!");
       
  1377             }
       
  1378             iqflags.append(iqflaglist);
       
  1379         }
       
  1380         missingqflags.append(iqflags);
       
  1381     }
       
  1382     return missingqflags;
       
  1383 }
       
  1384 
       
  1385 /**************************************
       
  1386 Function that resolves the dependensies
       
  1387 between Q_FLAG, Q_DECLARE_FLAGS
       
  1388 and enums.
       
  1389 ***************************************/
       
  1390 void ParseManager::assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist)
       
  1391 {
       
  1392     QString qflagname;
       
  1393     QString enumname;
       
  1394     //read the flag names
       
  1395     EnumeratorAST *pflags = qflags->ast->asEnumerator();
       
  1396     if(pflags){
       
  1397         qflagname = qflags->trlUnit->spell(pflags->firstToken());
       
  1398         enumname = qflagname;
       
  1399         //try to find if there is a deflare flag macro with the same name as in qflagname
       
  1400         bool found = false;
       
  1401         foreach(QList<QDECLAREFLAGSITEM*> qdeclarelist, qdeclareflagslookuplist){
       
  1402             foreach(QDECLAREFLAGSITEM* qdeclare, qdeclarelist){
       
  1403                 QString declarename = qdeclare->trlUnit->spell(qdeclare->ast->flag_token);
       
  1404                 if(declarename == qflagname){
       
  1405                     //now map the right enum name to the flag
       
  1406                     enumname = qdeclare->trlUnit->spell(qdeclare->ast->enum_token);
       
  1407                     found = true;
       
  1408                     break;
       
  1409                 }
       
  1410             }
       
  1411             if(found)
       
  1412                 break;
       
  1413         }
       
  1414         //now we have the right enum name now we need to find the enum
       
  1415         found = false;
       
  1416         foreach(QList<ENUMITEM*> enumitemlist, enumlookuplist){
       
  1417             foreach(ENUMITEM* enumitem, enumitemlist){
       
  1418                 EnumSpecifierAST *penumspec = enumitem->ast;
       
  1419                 QString enumspecname = enumitem->trlUnit->spell(penumspec->name->firstToken());
       
  1420                 if(enumspecname == enumname){
       
  1421                     qflags->enumvalues << getEnumValueStringList(enumitem, qflagname);
       
  1422                     found = true;
       
  1423                     break;
       
  1424                 }
       
  1425             }
       
  1426             if(found)
       
  1427                 break;
       
  1428         }
       
  1429         if(!found)
       
  1430             qflags->foundallenums = false;
       
  1431     }
       
  1432 }
       
  1433 
       
  1434 /*****************************************
       
  1435 Function that compares if all enums
       
  1436 and flags assigned by using the Q_FLAGS
       
  1437 are complete defined.
       
  1438 *****************************************/
       
  1439 QList<QFLAGITEM*> ParseManager::containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist)
       
  1440 {
       
  1441     QList<QFLAGITEM*> ret;
       
  1442     foreach(QFLAGITEM* iqflags, iclassqflaglist){
       
  1443         if(iqflags->foundallenums){
       
  1444             bool found = false;
       
  1445             QStringList missingimplinclasses;
       
  1446             ClassSpecifierAST* clspec = 0;
       
  1447             QString classname = "";
       
  1448             foreach(QFLAGITEM* qflags, classqflaglist){
       
  1449                 if(clspec != qflags->highestlevelclass->classspec){
       
  1450                     clspec = qflags->highestlevelclass->classspec;
       
  1451                     //get the classname
       
  1452                     unsigned int firsttoken = clspec->name->firstToken();
       
  1453                     classname += qflags->trlUnit->spell(firsttoken);
       
  1454                     if(missingimplinclasses.indexOf(classname) < 0)
       
  1455                         missingimplinclasses.push_back(classname);
       
  1456                 }
       
  1457                 if(qflags->isEqualTo(iqflags)){
       
  1458                     found = true;
       
  1459                     missingimplinclasses.clear();
       
  1460                     Trace("- Flag: " + classname + "::" + qflags->trlUnit->spell(qflags->ast->firstToken()) + " found");
       
  1461                     break;
       
  1462                 }
       
  1463             }
       
  1464             if(!found){
       
  1465                 iqflags->classWichIsNotFound.append(missingimplinclasses);
       
  1466                 ret.push_back(iqflags);
       
  1467                 QString classname = iqflags->trlUnit->spell(iqflags->highestlevelclass->classspec->name->firstToken());
       
  1468                 Trace("- Flag: " + classname + "::" + iqflags->trlUnit->spell(iqflags->ast->firstToken()) + " not found!");
       
  1469             }
       
  1470         }
       
  1471         else
       
  1472             ret.push_back(iqflags);
       
  1473     }
       
  1474     return ret;
       
  1475 }
       
  1476 
       
  1477 /************************************
       
  1478 Function that gives back an error 
       
  1479 string for a Q_FLAGS mismatch.
       
  1480 ************************************/
       
  1481 QStringList ParseManager::getErrorMessage(QFLAGITEM* pfg)
       
  1482 {
       
  1483     QStringList ret;
       
  1484 
       
  1485     if(!pfg->foundallenums)
       
  1486     {
       
  1487         QString tmp;
       
  1488         QTextStream out(&tmp);
       
  1489 
       
  1490         unsigned int firsttoken = pfg->highestlevelclass->classspec->name->firstToken();
       
  1491         unsigned int lasttoken = pfg->highestlevelclass->classspec->name->lastToken();
       
  1492         for(unsigned int i = firsttoken; i < lasttoken; i++){
       
  1493             out << pfg->trlUnit->spell(i);
       
  1494         }
       
  1495         out << "::Q_FLAGS ( ";
       
  1496         firsttoken = pfg->ast->firstToken();
       
  1497         lasttoken = pfg->ast->lastToken();
       
  1498         for(unsigned int i = firsttoken; i < lasttoken; i++)
       
  1499             out << pfg->trlUnit->spell(i) << " ";
       
  1500         out << ")";
       
  1501         out << endl << " - one or more Enums missing." << endl;
       
  1502         ret << tmp;
       
  1503     }
       
  1504     for(int i = 0; i < pfg->classWichIsNotFound.size(); i++){
       
  1505         QString tmp;
       
  1506         QTextStream out(&tmp);
       
  1507 
       
  1508         out << pfg->classWichIsNotFound[i] << "::Q_FLAGS ( ";
       
  1509 
       
  1510         unsigned int firsttoken = pfg->ast->firstToken();
       
  1511         unsigned int lasttoken = pfg->ast->lastToken();
       
  1512         for(unsigned int i = firsttoken; i < lasttoken; i++)
       
  1513             out << pfg->trlUnit->spell(i) << " ";
       
  1514         out << ")";
       
  1515         ret << tmp;
       
  1516     }
       
  1517     return ret;
       
  1518 }
       
  1519 
       
  1520 inline QString ParseManager::getTraceFuntionString(const FUNCTIONITEM *fctitem, const QString& classname)
       
  1521 {
       
  1522     QString ret;
       
  1523 
       
  1524     if(fctitem->function->isPublic())
       
  1525         ret = "public ";
       
  1526     if(fctitem->function->isProtected())
       
  1527         ret = "protected ";
       
  1528     if(fctitem->function->isPrivate())
       
  1529         ret = "private ";
       
  1530 
       
  1531     if(fctitem->function->isVirtual())
       
  1532         ret += "virtual ";
       
  1533     if(fctitem->function->isPureVirtual())
       
  1534         ret += "pure virtual ";
       
  1535 
       
  1536     if(fctitem->function->isSignal())
       
  1537         ret += "Signal ";
       
  1538     if(fctitem->function->isSlot())
       
  1539         ret += "Slot ";
       
  1540     if(fctitem->function->isNormal())
       
  1541         ret += "Normal ";
       
  1542     if(fctitem->function->isInvokable())
       
  1543         ret += "Invokable ";
       
  1544 
       
  1545     ret += classname;
       
  1546     ret += "::";
       
  1547     ret += fctitem->trlUnit->spell(fctitem->function->sourceLocation());
       
  1548     return ret;
       
  1549 }
       
  1550 
       
  1551 void ParseManager::Trace(QString value)
       
  1552 {
       
  1553     if(::m_resultFile){
       
  1554         QTextStream out(::m_resultFile);
       
  1555         if(value == "\n")
       
  1556             out << endl;
       
  1557         else
       
  1558             out << value << endl;
       
  1559     }
       
  1560 }
       
  1561 //--->