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"
50 #include "vhdlscanner.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"
62 #define theTranslator_vhdlType VhdlDocGen::trVhdlType
64 static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
65 static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
66 static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
67 static QDict<QCString> g_xilinxUcfDict(17,FALSE);
69 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
70 static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
71 static void assignBinding(VhdlConfNode* conf);
72 static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
74 //---------- create svg -------------------------------------------------------------
75 static void createSVG();
76 static void startDot(FTextStream &t);
77 static void startTable(FTextStream &t,const QCString &className);
78 static QList<MemberDef>* getPorts(ClassDef *cd);
79 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
80 static void endDot(FTextStream &t);
81 static void writeTable(QList<MemberDef>* port,FTextStream & t);
82 static void endTabel(FTextStream &t);
83 static void writeClassToDot(FTextStream &t,ClassDef* cd);
84 static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
85 //static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
86 static const MemberDef *flowMember=0;
88 void VhdlDocGen::setFlowMember( const MemberDef* mem)
93 const MemberDef* VhdlDocGen::getFlowMember()
100 //--------------------------------------------------------------------------------------------------
101 static void codify(FTextStream &t,const char *str)
112 case '<': t << "<";
114 case '>': t << ">";
116 case '&': t << "&";
118 case '\'': t << "'";
120 case '"': t << """;
129 static void writeLink(const MemberDef* mdef,OutputList &ol)
131 ol.writeObjectLink(mdef->getReference(),
132 mdef->getOutputFileBase(),
137 static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
139 ol.startFontClass(keyword);
144 static QCString splitString(QCString& str,char c)
151 str=str.remove(0,i+1);
156 static int compareString(const QCString& s1,const QCString& s2)
158 return qstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
161 static void createSVG()
163 QCString ov =Config_getString("HTML_OUTPUT");
164 QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
165 ov+="/vhdl_design.dot";
168 QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
170 QCString dotExe = Config_getString("DOT_PATH")+"dot";
171 if (portable_system(dotExe,vlargs)!=0)
173 err("could not create dot file");
177 // Creates a svg image. All in/out/inout ports are shown with brief description and direction.
178 // Brief descriptions for entities are shown too.
179 void VhdlDocGen::writeOverview()
181 ClassSDict::Iterator cli(*Doxygen::classSDict);
184 for ( ; (cd=cli.current()) ; ++cli )
186 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )
195 QCString ov =Config_getString("HTML_OUTPUT");
196 QCString fileName=ov+"/vhdl_design.dot";
201 if (!f.open(IO_WriteOnly))
203 fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
209 for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
211 if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS )
216 QList<MemberDef>* port= getPorts(cd);
221 if (port->count()==0)
228 startTable(t,cd->name());
229 writeClassToDot(t,cd);
233 // writeVhdlPortToolTip(t,port,cd);
234 writeVhdlEntityToolTip(t,cd);
237 BaseClassList *bl=cd->baseClasses();
240 BaseClassListIterator bcli(*bl);
242 for ( ; (bcd=bcli.current()) ; ++bcli )
244 ClassDef *bClass=bcd->classDef;
245 QCString dotn=cd->name()+":";
247 QCString csc=bClass->name()+":";
249 // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
250 writeVhdlDotLink(t,dotn,csc,0);
256 // writePortLinks(t);
261 //------------------------------------------------------------------------------------------------------------------------------------------------------
263 static void startDot(FTextStream &t)
265 t << " digraph G { \n";
266 t << "rankdir=LR \n";
267 t << "concentrate=TRUE\n";
268 t << "stylesheet=\"doxygen.css\"\n";
271 static void endDot(FTextStream &t)
276 static void startTable(FTextStream &t,const QCString &className)
278 t << className <<" [ shape=none , fontname=\"arial\", fontcolor=\"blue\" , \n";
279 t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
282 static void writeVhdlDotLink(FTextStream &t,
283 const QCString &a,const QCString &b,const QCString &style)
286 if (!style.isEmpty())
288 t << "[style=" << style << "];\n";
294 static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
298 QCString repl("<BR ALIGN=\"LEFT\"/>");
299 QCString file=cd->getDefFileName();
301 int k=cd->briefLine();
303 QStringList qsl=QStringList::split(ep,brief);
304 for(uint j=0;j<qsl.count();j++)
306 QCString qcs=qsl[j].data();
307 vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
312 vForm.replace(ep,repl.data());
317 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
320 uint len=port->count();
323 for (uint j=0;j<len;j++)
325 md=(MemberDef*)port->at(j);
326 QCString brief=md->briefDescriptionAsTooltip();
327 if (brief.isEmpty()) continue;
329 QCString node="node";
330 node+=VhdlDocGen::getRecordNumber();
331 t << node <<"[shape=box margin=0.1, label=<\n";
332 t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
333 t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
335 t<<" </TD></TR></TABLE>>];";
336 QCString dotn=cd->name()+":";
338 // writeVhdlDotLink(t,dotn,node,"dotted");
344 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd)
347 QCString brief=cd->briefDescription();
349 if (brief.isEmpty()) return;
351 brief=formatBriefNote(brief,cd);
353 QCString node="node";
354 node+=VhdlDocGen::getRecordNumber();
355 t << node <<"[shape=none margin=0.1, label=<\n";
356 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
357 t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
359 t << " </TD></TR></TABLE>>];";
360 QCString dotn=cd->name()+":";
362 writeVhdlDotLink(t,dotn,node,"dotted");
365 static void writeColumn(FTextStream &t,MemberDef *md,bool start)
369 static QRegExp reg("[%]");
370 bool bidir=(md!=0 &&( qstricmp(md->typeString(),"inout")==0));
374 toolTip=md->briefDescriptionAsTooltip();
375 if (!toolTip.isEmpty())
377 QCString largs = md->argsString();
378 if (!largs.isEmpty())
379 largs=largs.replace(reg," ");
390 t << "<TD ALIGN=\"LEFT\" ";
394 t << md->getOutputFileBase()<< Doxygen::htmlFileExtension;
395 t << "#" << md->anchor();
399 if(!toolTip.isEmpty())
400 codify(t,toolTip.data());
402 QCString largs = md->argsString();
403 if(!largs.isEmpty()){
404 largs=largs.replace(reg," ");
405 codify(t,largs.data());
414 if (!toolTip.isEmpty())
416 // if (!toolTip.isEmpty())
419 t << "BGCOLOR=\"orange\">";
421 t << "BGCOLOR=\"azure\">";
425 t << "BGCOLOR=\"pink\">";
429 t << "BGCOLOR=\"lightgrey\">";
447 static void endTabel(FTextStream &t)
453 static void writeClassToDot(FTextStream &t,ClassDef* cd)
455 t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
460 t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
464 t << " </TD></TR>\n";
467 static QList<MemberDef>* getPorts(ClassDef *cd)
470 QList<MemberDef> *portList=new QList<MemberDef>;
471 MemberList *ml=cd->getMemberList(MemberListType_variableMembers);
473 if (ml==0) return NULL;
475 MemberListIterator fmni(*ml);
477 for (fmni.toFirst();(md=fmni.current());++fmni)
479 if (md->getMemberSpecifiers()==VhdlDocGen::PORT)
481 portList->append(md);
488 //writeColumn(FTextStream &t,QCString name,bool start)
490 static void writeTable(QList<MemberDef>* port,FTextStream & t)
494 uint len=port->count();
496 QList<MemberDef> inPorts;
497 QList<MemberDef> outPorts;
502 md=(MemberDef*)port->at(j);
503 QCString qc=md->typeString();
514 int inp = inPorts.count();
515 int outp = outPorts.count();
528 for(i=0;i<maxLen;i++)
533 md=(MemberDef*)inPorts.at(i);
534 writeColumn(t,md,TRUE);
538 writeColumn(t,NULL,TRUE);
543 md=(MemberDef*)outPorts.at(i);
544 writeColumn(t,md,FALSE);
548 writeColumn(t,NULL,FALSE);
553 //--------------------------------------------------------------------------------------------------
556 VhdlDocGen::VhdlDocGen()
560 VhdlDocGen::~VhdlDocGen()
564 void VhdlDocGen::init()
567 // vhdl keywords inlcuded VHDL 2008
568 const char* g_vhdlKeyWordMap0[] =
570 "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
571 "begin","block","body","buffer","bus",
572 "case","component","configuration","constant","context","cover",
573 "default","disconnect","downto",
574 "else","elsif","end","entity","exit",
575 "fairness","file","for","force","function",
576 "generate","generic","group","guarded",
577 "if","impure","in","inertial","inout","is",
578 "label","library","linkage","literal","loop",
580 "nand","new","next","nor","not","null",
581 "of","on","open","or","others","out",
582 "package","parameter","port","postponed","procedure","process","property","proctected","pure",
583 "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
584 "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
585 "then","to","transport","type",
586 "unaffected","units","until","use",
587 "variable","vmode","vprop","vunit",
588 "wait","when","while","with",
594 const char* g_vhdlKeyWordMap1[] =
596 "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
597 "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
598 "real","float","ufixed","sfixed","time",0
602 const char* g_vhdlKeyWordMap2[] =
604 "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
609 g_vhdlKeyDict0.setAutoDelete(TRUE);
610 g_vhdlKeyDict1.setAutoDelete(TRUE);
611 g_vhdlKeyDict2.setAutoDelete(TRUE);
614 while (g_vhdlKeyWordMap0[j])
616 g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
617 new QCString(g_vhdlKeyWordMap0[j]));
622 while (g_vhdlKeyWordMap1[j])
624 g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
625 new QCString(g_vhdlKeyWordMap1[j]));
630 while (g_vhdlKeyWordMap2[j])
632 g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
633 new QCString(g_vhdlKeyWordMap2[j]));
640 * returns the color of a keyword
643 QCString* VhdlDocGen::findKeyWord(const QCString& word)
645 static QCString g_vhdlkeyword("vhdlkeyword");
646 static QCString g_vhdltype("comment");
647 static QCString g_vhdllogic("vhdllogic");
649 if (word.isEmpty() || word.at(0)=='\0') return 0;
651 if (g_vhdlKeyDict0.find(word.lower()))
652 return &g_vhdlkeyword;
654 if (g_vhdlKeyDict1.find(word.lower()))
657 if (g_vhdlKeyDict2.find(word.lower()))
663 ClassDef *VhdlDocGen::getClass(const char *name)
665 if (name==0 || name[0]=='\0') return 0;
670 temp=temp.stripWhiteSpace();
671 cd= Doxygen::classSDict->find(temp.data());
675 ClassDef* VhdlDocGen::getPackageName(const QCString & name)
678 QStringList ql=QStringList::split(".",name,FALSE);
684 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
686 QDict<QCString> packages(17,FALSE);
687 packages.setAutoDelete(TRUE);
691 cd=getClass(className);
692 //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
695 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_variableMembers);
696 if (mdef) return mdef;
697 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
698 if (mdef) return mdef;
700 // nothing found so far
701 // if we are an architecture or package body search in entitiy
703 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
704 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
706 Definition *d = cd->getOuterScope();
707 // searching upper/lower case names
709 QCString tt=d->name();
710 ClassDef *ecd =getClass(tt);
722 if (ecd) //d && d->definitionType()==Definition::TypeClass)
724 //ClassDef *ecd = (ClassDef*)d;
725 mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberListType_variableMembers);
726 if (mdef) return mdef;
727 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
728 if (mdef) return mdef;
730 //cd=getClass(getClassName(cd));
733 // nothing found , so we are now searching all included packages
734 VhdlDocGen::findAllPackages(className,packages);
735 //cd=getClass(className.data());
736 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
737 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
739 Definition *d = cd->getOuterScope();
741 QCString tt=d->name();
742 ClassDef *ecd =getClass(tt);
754 if (ecd) //d && d->definitionType()==Definition::TypeClass)
756 VhdlDocGen::findAllPackages(ecd->className(),packages);
760 QDictIterator<QCString> packli(packages);
762 for (packli.toFirst();(curString=packli.current());++packli)
766 cd=VhdlDocGen::getPackageName(*curString);
769 *curString=curString->upper();
770 cd=VhdlDocGen::getPackageName(*curString);
774 *curString=curString->lower();
775 cd=VhdlDocGen::getPackageName(*curString);
780 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_variableMembers);
781 if (mdef) return mdef;
782 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
783 if (mdef) return mdef;
790 * This function returns the entity|package
791 * in which the key (type) is found
794 MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberListType type)
796 // return cd->getMemberByName(key);//does not work
799 MemberList *ml= cd->getMemberList(type);
802 MemberListIterator fmni(*ml);
804 for (fmni.toFirst();(md=fmni.current());++fmni)
806 if (qstricmp(key,md->name())==0)
815 * finds all included packages of an Entity or Package
818 void VhdlDocGen::findAllPackages(const QCString& className,QDict<QCString>& qdict)
820 ClassDef *cdef=getClass(className);
823 MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
828 MemberListIterator fmni(*mem);
829 for (fmni.toFirst();(md=fmni.current());++fmni)
831 if (VhdlDocGen::isPackage(md))
833 QCString *temp1=new QCString(md->name().data());
834 //*temp1=temp1->lower();
835 QCString p(md->name().data());
837 ClassDef* cd=VhdlDocGen::getPackageName(*temp1);
840 QCString *ss=qdict.find(*temp1);
843 qdict.insert(p,temp1);
844 QCString tmp=cd->className();
845 VhdlDocGen::findAllPackages(tmp,qdict);
857 * returns the function with the matching argument list
858 * is called in vhdlcode.l
861 MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
862 const QCString& funcname,
863 const QCString& package, bool /*type*/)
867 ClassDef *cdef=getClass(package.data());
868 if (cdef==0) return 0;
870 MemberList *mem=cdef->getMemberList(MemberListType_pubMethods);
874 MemberListIterator fmni(*mem);
875 for (fmni.toFirst();(mdef=fmni.current());++fmni)
877 QCString mname=mdef->name();
878 if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
880 ArgumentList *alp = mdef->argumentList();
882 // ArgumentList* arg2=mdef->getArgumentList();
884 ArgumentListIterator ali(*alp);
885 ArgumentListIterator ali1(ql);
887 if (ali.count() != ali1.count()) break;
892 for (;(arg=ali.current());++ali)
894 arg1=ali1.current(); ++ali1;
895 equ+=abs(compareString(arg->type,arg1->type));
897 QCString s1=arg->type;
898 QCString s2=arg1->type;
899 VhdlDocGen::deleteAllChars(s1,' ');
900 VhdlDocGen::deleteAllChars(s2,' ');
901 equ+=abs(compareString(s1,s2));
904 VhdlDocGen::deleteAllChars(s1,' ');
905 VhdlDocGen::deleteAllChars(s2,' ');
906 equ+=abs(compareString(s1,s2));
907 // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
908 // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
910 if (equ==0) return mdef;
921 * returns the class title+ref
924 QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
927 if (cd==0) return "";
928 pageTitle+=cd->displayName();
929 pageTitle=VhdlDocGen::getClassName(cd);
930 int ii=cd->protection();
932 pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
937 /* returns the class name without their prefixes */
939 QCString VhdlDocGen::getClassName(const ClassDef* cd)
942 if (cd==0) return "";
944 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
947 temp.stripPrefix("_");
951 return substitute(cd->className(),"::",".");
955 * writes an inline link form entity|package to architecture|package body and vice verca
958 void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol)
961 ql.setAutoDelete(TRUE);
962 QCString nn=cd->className();
963 int ii=(int)cd->protection()+2;
966 if (ii==VhdlDocGen::ENTITY)
967 type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE);
968 else if (ii==VhdlDocGen::ARCHITECTURE)
969 type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE);
970 else if (ii==VhdlDocGen::PACKAGE_BODY)
971 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
972 else if (ii==VhdlDocGen::PACKAGE)
973 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE);
979 ol.disable(OutputGenerator::RTF);
980 ol.disable(OutputGenerator::Man);
982 if (ii==VhdlDocGen::PACKAGE_BODY)
985 cd=getClass(nn.data());
987 else if (ii==VhdlDocGen::PACKAGE)
990 cd=getClass(nn.data());
992 else if (ii==VhdlDocGen::ARCHITECTURE)
994 QStringList qlist=QStringList::split("-",nn,FALSE);
996 cd=VhdlDocGen::getClass(nn.data());
1000 if (ii==VhdlDocGen::ENTITY)
1002 VhdlDocGen::findAllArchitectures(ql,cd);
1004 for (int i=0;i<j;i++)
1006 QCString *temp=ql.at(i);
1007 QStringList qlist=QStringList::split("-",*temp,FALSE);
1008 QCString s1=qlist[0].utf8();
1009 QCString s2=qlist[1].utf8();
1010 s1.stripPrefix("_");
1011 if (j==1) s1.resize(0);
1012 ClassDef*cc = getClass(temp->data());
1015 VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
1021 VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
1024 ol.enable(OutputGenerator::Man);
1025 ol.enable(OutputGenerator::RTF);
1030 * finds all architectures which belongs to an entiy
1032 void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
1035 ClassSDict::Iterator cli(*Doxygen::classSDict);
1036 for ( ; (citer=cli.current()) ; ++cli )
1038 QCString jj=citer->className();
1039 if (cd != citer && jj.contains('-')!=-1)
1041 QStringList ql=QStringList::split("-",jj,FALSE);
1042 QCString temp=ql[1].utf8();
1043 if (qstricmp(cd->className(),temp)==0)
1045 QCString *cl=new QCString(jj);
1050 }//findAllArchitectures
1052 ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd)
1055 QCString nn=cd->name();
1056 ClassSDict::Iterator cli(*Doxygen::classSDict);
1058 for ( ; (citer=cli.current()) ; ++cli )
1060 QCString jj=citer->name();
1061 QStringList ql=QStringList::split(":",jj,FALSE);
1064 if (ql[0].utf8()==nn )
1073 * writes the link entity >> .... or architecture >> ...
1076 void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
1079 QCString temp=ccd->getOutputFileBase();
1081 ol.docify(type.data());
1083 nn.stripPrefix("_");
1084 ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
1086 if (!behav.isEmpty())
1090 ol.docify(behav.data());
1099 * strips the "--" prefixes of vhdl comments
1101 void VhdlDocGen::prepareComment(QCString& qcs)
1103 const char* s="--!";
1108 index=qcs.find(s,0,TRUE);
1110 qcs=qcs.remove(index,qstrlen(s));
1112 qcs=qcs.stripWhiteSpace();
1117 * parses a function proto
1118 * @param text function string
1119 * @param qlist stores the function types
1120 * @param name points to the function name
1121 * @param ret Stores the return type
1124 void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
1125 QCString& name,QCString& ret,bool doc)
1127 (void)qlist; //unused
1133 end=s1.findRev(")");
1137 QCString tt=s1.mid(index,(end-index+1));
1138 temp=s1.mid(index+1,(end-index-1));
1139 //getFuncParams(qlist,temp);
1143 name=s1.left(index);
1144 name=name.stripWhiteSpace();
1154 s1=s1.stripWhiteSpace();
1155 int i=s1.find("(",0,FALSE);
1156 int s=s1.find(QRegExp("[ \\t]"));
1158 s1=VhdlDocGen::getIndexWord(s1.data(),1);
1159 else // s<i, s=start of name, i=end of name
1162 name=s1.stripWhiteSpace();
1164 index=s1.findRev("return",-1,FALSE);
1167 ret=s1.mid(index+6,s1.length());
1168 ret=ret.stripWhiteSpace();
1169 VhdlDocGen::deleteCharRev(ret,';');
1174 * returns the n'th word of a string
1177 QCString VhdlDocGen::getIndexWord(const char* c,int index)
1181 QRegExp reg("[\\s:|]");
1183 ql=QStringList::split(reg,temp,FALSE);
1185 if (ql.count() > (unsigned int)index)
1187 return ql[index].utf8();
1194 QCString VhdlDocGen::getProtectionName(int prot)
1196 if (prot==VhdlDocGen::ENTITYCLASS)
1198 else if (prot==VhdlDocGen::ARCHITECTURECLASS)
1199 return "architecture";
1200 else if (prot==VhdlDocGen::PACKAGECLASS)
1202 else if (prot==VhdlDocGen::PACKBODYCLASS)
1203 return "package body";
1208 QCString VhdlDocGen::trTypeString(uint64 type)
1212 case VhdlDocGen::LIBRARY: return "Library";
1213 case VhdlDocGen::ENTITY: return "Entity";
1214 case VhdlDocGen::PACKAGE_BODY: return "Package Body";
1215 case VhdlDocGen::ATTRIBUTE: return "Attribute";
1216 case VhdlDocGen::PACKAGE: return "Package";
1217 case VhdlDocGen::SIGNAL: return "Signal";
1218 case VhdlDocGen::COMPONENT: return "Component";
1219 case VhdlDocGen::CONSTANT: return "Constant";
1220 case VhdlDocGen::TYPE: return "Type";
1221 case VhdlDocGen::SUBTYPE: return "Subtype";
1222 case VhdlDocGen::FUNCTION: return "Function";
1223 case VhdlDocGen::RECORD: return "Record";
1224 case VhdlDocGen::PROCEDURE: return "Procedure";
1225 case VhdlDocGen::ARCHITECTURE: return "Architecture";
1226 case VhdlDocGen::USE: return "Package";
1227 case VhdlDocGen::PROCESS: return "Process";
1228 case VhdlDocGen::PORT: return "Port";
1229 case VhdlDocGen::GENERIC: return "Generic";
1230 case VhdlDocGen::UNITS: return "Units";
1231 //case VhdlDocGen::PORTMAP: return "Port Map";
1232 case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
1233 case VhdlDocGen::GROUP: return "Group";
1234 case VhdlDocGen::VFILE: return "File";
1235 case VhdlDocGen::INSTANTIATION: return "Instantiation";
1236 case VhdlDocGen::ALIAS: return "Alias";
1237 case VhdlDocGen::CONFIG: return "Configuration";
1238 case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous";
1239 case VhdlDocGen::UCF_CONST: return "Constraints";
1245 * deletes a char backwards in a string
1248 bool VhdlDocGen::deleteCharRev(QCString &s,char c)
1250 int index=s.findRev(c,-1,FALSE);
1253 QCString qcs=s.remove(index,1);
1260 void VhdlDocGen::deleteAllChars(QCString &s,char c)
1262 int index=s.findRev(c,-1,FALSE);
1265 QCString qcs=s.remove(index,1);
1267 index=s.findRev(c,-1,FALSE);
1272 static int recordCounter=0;
1275 * returns the next number of a record|unit member
1278 QCString VhdlDocGen::getRecordNumber()
1281 sprintf(buf,"%d",recordCounter++);
1282 QCString qcs(&buf[0]);
1287 * returns the next number of an anonymous process
1290 QCString VhdlDocGen::getProcessNumber()
1292 static int stringCounter;
1294 QCString qcs("PROCESS_");
1295 sprintf(buf,"%d",stringCounter++);
1296 qcs.append(&buf[0]);
1301 * writes a colored and formatted string
1304 void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
1306 QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
1308 qcs+=QCString(" ");// parsing the last sign
1317 j = reg.match(temp.data(),0,&len);
1326 ss=VhdlDocGen::findKeyWord(find);
1327 bool k=isNumber(find); // is this a number
1331 startFonts(find,"vhdldigit",ol);
1334 else if (j != 0 && ss)
1336 startFonts(find,ss->data(),ol);
1342 VhdlDocGen::writeStringLink(mdef,find,ol);
1345 startFonts(&buf[0],"vhdlchar",ol);
1347 QCString st=temp.remove(0,j+1);
1349 if (!find.isEmpty() && find.at(0)=='"')
1351 int ii=find.find('"',2);
1354 QCString com=find.left(ii+1);
1355 startFonts(com,"keyword",ol);
1356 temp=find.remove(0,ii+1);
1363 j = reg.match(temp.data(),0,&len);
1368 startFonts(find,"vhdlchar",ol);
1371 }// writeFormatString
1374 * returns TRUE if this string is a number
1376 bool VhdlDocGen::isNumber(const QCString& s)
1378 static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
1380 if (s.isEmpty()) return FALSE;
1382 j = regg.match(s.data(),0,&len);
1383 if ((j==0) && (len==(int)s.length())) return TRUE;
1390 * inserts white spaces for better readings
1391 * and writes a colored string to the output
1394 void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
1397 QCString temp(qcs.length());
1398 qcs.stripPrefix(":");
1399 qcs.stripPrefix("is");
1400 qcs.stripPrefix("IS");
1401 qcs.stripPrefix("of");
1402 qcs.stripPrefix("OF");
1404 // VhdlDocGen::deleteCharRev(qcs,';');
1406 int len = qcs.length();
1407 unsigned int index=1;//temp.length();
1409 for (int j=0;j<len;j++)
1413 if (j>0) b=qcs[j-1];
1414 if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
1416 if (temp.at(index-1) != ' ')
1425 if (b==':') // := operator
1427 temp.replace(index-1,1,"=");
1442 index=temp.length();
1444 temp=temp.stripWhiteSpace();
1445 // printf("\n [%s]",qcs.data());
1446 VhdlDocGen::writeFormatString(temp,ol,mdef);
1450 * writes a procedure prototype to the output
1453 void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1455 ArgumentListIterator ali(*al);
1458 int len=al->count();
1464 for (;(arg=ali.current());++ali)
1470 QCString nn=arg->name;
1473 QCString *str=VhdlDocGen::findKeyWord(arg->defval);
1477 startFonts(arg->defval,str->data(),ol);
1481 startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
1484 startFonts(nn,"vhdlchar",ol); // write name
1485 if (qstricmp(arg->attrib,arg->type) != 0)
1487 startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
1490 VhdlDocGen::formatString(arg->type,ol,mdef);
1506 * writes a function prototype to the output
1509 void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1512 ArgumentListIterator ali(*al);
1515 int len=al->count();
1523 for (;(arg=ali.current());++ali)
1526 QCString att=arg->defval;
1527 bool bGen=att.stripPrefix("gen!");
1535 VhdlDocGen::formatString(QCString("generic "),ol,mdef);
1539 QCString *str=VhdlDocGen::findKeyWord(att);
1542 VhdlDocGen::formatString(att,ol,mdef);
1544 startFonts(att,"vhdlchar",ol);
1547 QCString nn=arg->name;
1549 QCString ss=arg->type.stripWhiteSpace(); //.lower();
1550 QCString w=ss.stripWhiteSpace();//.upper();
1551 startFonts(nn,"vhdlchar",ol);
1552 startFonts("in ","stringliteral",ol);
1553 QCString *str=VhdlDocGen::findKeyWord(ss);
1555 VhdlDocGen::formatString(w,ol,mdef);
1557 startFonts(w,"vhdlchar",ol);
1560 startFonts(arg->attrib,"vhdlchar",ol);
1572 const char *exp=mdef->excpString();
1575 ol.insertMemberAlign();
1586 * writes a process prototype to the output
1589 void VhdlDocGen::writeProcessProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1592 ArgumentListIterator ali(*al);
1597 for (;(arg=ali.current());++ali)
1603 QCString nn=arg->name;
1604 // startFonts(nn,"vhdlchar",ol);
1605 VhdlDocGen::writeFormatString(nn,ol,mdef);
1614 * writes a function|procedure documentation to the output
1617 bool VhdlDocGen::writeFuncProcDocu(
1618 const MemberDef *md,
1620 const ArgumentList* al,
1623 if (al==0) return FALSE;
1627 ArgumentListIterator ali(*al);
1628 int index=ali.count();
1634 ol.endMemberDocName();
1635 ol.startParameterList(TRUE);
1636 //ol.startParameterName(FALSE);
1639 for (;(arg=ali.current());++ali)
1641 ol.startParameterType(first,"");
1642 // if (first) ol.writeChar('(');
1643 QCString attl=arg->defval;
1644 bool bGen=attl.stripPrefix("gen!");
1646 VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
1649 if (VhdlDocGen::isProcedure(md))
1651 startFonts(arg->defval,"keywordtype",ol);
1654 ol.endParameterType();
1656 ol.startParameterName(TRUE);
1657 VhdlDocGen::writeFormatString(arg->name,ol,md);
1659 if (VhdlDocGen::isProcedure(md))
1661 startFonts(arg->attrib,"stringliteral",ol);
1663 else if (VhdlDocGen::isVhdlFunction(md))
1665 startFonts(QCString("in"),"stringliteral",ol);
1669 ol.disable(OutputGenerator::Man);
1671 ol.enable(OutputGenerator::Man);
1672 if (!VhdlDocGen::isProcess(md))
1674 // startFonts(arg->type,"vhdlkeyword",ol);
1675 VhdlDocGen::writeFormatString(arg->type,ol,md);
1677 ol.disable(OutputGenerator::Man);
1679 ol.enable(OutputGenerator::Man);
1687 // ol.docify(" ) ");
1688 ol.endParameterName(TRUE,FALSE,TRUE);
1691 ol.endParameterName(FALSE,FALSE,FALSE);
1696 //ol.endParameterList();
1699 } // writeDocFunProc
1704 QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool func)
1708 ArgumentListIterator ali(*al);
1711 for (;(arg=ali.current());++ali)
1713 if (sem) argString.append(", ");
1716 argString+=arg->name;
1718 argString+=arg->type;
1722 argString+=arg->defval+" ";
1723 argString+=arg->name+" :";
1724 argString+=arg->attrib+" ";
1725 argString+=arg->type;
1733 void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
1734 OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
1736 static ClassDef *cdef;
1737 //static GroupDef* gdef;
1739 { // only one inline link
1740 VhdlDocGen::writeInlineClassLink(cd,ol);
1745 if (gd && gdef==gd) return;
1751 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
1752 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
1753 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
1754 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
1755 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONSTANT,FALSE),0,FALSE,VhdlDocGen::CONSTANT);
1756 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::TYPE,FALSE),0,FALSE,VhdlDocGen::TYPE);
1757 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SUBTYPE,FALSE),0,FALSE,VhdlDocGen::SUBTYPE);
1758 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GENERIC,FALSE),0,FALSE,VhdlDocGen::GENERIC);
1759 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PORT,FALSE),0,FALSE,VhdlDocGen::PORT);
1760 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCESS,FALSE),0,FALSE,VhdlDocGen::PROCESS);
1761 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SIGNAL,FALSE),0,FALSE,VhdlDocGen::SIGNAL);
1762 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ATTRIBUTE,FALSE),0,FALSE,VhdlDocGen::ATTRIBUTE);
1763 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCEDURE,FALSE),0,FALSE,VhdlDocGen::PROCEDURE);
1764 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::RECORD,FALSE),0,FALSE,VhdlDocGen::RECORD);
1765 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UNITS,FALSE),0,FALSE,VhdlDocGen::UNITS);
1766 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE);
1767 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE);
1768 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP);
1769 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION);
1770 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS);
1771 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS);
1773 // configurations must be added to global file definitions.
1774 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG);
1775 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
1779 static void setGlobalType(MemberList *ml)
1783 MemberListIterator mmli(*ml);
1784 for ( ; (mdd=mmli.current()); ++mmli )
1786 QCString l=mdd->typeString();
1788 if (qstrcmp(mdd->argsString(),"package")==0)
1790 mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
1792 else if (qstrcmp(mdd->argsString(),"configuration")==0)
1794 mdd->setMemberSpecifiers(VhdlDocGen::CONFIG);
1796 else if (qstrcmp(mdd->typeString(),"library")==0)
1798 mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY);
1800 else if (qstrcmp(mdd->typeString(),"use")==0)
1802 mdd->setMemberSpecifiers(VhdlDocGen::USE);
1804 else if (qstricmp(mdd->typeString(),"misc")==0)
1806 mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
1808 else if (qstricmp(mdd->typeString(),"ucf_const")==0)
1810 mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
1815 /* writes a vhdl type documentation */
1816 bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol)
1818 ClassDef *cd=(ClassDef*)d;
1819 bool hasParams = FALSE;
1821 if (cd==0) return hasParams;
1823 QCString ttype=mdef->typeString();
1824 QCString largs=mdef->argsString();
1826 if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
1828 QCString nn=mdef->typeString();
1829 nn=nn.stripWhiteSpace();
1830 QCString na=cd->name();
1831 MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1832 if (memdef && memdef->isLinkable())
1837 writeLink(memdef,ol);
1844 VhdlDocGen::formatString(ttype,ol,mdef);
1847 ol.docify(mdef->name());
1848 hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
1852 if (mdef->isVariable())
1854 if (VhdlDocGen::isConstraint(mdef))
1859 largs=largs.replace(QRegExp("#")," ");
1860 VhdlDocGen::formatString(largs,ol,mdef);
1866 if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
1873 // QCString largs=mdef->argsString();
1875 bool c=largs=="context";
1876 bool brec=largs.stripPrefix("record") ;
1879 VhdlDocGen::formatString(ttype,ol,mdef);
1881 if (c || brec || largs.stripPrefix("units"))
1885 VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1890 if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1892 // QCString largs=mdef->argsString();
1893 VhdlDocGen::formatString(largs,ol,mdef);
1900 /* writes a vhdl type declaration */
1902 void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
1903 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1906 static QRegExp reg("[%]");
1910 /* some vhdl files contain only a configuration description
1913 configuration cfg_tb_jtag_gotoBackup of tb_jtag_gotoBackup is
1916 end cfg_tb_jtag_gotoBackup;
1918 in this case library work does not belong to an entity, package ...
1922 ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
1923 mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY ||
1924 mdef->getMemberSpecifiers()==VhdlDocGen::USE
1925 ); // member should belong to something
1930 else d=(Definition*)mdef;
1932 // write tag file information of this member
1933 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1935 Doxygen::tagFile << " <member kind=\"";
1936 if (VhdlDocGen::isGeneric(mdef)) Doxygen::tagFile << "generic";
1937 if (VhdlDocGen::isPort(mdef)) Doxygen::tagFile << "port";
1938 if (VhdlDocGen::isEntity(mdef)) Doxygen::tagFile << "entity";
1939 if (VhdlDocGen::isComponent(mdef)) Doxygen::tagFile << "component";
1940 if (VhdlDocGen::isVType(mdef)) Doxygen::tagFile << "type";
1941 if (VhdlDocGen::isConstant(mdef)) Doxygen::tagFile << "constant";
1942 if (VhdlDocGen::isSubType(mdef)) Doxygen::tagFile << "subtype";
1943 if (VhdlDocGen::isVhdlFunction(mdef)) Doxygen::tagFile << "function";
1944 if (VhdlDocGen::isProcedure(mdef)) Doxygen::tagFile << "procedure";
1945 if (VhdlDocGen::isProcess(mdef)) Doxygen::tagFile << "process";
1946 if (VhdlDocGen::isSignals(mdef)) Doxygen::tagFile << "signal";
1947 if (VhdlDocGen::isAttribute(mdef)) Doxygen::tagFile << "attribute";
1948 if (VhdlDocGen::isRecord(mdef)) Doxygen::tagFile << "record";
1949 if (VhdlDocGen::isLibrary(mdef)) Doxygen::tagFile << "library";
1950 if (VhdlDocGen::isPackage(mdef)) Doxygen::tagFile << "package";
1951 if (VhdlDocGen::isVariable(mdef)) Doxygen::tagFile << "shared variable";
1952 if (VhdlDocGen::isFile(mdef)) Doxygen::tagFile << "file";
1953 if (VhdlDocGen::isGroup(mdef)) Doxygen::tagFile << "group";
1954 if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << " instantiation";
1955 if (VhdlDocGen::isAlias(mdef)) Doxygen::tagFile << "alias";
1956 if (VhdlDocGen::isCompInst(mdef)) Doxygen::tagFile << "configuration";
1958 Doxygen::tagFile << "\">" << endl;
1959 Doxygen::tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
1960 Doxygen::tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
1961 Doxygen::tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
1962 Doxygen::tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
1964 if (VhdlDocGen::isVhdlFunction(mdef))
1965 Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),TRUE)) << "</arglist>" << endl;
1966 else if (VhdlDocGen::isProcedure(mdef))
1967 Doxygen::tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),FALSE)) << "</arglist>" << endl;
1969 Doxygen::tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
1971 mdef->writeDocAnchorsToTagFile();
1972 Doxygen::tagFile << " </member>" << endl;
1976 // write search index info
1977 if (Doxygen::searchIndex)
1979 Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
1980 Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
1981 Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
1984 QCString cname = d->name();
1985 QCString cfname = d->getOutputFileBase();
1987 //HtmlHelp *htmlHelp=0;
1988 // bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
1989 // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1991 // search for the last anonymous scope in the member type
1992 ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
1994 // start a new member declaration
1995 bool isAnonymous = annoClassDef; // || m_impl->annMemb || m_impl->annEnumType;
1996 ///printf("startMemberItem for %s\n",name().data());
1997 int mm=mdef->getMemberSpecifiers();
1998 if (mm==VhdlDocGen::MISCELLANEOUS)
2001 ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
2003 // If there is no detailed description we need to write the anchor here.
2004 bool detailsVisible = mdef->isDetailedSectionLinkable();
2005 if (!detailsVisible) // && !m_impl->annMemb)
2007 QCString doxyName=mdef->name().copy();
2008 if (!cname.isEmpty()) doxyName.prepend(cname+"::");
2009 QCString doxyArgs=mdef->argsString();
2010 ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
2012 ol.pushGeneratorState();
2013 ol.disable(OutputGenerator::Man);
2014 ol.disable(OutputGenerator::Latex);
2016 ol.popGeneratorState();
2022 QCString ltype(mdef->typeString());
2023 // ltype=ltype.replace(reg," ");
2024 QCString largs(mdef->argsString());
2025 // largs=largs.replace(reg," ");
2026 mdef->setType(ltype.data());
2027 mdef->setArgsString(largs.data());
2028 //ClassDef * plo=mdef->getClassDef();
2030 ArgumentList *alp = mdef->argumentList();
2032 //VhdlDocGen::adjustRecordMember(mdef);
2036 case VhdlDocGen::MISCELLANEOUS:
2037 VhdlDocGen::writeSource(mdef,ol,nn);
2039 case VhdlDocGen::PROCEDURE:
2040 case VhdlDocGen::FUNCTION:
2042 VhdlDocGen::formatString(ltype,ol,mdef);
2044 ol.insertMemberAlign();
2048 if (alp!=0 && mm==VhdlDocGen::FUNCTION)
2049 VhdlDocGen::writeFunctionProto(ol,alp,mdef);
2051 if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
2052 VhdlDocGen::writeProcedureProto(ol,alp,mdef);
2055 case VhdlDocGen::USE:
2056 kl=VhdlDocGen::getClass(mdef->name());
2057 if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
2059 ol.insertMemberAlign();
2064 nn=kl->getOutputFileBase();
2065 ol.pushGeneratorState();
2066 ol.disableAllBut(OutputGenerator::Html);
2068 QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
2070 ol.docify(name.data());
2073 name+=" <"+mdef->name()+">";
2075 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2076 ol.popGeneratorState();
2079 case VhdlDocGen::LIBRARY:
2081 ol.insertMemberAlign();
2082 if (largs=="context")
2084 VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
2089 case VhdlDocGen::GENERIC:
2090 case VhdlDocGen::PORT:
2091 case VhdlDocGen::ALIAS:
2095 ol.insertMemberAlign();
2096 if (mm==VhdlDocGen::GENERIC)
2099 VhdlDocGen::formatString(largs,ol,mdef);
2106 VhdlDocGen::formatString(ltype,ol,mdef);
2109 VhdlDocGen::formatString(largs,ol,mdef);
2112 case VhdlDocGen::PROCESS:
2114 ol.insertMemberAlign();
2115 VhdlDocGen::writeProcessProto(ol,alp,mdef);
2117 case VhdlDocGen::PACKAGE:
2118 case VhdlDocGen::ENTITY:
2119 case VhdlDocGen::COMPONENT:
2120 case VhdlDocGen::INSTANTIATION:
2121 case VhdlDocGen::CONFIG:
2122 if (VhdlDocGen::isCompInst(mdef) )
2125 if(nn.stripPrefix("function") || nn.stripPrefix("package"))
2127 VhdlDocGen::formatString(largs,ol,mdef);
2128 ol.insertMemberAlign();
2131 VhdlDocGen::formatString(ltype,ol,mdef);
2135 largs.prepend("::");
2136 largs.prepend(mdef->name().data());
2137 ol.writeObjectLink(mdef->getReference(),
2145 ol.insertMemberAlign();
2152 if (VhdlDocGen::isComponent(mdef) ||
2153 VhdlDocGen::isConfig(mdef) ||
2154 VhdlDocGen::isCompInst(mdef))
2156 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2158 nn=mdef->getOutputFileBase();
2165 kl=getClass(nn.data());
2168 nn=kl->getOutputFileBase();
2169 ol.pushGeneratorState();
2170 ol.disableAllBut(OutputGenerator::Html);
2172 QCString name("<Entity ");
2173 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2179 name+=mdef->name()+"> ";
2181 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2183 ol.popGeneratorState();
2187 case VhdlDocGen::UCF_CONST:
2188 mm=mdef->name().findRev('_');
2191 mdef->setName(mdef->name().left(mm));
2193 writeUCFLink(mdef,ol);
2195 case VhdlDocGen::SIGNAL:
2196 case VhdlDocGen::ATTRIBUTE:
2197 case VhdlDocGen::SUBTYPE:
2198 case VhdlDocGen::CONSTANT:
2199 case VhdlDocGen::SHAREDVARIABLE:
2200 case VhdlDocGen::VFILE:
2201 case VhdlDocGen::GROUP:
2204 ol.insertMemberAlign();
2205 VhdlDocGen::formatString(ltype,ol,mdef);
2207 case VhdlDocGen::TYPE:
2208 bRec=largs.stripPrefix("record") ;
2209 bUnit=largs.stripPrefix("units") ;
2211 if (bRec) ol.docify("record: ");
2212 if (bUnit) ol.docify("units: ");
2214 ol.insertMemberAlign();
2215 if (!bRec) VhdlDocGen::formatString(ltype,ol,mdef);
2216 if (bUnit) ol.lineBreak();
2217 if (bRec || bUnit) writeRecorUnit(largs,ol,mdef);
2224 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2225 if (htmlOn && !ltype.isEmpty())
2227 ol.disable(OutputGenerator::Html);
2229 if (!ltype.isEmpty()) ol.docify(" ");
2233 ol.enable(OutputGenerator::Html);
2236 if (!detailsVisible)// && !m_impl->annMemb)
2238 ol.endDoxyAnchor(cfname,mdef->anchor());
2241 //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
2242 // name().data(),annoClassDef,annEnumType);
2244 if (!mdef->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC") /* && !annMemb */)
2246 ol.startMemberDescription(mdef->anchor());
2247 ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
2248 mdef->getOuterScope()?mdef->getOuterScope():d,
2249 mdef,mdef->briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
2252 ol.pushGeneratorState();
2253 ol.disableAllBut(OutputGenerator::Html);
2256 if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
2258 ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
2262 ol.startTextLink(0,mdef->anchor());
2265 //ol.startEmphasis();
2266 ol.popGeneratorState();
2268 //ol.newParagraph();
2269 ol.endMemberDescription();
2271 mdef->warnIfUndocumented();
2273 }// end writeVhdlDeclaration
2276 void VhdlDocGen::writePlainVHDLDeclarations(
2277 MemberList* mlist,OutputList &ol,
2278 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
2281 SDict<QCString> pack(1009);
2285 MemberListIterator mli(*mlist);
2286 for ( ; (md=mli.current()); ++mli )
2288 int mems=md->getMemberSpecifiers();
2289 if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
2291 if (first) {ol.startMemberList();first=FALSE;}
2292 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2294 else if (md->isBriefSectionVisible() && (mems==specifier))
2296 if (!pack.find(md->name().data()))
2298 if (first) ol.startMemberList(),first=FALSE;
2299 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2300 pack.append(md->name().data(),new QCString(md->name().data()));
2304 if (!first) ol.endMemberList();
2308 static bool membersHaveSpecificType(MemberList *ml,uint64 type)
2310 if (ml==0) return FALSE;
2312 MemberListIterator mmli(*ml);
2313 for ( ; (mdd=mmli.current()); ++mmli )
2315 if (mdd->getMemberSpecifiers()==type) //is type in class
2320 if (ml->getMemberGroupList())
2322 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2324 while ((mg=mgli.current()))
2328 if (membersHaveSpecificType(mg->members(),type)) return TRUE;
2336 void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
2337 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
2338 const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
2341 if (!membersHaveSpecificType(ml,type)) return;
2345 ol.startMemberHeader(title);
2346 ol.parseText(title);
2347 ol.endMemberHeader();
2350 if (subtitle && subtitle[0]!=0)
2352 ol.startMemberSubtitle();
2353 ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
2354 ol.endMemberSubtitle();
2355 } //printf("memberGroupList=%p\n",memberGroupList);
2357 VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
2359 if (ml->getMemberGroupList())
2361 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2363 while ((mg=mgli.current()))
2365 if (membersHaveSpecificType(mg->members(),type))
2367 //printf("mg->header=%s\n",mg->header().data());
2368 bool hasHeader=mg->header()!="[NOHEADER]";
2369 ol.startMemberGroupHeader(hasHeader);
2372 ol.parseText(mg->header());
2374 ol.endMemberGroupHeader();
2375 if (!mg->documentation().isEmpty())
2377 //printf("Member group has docs!\n");
2378 ol.startMemberGroupDocs();
2379 ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
2380 ol.endMemberGroupDocs();
2382 ol.startMemberGroup();
2383 //printf("--- mg->writePlainDeclarations ---\n");
2384 VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
2385 ol.endMemberGroup(hasHeader);
2390 }// writeVHDLDeclarations
2393 bool VhdlDocGen::writeClassType( ClassDef *& cd,
2394 OutputList &ol ,QCString & cname)
2396 int id=cd->protection();
2397 QCString qcs = VhdlDocGen::trTypeString(id+2);
2398 cname=VhdlDocGen::getClassName(cd);
2400 ol.writeString(qcs.data());
2401 ol.writeString(" ");
2403 //ol.insertMemberAlign();
2407 QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
2411 case VhdlDocGen::LIBRARY:
2412 if (sing) return "Library";
2413 else return "Libraries";
2414 case VhdlDocGen::PACKAGE:
2415 if (sing) return "Package";
2416 else return "Packages";
2417 case VhdlDocGen::SIGNAL:
2418 if (sing) return "Signal";
2419 else return "Signals";
2420 case VhdlDocGen::COMPONENT:
2421 if (sing) return "Component";
2422 else return "Components";
2423 case VhdlDocGen::CONSTANT:
2424 if (sing) return "Constant";
2425 else return "Constants";
2426 case VhdlDocGen::ENTITY:
2427 if (sing) return "Entity";
2428 else return "Entities";
2429 case VhdlDocGen::TYPE:
2430 if (sing) return "Type";
2431 else return "Types";
2432 case VhdlDocGen::SUBTYPE:
2433 if (sing) return "Subtype";
2434 else return "Subtypes";
2435 case VhdlDocGen::FUNCTION:
2436 if (sing) return "Function";
2437 else return "Functions";
2438 case VhdlDocGen::RECORD:
2439 if (sing) return "Record";
2440 else return "Records";
2441 case VhdlDocGen::PROCEDURE:
2442 if (sing) return "Procedure";
2443 else return "Procedures";
2444 case VhdlDocGen::ARCHITECTURE:
2445 if (sing) return "Architecture";
2446 else return "Architectures";
2447 case VhdlDocGen::ATTRIBUTE:
2448 if (sing) return "Attribute";
2449 else return "Attributes";
2450 case VhdlDocGen::PROCESS:
2451 if (sing) return "Process";
2452 else return "Processes";
2453 case VhdlDocGen::PORT:
2454 if (sing) return "Port";
2455 else return "Ports";
2456 case VhdlDocGen::USE:
2457 if (sing) return "use clause";
2458 else return "Use Clauses";
2459 case VhdlDocGen::GENERIC:
2460 if (sing) return "Generic";
2461 else return "Generics";
2462 case VhdlDocGen::PACKAGE_BODY:
2463 return "Package Body";
2464 case VhdlDocGen::UNITS:
2466 case VhdlDocGen::SHAREDVARIABLE:
2467 if (sing) return "Shared Variable";
2468 return "Shared Variables";
2469 case VhdlDocGen::VFILE:
2470 if (sing) return "File";
2472 case VhdlDocGen::GROUP:
2473 if (sing) return "Group";
2475 case VhdlDocGen::INSTANTIATION:
2476 if (sing) return "Instantiation";
2477 else return "Instantiations";
2478 case VhdlDocGen::ALIAS:
2479 if (sing) return "Alias";
2481 case VhdlDocGen::CONFIG:
2482 if (sing) return "Configuration";
2483 return "Configurations";
2484 case VhdlDocGen::MISCELLANEOUS:
2485 return "Miscellaneous";
2486 case VhdlDocGen::UCF_CONST:
2487 return "Constraints";
2493 QCString VhdlDocGen::trDesignUnitHierarchy()
2495 return "Design Unit Hierarchy";
2498 QCString VhdlDocGen::trDesignUnitList()
2500 return "Design Unit List";
2503 QCString VhdlDocGen::trDesignUnitMembers()
2505 return "Design Unit Members";
2508 QCString VhdlDocGen::trDesignUnitListDescription()
2510 return "Here is a list of all design unit members with links to "
2511 "the Entities they belong to:";
2514 QCString VhdlDocGen::trDesignUnitIndex()
2516 return "Design Unit Index";
2519 QCString VhdlDocGen::trDesignUnits()
2521 return "Design Units";
2524 QCString VhdlDocGen::trFunctionAndProc()
2526 return "Functions/Procedures/Processes";
2530 /*! writes a link if the string is linkable else a formatted string */
2532 void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
2536 ClassDef *cd=mdef->getClassDef();
2539 QCString n=cd->name();
2540 MemberDef* memdef=VhdlDocGen::findMember(n,mem);
2541 if (memdef && memdef->isLinkable())
2544 writeLink(memdef,ol);
2551 startFonts(mem,"vhdlchar",ol);
2556 void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
2558 ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd");
2559 pIntf->resetCodeParserState();
2561 QCString codeFragment=mdef->documentation();
2563 if (cname.isEmpty())
2570 fi=codeFragment.find("\n",++fi);
2571 } while(fi>=0 && j++ <3);
2573 // show only the first four lines
2576 codeFragment=codeFragment.left(fi);
2577 codeFragment.append("\n .... ");
2581 codeFragment.prepend("\n");
2582 ol.pushGeneratorState();
2583 ol.startCodeFragment();
2584 pIntf->parseCode(ol, // codeOutIntf
2586 codeFragment, // input
2587 SrcLangExt_VHDL, // lang
2590 mdef->getFileDef(), // fileDef
2591 mdef->getStartBodyLine(), // startLine
2592 mdef->getEndBodyLine(), // endLine
2593 TRUE, // inlineFragment
2595 TRUE // show line numbers
2598 ol.endCodeFragment();
2599 ol.popGeneratorState();
2601 if (cname.isEmpty()) return;
2603 mdef->writeSourceDef(ol,cname);
2604 mdef->writeSourceRefs(ol,cname);
2605 mdef->writeSourceReffedBy(ol,cname);
2610 QCString VhdlDocGen::convertFileNameToClassName(QCString name)
2618 while((i=n.find("__"))>0)
2623 while((i=n.find("_1"))>0)
2625 n=n.replace(i,2,":");
2631 void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,bool altera)
2633 QCString ucFile(input);
2635 QCString newLine="\n";
2636 QCString comment("#!");
2639 while (!ucFile.isEmpty())
2641 int i=ucFile.find("\n");
2644 QCString temp=ucFile.left(i);
2645 temp=temp.stripWhiteSpace();
2646 bool bb=temp.stripPrefix("//");
2648 if (!temp.isEmpty())
2650 if (temp.stripPrefix(comment) )
2653 brief.append("\\n");
2655 else if (!temp.stripPrefix("#") && !bb)
2659 int i=temp.find("-name");
2662 temp=temp.remove(0,i+5);
2665 temp.stripPrefix("set_location_assignment");
2667 initUCF(entity,0,temp,lineNo,fileName,brief);
2671 QRegExp ee("[\\s=]");
2672 int i=temp.find(ee);
2673 QCString ff=temp.left(i);
2674 temp.stripPrefix(ff.data());
2676 if (!temp.isEmpty())
2678 initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
2684 ucFile=ucFile.remove(0,i+1);
2688 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief)
2690 if (qcs.isEmpty())return;
2692 QRegExp reg("[\\s=]");
2694 // bool bo=(qstricmp(type,qcs.data())==0);
2696 VhdlDocGen::deleteAllChars(qcs,';');
2697 qcs=qcs.stripWhiteSpace();
2699 int i= qcs.find(reg);
2704 VhdlDocGen::deleteAllChars(n,'#');
2711 qcs=qcs.remove(0,i+1);
2712 // qcs.prepend("|");
2714 qcs.stripPrefix("=");
2716 Entry* current=new Entry;
2717 current->spec=VhdlDocGen::UCF_CONST;
2718 current->section=Entry::VARIABLE_SEC;
2719 current->bodyLine=line;
2720 current->fileName=fileName;
2721 current->type="ucf_const";
2723 current->lang= SrcLangExt_VHDL ;
2725 // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2729 n+=VhdlDocGen::getRecordNumber();
2732 current->name= n+"_";
2733 current->name.append(VhdlDocGen::getRecordNumber().data());
2735 if (!brief.isEmpty())
2737 current->brief=brief;
2738 current->briefLine=line;
2739 current->briefFile=fileName;
2743 root->addSubEntry(current);
2747 static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2750 QCString largs(mdef->argsString());
2751 QCString n= splitString(largs, '#');
2752 // VhdlDocGen::adjustRecordMember(mdef);
2753 bool equ=(n.length()==largs.length());
2757 ol.writeString(n.data());
2759 ol.insertMemberAlign();
2762 if (mdef->name().contains("dummy")==0)
2768 ol.insertMemberAlign();
2771 VhdlDocGen::formatString(largs,ol,mdef);
2774 bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne)
2776 //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
2778 LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files);
2779 // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files);
2781 QCString co("Constraints");
2783 if (Config_getBool("HAVE_DOT") && Config_getEnum("DOT_IMAGE_FORMAT")=="svg")
2785 QCString ov = theTranslator->trDesignOverview();
2786 QCString ofile("vhdl_design_overview");
2787 LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,"");
2791 FileNameListIterator fnli(*Doxygen::inputNameList);
2793 for (fnli.toFirst();(fn=fnli.current());++fnli)
2795 FileNameIterator fni(*fn);
2797 for (;(fd=fni.current());++fni)
2799 if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
2801 file = convertNameToFile(fd->name().data(),FALSE,FALSE);
2802 LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
2812 // for cell_inst : [entity] work.proto [ (label|expr) ]
2813 QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
2817 QCString ent("entity");
2818 if (!entity.contains(":")) return "";
2820 QRegExp exp("[:()\\s]");
2821 QStringList ql=QStringList::split(exp,entity,FALSE);
2822 //int ii=ql.findIndex(ent);
2823 assert(ql.count()>=2);
2824 label = ql[0].utf8();
2825 entity = ql[1].utf8();
2826 if ((index=entity.findRev("."))>=0)
2828 entity.remove(0,index+1);
2834 ql=QStringList::split(exp,arch,FALSE);
2835 if (ql.count()>1) // expression
2840 return label; // label
2843 // use (configuration|entity|open) work.test [(cellfor)];
2845 QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
2848 QRegExp exp("[()\\s]");
2851 QStringList ql=QStringList::split(exp,entity,FALSE);
2853 if (ql.contains("open"))
2860 entity = ql[1].utf8();
2861 if ((index=entity.findRev("."))>=0)
2863 entity.remove(0,index+1);
2875 // find class with upper/lower letters
2876 ClassDef* VhdlDocGen::findVhdlClass(const char *className )
2879 ClassSDict::Iterator cli(*Doxygen::classSDict);
2881 for (;(cd=cli.current());++cli)
2883 if (qstricmp(className,cd->name().data())==0)
2892 //@param arch bit0:flipflop
2893 //@param binding e.g entity work.foo(bar)
2894 //@param label |label0|label1
2895 // label0:architecture name
2896 //@param confVhdl of configuration file (identifier::entity_name) or
2897 // the architecture if isInlineConf TRUE
2898 //@param isInlineConf
2899 //@param confN List of configurations
2901 void assignBinding(VhdlConfNode * conf)
2903 QList<Entry> instList= getVhdlInstList();
2904 QListIterator<Entry> eli(instList);
2906 ClassDef *archClass=0,*entClass=0;
2907 QCString archName,entityName;
2908 QCString arcBind,entBind;
2911 entBind=conf->binding;
2912 QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind);
2914 if (qstricmp(conf2,"configuration")==0)
2916 QList<VhdlConfNode> confList = getVhdlConfiguration();
2917 VhdlConfNode* vconf;
2918 // bool found=false;
2919 for (uint iter=0;iter<confList.count(); iter++)
2921 vconf= (VhdlConfNode *)confList.at(iter);
2922 QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0);
2926 entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1);
2927 QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2928 QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2930 archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data());
2931 entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data());
2936 else // conf2!=configuration
2939 if (conf->isInlineConf)
2942 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0);
2946 a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2947 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2950 archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data());
2951 entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data());
2954 QCString label=conf->compSpec.lower();
2955 //label.prepend("|");
2959 // err("architecture %s not found ! ",conf->confVhdl.data());
2963 archName=archClass->name();
2964 QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
2965 all=allOt.lower()=="all" ;
2966 others= allOt.lower()=="others";
2968 for (;(cur=eli.current());++eli)
2970 if (cur->exception.lower()==label || conf->isInlineConf)
2972 QCString sign,archy;
2976 archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
2983 QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower();
2984 QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower();
2986 QStringList ql=QStringList::split(",",inst1);
2988 for (uint j=0;j<ql.count();j++)
2990 QCString archy1,sign1;
2993 archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1);
2998 archy1=comp+":"+ql[j].utf8();
2999 sign1=cur->type+":"+cur->name;
3002 if (archy1==sign1.lower() && !cur->stat)
3004 // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
3005 ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data());
3007 if (entClass==0 || ent==0)
3012 addInstance(ent,archClass,entClass,cur);
3018 }//for each element in instList
3029 // file foo_arch.vhd
3030 // architecture xxx of foo is
3035 void VhdlDocGen::computeVhdlComponentRelations()
3038 QCString entity,arch,inst;
3039 QList<VhdlConfNode> confList = getVhdlConfiguration();
3041 for (uint iter=0;iter<confList.count(); iter++)
3043 VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
3044 if (!(conf->isInlineConf || conf->isLeaf))
3048 assignBinding(conf);
3051 QList<Entry> qsl= getVhdlInstList();
3052 QListIterator<Entry> eli(qsl);
3055 for (eli.toFirst();(cur=eli.current());++eli)
3057 if (cur->stat ) // was bind
3062 if (cur->includeName=="entity" || cur->includeName=="component" )
3064 entity=cur->includeName+" "+cur->type;
3065 QCString rr=VhdlDocGen::parseForBinding(entity,arch);
3067 else if (cur->includeName.isEmpty())
3072 ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity);
3073 inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
3074 ClassDef *cd=Doxygen::classSDict->find(inst);
3075 ClassDef *ar=Doxygen::classSDict->find(cur->args);
3082 // if (classEntity==0)
3083 // err("%s:%d:Entity:%s%s",cur->fileName.data(),cur->startLine,entity.data()," could not be found");
3085 addInstance(classEntity,ar,cd,cur);
3090 static void addInstance(ClassDef* classEntity, ClassDef* ar,
3091 ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
3099 //add component inst
3104 if (classEntity==cd) return;
3106 bName=classEntity->name();
3107 // fprintf(stderr,"\naddInstance %s to %s %s %s\n", classEntity->name().data(),cd->name().data(),ar->name().data(),cur->name);
3108 n1=classEntity->name().data();
3110 if (!cd->isBaseClass(classEntity, true, 0))
3112 cd->insertBaseClass(classEntity,n1,Public,Normal,0);
3116 VhdlDocGen::addBaseClass(cd,classEntity);
3119 if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
3121 classEntity->insertSubClass(cd,Public,Normal,0);
3122 classEntity->setLanguage(SrcLangExt_VHDL);
3126 QCString uu=cur->name;
3127 MemberDef *md=new MemberDef(
3128 ar->getDefFileName(), cur->startLine,cur->startColumn,
3130 Public, Normal, cur->stat,Member,
3131 MemberType_Variable,
3135 if (ar->getOutputFileBase())
3139 tg.fileName = ar->getOutputFileBase();
3141 md->setTagInfo(&tg);
3144 //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
3146 md->setLanguage(SrcLangExt_VHDL);
3147 md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
3148 md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
3149 md->setBodySegment(cur->startLine,-1) ;
3150 md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine);
3151 FileDef *fd=ar->getFileDef();
3155 QCString info="Info: Elaborating entity "+n1;
3156 fd=ar->getFileDef();
3157 info+=" for hierarchy ";
3159 QCString label=cur->type+":"+cur->write+":"+cur->name;
3160 label.replace(epr,":");
3162 fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data());
3165 ar->insertMember(md);
3170 void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
3172 QStringList ql=QStringList::split("#",largs,FALSE);
3173 uint len=ql.count();
3174 for(uint i=0;i<len;i++)
3176 QCString n=ql[i].utf8();
3177 VhdlDocGen::formatString(n,ol,mdef);
3178 if ((len-i)>1) ol.lineBreak();
3183 void VhdlDocGen::writeRecUnitDocu(
3184 const MemberDef *md,
3189 QStringList ql=QStringList::split("#",largs,FALSE);
3190 uint len=ql.count();
3191 ol.startParameterList(TRUE);
3193 for(uint i=0;i<len;i++)
3195 QCString n=ql[i].utf8();
3196 ol.startParameterType(first,"");
3197 ol.endParameterType();
3198 ol.startParameterName(TRUE);
3199 VhdlDocGen::formatString(n,ol,md);
3202 ol.endParameterName(FALSE,FALSE,FALSE);
3206 ol.endParameterName(TRUE,FALSE,TRUE);
3215 bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
3218 //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3221 err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
3226 if (cd->subClasses())
3228 BaseClassListIterator bcli(*cd->subClasses());
3229 for ( ; bcli.current() && !found ; ++bcli)
3231 ClassDef *ccd=bcli.current()->classDef;
3232 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3233 //printf("isSubClass() subclass %s\n",ccd->name().data());
3242 found=ccd->isBaseClass(scd,followInstances,level+1);
3250 void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
3252 if (cd->baseClasses())
3254 BaseClassListIterator bcli(*cd->baseClasses());
3255 for ( ; bcli.current() ; ++bcli)
3257 ClassDef *ccd=bcli.current()->classDef;
3260 QCString n = bcli.current()->usedName;
3261 int i = n.find('(');
3264 bcli.current()->usedName.append("(2)");
3267 static QRegExp reg("[0-9]+");
3268 QCString s=n.left(i);
3269 QCString r=n.right(n.length()-i);
3271 VhdlDocGen::deleteAllChars(r,')');
3272 VhdlDocGen::deleteAllChars(r,'(');
3273 r.setNum(r.toInt()+1);
3274 t.replace(reg,r.data());
3276 bcli.current()->usedName=s;
3277 bcli.current()->templSpecifiers=t;
3284 static QList<MemberDef> mdList;
3286 static MemberDef* findMemFlow(const MemberDef* mdef)
3288 for(uint j=0;j<mdList.count();j++)
3290 MemberDef* md=(MemberDef*)mdList.at(j);
3291 if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
3297 void VhdlDocGen::createFlowChart(const MemberDef *mdef)
3299 if (mdef==0) return;
3301 QCString codeFragment;
3303 if((mm=findMemFlow(mdef))!=0)
3305 // don't create the same flowchart twice
3306 VhdlDocGen::setFlowMember(mm);
3311 mdList.append(mdef);
3314 //fprintf(stderr,"\n create flow mem %s %p\n",mdef->name().data(),mdef);
3316 int actualStart= mdef->getStartBodyLine();
3317 int actualEnd=mdef->getEndBodyLine();
3318 FileDef* fd=mdef->getFileDef();
3319 bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment);
3322 VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd");
3323 VhdlDocGen::setFlowMember(mdef);
3325 QStrList filesInSameTu;
3326 pIntf->startTranslationUnit("");
3327 pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu);
3328 pIntf->finishTranslationUnit();
3331 bool VhdlDocGen::isConstraint(const MemberDef *mdef)
3332 { return mdef->getMemberSpecifiers()==VhdlDocGen::UCF_CONST; }
3333 bool VhdlDocGen::isConfig(const MemberDef *mdef)
3334 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; }
3335 bool VhdlDocGen::isAlias(const MemberDef *mdef)
3336 { return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; }
3337 bool VhdlDocGen::isLibrary(const MemberDef *mdef)
3338 { return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; }
3339 bool VhdlDocGen::isGeneric(const MemberDef *mdef)
3340 { return mdef->getMemberSpecifiers()==VhdlDocGen::GENERIC; }
3341 bool VhdlDocGen::isPort(const MemberDef *mdef)
3342 { return mdef->getMemberSpecifiers()==VhdlDocGen::PORT; }
3343 bool VhdlDocGen::isComponent(const MemberDef *mdef)
3344 { return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT; }
3345 bool VhdlDocGen::isPackage(const MemberDef *mdef)
3346 { return mdef->getMemberSpecifiers()==VhdlDocGen::USE; }
3347 bool VhdlDocGen::isEntity(const MemberDef *mdef)
3348 { return mdef->getMemberSpecifiers()==VhdlDocGen::ENTITY; }
3349 bool VhdlDocGen::isConstant(const MemberDef *mdef)
3350 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONSTANT; }
3351 bool VhdlDocGen::isVType(const MemberDef *mdef)
3352 { return mdef->getMemberSpecifiers()==VhdlDocGen::TYPE; }
3353 bool VhdlDocGen::isSubType(const MemberDef *mdef)
3354 { return mdef->getMemberSpecifiers()==VhdlDocGen::SUBTYPE; }
3355 bool VhdlDocGen::isVhdlFunction(const MemberDef *mdef)
3356 { return mdef->getMemberSpecifiers()==VhdlDocGen::FUNCTION; }
3357 bool VhdlDocGen::isProcess(const MemberDef *mdef)
3358 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCESS; }
3359 bool VhdlDocGen::isSignal(const MemberDef *mdef)
3360 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3361 bool VhdlDocGen::isAttribute(const MemberDef *mdef)
3362 { return mdef->getMemberSpecifiers()==VhdlDocGen::ATTRIBUTE; }
3363 bool VhdlDocGen::isSignals(const MemberDef *mdef)
3364 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3365 bool VhdlDocGen::isProcedure(const MemberDef *mdef)
3366 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCEDURE; }
3367 bool VhdlDocGen::isRecord(const MemberDef *mdef)
3368 { return mdef->getMemberSpecifiers()==VhdlDocGen::RECORD; }
3369 bool VhdlDocGen::isArchitecture(const MemberDef *mdef)
3370 { return mdef->getMemberSpecifiers()==VhdlDocGen::ARCHITECTURE; }
3371 bool VhdlDocGen::isUnit(const MemberDef *mdef)
3372 { return mdef->getMemberSpecifiers()==VhdlDocGen::UNITS; }
3373 bool VhdlDocGen::isPackageBody(const MemberDef *mdef)
3374 { return mdef->getMemberSpecifiers()==VhdlDocGen::PACKAGE_BODY; }
3375 bool VhdlDocGen::isVariable(const MemberDef *mdef)
3376 { return mdef->getMemberSpecifiers()==VhdlDocGen::SHAREDVARIABLE; }
3377 bool VhdlDocGen::isFile(const MemberDef *mdef)
3378 { return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; }
3379 bool VhdlDocGen::isGroup(const MemberDef *mdef)
3380 { return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; }
3381 bool VhdlDocGen::isCompInst(const MemberDef *mdef)
3382 { return mdef->getMemberSpecifiers()==VhdlDocGen::INSTANTIATION; }
3383 bool VhdlDocGen::isMisc(const MemberDef *mdef)
3384 { return mdef->getMemberSpecifiers()==VhdlDocGen::MISCELLANEOUS; }
3388 //############################## Flowcharts #################################################
3390 #define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
3391 FlowChart::FOR_NO | FlowChart::CASE_NO | \
3392 FlowChart::LOOP_NO | WHEN_NO)
3393 #define DECLN (FlowChart::WHEN_NO | \
3394 FlowChart::ELSIF_NO | FlowChart::IF_NO | \
3395 FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3396 FlowChart::CASE_NO | FlowChart::LOOP_NO )
3397 #define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
3398 #define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3399 FlowChart::LOOP_NO )
3400 #define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
3401 #define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
3402 #define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
3403 #define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
3404 #define EMPTY (EEND | FlowChart::ELSIF_NO)
3405 #define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
3406 #define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
3407 #define FLOWLEN (flowList.count()-1)
3409 static int ifcounter=0;
3410 static int nodeCounter=0;
3415 const char *textNodeLink;
3416 const char *yesNodeLink;
3417 const char *noNodeLink;
3420 const char* comment;
3421 const char* decisionNode;
3422 const char* varNode;
3423 const char *startEndNode;
3424 const char* textNode;
3426 { "green", // textNodeLink
3427 "red", // yesNodeLink
3428 "black", // noNodeLink
3430 "0.7 0.3 1.0", // decisionNode
3431 "lightyellow", // varNode
3432 "white", // startEndNode
3433 "lightcyan" // textNode
3436 QList<FlowChart> FlowChart::flowList;
3439 static QMap<QCString,int> keyMap;
3442 void alignText(QCString & q)
3444 if (q.length()<=80) return;
3453 QRegExp reg("[\\s|]");
3454 QCString str(q.data());
3457 while (str.length()>80)
3459 int j=str.findRev(reg,80);
3468 QCString qcs=str.left(j);
3479 void FlowChart::printNode(const FlowChart* flo)
3484 QRegExp ep("[\t\n\r]");
3488 if (flo->type & STARTL)
3492 q=ui.left(2*flo->stamp);
3498 QCString nn=flo->exp.stripWhiteSpace();
3499 printf("\nYES: %s%s[%d,%d]",q.data(),nn.data(),flo->stamp,flo->id);
3503 if (flo->type & COMMENT_NO)
3518 q=ui.left(2*flo->stamp);
3524 if (flo->type & EMPTNODE)
3526 printf("\n NO: %s%s[%d,%d]",q.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3528 else if (flo->type & COMMENT_NO)
3530 printf("\n NO: %s%s[%d,%d]",t.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3534 printf("\n NO: %s%s[%d,%d]",q.data(),t.data(),flo->stamp,flo->id);
3539 void FlowChart::printFlowTree()
3541 uint size=flowList.count();
3542 for (uint j=0;j<size;j++)
3544 printNode(flowList.at(j));
3548 void FlowChart::colTextNodes()
3553 for (uint j=0;j<flowList.count();j++)
3555 FlowChart *flo=flowList.at(j);
3556 if (flo->type&TEXT_NO)
3558 text+=flo->text+'\n';
3565 flno->text+=flo->text;
3566 flowList.remove(flo);
3575 // find if..endif without text
3576 // if..elseif without text
3577 for (uint j=0;j<flowList.count()-1;j++)
3579 FlowChart *flo=flowList.at(j);
3581 if ( (kind & IFF) || (flo->type & ELSE_NO))
3583 FlowChart *ftemp=flowList.at(j+1);
3584 if (ftemp->type & EMPTY)
3586 FlowChart *fNew = new FlowChart(TEXT_NO,"empty ",0);
3587 fNew->stamp=flo->stamp;
3588 flowList.insert(j+1,fNew);
3595 QCString FlowChart::getNodeName(int n)
3599 return node.prepend("node");
3602 void FlowChart::delFlowList()
3606 uint size=flowList.count();
3608 for (uint j=0;j <size ;j++)
3610 FlowChart *fll=flowList.at(j);
3616 void FlowChart::alignCommentNode(FTextStream &t,QCString com)
3620 QStringList ql=QStringList::split("\n",com);
3621 for (uint j=0;j<ql.count();j++)
3623 s=(QCString)ql[j].utf8();
3624 if (max<s.length()) max=s.length();
3628 int diff=max-s.length();
3636 ql.remove(ql.last());
3640 for (uint j=0;j<ql.count();j++)
3642 s=(QCString)ql[j].utf8();
3647 FlowChart::codify(t,s.data());
3652 void FlowChart::buildCommentNodes(FTextStream & t)
3654 uint size=flowList.count();
3657 for (uint j=0;j < size-1 ;j++)
3659 FlowChart *fll=flowList.at(j);
3660 if (fll->type & COMMENT_NO)
3662 FlowChart* to=flowList.at(j+1);
3663 if (to->type & COMMENT_NO)
3666 QCString temp=fll->label+to->label;
3675 for (uint j=0;j <flowList.count() ;j++)
3677 FlowChart *fll=flowList.at(j);
3679 if (fll->type & BEGIN_NO)
3685 if (fll->type & COMMENT_NO)
3690 // comment between function/process .. begin is linked to start node
3695 if (j>0 && flowList.at(j-1)->line==fll->line)
3696 to=flowList.at(j-1);
3698 to=flowList.at(j+1);
3700 t << getNodeName(fll->id);
3701 t << "[shape=none, label=<\n";
3702 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
3703 t << "<TR><TD BGCOLOR=\"";
3704 t << flowCol.comment;
3707 FlowChart::alignCommentNode(t,fll->label);
3708 t << " </TD></TR></TABLE>>];";
3709 writeEdge(t,fll->id,to->id,2);
3713 // delete comment nodes;
3714 size=flowList.count();
3715 for (uint j=0;j < size;j++)
3717 FlowChart *fll=flowList.at(j);
3718 if (fll->type & (COMMENT_NO | BEGIN_NO))
3729 void FlowChart::codify(FTextStream &t,const char *str)
3740 case '<': t << "<"; break;
3741 case '>': t << ">"; break;
3742 case '&': t << "&"; break;
3743 case '\'': t << "'"; break;
3744 case '"': t << """; break;
3745 case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
3746 default: t << c; break;
3752 FlowChart::~FlowChart()
3756 FlowChart::FlowChart(int typ,const char * t,const char* ex,const char* lab)
3770 if (typ & (ELSE_NO | ELSIF_NO))
3775 if (typ & (START_NO | END_NO | VARIABLE_NO))
3783 void FlowChart::addFlowChart(int type,const char* text,const char* exp, const char *label)
3785 static QRegExp reg("[;]");
3786 static QRegExp reg1("[\"]");
3788 if (!VhdlDocGen::getFlowMember()) return;
3790 QCString typeString(text);
3791 QCString expression(exp);
3796 typeString=typeString.replace(reg,"\n");
3801 expression=expression.replace(reg1,"\\\"");
3804 FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label);
3806 fl->line=getVhdlCont()->yyLineNr;
3808 if (type & (START_NO | VARIABLE_NO))
3810 flowList.prepend(fl);
3814 flowList.append(fl);
3819 void FlowChart::moveToPrevLevel()
3821 if (!VhdlDocGen::getFlowMember()) return;
3826 QCString FlowChart::convertNameToFileName()
3828 static QRegExp exp ("[^][a-z_A-Z0-9]");
3830 const MemberDef* md=VhdlDocGen::getFlowMember();
3832 temp.sprintf("%p",md);
3835 if (qcs.find(exp,0)>=0)
3838 qcs=qcs.replace(exp,"_");
3844 const char* FlowChart::getNodeType(int c)
3848 case IF_NO: return "if ";
3849 case ELSIF_NO: return "elsif ";
3850 case ELSE_NO: return "else ";
3851 case CASE_NO: return "case ";
3852 case WHEN_NO: return "when ";
3853 case EXIT_NO: return "exit ";
3854 case END_NO: return "end ";
3855 case TEXT_NO: return "text ";
3856 case START_NO: return "start ";
3857 case ENDIF_NO: return "endif ";
3858 case FOR_NO: return "for ";
3859 case WHILE_NO: return "while ";
3860 case END_LOOP: return "end_loop ";
3861 case END_CASE: return "end_case ";
3862 case VARIABLE_NO: return "variable_decl ";
3863 case RETURN_NO: return "return ";
3864 case LOOP_NO: return "infinte loop ";
3865 case NEXT_NO: return "next ";
3866 case COMMENT_NO: return "comment ";
3867 case EMPTY_NO: return "empty ";
3868 case BEGIN_NO: return "<begin> ";
3869 default: return "--failure--";
3873 void FlowChart::createSVG()
3876 QCString ov = Config_getString("HTML_OUTPUT");
3878 qcs+=FlowChart::convertNameToFileName()+".svg";
3880 //const MemberDef *m=VhdlDocGen::getFlowMember();
3882 // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data());
3884 QCString dir=" -o "+ov+qcs;
3885 ov+="/flow_design.dot";
3887 QCString vlargs="-Tsvg "+ov+dir ;
3888 QCString dotExe = Config_getString("DOT_PATH")+"dot";
3890 if (portable_system(dotExe,vlargs)!=0)
3892 err("could not create dot file");
3896 void FlowChart::startDot(FTextStream &t)
3898 t << " digraph G { \n";
3899 t << "rankdir=TB \n";
3900 t << "concentrate=true\n";
3901 t << "stylesheet=\"doxygen.css\"\n";
3904 void FlowChart::endDot(FTextStream &t)
3909 void FlowChart::writeFlowChart()
3911 // assert(VhdlDocGen::flowMember);
3913 QCString ov = Config_getString("HTML_OUTPUT");
3914 QCString fileName = ov+"/flow_design.dot";
3918 if (!f.open(IO_WriteOnly))
3920 err("Cannot open file %s for writing\n",fileName.data());
3931 buildCommentNodes(t);
3933 uint size=flowList.count();
3935 for (uint j=0;j <size ;j++)
3937 FlowChart *fll=flowList.at(j);
3942 FlowChart::endDot(t);
3945 FlowChart::createSVG();
3948 void FlowChart::writeShape(FTextStream &t,const FlowChart* fl)
3950 if (fl->type & EEND) return;
3952 if (fl->type & LOOP)
3956 else if (fl->type & IFF)
3965 t<<getNodeName(fl->id).data();
3966 QCString q=getNodeType(fl->type);
3969 QCString qq(getNodeName(fl->id).data());
3970 keyMap.insert(qq,fl->id);
3973 bool dec=(fl->type & DECLN);
3974 bool exit=(fl->type & EXITNEXT);
3975 if (exit && !fl->exp.isEmpty())
3981 QCString exp=fl->exp;
3984 t << " [shape=diamond,style=filled,color=\"";
3985 t << flowCol.decisionNode;
3986 t << "\",label=\" ";
3988 if (exit) kl=fl->text+" ";
3992 kl+=fl->label+":"+exp+var;
3999 FlowChart::alignCommentNode(t,kl);
4002 else if (fl->type & ENDCL)
4004 QCString val=fl->text;
4005 t << " [shape=ellipse ,label=\""+val+"\"]\n";
4007 else if (fl->type & STARTFIN)
4009 QCString val=fl->text;
4010 t << "[shape=box , style=rounded label=<\n";
4011 t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
4012 t << "<TR><TD BGCOLOR=\"";
4013 t<< flowCol.startEndNode;
4015 FlowChart::alignCommentNode(t,val);
4016 t << " </TD></TR></TABLE>>];";
4020 if (fl->text.isEmpty()) return;
4021 bool var=(fl->type & FlowChart::VARIABLE_NO);
4022 QCString repl("<BR ALIGN=\"LEFT\"/>");
4023 QCString q=fl->text;
4030 int z=q.findRev("\n");
4032 if (z==(int)q.length()-1)
4036 t << "[shape=none margin=0.1, label=<\n";
4037 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
4040 t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
4044 t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
4046 FlowChart::alignCommentNode(t,q);
4047 t << " </TD></TR></TABLE>>];";
4052 void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i)
4054 bool b=fl_from->type & STARTL;
4055 bool c=fl_to->type & STARTL;
4058 QCString s1(getNodeName(fl_from->id).data());
4059 QCString s2(getNodeName(fl_to->id).data());
4060 QMap<QCString, int>::Iterator it = keyMap.find(s1);
4061 QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
4062 // checks if the link is connected to a valid node
4067 writeEdge(t,fl_from->id,fl_to->id,i,b,c);
4070 void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
4076 col=flowCol.yesNodeLink;
4081 col=flowCol.noNodeLink;
4086 col=flowCol.textNodeLink;
4090 t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
4091 t << getNodeName(fl_from).data();
4092 if (bFrom) t << ":s";
4094 t << getNodeName(fl_to).data();
4099 void FlowChart::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc)
4103 ArgumentListIterator ali(*al);
4104 int index=ali.count();
4105 if (index==0) return;
4107 int len=q.length()+VhdlDocGen::getFlowMember()->name().length();
4109 prev.fill(' ',len+1);
4113 for (;(arg=ali.current());++ali)
4115 QCString attl=arg->defval+" ";
4116 attl+=arg->name+" ";
4120 attl+=arg->attrib+" ";
4127 if (--index) attl+=",\n"; else attl+="\n";
4129 attl.prepend(prev.data());
4136 int FlowChart::findNextLoop(int index,int stamp)
4138 for (uint j=index+1;j<flowList.count();j++)
4140 FlowChart *flo=flowList.at(j);
4141 if (flo->stamp==stamp)
4145 if (flo->type&END_LOOP)
4150 return flowList.count()-1;
4153 int FlowChart::findPrevLoop(int index,int stamp,bool endif)
4155 for (uint j=index;j>0;j--)
4157 FlowChart *flo=flowList.at(j);
4158 if (flo->type & LOOP)
4160 if (flo->stamp==stamp && endif)
4166 if (flo->stamp<stamp)
4173 return flowList.count()-1;
4176 int FlowChart::findLabel(int index,QCString &label)
4178 for (uint j=index;j>0;j--)
4180 FlowChart *flo=flowList.at(j);
4181 if ((flo->type & LOOP) && !flo->label.isEmpty() && qstricmp(flo->label,label)==0)
4186 err("could not find label: ",label.data());
4190 int FlowChart::findNode(int index,int stamp,int type)
4192 for (uint j=index+1;j<flowList.count();j++)
4194 FlowChart *flo=flowList.at(j);
4195 if (flo->type==type && flo->stamp==stamp)
4203 int FlowChart::getNextNode(int index,int stamp)
4205 for (uint j=index+1;j<flowList.count();j++)
4207 FlowChart *flo=flowList.at(j);
4214 if (kind & ENDIF_NO)
4216 if (s<stamp && stamp>0)
4222 if (kind & (ELSE_NO | ELSIF_NO))
4224 if (s<stamp && stamp>0)
4228 j=findNode(j,stamp,ENDIF_NO);
4233 if (s<stamp && stamp>0)
4237 return findNode(j,stamp-1,END_CASE);
4244 int FlowChart::getNextIfLink(const FlowChart* fl,uint index)
4246 int stamp=fl->stamp;
4247 uint start = index+1;
4248 int endifNode = findNode(start,stamp,ENDIF_NO);
4249 int elseifNode = findNode(start,stamp,ELSIF_NO);
4250 int elseNode = findNode(start,stamp,ELSE_NO);
4252 assert(endifNode>-1);
4254 if (elseifNode>0 && elseifNode<endifNode)
4259 if (elseNode>0 && elseNode<endifNode)
4264 stamp=flowList.at(endifNode)->stamp;
4265 return getNextNode(endifNode,stamp);
4268 void FlowChart::writeFlowLinks(FTextStream &t)
4270 uint size=flowList.count();
4274 writeEdge(t,flowList.at(0),flowList.at(1),2);
4276 for (uint j=0;j<size;j++)
4278 FlowChart *fll=flowList.at(j);
4280 int stamp=fll->stamp;
4288 writeEdge(t,fll,flowList.at(j+1),0);
4289 int z=getNextIfLink(fll,j);
4291 writeEdge(t,fll,flowList.at(z),1);
4293 else if (kind & LOOP_NO)
4295 writeEdge(t,fll,flowList.at(j+1),2);
4298 else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
4302 writeEdge(t,fll,flowList.at(j+1),2);
4307 writeEdge(t,fll,flowList.at(j+1),0);
4311 int z=findNode(j+1,fll->stamp,kind);
4312 z=getNextNode(z,flowList.at(z)->stamp);
4315 writeEdge(t,fll,flowList.at(z),1);
4318 else if (kind & (TEXT_NO | VARIABLE_NO))
4320 int z=getNextNode(j,stamp);
4321 writeEdge(t,fll,flowList.at(z),2);
4323 else if (kind & WHEN_NO)
4326 if (qstricmp(fll->text.simplifyWhiteSpace().data(),"others")==0)
4328 writeEdge(t,fll,flowList.at(j+1),2);
4333 writeEdge(t,fll,flowList.at(j+1),0);
4334 int u=findNode(j,stamp,WHEN_NO);
4335 int v=findNode(j,stamp-1,END_CASE);
4339 writeEdge(t,fll,flowList.at(u),1);
4343 writeEdge(t,fll,flowList.at(v),1);
4346 else if (kind & END_CASE)
4348 int z=FlowChart::getNextNode(j,fll->stamp);
4349 writeEdge(t,fll,flowList.at(z),2);
4351 else if (kind & END_LOOP)
4353 int z=findPrevLoop(j,fll->stamp,true);
4354 writeEdge(t,fll,flowList.at(z),2);
4356 else if (kind & RETURN_NO)
4358 writeEdge(t,fll,FlowChart::flowList.at(size-1),2);
4360 else if (kind & (EXIT_NO | NEXT_NO))
4363 bool b = kind==NEXT_NO;
4366 writeEdge(t,fll,flowList.at(j+1),1);
4368 if (!fll->label.isEmpty())
4370 z=findLabel(j,fll->label);
4373 writeEdge(t,fll,flowList.at(z),0);
4377 z=findNode(z,flowList.at(z)->stamp,END_LOOP);
4378 z=getNextNode(z,flowList.at(z)->stamp);
4379 writeEdge(t,fll,flowList.at(z),0);
4387 z=findPrevLoop(j,fll->stamp);
4388 writeEdge(t,fll,flowList.at(z),0);
4393 z =findNextLoop(j,fll->stamp-1);
4395 z=getNextNode(z,flowList.at(z)->stamp);
4397 writeEdge(t,fll,flowList.at(z),0);