1 /******************************************************************************
3 * Copyright (C) 1997-2015 by Dimitri van Heesch.
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.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
15 /******************************************************************************
16 * Parser for syntax highlighting and references for vhdl subset
18 * supports VHDL-87/93/2008
19 ******************************************************************************/
20 %option never-interactive
21 %option case-insensitive
22 %option prefix="vhdlcodeYY"
34 #include <qcstringlist.h>
39 #include "outputlist.h"
41 #include "membername.h"
42 #include "searchindex.h"
43 #include "vhdldocgen.h"
44 #include "arguments.h"
51 #define YY_NO_UNISTD_H 1
53 // Toggle for some debugging info
54 //#define DBG_CTX(x) fprintf x
55 #define DBG_CTX(x) do { } while(0)
58 /* -----------------------------------------------------------------
62 // ----------------- <vhdl> ----------------------------------
64 //static bool isPackBody=FALSE;
65 //static bool isStartMap;
66 static bool isFuncProto=FALSE;
67 static bool isComponent=FALSE;
68 static bool isPackageBody=FALSE;
69 static bool isProto = FALSE;
70 static bool g_startCode = FALSE;
71 static QCString g_PrevString;
72 static QCString g_CurrClass;
73 static QDict<QCString>g_vhdlKeyDict;
74 static QCString g_tempComp;
75 static QCString g_PortMapComp;
76 static MemberDef *g_vhdlMember;
77 static QCString g_FuncProto;
79 //-----------------------------------------------------------
81 static CodeOutputInterface * g_code;
82 static QCString g_parmType;
83 static QCString g_parmName;
84 static const char * g_inputString; //!< the code fragment as text
85 static int g_inputPosition; //!< read offset during parsing
86 static int g_inputLines; //!< number of line in the code fragment
87 static int g_yyLineNr; //!< current line number
88 static bool g_needsTermination;
89 static Definition *g_searchCtx;
91 static bool g_exampleBlock;
92 static QCString g_exampleName;
93 static QCString g_exampleFile;
95 static QCString g_classScope;
97 static bool g_CurrARCH = FALSE;
99 static FileDef * g_sourceFileDef;
100 static Definition * g_currentDefinition;
101 static MemberDef * g_currentMemberDef;
102 static bool g_includeCodeFragment;
103 static const char * g_currentFontClass;
105 static bool g_lexInit = FALSE;
106 static int g_braceCount=0;
109 static void writeFont(const char *s,const char* text);
110 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
111 static bool writeColoredWord(QCString& word );
112 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE, const char *curr_class=0);
113 static void endFontClass();
114 static void startFontClass(const char *s);
115 //-------------------------------------------------------------------
118 static void setCurrentDoc(const QCString &anchor)
120 if (Doxygen::searchIndex)
124 Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
128 Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
133 static bool checkVhdlString(QCString &name)
135 if (name.isEmpty()) return FALSE;
136 static QRegExp regg("[\\s\"]");
138 int len=name.length();
139 if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
141 QCStringList qrl=QCStringList::split(regg,name);
142 if (VhdlDocGen::isNumber(qrl[0]))
144 g_code->codify("\"");
145 startFontClass("vhdllogic");
146 QCString mid=name.mid(1,len-2); //" 1223 "
147 g_code->codify(mid.data());
149 g_code->codify("\"");
153 startFontClass("keyword");
154 g_code->codify(name.data());
160 if (VhdlDocGen::isNumber(name))
162 startFontClass("vhdllogic");
163 g_code->codify(name.data());
170 static void addToSearchIndex(const char *text)
172 if (Doxygen::searchIndex)
174 Doxygen::searchIndex->addWord(text,FALSE);
179 /*! start a new line of code, inserting a line number if g_sourceFileDef
180 * is TRUE. If a definition starts at the current line, then the line
181 * number is linked to the documentation of that definition.
183 static void startCodeLine()
185 //if (g_currentFontClass) { g_code->endFontClass(); }
188 //QCString lineNumber,lineAnchor;
189 //lineNumber.sprintf("%05d",g_yyLineNr);
190 //lineAnchor.sprintf("l%05d",g_yyLineNr);
191 // if ((g_yyLineNr % 500) == 0)
192 // fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
193 Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
194 //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
195 if (!g_includeCodeFragment && d)
197 g_currentDefinition = d;
198 g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
199 if (!g_tempComp.isEmpty() && g_currentMemberDef )
201 //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
202 QCString nn=g_currentMemberDef->name();
203 MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
206 g_currentMemberDef=mdeff;
210 g_parmType.resize(0);
211 g_parmName.resize(0);
213 lineAnchor.sprintf("l%05d",g_yyLineNr);
214 if (g_currentMemberDef)
216 g_code->writeLineNumber(g_currentMemberDef->getReference(),
217 g_currentMemberDef->getOutputFileBase(),
218 g_currentMemberDef->anchor(),g_yyLineNr);
219 setCurrentDoc(lineAnchor);
221 else if (d->isLinkableInProject())
223 g_code->writeLineNumber(d->getReference(),
224 d->getOutputFileBase(),
226 setCurrentDoc(lineAnchor);
231 g_code->writeLineNumber(0,0,0,g_yyLineNr);
234 g_code->startCodeLine(g_sourceFileDef);
236 if (g_currentFontClass)
238 g_code->startFontClass(g_currentFontClass);
242 static void endCodeLine()
245 g_code->endCodeLine();
248 static void nextCodeLine()
252 endCodeLine(); // </div>
254 const char *fc = g_currentFontClass;
255 if (g_yyLineNr<g_inputLines)
257 g_currentFontClass = fc;
258 startCodeLine(); //<div>
262 /*! writes a word to the output.
263 * If curr_class is defined, the word belongs to a class
264 * and will be linked.
267 static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
271 QCString tclass(curr_class);
273 if (ttt.isEmpty()) return;
274 for (unsigned int j=0;j<ttt.length();j++)
277 if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
281 if (!writeColoredWord(temp)) // is it a keyword ?
283 //if (VhdlDocGen::findKeyWord(temp))
284 // writeFont("vhdlkeyword",temp.data());
285 //printf("writeWord: %s\n",temp.data());
286 if (!tclass.isEmpty())
290 generateMemLink(*g_code,tclass,temp);
294 generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class);
299 if (!checkVhdlString(temp))
300 g_code->codify(temp.data());
321 if (!writeColoredWord(temp))
323 if (!tclass.isEmpty())
327 generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left);
331 generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class);
336 QCString qc(temp.data());
337 if (VhdlDocGen::isNumber(qc)){
338 startFontClass("vhdllogic");
339 g_code->codify(temp.data());
343 g_code->codify(temp.data());
350 /*! write a code fragment `text' that may span multiple lines, inserting
351 * line numbers for each line.
353 static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,bool comment=FALSE)
356 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
357 const char *p=text,*sp=p;
363 while ((c=*p++) && c!='\n') {}
368 line = line.left((int)(p-sp)-1);
370 //g_code->codify(sp);
373 writeFont("comment",line.data());
377 writeWord(line,cl,classlink);
384 writeFont("comment",sp);
386 writeWord(sp,cl,classlink);
392 /*! writes a link to a fragment \a text that may span multiple lines, inserting
393 * line numbers for each line. If \a text contains newlines, the link will be
394 * split into multiple links with the same destination, one for each line.
396 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
400 static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
401 TooltipManager::instance()->addTooltip(d);
402 QCString ref = d->getReference();
403 QCString file = d->getOutputFileBase();
404 QCString anchor = d->anchor();
406 if (!sourceTooltips) // fall back to simple "title" tooltips
408 tooltip = d->briefDescriptionAsTooltip();
411 char *p=(char *)text;
416 while ((c=*p++) && c!='\n') {}
421 // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
422 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
427 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
433 static void setParameterList(MemberDef *md)
435 g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
436 ArgumentList *al = md->argumentList();
438 ArgumentListIterator ali(*al);
440 for (ali.toFirst();(a=ali.current());++ali)
442 g_parmName = a->name.copy();
443 g_parmType = a->type.copy();
444 int i = g_parmType.find('*');
445 if (i!=-1) g_parmType = g_parmType.left(i);
446 i = g_parmType.find('&');
447 if (i!=-1) g_parmType = g_parmType.left(i);
448 g_parmType.stripPrefix("const ");
449 g_parmType=g_parmType.stripWhiteSpace();
450 // g_theVarContext.addVariable(g_parmType,g_parmName);
455 /*! writes a link to a function or procedure
458 static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
461 //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
462 QCString memberName=mdef->name();
464 if (mdef && mdef->isLinkable()) // is it a linkable class
466 writeMultiLineCodeLink(ol,mdef,mdef->name());
467 addToSearchIndex(memberName);
470 codifyLines(memberName.data());
471 addToSearchIndex(memberName);
472 } // generateFuncLink
475 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
477 if (memberName.isEmpty()) return;
478 if (clName.isEmpty())
480 codifyLines(memberName.data());
485 QCString className=clName;
489 //bool isLocal=FALSE;
491 md=VhdlDocGen::findMember(className,memberName);
492 ClassDef *po=VhdlDocGen::getClass(className.data());
494 if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS)
496 QCString temp=className;//.stripPrefix("_");
497 temp.stripPrefix("_");
498 md=VhdlDocGen::findMember(temp,memberName);
501 if (md && md->isLinkable()) // is it a linkable class
503 writeMultiLineCodeLink(ol,md,memberName);
504 addToSearchIndex(memberName);
507 // nothing found, just write out the word
508 codifyLines(memberName.data());
509 addToSearchIndex(memberName);
513 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/, const char *curr_class)
515 QCString className=clName;
517 if (className.isEmpty()) return;
521 //bool isLocal=FALSE;
522 className.stripPrefix("_");
523 cd = getClass(className.data());
524 if (!cd && curr_class)
526 if (QCString(curr_class).contains(QRegExp("::"+QCString(clName)+"$"))) cd = getClass(curr_class);
531 //className.stripPrefix("_");
532 QCString temp(clName);
533 temp.stripPrefix("_");
534 if (cd && cd->isLinkable()) // is it a linkable class
536 //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
538 // temp=VhdlDocGen::getClassName(cd);
540 writeMultiLineCodeLink(ol,cd,temp);
541 addToSearchIndex(className);
544 Definition *d = cd->getOuterScope();
545 if (d && d->definitionType()==Definition::TypeClass)
555 // nothing found, just write out the word
557 addToSearchIndex(clName);
558 }// generateClasss or global link
561 /*! counts the number of lines in the input */
562 static int countLines()
564 const char *p=g_inputString;
570 if (c=='\n') count++;
572 if (p>g_inputString && *(p-1)!='\n')
573 { // last line does not end with a \n, so we add an extra
574 // line and explicitly terminate the line after parsing.
576 g_needsTermination=TRUE;
581 static void endFontClass()
583 if (g_currentFontClass)
585 g_code->endFontClass();
586 g_currentFontClass=0;
590 static void startFontClass(const char *s)
594 g_code->startFontClass(s);
595 g_currentFontClass=s;
598 static void writeFont(const char *s,const char* text)
600 if (s==0 || text==0) return;
601 //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
602 g_code->startFontClass(s);
603 g_code->codify(text);
604 g_code->endFontClass();
607 //----------------------------------------------------------------------------
609 static void appStringLower(QCString& qcs,const char* text)
614 qcs=qcs.stripWhiteSpace();
617 //static void appString(QCString& qcs,const char* text)
623 static QCString g_temp;
625 /* writes and links a port map statement */
626 static void codifyMapLines(const char *text)
633 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
634 const char *p=text; //,*sp=p;
640 while ((c=*p++) && c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
646 if (!g_temp.isEmpty()) wordCounter++;
648 if (!g_temp.isEmpty())
650 // different kinds of component instantiations
651 // xxx:yyy (generic/port) map(
652 // xxx:(entity/component/configuration) yyy (generic/port) map(
653 // xxx: entity yyy(zzz) (generic/port) map(
654 if (wordCounter==2 || wordCounter==3)
656 QCString q=g_temp.lower(); // consider (upper/lower) cases
657 if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
659 generateMemLink(*g_code,g_CurrClass,g_temp);
663 g_PortMapComp=g_temp;
664 generateClassOrGlobalLink(*g_code,g_temp);
669 generateMemLink(*g_code,g_CurrClass,g_temp);
673 codifyLines(ctemp.data());
680 * writes a function|procedure prototype and links the function|procedure name
683 static void writeFuncProto()
687 VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
691 codifyLines(g_FuncProto.data(),g_CurrClass.data());
694 QCStringList qlist=QCStringList::split(name,g_FuncProto);
695 QCString temp=qlist[0];
696 codifyLines(temp.data(),g_CurrClass.data());
697 g_FuncProto.stripPrefix(temp.data());
702 temp.stripPrefix("_");// _{package body name}
704 MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
708 generateFuncLink(*g_code,mdef);
709 g_FuncProto.stripPrefix(name.data());
710 codifyLines(g_FuncProto.data(),g_CurrClass.data());
714 codifyLines(g_FuncProto.data(),g_CurrClass.data());
718 /* writes a process prototype to the output */
720 static void writeProcessProto(){
721 codifyLines(g_FuncProto.data(),g_CurrClass.data());
722 g_vhdlKeyDict.clear();
723 }// writeProcessProto
725 /* writes a keyword */
727 static bool writeColoredWord(QCString& word )
729 QCString qcs=word.lower();
730 QCString *ss=VhdlDocGen::findKeyWord(qcs);
733 writeFont(ss->data(),word.data());
740 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
742 static int yyread(char *buf,int max_size)
745 while( c < max_size && g_inputString[g_inputPosition] )
747 *buf = g_inputString[g_inputPosition++] ;
759 NAME [a-z_A-Z][ a-z_A-Z0-9]*
760 FUNCNAME [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
761 ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
762 SPECSIGN [:;, +*&\/=<>'\t]*
763 DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
764 ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}*
765 ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}*
767 ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}{BN}+("is")
768 PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
770 END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
771 END2 [^a-zA-Z_]("end"){BN}*[;]
772 END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
773 END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
774 ENDEFUNC {END3}|{END4}|{END2}
776 KEYWORD ("of"|"new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
777 TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
778 FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
780 ARITHOP "+"|"-"|"/"|"*"|"%"|"/="|":="
781 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
782 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
783 BITOP "&"|"|"|"^"|"<<"|">>"|"~"
784 OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
786 PORT {B}*("port"){BN}*("(")
787 GENERIC {B}*("generic"){BN}*("(")
794 MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
795 MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
796 MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
797 MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
799 XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFIG"|"CONFIG_MODE"|"COOL_CLK"|"DATA_GATE"|"DCI_VALUE"|"DISABLE"|"DRIVE"|"DROP_SPEC"|"ENABLE"|"FAST"|"FEEDBACK"|"FILE"|"FLOAT"|"FROM-THRU-TO"|"FROM-TO"|"HBLKNM"|"HU_SET"|"INREG"|"IOB"|"IOBDELAY"|"IOSTANDARD"|"KEEP"|"KEEPER"|"LOC"|"LOCATE"|"LOCK_PINS"|"MAP"|"MAXDELAY"|"MAXPT"|"MAXSKEW"|"NODELAY"|"NOREDUCE"|"OFFSET"|"OPEN_DRAIN"|"OPT_EFFORT"|"OPTIMIZE"|"PERIOD"|"PIN"|"PRIORITY"|"PROHIBIT"|"PULLDOWN"|"PULLUP"|"PWR_MODE"|"REG"|"RLOC"|"RLOC_ORIGIN"|"RLOC_RANGE"|"SAVE NET"|"FLAG"|"SYSTEM_JITTER"|"TEMPERATURE"|"TIMEGRP"|"TIMESPEC"|"VOLTAGE"
826 writeFont("vhdlchar",vhdlcodeYYtext);
830 <Map>[^()\n,--]* { /* write and link a port map lines */
831 QCString tt(vhdlcodeYYtext);
832 VhdlDocGen::deleteAllChars(tt,',');
834 QCStringList ql=QCStringList::split(r,tt);
837 unsigned int index=0;
839 char cc=t1.at(index);
840 while (cc==' ' || cc=='\t')
847 if (index>=t1.size()) break;
852 s1=s1.stripWhiteSpace();
854 // if (!g_PortMapComp.isEmpty())
855 generateMemLink(*g_code,g_PortMapComp,s1);
856 while (index++<t1.size())
858 char cc=t1.at(index);
859 if (cc==' ' || cc=='\t')
872 while (cc==' ' || cc=='\t')
879 if (index>=t1.size()) break;
882 s2=s2.stripWhiteSpace();
883 if (!checkVhdlString(s2))
884 generateMemLink(*g_code,g_CurrClass,s2);
885 while (index++<t1.size())
887 if (t1.at(index)==' ')
895 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
901 codifyLines(vhdlcodeYYtext);
907 writeFont("vhdlchar",vhdlcodeYYtext);
914 <ParseFuncProto>{NAME} {
915 QCString tmp(vhdlcodeYYtext);
916 tmp=tmp.stripWhiteSpace();
917 appStringLower(g_PrevString,vhdlcodeYYtext);
918 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
919 if (!writeColoredWord(tmp))
921 generateMemLink(*g_code,g_CurrClass,tmp);
926 <ParseType>{STRING} {
927 QCString qcs(vhdlcodeYYtext);
928 VhdlDocGen::deleteAllChars(qcs,'"');
929 VhdlDocGen::deleteAllChars(qcs,' ');
930 if (VhdlDocGen::isNumber(qcs))
931 writeFont("vhdllogic",vhdlcodeYYtext);
933 writeFont("keyword",vhdlcodeYYtext);
937 g_FuncProto.append(vhdlcodeYYtext);
940 codifyLines(vhdlcodeYYtext);
947 g_FuncProto.append(vhdlcodeYYtext);
950 writeFont("keyword",vhdlcodeYYtext);
955 <ParseType>{ENDEFUNC} {
956 QRegExp regg("[\\s]");
957 QCString tt(vhdlcodeYYtext);
958 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
960 VhdlDocGen::deleteAllChars(tt,';');
961 tt.stripWhiteSpace();
962 QCStringList ql=QCStringList::split(regg,tt);
963 int index=ql.findIndex(QCString("if"))+1;
964 index+=ql.findIndex(QCString("case"))+1;
965 index+=ql.findIndex(QCString("loop"))+1;
966 index+=ql.findIndex(QCString("generate"))+1;
978 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
979 g_vhdlKeyDict.clear();
982 <ParseType>^{B}*("begin "|"begin") {
983 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
987 <ParseType>{SPECSIGN} {
988 g_FuncProto.append(vhdlcodeYYtext);
991 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
995 <ParseType>["_a-zA-Z0-9]* {
996 QCString val(vhdlcodeYYtext);
997 g_FuncProto.append(vhdlcodeYYtext);
998 appStringLower(g_PrevString,vhdlcodeYYtext);
1000 if (isFuncProto && g_braceCount==0)
1002 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
1007 if (!writeColoredWord(val))
1009 if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
1011 val=val.stripWhiteSpace();
1012 if (VhdlDocGen::isNumber(val))
1014 startFontClass("vhdllogic");
1015 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1019 generateMemLink(*g_code,g_CurrClass,val);
1023 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1030 <ParseType>{BRACEOPEN} {
1035 writeFont("vhdlchar",vhdlcodeYYtext);
1040 <ParseType>{BRACECLOSE} {
1045 writeFont("vhdlchar",vhdlcodeYYtext);
1047 if (g_braceCount==0 && !isProto)// && !isPackageBody)
1050 appStringLower(g_PrevString,vhdlcodeYYtext);
1061 <ClassesName>{FUNCNAME} {
1062 appStringLower(g_PrevString,vhdlcodeYYtext);
1063 g_CurrClass.resize(0);
1064 g_CurrClass.append(vhdlcodeYYtext);
1065 g_CurrClass=g_CurrClass.stripWhiteSpace();
1067 generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
1072 <ParseComponent>{BRACEOPEN} {
1074 g_code->codify(vhdlcodeYYtext);
1078 <ParseComponent>{BRACECLOSE} {
1080 g_code->codify(vhdlcodeYYtext);
1081 if (g_braceCount==0 && !isComponent)
1083 g_tempComp.resize(0);
1088 BEGIN(ParseComponent);
1092 <ParseComponent>{B}*"-" {
1093 if (strlen(vhdlcodeYYtext)>=2) // found text ?
1095 writeFont("keyword",vhdlcodeYYtext);
1099 writeFont("vhdlchar",vhdlcodeYYtext);
1103 <ParseComponent>{SPECSIGN} {
1104 codifyLines(vhdlcodeYYtext);
1109 <ParseComponent>"\n"|" " {
1110 codifyLines(vhdlcodeYYtext);
1113 <ParseComponent>{DIGITSS} {
1114 startFontClass("vhdllogic");
1115 codifyLines(vhdlcodeYYtext);
1119 <ParseComponent>{PORT} {
1120 codifyLines(vhdlcodeYYtext);
1125 <ParseComponent>{GENERIC} {
1126 codifyLines(vhdlcodeYYtext);
1130 <ParseComponent>[_a-zA_Z][_a-zA-Z0-9]* {
1131 QCString temp(vhdlcodeYYtext);
1132 appStringLower(g_PrevString,vhdlcodeYYtext);
1133 if (!checkVhdlString(temp)){
1134 if (!writeColoredWord(g_PrevString))
1136 generateMemLink(*g_code,g_tempComp,temp);
1141 <ParseComponent>{STRING} {
1142 QCString temp(vhdlcodeYYtext);
1143 if (!checkVhdlString(temp))
1144 codifyLines(vhdlcodeYYtext);
1148 <ParseProcessProto>[^()]* {
1149 g_FuncProto.append(vhdlcodeYYtext);
1154 <ParseProcessProto>{BRACEOPEN} {
1155 g_FuncProto.append(vhdlcodeYYtext);
1159 <ParseProcessProto>{BRACECLOSE} {
1160 g_FuncProto.append(vhdlcodeYYtext);
1162 if (g_braceCount==0)
1164 writeProcessProto();
1169 <ParsePackage>[^:;]* { //found package
1170 QCString temp(vhdlcodeYYtext);
1171 QCStringList strl=QCStringList::split(".",temp);
1174 QCString s1=strl[0];
1175 QCString s2=strl[1];
1176 QCString s3=strl[2];
1179 codifyLines(s1.data(),g_CurrClass.data());
1180 ClassDef *cd=VhdlDocGen::getPackageName(s2);
1183 generateClassOrGlobalLink(*g_code,s2.data());
1187 codifyLines(s2.data());
1189 codifyLines(s3.data());
1193 writeFont("keywordflow",vhdlcodeYYtext);
1198 <Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4} { // found port or generic map
1199 QCString tt(vhdlcodeYYtext);
1201 if (tt.contains(':',FALSE))
1214 QCString left=tt.left(j+1);
1215 codifyLines(left.data());
1216 tt=tt.right(tt.length()-j-1);
1217 left=VhdlDocGen::getIndexWord(tt.data(),0);
1218 if (!left.isEmpty())
1220 if (left.contains('('))
1222 j=left.find('(',FALSE);
1223 QCString name=left.left(j);
1224 generateClassOrGlobalLink(*g_code,name.data());
1226 name=tt.right(tt.length()-name.length());
1227 codifyLines(name.data());
1231 generateClassOrGlobalLink(*g_code,left.data());
1232 tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
1235 codifyLines(tt.data());
1241 if (tt.contains(':',FALSE))
1242 codifyMapLines(tt.data());
1244 codifyLines(tt.data());
1250 <Bases>^{B}*("component"){BN}+{FUNCNAME} { // found component
1251 appStringLower(g_PrevString,vhdlcodeYYtext);
1252 // writeFont("keywordflow",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1253 // writeFont("vhdlkeyword"," ");
1254 QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1255 temp=temp.stripWhiteSpace();
1256 VhdlDocGen::deleteAllChars(temp,'\n');
1258 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1261 //if (getClass(temp.data()))
1262 // generateClassOrGlobalLink(*g_code,temp.data());
1264 // generateMemLink(*g_code,g_CurrClass,temp);
1267 BEGIN(ParseComponent);
1272 <Bases>{ARCHITECTURE} { // found architecture
1273 g_PortMapComp.resize(0);
1274 // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1275 // writeFont("vhdlkeyword"," ");
1276 // writeFont("vhdlchar",VhdlDocGen::getIndexWord(vhdlcodeYYtext,1).data());
1277 // writeFont("vhdlkeyword"," ");
1278 // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,2).data());
1279 // writeFont("vhdlkeyword"," ");
1280 //QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1281 //temp=temp.stripWhiteSpace();
1283 //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1284 QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1287 temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1289 VhdlDocGen::deleteAllChars(temp,'\n');
1290 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1291 //generateClassOrGlobalLink(*g_code,temp.data());
1292 isPackageBody=FALSE;
1296 <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body
1297 QCString ss(vhdlcodeYYtext);
1298 QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
1299 QCStringList ql=QCStringList::split(temp,ss);
1301 codifyLines(ll.data(),g_CurrClass.data());
1302 temp=temp.stripWhiteSpace();
1304 generateClassOrGlobalLink(*g_code,temp.data());
1305 g_CurrClass.resize(0);
1309 // BEGIN(ClassesName);
1312 <Bases>{PROCESS} { // found process
1314 g_FuncProto.resize(0);
1315 g_FuncProto.append(vhdlcodeYYtext);
1316 g_vhdlKeyDict.clear();
1317 appStringLower(g_PrevString,vhdlcodeYYtext);
1318 if (g_PrevString.contains('('))
1321 BEGIN(ParseProcessProto);
1325 writeProcessProto();
1329 <Bases>("end"){BN}+("process") { // end of process
1331 codifyLines(vhdlcodeYYtext);
1336 <Bases>^{B}*("begin "|"begin") {
1338 writeFont("vhdlkeyword",vhdlcodeYYtext);
1341 <Bases>^{B}*("use"|"library"){BN}+ { //found package or library
1342 writeFont("vhdlkeyword",vhdlcodeYYtext);
1343 BEGIN(ParsePackage);
1347 <Bases>^{B}*("use"){BN}+("configuration")[^\n]* {
1348 codifyLines(vhdlcodeYYtext);
1353 <Bases>{FUNC} { // found function|procedure
1354 g_vhdlKeyDict.clear();
1355 g_FuncProto.resize(0);
1357 g_FuncProto.append(vhdlcodeYYtext);
1364 <Bases>^{B}*("entity"|"package"){BN}+ {
1365 appStringLower(g_PrevString,vhdlcodeYYtext);
1366 writeFont("keywordflow",vhdlcodeYYtext);
1367 isPackageBody=FALSE;
1372 <Bases>"end"{BN}+"architecture"{BN}+{FUNCNAME} {
1373 codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1376 <Bases>"end"{BN}+{FUNCNAME} {
1379 codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1386 appStringLower(g_PrevString,vhdlcodeYYtext);
1387 QCString temp(vhdlcodeYYtext);
1388 temp=temp.stripWhiteSpace();
1390 writeColoredWord(temp);
1394 appStringLower(g_PrevString,vhdlcodeYYtext);
1395 QCString temp(vhdlcodeYYtext);
1396 temp=temp.stripWhiteSpace();
1398 if (!writeColoredWord(temp))
1400 generateClassOrGlobalLink(*g_code,temp.data());
1404 codifyLines(vhdlcodeYYtext);
1407 <Bases>{KEYWORD} { // found keyword
1408 QCString qcs(vhdlcodeYYtext);
1409 if (!writeColoredWord(qcs))
1411 startFontClass("vhdlchar");
1412 g_code->codify(vhdlcodeYYtext);
1419 appStringLower(g_PrevString,vhdlcodeYYtext);
1420 QCString temp(vhdlcodeYYtext);
1421 temp=temp.stripWhiteSpace();
1423 if (!writeColoredWord(temp))
1425 startFontClass("vhdlchar");
1426 generateMemLink(*g_code,g_CurrClass,temp);
1431 <Bases,ParseComponent>{DIGITSS} {
1432 startFontClass("vhdllogic");
1433 codifyLines(vhdlcodeYYtext);
1437 <Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* {
1438 codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1443 codifyLines(vhdlcodeYYtext);
1446 BEGIN(ParseFuncProto);
1455 startFontClass("vhdlchar");
1456 g_code->codify(vhdlcodeYYtext);
1460 <Bases>","|"."|":"|"'"|"("|")" {
1461 startFontClass("vhdlchar");
1462 g_code->codify(vhdlcodeYYtext);
1467 QCString qcs(vhdlcodeYYtext);
1468 VhdlDocGen::deleteAllChars(qcs,'"');
1469 VhdlDocGen::deleteAllChars(qcs,' ');
1471 if (VhdlDocGen::isNumber(qcs))
1472 writeFont("vhdllogic",vhdlcodeYYtext);
1474 writeFont("keyword",vhdlcodeYYtext);
1477 <Bases>{B}*"#"[^\n]* {
1478 writeFont("keyword",vhdlcodeYYtext);
1481 <Bases>^{B}*{XILINX}/[^a-zA-Z0-9_] {
1483 //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1486 <Bases>^{B}*"set_"[^\n]* {
1491 codifyLines(vhdlcodeYYtext);
1496 g_code->codify(vhdlcodeYYtext);
1499 <*>\n{TEXTT} { // found normal or special comment on its own line
1500 QCString text(vhdlcodeYYtext);
1501 int i=text.find("--");
1502 if (text.mid(i,3)=="--!") // && // hide special comment
1504 if (!Config_getBool(STRIP_CODE_COMMENTS))
1506 codifyLines(text,0,FALSE,TRUE);
1508 else g_yyLineNr++; // skip complete line, but count line
1510 else // normal comment
1512 codifyLines(text,0,FALSE,TRUE);
1515 <*>{TEXTT} { // found normal or special comment after something
1516 QCString text(vhdlcodeYYtext);
1517 int i=text.find("--");
1518 if (text.mid(i,3)=="--!")
1520 // hide special comment
1521 if (!Config_getBool(STRIP_CODE_COMMENTS))
1523 codifyLines(text,0,FALSE,TRUE);
1526 else // normal comment
1528 codifyLines(text,0,FALSE,TRUE);
1534 /*@ ----------------------------------------------------------------------------
1537 void resetVhdlCodeParserState()
1539 g_vhdlKeyDict.setAutoDelete(TRUE);
1540 g_vhdlKeyDict.clear();
1543 void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s,
1544 bool exBlock, const char *exName,FileDef *fd,
1545 int startLine,int endLine,bool inlineFragment,
1546 MemberDef *memberDef,bool,Definition *searchCtx,
1547 bool /* collectXRefs */)
1549 //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1550 if (s.isEmpty()) return;
1551 printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
1552 TooltipManager::instance()->clearTooltips();
1555 ClassDef *dd=memberDef->getClassDef();
1556 if (dd) g_CurrClass=dd->name();
1559 resetVhdlCodeParserState();
1562 g_inputPosition = 0;
1563 g_currentFontClass = 0;
1564 g_needsTermination = FALSE;
1565 g_searchCtx = searchCtx;
1568 g_yyLineNr = startLine;
1573 g_inputLines = endLine+1;
1575 g_inputLines = g_yyLineNr + countLines() - 1;
1578 // g_theCallContext.clear();
1579 g_classScope = className;
1580 g_exampleBlock = exBlock;
1581 g_exampleName = exName;
1582 g_sourceFileDef = fd;
1583 bool cleanupSourceDef = FALSE;
1584 if (exBlock && fd==0)
1586 // create a dummy filedef for the example
1587 g_sourceFileDef = new FileDef("",exName);
1588 cleanupSourceDef = TRUE;
1590 if (g_sourceFileDef)
1592 setCurrentDoc("l00001");
1594 g_currentDefinition = 0;
1595 g_currentMemberDef = 0;
1597 if (!g_exampleName.isEmpty())
1599 g_exampleFile = convertNameToFile(g_exampleName+"-example");
1601 g_includeCodeFragment = inlineFragment;
1606 // g_type.resize(0);
1607 // g_name.resize(0);
1608 // g_args.resize(0);
1609 g_parmName.resize(0);
1610 g_parmType.resize(0);
1615 setParameterList(memberDef);
1617 /*int iLine=*/countLines();
1618 vhdlcodeYYrestart( vhdlcodeYYin );
1622 if (g_needsTermination)
1628 TooltipManager::instance()->writeTooltips(*g_code);
1630 if (cleanupSourceDef)
1632 // delete the temporary file definition used for this example
1633 delete g_sourceFileDef;
1637 printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
1640 void codeFreeVhdlScanner()
1642 #if defined(YY_FLEX_SUBMINOR_VERSION)
1645 vhdlcodeYYlex_destroy();
1650 #if !defined(YY_FLEX_SUBMINOR_VERSION)
1651 extern "C" { // some bogus code to keep the compiler happy
1652 void vhdlcodeYYdummy() { yy_flex_realloc(0,0); }
1654 #elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
1655 #error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"