Orb/Doxygen/src/vhdlscanner.l
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/Doxygen/src/vhdlscanner.l	Thu Jan 21 17:29:01 2010 +0000
@@ -0,0 +1,2018 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2008 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby 
+ * granted. No representations are made about the suitability of this software 
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+/******************************************************************************
+ * Parser for VHDL subset
+ * written by M. Kreis
+ * supports VHDL-87/93
+ * does not support VHDL-AMS 
+ ******************************************************************************/
+%{
+
+// global includes
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <qcstring.h>
+#include <qfileinfo.h>
+#include <qstringlist.h>
+
+/* --------------------------------------------------------------- */
+
+// local includes
+#include "vhdlscanner.h"
+#include "vhdlcode.h"
+#include "vhdldocgen.h"
+#include "message.h"
+#include "config.h"
+#include "doxygen.h"
+#include "util.h"
+#include "language.h"
+#include "commentscan.h"
+#include "index.h"
+#include "definition.h"
+#include "searchindex.h"
+#include "outputlist.h"
+
+/* --------------------------------------------------------------- */
+
+//#define theTranslator_vhdlType theTranslator->trVhdlType
+#define theTranslator_vhdlType VhdlDocGen::getVhdlType
+
+static QStringList      qrl;
+static int              openGroups;
+static ParserInterface *g_thisParser;
+static const char *     inputString;
+static int              inputPosition;
+static int              startComment  = 0;
+static QFile            inputFile;
+static QCString         inbuf;
+static Entry*           global_root   = 0;
+static Entry*           current_root  = 0;
+static Entry*           current       = 0;
+static Entry*           previous      = 0;
+static Entry*           functionEntry = 0;
+static Entry*           lastEntity    = 0;
+static Entry*           lastCompound  = 0;
+static int              genPort       = 0;
+static QCString         yyFileName;
+static int              iFuncLine     = 1;
+static bool             g_inputFromFile ;
+static bool             g_lexInit     = FALSE;
+static int              isBody=0;
+static int              isFunc=0;
+static int              yyLineNr      = 1;
+static char *           g_buf         = 0;
+static uint             g_bufSize     = 0;
+static int              iTextCounter  = 0;
+static int              iCounter      = 0;
+static int              bropen        = 0;
+static int              scantype      = 0;
+static int              g_lastCommentContext = 0;
+static bool             docBlockAutoBrief;
+static char             docBlockTerm;
+static int              iDocLine      = -1;
+
+//#define YY_A_INTERACTIVE 1
+#define YY_NEVER_INTERACTIVE 1
+//-----------------------------------------------------------------------------
+
+static void parserInit();
+static void deleteSpecChars(char* str,char *buf);
+static void handleCommentBlock(const QCString &doc,bool brief);
+static void newEntry();
+static void initEntry(Entry *e);
+
+static void addSubEntry(Entry* root, Entry* e)
+{
+  if (e==0 || root==0) return;
+  //if (isPrevDoc) 
+  //{
+  //  e->brief=prevDocEntry.brief;
+  //  e->briefLine=prevDocEntry.briefLine;
+  //  prevDocEntry.reset();
+  //  isPrevDoc=FALSE;
+  //}
+  root->addSubEntry(e);
+} 
+
+static void bufferClear()
+{
+  int j;
+  for (j=0;j<iCounter+1;j++)
+  {
+    g_buf[j]=0;
+  }
+
+  iCounter=0;
+}
+
+static void  addText (char *word, int llen)
+{
+  if ((uint)(iCounter + llen) > g_bufSize)
+  {
+    char *pTmp = (char*)realloc(g_buf,iCounter+llen+2048);
+    if (pTmp)
+    {
+      g_buf = pTmp;
+    }
+    else
+    {
+      fprintf(stderr,"\n not enough memory for realloc\n");
+      return; 
+    }
+  }
+  while (llen>0)
+  {
+    g_buf[iCounter]=*word++;
+    iCounter++;
+    llen--;
+  }    
+  g_buf[iCounter]='\0'; 
+} 
+
+static void getBufText(QCString& qc,int start)
+{
+  while (start < iCounter)
+  {
+    qc+=(g_buf[start]);
+    start++;
+  }
+}
+
+static void lineCount()
+{
+  for ( const char* c = yytext ; *c ; ++c )
+  {
+    yyLineNr += (*c == '\n') ;
+  }
+}
+
+static void deleteSpecChars(char* str,char *buf)
+{
+  while (*str)
+  {
+    if ((*str == '\t') || (*str == '\n') || (*str == '\r') || (*str == ' ')) 
+    {
+      *str++;
+    }
+    else
+    {
+      *buf++ = *str++;
+    }
+  }
+  *buf='\0';
+}
+
+void getType(Entry* p,char* text)
+{
+  QCString name(text);
+  name=name.stripWhiteSpace();           
+  if (stricmp(name.data(),"signal" )==0)
+  {
+    p->spec=VhdlDocGen::SIGNAL;
+  }
+  else if (stricmp(name.data(),"type" )==0)
+  {
+    p->spec=VhdlDocGen::TYPE; 
+  }
+  else if (stricmp(name.data(),"subtype" )==0)
+  {
+    p->spec=VhdlDocGen::SUBTYPE;   
+  }
+  else if (stricmp(name.data(),"constant" )==0)
+  {
+    p->spec=VhdlDocGen::CONSTANT;    
+  }
+  else if (stricmp(name.data(),"attribute" )==0)
+  {
+    p->spec=VhdlDocGen::ATTRIBUTE;
+  }
+  else if (stricmp(name.data(),"function" )==0)
+  {
+    p->spec=VhdlDocGen::FUNCTION;    
+  }
+  else if (stricmp(name.data(),"procedure" )==0)
+  {
+    p->spec=VhdlDocGen::PROCEDURE;
+  }
+  else if (stricmp(name.data(),"units" )==0)
+  {
+    p->spec=VhdlDocGen::UNITS;
+  }
+  else if (name.contains("shared",false) && name.contains("variable",false))
+  {
+    p->spec=VhdlDocGen::SHAREDVARIABLE;
+  }
+  else if (stricmp(name.data(),"file" )==0) 
+  {
+    p->spec=VhdlDocGen::VFILE;
+  }
+  else if (stricmp(name.data(),"group" )==0) 
+  {
+    p->spec=VhdlDocGen::GROUP; 
+  }
+  else if (stricmp(name.data(),"alias" )==0) 
+  {
+    p->spec=VhdlDocGen::ALIAS; 
+  }
+  else 
+  {
+    err("wrong type");
+  }
+  p->section=Entry::VARIABLE_SEC;
+}
+
+//-------------------------------------------------------------------------
+
+/*
+ * adds signals found in entities|records|units
+ */
+
+void addSignals(const char* str,int line, Entry *e,const char *comment=0)
+{
+  //printf("===> addSignals (%s) comment='%s'\n",str,comment);
+  QList<QCString> ql;
+  QCString bufio;
+  ql.setAutoDelete(TRUE);
+
+  VhdlDocGen::getSigName(ql,str,bufio);
+  int count = ql.count();
+
+  QCString brief  = current->brief;
+  QCString doc    = current->doc;
+  Entry *tmpEntry = current;
+  current = new Entry;
+  initEntry(current);
+  handleCommentBlock(comment,TRUE);
+  if (!current->brief.isEmpty())
+  {
+    if (doc.isEmpty())
+    {
+      doc = brief;
+    }
+    else if (!brief.isEmpty())
+    {
+      doc = brief + "<p>" + doc;
+    }
+    brief = current->brief;
+  }
+  delete current;
+  current = tmpEntry;
+  current->brief.resize(0);
+  current->doc.resize(0);
+ 
+  if (genPort!=3) // not a unit
+  {
+    for (int k=1;k<count;k++)
+    {
+      //printf("adding '%s' '%s'\n",ql.at(0)->data(),ql.at(k)->data());
+      Entry *pTemp=new Entry;
+      initEntry(pTemp);
+      pTemp->startLine = line;
+      pTemp->bodyLine  = line;
+      pTemp->name      = ql.at(k)->data();
+      pTemp->section   = Entry::VARIABLE_SEC;
+      pTemp->brief     = brief;
+      pTemp->doc       = doc;
+      pTemp->mGrpId    = current->mGrpId; // copy member group id
+      QCString stSpec  = ql.at(0)->data();
+      if (genPort==1) // found port
+      {
+	pTemp->spec    = VhdlDocGen::PORT;
+	stSpec.stripPrefix(bufio.data()); 
+	stSpec=stSpec.stripWhiteSpace();
+	pTemp->args    = stSpec;
+	pTemp->type    = bufio;
+	addSubEntry(e,pTemp);
+      }
+      else if (genPort==2) // found record
+      {
+	pTemp->spec    = VhdlDocGen::RECORD;
+	pTemp->type    = stSpec;
+	pTemp->name.prepend(VhdlDocGen::getRecordNumber());
+	delete current;
+	current = new Entry(*pTemp); // make a deep copy of pTemp
+	newEntry();                  // add it to lastCompound and make a new current
+	delete pTemp;
+      }
+      else 
+      {
+	pTemp->spec    = VhdlDocGen::GENERIC;
+	pTemp->type    = stSpec;
+	addSubEntry(e,pTemp);
+      }
+    }// for
+  }
+  else // found a unit 
+  {
+    Entry *pTemp=new Entry;
+    initEntry(pTemp);
+    QCString tt(str);
+    QStringList ql=QStringList::split("=",tt,FALSE);
+    pTemp->spec      = VhdlDocGen::UNITS;
+    pTemp->section   = Entry::VARIABLE_SEC;
+    pTemp->startLine = line;
+    pTemp->bodyLine  = line;
+    pTemp->brief     = brief; // adds brief description to the unit member
+    pTemp->doc       = doc;   // adds doc to the unit member
+    pTemp->type      = ql[1];
+    pTemp->name      = ql[0].stripWhiteSpace();
+    pTemp->name.prepend(VhdlDocGen::getRecordNumber());
+    delete current;
+    current = new Entry(*pTemp); // make a deep copy
+    newEntry();                  // add it to lastCompound
+    delete pTemp;
+  }
+}                                              
+
+/*
+ * this function parses a process prototype
+ * and adds the signal to the process
+ */
+
+static void parseProcessProto()
+{
+  QStringList ql;
+  QCString qcs;
+  bool sem=FALSE;
+  //Entry* ppEntry=new Entry;
+  //ppEntry->fileName=yyFileName;
+  //processEntry=ppEntry;
+  QCString name; 
+  scantype=0;
+  getBufText(qcs,0);
+  if (qcs.contains('(') != qcs.contains(')')) return; 
+  VhdlDocGen::deleteAllChars(qcs,'\n');
+  VhdlDocGen::parseProcessProto(qcs,name,ql);
+  current->section=Entry::FUNCTION_SEC;
+  //current->stat=TRUE;
+  current->spec=VhdlDocGen::PROCESS;
+  current->startLine=iFuncLine;
+  current->bodyLine=iFuncLine;
+  current->fileName=yyFileName;
+  if (!name.isEmpty())
+  {
+    current->name=name.stripWhiteSpace();
+  }
+  else // found an anonymous process, so we add a generated name  
+  {
+    current->name=VhdlDocGen::getProcessNumber(); 
+  }
+
+  current->args+=" ( "; 
+  if (!ql.isEmpty())
+  {
+    QValueList<QString>::Iterator iter = ql.begin();
+    for ( ; iter != ql.end(); ++iter)
+    {
+      if (sem)
+      {
+        current->args+=',';
+      }
+      Argument *arg=new Argument;
+      arg->name=((QCString)*iter).stripWhiteSpace();    
+      current->argList->append(arg);
+      current->args+=(QCString)*iter; 
+      sem = TRUE;
+    }    
+  }
+  current->args+=" ) ";
+  bufferClear();
+}//parseProcessProto
+
+
+/*
+ * parses a function|procedure protoype
+ */
+
+static void parseFunctionProto()
+{
+  QCString name,ret,qcs,temp;
+  bool sem=FALSE;
+  QList<Argument> ql;
+  ql.setAutoDelete(TRUE);
+  getBufText(qcs,0);
+  if (qcs.contains('(') != qcs.contains(')')) 
+    return; // function without a prototype 
+  if (qcs.contains("function",FALSE)==0 && qcs.contains("procedure",FALSE)==0) 
+    return; 
+  qcs=qcs.stripWhiteSpace();
+  temp=qcs.lower();
+  if (temp.stripPrefix("impure"))
+  {
+    current->exception="impure";
+    qcs=qcs.remove(0,6);
+  }
+  else if (temp.stripPrefix("pure")) 
+  {
+    current->exception="pure";
+    qcs=qcs.remove(0,4);
+  }
+
+  VhdlDocGen::parseFuncProto(qcs.data(),ql,name,ret); 
+  //printf("parseFuncProto(%s)=%s,%s\n",qcs.data(),name.data(),ret.data());
+  VhdlDocGen::deleteAllChars(name,';');
+  current->name=name;
+  current->startLine=iFuncLine;
+  current->bodyLine=iFuncLine;
+
+  int count = ql.count(); 
+
+  current->args+" ( "; 
+  for (int k=0;k<count;k++)
+  {
+    if (sem)
+    {
+      current->args+=",";
+    }
+    Argument *arg=new Argument;
+    Argument *hh=(Argument*)ql.at(k);
+    arg->name=hh->name;
+    arg->type=hh->type;
+    arg->defval=hh->defval;
+    arg->attrib=hh->attrib;
+    current->argList->append(arg);
+    current->args+=hh->name;
+    sem=TRUE;
+  }
+  current->args+" )";
+
+  if (!ret.isEmpty()) 
+    current->spec=VhdlDocGen::FUNCTION;
+  else
+    current->spec=VhdlDocGen::PROCEDURE;
+
+  current->section=Entry::FUNCTION_SEC;
+  current->type=ret;
+  //addSubEntry(ee,ppEntry); 
+  if (lastCompound)
+  {
+    lastCompound->addSubEntry(current);
+    current = new Entry;
+    initEntry(current);
+  }
+  else
+  {
+    newEntry();
+  }
+  bufferClear();
+}//parseFunctionProto
+
+static Entry* getEntryAtLine(const Entry* ce,int line)
+{
+  EntryListIterator eli(*ce->children());
+  Entry *found=0;
+  Entry *rt;
+  for (;(rt=eli.current());++eli)
+  {
+    if (rt->bodyLine==line)
+    {
+      found=rt;
+    } // if
+    if (!found) 
+    {
+      found=getEntryAtLine(rt,line);
+    }
+  }
+  return found;
+}// getEntryAtLine
+
+//-------------------------------------------------------------------------
+
+
+void parserInit()
+{
+  iCounter=0; 
+  iTextCounter=0;
+  yyLineNr=1;
+  current=0;
+  previous=0;
+  isFunc=0;
+  isBody=0;
+  scantype=0;
+  //pEntry=0;
+  //pp=0; 
+  lastCompound=0;
+  lastEntity=0;
+  bropen=0;
+  openGroups=0;
+  iDocLine=-1;
+  //isPrevDoc=FALSE;
+  //prevDocEntry.reset();
+  qrl.clear();
+
+  if (!g_lexInit) 
+  {
+    VhdlDocGen::init();
+  }
+
+  g_bufSize=inputFile.size()+1024;
+  if (g_buf==0) free(g_buf);
+  g_buf=(char*)(calloc(g_bufSize,sizeof(char)));
+
+  if (g_buf==0)
+  {
+    fprintf(stderr,"\n not enough memory");
+    return;
+  }
+  g_buf[g_bufSize-1]='\0';
+}
+
+bool VHDLLanguageScanner::needsPreprocessing(const QCString &)
+{
+  return FALSE;
+}
+
+
+void VHDLLanguageScanner::resetCodeParserState()
+{
+
+}
+
+#undef    YY_INPUT
+#define    YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
+
+static int yyread(char *buf,int max_size)
+{
+  int c=0;
+  if (g_inputFromFile)
+  {
+    c = inputFile.readBlock(buf,max_size);
+    if (c==-1) yy_fatal_error("input in flex scanner failed");
+  }
+  else
+  {
+    while ( c < max_size && inputString[inputPosition] )
+    {
+      *buf = inputString[inputPosition++] ;
+      c++; buf++;
+    }
+  }
+  return c;
+}
+
+#if 0
+/*
+ * adds a  text line description [--#] to the the previous type  
+ */
+
+static void addOneTextLine(QCString& ss )
+{
+  Entry* pTemp=0;
+  if (current && current->bodyLine==yyLineNr)
+    pTemp=current;
+  //else if (pEntry && pEntry->bodyLine==yyLineNr)
+  //  pTemp=pEntry;
+  else 
+    pTemp=getEntryAtLine(current_root,yyLineNr) ;
+
+  if (pTemp)
+  {
+    ss=ss.stripWhiteSpace();
+    ss.stripPrefix("--!");
+    pTemp->brief=ss;
+    pTemp->briefLine=yyLineNr;
+  }        
+}
+#endif
+
+%}
+
+
+  /* start command character */
+  /* -------------- VHDL SECTION -----------------------------------*/
+
+B                       [ \t]
+CR                      [\r\n]
+BR                      [ \t\n\r]
+DIGIT                   [0-9]
+LOWER_CASE_LETTER       [a-z]
+UPPER_CASE_LETTER       [A-Z]
+LETTER                  [a-zA-Z_0-9]
+SPACE_CHARACTER         [ \t]
+SPECIAL_CHARACTER       [#&'()*+,\-\./:;<=>_|]
+OTHER_SPECIAL_CHARACTER [~!$ยง%?@\[\\\]^{}]
+BASIC_GRAPHIC_CHARACTER {UPPER_CASE_LETTER}|{DIGIT}|{SPECIAL_CHARACTER}|{SPACE_CHARACTER}
+GRAPHIC_CHARACTER       {BASIC_GRAPHIC_CHARACTER}|{LOWER_CASE_LETTER}|{OTHER_SPECIAL_CHARACTER}
+EXTENDED_CHARACTER      [\\]{GRAPHIC_CHARACTER}*[\\] 
+
+NAME                    ({LETTER}[a-zA-Z0-9_.]*)|{EXTENDED_CHARACTER}
+STRING_LITERAL          \"{GRAPHIC_CHARACTER}*\"
+FUNCNAME                ([a-zA-Z"][*+\-_a-zA-Z0-9"\/=<>]*)|{EXTENDED_CHARACTER}
+DIGITS                  [0-9]+|[0-9]+"."[0-9]+|[0-9]+"#"[0-9_a-fA-F\+\.]+"#"
+COMMENT                 "--"[^\n]*
+LABELID                 [a-z_A-Z][^\;]*";"({B}*{COMMENT})*
+PROTO                   [ (]*
+TEXTT                   "--"[^\/\@\*\#][^\n]*
+PROC                    ("function"|"procedure")
+ENDE                    ({BR}*("end"){BR}*{PROC}*{BR}*[;]{1})
+ENDEFF                  ("if"|"case"|"loop"|"generate"){BR}*[;]
+ENDE3                   ({BR}*("end"){BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;])|{ENDE}
+ENDFUNC                 {B}*"end"{BR}*{PROC}*{BR}*{FUNCNAME}{BR}*[;]
+FUNCIMPURE              "impure"|"pure"
+FUNCPROC                ^{B}*{FUNCIMPURE}*{BR}*("function"|"procedure"){B}*
+ARCHITECTURE            ("architecture"){BR}+{NAME}{BR}*("of")
+   /* Removed due to bug 538239
+      POST         "postponed"
+      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")
+   */
+PROCESS                 ({B}*{FUNCNAME}{B}*:{BR}*)?({B}*("postponed"){BR}+)?{B}*("process"){BR}*{PROTO}
+
+ENDPROCESS              ("end"){BR}*("postponed")*("process"){BR}*{FUNCNAME}*{BR}*[;]
+LIBUSE                  ^{B}*("use"|"library"){BR}+
+ENTITY                  ^{B}*("component"|"entity"|"package"){BR}+
+PBODY                   ("package"){B}+("body"){BR}+{NAME}
+SHARED                  ("shared"){BR}+("variable")
+SIGTYPES                ^{B}*({SHARED}|"alias"|"file"|"group"|"subtype"|"type"|"constant"|"attribute"|"signal"|"units"){BR}+
+CONFIG                  ("configuration"){BR}+{NAME}{BR}*("of"){BR}+{NAME}{BR}+"is"
+
+ALLTYPESMAP             {B}*[_a-zA-ZA_Z0-9.() ]*{B}*
+MAPCOMPONENT            ({ALLTYPESMAP}{BR}*[:]{BR}*("component"|"configuration")*{ALLTYPESMAP}{BR}*{TEXTT}*{BR}*("port"|"generic"){BR}*("map"){BR}*("("){1})
+MAPCOMPONENT1           ({ALLTYPESMAP}{BR}*[:]{BR}*("entity"){BR}*{ALLTYPESMAP}{BR}*("port"|"generic"){BR}*("map"){BR}*("("){1})
+
+BRACEOPEN               [(]{1}
+BRACECLOSE              [)]{1}
+
+ALLID                   [^;()\t ]
+
+/* VHDL 2001 */
+ENDPROTECTED            ("end"{BR}+"protected"{BR}+{NAME}{BR}*";")|("end"{BR}+"protected"{BR}*";")
+ENDPROTECEDBODY         "end"{BR}+"protected"{BR}+"body"{BR}+{NAME}
+
+
+%option noyywrap
+
+  /* language parsing states */
+
+%x Start
+%x Comment
+%x FindTypeName
+%x ParseType 
+%x ParseRecord
+%x ParseUnits
+%x ParseProcess
+%x ParseFunc
+%x FindName
+%x FindEntityName
+%x FindGenPort
+%x FindTypes
+%x FindSigName
+%x FindFuncName
+%x FindBegin
+
+%%
+
+<Start>{ENDPROTECTED}|{ENDPROTECEDBODY}  {
+ lineCount();
+}
+
+
+
+<Start>{CONFIG} { // found configuration
+ 
+  QCString qcs(vhdlscanYYtext);
+  current->name=VhdlDocGen::getIndexWord(qcs,1);
+  current->type=VhdlDocGen::getIndexWord(qcs,3);
+  current->startLine=yyLineNr;
+  current->bodyLine=yyLineNr;
+  current->section=Entry::VARIABLE_SEC; 
+  current->spec=VhdlDocGen::CONFIG;
+  current->args="configuration";
+  newEntry();
+  BEGIN(Start);
+}
+
+<Start>{SIGTYPES}  { // found type constant|type|attribute and so on..
+    bropen=0;
+    lineCount();
+
+    bufferClear();
+    //pEntry=current;
+    getType(current,yytext);
+    current->bodyLine=yyLineNr;
+    if (current->spec==VhdlDocGen::UNITS)
+    {
+      //addSubEntry(current,pEntry);
+      current->startLine=yyLineNr;
+      current->bodyLine=yyLineNr;
+      newEntry(); // adds the unit to the lastCompound
+      genPort=3;
+      BEGIN(ParseRecord);
+    }
+    else    
+    {
+      BEGIN(FindTypeName);
+    }
+  }
+
+<Start>{ARCHITECTURE} {     //found architecure
+  lineCount();
+  bropen=0;
+  bufferClear();
+  isBody=0;
+  lastCompound = current;
+  QCString curName=VhdlDocGen::getIndexWord(yytext,1);
+  current->section=Entry::CLASS_SEC; //Entry::CLASS_SEC;
+  current->spec=VhdlDocGen::ARCHITECTURE;
+  current->protection=Private;
+  current->name=curName;
+  current->fileName=yyFileName;
+  current->startLine=yyLineNr;
+  current->bodyLine=yyLineNr;      
+  //printf("-> Architecture at line %d\n",yyLineNr);
+  BEGIN(FindName);
+}
+
+
+<Start>{PROCESS} {          //found process
+  lineCount();
+  iFuncLine=yyLineNr;
+  bropen=0;
+  //printf("--> Process: line=%d\n",yyLineNr);
+  bufferClear();
+  addText(yytext,yyleng);
+  QCString qcs(yytext);
+  if (qcs.contains('('))
+  {
+    bropen=1;
+    scantype=2;
+    BEGIN(ParseType);
+  }
+  else 
+  {
+    //                      iFuncLine--;
+    parseProcessProto();  
+    BEGIN(ParseProcess);
+  }
+}                                                                               
+
+<Start>{LIBUSE}{BR}*       {      //  found library or package
+  bropen=0;
+  bufferClear();
+  isBody=0;
+  QCString qcs=QCString(yytext);
+  // lowerString(qcs);
+  qcs=qcs.stripWhiteSpace();
+  if (stricmp(qcs.data(),"use")==0)
+  {
+    current->spec=VhdlDocGen::USE;
+    current->type="package";
+  }
+  else 
+  {
+    current->spec=VhdlDocGen::LIBRARY;
+    current->type="library";
+  }
+  current->section=Entry::VARIABLE_SEC;
+  current->bodyLine=yyLineNr;
+  lineCount();
+  BEGIN(FindName);
+}
+
+<Start>{FUNCPROC}       {   // found a new function|procedure
+  lineCount();
+  iFuncLine=yyLineNr;
+  bropen=0;
+  bufferClear();
+  isFunc=1;
+  addText(yytext,yyleng);
+  BEGIN(FindFuncName);
+}
+
+<Start>{ENTITY}  {     // found entity|component|package
+  lineCount();
+  //printf("--> Entity at line %d\n",yyLineNr);
+
+  bropen=0;  
+  bufferClear();
+  QCString word(yytext);
+  word=word.lower();  
+  word=word.stripWhiteSpace();
+
+  if (strcmp(word.data(),"entity")==0)
+  {
+    isBody=0;
+    scantype=0;                                    
+    lastCompound=0;
+    current->section=Entry::CLASS_SEC;
+    current->spec=VhdlDocGen::ENTITY;
+    current->protection=Public;
+    current->bodyLine=yyLineNr;
+    current->fileName=yyFileName;
+    lastEntity = current;
+  }
+  else if (strcmp(word.data(),"component")==0)
+  {
+    current->section=Entry::VARIABLE_SEC;
+   // current->stat=TRUE;
+    current->spec=VhdlDocGen::COMPONENT;
+    current->bodyLine=yyLineNr;
+    scantype=1;  
+  }
+  else if (strcmp(word,"package")==0)
+  {
+    isBody=0;
+    scantype=0;
+    lastCompound = current;
+    current->section=Entry::CLASS_SEC;
+    current->spec=VhdlDocGen::PACKAGE;
+    current->protection=Package; //VhdlDocGen::PACKAGE;
+    current->bodyLine=yyLineNr;
+    current->fileName=yyFileName;
+  }
+  else
+    err("\n found wrong component at line [%d]",yyLineNr); 
+
+  BEGIN(FindEntityName);
+}
+
+<Start>{MAPCOMPONENT}|{MAPCOMPONENT1}  { // found component instantiation 
+
+ // lineCount();
+  QCString type;
+  QCString tt(yytext);
+  QRegExp regg("[\\s:.()-]");
+  QStringList qsl=QStringList::split(regg,tt,false);
+
+  // consider upper/lower-case letters
+  QStringList qsltemp=QStringList::split(regg,tt.lower(),false);
+  int index=qsltemp.findIndex(QCString("entity"))+1;
+  index+=qsltemp.findIndex(QCString("component"))+1;
+  index+=qsltemp.findIndex(QCString("configuration"))+1;
+  int len=qsltemp.count();
+
+  current->spec=VhdlDocGen::COMPONENT_INST;
+  current->section=Entry::VARIABLE_SEC;
+  current->startLine=yyLineNr;
+  current->bodyLine=yyLineNr;
+
+  if (index!=0 && tt.contains(')')==0)     // found component instantiation xxx: configuration/component/entity yyy
+  {
+    current->type=(QCString)qsl[len-3];
+  }
+  else if (index!=0 && tt.contains(')'))   // found component instantiation xxx: entity www.yyy(zzz)
+  {
+    current->type=(QCString)qsl[len-4];
+  }
+  else
+  {
+    current->type=(QCString)qsl[1];          // found component instantiation xxx:yyy
+  }
+
+  current->name=QCString(qsl[0]);
+  if (lastCompound)
+  {
+    lastCompound->addSubEntry(current);
+    current = new Entry;
+    initEntry(current);
+  }
+  else
+  {
+    newEntry();
+  }
+ lineCount();
+
+} 
+
+<Start>{CR}*    {
+  lineCount();
+  addText(yytext,yyleng);
+  BEGIN(Start); 
+}
+
+<ParseProcess>[^;()] {
+  // eat process body
+  lineCount();
+  BEGIN(ParseProcess);
+}
+
+<ParseProcess,ParseType>{ENDPROCESS} {  // find end of process
+  lineCount();
+  current->endBodyLine=yyLineNr;
+  //printf("Process: start=%d end=%d\n",current->bodyLine,current->endBodyLine);
+  if (lastCompound)
+  {
+    lastCompound->addSubEntry(current);
+    current = new Entry;
+    initEntry(current);
+  }
+  else
+  {
+    newEntry();
+  }
+  BEGIN(Start);
+}
+
+
+<ParseUnits>{BR}* { 
+  lineCount();
+}
+
+<ParseUnits>{B}*[a-z_][^\n;]* { // parse record|unit body
+  lineCount();
+  QCString zz(yytext);
+  addSignals(zz.data(),yyLineNr,current);
+  BEGIN(ParseUnits);
+}
+
+<FindName>{NAME} {  // found entity|architecture|component name
+  lineCount();
+
+  QCString qcs(yytext);
+  qcs=qcs.stripWhiteSpace();
+  if (current->spec==VhdlDocGen::USE || current->spec==VhdlDocGen::LIBRARY)
+  {
+    int j=qcs.length();
+    int i=qcs.find(".");
+    if (i>0)
+      qcs=qcs.right(j-i-1);
+    i=qcs.find(".");
+    if (i>0)
+      qcs=qcs.left(i);            
+  /*  
+    -- Consider the case we have more than one entity in one file.Each entity has its own package/library
+    -- declaration. In this case package yyy will be added [with newEntry()] to architecture aaa !! instead to entity
+    -- bbb. We must place these constructs to current_root and the function mapLibPackage() will finish the rest.
+    
+    -- package xxx;
+    -- entity aaa
+    --  ....
+    -- end entity aaa;
+    -- architecture aaa
+    --     ...
+    -- end architecture aaa;
+    -- package yyy;
+    -- entity bbb;
+    */
+      
+    current->name=qcs;                 
+    Entry *copy=new Entry(*current);
+    current->reset();
+    addSubEntry(current_root,copy);   //  insert into entry list  with mapLibPackage()           
+  }
+  else if (current->spec==VhdlDocGen::ARCHITECTURE)
+  {
+    //current->name+=qcs.lower();
+    current->name.prepend(qcs+"::");
+
+    if (lastEntity)
+    {
+      // inherit private inheritance relation between entity and architecture
+      if (!VhdlDocGen::foundInsertedComponent(current->name,lastEntity))
+      {
+	BaseInfo *bb=new BaseInfo(current->name,Private,Normal);
+	lastEntity->extends->append(bb);    
+      }
+    }
+
+  }
+  else if (current->spec==VhdlDocGen::PACKAGE_BODY)
+  {
+    current->name+=qcs;
+  }
+  else
+  {
+    current->name+=qcs;
+  }
+  if (!(current->spec==VhdlDocGen::USE || current->spec==VhdlDocGen::LIBRARY))
+  newEntry();
+
+  BEGIN(Start);
+}
+
+<FindFuncName>{FUNCNAME}    { // found name of a process|function|procedure
+  lineCount();
+
+  addText(yytext,yyleng);
+  BEGIN(ParseType);
+}
+
+<FindTypeName>{NAME}{BR}* {
+  lineCount();                                                            
+  current->name=QCString(yytext);
+  BEGIN(ParseType);
+}
+
+
+<ParseType>("is"){BR}+("protected"){BR}+("body") {lineCount(); BEGIN(Start); }
+
+<ParseType>("is"){BR}+("protected"){BR}+ { 
+ lineCount();
+ current->section=Entry::VARIABLE_SEC;
+ current->spec=VhdlDocGen::TYPE;
+ current->type="protected"; 
+ newEntry(); 
+  BEGIN(Start);
+}
+
+
+
+
+<ParseType>("is"){BR}*("record") { // find record
+  lineCount();
+  if (isFunc)
+  {
+    BEGIN(Start);
+  }
+
+  genPort=2;
+  current->section=Entry::VARIABLE_SEC;
+  current->spec=VhdlDocGen::RECORD;
+  addText(yytext,yyleng); 
+  newEntry(); // adds the record to the last compound
+  BEGIN(ParseRecord);
+}
+
+<ParseRecord>{BR}* {
+  lineCount();
+}
+
+<ParseRecord>("end"){BR}*("record"){BR}*{LETTER}*{BR}*[;]|("end"){BR}*("units"){BR}*[;]  {
+  lineCount();
+  genPort=0;
+  bufferClear();
+  BEGIN(Start);
+}
+
+<ParseRecord>[a-z_A-Z0-9][^\n;]*";"({B}*{COMMENT})* { // parse record body
+  lineCount();
+  QCString comment;
+  QCString zz(yytext);
+  VhdlDocGen::deleteAllChars(zz,';'); //delete ; in unit construct
+  if (zz.contains("--!"))
+  {
+    QStringList ql=QStringList::split("--!",zz,FALSE);
+    comment = ql[1];
+    zz = ql[0];
+  }
+  else if (zz.contains("--"))
+  {
+    QStringList ql=QStringList::split("--",zz,FALSE);
+    zz = ql[0];
+  }
+  initEntry(current);
+  addSignals(zz,yyLineNr,current,comment);
+  addText(yytext,yyleng); 
+  BEGIN(ParseRecord);
+}
+
+<ParseType>{BR}+("is"){BR}+|{BR}+("is"){B}*"--" { // found a new function  in an architecture ?
+  addText(yytext,yyleng);
+  lineCount();
+  QCString ttt;
+  bool bb=TRUE;
+  getBufText(ttt,0);
+  if (ttt.contains("--"))
+  { 
+    unput('-');unput('-'); 
+    VhdlDocGen::deleteCharRev(ttt,'-');
+    VhdlDocGen::deleteCharRev(ttt,'-');
+  }
+  if (ttt.contains('(') != ttt.contains(')'))
+  {
+    bb=FALSE;
+  }
+  bool ss = VhdlDocGen::isFunctionProto(ttt);
+  //printf("VhdlDocGen::isFunctionProto(%s)=%d\n",ttt.data(),ss);
+  if (ss && bb)
+  {
+    bufferClear();
+    addText(ttt.data(),ttt.length());
+    functionEntry=0;
+    //eFuncBody=new Entry;
+    ::parseFunctionProto();
+#if 0
+
+    EntryListIterator eli(*eFuncBody->children());
+    Entry *rrt=eli.current();
+
+    if (current && (current->spec==VhdlDocGen::ARCHITECTURE && rrt))
+    {
+      Entry *ep=new Entry(*rrt);
+      addSubEntry(current,ep);
+      isBody=1;
+    }
+    if (rrt) 
+    {
+      Entry *ef=VhdlDocGen::findFunction(current_root,rrt);
+      if (ef) 
+      { 
+	ef->bodyLine=iFuncLine;
+	functionEntry=ef;
+      }
+      else if ((current->spec==VhdlDocGen::PACKAGE_BODY))//VhdlDocGen::Package_Body))
+      {
+	Entry *ep=new Entry(*rrt);
+	addSubEntry(current,ep);
+	ep->bodyLine=iFuncLine;
+	functionEntry = ep;
+      }
+    }
+    delete eFuncBody;
+    eFuncBody=0;
+#endif
+  }
+  bufferClear();  
+  BEGIN(ParseType);
+}
+
+
+<ParseType>[^;()\t ] {
+  lineCount();      
+  addText(yytext,yyleng); 
+  BEGIN(ParseType);
+}
+
+<ParseType>{BRACEOPEN} {
+  lineCount();
+  bropen++;
+  addText(yytext,yyleng);
+  BEGIN(ParseType);
+}
+
+<ParseType>{BRACECLOSE} {
+  lineCount();
+  bropen--;
+  addText(yytext,yyleng);
+  if (bropen==0 && scantype==2) // process
+  {
+    ::parseProcessProto();
+    BEGIN(ParseProcess);
+  } // if
+  else
+  {
+    BEGIN(ParseType);
+  }
+}
+
+
+<ParseType>{ENDE}|{ENDFUNC} { // found end of function|process
+  QRegExp regg("[\\s;]");
+  lineCount();
+  QCString tt(yytext);
+  tt=tt.lower();
+  QStringList ql=QStringList::split(regg,tt,FALSE);
+  int index=ql.findIndex(QCString("if"))+1;
+  index+=ql.findIndex(QCString("case"))+1;
+  index+=ql.findIndex(QCString("loop"))+1;
+  index+=ql.findIndex(QCString("generate"))+1;
+  bufferClear();
+  if (index==0)
+  {
+    if (isFunc)
+    {
+      Entry* pFunc=getEntryAtLine(current_root,iFuncLine);
+      if (pFunc && pFunc->section==Entry::FUNCTION_SEC)
+      {
+	pFunc->endBodyLine=yyLineNr;
+      }
+      isFunc=0;
+      BEGIN(Start);
+    }
+  }
+}
+
+<ParseFunc>[^;()] {
+  // eat process body
+  lineCount();
+  BEGIN(ParseFunc);
+ }
+
+<ParseFunc>{ENDE3} {
+  QRegExp regg("[\\s;]");
+  lineCount();
+  QCString tt(yytext);
+  tt=tt.lower();
+  QStringList ql=QStringList::split(regg,tt,FALSE);
+  int index=ql.findIndex(QCString("if"))+1;
+  index+=ql.findIndex(QCString("case"))+1;
+  index+=ql.findIndex(QCString("loop"))+1;
+  index+=ql.findIndex(QCString("generate"))+1;
+  bufferClear();
+  if (index==0 && isFunc)
+  {
+    Entry* pFunc=getEntryAtLine(current_root,iFuncLine);
+    if (pFunc && pFunc->section==Entry::FUNCTION_SEC)
+    {
+      pFunc->endBodyLine=yyLineNr;
+    }
+    isFunc=0;
+    BEGIN(Start);
+  }
+}
+
+<ParseType>";" {
+  lineCount();
+  addText(yytext,yyleng);    
+  if (bropen==0 && !(isFunc==1 && isBody==1) )
+  {
+    if (isFunc)
+    {
+      parseFunctionProto();
+      bufferClear();
+      if (lastCompound && lastCompound->spec==VhdlDocGen::PACKAGE) 
+      {
+        isFunc=0;
+        BEGIN(Start);
+      }
+      else
+      {
+        BEGIN(ParseFunc); 
+      }
+    }//if
+    else
+    {
+      QCString qcs;
+      getBufText(qcs,0);
+      qcs=qcs.stripWhiteSpace();
+      current->section=Entry::VARIABLE_SEC;
+      current->type+=qcs.data();  
+
+      if ((current->spec==VhdlDocGen::SIGNAL   || 
+	   current->spec==VhdlDocGen::CONSTANT || 
+	   current->spec==VhdlDocGen::TYPE     || 
+	   current->spec==VhdlDocGen::SUBTYPE  ||
+	   current->spec==VhdlDocGen::SHAREDVARIABLE
+	  ) &&  
+	  qcs.stripPrefix(","))
+      {
+	QList<QCString> ql;
+	ql.setAutoDelete(TRUE);
+	QCString buffer;
+	if (current->spec==VhdlDocGen::SUBTYPE || 
+	    current->spec==VhdlDocGen::TYPE
+	   )
+	{
+	  VhdlDocGen::getSigTypeName(ql,qcs.data(),buffer);
+	}
+	else
+	{
+	  VhdlDocGen::getSigName(ql,qcs.data(),buffer);
+	}
+	QCString doc = current->doc;
+	QCString brief = current->brief;
+	if (ql.count()>0) 
+	{
+	  for (uint j=1;j<ql.count();j++)
+	  {
+	    Entry *ppt = new Entry;
+            initEntry(ppt);
+	    ppt->type     += ql.at(0)->data();  
+	    ppt->section   = Entry::VARIABLE_SEC;
+	    ppt->spec      = current->spec;        
+	    ppt->name     += ql.at(j)->data();
+	    ppt->bodyLine  = yyLineNr;
+	    ppt->startLine = yyLineNr;
+	    ppt->brief     = brief;
+	    ppt->doc       = doc;
+	    if (lastCompound)
+	    {
+	      lastCompound->addSubEntry(ppt);
+	    }
+	    else
+	    {
+	      current->addSubEntry(ppt);
+	    }
+	  }
+	  current->type=ql.at(0)->data(); 
+	  ql.clear();   
+	}
+      }
+      if (lastCompound)
+      {
+	lastCompound->addSubEntry(current);
+	current = new Entry;
+	initEntry(current);
+      }
+      else
+      {
+	newEntry();
+      }
+      isFunc=0;
+      bufferClear();
+      BEGIN(Start);
+    }
+  }
+  else
+  {
+    BEGIN(ParseType);
+  }
+}
+
+<ParseType>{TEXTT} {
+  lineCount();
+  BEGIN(ParseType);
+}
+
+<ParseType>{BR}* {
+  lineCount();
+  addText(yytext,yyleng);
+  BEGIN(ParseType);
+}
+
+<FindEntityName>{NAME} {    // found name of an entity/architecture/package
+  lineCount();
+  QCString qcs(yytext);
+  qcs=qcs.stripWhiteSpace();
+  qcs=qcs.lower();
+  if (strcmp(qcs.data(),"body")==0) // found package body
+  {
+    current->spec=VhdlDocGen::PACKAGE_BODY;
+    current->section=Entry::CLASS_SEC;
+    current->protection=Protected;
+    current->name+=QCString("_");
+    isBody=1;
+    BEGIN(FindName);
+  }
+  else if (scantype==1) // found a component
+  {
+    QCString qq(yytext);
+    qq=qq.stripWhiteSpace();
+    //qq=qq.lower();
+
+    current->name=qq;
+    if (lastCompound)
+    {
+      if (lastCompound->spec==VhdlDocGen::PACKAGE)
+      {
+        if (!VhdlDocGen::foundInsertedComponent(qq,lastCompound))
+        {  
+	  BaseInfo *bb=new BaseInfo(qq,Private,Normal);
+	  lastCompound->extends->append(bb);    
+        }
+      } 
+
+      lastCompound->addSubEntry(current);
+      current = new Entry;
+      initEntry(current);
+    }
+    else
+    {
+      newEntry();
+    }
+    BEGIN(Start);
+  } 
+  else
+  {
+    QCString qq(yytext);
+    qq=qq.stripWhiteSpace();
+    current->name=qq;
+    newEntry();
+    //QCString qreal=QCString(yytext);
+    BEGIN(Start);
+  }
+}
+
+<Start>{B}*("generic"|"port"){BR}*[(]+ { // found generic|port in entity
+    QCString genp(yyleng+1);
+    deleteSpecChars(yytext,genp.data());
+    VhdlDocGen::deleteCharRev(genp,'(');
+
+    if (stricmp(genp.data(),"port" )==0)
+    {
+      genPort=1;
+    }
+    else 
+    {
+      genPort=0;
+    }
+
+    bropen=1;
+    bufferClear();
+    lineCount();
+    BEGIN(FindSigName);
+}
+
+<FindSigName>{BRACECLOSE} { 
+    lineCount();
+    bropen--;
+    addText(yytext,yyleng); 
+    if (bropen==0)
+    {
+      bufferClear();
+      BEGIN(Start);
+    }
+    else
+    {
+      BEGIN(FindSigName);
+    }
+}
+
+<FindSigName>{LABELID} {  // found signals in entity
+  QCString line(yytext);
+
+  // note that line can be something like:
+  // "var1, var2, var3 : in std_logic_vector(8 downto 0); --! Some comment"
+
+  // but also
+  // "var4 --! Some comment
+  // );"
+  // which marks the end of a port
+
+  // and also
+  // "-- Some comment
+  // var1 : in std_logic;"
+
+  //printf("--> labelid='%s'\n",line.data());
+  QStringList ql;
+  QCString comment;
+  int openCount=line.contains('(');
+  int closeCount=line.contains(')');
+  int semi = line.find(';');
+  int pos  = line.find("--");
+  int pos1 = line.find("--!");
+  if (pos!=-1 && pos<pos1) // strip normal comment before special one
+  {
+    line = line.remove(pos,pos1-pos);
+  }
+  //printf("=> signal: line='%s'\n",line.data());
+  if (semi!=-1 && pos!=-1)
+  {
+    int eol = line.findRev('\n');
+    //printf("pos=%d eol=%d\n",pos,eol);
+    if (eol>=pos+2)
+    {
+      QRegExp re("\\n[\\s]*--!"); // comment continuation
+      comment=line.mid(pos+2,eol-pos-2);
+      //printf("Comment: '%s'\n",comment.data());
+      int p,l;
+      while ((p=re.match(comment,0,&l))!=-1)
+      {
+	comment.remove(p,l);
+      }
+      line=line.left(pos)+line.right(line.length()-eol);
+    }
+    else
+    {
+      comment=line.mid(pos+2);
+      line=line.left(pos);
+    }
+    comment.stripWhiteSpace();
+    // must subtract "(" and ")" in comments because they are used for determining the
+    // end of a port/generic construct
+    openCount-=comment.contains('(');
+    closeCount-=comment.contains(')');
+    if (!comment.stripPrefix("!")) // not a special comment
+    {
+      comment.resize(0);
+    }
+  }
+  else
+  {
+    //printf("no ; or --: pos=%d semi=%d\n",pos,semi);
+  }
+  int diff=openCount-closeCount;
+  if (diff<0)
+  {
+    VhdlDocGen::deleteCharRev(line,')');
+  }
+
+  if (scantype!=1) // not a component
+  {  
+    addText(yytext,yyleng);
+    addSignals(line,yyLineNr,lastEntity,comment);
+  } 
+
+  lineCount();
+
+  if ((bropen+openCount-closeCount)==0)
+  {
+    bufferClear();
+    BEGIN(Start);
+  }
+}
+
+
+<FindSigName>{BRACEOPEN} { 
+  lineCount();
+  bropen++;
+  addText(yytext,yyleng);
+}
+
+
+<FindSigName>{CR}        { 
+  lineCount();
+  addText(yytext,yyleng);
+  //BEGIN(FindSigName);
+}
+
+
+<*>^{B}*("for ")[^;]* {
+  //printf("\n found for[%s] [%d]",yytext,yyLineNr);
+  lineCount();
+}
+
+<*>{DIGITS}                {   // found digit
+  addText(yytext,yyleng);
+  lineCount();
+}
+
+<*>{STRING_LITERAL} {
+  // Make sure string literals get transfered to the output
+  // We have to match these because the comment characters (--)
+  // can exist inside a string literal.
+  // We shouldn't have to call lineCount because newlines
+  // are not allowed inside string literals
+  addText(yytext,yyleng);
+}
+
+   /*
+<*>{BR}*"--!"{B}*"@}"    { // end group
+  if (current) 
+  {
+    Entry *pg=new Entry;  
+    addSubEntry(current,pg);
+    pg->startLine=yyLineNr;
+    pg->name="endgroup";
+  }
+  lineCount();
+}
+
+<*>{BR}*"--!"{B}*"@{"     {  // start group
+  if (current) 
+  {
+    Entry *pg=new Entry;  
+    addSubEntry(current,pg);
+    pg->startLine=yyLineNr;
+    pg->name="startgroup";
+  }
+  lineCount();
+}
+   */
+
+<*>{BR}*"--!"[^{}\n][^\n]*\n/{B}*"--!" { // multi line comment
+  if (iDocLine==-1) iDocLine=yyLineNr;
+  // signal clk :in std_logic; --!@brief global clock
+  // --!@brief  global reset
+  // signal reset:in std_logic;
+  // these two comments are detected as a multi line comment
+  QCString qc(yytext);
+  int len=qc.contains('\n')+yyLineNr-1;
+
+  if (YY_START!=Comment) // Start of the comment block
+  {
+    bufferClear();
+    iTextCounter=0;
+    startComment=yyLineNr;
+    g_lastCommentContext=YY_START;
+  }
+
+  Entry* pTemp=getEntryAtLine(current_root,len);
+  if (pTemp)
+  { // found one line comment, add it to the entry on this line
+    pTemp->briefLine=yyLineNr;
+    pTemp->brief+=yytext;
+    VhdlDocGen::prepareComment(pTemp->brief);
+  }
+  else 
+  {
+    addText(yytext,yyleng);
+  }
+  lineCount();
+  BEGIN(Comment);
+}
+
+<Comment>^{B}*"--!"[^\n]* {
+  if (iDocLine==-1) iDocLine=yyLineNr;
+  addText(yytext,yyleng);
+  lineCount();
+}
+
+<Comment>.|\n {
+  // found end of comment block
+  QCString qcs;
+  getBufText(qcs,iTextCounter);
+  VhdlDocGen::prepareComment(qcs);
+  handleCommentBlock(qcs,FALSE);
+  bufferClear();
+  unput(*yytext);
+  BEGIN(g_lastCommentContext);
+}
+
+<*>"--!"[^\n]* { // one line comment
+  if (iDocLine==-1) iDocLine=yyLineNr;
+  QCString qcs(yytext);
+  int j=qcs.find("--!");
+  qcs=qcs.right(qcs.length()-3-j);
+  //printf("--> handleCommentBlock line %d\n",yyLineNr);
+  Entry* pTemp=getEntryAtLine(current_root,yyLineNr);
+  if (pTemp)
+  {
+    pTemp->briefLine=yyLineNr;
+    pTemp->brief+=qcs;
+    iDocLine=-1;
+  }
+  else
+  {
+    handleCommentBlock(qcs,TRUE);
+  }
+  //printf("--> end: handleCommentBlock line %d\n",yyLineNr);
+  bufferClear();
+} 
+
+<*>{COMMENT} {
+}
+
+<*>\n                    {
+  lineCount();
+  addText(yytext,yyleng);
+  //         printf("\n new-line [%d]",yyLineNr);
+  BEGIN(Start);
+}
+
+<*>{NAME} {
+  addText(yytext,yyleng);
+  lineCount();
+}
+
+<*>{B}*	{
+  addText(yytext,yyleng);
+  lineCount();
+}
+
+<*>.                    {
+  addText(yytext,yyleng);
+  lineCount();
+}
+
+
+%%
+
+static void initEntry(Entry *e)
+{
+  e->fileName = yyFileName;
+  initGroupInfo(e);
+}
+
+static void newEntry()
+{
+  // Add only enties/architectures/packages to root 
+  // and signals to  classes where they were found
+  // ENTITY dlatch_93 IS -- VHDL'93-Syntax !!!
+  //      PORT (d, clk : IN bit;
+  //      q, qbar : OUT bit);
+  //      GROUP path IS (SIGNAL, SIGNAL);
+  //      GROUP d_to_q : path (d, q);
+  //      ATTRIBUTE propagation : time;
+  //  END dlatch_93;
+
+  if (current->spec==VhdlDocGen::ENTITY || 
+      current->spec==VhdlDocGen::PACKAGE || 
+      current->spec==VhdlDocGen::ARCHITECTURE || 
+      current->spec==VhdlDocGen::PACKAGE_BODY)
+  {
+    current_root->addSubEntry(current);
+  }
+  else
+  {
+    if (lastCompound) 
+    {
+      lastCompound->addSubEntry(current);
+    }
+    else
+    {
+      if (lastEntity)
+      {
+	lastEntity->addSubEntry(current);
+      }
+      else 
+      {
+	current_root->addSubEntry(current); // should not happen!
+      }
+    }
+  }
+  previous = current;
+  current = new Entry ;
+  initEntry(current);
+}
+
+static void handleCommentBlock(const QCString &doc,bool brief)
+{
+  int position=0;
+  bool needsEntry=FALSE;
+  Protection protection=Public;
+  int lineNr = iDocLine;
+  if (brief) 
+    current->briefLine = iDocLine; 
+  else 
+    current->docLine = iDocLine;
+
+  //printf("parseCommentBlock %p [%s]\n",current,doc.data());
+  while (parseCommentBlock(
+	g_thisParser,
+	current,
+	doc,        // text
+	yyFileName, // file
+	lineNr,     // line of block start
+	brief, 
+	docBlockAutoBrief,
+	FALSE,
+	protection,
+        position,
+        needsEntry
+        )
+     ) 
+  {
+    //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
+    if (needsEntry) newEntry();
+  }
+  if (needsEntry)
+  {
+    newEntry();
+  }
+
+  if (docBlockTerm)
+  {
+    unput(docBlockTerm);
+    docBlockTerm=0;
+  }
+  iDocLine=-1;
+}
+
+#if 0
+/*!
+ * adds grouping to the entries
+ */
+static void mergeGrouping(const Entry* ce,int)
+{
+  EntryListIterator eli(*ce->children());
+  Entry *rt;
+  for (;(rt=eli.current());++eli)
+  {
+    if (rt->section==Entry::GROUPDOC_SEC)
+    {
+      if (openGroups)
+      {
+	QCString tt=(QCString)qrl.last();
+	if (!tt.isEmpty()) 
+	{
+	  rt->groups->append(new Grouping(tt.data(),Grouping::GROUPING_LOWEST));
+	}
+      }
+      qrl.append(rt->name);    
+    }
+
+    if ((strcmp(rt->name.data(),"endgroup")==0) && !qrl.isEmpty())
+    {
+      qrl.remove((QCString)qrl.last());
+      openGroups--;
+    }
+
+    if ((strcmp(rt->name.data(),"startgroup")==0))
+    {
+      openGroups++;
+    }
+
+    if (rt->section!=Entry::GROUPDOC_SEC && openGroups && !qrl.isEmpty())
+    {
+      rt->groups->append(new Grouping(qrl.last().data(),Grouping::GROUPING_LOWEST));
+    }
+
+    mergeGrouping(rt,openGroups);
+  }
+}
+#endif
+
+/*
+ * adds the library|use statements to the next class (entity|package|architecture|package body
+ * library ieee
+ * entity xxx
+ * .....
+ * library
+ * package
+ * enity zzz
+ * .....
+ * and so on..
+ */
+
+void mapLibPackage(const Entry* ce)
+{
+  Entry *lastComp=0;
+  while (TRUE)
+  {
+    bool found = FALSE;
+    Entry *rt=0;
+    //const QList<Entry> *epp=ce->children();
+    EntryListIterator eli(*ce->children());
+    EntryListIterator eli1=eli;
+    for (;(rt=eli.current()),eli1=eli;++eli)
+    {
+      if (rt->spec==VhdlDocGen::LIBRARY || rt->spec==VhdlDocGen::USE)
+        // top level library or use statement
+      {
+	Entry *temp=0;
+	for (;(temp=eli1.current());++eli1) // find next entity
+	{
+	  if (temp->spec==VhdlDocGen::ENTITY || temp->spec==VhdlDocGen::PACKAGE || temp->spec==VhdlDocGen::ARCHITECTURE || temp->spec==VhdlDocGen::PACKAGE_BODY)
+	  {
+	    Entry *ee=new Entry(*rt); //append a copy to entries sublist
+	    temp->addSubEntry(ee);
+	    found=TRUE;
+	    rt->spec=-1; //nullify entry
+	    rt->section=0;
+	    lastComp=temp;
+	    break;
+	  }
+	}//for
+	if (lastComp && rt->spec!=-1)
+	{
+	  Entry *ee=new Entry(*rt); //append a copy to entries sublist
+	  lastComp->addSubEntry(ee);
+	  found=TRUE;
+	  rt->spec=-1; //nullify entry
+	  rt->section=0;
+	}
+      }//if
+    }//for
+    if (!found) // nothing left to do
+    {
+      return; 
+    }
+  }//while
+}//MapLib
+
+#if 0
+/*!
+ * merges a brief descriptions to the next entry
+ */
+void mergeBrief(const Entry* ce)
+{
+  EntryListIterator eli(*ce->children());
+  Entry *rt;
+  for (;(rt=eli.current());++eli)
+  {
+
+    if (found && (!eMerge.brief.isEmpty() || !eMerge.doc.isEmpty()))
+    {
+      rt->doc+=eMerge.doc.data();
+      rt->docLine=eMerge.docLine;
+      rt->brief+=eMerge.brief.data();
+      rt->briefLine=eMerge.briefLine;
+      found=FALSE;
+    }
+
+    if ((strcmp(rt->name.data(),"string")==0))
+    {
+      eMerge.reset();
+      eMerge.doc+=rt->doc.data();
+      eMerge.docLine=rt->docLine;
+      eMerge.brief+=rt->brief.data();
+      eMerge.briefLine=rt->briefLine;
+
+      found=TRUE;
+    }
+    MergeBrief(rt);
+  }
+}
+#endif
+
+
+
+void vhdlscanFreeScanner()
+{
+#if defined(YY_FLEX_SUBMINOR_VERSION)
+  if (g_lexInit)
+  {
+    vhdlscanYYlex_destroy();
+  }
+
+  if (g_buf)
+  {
+    free(g_buf);
+  }
+
+  g_buf=0;
+#endif
+
+}
+
+void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root)
+{
+  inputFile.setName(fileName);
+  //uint jfile=inputFile.size();
+  ::parserInit(); 
+  yyFileName=QCString(fileName);
+  groupEnterFile(fileName,yyLineNr);
+  g_thisParser = this;
+  g_inputFromFile = FALSE;
+  inputPosition = 0;
+  assert(root!=0);
+  inputString=fileBuf;
+  current_root  = root;
+  global_root   = root;
+  current=new Entry;
+  initEntry(current);
+  //current_root->name=QCString("XXX"); // dummy name for root
+  if (!inputFile.open(IO_ReadOnly))
+  {
+    err("\n\n could not open file: %s !!\n\n",yyFileName.data());
+    return ;
+  }
+
+  if (g_lexInit)
+  {
+    vhdlscanYYrestart(vhdlscanYYin);     
+    unput(' ');
+    BEGIN(Start);
+  }
+  vhdlscanYYlex();
+  g_lexInit=TRUE;
+
+  free(g_buf);
+  g_buf=0;
+
+  delete current;
+  current=0;
+
+  groupLeaveFile(yyFileName,yyLineNr);
+  inputFile.close();
+
+  //mergeBrief(current_root);
+  //mergeGrouping(current_root,0);
+  mapLibPackage(current_root);
+}
+
+
+void VHDLLanguageScanner::parsePrototype(const char *text)
+{
+  // will be called when a \fn command is found in a comment block
+
+  QCString ss,ret;
+  bool sem=FALSE;
+  bool func=FALSE;
+  QList<Argument> qs;
+  qs.setAutoDelete(TRUE);
+  VhdlDocGen::parseFuncProto(text,qs,ss,ret,TRUE);
+  int count=qs.count();
+  if (stricmp(ret.data(),"function")==0)
+  {
+    func=TRUE;
+  }
+  if (count<1 && !func)
+  {
+    return;
+  }
+  Entry *pp = new Entry;
+  initEntry(pp);
+  pp->name=ss.stripWhiteSpace();
+  pp->args+='(';
+  for (int j=0;j<count;j++)
+  {
+    if (sem)
+    {
+      pp->args+=','; 
+    }
+
+    Argument *ars=(Argument*)(qs.at(j));
+    Argument *arg=new Argument;
+    arg->attrib = ars->attrib;
+    arg->name = ars->name;
+    arg->type = ars->type;
+    pp->args+=ars->name.data();
+    pp->args+=" ";
+    pp->args+=ars->type.data();
+    pp->argList->append(arg);
+    sem=TRUE;
+  }
+  pp->args+=')';
+
+  if (!ret.isEmpty()) 
+    pp->spec=VhdlDocGen::FUNCTION;
+  else
+    pp->spec=VhdlDocGen::PROCEDURE;
+
+  if (pp->section == Entry::MEMBERDOC_SEC && pp->args.isEmpty())
+    pp->section = Entry::VARIABLEDOC_SEC;
+
+  pp->type=ret;
+  current_root->addSubEntry(pp);
+}
+
+void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
+    const char *scopeName,
+    const QCString &input,
+    bool isExampleBlock,
+    const char *exampleName,
+    FileDef *fileDef,
+    int startLine,
+    int endLine,
+    bool inlineFragment,
+    MemberDef *memberDef
+    )
+{
+  ::parseVhdlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,fileDef,startLine,endLine,inlineFragment,memberDef);
+}
+