1 /******************************************************************************
3 * Copyright (C) 1997-2014 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 VHDL subset
18 * supports VHDL-87/93/2008
19 * does not support VHDL-AMS
20 ******************************************************************************/
28 #include <qfileinfo.h>
29 #include <qstringlist.h>
35 /* --------------------------------------------------------------- */
38 #include "vhdldocgen.h"
44 #include "commentscan.h"
46 #include "definition.h"
47 #include "searchindex.h"
48 #include "outputlist.h"
49 #include "parserintf.h"
52 #include "arguments.h"
54 #include "memberlist.h"
55 #include "memberdef.h"
57 #include "classlist.h"
58 #include "namespacedef.h"
60 #include "membergroup.h"
61 #include "memberdef.h"
63 #include "vhdljjparser.h"
64 #include "VhdlParser.h"
67 #define theTranslator_vhdlType VhdlDocGen::trVhdlType
69 static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
70 static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
71 static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
72 static QDict<QCString> g_vhdlKeyDict3(17,FALSE);
73 static QDict<QCString> g_xilinxUcfDict(17,FALSE);
75 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
76 static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
77 static void assignBinding(VhdlConfNode* conf);
78 static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
80 //---------- create svg -------------------------------------------------------------
81 static void createSVG();
82 static void startDot(FTextStream &t);
83 static void startTable(FTextStream &t,const QCString &className);
84 static QList<MemberDef>* getPorts(ClassDef *cd);
85 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
86 static void endDot(FTextStream &t);
87 static void writeTable(QList<MemberDef>* port,FTextStream & t);
88 static void endTabel(FTextStream &t);
89 static void writeClassToDot(FTextStream &t,ClassDef* cd);
90 static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
91 //static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
92 static const MemberDef *flowMember=0;
94 void VhdlDocGen::setFlowMember( const MemberDef* mem)
99 const MemberDef* VhdlDocGen::getFlowMember()
106 //--------------------------------------------------------------------------------------------------
107 static void codify(FTextStream &t,const char *str)
118 case '<': t << "<";
120 case '>': t << ">";
122 case '&': t << "&";
124 case '\'': t << "'";
126 case '"': t << """;
135 static void writeLink(const MemberDef* mdef,OutputList &ol)
137 ol.writeObjectLink(mdef->getReference(),
138 mdef->getOutputFileBase(),
143 static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
145 ol.startFontClass(keyword);
150 static QCString splitString(QCString& str,char c)
157 str=str.remove(0,i+1);
162 static int compareString(const QCString& s1,const QCString& s2)
164 return qstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
167 static void createSVG()
169 QCString ov =Config_getString("HTML_OUTPUT");
170 QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
171 ov+="/vhdl_design.dot";
174 QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
176 if (portable_system("dot",vlargs)!=0)
178 err("could not create dot file");
182 // Creates a svg image. All in/out/inout ports are shown with brief description and direction.
183 // Brief descriptions for entities are shown too.
184 void VhdlDocGen::writeOverview()
186 ClassSDict::Iterator cli(*Doxygen::classSDict);
189 for ( ; (cd=cli.current()) ; ++cli )
191 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )
200 QCString ov =Config_getString("HTML_OUTPUT");
201 QCString fileName=ov+"/vhdl_design.dot";
206 if (!f.open(IO_WriteOnly))
208 fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
214 for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
216 if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS )
221 QList<MemberDef>* port= getPorts(cd);
226 if (port->count()==0)
233 startTable(t,cd->name());
234 writeClassToDot(t,cd);
238 // writeVhdlPortToolTip(t,port,cd);
239 writeVhdlEntityToolTip(t,cd);
242 BaseClassList *bl=cd->baseClasses();
245 BaseClassListIterator bcli(*bl);
247 for ( ; (bcd=bcli.current()) ; ++bcli )
249 ClassDef *bClass=bcd->classDef;
250 QCString dotn=cd->name()+":";
252 QCString csc=bClass->name()+":";
254 // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
255 writeVhdlDotLink(t,dotn,csc,0);
261 // writePortLinks(t);
266 //------------------------------------------------------------------------------------------------------------------------------------------------------
268 static void startDot(FTextStream &t)
270 t << " digraph G { \n";
271 t << "rankdir=LR \n";
272 t << "concentrate=TRUE\n";
273 t << "stylesheet=\"doxygen.css\"\n";
276 static void endDot(FTextStream &t)
281 static void startTable(FTextStream &t,const QCString &className)
283 t << className <<" [ shape=none , fontname=\"arial\", fontcolor=\"blue\" , \n";
284 t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
287 static void writeVhdlDotLink(FTextStream &t,
288 const QCString &a,const QCString &b,const QCString &style)
291 if (!style.isEmpty())
293 t << "[style=" << style << "];\n";
299 static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
303 QCString repl("<BR ALIGN=\"LEFT\"/>");
304 QCString file=cd->getDefFileName();
306 int k=cd->briefLine();
308 QStringList qsl=QStringList::split(ep,brief);
309 for(uint j=0;j<qsl.count();j++)
311 QCString qcs=qsl[j].data();
312 vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
317 vForm.replace(ep,repl.data());
322 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
325 uint len=port->count();
328 for (uint j=0;j<len;j++)
330 md=(MemberDef*)port->at(j);
331 QCString brief=md->briefDescriptionAsTooltip();
332 if (brief.isEmpty()) continue;
334 QCString node="node";
335 node+=VhdlDocGen::getRecordNumber();
336 t << node <<"[shape=box margin=0.1, label=<\n";
337 t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
338 t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
340 t<<" </TD></TR></TABLE>>];";
341 QCString dotn=cd->name()+":";
343 // writeVhdlDotLink(t,dotn,node,"dotted");
349 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd)
352 QCString brief=cd->briefDescription();
354 if (brief.isEmpty()) return;
356 brief=formatBriefNote(brief,cd);
358 QCString node="node";
359 node+=VhdlDocGen::getRecordNumber();
360 t << node <<"[shape=none margin=0.1, label=<\n";
361 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
362 t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
364 t << " </TD></TR></TABLE>>];";
365 QCString dotn=cd->name()+":";
367 writeVhdlDotLink(t,dotn,node,"dotted");
370 static void writeColumn(FTextStream &t,MemberDef *md,bool start)
374 static QRegExp reg("[%]");
375 bool bidir=(md!=0 &&( qstricmp(md->typeString(),"inout")==0));
379 toolTip=md->briefDescriptionAsTooltip();
380 if (!toolTip.isEmpty())
382 QCString largs = md->argsString();
383 if (!largs.isEmpty())
384 largs=largs.replace(reg," ");
395 t << "<TD ALIGN=\"LEFT\" ";
399 t << md->getOutputFileBase()<< Doxygen::htmlFileExtension;
400 t << "#" << md->anchor();
404 if (!toolTip.isEmpty())
406 codify(t,toolTip.data());
410 QCString largs = md->argsString();
411 if (!largs.isEmpty())
413 largs=largs.replace(reg," ");
414 codify(t,largs.data());
423 if (!toolTip.isEmpty())
425 // if (!toolTip.isEmpty())
428 t << "BGCOLOR=\"orange\">";
430 t << "BGCOLOR=\"azure\">";
434 t << "BGCOLOR=\"pink\">";
438 t << "BGCOLOR=\"lightgrey\">";
456 static void endTabel(FTextStream &t)
462 static void writeClassToDot(FTextStream &t,ClassDef* cd)
464 t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
469 t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
473 t << " </TD></TR>\n";
476 static QList<MemberDef>* getPorts(ClassDef *cd)
479 QList<MemberDef> *portList=new QList<MemberDef>;
480 MemberList *ml=cd->getMemberList(MemberListType_variableMembers);
482 if (ml==0) return NULL;
484 MemberListIterator fmni(*ml);
486 for (fmni.toFirst();(md=fmni.current());++fmni)
488 if (md->getMemberSpecifiers()==VhdlDocGen::PORT)
490 portList->append(md);
497 //writeColumn(FTextStream &t,QCString name,bool start)
499 static void writeTable(QList<MemberDef>* port,FTextStream & t)
503 uint len=port->count();
505 QList<MemberDef> inPorts;
506 QList<MemberDef> outPorts;
511 md=(MemberDef*)port->at(j);
512 QCString qc=md->typeString();
523 int inp = inPorts.count();
524 int outp = outPorts.count();
537 for(i=0;i<maxLen;i++)
542 md=(MemberDef*)inPorts.at(i);
543 writeColumn(t,md,TRUE);
547 writeColumn(t,NULL,TRUE);
552 md=(MemberDef*)outPorts.at(i);
553 writeColumn(t,md,FALSE);
557 writeColumn(t,NULL,FALSE);
562 //--------------------------------------------------------------------------------------------------
565 VhdlDocGen::VhdlDocGen()
569 VhdlDocGen::~VhdlDocGen()
573 void VhdlDocGen::init()
576 // vhdl keywords inlcuded VHDL 2008
577 const char* g_vhdlKeyWordMap0[] =
579 "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
580 "begin","block","body","buffer","bus",
581 "case","component","configuration","constant","context","cover",
582 "default","disconnect","downto",
583 "else","elsif","end","entity","exit",
584 "fairness","file","for","force","function",
585 "generate","generic","group","guarded",
586 "if","impure","in","inertial","inout","is",
587 "label","library","linkage","literal","loop",
589 "nand","new","next","nor","not","null",
590 "of","on","open","or","others","out",
591 "package","parameter","port","postponed","procedure","process","property","proctected","pure",
592 "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
593 "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
594 "then","to","transport","type",
595 "unaffected","units","until","use",
596 "variable","vmode","vprop","vunit",
597 "wait","when","while","with",
604 const char* g_vhdlKeyWordMap1[] =
606 "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
607 "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
608 "real","float","ufixed","sfixed","time",0
612 const char* g_vhdlKeyWordMap2[] =
614 "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
618 // predefined attributes
619 const char* g_vhdlKeyWordMap3[] =
621 "base","left","right","high","low","ascending",
622 "image","value","pos","val","succ","pred","leftof","rightof","left","right","high","low",
623 "range","reverse_range","length","ascending","delayed","stable","quiet","transaction","event",
624 "active","last_event","last_active","last_value","driving","driving_value","simple_name","instance_name","path_name",0
628 g_vhdlKeyDict0.setAutoDelete(TRUE);
629 g_vhdlKeyDict1.setAutoDelete(TRUE);
630 g_vhdlKeyDict2.setAutoDelete(TRUE);
631 g_vhdlKeyDict3.setAutoDelete(TRUE);
633 while (g_vhdlKeyWordMap0[j])
635 g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
636 new QCString(g_vhdlKeyWordMap0[j]));
641 while (g_vhdlKeyWordMap1[j])
643 g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
644 new QCString(g_vhdlKeyWordMap1[j]));
649 while (g_vhdlKeyWordMap2[j])
651 g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
652 new QCString(g_vhdlKeyWordMap2[j]));
657 while (g_vhdlKeyWordMap3[j])
659 g_vhdlKeyDict3.insert(g_vhdlKeyWordMap3[j],
660 new QCString(g_vhdlKeyWordMap3[j]));
667 * returns the color of a keyword
670 QCString* VhdlDocGen::findKeyWord(const QCString& tmp)
672 static QCString vhdlkeyword("vhdlkeyword");
673 static QCString vhdltype("comment");
674 static QCString vhdllogic("vhdllogic");
675 static QCString preprocessor("keywordflow");
677 QCString word=tmp.lower();
679 if (word.isEmpty() || word.at(0)=='\0') return 0;
681 if (g_vhdlKeyDict0.find(word))
682 return &preprocessor;
684 if (g_vhdlKeyDict1.find(word))
687 if (g_vhdlKeyDict2.find(word))
690 if (g_vhdlKeyDict3.find(word))
696 ClassDef *VhdlDocGen::getClass(const char *name)
698 if (name==0 || name[0]=='\0') return 0;
703 temp=temp.stripWhiteSpace();
704 cd= Doxygen::classSDict->find(temp.data());
708 ClassDef* VhdlDocGen::getPackageName(const QCString & name)
711 QStringList ql=QStringList::split(".",name,FALSE);
717 static QMap<QCString,MemberDef*> varMap;
718 static QList<ClassDef> qli;
719 static QMap<ClassDef*,QList<ClassDef> > packages;
721 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
726 cd=getClass(className);
727 //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
730 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_variableMembers);
731 if (mdef) return mdef;
732 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
733 if (mdef) return mdef;
735 // nothing found so far
736 // if we are an architecture or package body search in entitiy
738 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
739 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
741 Definition *d = cd->getOuterScope();
742 // searching upper/lower case names
744 QCString tt=d->name();
757 if (ecd) //d && d->definitionType()==Definition::TypeClass)
759 //ClassDef *ecd = (ClassDef*)d;
760 mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberListType_variableMembers);
761 if (mdef) return mdef;
762 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
763 if (mdef) return mdef;
768 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
769 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
771 Definition *d = cd->getOuterScope();
773 QCString tt=d->name();
774 ClassDef *ecd =getClass(tt);
785 if (ecd) //d && d->definitionType()==Definition::TypeClass)
787 if(!packages.contains(ecd))
789 VhdlDocGen::findAllPackages(ecd);
796 if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
799 uint len=packages.count();
800 for (uint j=0;j<len;j++)
802 for (QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.begin();cList != packages.end();cList++)
804 if (cList.key()==0) continue;
805 QList<ClassDef> mlist=cList.data();
806 for (uint j=0;j<mlist.count();j++)
808 mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_variableMembers);
809 if (mdef) return mdef;
810 mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
811 if (mdef) return mdef;
820 * This function returns the entity|package
821 * in which the key (type) is found
823 MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberListType type)
827 QCString keyType=cd->symbolName()+"@"+key;
828 //printf("\n %s | %s | %s",cd->symbolName().data(),key.data(,),keyType.data());
830 QMap<QCString, MemberDef*>::Iterator it =varMap.find(keyType);
839 if (qli.contains(cd))
843 ml=cd->getMemberList(type);
849 MemberListIterator fmni(*ml);
851 // fprintf(stderr,"\n loading enity %s %s: %d",cd->symbolName().data(),keyType.data(),l);
853 for (fmni.toFirst();(md=fmni.current());++fmni)
855 QCString tkey=cd->symbolName()+"@"+md->name();
856 if (varMap.contains(tkey))
860 varMap.insert(tkey.data(),md);
862 it=varMap.find(keyType.data());
875 * finds all included packages of an Entity or Package
878 void VhdlDocGen::findAllPackages( ClassDef *cdef)
880 QList<ClassDef> cList;
881 if (packages.contains(cdef)) return;
882 MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
887 MemberListIterator fmni(*mem);
888 for (fmni.toFirst();(md=fmni.current());++fmni)
890 if (VhdlDocGen::isPackage(md))
892 ClassDef* cd=VhdlDocGen::getPackageName(md->name());
896 VhdlDocGen::findAllPackages(cd);
897 packages.insert(cdef,cList);
905 * returns the function with the matching argument list
906 * is called in vhdlcode.l
909 MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
910 const QCString& funcname,
911 const QCString& package, bool /*type*/)
915 ClassDef *cdef=getClass(package.data());
916 if (cdef==0) return 0;
918 MemberList *mem=cdef->getMemberList(MemberListType_pubMethods);
922 MemberListIterator fmni(*mem);
923 for (fmni.toFirst();(mdef=fmni.current());++fmni)
925 QCString mname=mdef->name();
926 if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
928 ArgumentList *alp = mdef->argumentList();
930 // ArgumentList* arg2=mdef->getArgumentList();
932 ArgumentListIterator ali(*alp);
933 ArgumentListIterator ali1(ql);
935 if (ali.count() != ali1.count()) break;
940 for (;(arg=ali.current());++ali)
942 arg1=ali1.current(); ++ali1;
943 equ+=abs(compareString(arg->type,arg1->type));
945 QCString s1=arg->type;
946 QCString s2=arg1->type;
947 VhdlDocGen::deleteAllChars(s1,' ');
948 VhdlDocGen::deleteAllChars(s2,' ');
949 equ+=abs(compareString(s1,s2));
952 VhdlDocGen::deleteAllChars(s1,' ');
953 VhdlDocGen::deleteAllChars(s2,' ');
954 equ+=abs(compareString(s1,s2));
955 // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
956 // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
958 if (equ==0) return mdef;
969 * returns the class title+ref
972 QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
975 if (cd==0) return "";
976 pageTitle+=cd->displayName();
977 pageTitle=VhdlDocGen::getClassName(cd);
978 int ii=cd->protection();
980 pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
985 /* returns the class name without their prefixes */
987 QCString VhdlDocGen::getClassName(const ClassDef* cd)
990 if (cd==0) return "";
992 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
995 temp.stripPrefix("_");
999 return substitute(cd->className(),"::",".");
1003 * writes an inline link form entity|package to architecture|package body and vice verca
1006 void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol)
1009 ql.setAutoDelete(TRUE);
1010 QCString nn=cd->className();
1011 int ii=(int)cd->protection()+2;
1014 if (ii==VhdlDocGen::ENTITY)
1015 type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE);
1016 else if (ii==VhdlDocGen::ARCHITECTURE)
1017 type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE);
1018 else if (ii==VhdlDocGen::PACKAGE_BODY)
1019 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
1020 else if (ii==VhdlDocGen::PACKAGE)
1021 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE);
1025 //type=type.lower();
1027 ol.disable(OutputGenerator::RTF);
1028 ol.disable(OutputGenerator::Man);
1030 if (ii==VhdlDocGen::PACKAGE_BODY)
1032 nn.stripPrefix("_");
1033 cd=getClass(nn.data());
1035 else if (ii==VhdlDocGen::PACKAGE)
1038 cd=getClass(nn.data());
1040 else if (ii==VhdlDocGen::ARCHITECTURE)
1042 QStringList qlist=QStringList::split("-",nn,FALSE);
1044 cd=VhdlDocGen::getClass(nn.data());
1048 if (ii==VhdlDocGen::ENTITY)
1050 VhdlDocGen::findAllArchitectures(ql,cd);
1052 for (int i=0;i<j;i++)
1054 QCString *temp=ql.at(i);
1055 QStringList qlist=QStringList::split("-",*temp,FALSE);
1056 QCString s1=qlist[0].utf8();
1057 QCString s2=qlist[1].utf8();
1058 s1.stripPrefix("_");
1059 if (j==1) s1.resize(0);
1060 ClassDef*cc = getClass(temp->data());
1063 VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
1069 VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
1072 ol.enable(OutputGenerator::Man);
1073 ol.enable(OutputGenerator::RTF);
1078 * finds all architectures which belongs to an entiy
1080 void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
1083 ClassSDict::Iterator cli(*Doxygen::classSDict);
1084 for ( ; (citer=cli.current()) ; ++cli )
1086 QCString jj=citer->className();
1087 if (cd != citer && jj.contains('-')!=-1)
1089 QStringList ql=QStringList::split("-",jj,FALSE);
1090 QCString temp=ql[1].utf8();
1091 if (qstricmp(cd->className(),temp)==0)
1093 QCString *cl=new QCString(jj);
1098 }//findAllArchitectures
1100 ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd)
1103 QCString nn=cd->name();
1104 ClassSDict::Iterator cli(*Doxygen::classSDict);
1106 for ( ; (citer=cli.current()) ; ++cli )
1108 QCString jj=citer->name();
1109 QStringList ql=QStringList::split(":",jj,FALSE);
1112 if (ql[0].utf8()==nn )
1121 * writes the link entity >> .... or architecture >> ...
1124 void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
1127 QCString temp=ccd->getOutputFileBase();
1129 ol.docify(type.data());
1131 nn.stripPrefix("_");
1132 ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
1134 if (!behav.isEmpty())
1138 ol.docify(behav.data());
1147 * strips the "--" prefixes of vhdl comments
1149 void VhdlDocGen::prepareComment(QCString& qcs)
1151 const char* s="--!";
1156 index=qcs.find(s,0,TRUE);
1158 qcs=qcs.remove(index,qstrlen(s));
1160 qcs=qcs.stripWhiteSpace();
1165 * parses a function proto
1166 * @param text function string
1167 * @param qlist stores the function types
1168 * @param name points to the function name
1169 * @param ret Stores the return type
1172 void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
1173 QCString& name,QCString& ret,bool doc)
1175 (void)qlist; //unused
1181 end=s1.findRev(")");
1185 QCString tt=s1.mid(index,(end-index+1));
1186 temp=s1.mid(index+1,(end-index-1));
1187 //getFuncParams(qlist,temp);
1191 name=s1.left(index);
1192 name=name.stripWhiteSpace();
1202 s1=s1.stripWhiteSpace();
1203 int i=s1.find("(",0,FALSE);
1204 int s=s1.find(QRegExp("[ \\t]"));
1206 s1=VhdlDocGen::getIndexWord(s1.data(),1);
1207 else // s<i, s=start of name, i=end of name
1210 name=s1.stripWhiteSpace();
1212 index=s1.findRev("return",-1,FALSE);
1215 ret=s1.mid(index+6,s1.length());
1216 ret=ret.stripWhiteSpace();
1217 VhdlDocGen::deleteCharRev(ret,';');
1222 * returns the n'th word of a string
1225 QCString VhdlDocGen::getIndexWord(const char* c,int index)
1229 QRegExp reg("[\\s:|]");
1231 ql=QStringList::split(reg,temp,FALSE);
1233 if (ql.count() > (unsigned int)index)
1235 return ql[index].utf8();
1242 QCString VhdlDocGen::getProtectionName(int prot)
1244 if (prot==VhdlDocGen::ENTITYCLASS)
1246 else if (prot==VhdlDocGen::ARCHITECTURECLASS)
1247 return "architecture";
1248 else if (prot==VhdlDocGen::PACKAGECLASS)
1250 else if (prot==VhdlDocGen::PACKBODYCLASS)
1251 return "package body";
1256 QCString VhdlDocGen::trTypeString(uint64 type)
1260 case VhdlDocGen::LIBRARY: return "Library";
1261 case VhdlDocGen::ENTITY: return "Entity";
1262 case VhdlDocGen::PACKAGE_BODY: return "Package Body";
1263 case VhdlDocGen::ATTRIBUTE: return "Attribute";
1264 case VhdlDocGen::PACKAGE: return "Package";
1265 case VhdlDocGen::SIGNAL: return "Signal";
1266 case VhdlDocGen::COMPONENT: return "Component";
1267 case VhdlDocGen::CONSTANT: return "Constant";
1268 case VhdlDocGen::TYPE: return "Type";
1269 case VhdlDocGen::SUBTYPE: return "Subtype";
1270 case VhdlDocGen::FUNCTION: return "Function";
1271 case VhdlDocGen::RECORD: return "Record";
1272 case VhdlDocGen::PROCEDURE: return "Procedure";
1273 case VhdlDocGen::ARCHITECTURE: return "Architecture";
1274 case VhdlDocGen::USE: return "Package";
1275 case VhdlDocGen::PROCESS: return "Process";
1276 case VhdlDocGen::PORT: return "Port";
1277 case VhdlDocGen::GENERIC: return "Generic";
1278 case VhdlDocGen::UNITS: return "Units";
1279 //case VhdlDocGen::PORTMAP: return "Port Map";
1280 case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
1281 case VhdlDocGen::GROUP: return "Group";
1282 case VhdlDocGen::VFILE: return "File";
1283 case VhdlDocGen::INSTANTIATION: return "Instantiation";
1284 case VhdlDocGen::ALIAS: return "Alias";
1285 case VhdlDocGen::CONFIG: return "Configuration";
1286 case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous";
1287 case VhdlDocGen::UCF_CONST: return "Constraints";
1293 * deletes a char backwards in a string
1296 bool VhdlDocGen::deleteCharRev(QCString &s,char c)
1298 int index=s.findRev(c,-1,FALSE);
1301 QCString qcs=s.remove(index,1);
1308 void VhdlDocGen::deleteAllChars(QCString &s,char c)
1310 int index=s.findRev(c,-1,FALSE);
1313 QCString qcs=s.remove(index,1);
1315 index=s.findRev(c,-1,FALSE);
1320 static int recordCounter=0;
1323 * returns the next number of a record|unit member
1326 QCString VhdlDocGen::getRecordNumber()
1329 sprintf(buf,"%d",recordCounter++);
1330 QCString qcs(&buf[0]);
1335 * returns the next number of an anonymous process
1338 QCString VhdlDocGen::getProcessNumber()
1340 static int stringCounter;
1342 QCString qcs("PROCESS_");
1343 sprintf(buf,"%d",stringCounter++);
1344 qcs.append(&buf[0]);
1349 * writes a colored and formatted string
1352 void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
1354 QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
1356 qcs+=QCString(" ");// parsing the last sign
1365 j = reg.match(temp.data(),0,&len);
1374 ss=VhdlDocGen::findKeyWord(find);
1375 bool k=isNumber(find); // is this a number
1379 startFonts(find,"vhdldigit",ol);
1382 else if (j != 0 && ss)
1384 startFonts(find,ss->data(),ol);
1390 VhdlDocGen::writeStringLink(mdef,find,ol);
1393 startFonts(&buf[0],"vhdlchar",ol);
1395 QCString st=temp.remove(0,j+1);
1397 if (!find.isEmpty() && find.at(0)=='"')
1399 int ii=find.find('"',2);
1402 QCString com=find.left(ii+1);
1403 startFonts(com,"keyword",ol);
1404 temp=find.remove(0,ii+1);
1411 j = reg.match(temp.data(),0,&len);
1416 startFonts(find,"vhdlchar",ol);
1419 }// writeFormatString
1422 * returns TRUE if this string is a number
1424 bool VhdlDocGen::isNumber(const QCString& s)
1426 static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
1428 if (s.isEmpty()) return FALSE;
1430 j = regg.match(s.data(),0,&len);
1431 if ((j==0) && (len==(int)s.length())) return TRUE;
1438 * inserts white spaces for better readings
1439 * and writes a colored string to the output
1442 void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
1445 QCString temp(qcs.length());
1446 qcs.stripPrefix(":");
1447 qcs.stripPrefix("is");
1448 qcs.stripPrefix("IS");
1449 qcs.stripPrefix("of");
1450 qcs.stripPrefix("OF");
1452 // VhdlDocGen::deleteCharRev(qcs,';');
1454 int len = qcs.length();
1455 unsigned int index=1;//temp.length();
1457 for (int j=0;j<len;j++)
1461 if (j>0) b=qcs[j-1];
1462 if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
1464 if (temp.at(index-1) != ' ')
1473 if (b==':') // := operator
1475 temp.replace(index-1,1,"=");
1490 index=temp.length();
1492 temp=temp.stripWhiteSpace();
1493 // printf("\n [%s]",qcs.data());
1494 VhdlDocGen::writeFormatString(temp,ol,mdef);
1498 * writes a procedure prototype to the output
1501 void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1503 ArgumentListIterator ali(*al);
1506 int len=al->count();
1512 for (;(arg=ali.current());++ali)
1518 QCString nn=arg->name;
1521 QCString *str=VhdlDocGen::findKeyWord(arg->defval);
1525 startFonts(arg->defval,str->data(),ol);
1529 startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
1532 startFonts(nn,"vhdlchar",ol); // write name
1533 if (qstricmp(arg->attrib,arg->type) != 0)
1535 startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
1538 VhdlDocGen::formatString(arg->type,ol,mdef);
1554 * writes a function prototype to the output
1557 void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1560 ArgumentListIterator ali(*al);
1563 int len=al->count();
1571 for (;(arg=ali.current());++ali)
1574 QCString att=arg->defval;
1575 bool bGen=att.stripPrefix("gen!");
1584 VhdlDocGen::formatString(QCString("generic "),ol,mdef);
1588 QCString *str=VhdlDocGen::findKeyWord(att);
1591 VhdlDocGen::formatString(att,ol,mdef);
1593 startFonts(att,"vhdlchar",ol);
1596 QCString nn=arg->name;
1598 QCString ss=arg->type.stripWhiteSpace(); //.lower();
1599 QCString w=ss.stripWhiteSpace();//.upper();
1600 startFonts(nn,"vhdlchar",ol);
1601 startFonts("in ","stringliteral",ol);
1602 QCString *str=VhdlDocGen::findKeyWord(ss);
1604 VhdlDocGen::formatString(w,ol,mdef);
1606 startFonts(w,"vhdlchar",ol);
1609 startFonts(arg->attrib,"vhdlchar",ol);
1621 const char *exp=mdef->excpString();
1624 ol.insertMemberAlign();
1635 * writes a process prototype to the output
1638 void VhdlDocGen::writeProcessProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1641 ArgumentListIterator ali(*al);
1646 for (;(arg=ali.current());++ali)
1652 QCString nn=arg->name;
1653 // startFonts(nn,"vhdlchar",ol);
1654 VhdlDocGen::writeFormatString(nn,ol,mdef);
1663 * writes a function|procedure documentation to the output
1666 bool VhdlDocGen::writeFuncProcDocu(
1667 const MemberDef *md,
1669 const ArgumentList* al,
1672 if (al==0) return FALSE;
1676 ArgumentListIterator ali(*al);
1677 int index=ali.count();
1683 ol.endMemberDocName();
1684 ol.startParameterList(TRUE);
1685 //ol.startParameterName(FALSE);
1688 for (;(arg=ali.current());++ali)
1690 ol.startParameterType(first,"");
1691 // if (first) ol.writeChar('(');
1692 QCString attl=arg->defval;
1693 bool bGen=attl.stripPrefix("gen!");
1695 VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
1698 if (VhdlDocGen::isProcedure(md))
1700 startFonts(arg->defval,"keywordtype",ol);
1703 ol.endParameterType();
1705 ol.startParameterName(TRUE);
1706 VhdlDocGen::writeFormatString(arg->name,ol,md);
1708 if (VhdlDocGen::isProcedure(md))
1710 startFonts(arg->attrib,"stringliteral",ol);
1712 else if (VhdlDocGen::isVhdlFunction(md))
1714 startFonts(QCString("in"),"stringliteral",ol);
1718 ol.disable(OutputGenerator::Man);
1720 ol.enable(OutputGenerator::Man);
1721 if (!VhdlDocGen::isProcess(md))
1723 // startFonts(arg->type,"vhdlkeyword",ol);
1724 VhdlDocGen::writeFormatString(arg->type,ol,md);
1726 ol.disable(OutputGenerator::Man);
1728 ol.enable(OutputGenerator::Man);
1736 // ol.docify(" ) ");
1737 ol.endParameterName(TRUE,FALSE,TRUE);
1740 ol.endParameterName(FALSE,FALSE,FALSE);
1745 //ol.endParameterList();
1748 } // writeDocFunProc
1753 QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool func)
1757 ArgumentListIterator ali(*al);
1760 for (;(arg=ali.current());++ali)
1762 if (sem) argString.append(", ");
1765 argString+=arg->name;
1767 argString+=arg->type;
1771 argString+=arg->defval+" ";
1772 argString+=arg->name+" :";
1773 argString+=arg->attrib+" ";
1774 argString+=arg->type;
1782 void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
1783 OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
1785 static ClassDef *cdef;
1786 //static GroupDef* gdef;
1788 { // only one inline link
1789 VhdlDocGen::writeInlineClassLink(cd,ol);
1794 if (gd && gdef==gd) return;
1800 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
1801 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
1802 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
1803 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
1804 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONSTANT,FALSE),0,FALSE,VhdlDocGen::CONSTANT);
1805 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::TYPE,FALSE),0,FALSE,VhdlDocGen::TYPE);
1806 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SUBTYPE,FALSE),0,FALSE,VhdlDocGen::SUBTYPE);
1807 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GENERIC,FALSE),0,FALSE,VhdlDocGen::GENERIC);
1808 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PORT,FALSE),0,FALSE,VhdlDocGen::PORT);
1809 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCESS,FALSE),0,FALSE,VhdlDocGen::PROCESS);
1810 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SIGNAL,FALSE),0,FALSE,VhdlDocGen::SIGNAL);
1811 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ATTRIBUTE,FALSE),0,FALSE,VhdlDocGen::ATTRIBUTE);
1812 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCEDURE,FALSE),0,FALSE,VhdlDocGen::PROCEDURE);
1813 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::RECORD,FALSE),0,FALSE,VhdlDocGen::RECORD);
1814 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UNITS,FALSE),0,FALSE,VhdlDocGen::UNITS);
1815 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE);
1816 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE);
1817 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP);
1818 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION);
1819 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS);
1820 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS);
1822 // configurations must be added to global file definitions.
1823 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG);
1824 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
1828 static void setGlobalType(MemberList *ml)
1832 MemberListIterator mmli(*ml);
1833 for ( ; (mdd=mmli.current()); ++mmli )
1835 QCString l=mdd->typeString();
1837 if (qstrcmp(mdd->argsString(),"package")==0)
1839 mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
1841 else if (qstrcmp(mdd->argsString(),"configuration")==0)
1843 mdd->setMemberSpecifiers(VhdlDocGen::CONFIG);
1845 else if (qstrcmp(mdd->typeString(),"library")==0)
1847 mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY);
1849 else if (qstrcmp(mdd->typeString(),"use")==0)
1851 mdd->setMemberSpecifiers(VhdlDocGen::USE);
1853 else if (qstricmp(mdd->typeString(),"misc")==0)
1855 mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
1857 else if (qstricmp(mdd->typeString(),"ucf_const")==0)
1859 mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
1864 /* writes a vhdl type documentation */
1865 bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol)
1867 ClassDef *cd=(ClassDef*)d;
1868 bool hasParams = FALSE;
1870 if (cd==0) return hasParams;
1872 QCString ttype=mdef->typeString();
1873 QCString largs=mdef->argsString();
1875 if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
1877 QCString nn=mdef->typeString();
1878 nn=nn.stripWhiteSpace();
1879 QCString na=cd->name();
1880 MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1881 if (memdef && memdef->isLinkable())
1886 writeLink(memdef,ol);
1893 VhdlDocGen::formatString(ttype,ol,mdef);
1896 ol.docify(mdef->name());
1897 hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
1901 if (mdef->isVariable())
1903 if (VhdlDocGen::isConstraint(mdef))
1908 largs=largs.replace(QRegExp("#")," ");
1909 VhdlDocGen::formatString(largs,ol,mdef);
1915 if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
1922 // QCString largs=mdef->argsString();
1924 bool c=largs=="context";
1925 bool brec=largs.stripPrefix("record") ;
1928 VhdlDocGen::formatString(ttype,ol,mdef);
1930 if (c || brec || largs.stripPrefix("units"))
1934 VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1939 if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1941 // QCString largs=mdef->argsString();
1942 VhdlDocGen::formatString(largs,ol,mdef);
1949 /* writes a vhdl type declaration */
1951 void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
1952 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1955 static QRegExp reg("[%]");
1960 ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
1961 mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY ||
1962 mdef->getMemberSpecifiers()==VhdlDocGen::USE
1963 ); // member should belong to something
1968 else d=(Definition*)mdef;
1970 // write tag file information of this member
1971 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1973 Doxygen::tagFile << " <member kind=\"";
1974 if (VhdlDocGen::isGeneric(mdef)) Doxygen::tagFile << "generic";
1975 if (VhdlDocGen::isPort(mdef)) Doxygen::tagFile << "port";
1976 if (VhdlDocGen::isEntity(mdef)) Doxygen::tagFile << "entity";
1977 if (VhdlDocGen::isComponent(mdef)) Doxygen::tagFile << "component";
1978 if (VhdlDocGen::isVType(mdef)) Doxygen::tagFile << "type";
1979 if (VhdlDocGen::isConstant(mdef)) Doxygen::tagFile << "constant";
1980 if (VhdlDocGen::isSubType(mdef)) Doxygen::tagFile << "subtype";
1981 if (VhdlDocGen::isVhdlFunction(mdef)) Doxygen::tagFile << "function";
1982 if (VhdlDocGen::isProcedure(mdef)) Doxygen::tagFile << "procedure";
1983 if (VhdlDocGen::isProcess(mdef)) Doxygen::tagFile << "process";
1984 if (VhdlDocGen::isSignals(mdef)) Doxygen::tagFile << "signal";
1985 if (VhdlDocGen::isAttribute(mdef)) Doxygen::tagFile << "attribute";
1986 if (VhdlDocGen::isRecord(mdef)) Doxygen::tagFile << "record";
1987 if (VhdlDocGen::isLibrary(mdef)) Doxygen::tagFile << "library";
1988 if (VhdlDocGen::isPackage(mdef)) Doxygen::tagFile << "package";
1989 if (VhdlDocGen::isVariable(mdef)) Doxygen::tagFile << "shared variable";
1990 if (VhdlDocGen::isFile(mdef)) Doxygen::tagFile << "file";
1991 if (VhdlDocGen::isGroup(mdef)) Doxygen::tagFile << "group";
1992 if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << " instantiation";
1993 if (VhdlDocGen::isAlias(mdef)) Doxygen::tagFile << "alias";
1994 if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << "configuration";
1996 Doxygen::tagFile << "\">" << endl;
1997 Doxygen::tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
1998 Doxygen::tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
1999 Doxygen::tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
2000 Doxygen::tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
2002 if (VhdlDocGen::isVhdlFunction(mdef))
2003 Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),TRUE)) << "</arglist>" << endl;
2004 else if (VhdlDocGen::isProcedure(mdef))
2005 Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),FALSE)) << "</arglist>" << endl;
2007 Doxygen::tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
2009 mdef->writeDocAnchorsToTagFile();
2010 Doxygen::tagFile << " </member>" << endl;
2014 // write search index info
2015 if (Doxygen::searchIndex)
2017 Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
2018 Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
2019 Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
2022 QCString cname = d->name();
2023 QCString cfname = d->getOutputFileBase();
2025 //HtmlHelp *htmlHelp=0;
2026 // bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
2027 // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
2029 // search for the last anonymous scope in the member type
2030 ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
2032 // start a new member declaration
2033 uint isAnonymous = (bool)(annoClassDef); // || m_impl->annMemb || m_impl->annEnumType;
2034 ///printf("startMemberItem for %s\n",name().data());
2035 int mm=mdef->getMemberSpecifiers();
2036 if (mm==VhdlDocGen::MISCELLANEOUS)
2039 ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
2041 // If there is no detailed description we need to write the anchor here.
2042 bool detailsVisible = mdef->isDetailedSectionLinkable();
2043 if (!detailsVisible) // && !m_impl->annMemb)
2045 QCString doxyName=mdef->name().copy();
2046 if (!cname.isEmpty()) doxyName.prepend(cname+"::");
2047 QCString doxyArgs=mdef->argsString();
2048 ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
2050 ol.pushGeneratorState();
2051 ol.disable(OutputGenerator::Man);
2052 ol.disable(OutputGenerator::Latex);
2054 ol.popGeneratorState();
2060 QCString ltype(mdef->typeString());
2061 // ltype=ltype.replace(reg," ");
2062 QCString largs(mdef->argsString());
2063 // largs=largs.replace(reg," ");
2064 mdef->setType(ltype.data());
2065 mdef->setArgsString(largs.data());
2066 //ClassDef * plo=mdef->getClassDef();
2068 ArgumentList *alp = mdef->argumentList();
2070 //VhdlDocGen::adjustRecordMember(mdef);
2074 case VhdlDocGen::MISCELLANEOUS:
2075 VhdlDocGen::writeSource(mdef,ol,nn);
2077 case VhdlDocGen::PROCEDURE:
2078 case VhdlDocGen::FUNCTION:
2080 VhdlDocGen::formatString(ltype,ol,mdef);
2082 ol.insertMemberAlign();
2086 if (alp!=0 && mm==VhdlDocGen::FUNCTION)
2087 VhdlDocGen::writeFunctionProto(ol,alp,mdef);
2089 if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
2090 VhdlDocGen::writeProcedureProto(ol,alp,mdef);
2093 case VhdlDocGen::USE:
2094 kl=VhdlDocGen::getClass(mdef->name());
2095 if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
2097 ol.insertMemberAlign();
2102 nn=kl->getOutputFileBase();
2103 ol.pushGeneratorState();
2104 ol.disableAllBut(OutputGenerator::Html);
2106 QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
2108 ol.docify(name.data());
2111 name+=" <"+mdef->name()+">";
2113 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2114 ol.popGeneratorState();
2117 case VhdlDocGen::LIBRARY:
2119 ol.insertMemberAlign();
2120 if (largs=="context")
2122 VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
2127 case VhdlDocGen::GENERIC:
2128 case VhdlDocGen::PORT:
2129 case VhdlDocGen::ALIAS:
2133 ol.insertMemberAlign();
2134 if (mm==VhdlDocGen::GENERIC)
2137 VhdlDocGen::formatString(largs,ol,mdef);
2144 VhdlDocGen::formatString(ltype,ol,mdef);
2147 VhdlDocGen::formatString(largs,ol,mdef);
2150 case VhdlDocGen::PROCESS:
2152 ol.insertMemberAlign();
2153 VhdlDocGen::writeProcessProto(ol,alp,mdef);
2155 case VhdlDocGen::PACKAGE:
2156 case VhdlDocGen::ENTITY:
2157 case VhdlDocGen::COMPONENT:
2158 case VhdlDocGen::INSTANTIATION:
2159 case VhdlDocGen::CONFIG:
2160 if (VhdlDocGen::isCompInst(mdef) )
2163 if(nn.stripPrefix("function") || nn.stripPrefix("package"))
2165 VhdlDocGen::formatString(largs,ol,mdef);
2166 ol.insertMemberAlign();
2169 VhdlDocGen::formatString(ltype,ol,mdef);
2173 largs.prepend("::");
2174 largs.prepend(mdef->name().data());
2175 ol.writeObjectLink(mdef->getReference(),
2183 ol.insertMemberAlign();
2190 if (VhdlDocGen::isComponent(mdef) ||
2191 VhdlDocGen::isConfig(mdef) ||
2192 VhdlDocGen::isCompInst(mdef))
2194 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2196 nn=mdef->getOutputFileBase();
2203 kl=getClass(nn.data());
2206 nn=kl->getOutputFileBase();
2207 ol.pushGeneratorState();
2208 ol.disableAllBut(OutputGenerator::Html);
2210 QCString name("<Entity ");
2211 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2217 name+=mdef->name()+"> ";
2219 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2221 ol.popGeneratorState();
2225 case VhdlDocGen::UCF_CONST:
2226 mm=mdef->name().findRev('_');
2229 mdef->setName(mdef->name().left(mm));
2231 writeUCFLink(mdef,ol);
2233 case VhdlDocGen::SIGNAL:
2234 case VhdlDocGen::ATTRIBUTE:
2235 case VhdlDocGen::SUBTYPE:
2236 case VhdlDocGen::CONSTANT:
2237 case VhdlDocGen::SHAREDVARIABLE:
2238 case VhdlDocGen::VFILE:
2239 case VhdlDocGen::GROUP:
2242 ol.insertMemberAlign();
2243 VhdlDocGen::formatString(ltype,ol,mdef);
2245 case VhdlDocGen::TYPE:
2246 bRec=largs.stripPrefix("record") ;
2247 bUnit=largs.stripPrefix("units") ;
2249 if (bRec) ol.docify("record: ");
2250 if (bUnit) ol.docify("units: ");
2252 ol.insertMemberAlign();
2253 if (!bRec && !bUnit) VhdlDocGen::formatString(ltype,ol,mdef);
2254 if (bUnit) ol.lineBreak();
2257 writeRecorUnit(largs,ol,mdef);
2266 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2267 if (htmlOn && /*Config_getBool("HTML_ALIGN_MEMBERS") &&*/ !ltype.isEmpty())
2269 ol.disable(OutputGenerator::Html);
2271 if (!ltype.isEmpty()) ol.docify(" ");
2275 ol.enable(OutputGenerator::Html);
2278 if (!detailsVisible)// && !m_impl->annMemb)
2280 ol.endDoxyAnchor(cfname,mdef->anchor());
2283 // name().data(),annoClassDef,annEnumType);
2284 // if(mm!=VhdlDocGen::MISCELLANEOUS)
2286 if (!mdef->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC") /* && !annMemb */)
2288 ol.startMemberDescription(mdef->anchor());
2289 ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
2290 mdef->getOuterScope()?mdef->getOuterScope():d,
2291 mdef,mdef->briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
2294 ol.pushGeneratorState();
2295 ol.disableAllBut(OutputGenerator::Html);
2298 if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
2300 ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
2304 ol.startTextLink(0,mdef->anchor());
2307 //ol.startEmphasis();
2308 ol.popGeneratorState();
2310 //ol.newParagraph();
2311 ol.endMemberDescription();
2313 mdef->warnIfUndocumented();
2315 }// end writeVhdlDeclaration
2318 void VhdlDocGen::writePlainVHDLDeclarations(
2319 MemberList* mlist,OutputList &ol,
2320 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
2323 SDict<QCString> pack(1009);
2327 MemberListIterator mli(*mlist);
2328 for ( ; (md=mli.current()); ++mli )
2330 int mems=md->getMemberSpecifiers();
2331 if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
2333 if (first) { ol.startMemberList();first=FALSE; }
2334 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2336 else if (md->isBriefSectionVisible() && (mems==specifier))
2338 if (!pack.find(md->name().data()))
2340 if (first) ol.startMemberList(),first=FALSE;
2341 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2342 pack.append(md->name().data(),new QCString(md->name().data()));
2346 if (!first) ol.endMemberList();
2350 static bool membersHaveSpecificType(MemberList *ml,uint64 type)
2352 if (ml==0) return FALSE;
2354 MemberListIterator mmli(*ml);
2355 for ( ; (mdd=mmli.current()); ++mmli )
2357 if (mdd->getMemberSpecifiers()==type) //is type in class
2362 if (ml->getMemberGroupList())
2364 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2366 while ((mg=mgli.current()))
2370 if (membersHaveSpecificType(mg->members(),type)) return TRUE;
2378 void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
2379 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
2380 const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
2383 if (!membersHaveSpecificType(ml,type)) return;
2387 ol.startMemberHeader(title);
2388 ol.parseText(title);
2389 ol.endMemberHeader();
2392 if (subtitle && subtitle[0]!=0)
2394 ol.startMemberSubtitle();
2395 ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
2396 ol.endMemberSubtitle();
2397 } //printf("memberGroupList=%p\n",memberGroupList);
2399 VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
2401 if (ml->getMemberGroupList())
2403 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2405 while ((mg=mgli.current()))
2407 if (membersHaveSpecificType(mg->members(),type))
2409 //printf("mg->header=%s\n",mg->header().data());
2410 bool hasHeader=mg->header()!="[NOHEADER]";
2411 ol.startMemberGroupHeader(hasHeader);
2414 ol.parseText(mg->header());
2416 ol.endMemberGroupHeader();
2417 if (!mg->documentation().isEmpty())
2419 //printf("Member group has docs!\n");
2420 ol.startMemberGroupDocs();
2421 ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
2422 ol.endMemberGroupDocs();
2424 ol.startMemberGroup();
2425 //printf("--- mg->writePlainDeclarations ---\n");
2426 VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
2427 ol.endMemberGroup(hasHeader);
2432 }// writeVHDLDeclarations
2435 bool VhdlDocGen::writeClassType( ClassDef *& cd,
2436 OutputList &ol ,QCString & cname)
2438 int id=cd->protection();
2439 QCString qcs = VhdlDocGen::trTypeString(id+2);
2440 cname=VhdlDocGen::getClassName(cd);
2442 ol.writeString(qcs.data());
2443 ol.writeString(" ");
2445 //ol.insertMemberAlign();
2449 QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
2453 case VhdlDocGen::LIBRARY:
2454 if (sing) return "Library";
2455 else return "Libraries";
2456 case VhdlDocGen::PACKAGE:
2457 if (sing) return "Package";
2458 else return "Packages";
2459 case VhdlDocGen::SIGNAL:
2460 if (sing) return "Signal";
2461 else return "Signals";
2462 case VhdlDocGen::COMPONENT:
2463 if (sing) return "Component";
2464 else return "Components";
2465 case VhdlDocGen::CONSTANT:
2466 if (sing) return "Constant";
2467 else return "Constants";
2468 case VhdlDocGen::ENTITY:
2469 if (sing) return "Entity";
2470 else return "Entities";
2471 case VhdlDocGen::TYPE:
2472 if (sing) return "Type";
2473 else return "Types";
2474 case VhdlDocGen::SUBTYPE:
2475 if (sing) return "Subtype";
2476 else return "Subtypes";
2477 case VhdlDocGen::FUNCTION:
2478 if (sing) return "Function";
2479 else return "Functions";
2480 case VhdlDocGen::RECORD:
2481 if (sing) return "Record";
2482 else return "Records";
2483 case VhdlDocGen::PROCEDURE:
2484 if (sing) return "Procedure";
2485 else return "Procedures";
2486 case VhdlDocGen::ARCHITECTURE:
2487 if (sing) return "Architecture";
2488 else return "Architectures";
2489 case VhdlDocGen::ATTRIBUTE:
2490 if (sing) return "Attribute";
2491 else return "Attributes";
2492 case VhdlDocGen::PROCESS:
2493 if (sing) return "Process";
2494 else return "Processes";
2495 case VhdlDocGen::PORT:
2496 if (sing) return "Port";
2497 else return "Ports";
2498 case VhdlDocGen::USE:
2499 if (sing) return "use clause";
2500 else return "Use Clauses";
2501 case VhdlDocGen::GENERIC:
2502 if (sing) return "Generic";
2503 else return "Generics";
2504 case VhdlDocGen::PACKAGE_BODY:
2505 return "Package Body";
2506 case VhdlDocGen::UNITS:
2508 case VhdlDocGen::SHAREDVARIABLE:
2509 if (sing) return "Shared Variable";
2510 return "Shared Variables";
2511 case VhdlDocGen::VFILE:
2512 if (sing) return "File";
2514 case VhdlDocGen::GROUP:
2515 if (sing) return "Group";
2517 case VhdlDocGen::INSTANTIATION:
2518 if (sing) return "Instantiation";
2519 else return "Instantiations";
2520 case VhdlDocGen::ALIAS:
2521 if (sing) return "Alias";
2523 case VhdlDocGen::CONFIG:
2524 if (sing) return "Configuration";
2525 return "Configurations";
2526 case VhdlDocGen::MISCELLANEOUS:
2527 return "Miscellaneous";
2528 case VhdlDocGen::UCF_CONST:
2529 return "Constraints";
2535 QCString VhdlDocGen::trDesignUnitHierarchy()
2537 return "Design Unit Hierarchy";
2540 QCString VhdlDocGen::trDesignUnitList()
2542 return "Design Unit List";
2545 QCString VhdlDocGen::trDesignUnitMembers()
2547 return "Design Unit Members";
2550 QCString VhdlDocGen::trDesignUnitListDescription()
2552 return "Here is a list of all design unit members with links to "
2553 "the Entities they belong to:";
2556 QCString VhdlDocGen::trDesignUnitIndex()
2558 return "Design Unit Index";
2561 QCString VhdlDocGen::trDesignUnits()
2563 return "Design Units";
2566 QCString VhdlDocGen::trFunctionAndProc()
2568 return "Functions/Procedures/Processes";
2572 /*! writes a link if the string is linkable else a formatted string */
2574 void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
2578 ClassDef *cd=mdef->getClassDef();
2581 QCString n=cd->name();
2582 MemberDef* memdef=VhdlDocGen::findMember(n,mem);
2583 if (memdef && memdef->isLinkable())
2586 writeLink(memdef,ol);
2593 startFonts(mem,"vhdlchar",ol);
2598 void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
2600 ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd");
2601 // pIntf->resetCodeParserState();
2603 QCString codeFragment=mdef->documentation();
2605 if (cname.isEmpty())
2612 fi=codeFragment.find("\n",++fi);
2613 } while(fi>=0 && j++ <3);
2615 // show only the first four lines
2618 codeFragment=codeFragment.left(fi);
2619 codeFragment.append("\n .... ");
2623 codeFragment.prepend("\n");
2624 ol.pushGeneratorState();
2625 ol.startCodeFragment();
2626 pIntf->parseCode(ol, // codeOutIntf
2628 codeFragment, // input
2629 SrcLangExt_VHDL, // lang
2632 mdef->getFileDef(), // fileDef
2633 mdef->getStartBodyLine(), // startLine
2634 mdef->getEndBodyLine(), // endLine
2635 TRUE, // inlineFragment
2637 TRUE // show line numbers
2640 ol.endCodeFragment();
2641 ol.popGeneratorState();
2643 if (cname.isEmpty()) return;
2645 mdef->writeSourceDef(ol,cname);
2646 mdef->writeSourceRefs(ol,cname);
2647 mdef->writeSourceReffedBy(ol,cname);
2652 QCString VhdlDocGen::convertFileNameToClassName(QCString name)
2660 while((i=n.find("__"))>0)
2665 while((i=n.find("_1"))>0)
2667 n=n.replace(i,2,":");
2673 void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,bool altera)
2675 QCString ucFile(input);
2677 QCString newLine="\n";
2678 QCString comment("#!");
2681 while (!ucFile.isEmpty())
2683 int i=ucFile.find("\n");
2686 QCString temp=ucFile.left(i);
2687 temp=temp.stripWhiteSpace();
2688 bool bb=temp.stripPrefix("//");
2690 if (!temp.isEmpty())
2692 if (temp.stripPrefix(comment) )
2695 brief.append("\\n");
2697 else if (!temp.stripPrefix("#") && !bb)
2701 int i=temp.find("-name");
2704 temp=temp.remove(0,i+5);
2707 temp.stripPrefix("set_location_assignment");
2709 initUCF(entity,0,temp,lineNo,fileName,brief);
2713 QRegExp ee("[\\s=]");
2714 int i=temp.find(ee);
2715 QCString ff=temp.left(i);
2716 temp.stripPrefix(ff.data());
2718 if (!temp.isEmpty())
2720 initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
2726 ucFile=ucFile.remove(0,i+1);
2730 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief)
2732 if (qcs.isEmpty())return;
2734 QRegExp reg("[\\s=]");
2736 // bool bo=(qstricmp(type,qcs.data())==0);
2738 VhdlDocGen::deleteAllChars(qcs,';');
2739 qcs=qcs.stripWhiteSpace();
2741 int i= qcs.find(reg);
2746 VhdlDocGen::deleteAllChars(n,'#');
2753 qcs=qcs.remove(0,i+1);
2754 // qcs.prepend("|");
2756 qcs.stripPrefix("=");
2758 Entry* current=new Entry;
2759 current->spec=VhdlDocGen::UCF_CONST;
2760 current->section=Entry::VARIABLE_SEC;
2761 current->bodyLine=line;
2762 current->fileName=fileName;
2763 current->type="ucf_const";
2765 current->lang= SrcLangExt_VHDL ;
2767 // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2771 n+=VhdlDocGen::getRecordNumber();
2774 current->name= n+"_";
2775 current->name.append(VhdlDocGen::getRecordNumber().data());
2777 if (!brief.isEmpty())
2779 current->brief=brief;
2780 current->briefLine=line;
2781 current->briefFile=fileName;
2785 root->addSubEntry(current);
2789 static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2792 QCString largs(mdef->argsString());
2793 QCString n= splitString(largs, '#');
2794 // VhdlDocGen::adjustRecordMember(mdef);
2795 bool equ=(n.length()==largs.length());
2799 ol.writeString(n.data());
2801 ol.insertMemberAlign();
2804 if (mdef->name().contains("dummy")==0)
2810 ol.insertMemberAlign();
2813 VhdlDocGen::formatString(largs,ol,mdef);
2816 bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne)
2818 FileName *fn=Doxygen::inputNameList->getFirst();
2819 //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
2820 uint count=Doxygen::inputNameList->count();
2821 LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files);
2822 // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files);
2824 QCString co("Constraints");
2826 if (Config_getBool("HAVE_DOT") && Config_getEnum("DOT_IMAGE_FORMAT")=="svg")
2828 QCString ov = theTranslator->trDesignOverview();
2829 QCString ofile("vhdl_design_overview");
2830 LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,"");
2837 FileDef *fd=fn->at(i);
2838 if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
2840 file = convertNameToFile(fd->name().data(),FALSE,FALSE);
2841 LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
2851 // for cell_inst : [entity] work.proto [ (label|expr) ]
2852 QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
2856 QCString ent("entity");
2857 if (!entity.contains(":")) return "";
2859 QRegExp exp("[:()\\s]");
2860 QStringList ql=QStringList::split(exp,entity,FALSE);
2861 //int ii=ql.findIndex(ent);
2862 assert(ql.count()>=2);
2863 label = ql[0].utf8();
2864 entity = ql[1].utf8();
2865 if ((index=entity.findRev("."))>=0)
2867 entity.remove(0,index+1);
2873 ql=QStringList::split(exp,arch,FALSE);
2874 if (ql.count()>1) // expression
2879 return label; // label
2882 // use (configuration|entity|open) work.test [(cellfor)];
2884 QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
2887 QRegExp exp("[()\\s]");
2890 QStringList ql=QStringList::split(exp,entity,FALSE);
2892 if (ql.contains("open"))
2899 entity = ql[1].utf8();
2900 if ((index=entity.findRev("."))>=0)
2902 entity.remove(0,index+1);
2914 // find class with upper/lower letters
2915 ClassDef* VhdlDocGen::findVhdlClass(const char *className )
2918 ClassSDict::Iterator cli(*Doxygen::classSDict);
2920 for (;(cd=cli.current());++cli)
2922 if (qstricmp(className,cd->name().data())==0)
2931 //@param arch bit0:flipflop
2932 //@param binding e.g entity work.foo(bar)
2933 //@param label |label0|label1
2934 // label0:architecture name
2935 //@param confVhdl of configuration file (identifier::entity_name) or
2936 // the architecture if isInlineConf TRUE
2937 //@param isInlineConf
2938 //@param confN List of configurations
2940 void assignBinding(VhdlConfNode * conf)
2942 QList<Entry> instList=getVhdlInstList();
2943 QListIterator<Entry> eli(instList);
2945 ClassDef *archClass=0,*entClass=0;
2946 QCString archName,entityName;
2947 QCString arcBind,entBind;
2950 entBind=conf->binding;
2951 QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind);
2953 if (qstricmp(conf2,"configuration")==0)
2955 QList<VhdlConfNode> confList = getVhdlConfiguration();
2956 VhdlConfNode* vconf;
2957 // bool found=false;
2958 for (uint iter=0;iter<confList.count(); iter++)
2960 vconf= (VhdlConfNode *)confList.at(iter);
2961 QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0);
2965 entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1);
2966 QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2967 QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2969 archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data());
2970 entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data());
2975 else // conf2!=configuration
2978 if (conf->isInlineConf)
2981 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0);
2985 a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2986 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2989 archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data());
2990 entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data());
2993 QCString label=conf->compSpec.lower();
2994 //label.prepend("|");
2998 // err("architecture %s not found ! ",conf->confVhdl.data());
3002 archName=archClass->name();
3003 QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
3004 all=allOt.lower()=="all" ;
3005 others= allOt.lower()=="others";
3007 for (;(cur=eli.current());++eli)
3009 if (cur->exception.lower()==label || conf->isInlineConf)
3011 QCString sign,archy;
3015 archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
3022 QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower();
3023 QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower();
3025 QStringList ql=QStringList::split(",",inst1);
3027 for (uint j=0;j<ql.count();j++)
3029 QCString archy1,sign1;
3032 archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1);
3037 archy1=comp+":"+ql[j].utf8();
3038 sign1=cur->type+":"+cur->name;
3041 if (archy1==sign1.lower() && !cur->stat)
3043 // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
3044 ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data());
3046 if (entClass==0 || ent==0)
3051 addInstance(ent,archClass,entClass,cur);
3057 }//for each element in instList
3068 // file foo_arch.vhd
3069 // architecture xxx of foo is
3074 void VhdlDocGen::computeVhdlComponentRelations()
3077 QCString entity,arch,inst;
3078 QList<VhdlConfNode> confList = getVhdlConfiguration();
3080 for (uint iter=0;iter<confList.count(); iter++)
3082 VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
3083 if (!(conf->isInlineConf || conf->isLeaf))
3087 assignBinding(conf);
3090 QList<Entry> qsl= getVhdlInstList();
3091 QListIterator<Entry> eli(qsl);
3094 for (eli.toFirst();(cur=eli.current());++eli)
3096 if (cur->stat ) // was bind
3101 if (cur->includeName=="entity" || cur->includeName=="component" )
3103 entity=cur->includeName+" "+cur->type;
3104 QCString rr=VhdlDocGen::parseForBinding(entity,arch);
3106 else if (cur->includeName.isEmpty())
3111 ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity);
3112 inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
3113 ClassDef *cd=Doxygen::classSDict->find(inst);
3114 ClassDef *ar=Doxygen::classSDict->find(cur->args);
3121 // if (classEntity==0)
3122 // err("%s:%d:Entity:%s%s",cur->fileName.data(),cur->startLine,entity.data()," could not be found");
3124 addInstance(classEntity,ar,cd,cur);
3129 static void addInstance(ClassDef* classEntity, ClassDef* ar,
3130 ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
3138 //add component inst
3143 if (classEntity==cd) return;
3145 bName=classEntity->name();
3146 // fprintf(stderr,"\naddInstance %s to %s %s %s\n", classEntity->name().data(),cd->name().data(),ar->name().data(),cur->name);
3147 n1=classEntity->name().data();
3149 if (!cd->isBaseClass(classEntity, true, 0))
3151 cd->insertBaseClass(classEntity,n1,Public,Normal,0);
3155 VhdlDocGen::addBaseClass(cd,classEntity);
3158 if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
3160 classEntity->insertSubClass(cd,Public,Normal,0);
3161 classEntity->setLanguage(SrcLangExt_VHDL);
3165 QCString uu=cur->name;
3166 MemberDef *md=new MemberDef(
3167 ar->getDefFileName(), cur->startLine,cur->startColumn,
3169 Public, Normal, cur->stat,Member,
3170 MemberType_Variable,
3174 if (ar->getOutputFileBase())
3178 tg.fileName = ar->getOutputFileBase();
3180 md->setTagInfo(&tg);
3183 //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
3185 md->setLanguage(SrcLangExt_VHDL);
3186 md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
3187 md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
3188 md->setBodySegment(cur->startLine,-1) ;
3189 md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine);
3190 FileDef *fd=ar->getFileDef();
3194 QCString info="Info: Elaborating entity "+n1;
3195 fd=ar->getFileDef();
3196 info+=" for hierarchy ";
3198 QCString label=cur->type+":"+cur->write+":"+cur->name;
3199 label.replace(epr,":");
3201 fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data());
3204 ar->insertMember(md);
3209 void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
3211 QStringList ql=QStringList::split("#",largs,FALSE);
3212 uint len=ql.count();
3213 for(uint i=0;i<len;i++)
3215 QCString n=ql[i].utf8();
3216 VhdlDocGen::formatString(n,ol,mdef);
3217 if ((len-i)>1) ol.lineBreak();
3222 void VhdlDocGen::writeRecUnitDocu(
3223 const MemberDef *md,
3228 QStringList ql=QStringList::split("#",largs,FALSE);
3229 uint len=ql.count();
3230 ol.startParameterList(TRUE);
3233 for(uint i=0;i<len;i++)
3235 QCString n=ql[i].utf8();
3236 ol.startParameterType(first,"");
3237 ol.endParameterType();
3238 ol.startParameterName(TRUE);
3239 VhdlDocGen::formatString(n,ol,md);
3242 ol.endParameterName(FALSE,FALSE,FALSE);
3246 ol.endParameterName(TRUE,FALSE,TRUE);
3256 bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
3259 //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3262 err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
3267 if (cd->subClasses())
3269 BaseClassListIterator bcli(*cd->subClasses());
3270 for ( ; bcli.current() && !found ; ++bcli)
3272 ClassDef *ccd=bcli.current()->classDef;
3273 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3274 //printf("isSubClass() subclass %s\n",ccd->name().data());
3283 found=ccd->isBaseClass(scd,followInstances,level+1);
3291 void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
3293 if (cd->baseClasses())
3295 BaseClassListIterator bcli(*cd->baseClasses());
3296 for ( ; bcli.current() ; ++bcli)
3298 ClassDef *ccd=bcli.current()->classDef;
3301 QCString n = bcli.current()->usedName;
3302 int i = n.find('(');
3305 bcli.current()->usedName.append("(2)");
3308 static QRegExp reg("[0-9]+");
3309 QCString s=n.left(i);
3310 QCString r=n.right(n.length()-i);
3312 VhdlDocGen::deleteAllChars(r,')');
3313 VhdlDocGen::deleteAllChars(r,'(');
3314 r.setNum(r.toInt()+1);
3315 t.replace(reg,r.data());
3317 bcli.current()->usedName=s;
3318 bcli.current()->templSpecifiers=t;
3325 static QList<MemberDef> mdList;
3327 static MemberDef* findMemFlow(const MemberDef* mdef)
3329 for(uint j=0;j<mdList.count();j++)
3331 MemberDef* md=(MemberDef*)mdList.at(j);
3332 if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
3338 void VhdlDocGen::createFlowChart(const MemberDef *mdef)
3340 if (mdef==0) return;
3342 QCString codeFragment;
3344 if((mm=findMemFlow(mdef))!=0)
3346 // don't create the same flowchart twice
3347 VhdlDocGen::setFlowMember(mm);
3352 mdList.append(mdef);
3355 //fprintf(stderr,"\n create flow mem %s %p\n",mdef->name().data(),mdef);
3357 int actualStart= mdef->getStartBodyLine();
3358 int actualEnd=mdef->getEndBodyLine();
3359 FileDef* fd=mdef->getFileDef();
3360 bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment);
3363 VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd");
3364 VhdlDocGen::setFlowMember(mdef);
3366 QStrList filesInSameTu;
3367 pIntf->startTranslationUnit("");
3368 pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu);
3369 pIntf->finishTranslationUnit();
3372 void VhdlDocGen::resetCodeVhdlParserState()
3379 bool VhdlDocGen::isConstraint(const MemberDef *mdef)
3380 { return mdef->getMemberSpecifiers()==VhdlDocGen::UCF_CONST; }
3381 bool VhdlDocGen::isConfig(const MemberDef *mdef)
3382 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; }
3383 bool VhdlDocGen::isAlias(const MemberDef *mdef)
3384 { return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; }
3385 bool VhdlDocGen::isLibrary(const MemberDef *mdef)
3386 { return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; }
3387 bool VhdlDocGen::isGeneric(const MemberDef *mdef)
3388 { return mdef->getMemberSpecifiers()==VhdlDocGen::GENERIC; }
3389 bool VhdlDocGen::isPort(const MemberDef *mdef)
3390 { return mdef->getMemberSpecifiers()==VhdlDocGen::PORT; }
3391 bool VhdlDocGen::isComponent(const MemberDef *mdef)
3392 { return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT; }
3393 bool VhdlDocGen::isPackage(const MemberDef *mdef)
3394 { return mdef->getMemberSpecifiers()==VhdlDocGen::USE; }
3395 bool VhdlDocGen::isEntity(const MemberDef *mdef)
3396 { return mdef->getMemberSpecifiers()==VhdlDocGen::ENTITY; }
3397 bool VhdlDocGen::isConstant(const MemberDef *mdef)
3398 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONSTANT; }
3399 bool VhdlDocGen::isVType(const MemberDef *mdef)
3400 { return mdef->getMemberSpecifiers()==VhdlDocGen::TYPE; }
3401 bool VhdlDocGen::isSubType(const MemberDef *mdef)
3402 { return mdef->getMemberSpecifiers()==VhdlDocGen::SUBTYPE; }
3403 bool VhdlDocGen::isVhdlFunction(const MemberDef *mdef)
3404 { return mdef->getMemberSpecifiers()==VhdlDocGen::FUNCTION; }
3405 bool VhdlDocGen::isProcess(const MemberDef *mdef)
3406 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCESS; }
3407 bool VhdlDocGen::isSignal(const MemberDef *mdef)
3408 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3409 bool VhdlDocGen::isAttribute(const MemberDef *mdef)
3410 { return mdef->getMemberSpecifiers()==VhdlDocGen::ATTRIBUTE; }
3411 bool VhdlDocGen::isSignals(const MemberDef *mdef)
3412 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3413 bool VhdlDocGen::isProcedure(const MemberDef *mdef)
3414 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCEDURE; }
3415 bool VhdlDocGen::isRecord(const MemberDef *mdef)
3416 { return mdef->getMemberSpecifiers()==VhdlDocGen::RECORD; }
3417 bool VhdlDocGen::isArchitecture(const MemberDef *mdef)
3418 { return mdef->getMemberSpecifiers()==VhdlDocGen::ARCHITECTURE; }
3419 bool VhdlDocGen::isUnit(const MemberDef *mdef)
3420 { return mdef->getMemberSpecifiers()==VhdlDocGen::UNITS; }
3421 bool VhdlDocGen::isPackageBody(const MemberDef *mdef)
3422 { return mdef->getMemberSpecifiers()==VhdlDocGen::PACKAGE_BODY; }
3423 bool VhdlDocGen::isVariable(const MemberDef *mdef)
3424 { return mdef->getMemberSpecifiers()==VhdlDocGen::SHAREDVARIABLE; }
3425 bool VhdlDocGen::isFile(const MemberDef *mdef)
3426 { return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; }
3427 bool VhdlDocGen::isGroup(const MemberDef *mdef)
3428 { return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; }
3429 bool VhdlDocGen::isCompInst(const MemberDef *mdef)
3430 { return mdef->getMemberSpecifiers()==VhdlDocGen::INSTANTIATION; }
3431 bool VhdlDocGen::isMisc(const MemberDef *mdef)
3432 { return mdef->getMemberSpecifiers()==VhdlDocGen::MISCELLANEOUS; }
3436 //############################## Flowcharts #################################################
3438 #define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
3439 FlowChart::FOR_NO | FlowChart::CASE_NO | \
3440 FlowChart::LOOP_NO | WHEN_NO)
3441 #define DECLN (FlowChart::WHEN_NO | \
3442 FlowChart::ELSIF_NO | FlowChart::IF_NO | \
3443 FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3444 FlowChart::CASE_NO | FlowChart::LOOP_NO )
3445 #define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
3446 #define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3447 FlowChart::LOOP_NO )
3448 #define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
3449 #define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
3450 #define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
3451 #define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
3452 #define EMPTY (EEND | FlowChart::ELSIF_NO)
3453 #define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
3454 #define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
3455 #define FLOWLEN (flowList.count()-1)
3457 static int ifcounter=0;
3458 static int nodeCounter=0;
3463 const char *textNodeLink;
3464 const char *yesNodeLink;
3465 const char *noNodeLink;
3468 const char* comment;
3469 const char* decisionNode;
3470 const char* varNode;
3471 const char *startEndNode;
3472 const char* textNode;
3474 { "green", // textNodeLink
3475 "red", // yesNodeLink
3476 "black", // noNodeLink
3478 "0.7 0.3 1.0", // decisionNode
3479 "lightyellow", // varNode
3480 "white", // startEndNode
3481 "lightcyan" // textNode
3484 QList<FlowChart> FlowChart::flowList;
3487 static QMap<QCString,int> keyMap;
3490 void alignText(QCString & q)
3492 if (q.length()<=80) return;
3501 QRegExp reg("[\\s|]");
3502 QCString str(q.data());
3505 while (str.length()>80)
3507 int j=str.findRev(reg,80);
3516 QCString qcs=str.left(j);
3527 void FlowChart::printNode(const FlowChart* flo)
3532 QRegExp ep("[\t\n\r]");
3536 if (flo->type & STARTL)
3540 q=ui.left(2*flo->stamp);
3546 QCString nn=flo->exp.stripWhiteSpace();
3547 printf("\nYES: %s%s[%d,%d]",q.data(),nn.data(),flo->stamp,flo->id);
3551 if (flo->type & COMMENT_NO)
3566 q=ui.left(2*flo->stamp);
3572 if (flo->type & EMPTNODE)
3574 printf("\n NO: %s%s[%d,%d]",q.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3576 else if (flo->type & COMMENT_NO)
3578 printf("\n NO: %s%s[%d,%d]",t.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3582 printf("\n NO: %s%s[%d,%d]",q.data(),t.data(),flo->stamp,flo->id);
3587 void FlowChart::printFlowTree()
3589 uint size=flowList.count();
3590 for (uint j=0;j<size;j++)
3592 printNode(flowList.at(j));
3596 void FlowChart::colTextNodes()
3601 for (uint j=0;j<flowList.count();j++)
3603 FlowChart *flo=flowList.at(j);
3604 if (flo->type&TEXT_NO)
3606 text+=flo->text+'\n';
3613 flno->text+=flo->text;
3614 flowList.remove(flo);
3623 // find if..endif without text
3624 // if..elseif without text
3625 for (uint j=0;j<flowList.count()-1;j++)
3627 FlowChart *flo=flowList.at(j);
3629 if ( (kind & IFF) || (flo->type & ELSE_NO))
3631 FlowChart *ftemp=flowList.at(j+1);
3632 if (ftemp->type & EMPTY)
3634 FlowChart *fNew = new FlowChart(TEXT_NO,"empty ",0);
3635 fNew->stamp=flo->stamp;
3636 flowList.insert(j+1,fNew);
3643 QCString FlowChart::getNodeName(int n)
3647 return node.prepend("node");
3650 void FlowChart::delFlowList()
3654 uint size=flowList.count();
3656 for (uint j=0;j <size ;j++)
3658 FlowChart *fll=flowList.at(j);
3664 void FlowChart::alignCommentNode(FTextStream &t,QCString com)
3668 QStringList ql=QStringList::split("\n",com);
3669 for (uint j=0;j<ql.count();j++)
3671 s=(QCString)ql[j].utf8();
3672 if (max<s.length()) max=s.length();
3676 int diff=max-s.length();
3684 ql.remove(ql.last());
3688 for (uint j=0;j<ql.count();j++)
3690 s=(QCString)ql[j].utf8();
3695 FlowChart::codify(t,s.data());
3700 void FlowChart::buildCommentNodes(FTextStream & t)
3702 uint size=flowList.count();
3705 for (uint j=0;j < size-1 ;j++)
3707 FlowChart *fll=flowList.at(j);
3708 if (fll->type & COMMENT_NO)
3710 FlowChart* to=flowList.at(j+1);
3711 if (to->type & COMMENT_NO)
3714 QCString temp=fll->label+to->label;
3723 for (uint j=0;j <flowList.count() ;j++)
3725 FlowChart *fll=flowList.at(j);
3727 if (fll->type & BEGIN_NO)
3733 if (fll->type & COMMENT_NO)
3738 // comment between function/process .. begin is linked to start node
3743 if (j>0 && flowList.at(j-1)->line==fll->line)
3744 to=flowList.at(j-1);
3746 to=flowList.at(j+1);
3748 t << getNodeName(fll->id);
3749 t << "[shape=none, label=<\n";
3750 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
3751 t << "<TR><TD BGCOLOR=\"";
3752 t << flowCol.comment;
3755 FlowChart::alignCommentNode(t,fll->label);
3756 t << " </TD></TR></TABLE>>];";
3757 writeEdge(t,fll->id,to->id,2);
3761 // delete comment nodes;
3762 size=flowList.count();
3763 for (uint j=0;j < size;j++)
3765 FlowChart *fll=flowList.at(j);
3766 if (fll->type & (COMMENT_NO | BEGIN_NO))
3777 void FlowChart::codify(FTextStream &t,const char *str)
3788 case '<': t << "<"; break;
3789 case '>': t << ">"; break;
3790 case '&': t << "&"; break;
3791 case '\'': t << "'"; break;
3792 case '"': t << """; break;
3793 case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
3794 default: t << c; break;
3800 FlowChart::~FlowChart()
3804 FlowChart::FlowChart(int typ,const char * t,const char* ex,const char* lab)
3818 if (typ & (ELSE_NO | ELSIF_NO))
3823 if (typ & (START_NO | END_NO | VARIABLE_NO))
3831 void FlowChart::addFlowChart(int type,const char* text,const char* exp, const char *label)
3833 static QRegExp reg("[;]");
3834 static QRegExp reg1("[\"]");
3836 if (!VhdlDocGen::getFlowMember()) return;
3838 QCString typeString(text);
3839 QCString expression(exp);
3844 typeString=typeString.replace(reg,"\n");
3849 expression=expression.replace(reg1,"\\\"");
3852 FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label);
3854 fl->line=vhdl::parser::VhdlParser::getLine();
3856 if (type & (START_NO | VARIABLE_NO))
3858 flowList.prepend(fl);
3862 flowList.append(fl);
3867 void FlowChart::moveToPrevLevel()
3869 if (!VhdlDocGen::getFlowMember()) return;
3874 QCString FlowChart::convertNameToFileName()
3876 static QRegExp exp ("[^][a-z_A-Z0-9]");
3878 const MemberDef* md=VhdlDocGen::getFlowMember();
3880 temp.sprintf("%p",md);
3883 if (qcs.find(exp,0)>=0)
3886 qcs=qcs.replace(exp,"_");
3892 const char* FlowChart::getNodeType(int c)
3896 case IF_NO: return "if ";
3897 case ELSIF_NO: return "elsif ";
3898 case ELSE_NO: return "else ";
3899 case CASE_NO: return "case ";
3900 case WHEN_NO: return "when ";
3901 case EXIT_NO: return "exit ";
3902 case END_NO: return "end ";
3903 case TEXT_NO: return "text ";
3904 case START_NO: return "start ";
3905 case ENDIF_NO: return "endif ";
3906 case FOR_NO: return "for ";
3907 case WHILE_NO: return "while ";
3908 case END_LOOP: return "end_loop ";
3909 case END_CASE: return "end_case ";
3910 case VARIABLE_NO: return "variable_decl ";
3911 case RETURN_NO: return "return ";
3912 case LOOP_NO: return "infinte loop ";
3913 case NEXT_NO: return "next ";
3914 case COMMENT_NO: return "comment ";
3915 case EMPTY_NO: return "empty ";
3916 case BEGIN_NO: return "<begin> ";
3917 default: return "--failure--";
3921 void FlowChart::createSVG()
3924 QCString ov = Config_getString("HTML_OUTPUT");
3926 qcs+=FlowChart::convertNameToFileName()+".svg";
3928 //const MemberDef *m=VhdlDocGen::getFlowMember();
3930 // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data());
3932 QCString dir=" -o "+ov+qcs;
3933 ov+="/flow_design.dot";
3935 QCString vlargs="-Tsvg "+ov+dir ;
3937 if (portable_system("dot",vlargs)!=0)
3939 err("could not create dot file");
3943 void FlowChart::startDot(FTextStream &t)
3945 t << " digraph G { \n";
3946 t << "rankdir=TB \n";
3947 t << "concentrate=true\n";
3948 t << "stylesheet=\"doxygen.css\"\n";
3951 void FlowChart::endDot(FTextStream &t)
3956 void FlowChart::writeFlowChart()
3958 // assert(VhdlDocGen::flowMember);
3960 QCString ov = Config_getString("HTML_OUTPUT");
3961 QCString fileName = ov+"/flow_design.dot";
3965 if (!f.open(IO_WriteOnly))
3967 err("Cannot open file %s for writing\n",fileName.data());
3978 buildCommentNodes(t);
3980 uint size=flowList.count();
3982 for (uint j=0;j <size ;j++)
3984 FlowChart *fll=flowList.at(j);
3989 FlowChart::endDot(t);
3992 FlowChart::createSVG();
3995 void FlowChart::writeShape(FTextStream &t,const FlowChart* fl)
3997 if (fl->type & EEND) return;
3999 if (fl->type & LOOP)
4003 else if (fl->type & IFF)
4012 t<<getNodeName(fl->id).data();
4013 QCString q=getNodeType(fl->type);
4016 QCString qq(getNodeName(fl->id).data());
4017 keyMap.insert(qq,fl->id);
4020 bool dec=(fl->type & DECLN);
4021 bool exit=(fl->type & EXITNEXT);
4022 if (exit && !fl->exp.isEmpty())
4028 QCString exp=fl->exp;
4031 t << " [shape=diamond,style=filled,color=\"";
4032 t << flowCol.decisionNode;
4033 t << "\",label=\" ";
4035 if (exit) kl=fl->text+" ";
4039 kl+=fl->label+":"+exp+var;
4046 FlowChart::alignCommentNode(t,kl);
4049 else if (fl->type & ENDCL)
4051 QCString val=fl->text;
4052 t << " [shape=ellipse ,label=\""+val+"\"]\n";
4054 else if (fl->type & STARTFIN)
4056 QCString val=fl->text;
4057 t << "[shape=box , style=rounded label=<\n";
4058 t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
4059 t << "<TR><TD BGCOLOR=\"";
4060 t<< flowCol.startEndNode;
4062 FlowChart::alignCommentNode(t,val);
4063 t << " </TD></TR></TABLE>>];";
4067 if (fl->text.isEmpty()) return;
4068 bool var=(fl->type & FlowChart::VARIABLE_NO);
4069 QCString repl("<BR ALIGN=\"LEFT\"/>");
4070 QCString q=fl->text;
4077 int z=q.findRev("\n");
4079 if (z==(int)q.length()-1)
4083 t << "[shape=none margin=0.1, label=<\n";
4084 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
4087 t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
4091 t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
4093 FlowChart::alignCommentNode(t,q);
4094 t << " </TD></TR></TABLE>>];";
4099 void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i)
4101 bool b=fl_from->type & STARTL;
4102 bool c=fl_to->type & STARTL;
4105 QCString s1(getNodeName(fl_from->id).data());
4106 QCString s2(getNodeName(fl_to->id).data());
4107 QMap<QCString, int>::Iterator it = keyMap.find(s1);
4108 QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
4109 // checks if the link is connected to a valid node
4114 writeEdge(t,fl_from->id,fl_to->id,i,b,c);
4117 void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
4123 col=flowCol.yesNodeLink;
4128 col=flowCol.noNodeLink;
4133 col=flowCol.textNodeLink;
4137 t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
4138 t << getNodeName(fl_from).data();
4139 if (bFrom) t << ":s";
4141 t << getNodeName(fl_to).data();
4146 void FlowChart::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc)
4150 ArgumentListIterator ali(*al);
4151 int index=ali.count();
4152 if (index==0) return;
4154 int len=q.length()+VhdlDocGen::getFlowMember()->name().length();
4156 prev.fill(' ',len+1);
4160 for (;(arg=ali.current());++ali)
4162 QCString attl=arg->defval+" ";
4163 attl+=arg->name+" ";
4167 attl+=arg->attrib+" ";
4174 if (--index) attl+=",\n"; else attl+="\n";
4176 attl.prepend(prev.data());
4183 int FlowChart::findNextLoop(int index,int stamp)
4185 for (uint j=index+1;j<flowList.count();j++)
4187 FlowChart *flo=flowList.at(j);
4188 if (flo->stamp==stamp)
4192 if (flo->type&END_LOOP)
4197 return flowList.count()-1;
4200 int FlowChart::findPrevLoop(int index,int stamp,bool endif)
4202 for (uint j=index;j>0;j--)
4204 FlowChart *flo=flowList.at(j);
4205 if (flo->type & LOOP)
4207 if (flo->stamp==stamp && endif)
4213 if (flo->stamp<stamp)
4220 return flowList.count()-1;
4223 int FlowChart::findLabel(int index,QCString &label)
4225 for (uint j=index;j>0;j--)
4227 FlowChart *flo=flowList.at(j);
4228 if ((flo->type & LOOP) && !flo->label.isEmpty() && qstricmp(flo->label,label)==0)
4233 err("could not find label: ",label.data());
4237 int FlowChart::findNode(int index,int stamp,int type)
4239 for (uint j=index+1;j<flowList.count();j++)
4241 FlowChart *flo=flowList.at(j);
4242 if (flo->type==type && flo->stamp==stamp)
4250 int FlowChart::getNextNode(int index,int stamp)
4252 for (uint j=index+1;j<flowList.count();j++)
4254 FlowChart *flo=flowList.at(j);
4261 if (kind & ENDIF_NO)
4263 if (s<stamp && stamp>0)
4269 if (kind & (ELSE_NO | ELSIF_NO))
4271 if (s<stamp && stamp>0)
4275 j=findNode(j,stamp,ENDIF_NO);
4280 if (s<stamp && stamp>0)
4284 return findNode(j,stamp-1,END_CASE);
4291 int FlowChart::getNextIfLink(const FlowChart* fl,uint index)
4293 int stamp=fl->stamp;
4294 uint start = index+1;
4295 int endifNode = findNode(start,stamp,ENDIF_NO);
4296 int elseifNode = findNode(start,stamp,ELSIF_NO);
4297 int elseNode = findNode(start,stamp,ELSE_NO);
4299 assert(endifNode>-1);
4301 if (elseifNode>0 && elseifNode<endifNode)
4306 if (elseNode>0 && elseNode<endifNode)
4311 stamp=flowList.at(endifNode)->stamp;
4312 return getNextNode(endifNode,stamp);
4315 void FlowChart::writeFlowLinks(FTextStream &t)
4317 uint size=flowList.count();
4321 writeEdge(t,flowList.at(0),flowList.at(1),2);
4323 for (uint j=0;j<size;j++)
4325 FlowChart *fll=flowList.at(j);
4327 int stamp=fll->stamp;
4335 writeEdge(t,fll,flowList.at(j+1),0);
4336 int z=getNextIfLink(fll,j);
4338 writeEdge(t,fll,flowList.at(z),1);
4340 else if (kind & LOOP_NO)
4342 writeEdge(t,fll,flowList.at(j+1),2);
4345 else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
4349 writeEdge(t,fll,flowList.at(j+1),2);
4354 writeEdge(t,fll,flowList.at(j+1),0);
4358 int z=findNode(j+1,fll->stamp,kind);
4359 z=getNextNode(z,flowList.at(z)->stamp);
4362 writeEdge(t,fll,flowList.at(z),1);
4365 else if (kind & (TEXT_NO | VARIABLE_NO))
4367 int z=getNextNode(j,stamp);
4368 writeEdge(t,fll,flowList.at(z),2);
4370 else if (kind & WHEN_NO)
4373 if (qstricmp(fll->text.simplifyWhiteSpace().data(),"others")==0)
4375 writeEdge(t,fll,flowList.at(j+1),2);
4380 writeEdge(t,fll,flowList.at(j+1),0);
4381 int u=findNode(j,stamp,WHEN_NO);
4382 int v=findNode(j,stamp-1,END_CASE);
4386 writeEdge(t,fll,flowList.at(u),1);
4390 writeEdge(t,fll,flowList.at(v),1);
4393 else if (kind & END_CASE)
4395 int z=FlowChart::getNextNode(j,fll->stamp);
4396 writeEdge(t,fll,flowList.at(z),2);
4398 else if (kind & END_LOOP)
4400 int z=findPrevLoop(j,fll->stamp,true);
4401 writeEdge(t,fll,flowList.at(z),2);
4403 else if (kind & RETURN_NO)
4405 writeEdge(t,fll,FlowChart::flowList.at(size-1),2);
4407 else if (kind & (EXIT_NO | NEXT_NO))
4410 bool b = kind==NEXT_NO;
4413 writeEdge(t,fll,flowList.at(j+1),1);
4415 if (!fll->label.isEmpty())
4417 z=findLabel(j,fll->label);
4420 writeEdge(t,fll,flowList.at(z),0);
4424 z=findNode(z,flowList.at(z)->stamp,END_LOOP);
4425 z=getNextNode(z,flowList.at(z)->stamp);
4426 writeEdge(t,fll,flowList.at(z),0);
4434 z=findPrevLoop(j,fll->stamp);
4435 writeEdge(t,fll,flowList.at(z),0);
4440 z =findNextLoop(j,fll->stamp-1);
4442 z=getNextNode(z,flowList.at(z)->stamp);
4444 writeEdge(t,fll,flowList.at(z),0);
4450 void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
4451 const char *scopeName,
4452 const QCString &input,
4454 bool isExampleBlock,
4455 const char *exampleName,
4459 bool inlineFragment,
4460 MemberDef *memberDef,
4461 bool showLineNumbers,
4462 Definition *searchCtx,
4467 parseVhdlCode(codeOutIntf,