Orb/Doxygen/src/vhdlscanner.l
changeset 3 d8fccb2cd802
parent 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
2:932c358ece3e 3:d8fccb2cd802
       
     1 /******************************************************************************
       
     2  *
       
     3  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     4  *
       
     5  * Permission to use, copy, modify, and distribute this software and its
       
     6  * documentation under the terms of the GNU General Public License is hereby 
       
     7  * granted. No representations are made about the suitability of this software 
       
     8  * for any purpose. It is provided "as is" without express or implied warranty.
       
     9  * See the GNU General Public License for more details.
       
    10  *
       
    11  * Documents produced by Doxygen are derivative works derived from the
       
    12  * input used in their production; they are not affected by this license.
       
    13  *
       
    14  */
       
    15 /******************************************************************************
       
    16  * Parser for VHDL subset
       
    17  * written by M. Kreis
       
    18  * supports VHDL-87/93
       
    19  * does not support VHDL-AMS 
       
    20  ******************************************************************************/
       
    21 %{
       
    22 
       
    23 // global includes
       
    24 #include <stdio.h>
       
    25 #include <stdlib.h>
       
    26 #include <assert.h>
       
    27 #include <string.h>
       
    28 #include <qcstring.h>
       
    29 #include <qfileinfo.h>
       
    30 #include <qstringlist.h>
       
    31 
       
    32 /* --------------------------------------------------------------- */
       
    33 
       
    34 // local includes
       
    35 #include "vhdlscanner.h"
       
    36 #include "vhdlcode.h"
       
    37 #include "vhdldocgen.h"
       
    38 #include "message.h"
       
    39 #include "config.h"
       
    40 #include "doxygen.h"
       
    41 #include "util.h"
       
    42 #include "language.h"
       
    43 #include "commentscan.h"
       
    44 #include "index.h"
       
    45 #include "definition.h"
       
    46 #include "searchindex.h"
       
    47 #include "outputlist.h"
       
    48 
       
    49 /* --------------------------------------------------------------- */
       
    50 
       
    51 //#define theTranslator_vhdlType theTranslator->trVhdlType
       
    52 #define theTranslator_vhdlType VhdlDocGen::getVhdlType
       
    53 
       
    54 static QStringList      qrl;
       
    55 static int              openGroups;
       
    56 static ParserInterface *g_thisParser;
       
    57 static const char *     inputString;
       
    58 static int              inputPosition;
       
    59 static int              startComment  = 0;
       
    60 static QFile            inputFile;
       
    61 static QCString         inbuf;
       
    62 static Entry*           global_root   = 0;
       
    63 static Entry*           current_root  = 0;
       
    64 static Entry*           current       = 0;
       
    65 static Entry*           previous      = 0;
       
    66 static Entry*           functionEntry = 0;
       
    67 static Entry*           lastEntity    = 0;
       
    68 static Entry*           lastCompound  = 0;
       
    69 static int              genPort       = 0;
       
    70 static QCString         yyFileName;
       
    71 static int              iFuncLine     = 1;
       
    72 static bool             g_inputFromFile ;
       
    73 static bool             g_lexInit     = FALSE;
       
    74 static int              isBody=0;
       
    75 static int              isFunc=0;
       
    76 static int              yyLineNr      = 1;
       
    77 static char *           g_buf         = 0;
       
    78 static uint             g_bufSize     = 0;
       
    79 static int              iTextCounter  = 0;
       
    80 static int              iCounter      = 0;
       
    81 static int              bropen        = 0;
       
    82 static int              scantype      = 0;
       
    83 static int              g_lastCommentContext = 0;
       
    84 static bool             docBlockAutoBrief;
       
    85 static char             docBlockTerm;
       
    86 static int              iDocLine      = -1;
       
    87 
       
    88 //#define YY_A_INTERACTIVE 1
       
    89 #define YY_NEVER_INTERACTIVE 1
       
    90 //-----------------------------------------------------------------------------
       
    91 
       
    92 static void parserInit();
       
    93 static void deleteSpecChars(char* str,char *buf);
       
    94 static void handleCommentBlock(const QCString &doc,bool brief);
       
    95 static void newEntry();
       
    96 static void initEntry(Entry *e);
       
    97 
       
    98 static void addSubEntry(Entry* root, Entry* e)
       
    99 {
       
   100   if (e==0 || root==0) return;
       
   101   //if (isPrevDoc) 
       
   102   //{
       
   103   //  e->brief=prevDocEntry.brief;
       
   104   //  e->briefLine=prevDocEntry.briefLine;
       
   105   //  prevDocEntry.reset();
       
   106   //  isPrevDoc=FALSE;
       
   107   //}
       
   108   root->addSubEntry(e);
       
   109 } 
       
   110 
       
   111 static void bufferClear()
       
   112 {
       
   113   int j;
       
   114   for (j=0;j<iCounter+1;j++)
       
   115   {
       
   116     g_buf[j]=0;
       
   117   }
       
   118 
       
   119   iCounter=0;
       
   120 }
       
   121 
       
   122 static void  addText (char *word, int llen)
       
   123 {
       
   124   if ((uint)(iCounter + llen) > g_bufSize)
       
   125   {
       
   126     char *pTmp = (char*)realloc(g_buf,iCounter+llen+2048);
       
   127     if (pTmp)
       
   128     {
       
   129       g_buf = pTmp;
       
   130     }
       
   131     else
       
   132     {
       
   133       fprintf(stderr,"\n not enough memory for realloc\n");
       
   134       return; 
       
   135     }
       
   136   }
       
   137   while (llen>0)
       
   138   {
       
   139     g_buf[iCounter]=*word++;
       
   140     iCounter++;
       
   141     llen--;
       
   142   }    
       
   143   g_buf[iCounter]='\0'; 
       
   144 } 
       
   145 
       
   146 static void getBufText(QCString& qc,int start)
       
   147 {
       
   148   while (start < iCounter)
       
   149   {
       
   150     qc+=(g_buf[start]);
       
   151     start++;
       
   152   }
       
   153 }
       
   154 
       
   155 static void lineCount()
       
   156 {
       
   157   for ( const char* c = yytext ; *c ; ++c )
       
   158   {
       
   159     yyLineNr += (*c == '\n') ;
       
   160   }
       
   161 }
       
   162 
       
   163 static void deleteSpecChars(char* str,char *buf)
       
   164 {
       
   165   while (*str)
       
   166   {
       
   167     if ((*str == '\t') || (*str == '\n') || (*str == '\r') || (*str == ' ')) 
       
   168     {
       
   169       *str++;
       
   170     }
       
   171     else
       
   172     {
       
   173       *buf++ = *str++;
       
   174     }
       
   175   }
       
   176   *buf='\0';
       
   177 }
       
   178 
       
   179 void getType(Entry* p,char* text)
       
   180 {
       
   181   QCString name(text);
       
   182   name=name.stripWhiteSpace();           
       
   183   if (stricmp(name.data(),"signal" )==0)
       
   184   {
       
   185     p->spec=VhdlDocGen::SIGNAL;
       
   186   }
       
   187   else if (stricmp(name.data(),"type" )==0)
       
   188   {
       
   189     p->spec=VhdlDocGen::TYPE; 
       
   190   }
       
   191   else if (stricmp(name.data(),"subtype" )==0)
       
   192   {
       
   193     p->spec=VhdlDocGen::SUBTYPE;   
       
   194   }
       
   195   else if (stricmp(name.data(),"constant" )==0)
       
   196   {
       
   197     p->spec=VhdlDocGen::CONSTANT;    
       
   198   }
       
   199   else if (stricmp(name.data(),"attribute" )==0)
       
   200   {
       
   201     p->spec=VhdlDocGen::ATTRIBUTE;
       
   202   }
       
   203   else if (stricmp(name.data(),"function" )==0)
       
   204   {
       
   205     p->spec=VhdlDocGen::FUNCTION;    
       
   206   }
       
   207   else if (stricmp(name.data(),"procedure" )==0)
       
   208   {
       
   209     p->spec=VhdlDocGen::PROCEDURE;
       
   210   }
       
   211   else if (stricmp(name.data(),"units" )==0)
       
   212   {
       
   213     p->spec=VhdlDocGen::UNITS;
       
   214   }
       
   215   else if (name.contains("shared",false) && name.contains("variable",false))
       
   216   {
       
   217     p->spec=VhdlDocGen::SHAREDVARIABLE;
       
   218   }
       
   219   else if (stricmp(name.data(),"file" )==0) 
       
   220   {
       
   221     p->spec=VhdlDocGen::VFILE;
       
   222   }
       
   223   else if (stricmp(name.data(),"group" )==0) 
       
   224   {
       
   225     p->spec=VhdlDocGen::GROUP; 
       
   226   }
       
   227   else if (stricmp(name.data(),"alias" )==0) 
       
   228   {
       
   229     p->spec=VhdlDocGen::ALIAS; 
       
   230   }
       
   231   else 
       
   232   {
       
   233     err("wrong type");
       
   234   }
       
   235   p->section=Entry::VARIABLE_SEC;
       
   236 }
       
   237 
       
   238 //-------------------------------------------------------------------------
       
   239 
       
   240 /*
       
   241  * adds signals found in entities|records|units
       
   242  */
       
   243 
       
   244 void addSignals(const char* str,int line, Entry *e,const char *comment=0)
       
   245 {
       
   246   //printf("===> addSignals (%s) comment='%s'\n",str,comment);
       
   247   QList<QCString> ql;
       
   248   QCString bufio;
       
   249   ql.setAutoDelete(TRUE);
       
   250 
       
   251   VhdlDocGen::getSigName(ql,str,bufio);
       
   252   int count = ql.count();
       
   253 
       
   254   QCString brief  = current->brief;
       
   255   QCString doc    = current->doc;
       
   256   Entry *tmpEntry = current;
       
   257   current = new Entry;
       
   258   initEntry(current);
       
   259   handleCommentBlock(comment,TRUE);
       
   260   if (!current->brief.isEmpty())
       
   261   {
       
   262     if (doc.isEmpty())
       
   263     {
       
   264       doc = brief;
       
   265     }
       
   266     else if (!brief.isEmpty())
       
   267     {
       
   268       doc = brief + "<p>" + doc;
       
   269     }
       
   270     brief = current->brief;
       
   271   }
       
   272   delete current;
       
   273   current = tmpEntry;
       
   274   current->brief.resize(0);
       
   275   current->doc.resize(0);
       
   276  
       
   277   if (genPort!=3) // not a unit
       
   278   {
       
   279     for (int k=1;k<count;k++)
       
   280     {
       
   281       //printf("adding '%s' '%s'\n",ql.at(0)->data(),ql.at(k)->data());
       
   282       Entry *pTemp=new Entry;
       
   283       initEntry(pTemp);
       
   284       pTemp->startLine = line;
       
   285       pTemp->bodyLine  = line;
       
   286       pTemp->name      = ql.at(k)->data();
       
   287       pTemp->section   = Entry::VARIABLE_SEC;
       
   288       pTemp->brief     = brief;
       
   289       pTemp->doc       = doc;
       
   290       pTemp->mGrpId    = current->mGrpId; // copy member group id
       
   291       QCString stSpec  = ql.at(0)->data();
       
   292       if (genPort==1) // found port
       
   293       {
       
   294 	pTemp->spec    = VhdlDocGen::PORT;
       
   295 	stSpec.stripPrefix(bufio.data()); 
       
   296 	stSpec=stSpec.stripWhiteSpace();
       
   297 	pTemp->args    = stSpec;
       
   298 	pTemp->type    = bufio;
       
   299 	addSubEntry(e,pTemp);
       
   300       }
       
   301       else if (genPort==2) // found record
       
   302       {
       
   303 	pTemp->spec    = VhdlDocGen::RECORD;
       
   304 	pTemp->type    = stSpec;
       
   305 	pTemp->name.prepend(VhdlDocGen::getRecordNumber());
       
   306 	delete current;
       
   307 	current = new Entry(*pTemp); // make a deep copy of pTemp
       
   308 	newEntry();                  // add it to lastCompound and make a new current
       
   309 	delete pTemp;
       
   310       }
       
   311       else 
       
   312       {
       
   313 	pTemp->spec    = VhdlDocGen::GENERIC;
       
   314 	pTemp->type    = stSpec;
       
   315 	addSubEntry(e,pTemp);
       
   316       }
       
   317     }// for
       
   318   }
       
   319   else // found a unit 
       
   320   {
       
   321     Entry *pTemp=new Entry;
       
   322     initEntry(pTemp);
       
   323     QCString tt(str);
       
   324     QStringList ql=QStringList::split("=",tt,FALSE);
       
   325     pTemp->spec      = VhdlDocGen::UNITS;
       
   326     pTemp->section   = Entry::VARIABLE_SEC;
       
   327     pTemp->startLine = line;
       
   328     pTemp->bodyLine  = line;
       
   329     pTemp->brief     = brief; // adds brief description to the unit member
       
   330     pTemp->doc       = doc;   // adds doc to the unit member
       
   331     pTemp->type      = ql[1];
       
   332     pTemp->name      = ql[0].stripWhiteSpace();
       
   333     pTemp->name.prepend(VhdlDocGen::getRecordNumber());
       
   334     delete current;
       
   335     current = new Entry(*pTemp); // make a deep copy
       
   336     newEntry();                  // add it to lastCompound
       
   337     delete pTemp;
       
   338   }
       
   339 }                                              
       
   340 
       
   341 /*
       
   342  * this function parses a process prototype
       
   343  * and adds the signal to the process
       
   344  */
       
   345 
       
   346 static void parseProcessProto()
       
   347 {
       
   348   QStringList ql;
       
   349   QCString qcs;
       
   350   bool sem=FALSE;
       
   351   //Entry* ppEntry=new Entry;
       
   352   //ppEntry->fileName=yyFileName;
       
   353   //processEntry=ppEntry;
       
   354   QCString name; 
       
   355   scantype=0;
       
   356   getBufText(qcs,0);
       
   357   if (qcs.contains('(') != qcs.contains(')')) return; 
       
   358   VhdlDocGen::deleteAllChars(qcs,'\n');
       
   359   VhdlDocGen::parseProcessProto(qcs,name,ql);
       
   360   current->section=Entry::FUNCTION_SEC;
       
   361   //current->stat=TRUE;
       
   362   current->spec=VhdlDocGen::PROCESS;
       
   363   current->startLine=iFuncLine;
       
   364   current->bodyLine=iFuncLine;
       
   365   current->fileName=yyFileName;
       
   366   if (!name.isEmpty())
       
   367   {
       
   368     current->name=name.stripWhiteSpace();
       
   369   }
       
   370   else // found an anonymous process, so we add a generated name  
       
   371   {
       
   372     current->name=VhdlDocGen::getProcessNumber(); 
       
   373   }
       
   374 
       
   375   current->args+=" ( "; 
       
   376   if (!ql.isEmpty())
       
   377   {
       
   378     QValueList<QString>::Iterator iter = ql.begin();
       
   379     for ( ; iter != ql.end(); ++iter)
       
   380     {
       
   381       if (sem)
       
   382       {
       
   383         current->args+=',';
       
   384       }
       
   385       Argument *arg=new Argument;
       
   386       arg->name=((QCString)*iter).stripWhiteSpace();    
       
   387       current->argList->append(arg);
       
   388       current->args+=(QCString)*iter; 
       
   389       sem = TRUE;
       
   390     }    
       
   391   }
       
   392   current->args+=" ) ";
       
   393   bufferClear();
       
   394 }//parseProcessProto
       
   395 
       
   396 
       
   397 /*
       
   398  * parses a function|procedure protoype
       
   399  */
       
   400 
       
   401 static void parseFunctionProto()
       
   402 {
       
   403   QCString name,ret,qcs,temp;
       
   404   bool sem=FALSE;
       
   405   QList<Argument> ql;
       
   406   ql.setAutoDelete(TRUE);
       
   407   getBufText(qcs,0);
       
   408   if (qcs.contains('(') != qcs.contains(')')) 
       
   409     return; // function without a prototype 
       
   410   if (qcs.contains("function",FALSE)==0 && qcs.contains("procedure",FALSE)==0) 
       
   411     return; 
       
   412   qcs=qcs.stripWhiteSpace();
       
   413   temp=qcs.lower();
       
   414   if (temp.stripPrefix("impure"))
       
   415   {
       
   416     current->exception="impure";
       
   417     qcs=qcs.remove(0,6);
       
   418   }
       
   419   else if (temp.stripPrefix("pure")) 
       
   420   {
       
   421     current->exception="pure";
       
   422     qcs=qcs.remove(0,4);
       
   423   }
       
   424 
       
   425   VhdlDocGen::parseFuncProto(qcs.data(),ql,name,ret); 
       
   426   //printf("parseFuncProto(%s)=%s,%s\n",qcs.data(),name.data(),ret.data());
       
   427   VhdlDocGen::deleteAllChars(name,';');
       
   428   current->name=name;
       
   429   current->startLine=iFuncLine;
       
   430   current->bodyLine=iFuncLine;
       
   431 
       
   432   int count = ql.count(); 
       
   433 
       
   434   current->args+" ( "; 
       
   435   for (int k=0;k<count;k++)
       
   436   {
       
   437     if (sem)
       
   438     {
       
   439       current->args+=",";
       
   440     }
       
   441     Argument *arg=new Argument;
       
   442     Argument *hh=(Argument*)ql.at(k);
       
   443     arg->name=hh->name;
       
   444     arg->type=hh->type;
       
   445     arg->defval=hh->defval;
       
   446     arg->attrib=hh->attrib;
       
   447     current->argList->append(arg);
       
   448     current->args+=hh->name;
       
   449     sem=TRUE;
       
   450   }
       
   451   current->args+" )";
       
   452 
       
   453   if (!ret.isEmpty()) 
       
   454     current->spec=VhdlDocGen::FUNCTION;
       
   455   else
       
   456     current->spec=VhdlDocGen::PROCEDURE;
       
   457 
       
   458   current->section=Entry::FUNCTION_SEC;
       
   459   current->type=ret;
       
   460   //addSubEntry(ee,ppEntry); 
       
   461   if (lastCompound)
       
   462   {
       
   463     lastCompound->addSubEntry(current);
       
   464     current = new Entry;
       
   465     initEntry(current);
       
   466   }
       
   467   else
       
   468   {
       
   469     newEntry();
       
   470   }
       
   471   bufferClear();
       
   472 }//parseFunctionProto
       
   473 
       
   474 static Entry* getEntryAtLine(const Entry* ce,int line)
       
   475 {
       
   476   EntryListIterator eli(*ce->children());
       
   477   Entry *found=0;
       
   478   Entry *rt;
       
   479   for (;(rt=eli.current());++eli)
       
   480   {
       
   481     if (rt->bodyLine==line)
       
   482     {
       
   483       found=rt;
       
   484     } // if
       
   485     if (!found) 
       
   486     {
       
   487       found=getEntryAtLine(rt,line);
       
   488     }
       
   489   }
       
   490   return found;
       
   491 }// getEntryAtLine
       
   492 
       
   493 //-------------------------------------------------------------------------
       
   494 
       
   495 
       
   496 void parserInit()
       
   497 {
       
   498   iCounter=0; 
       
   499   iTextCounter=0;
       
   500   yyLineNr=1;
       
   501   current=0;
       
   502   previous=0;
       
   503   isFunc=0;
       
   504   isBody=0;
       
   505   scantype=0;
       
   506   //pEntry=0;
       
   507   //pp=0; 
       
   508   lastCompound=0;
       
   509   lastEntity=0;
       
   510   bropen=0;
       
   511   openGroups=0;
       
   512   iDocLine=-1;
       
   513   //isPrevDoc=FALSE;
       
   514   //prevDocEntry.reset();
       
   515   qrl.clear();
       
   516 
       
   517   if (!g_lexInit) 
       
   518   {
       
   519     VhdlDocGen::init();
       
   520   }
       
   521 
       
   522   g_bufSize=inputFile.size()+1024;
       
   523   if (g_buf==0) free(g_buf);
       
   524   g_buf=(char*)(calloc(g_bufSize,sizeof(char)));
       
   525 
       
   526   if (g_buf==0)
       
   527   {
       
   528     fprintf(stderr,"\n not enough memory");
       
   529     return;
       
   530   }
       
   531   g_buf[g_bufSize-1]='\0';
       
   532 }
       
   533 
       
   534 bool VHDLLanguageScanner::needsPreprocessing(const QCString &)
       
   535 {
       
   536   return FALSE;
       
   537 }
       
   538 
       
   539 
       
   540 void VHDLLanguageScanner::resetCodeParserState()
       
   541 {
       
   542 
       
   543 }
       
   544 
       
   545 #undef    YY_INPUT
       
   546 #define    YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
       
   547 
       
   548 static int yyread(char *buf,int max_size)
       
   549 {
       
   550   int c=0;
       
   551   if (g_inputFromFile)
       
   552   {
       
   553     c = inputFile.readBlock(buf,max_size);
       
   554     if (c==-1) yy_fatal_error("input in flex scanner failed");
       
   555   }
       
   556   else
       
   557   {
       
   558     while ( c < max_size && inputString[inputPosition] )
       
   559     {
       
   560       *buf = inputString[inputPosition++] ;
       
   561       c++; buf++;
       
   562     }
       
   563   }
       
   564   return c;
       
   565 }
       
   566 
       
   567 #if 0
       
   568 /*
       
   569  * adds a  text line description [--#] to the the previous type  
       
   570  */
       
   571 
       
   572 static void addOneTextLine(QCString& ss )
       
   573 {
       
   574   Entry* pTemp=0;
       
   575   if (current && current->bodyLine==yyLineNr)
       
   576     pTemp=current;
       
   577   //else if (pEntry && pEntry->bodyLine==yyLineNr)
       
   578   //  pTemp=pEntry;
       
   579   else 
       
   580     pTemp=getEntryAtLine(current_root,yyLineNr) ;
       
   581 
       
   582   if (pTemp)
       
   583   {
       
   584     ss=ss.stripWhiteSpace();
       
   585     ss.stripPrefix("--!");
       
   586     pTemp->brief=ss;
       
   587     pTemp->briefLine=yyLineNr;
       
   588   }        
       
   589 }
       
   590 #endif
       
   591 
       
   592 %}
       
   593 
       
   594 
       
   595   /* start command character */
       
   596   /* -------------- VHDL SECTION -----------------------------------*/
       
   597 
       
   598 B                       [ \t]
       
   599 CR                      [\r\n]
       
   600 BR                      [ \t\n\r]
       
   601 DIGIT                   [0-9]
       
   602 LOWER_CASE_LETTER       [a-z]
       
   603 UPPER_CASE_LETTER       [A-Z]
       
   604 LETTER                  [a-zA-Z_0-9]
       
   605 SPACE_CHARACTER         [ \t]
       
   606 SPECIAL_CHARACTER       [#&'()*+,\-\./:;<=>_|]
       
   607 OTHER_SPECIAL_CHARACTER [~!$§%?@\[\\\]^{}]
       
   608 BASIC_GRAPHIC_CHARACTER {UPPER_CASE_LETTER}|{DIGIT}|{SPECIAL_CHARACTER}|{SPACE_CHARACTER}
       
   609 GRAPHIC_CHARACTER       {BASIC_GRAPHIC_CHARACTER}|{LOWER_CASE_LETTER}|{OTHER_SPECIAL_CHARACTER}
       
   610 EXTENDED_CHARACTER      [\\]{GRAPHIC_CHARACTER}*[\\] 
       
   611 
       
   612 NAME                    ({LETTER}[a-zA-Z0-9_.]*)|{EXTENDED_CHARACTER}
       
   613 STRING_LITERAL          \"{GRAPHIC_CHARACTER}*\"
       
   614 FUNCNAME                ([a-zA-Z"][*+\-_a-zA-Z0-9"\/=<>]*)|{EXTENDED_CHARACTER}
       
   615 DIGITS                  [0-9]+|[0-9]+"."[0-9]+|[0-9]+"#"[0-9_a-fA-F\+\.]+"#"
       
   616 COMMENT                 "--"[^\n]*
       
   617 LABELID                 [a-z_A-Z][^\;]*";"({B}*{COMMENT})*
       
   618 PROTO                   [ (]*
       
   619 TEXTT                   "--"[^\/\@\*\#][^\n]*
       
   620 PROC                    ("function"|"procedure")
       
   621 ENDE                    ({BR}*("end"){BR}*{PROC}*{BR}*[;]{1})
       
   622 ENDEFF                  ("if"|"case"|"loop"|"generate"){BR}*[;]
       
   623 ENDE3                   ({BR}*("end"){BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;])|{ENDE}
       
   624 ENDFUNC                 {B}*"end"{BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;]
       
   625 FUNCIMPURE              "impure"|"pure"
       
   626 FUNCPROC                ^{B}*{FUNCIMPURE}*{BR}*("function"|"procedure"){B}*
       
   627 ARCHITECTURE            ("architecture"){BR}+{NAME}{BR}*("of")
       
   628    /* Removed due to bug 538239
       
   629       POST         "postponed"
       
   630       PROCESS      ({BR}*{FUNCNAME}{B}*[:]{BR}*({POST}{BR}+)?("process"){BR}*{PROTO})|("process"){BR}*("("){BR}*{PROTO}|[^a-zA-Z]("process"){CR}|[^a-zA-Z]("process"){BR}+("is")
       
   631    */
       
   632 PROCESS                 ({B}*{FUNCNAME}{B}*:{BR}*)?({B}*("postponed"){BR}+)?{B}*("process"){BR}*{PROTO}
       
   633 
       
   634 ENDPROCESS              ("end"){BR}*("postponed")*("process"){BR}*{FUNCNAME}*{BR}*[;]
       
   635 LIBUSE                  ^{B}*("use"|"library"){BR}+
       
   636 ENTITY                  ^{B}*("component"|"entity"|"package"){BR}+
       
   637 PBODY                   ("package"){B}+("body"){BR}+{NAME}
       
   638 SHARED                  ("shared"){BR}+("variable")
       
   639 SIGTYPES                ^{B}*({SHARED}|"alias"|"file"|"group"|"subtype"|"type"|"constant"|"attribute"|"signal"|"units"){BR}+
       
   640 CONFIG                  ("configuration"){BR}+{NAME}{BR}*("of"){BR}+{NAME}{BR}+"is"
       
   641 
       
   642 ALLTYPESMAP             {B}*[_a-zA-ZA_Z0-9.() ]*{B}*
       
   643 MAPCOMPONENT            ({ALLTYPESMAP}{BR}*[:]{BR}*("component"|"configuration")*{ALLTYPESMAP}{BR}*{TEXTT}*{BR}*("port"|"generic"){BR}*("map"){BR}*("("){1})
       
   644 MAPCOMPONENT1           ({ALLTYPESMAP}{BR}*[:]{BR}*("entity"){BR}*{ALLTYPESMAP}{BR}*("port"|"generic"){BR}*("map"){BR}*("("){1})
       
   645 
       
   646 BRACEOPEN               [(]{1}
       
   647 BRACECLOSE              [)]{1}
       
   648 
       
   649 ALLID                   [^;()\t ]
       
   650 
       
   651 /* VHDL 2001 */
       
   652 ENDPROTECTED            ("end"{BR}+"protected"{BR}+{NAME}{BR}*";")|("end"{BR}+"protected"{BR}*";")
       
   653 ENDPROTECEDBODY         "end"{BR}+"protected"{BR}+"body"{BR}+{NAME}
       
   654 
       
   655 
       
   656 %option noyywrap
       
   657 
       
   658   /* language parsing states */
       
   659 
       
   660 %x Start
       
   661 %x Comment
       
   662 %x FindTypeName
       
   663 %x ParseType 
       
   664 %x ParseRecord
       
   665 %x ParseUnits
       
   666 %x ParseProcess
       
   667 %x ParseFunc
       
   668 %x FindName
       
   669 %x FindEntityName
       
   670 %x FindGenPort
       
   671 %x FindTypes
       
   672 %x FindSigName
       
   673 %x FindFuncName
       
   674 %x FindBegin
       
   675 
       
   676 %%
       
   677 
       
   678 <Start>{ENDPROTECTED}|{ENDPROTECEDBODY}  {
       
   679  lineCount();
       
   680 }
       
   681 
       
   682 
       
   683 
       
   684 <Start>{CONFIG} { // found configuration
       
   685  
       
   686   QCString qcs(vhdlscanYYtext);
       
   687   current->name=VhdlDocGen::getIndexWord(qcs,1);
       
   688   current->type=VhdlDocGen::getIndexWord(qcs,3);
       
   689   current->startLine=yyLineNr;
       
   690   current->bodyLine=yyLineNr;
       
   691   current->section=Entry::VARIABLE_SEC; 
       
   692   current->spec=VhdlDocGen::CONFIG;
       
   693   current->args="configuration";
       
   694   newEntry();
       
   695   BEGIN(Start);
       
   696 }
       
   697 
       
   698 <Start>{SIGTYPES}  { // found type constant|type|attribute and so on..
       
   699     bropen=0;
       
   700     lineCount();
       
   701 
       
   702     bufferClear();
       
   703     //pEntry=current;
       
   704     getType(current,yytext);
       
   705     current->bodyLine=yyLineNr;
       
   706     if (current->spec==VhdlDocGen::UNITS)
       
   707     {
       
   708       //addSubEntry(current,pEntry);
       
   709       current->startLine=yyLineNr;
       
   710       current->bodyLine=yyLineNr;
       
   711       newEntry(); // adds the unit to the lastCompound
       
   712       genPort=3;
       
   713       BEGIN(ParseRecord);
       
   714     }
       
   715     else    
       
   716     {
       
   717       BEGIN(FindTypeName);
       
   718     }
       
   719   }
       
   720 
       
   721 <Start>{ARCHITECTURE} {     //found architecure
       
   722   lineCount();
       
   723   bropen=0;
       
   724   bufferClear();
       
   725   isBody=0;
       
   726   lastCompound = current;
       
   727   QCString curName=VhdlDocGen::getIndexWord(yytext,1);
       
   728   current->section=Entry::CLASS_SEC; //Entry::CLASS_SEC;
       
   729   current->spec=VhdlDocGen::ARCHITECTURE;
       
   730   current->protection=Private;
       
   731   current->name=curName;
       
   732   current->fileName=yyFileName;
       
   733   current->startLine=yyLineNr;
       
   734   current->bodyLine=yyLineNr;      
       
   735   //printf("-> Architecture at line %d\n",yyLineNr);
       
   736   BEGIN(FindName);
       
   737 }
       
   738 
       
   739 
       
   740 <Start>{PROCESS} {          //found process
       
   741   lineCount();
       
   742   iFuncLine=yyLineNr;
       
   743   bropen=0;
       
   744   //printf("--> Process: line=%d\n",yyLineNr);
       
   745   bufferClear();
       
   746   addText(yytext,yyleng);
       
   747   QCString qcs(yytext);
       
   748   if (qcs.contains('('))
       
   749   {
       
   750     bropen=1;
       
   751     scantype=2;
       
   752     BEGIN(ParseType);
       
   753   }
       
   754   else 
       
   755   {
       
   756     //                      iFuncLine--;
       
   757     parseProcessProto();  
       
   758     BEGIN(ParseProcess);
       
   759   }
       
   760 }                                                                               
       
   761 
       
   762 <Start>{LIBUSE}{BR}*       {      //  found library or package
       
   763   bropen=0;
       
   764   bufferClear();
       
   765   isBody=0;
       
   766   QCString qcs=QCString(yytext);
       
   767   // lowerString(qcs);
       
   768   qcs=qcs.stripWhiteSpace();
       
   769   if (stricmp(qcs.data(),"use")==0)
       
   770   {
       
   771     current->spec=VhdlDocGen::USE;
       
   772     current->type="package";
       
   773   }
       
   774   else 
       
   775   {
       
   776     current->spec=VhdlDocGen::LIBRARY;
       
   777     current->type="library";
       
   778   }
       
   779   current->section=Entry::VARIABLE_SEC;
       
   780   current->bodyLine=yyLineNr;
       
   781   lineCount();
       
   782   BEGIN(FindName);
       
   783 }
       
   784 
       
   785 <Start>{FUNCPROC}       {   // found a new function|procedure
       
   786   lineCount();
       
   787   iFuncLine=yyLineNr;
       
   788   bropen=0;
       
   789   bufferClear();
       
   790   isFunc=1;
       
   791   addText(yytext,yyleng);
       
   792   BEGIN(FindFuncName);
       
   793 }
       
   794 
       
   795 <Start>{ENTITY}  {     // found entity|component|package
       
   796   lineCount();
       
   797   //printf("--> Entity at line %d\n",yyLineNr);
       
   798 
       
   799   bropen=0;  
       
   800   bufferClear();
       
   801   QCString word(yytext);
       
   802   word=word.lower();  
       
   803   word=word.stripWhiteSpace();
       
   804 
       
   805   if (strcmp(word.data(),"entity")==0)
       
   806   {
       
   807     isBody=0;
       
   808     scantype=0;                                    
       
   809     lastCompound=0;
       
   810     current->section=Entry::CLASS_SEC;
       
   811     current->spec=VhdlDocGen::ENTITY;
       
   812     current->protection=Public;
       
   813     current->bodyLine=yyLineNr;
       
   814     current->fileName=yyFileName;
       
   815     lastEntity = current;
       
   816   }
       
   817   else if (strcmp(word.data(),"component")==0)
       
   818   {
       
   819     current->section=Entry::VARIABLE_SEC;
       
   820    // current->stat=TRUE;
       
   821     current->spec=VhdlDocGen::COMPONENT;
       
   822     current->bodyLine=yyLineNr;
       
   823     scantype=1;  
       
   824   }
       
   825   else if (strcmp(word,"package")==0)
       
   826   {
       
   827     isBody=0;
       
   828     scantype=0;
       
   829     lastCompound = current;
       
   830     current->section=Entry::CLASS_SEC;
       
   831     current->spec=VhdlDocGen::PACKAGE;
       
   832     current->protection=Package; //VhdlDocGen::PACKAGE;
       
   833     current->bodyLine=yyLineNr;
       
   834     current->fileName=yyFileName;
       
   835   }
       
   836   else
       
   837     err("\n found wrong component at line [%d]",yyLineNr); 
       
   838 
       
   839   BEGIN(FindEntityName);
       
   840 }
       
   841 
       
   842 <Start>{MAPCOMPONENT}|{MAPCOMPONENT1}  { // found component instantiation 
       
   843 
       
   844  // lineCount();
       
   845   QCString type;
       
   846   QCString tt(yytext);
       
   847   QRegExp regg("[\\s:.()-]");
       
   848   QStringList qsl=QStringList::split(regg,tt,false);
       
   849 
       
   850   // consider upper/lower-case letters
       
   851   QStringList qsltemp=QStringList::split(regg,tt.lower(),false);
       
   852   int index=qsltemp.findIndex(QCString("entity"))+1;
       
   853   index+=qsltemp.findIndex(QCString("component"))+1;
       
   854   index+=qsltemp.findIndex(QCString("configuration"))+1;
       
   855   int len=qsltemp.count();
       
   856 
       
   857   current->spec=VhdlDocGen::COMPONENT_INST;
       
   858   current->section=Entry::VARIABLE_SEC;
       
   859   current->startLine=yyLineNr;
       
   860   current->bodyLine=yyLineNr;
       
   861 
       
   862   if (index!=0 && tt.contains(')')==0)     // found component instantiation xxx: configuration/component/entity yyy
       
   863   {
       
   864     current->type=(QCString)qsl[len-3];
       
   865   }
       
   866   else if (index!=0 && tt.contains(')'))   // found component instantiation xxx: entity www.yyy(zzz)
       
   867   {
       
   868     current->type=(QCString)qsl[len-4];
       
   869   }
       
   870   else
       
   871   {
       
   872     current->type=(QCString)qsl[1];          // found component instantiation xxx:yyy
       
   873   }
       
   874 
       
   875   current->name=QCString(qsl[0]);
       
   876   if (lastCompound)
       
   877   {
       
   878     lastCompound->addSubEntry(current);
       
   879     current = new Entry;
       
   880     initEntry(current);
       
   881   }
       
   882   else
       
   883   {
       
   884     newEntry();
       
   885   }
       
   886  lineCount();
       
   887 
       
   888 } 
       
   889 
       
   890 <Start>{CR}*    {
       
   891   lineCount();
       
   892   addText(yytext,yyleng);
       
   893   BEGIN(Start); 
       
   894 }
       
   895 
       
   896 <ParseProcess>[^;()] {
       
   897   // eat process body
       
   898   lineCount();
       
   899   BEGIN(ParseProcess);
       
   900 }
       
   901 
       
   902 <ParseProcess,ParseType>{ENDPROCESS} {  // find end of process
       
   903   lineCount();
       
   904   current->endBodyLine=yyLineNr;
       
   905   //printf("Process: start=%d end=%d\n",current->bodyLine,current->endBodyLine);
       
   906   if (lastCompound)
       
   907   {
       
   908     lastCompound->addSubEntry(current);
       
   909     current = new Entry;
       
   910     initEntry(current);
       
   911   }
       
   912   else
       
   913   {
       
   914     newEntry();
       
   915   }
       
   916   BEGIN(Start);
       
   917 }
       
   918 
       
   919 
       
   920 <ParseUnits>{BR}* { 
       
   921   lineCount();
       
   922 }
       
   923 
       
   924 <ParseUnits>{B}*[a-z_][^\n;]* { // parse record|unit body
       
   925   lineCount();
       
   926   QCString zz(yytext);
       
   927   addSignals(zz.data(),yyLineNr,current);
       
   928   BEGIN(ParseUnits);
       
   929 }
       
   930 
       
   931 <FindName>{NAME} {  // found entity|architecture|component name
       
   932   lineCount();
       
   933 
       
   934   QCString qcs(yytext);
       
   935   qcs=qcs.stripWhiteSpace();
       
   936   if (current->spec==VhdlDocGen::USE || current->spec==VhdlDocGen::LIBRARY)
       
   937   {
       
   938     int j=qcs.length();
       
   939     int i=qcs.find(".");
       
   940     if (i>0)
       
   941       qcs=qcs.right(j-i-1);
       
   942     i=qcs.find(".");
       
   943     if (i>0)
       
   944       qcs=qcs.left(i);            
       
   945   /*  
       
   946     -- Consider the case we have more than one entity in one file.Each entity has its own package/library
       
   947     -- declaration. In this case package yyy will be added [with newEntry()] to architecture aaa !! instead to entity
       
   948     -- bbb. We must place these constructs to current_root and the function mapLibPackage() will finish the rest.
       
   949     
       
   950     -- package xxx;
       
   951     -- entity aaa
       
   952     --  ....
       
   953     -- end entity aaa;
       
   954     -- architecture aaa
       
   955     --     ...
       
   956     -- end architecture aaa;
       
   957     -- package yyy;
       
   958     -- entity bbb;
       
   959     */
       
   960       
       
   961     current->name=qcs;                 
       
   962     Entry *copy=new Entry(*current);
       
   963     current->reset();
       
   964     addSubEntry(current_root,copy);   //  insert into entry list  with mapLibPackage()           
       
   965   }
       
   966   else if (current->spec==VhdlDocGen::ARCHITECTURE)
       
   967   {
       
   968     //current->name+=qcs.lower();
       
   969     current->name.prepend(qcs+"::");
       
   970 
       
   971     if (lastEntity)
       
   972     {
       
   973       // inherit private inheritance relation between entity and architecture
       
   974       if (!VhdlDocGen::foundInsertedComponent(current->name,lastEntity))
       
   975       {
       
   976 	BaseInfo *bb=new BaseInfo(current->name,Private,Normal);
       
   977 	lastEntity->extends->append(bb);    
       
   978       }
       
   979     }
       
   980 
       
   981   }
       
   982   else if (current->spec==VhdlDocGen::PACKAGE_BODY)
       
   983   {
       
   984     current->name+=qcs;
       
   985   }
       
   986   else
       
   987   {
       
   988     current->name+=qcs;
       
   989   }
       
   990   if (!(current->spec==VhdlDocGen::USE || current->spec==VhdlDocGen::LIBRARY))
       
   991   newEntry();
       
   992 
       
   993   BEGIN(Start);
       
   994 }
       
   995 
       
   996 <FindFuncName>{FUNCNAME}    { // found name of a process|function|procedure
       
   997   lineCount();
       
   998 
       
   999   addText(yytext,yyleng);
       
  1000   BEGIN(ParseType);
       
  1001 }
       
  1002 
       
  1003 <FindTypeName>{NAME}{BR}* {
       
  1004   lineCount();                                                            
       
  1005   current->name=QCString(yytext);
       
  1006   BEGIN(ParseType);
       
  1007 }
       
  1008 
       
  1009 
       
  1010 <ParseType>("is"){BR}+("protected"){BR}+("body") {lineCount(); BEGIN(Start); }
       
  1011 
       
  1012 <ParseType>("is"){BR}+("protected"){BR}+ { 
       
  1013  lineCount();
       
  1014  current->section=Entry::VARIABLE_SEC;
       
  1015  current->spec=VhdlDocGen::TYPE;
       
  1016  current->type="protected"; 
       
  1017  newEntry(); 
       
  1018   BEGIN(Start);
       
  1019 }
       
  1020 
       
  1021 
       
  1022 
       
  1023 
       
  1024 <ParseType>("is"){BR}*("record") { // find record
       
  1025   lineCount();
       
  1026   if (isFunc)
       
  1027   {
       
  1028     BEGIN(Start);
       
  1029   }
       
  1030 
       
  1031   genPort=2;
       
  1032   current->section=Entry::VARIABLE_SEC;
       
  1033   current->spec=VhdlDocGen::RECORD;
       
  1034   addText(yytext,yyleng); 
       
  1035   newEntry(); // adds the record to the last compound
       
  1036   BEGIN(ParseRecord);
       
  1037 }
       
  1038 
       
  1039 <ParseRecord>{BR}* {
       
  1040   lineCount();
       
  1041 }
       
  1042 
       
  1043 <ParseRecord>("end"){BR}*("record"){BR}*{LETTER}*{BR}*[;]|("end"){BR}*("units"){BR}*[;]  {
       
  1044   lineCount();
       
  1045   genPort=0;
       
  1046   bufferClear();
       
  1047   BEGIN(Start);
       
  1048 }
       
  1049 
       
  1050 <ParseRecord>[a-z_A-Z0-9][^\n;]*";"({B}*{COMMENT})* { // parse record body
       
  1051   lineCount();
       
  1052   QCString comment;
       
  1053   QCString zz(yytext);
       
  1054   VhdlDocGen::deleteAllChars(zz,';'); //delete ; in unit construct
       
  1055   if (zz.contains("--!"))
       
  1056   {
       
  1057     QStringList ql=QStringList::split("--!",zz,FALSE);
       
  1058     comment = ql[1];
       
  1059     zz = ql[0];
       
  1060   }
       
  1061   else if (zz.contains("--"))
       
  1062   {
       
  1063     QStringList ql=QStringList::split("--",zz,FALSE);
       
  1064     zz = ql[0];
       
  1065   }
       
  1066   initEntry(current);
       
  1067   addSignals(zz,yyLineNr,current,comment);
       
  1068   addText(yytext,yyleng); 
       
  1069   BEGIN(ParseRecord);
       
  1070 }
       
  1071 
       
  1072 <ParseType>{BR}+("is"){BR}+|{BR}+("is"){B}*"--" { // found a new function  in an architecture ?
       
  1073   addText(yytext,yyleng);
       
  1074   lineCount();
       
  1075   QCString ttt;
       
  1076   bool bb=TRUE;
       
  1077   getBufText(ttt,0);
       
  1078   if (ttt.contains("--"))
       
  1079   { 
       
  1080     unput('-');unput('-'); 
       
  1081     VhdlDocGen::deleteCharRev(ttt,'-');
       
  1082     VhdlDocGen::deleteCharRev(ttt,'-');
       
  1083   }
       
  1084   if (ttt.contains('(') != ttt.contains(')'))
       
  1085   {
       
  1086     bb=FALSE;
       
  1087   }
       
  1088   bool ss = VhdlDocGen::isFunctionProto(ttt);
       
  1089   //printf("VhdlDocGen::isFunctionProto(%s)=%d\n",ttt.data(),ss);
       
  1090   if (ss && bb)
       
  1091   {
       
  1092     bufferClear();
       
  1093     addText(ttt.data(),ttt.length());
       
  1094     functionEntry=0;
       
  1095     //eFuncBody=new Entry;
       
  1096     ::parseFunctionProto();
       
  1097 #if 0
       
  1098 
       
  1099     EntryListIterator eli(*eFuncBody->children());
       
  1100     Entry *rrt=eli.current();
       
  1101 
       
  1102     if (current && (current->spec==VhdlDocGen::ARCHITECTURE && rrt))
       
  1103     {
       
  1104       Entry *ep=new Entry(*rrt);
       
  1105       addSubEntry(current,ep);
       
  1106       isBody=1;
       
  1107     }
       
  1108     if (rrt) 
       
  1109     {
       
  1110       Entry *ef=VhdlDocGen::findFunction(current_root,rrt);
       
  1111       if (ef) 
       
  1112       { 
       
  1113 	ef->bodyLine=iFuncLine;
       
  1114 	functionEntry=ef;
       
  1115       }
       
  1116       else if ((current->spec==VhdlDocGen::PACKAGE_BODY))//VhdlDocGen::Package_Body))
       
  1117       {
       
  1118 	Entry *ep=new Entry(*rrt);
       
  1119 	addSubEntry(current,ep);
       
  1120 	ep->bodyLine=iFuncLine;
       
  1121 	functionEntry = ep;
       
  1122       }
       
  1123     }
       
  1124     delete eFuncBody;
       
  1125     eFuncBody=0;
       
  1126 #endif
       
  1127   }
       
  1128   bufferClear();  
       
  1129   BEGIN(ParseType);
       
  1130 }
       
  1131 
       
  1132 
       
  1133 <ParseType>[^;()\t ] {
       
  1134   lineCount();      
       
  1135   addText(yytext,yyleng); 
       
  1136   BEGIN(ParseType);
       
  1137 }
       
  1138 
       
  1139 <ParseType>{BRACEOPEN} {
       
  1140   lineCount();
       
  1141   bropen++;
       
  1142   addText(yytext,yyleng);
       
  1143   BEGIN(ParseType);
       
  1144 }
       
  1145 
       
  1146 <ParseType>{BRACECLOSE} {
       
  1147   lineCount();
       
  1148   bropen--;
       
  1149   addText(yytext,yyleng);
       
  1150   if (bropen==0 && scantype==2) // process
       
  1151   {
       
  1152     ::parseProcessProto();
       
  1153     BEGIN(ParseProcess);
       
  1154   } // if
       
  1155   else
       
  1156   {
       
  1157     BEGIN(ParseType);
       
  1158   }
       
  1159 }
       
  1160 
       
  1161 
       
  1162 <ParseType>{ENDE}|{ENDFUNC} { // found end of function|process
       
  1163   QRegExp regg("[\\s;]");
       
  1164   lineCount();
       
  1165   QCString tt(yytext);
       
  1166   tt=tt.lower();
       
  1167   QStringList ql=QStringList::split(regg,tt,FALSE);
       
  1168   int index=ql.findIndex(QCString("if"))+1;
       
  1169   index+=ql.findIndex(QCString("case"))+1;
       
  1170   index+=ql.findIndex(QCString("loop"))+1;
       
  1171   index+=ql.findIndex(QCString("generate"))+1;
       
  1172   bufferClear();
       
  1173   if (index==0)
       
  1174   {
       
  1175     if (isFunc)
       
  1176     {
       
  1177       Entry* pFunc=getEntryAtLine(current_root,iFuncLine);
       
  1178       if (pFunc && pFunc->section==Entry::FUNCTION_SEC)
       
  1179       {
       
  1180 	pFunc->endBodyLine=yyLineNr;
       
  1181       }
       
  1182       isFunc=0;
       
  1183       BEGIN(Start);
       
  1184     }
       
  1185   }
       
  1186 }
       
  1187 
       
  1188 <ParseFunc>[^;()] {
       
  1189   // eat process body
       
  1190   lineCount();
       
  1191   BEGIN(ParseFunc);
       
  1192  }
       
  1193 
       
  1194 <ParseFunc>{ENDE3} {
       
  1195   QRegExp regg("[\\s;]");
       
  1196   lineCount();
       
  1197   QCString tt(yytext);
       
  1198   tt=tt.lower();
       
  1199   QStringList ql=QStringList::split(regg,tt,FALSE);
       
  1200   int index=ql.findIndex(QCString("if"))+1;
       
  1201   index+=ql.findIndex(QCString("case"))+1;
       
  1202   index+=ql.findIndex(QCString("loop"))+1;
       
  1203   index+=ql.findIndex(QCString("generate"))+1;
       
  1204   bufferClear();
       
  1205   if (index==0 && isFunc)
       
  1206   {
       
  1207     Entry* pFunc=getEntryAtLine(current_root,iFuncLine);
       
  1208     if (pFunc && pFunc->section==Entry::FUNCTION_SEC)
       
  1209     {
       
  1210       pFunc->endBodyLine=yyLineNr;
       
  1211     }
       
  1212     isFunc=0;
       
  1213     BEGIN(Start);
       
  1214   }
       
  1215 }
       
  1216 
       
  1217 <ParseType>";" {
       
  1218   lineCount();
       
  1219   addText(yytext,yyleng);    
       
  1220   if (bropen==0 && !(isFunc==1 && isBody==1) )
       
  1221   {
       
  1222     if (isFunc)
       
  1223     {
       
  1224       parseFunctionProto();
       
  1225       bufferClear();
       
  1226       if (lastCompound && lastCompound->spec==VhdlDocGen::PACKAGE) 
       
  1227       {
       
  1228         isFunc=0;
       
  1229         BEGIN(Start);
       
  1230       }
       
  1231       else
       
  1232       {
       
  1233         BEGIN(ParseFunc); 
       
  1234       }
       
  1235     }//if
       
  1236     else
       
  1237     {
       
  1238       QCString qcs;
       
  1239       getBufText(qcs,0);
       
  1240       qcs=qcs.stripWhiteSpace();
       
  1241       current->section=Entry::VARIABLE_SEC;
       
  1242       current->type+=qcs.data();  
       
  1243 
       
  1244       if ((current->spec==VhdlDocGen::SIGNAL   || 
       
  1245 	   current->spec==VhdlDocGen::CONSTANT || 
       
  1246 	   current->spec==VhdlDocGen::TYPE     || 
       
  1247 	   current->spec==VhdlDocGen::SUBTYPE  ||
       
  1248 	   current->spec==VhdlDocGen::SHAREDVARIABLE
       
  1249 	  ) &&  
       
  1250 	  qcs.stripPrefix(","))
       
  1251       {
       
  1252 	QList<QCString> ql;
       
  1253 	ql.setAutoDelete(TRUE);
       
  1254 	QCString buffer;
       
  1255 	if (current->spec==VhdlDocGen::SUBTYPE || 
       
  1256 	    current->spec==VhdlDocGen::TYPE
       
  1257 	   )
       
  1258 	{
       
  1259 	  VhdlDocGen::getSigTypeName(ql,qcs.data(),buffer);
       
  1260 	}
       
  1261 	else
       
  1262 	{
       
  1263 	  VhdlDocGen::getSigName(ql,qcs.data(),buffer);
       
  1264 	}
       
  1265 	QCString doc = current->doc;
       
  1266 	QCString brief = current->brief;
       
  1267 	if (ql.count()>0) 
       
  1268 	{
       
  1269 	  for (uint j=1;j<ql.count();j++)
       
  1270 	  {
       
  1271 	    Entry *ppt = new Entry;
       
  1272             initEntry(ppt);
       
  1273 	    ppt->type     += ql.at(0)->data();  
       
  1274 	    ppt->section   = Entry::VARIABLE_SEC;
       
  1275 	    ppt->spec      = current->spec;        
       
  1276 	    ppt->name     += ql.at(j)->data();
       
  1277 	    ppt->bodyLine  = yyLineNr;
       
  1278 	    ppt->startLine = yyLineNr;
       
  1279 	    ppt->brief     = brief;
       
  1280 	    ppt->doc       = doc;
       
  1281 	    if (lastCompound)
       
  1282 	    {
       
  1283 	      lastCompound->addSubEntry(ppt);
       
  1284 	    }
       
  1285 	    else
       
  1286 	    {
       
  1287 	      current->addSubEntry(ppt);
       
  1288 	    }
       
  1289 	  }
       
  1290 	  current->type=ql.at(0)->data(); 
       
  1291 	  ql.clear();   
       
  1292 	}
       
  1293       }
       
  1294       if (lastCompound)
       
  1295       {
       
  1296 	lastCompound->addSubEntry(current);
       
  1297 	current = new Entry;
       
  1298 	initEntry(current);
       
  1299       }
       
  1300       else
       
  1301       {
       
  1302 	newEntry();
       
  1303       }
       
  1304       isFunc=0;
       
  1305       bufferClear();
       
  1306       BEGIN(Start);
       
  1307     }
       
  1308   }
       
  1309   else
       
  1310   {
       
  1311     BEGIN(ParseType);
       
  1312   }
       
  1313 }
       
  1314 
       
  1315 <ParseType>{TEXTT} {
       
  1316   lineCount();
       
  1317   BEGIN(ParseType);
       
  1318 }
       
  1319 
       
  1320 <ParseType>{BR}* {
       
  1321   lineCount();
       
  1322   addText(yytext,yyleng);
       
  1323   BEGIN(ParseType);
       
  1324 }
       
  1325 
       
  1326 <FindEntityName>{NAME} {    // found name of an entity/architecture/package
       
  1327   lineCount();
       
  1328   QCString qcs(yytext);
       
  1329   qcs=qcs.stripWhiteSpace();
       
  1330   qcs=qcs.lower();
       
  1331   if (strcmp(qcs.data(),"body")==0) // found package body
       
  1332   {
       
  1333     current->spec=VhdlDocGen::PACKAGE_BODY;
       
  1334     current->section=Entry::CLASS_SEC;
       
  1335     current->protection=Protected;
       
  1336     current->name+=QCString("_");
       
  1337     isBody=1;
       
  1338     BEGIN(FindName);
       
  1339   }
       
  1340   else if (scantype==1) // found a component
       
  1341   {
       
  1342     QCString qq(yytext);
       
  1343     qq=qq.stripWhiteSpace();
       
  1344     //qq=qq.lower();
       
  1345 
       
  1346     current->name=qq;
       
  1347     if (lastCompound)
       
  1348     {
       
  1349       if (lastCompound->spec==VhdlDocGen::PACKAGE)
       
  1350       {
       
  1351         if (!VhdlDocGen::foundInsertedComponent(qq,lastCompound))
       
  1352         {  
       
  1353 	  BaseInfo *bb=new BaseInfo(qq,Private,Normal);
       
  1354 	  lastCompound->extends->append(bb);    
       
  1355         }
       
  1356       } 
       
  1357 
       
  1358       lastCompound->addSubEntry(current);
       
  1359       current = new Entry;
       
  1360       initEntry(current);
       
  1361     }
       
  1362     else
       
  1363     {
       
  1364       newEntry();
       
  1365     }
       
  1366     BEGIN(Start);
       
  1367   } 
       
  1368   else
       
  1369   {
       
  1370     QCString qq(yytext);
       
  1371     qq=qq.stripWhiteSpace();
       
  1372     current->name=qq;
       
  1373     newEntry();
       
  1374     //QCString qreal=QCString(yytext);
       
  1375     BEGIN(Start);
       
  1376   }
       
  1377 }
       
  1378 
       
  1379 <Start>{B}*("generic"|"port"){BR}*[(]+ { // found generic|port in entity
       
  1380     QCString genp(yyleng+1);
       
  1381     deleteSpecChars(yytext,genp.data());
       
  1382     VhdlDocGen::deleteCharRev(genp,'(');
       
  1383 
       
  1384     if (stricmp(genp.data(),"port" )==0)
       
  1385     {
       
  1386       genPort=1;
       
  1387     }
       
  1388     else 
       
  1389     {
       
  1390       genPort=0;
       
  1391     }
       
  1392 
       
  1393     bropen=1;
       
  1394     bufferClear();
       
  1395     lineCount();
       
  1396     BEGIN(FindSigName);
       
  1397 }
       
  1398 
       
  1399 <FindSigName>{BRACECLOSE} { 
       
  1400     lineCount();
       
  1401     bropen--;
       
  1402     addText(yytext,yyleng); 
       
  1403     if (bropen==0)
       
  1404     {
       
  1405       bufferClear();
       
  1406       BEGIN(Start);
       
  1407     }
       
  1408     else
       
  1409     {
       
  1410       BEGIN(FindSigName);
       
  1411     }
       
  1412 }
       
  1413 
       
  1414 <FindSigName>{LABELID} {  // found signals in entity
       
  1415   QCString line(yytext);
       
  1416 
       
  1417   // note that line can be something like:
       
  1418   // "var1, var2, var3 : in std_logic_vector(8 downto 0); --! Some comment"
       
  1419 
       
  1420   // but also
       
  1421   // "var4 --! Some comment
       
  1422   // );"
       
  1423   // which marks the end of a port
       
  1424 
       
  1425   // and also
       
  1426   // "-- Some comment
       
  1427   // var1 : in std_logic;"
       
  1428 
       
  1429   //printf("--> labelid='%s'\n",line.data());
       
  1430   QStringList ql;
       
  1431   QCString comment;
       
  1432   int openCount=line.contains('(');
       
  1433   int closeCount=line.contains(')');
       
  1434   int semi = line.find(';');
       
  1435   int pos  = line.find("--");
       
  1436   int pos1 = line.find("--!");
       
  1437   if (pos!=-1 && pos<pos1) // strip normal comment before special one
       
  1438   {
       
  1439     line = line.remove(pos,pos1-pos);
       
  1440   }
       
  1441   //printf("=> signal: line='%s'\n",line.data());
       
  1442   if (semi!=-1 && pos!=-1)
       
  1443   {
       
  1444     int eol = line.findRev('\n');
       
  1445     //printf("pos=%d eol=%d\n",pos,eol);
       
  1446     if (eol>=pos+2)
       
  1447     {
       
  1448       QRegExp re("\\n[\\s]*--!"); // comment continuation
       
  1449       comment=line.mid(pos+2,eol-pos-2);
       
  1450       //printf("Comment: '%s'\n",comment.data());
       
  1451       int p,l;
       
  1452       while ((p=re.match(comment,0,&l))!=-1)
       
  1453       {
       
  1454 	comment.remove(p,l);
       
  1455       }
       
  1456       line=line.left(pos)+line.right(line.length()-eol);
       
  1457     }
       
  1458     else
       
  1459     {
       
  1460       comment=line.mid(pos+2);
       
  1461       line=line.left(pos);
       
  1462     }
       
  1463     comment.stripWhiteSpace();
       
  1464     // must subtract "(" and ")" in comments because they are used for determining the
       
  1465     // end of a port/generic construct
       
  1466     openCount-=comment.contains('(');
       
  1467     closeCount-=comment.contains(')');
       
  1468     if (!comment.stripPrefix("!")) // not a special comment
       
  1469     {
       
  1470       comment.resize(0);
       
  1471     }
       
  1472   }
       
  1473   else
       
  1474   {
       
  1475     //printf("no ; or --: pos=%d semi=%d\n",pos,semi);
       
  1476   }
       
  1477   int diff=openCount-closeCount;
       
  1478   if (diff<0)
       
  1479   {
       
  1480     VhdlDocGen::deleteCharRev(line,')');
       
  1481   }
       
  1482 
       
  1483   if (scantype!=1) // not a component
       
  1484   {  
       
  1485     addText(yytext,yyleng);
       
  1486     addSignals(line,yyLineNr,lastEntity,comment);
       
  1487   } 
       
  1488 
       
  1489   lineCount();
       
  1490 
       
  1491   if ((bropen+openCount-closeCount)==0)
       
  1492   {
       
  1493     bufferClear();
       
  1494     BEGIN(Start);
       
  1495   }
       
  1496 }
       
  1497 
       
  1498 
       
  1499 <FindSigName>{BRACEOPEN} { 
       
  1500   lineCount();
       
  1501   bropen++;
       
  1502   addText(yytext,yyleng);
       
  1503 }
       
  1504 
       
  1505 
       
  1506 <FindSigName>{CR}        { 
       
  1507   lineCount();
       
  1508   addText(yytext,yyleng);
       
  1509   //BEGIN(FindSigName);
       
  1510 }
       
  1511 
       
  1512 
       
  1513 <*>^{B}*("for ")[^;]* {
       
  1514   //printf("\n found for[%s] [%d]",yytext,yyLineNr);
       
  1515   lineCount();
       
  1516 }
       
  1517 
       
  1518 <*>{DIGITS}                {   // found digit
       
  1519   addText(yytext,yyleng);
       
  1520   lineCount();
       
  1521 }
       
  1522 
       
  1523 <*>{STRING_LITERAL} {
       
  1524   // Make sure string literals get transfered to the output
       
  1525   // We have to match these because the comment characters (--)
       
  1526   // can exist inside a string literal.
       
  1527   // We shouldn't have to call lineCount because newlines
       
  1528   // are not allowed inside string literals
       
  1529   addText(yytext,yyleng);
       
  1530 }
       
  1531 
       
  1532    /*
       
  1533 <*>{BR}*"--!"{B}*"@}"    { // end group
       
  1534   if (current) 
       
  1535   {
       
  1536     Entry *pg=new Entry;  
       
  1537     addSubEntry(current,pg);
       
  1538     pg->startLine=yyLineNr;
       
  1539     pg->name="endgroup";
       
  1540   }
       
  1541   lineCount();
       
  1542 }
       
  1543 
       
  1544 <*>{BR}*"--!"{B}*"@{"     {  // start group
       
  1545   if (current) 
       
  1546   {
       
  1547     Entry *pg=new Entry;  
       
  1548     addSubEntry(current,pg);
       
  1549     pg->startLine=yyLineNr;
       
  1550     pg->name="startgroup";
       
  1551   }
       
  1552   lineCount();
       
  1553 }
       
  1554    */
       
  1555 
       
  1556 <*>{BR}*"--!"[^{}\n][^\n]*\n/{B}*"--!" { // multi line comment
       
  1557   if (iDocLine==-1) iDocLine=yyLineNr;
       
  1558   // signal clk :in std_logic; --!@brief global clock
       
  1559   // --!@brief  global reset
       
  1560   // signal reset:in std_logic;
       
  1561   // these two comments are detected as a multi line comment
       
  1562   QCString qc(yytext);
       
  1563   int len=qc.contains('\n')+yyLineNr-1;
       
  1564 
       
  1565   if (YY_START!=Comment) // Start of the comment block
       
  1566   {
       
  1567     bufferClear();
       
  1568     iTextCounter=0;
       
  1569     startComment=yyLineNr;
       
  1570     g_lastCommentContext=YY_START;
       
  1571   }
       
  1572 
       
  1573   Entry* pTemp=getEntryAtLine(current_root,len);
       
  1574   if (pTemp)
       
  1575   { // found one line comment, add it to the entry on this line
       
  1576     pTemp->briefLine=yyLineNr;
       
  1577     pTemp->brief+=yytext;
       
  1578     VhdlDocGen::prepareComment(pTemp->brief);
       
  1579   }
       
  1580   else 
       
  1581   {
       
  1582     addText(yytext,yyleng);
       
  1583   }
       
  1584   lineCount();
       
  1585   BEGIN(Comment);
       
  1586 }
       
  1587 
       
  1588 <Comment>^{B}*"--!"[^\n]* {
       
  1589   if (iDocLine==-1) iDocLine=yyLineNr;
       
  1590   addText(yytext,yyleng);
       
  1591   lineCount();
       
  1592 }
       
  1593 
       
  1594 <Comment>.|\n {
       
  1595   // found end of comment block
       
  1596   QCString qcs;
       
  1597   getBufText(qcs,iTextCounter);
       
  1598   VhdlDocGen::prepareComment(qcs);
       
  1599   handleCommentBlock(qcs,FALSE);
       
  1600   bufferClear();
       
  1601   unput(*yytext);
       
  1602   BEGIN(g_lastCommentContext);
       
  1603 }
       
  1604 
       
  1605 <*>"--!"[^\n]* { // one line comment
       
  1606   if (iDocLine==-1) iDocLine=yyLineNr;
       
  1607   QCString qcs(yytext);
       
  1608   int j=qcs.find("--!");
       
  1609   qcs=qcs.right(qcs.length()-3-j);
       
  1610   //printf("--> handleCommentBlock line %d\n",yyLineNr);
       
  1611   Entry* pTemp=getEntryAtLine(current_root,yyLineNr);
       
  1612   if (pTemp)
       
  1613   {
       
  1614     pTemp->briefLine=yyLineNr;
       
  1615     pTemp->brief+=qcs;
       
  1616     iDocLine=-1;
       
  1617   }
       
  1618   else
       
  1619   {
       
  1620     handleCommentBlock(qcs,TRUE);
       
  1621   }
       
  1622   //printf("--> end: handleCommentBlock line %d\n",yyLineNr);
       
  1623   bufferClear();
       
  1624 } 
       
  1625 
       
  1626 <*>{COMMENT} {
       
  1627 }
       
  1628 
       
  1629 <*>\n                    {
       
  1630   lineCount();
       
  1631   addText(yytext,yyleng);
       
  1632   //         printf("\n new-line [%d]",yyLineNr);
       
  1633   BEGIN(Start);
       
  1634 }
       
  1635 
       
  1636 <*>{NAME} {
       
  1637   addText(yytext,yyleng);
       
  1638   lineCount();
       
  1639 }
       
  1640 
       
  1641 <*>{B}*	{
       
  1642   addText(yytext,yyleng);
       
  1643   lineCount();
       
  1644 }
       
  1645 
       
  1646 <*>.                    {
       
  1647   addText(yytext,yyleng);
       
  1648   lineCount();
       
  1649 }
       
  1650 
       
  1651 
       
  1652 %%
       
  1653 
       
  1654 static void initEntry(Entry *e)
       
  1655 {
       
  1656   e->fileName = yyFileName;
       
  1657   initGroupInfo(e);
       
  1658 }
       
  1659 
       
  1660 static void newEntry()
       
  1661 {
       
  1662   // Add only enties/architectures/packages to root 
       
  1663   // and signals to  classes where they were found
       
  1664   // ENTITY dlatch_93 IS -- VHDL'93-Syntax !!!
       
  1665   //      PORT (d, clk : IN bit;
       
  1666   //      q, qbar : OUT bit);
       
  1667   //      GROUP path IS (SIGNAL, SIGNAL);
       
  1668   //      GROUP d_to_q : path (d, q);
       
  1669   //      ATTRIBUTE propagation : time;
       
  1670   //  END dlatch_93;
       
  1671 
       
  1672   if (current->spec==VhdlDocGen::ENTITY || 
       
  1673       current->spec==VhdlDocGen::PACKAGE || 
       
  1674       current->spec==VhdlDocGen::ARCHITECTURE || 
       
  1675       current->spec==VhdlDocGen::PACKAGE_BODY)
       
  1676   {
       
  1677     current_root->addSubEntry(current);
       
  1678   }
       
  1679   else
       
  1680   {
       
  1681     if (lastCompound) 
       
  1682     {
       
  1683       lastCompound->addSubEntry(current);
       
  1684     }
       
  1685     else
       
  1686     {
       
  1687       if (lastEntity)
       
  1688       {
       
  1689 	lastEntity->addSubEntry(current);
       
  1690       }
       
  1691       else 
       
  1692       {
       
  1693 	current_root->addSubEntry(current); // should not happen!
       
  1694       }
       
  1695     }
       
  1696   }
       
  1697   previous = current;
       
  1698   current = new Entry ;
       
  1699   initEntry(current);
       
  1700 }
       
  1701 
       
  1702 static void handleCommentBlock(const QCString &doc,bool brief)
       
  1703 {
       
  1704   int position=0;
       
  1705   bool needsEntry=FALSE;
       
  1706   Protection protection=Public;
       
  1707   int lineNr = iDocLine;
       
  1708   if (brief) 
       
  1709     current->briefLine = iDocLine; 
       
  1710   else 
       
  1711     current->docLine = iDocLine;
       
  1712 
       
  1713   //printf("parseCommentBlock %p [%s]\n",current,doc.data());
       
  1714   while (parseCommentBlock(
       
  1715 	g_thisParser,
       
  1716 	current,
       
  1717 	doc,        // text
       
  1718 	yyFileName, // file
       
  1719 	lineNr,     // line of block start
       
  1720 	brief, 
       
  1721 	docBlockAutoBrief,
       
  1722 	FALSE,
       
  1723 	protection,
       
  1724         position,
       
  1725         needsEntry
       
  1726         )
       
  1727      ) 
       
  1728   {
       
  1729     //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
       
  1730     if (needsEntry) newEntry();
       
  1731   }
       
  1732   if (needsEntry)
       
  1733   {
       
  1734     newEntry();
       
  1735   }
       
  1736 
       
  1737   if (docBlockTerm)
       
  1738   {
       
  1739     unput(docBlockTerm);
       
  1740     docBlockTerm=0;
       
  1741   }
       
  1742   iDocLine=-1;
       
  1743 }
       
  1744 
       
  1745 #if 0
       
  1746 /*!
       
  1747  * adds grouping to the entries
       
  1748  */
       
  1749 static void mergeGrouping(const Entry* ce,int)
       
  1750 {
       
  1751   EntryListIterator eli(*ce->children());
       
  1752   Entry *rt;
       
  1753   for (;(rt=eli.current());++eli)
       
  1754   {
       
  1755     if (rt->section==Entry::GROUPDOC_SEC)
       
  1756     {
       
  1757       if (openGroups)
       
  1758       {
       
  1759 	QCString tt=(QCString)qrl.last();
       
  1760 	if (!tt.isEmpty()) 
       
  1761 	{
       
  1762 	  rt->groups->append(new Grouping(tt.data(),Grouping::GROUPING_LOWEST));
       
  1763 	}
       
  1764       }
       
  1765       qrl.append(rt->name);    
       
  1766     }
       
  1767 
       
  1768     if ((strcmp(rt->name.data(),"endgroup")==0) && !qrl.isEmpty())
       
  1769     {
       
  1770       qrl.remove((QCString)qrl.last());
       
  1771       openGroups--;
       
  1772     }
       
  1773 
       
  1774     if ((strcmp(rt->name.data(),"startgroup")==0))
       
  1775     {
       
  1776       openGroups++;
       
  1777     }
       
  1778 
       
  1779     if (rt->section!=Entry::GROUPDOC_SEC && openGroups && !qrl.isEmpty())
       
  1780     {
       
  1781       rt->groups->append(new Grouping(qrl.last().data(),Grouping::GROUPING_LOWEST));
       
  1782     }
       
  1783 
       
  1784     mergeGrouping(rt,openGroups);
       
  1785   }
       
  1786 }
       
  1787 #endif
       
  1788 
       
  1789 /*
       
  1790  * adds the library|use statements to the next class (entity|package|architecture|package body
       
  1791  * library ieee
       
  1792  * entity xxx
       
  1793  * .....
       
  1794  * library
       
  1795  * package
       
  1796  * enity zzz
       
  1797  * .....
       
  1798  * and so on..
       
  1799  */
       
  1800 
       
  1801 void mapLibPackage(const Entry* ce)
       
  1802 {
       
  1803   Entry *lastComp=0;
       
  1804   while (TRUE)
       
  1805   {
       
  1806     bool found = FALSE;
       
  1807     Entry *rt=0;
       
  1808     //const QList<Entry> *epp=ce->children();
       
  1809     EntryListIterator eli(*ce->children());
       
  1810     EntryListIterator eli1=eli;
       
  1811     for (;(rt=eli.current()),eli1=eli;++eli)
       
  1812     {
       
  1813       if (rt->spec==VhdlDocGen::LIBRARY || rt->spec==VhdlDocGen::USE)
       
  1814         // top level library or use statement
       
  1815       {
       
  1816 	Entry *temp=0;
       
  1817 	for (;(temp=eli1.current());++eli1) // find next entity
       
  1818 	{
       
  1819 	  if (temp->spec==VhdlDocGen::ENTITY || temp->spec==VhdlDocGen::PACKAGE || temp->spec==VhdlDocGen::ARCHITECTURE || temp->spec==VhdlDocGen::PACKAGE_BODY)
       
  1820 	  {
       
  1821 	    Entry *ee=new Entry(*rt); //append a copy to entries sublist
       
  1822 	    temp->addSubEntry(ee);
       
  1823 	    found=TRUE;
       
  1824 	    rt->spec=-1; //nullify entry
       
  1825 	    rt->section=0;
       
  1826 	    lastComp=temp;
       
  1827 	    break;
       
  1828 	  }
       
  1829 	}//for
       
  1830 	if (lastComp && rt->spec!=-1)
       
  1831 	{
       
  1832 	  Entry *ee=new Entry(*rt); //append a copy to entries sublist
       
  1833 	  lastComp->addSubEntry(ee);
       
  1834 	  found=TRUE;
       
  1835 	  rt->spec=-1; //nullify entry
       
  1836 	  rt->section=0;
       
  1837 	}
       
  1838       }//if
       
  1839     }//for
       
  1840     if (!found) // nothing left to do
       
  1841     {
       
  1842       return; 
       
  1843     }
       
  1844   }//while
       
  1845 }//MapLib
       
  1846 
       
  1847 #if 0
       
  1848 /*!
       
  1849  * merges a brief descriptions to the next entry
       
  1850  */
       
  1851 void mergeBrief(const Entry* ce)
       
  1852 {
       
  1853   EntryListIterator eli(*ce->children());
       
  1854   Entry *rt;
       
  1855   for (;(rt=eli.current());++eli)
       
  1856   {
       
  1857 
       
  1858     if (found && (!eMerge.brief.isEmpty() || !eMerge.doc.isEmpty()))
       
  1859     {
       
  1860       rt->doc+=eMerge.doc.data();
       
  1861       rt->docLine=eMerge.docLine;
       
  1862       rt->brief+=eMerge.brief.data();
       
  1863       rt->briefLine=eMerge.briefLine;
       
  1864       found=FALSE;
       
  1865     }
       
  1866 
       
  1867     if ((strcmp(rt->name.data(),"string")==0))
       
  1868     {
       
  1869       eMerge.reset();
       
  1870       eMerge.doc+=rt->doc.data();
       
  1871       eMerge.docLine=rt->docLine;
       
  1872       eMerge.brief+=rt->brief.data();
       
  1873       eMerge.briefLine=rt->briefLine;
       
  1874 
       
  1875       found=TRUE;
       
  1876     }
       
  1877     MergeBrief(rt);
       
  1878   }
       
  1879 }
       
  1880 #endif
       
  1881 
       
  1882 
       
  1883 
       
  1884 void vhdlscanFreeScanner()
       
  1885 {
       
  1886 #if defined(YY_FLEX_SUBMINOR_VERSION)
       
  1887   if (g_lexInit)
       
  1888   {
       
  1889     vhdlscanYYlex_destroy();
       
  1890   }
       
  1891 
       
  1892   if (g_buf)
       
  1893   {
       
  1894     free(g_buf);
       
  1895   }
       
  1896 
       
  1897   g_buf=0;
       
  1898 #endif
       
  1899 
       
  1900 }
       
  1901 
       
  1902 void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root)
       
  1903 {
       
  1904   inputFile.setName(fileName);
       
  1905   //uint jfile=inputFile.size();
       
  1906   ::parserInit(); 
       
  1907   yyFileName=QCString(fileName);
       
  1908   groupEnterFile(fileName,yyLineNr);
       
  1909   g_thisParser = this;
       
  1910   g_inputFromFile = FALSE;
       
  1911   inputPosition = 0;
       
  1912   assert(root!=0);
       
  1913   inputString=fileBuf;
       
  1914   current_root  = root;
       
  1915   global_root   = root;
       
  1916   current=new Entry;
       
  1917   initEntry(current);
       
  1918   //current_root->name=QCString("XXX"); // dummy name for root
       
  1919   if (!inputFile.open(IO_ReadOnly))
       
  1920   {
       
  1921     err("\n\n could not open file: %s !!\n\n",yyFileName.data());
       
  1922     return ;
       
  1923   }
       
  1924 
       
  1925   if (g_lexInit)
       
  1926   {
       
  1927     vhdlscanYYrestart(vhdlscanYYin);     
       
  1928     unput(' ');
       
  1929     BEGIN(Start);
       
  1930   }
       
  1931   vhdlscanYYlex();
       
  1932   g_lexInit=TRUE;
       
  1933 
       
  1934   free(g_buf);
       
  1935   g_buf=0;
       
  1936 
       
  1937   delete current;
       
  1938   current=0;
       
  1939 
       
  1940   groupLeaveFile(yyFileName,yyLineNr);
       
  1941   inputFile.close();
       
  1942 
       
  1943   //mergeBrief(current_root);
       
  1944   //mergeGrouping(current_root,0);
       
  1945   mapLibPackage(current_root);
       
  1946 }
       
  1947 
       
  1948 
       
  1949 void VHDLLanguageScanner::parsePrototype(const char *text)
       
  1950 {
       
  1951   // will be called when a \fn command is found in a comment block
       
  1952 
       
  1953   QCString ss,ret;
       
  1954   bool sem=FALSE;
       
  1955   bool func=FALSE;
       
  1956   QList<Argument> qs;
       
  1957   qs.setAutoDelete(TRUE);
       
  1958   VhdlDocGen::parseFuncProto(text,qs,ss,ret,TRUE);
       
  1959   int count=qs.count();
       
  1960   if (stricmp(ret.data(),"function")==0)
       
  1961   {
       
  1962     func=TRUE;
       
  1963   }
       
  1964   if (count<1 && !func)
       
  1965   {
       
  1966     return;
       
  1967   }
       
  1968   Entry *pp = new Entry;
       
  1969   initEntry(pp);
       
  1970   pp->name=ss.stripWhiteSpace();
       
  1971   pp->args+='(';
       
  1972   for (int j=0;j<count;j++)
       
  1973   {
       
  1974     if (sem)
       
  1975     {
       
  1976       pp->args+=','; 
       
  1977     }
       
  1978 
       
  1979     Argument *ars=(Argument*)(qs.at(j));
       
  1980     Argument *arg=new Argument;
       
  1981     arg->attrib = ars->attrib;
       
  1982     arg->name = ars->name;
       
  1983     arg->type = ars->type;
       
  1984     pp->args+=ars->name.data();
       
  1985     pp->args+=" ";
       
  1986     pp->args+=ars->type.data();
       
  1987     pp->argList->append(arg);
       
  1988     sem=TRUE;
       
  1989   }
       
  1990   pp->args+=')';
       
  1991 
       
  1992   if (!ret.isEmpty()) 
       
  1993     pp->spec=VhdlDocGen::FUNCTION;
       
  1994   else
       
  1995     pp->spec=VhdlDocGen::PROCEDURE;
       
  1996 
       
  1997   if (pp->section == Entry::MEMBERDOC_SEC && pp->args.isEmpty())
       
  1998     pp->section = Entry::VARIABLEDOC_SEC;
       
  1999 
       
  2000   pp->type=ret;
       
  2001   current_root->addSubEntry(pp);
       
  2002 }
       
  2003 
       
  2004 void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
       
  2005     const char *scopeName,
       
  2006     const QCString &input,
       
  2007     bool isExampleBlock,
       
  2008     const char *exampleName,
       
  2009     FileDef *fileDef,
       
  2010     int startLine,
       
  2011     int endLine,
       
  2012     bool inlineFragment,
       
  2013     MemberDef *memberDef
       
  2014     )
       
  2015 {
       
  2016   ::parseVhdlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,fileDef,startLine,endLine,inlineFragment,memberDef);
       
  2017 }
       
  2018