--- /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);
+}
+