1 /******************************************************************************
3 * Copyright (C) 1997-2015 by Dimitri van Heesch.
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
15 /******************************************************************************
16 * Parser for VHDL subset
18 * supports VHDL-87/93/2008
19 * does not support VHDL-AMS
20 ******************************************************************************/
28 #include <qfileinfo.h>
29 #include <qstringlist.h>
32 /* --------------------------------------------------------------- */
35 #include "vhdldocgen.h"
41 #include "commentscan.h"
43 #include "definition.h"
44 #include "searchindex.h"
45 #include "outputlist.h"
46 #include "parserintf.h"
48 #include "arguments.h"
50 #include "memberlist.h"
51 #include "memberdef.h"
53 #include "classlist.h"
54 #include "namespacedef.h"
56 #include "membergroup.h"
57 #include "memberdef.h"
59 #include "vhdljjparser.h"
60 #include "VhdlParser.h"
64 #define theTranslator_vhdlType VhdlDocGen::trVhdlType
66 static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
67 static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
68 static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
69 static QDict<QCString> g_vhdlKeyDict3(17,FALSE);
71 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
72 static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
73 static void assignBinding(VhdlConfNode* conf);
74 static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
76 //---------- create svg -------------------------------------------------------------
77 static void createSVG();
78 static void startDot(FTextStream &t);
79 static void startTable(FTextStream &t,const QCString &className);
80 static QList<MemberDef>* getPorts(ClassDef *cd);
81 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
82 static void endDot(FTextStream &t);
83 static void writeTable(QList<MemberDef>* port,FTextStream & t);
84 static void endTabel(FTextStream &t);
85 static void writeClassToDot(FTextStream &t,ClassDef* cd);
86 static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
87 //static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
88 static const MemberDef *flowMember=0;
90 void VhdlDocGen::setFlowMember( const MemberDef* mem)
95 const MemberDef* VhdlDocGen::getFlowMember()
102 //--------------------------------------------------------------------------------------------------
103 static void codify(FTextStream &t,const char *str)
114 case '<': t << "<";
116 case '>': t << ">";
118 case '&': t << "&";
120 case '\'': t << "'";
122 case '"': t << """;
131 static void writeLink(const MemberDef* mdef,OutputList &ol)
133 ol.writeObjectLink(mdef->getReference(),
134 mdef->getOutputFileBase(),
139 static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
141 ol.startFontClass(keyword);
146 static QCString splitString(QCString& str,char c)
153 str=str.remove(0,i+1);
158 static int compareString(const QCString& s1,const QCString& s2)
160 return qstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
163 static void createSVG()
165 QCString ov =Config_getString(HTML_OUTPUT);
166 QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
167 ov+="/vhdl_design.dot";
169 QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
171 if (portable_system("dot",vlargs)!=0)
173 err("could not create dot file");
177 // Creates an 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";
200 if (!f.open(IO_WriteOnly))
202 fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
208 for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
210 if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS )
215 QList<MemberDef>* port= getPorts(cd);
220 if (port->count()==0)
227 startTable(t,cd->name());
228 writeClassToDot(t,cd);
232 // writeVhdlPortToolTip(t,port,cd);
233 writeVhdlEntityToolTip(t,cd);
236 BaseClassList *bl=cd->baseClasses();
239 BaseClassListIterator bcli(*bl);
241 for ( ; (bcd=bcli.current()) ; ++bcli )
243 ClassDef *bClass=bcd->classDef;
244 QCString dotn=cd->name()+":";
246 QCString csc=bClass->name()+":";
248 // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
249 writeVhdlDotLink(t,dotn,csc,0);
255 // writePortLinks(t);
260 //------------------------------------------------------------------------------------------------------------------------------------------------------
262 static void startDot(FTextStream &t)
264 t << " digraph G { \n";
265 t << "rankdir=LR \n";
266 t << "concentrate=TRUE\n";
267 t << "stylesheet=\"doxygen.css\"\n";
270 static void endDot(FTextStream &t)
275 static void startTable(FTextStream &t,const QCString &className)
277 t << className <<" [ shape=none , fontname=\"arial\", fontcolor=\"blue\" , \n";
278 t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
281 static void writeVhdlDotLink(FTextStream &t,
282 const QCString &a,const QCString &b,const QCString &style)
285 if (!style.isEmpty())
287 t << "[style=" << style << "];\n";
293 static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
297 QCString repl("<BR ALIGN=\"LEFT\"/>");
298 QCString file=cd->getDefFileName();
300 int k=cd->briefLine();
302 QStringList qsl=QStringList::split(ep,brief);
303 for(uint j=0;j<qsl.count();j++)
305 QCString qcs=qsl[j].data();
306 vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
311 vForm.replace(ep,repl.data());
316 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
319 uint len=port->count();
322 for (uint j=0;j<len;j++)
324 md=(MemberDef*)port->at(j);
325 QCString brief=md->briefDescriptionAsTooltip();
326 if (brief.isEmpty()) continue;
328 QCString node="node";
329 node+=VhdlDocGen::getRecordNumber();
330 t << node <<"[shape=box margin=0.1, label=<\n";
331 t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
332 t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
334 t<<" </TD></TR></TABLE>>];";
335 QCString dotn=cd->name()+":";
337 // writeVhdlDotLink(t,dotn,node,"dotted");
343 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd)
346 QCString brief=cd->briefDescription();
348 if (brief.isEmpty()) return;
350 brief=formatBriefNote(brief,cd);
352 QCString node="node";
353 node+=VhdlDocGen::getRecordNumber();
354 t << node <<"[shape=none margin=0.1, label=<\n";
355 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
356 t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
358 t << " </TD></TR></TABLE>>];";
359 QCString dotn=cd->name()+":";
361 writeVhdlDotLink(t,dotn,node,"dotted");
364 static void writeColumn(FTextStream &t,MemberDef *md,bool start)
368 static QRegExp reg("[%]");
369 bool bidir=(md!=0 &&( qstricmp(md->typeString(),"inout")==0));
373 toolTip=md->briefDescriptionAsTooltip();
374 if (!toolTip.isEmpty())
376 QCString largs = md->argsString();
377 if (!largs.isEmpty())
378 largs=largs.replace(reg," ");
389 t << "<TD ALIGN=\"LEFT\" ";
393 t << md->getOutputFileBase()<< Doxygen::htmlFileExtension;
394 t << "#" << md->anchor();
398 if (!toolTip.isEmpty())
400 codify(t,toolTip.data());
404 QCString largs = md->argsString();
405 if (!largs.isEmpty())
407 largs=largs.replace(reg," ");
408 codify(t,largs.data());
417 if (!toolTip.isEmpty())
419 // if (!toolTip.isEmpty())
422 t << "BGCOLOR=\"orange\">";
424 t << "BGCOLOR=\"azure\">";
428 t << "BGCOLOR=\"pink\">";
432 t << "BGCOLOR=\"lightgrey\">";
450 static void endTabel(FTextStream &t)
456 static void writeClassToDot(FTextStream &t,ClassDef* cd)
458 t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
463 t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
467 t << " </TD></TR>\n";
470 static QList<MemberDef>* getPorts(ClassDef *cd)
473 QList<MemberDef> *portList=new QList<MemberDef>;
474 MemberList *ml=cd->getMemberList(MemberListType_variableMembers);
482 MemberListIterator fmni(*ml);
484 for (fmni.toFirst();(md=fmni.current());++fmni)
486 if (md->getMemberSpecifiers()==VhdlDocGen::PORT)
488 portList->append(md);
495 //writeColumn(FTextStream &t,QCString name,bool start)
497 static void writeTable(QList<MemberDef>* port,FTextStream & t)
500 uint len=port->count();
502 QList<MemberDef> inPorts;
503 QList<MemberDef> outPorts;
508 md=(MemberDef*)port->at(j);
509 QCString qc=md->typeString();
520 int inp = inPorts.count();
521 int outp = outPorts.count();
534 for(i=0;i<maxLen;i++)
539 md=(MemberDef*)inPorts.at(i);
540 writeColumn(t,md,TRUE);
544 writeColumn(t,NULL,TRUE);
549 md=(MemberDef*)outPorts.at(i);
550 writeColumn(t,md,FALSE);
554 writeColumn(t,NULL,FALSE);
559 //--------------------------------------------------------------------------------------------------
562 VhdlDocGen::VhdlDocGen()
566 VhdlDocGen::~VhdlDocGen()
570 void VhdlDocGen::init()
573 // vhdl keywords included VHDL 2008
574 const char* g_vhdlKeyWordMap0[] =
576 "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
577 "begin","block","body","buffer","bus",
578 "case","component","configuration","constant","context","cover",
579 "default","disconnect","downto",
580 "else","elsif","end","entity","exit",
581 "fairness","file","for","force","function",
582 "generate","generic","group","guarded",
583 "if","impure","in","inertial","inout","is",
584 "label","library","linkage","literal","loop",
586 "nand","new","next","nor","not","null",
587 "of","on","open","or","others","out",
588 "package","parameter","port","postponed","procedure","process","property","protected","pure",
589 "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
590 "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
591 "then","to","transport","type",
592 "unaffected","units","until","use",
593 "variable","vmode","vprop","vunit",
594 "wait","when","while","with",
601 const char* g_vhdlKeyWordMap1[] =
603 "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
604 "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
605 "real","float","ufixed","sfixed","time",0
609 const char* g_vhdlKeyWordMap2[] =
611 "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
615 // predefined attributes
616 const char* g_vhdlKeyWordMap3[] =
618 "base","left","right","high","low","ascending",
619 "image","value","pos","val","succ","pred","leftof","rightof","left","right","high","low",
620 "range","reverse_range","length","ascending","delayed","stable","quiet","transaction","event",
621 "active","last_event","last_active","last_value","driving","driving_value","simple_name","instance_name","path_name",0
625 g_vhdlKeyDict0.setAutoDelete(TRUE);
626 g_vhdlKeyDict1.setAutoDelete(TRUE);
627 g_vhdlKeyDict2.setAutoDelete(TRUE);
628 g_vhdlKeyDict3.setAutoDelete(TRUE);
630 while (g_vhdlKeyWordMap0[j])
632 g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
633 new QCString(g_vhdlKeyWordMap0[j]));
638 while (g_vhdlKeyWordMap1[j])
640 g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
641 new QCString(g_vhdlKeyWordMap1[j]));
646 while (g_vhdlKeyWordMap2[j])
648 g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
649 new QCString(g_vhdlKeyWordMap2[j]));
654 while (g_vhdlKeyWordMap3[j])
656 g_vhdlKeyDict3.insert(g_vhdlKeyWordMap3[j],
657 new QCString(g_vhdlKeyWordMap3[j]));
664 * returns the color of a keyword
667 QCString* VhdlDocGen::findKeyWord(const QCString& tmp)
669 static QCString vhdlkeyword("vhdlkeyword");
670 static QCString vhdltype("comment");
671 static QCString vhdllogic("vhdllogic");
672 static QCString preprocessor("keywordflow");
674 QCString word=tmp.lower();
676 if (word.isEmpty() || word.at(0)=='\0') return 0;
678 if (g_vhdlKeyDict0.find(word))
679 return &preprocessor;
681 if (g_vhdlKeyDict1.find(word))
684 if (g_vhdlKeyDict2.find(word))
687 if (g_vhdlKeyDict3.find(word))
693 ClassDef *VhdlDocGen::getClass(const char *name)
695 if (name==0 || name[0]=='\0') return 0;
700 temp=temp.stripWhiteSpace();
701 cd= Doxygen::classSDict->find(temp.data());
705 ClassDef* VhdlDocGen::getPackageName(const QCString & name)
713 static QMap<QCString,MemberDef*> varMap;
714 static QList<ClassDef> qli;
715 static QMap<ClassDef*,QList<ClassDef> > packages;
717 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
722 cd=getClass(className);
723 //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
726 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_variableMembers);
727 if (mdef) return mdef;
728 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
729 if (mdef) return mdef;
731 // nothing found so far
732 // if we are an architecture or package body search in entity
734 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
735 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
737 Definition *d = cd->getOuterScope();
738 // searching upper/lower case names
740 QCString tt=d->name();
753 if (ecd) //d && d->definitionType()==Definition::TypeClass)
755 //ClassDef *ecd = (ClassDef*)d;
756 mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberListType_variableMembers);
757 if (mdef) return mdef;
758 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType_pubMethods);
759 if (mdef) return mdef;
764 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
765 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
767 Definition *d = cd->getOuterScope();
769 QCString tt=d->name();
770 ClassDef *ecd =getClass(tt);
781 if (ecd) //d && d->definitionType()==Definition::TypeClass)
783 if(!packages.contains(ecd))
785 VhdlDocGen::findAllPackages(ecd);
792 if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
795 QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.find(ecd);
798 QList<ClassDef> mlist=cList.data();
799 for (uint j=0;j<mlist.count();j++)
801 mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_variableMembers);
802 if (mdef) return mdef;
803 mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
804 if (mdef) return mdef;
812 * This function returns the entity|package
813 * in which the key (type) is found
815 MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberListType type)
819 QCString keyType=cd->symbolName()+"@"+key;
820 //printf("\n %s | %s | %s",cd->symbolName().data(),key.data(,),keyType.data());
822 QMap<QCString, MemberDef*>::Iterator it =varMap.find(keyType);
831 if (qli.contains(cd))
835 ml=cd->getMemberList(type);
841 MemberListIterator fmni(*ml);
843 // fprintf(stderr,"\n loading entity %s %s: %d",cd->symbolName().data(),keyType.data(),l);
845 for (fmni.toFirst();(md=fmni.current());++fmni)
847 QCString tkey=cd->symbolName()+"@"+md->name();
848 if (varMap.contains(tkey))
852 varMap.insert(tkey.data(),md);
854 it=varMap.find(keyType.data());
867 * finds all included packages of an Entity or Package
870 void VhdlDocGen::findAllPackages( ClassDef *cdef)
872 QList<ClassDef> cList;
873 if (packages.contains(cdef)) return;
874 MemberList *mem=cdef->getMemberList(MemberListType_variableMembers);
879 MemberListIterator fmni(*mem);
880 for (fmni.toFirst();(md=fmni.current());++fmni)
882 if (VhdlDocGen::isPackage(md))
884 ClassDef* cd=VhdlDocGen::getPackageName(md->name());
888 VhdlDocGen::findAllPackages(cd);
889 packages.insert(cdef,cList);
897 * returns the function with the matching argument list
898 * is called in vhdlcode.l
901 MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
902 const QCString& funcname,
903 const QCString& package, bool /*type*/)
907 ClassDef *cdef=getClass(package.data());
908 if (cdef==0) return 0;
910 MemberList *mem=cdef->getMemberList(MemberListType_pubMethods);
914 MemberListIterator fmni(*mem);
915 for (fmni.toFirst();(mdef=fmni.current());++fmni)
917 QCString mname=mdef->name();
918 if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
920 ArgumentList *alp = mdef->argumentList();
922 // ArgumentList* arg2=mdef->getArgumentList();
924 ArgumentListIterator ali(*alp);
925 ArgumentListIterator ali1(ql);
927 if (ali.count() != ali1.count()) break;
932 for (;(arg=ali.current()) && (arg1=ali1.current());++ali,++ali1)
934 equ+=abs(compareString(arg->type,arg1->type));
936 QCString s1=arg->type;
937 QCString s2=arg1->type;
938 VhdlDocGen::deleteAllChars(s1,' ');
939 VhdlDocGen::deleteAllChars(s2,' ');
940 equ+=abs(compareString(s1,s2));
943 VhdlDocGen::deleteAllChars(s1,' ');
944 VhdlDocGen::deleteAllChars(s2,' ');
945 equ+=abs(compareString(s1,s2));
946 // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
947 // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
949 if (equ==0) return mdef;
960 * returns the class title+ref
963 QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
966 if (cd==0) return "";
967 pageTitle=VhdlDocGen::getClassName(cd);
968 int ii=cd->protection();
970 pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
975 /* returns the class name without their prefixes */
977 QCString VhdlDocGen::getClassName(const ClassDef* cd)
980 if (cd==0) return "";
982 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
985 temp.stripPrefix("_");
989 return substitute(cd->className(),"::",".");
993 * writes an inline link form entity|package to architecture|package body and vice verca
996 void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol)
999 ql.setAutoDelete(TRUE);
1000 QCString nn=cd->className();
1001 int ii=(int)cd->protection()+2;
1004 if (ii==VhdlDocGen::ENTITY)
1005 type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE);
1006 else if (ii==VhdlDocGen::ARCHITECTURE)
1007 type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE);
1008 else if (ii==VhdlDocGen::PACKAGE_BODY)
1009 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
1010 else if (ii==VhdlDocGen::PACKAGE)
1011 type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE);
1015 //type=type.lower();
1017 ol.disable(OutputGenerator::RTF);
1018 ol.disable(OutputGenerator::Man);
1020 if (ii==VhdlDocGen::PACKAGE_BODY)
1022 nn.stripPrefix("_");
1023 cd=getClass(nn.data());
1025 else if (ii==VhdlDocGen::PACKAGE)
1028 cd=getClass(nn.data());
1030 else if (ii==VhdlDocGen::ARCHITECTURE)
1032 QStringList qlist=QStringList::split("-",nn,FALSE);
1034 cd=VhdlDocGen::getClass(nn.data());
1038 if (ii==VhdlDocGen::ENTITY)
1040 VhdlDocGen::findAllArchitectures(ql,cd);
1042 for (int i=0;i<j;i++)
1044 QCString *temp=ql.at(i);
1045 QStringList qlist=QStringList::split("-",*temp,FALSE);
1046 QCString s1=qlist[0].utf8();
1047 QCString s2=qlist[1].utf8();
1048 s1.stripPrefix("_");
1049 if (j==1) s1.resize(0);
1050 ClassDef*cc = getClass(temp->data());
1053 VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
1059 VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
1062 ol.enable(OutputGenerator::Man);
1063 ol.enable(OutputGenerator::RTF);
1068 * finds all architectures which belongs to an entity
1070 void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
1073 ClassSDict::Iterator cli(*Doxygen::classSDict);
1074 for ( ; (citer=cli.current()) ; ++cli )
1076 QCString jj=citer->className();
1077 if (cd != citer && jj.contains('-')!=-1)
1079 QStringList ql=QStringList::split("-",jj,FALSE);
1080 QCString temp=ql[1].utf8();
1081 if (qstricmp(cd->className(),temp)==0)
1083 QCString *cl=new QCString(jj);
1088 }//findAllArchitectures
1090 ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd)
1093 QCString nn=cd->name();
1094 ClassSDict::Iterator cli(*Doxygen::classSDict);
1096 for ( ; (citer=cli.current()) ; ++cli )
1098 QCString jj=citer->name();
1099 QStringList ql=QStringList::split(":",jj,FALSE);
1102 if (ql[0].utf8()==nn )
1111 * writes the link entity >> .... or architecture >> ...
1114 void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
1118 ol.docify(type.data());
1120 nn.stripPrefix("_");
1121 ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
1123 if (!behav.isEmpty())
1127 ol.docify(behav.data());
1136 * strips the "--" prefixes of vhdl comments
1138 void VhdlDocGen::prepareComment(QCString& qcs)
1140 const char* s="--!";
1145 index=qcs.find(s,0,TRUE);
1147 qcs=qcs.remove(index,qstrlen(s));
1149 qcs=qcs.stripWhiteSpace();
1154 * parses a function proto
1155 * @param text function string
1156 * @param qlist stores the function types
1157 * @param name points to the function name
1158 * @param ret Stores the return type
1161 void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
1162 QCString& name,QCString& ret,bool doc)
1164 (void)qlist; //unused
1170 end=s1.findRev(")");
1174 temp=s1.mid(index+1,(end-index-1));
1175 //getFuncParams(qlist,temp);
1179 name=s1.left(index);
1180 name=name.stripWhiteSpace();
1190 s1=s1.stripWhiteSpace();
1191 int i=s1.find("(",0,FALSE);
1192 int s=s1.find(QRegExp("[ \\t]"));
1194 s1=VhdlDocGen::getIndexWord(s1.data(),1);
1195 else // s<i, s=start of name, i=end of name
1198 name=s1.stripWhiteSpace();
1200 index=s1.findRev("return",-1,FALSE);
1203 ret=s1.mid(index+6,s1.length());
1204 ret=ret.stripWhiteSpace();
1205 VhdlDocGen::deleteCharRev(ret,';');
1210 * returns the n'th word of a string
1213 QCString VhdlDocGen::getIndexWord(const char* c,int index)
1217 QRegExp reg("[\\s:|]");
1219 ql=QStringList::split(reg,temp,FALSE);
1221 if (ql.count() > (unsigned int)index)
1223 return ql[index].utf8();
1230 QCString VhdlDocGen::getProtectionName(int prot)
1232 if (prot==VhdlDocGen::ENTITYCLASS)
1234 else if (prot==VhdlDocGen::ARCHITECTURECLASS)
1235 return "architecture";
1236 else if (prot==VhdlDocGen::PACKAGECLASS)
1238 else if (prot==VhdlDocGen::PACKBODYCLASS)
1239 return "package body";
1244 QCString VhdlDocGen::trTypeString(uint64 type)
1248 case VhdlDocGen::LIBRARY: return "Library";
1249 case VhdlDocGen::ENTITY: return "Entity";
1250 case VhdlDocGen::PACKAGE_BODY: return "Package Body";
1251 case VhdlDocGen::ATTRIBUTE: return "Attribute";
1252 case VhdlDocGen::PACKAGE: return "Package";
1253 case VhdlDocGen::SIGNAL: return "Signal";
1254 case VhdlDocGen::COMPONENT: return "Component";
1255 case VhdlDocGen::CONSTANT: return "Constant";
1256 case VhdlDocGen::TYPE: return "Type";
1257 case VhdlDocGen::SUBTYPE: return "Subtype";
1258 case VhdlDocGen::FUNCTION: return "Function";
1259 case VhdlDocGen::RECORD: return "Record";
1260 case VhdlDocGen::PROCEDURE: return "Procedure";
1261 case VhdlDocGen::ARCHITECTURE: return "Architecture";
1262 case VhdlDocGen::USE: return "Package";
1263 case VhdlDocGen::PROCESS: return "Process";
1264 case VhdlDocGen::PORT: return "Port";
1265 case VhdlDocGen::GENERIC: return "Generic";
1266 case VhdlDocGen::UNITS: return "Units";
1267 //case VhdlDocGen::PORTMAP: return "Port Map";
1268 case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
1269 case VhdlDocGen::GROUP: return "Group";
1270 case VhdlDocGen::VFILE: return "File";
1271 case VhdlDocGen::INSTANTIATION: return "Instantiation";
1272 case VhdlDocGen::ALIAS: return "Alias";
1273 case VhdlDocGen::CONFIG: return "Configuration";
1274 case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous";
1275 case VhdlDocGen::UCF_CONST: return "Constraints";
1281 * deletes a char backwards in a string
1284 bool VhdlDocGen::deleteCharRev(QCString &s,char c)
1286 int index=s.findRev(c,-1,FALSE);
1289 QCString qcs=s.remove(index,1);
1296 void VhdlDocGen::deleteAllChars(QCString &s,char c)
1298 int index=s.findRev(c,-1,FALSE);
1301 QCString qcs=s.remove(index,1);
1303 index=s.findRev(c,-1,FALSE);
1308 static int recordCounter=0;
1311 * returns the next number of a record|unit member
1314 QCString VhdlDocGen::getRecordNumber()
1317 sprintf(buf,"%d",recordCounter++);
1318 QCString qcs(&buf[0]);
1323 * returns the next number of an anonymous process
1326 QCString VhdlDocGen::getProcessNumber()
1328 static int stringCounter;
1330 QCString qcs("PROCESS_");
1331 sprintf(buf,"%d",stringCounter++);
1332 qcs.append(&buf[0]);
1337 * writes a colored and formatted string
1340 void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
1342 QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
1344 qcs+=QCString(" ");// parsing the last sign
1353 j = reg.match(temp.data(),0,&len);
1362 ss=VhdlDocGen::findKeyWord(find);
1363 bool k=isNumber(find); // is this a number
1367 startFonts(find,"vhdldigit",ol);
1370 else if (j != 0 && ss)
1372 startFonts(find,ss->data(),ol);
1378 VhdlDocGen::writeStringLink(mdef,find,ol);
1381 startFonts(&buf[0],"vhdlchar",ol);
1383 QCString st=temp.remove(0,j+1);
1385 if (!find.isEmpty() && find.at(0)=='"')
1387 int ii=find.find('"',2);
1390 QCString com=find.left(ii+1);
1391 startFonts(com,"keyword",ol);
1392 temp=find.remove(0,ii+1);
1399 j = reg.match(temp.data(),0,&len);
1404 startFonts(find,"vhdlchar",ol);
1407 }// writeFormatString
1410 * returns TRUE if this string is a number
1412 bool VhdlDocGen::isNumber(const QCString& s)
1414 static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
1416 if (s.isEmpty()) return FALSE;
1418 j = regg.match(s.data(),0,&len);
1419 if ((j==0) && (len==(int)s.length())) return TRUE;
1426 * inserts white spaces for better readings
1427 * and writes a colored string to the output
1430 void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
1434 qcs.stripPrefix(":");
1435 qcs.stripPrefix("is");
1436 qcs.stripPrefix("IS");
1437 qcs.stripPrefix("of");
1438 qcs.stripPrefix("OF");
1440 // VhdlDocGen::deleteCharRev(qcs,';');
1442 int len = qcs.length();
1443 unsigned int index=1;//temp.length();
1445 for (int j=0;j<len;j++)
1449 if (j>0) b=qcs[j-1];
1450 if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
1452 if (temp.length()>=index && temp.at(index-1) != ' ')
1461 if (b==':') // := operator
1463 temp.replace(index-1,1,"=");
1478 index=temp.length();
1480 temp=temp.stripWhiteSpace();
1481 // printf("\n [%s]",qcs.data());
1482 VhdlDocGen::writeFormatString(temp,ol,mdef);
1486 * writes a procedure prototype to the output
1489 void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1491 ArgumentListIterator ali(*al);
1494 int len=al->count();
1500 for (;(arg=ali.current());++ali)
1506 QCString nn=arg->name;
1509 QCString *str=VhdlDocGen::findKeyWord(arg->defval);
1513 startFonts(arg->defval,str->data(),ol);
1517 startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
1520 startFonts(nn,"vhdlchar",ol); // write name
1521 if (qstricmp(arg->attrib,arg->type) != 0)
1523 startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
1526 VhdlDocGen::formatString(arg->type,ol,mdef);
1542 * writes a function prototype to the output
1545 void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1548 ArgumentListIterator ali(*al);
1551 int len=al->count();
1559 for (;(arg=ali.current());++ali)
1562 QCString att=arg->defval;
1563 bool bGen=att.stripPrefix("gen!");
1572 VhdlDocGen::formatString(QCString("generic "),ol,mdef);
1576 QCString *str=VhdlDocGen::findKeyWord(att);
1579 VhdlDocGen::formatString(att,ol,mdef);
1581 startFonts(att,"vhdlchar",ol);
1584 QCString nn=arg->name;
1586 QCString ss=arg->type.stripWhiteSpace(); //.lower();
1587 QCString w=ss.stripWhiteSpace();//.upper();
1588 startFonts(nn,"vhdlchar",ol);
1589 startFonts("in ","stringliteral",ol);
1590 QCString *str=VhdlDocGen::findKeyWord(ss);
1592 VhdlDocGen::formatString(w,ol,mdef);
1594 startFonts(w,"vhdlchar",ol);
1597 startFonts(arg->attrib,"vhdlchar",ol);
1609 const char *exp=mdef->excpString();
1612 ol.insertMemberAlign();
1623 * writes a process prototype to the output
1626 void VhdlDocGen::writeProcessProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1629 ArgumentListIterator ali(*al);
1634 for (;(arg=ali.current());++ali)
1640 QCString nn=arg->name;
1641 // startFonts(nn,"vhdlchar",ol);
1642 VhdlDocGen::writeFormatString(nn,ol,mdef);
1651 * writes a function|procedure documentation to the output
1654 bool VhdlDocGen::writeFuncProcDocu(
1655 const MemberDef *md,
1657 const ArgumentList* al,
1660 if (al==0) return FALSE;
1664 ArgumentListIterator ali(*al);
1665 int index=ali.count();
1671 ol.endMemberDocName();
1672 ol.startParameterList(TRUE);
1673 //ol.startParameterName(FALSE);
1676 for (;(arg=ali.current());++ali)
1678 ol.startParameterType(first,"");
1679 // if (first) ol.writeChar('(');
1680 QCString attl=arg->defval;
1681 bool bGen=attl.stripPrefix("gen!");
1683 VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
1686 if (VhdlDocGen::isProcedure(md))
1688 startFonts(arg->defval,"keywordtype",ol);
1691 ol.endParameterType();
1693 ol.startParameterName(TRUE);
1694 VhdlDocGen::writeFormatString(arg->name,ol,md);
1696 if (VhdlDocGen::isProcedure(md))
1698 startFonts(arg->attrib,"stringliteral",ol);
1700 else if (VhdlDocGen::isVhdlFunction(md))
1702 startFonts(QCString("in"),"stringliteral",ol);
1706 ol.disable(OutputGenerator::Man);
1708 ol.enable(OutputGenerator::Man);
1709 if (!VhdlDocGen::isProcess(md))
1711 // startFonts(arg->type,"vhdlkeyword",ol);
1712 VhdlDocGen::writeFormatString(arg->type,ol,md);
1714 ol.disable(OutputGenerator::Man);
1716 ol.enable(OutputGenerator::Man);
1724 // ol.docify(" ) ");
1725 ol.endParameterName(TRUE,FALSE,TRUE);
1728 ol.endParameterName(FALSE,FALSE,FALSE);
1733 //ol.endParameterList();
1736 } // writeDocFunProc
1741 QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool func)
1745 ArgumentListIterator ali(*al);
1748 for (;(arg=ali.current());++ali)
1750 if (sem) argString.append(", ");
1753 argString+=arg->name;
1755 argString+=arg->type;
1759 argString+=arg->defval+" ";
1760 argString+=arg->name+" :";
1761 argString+=arg->attrib+" ";
1762 argString+=arg->type;
1770 void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
1771 OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
1773 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
1774 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
1775 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
1776 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
1777 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONSTANT,FALSE),0,FALSE,VhdlDocGen::CONSTANT);
1778 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::TYPE,FALSE),0,FALSE,VhdlDocGen::TYPE);
1779 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SUBTYPE,FALSE),0,FALSE,VhdlDocGen::SUBTYPE);
1780 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GENERIC,FALSE),0,FALSE,VhdlDocGen::GENERIC);
1781 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PORT,FALSE),0,FALSE,VhdlDocGen::PORT);
1782 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCESS,FALSE),0,FALSE,VhdlDocGen::PROCESS);
1783 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SIGNAL,FALSE),0,FALSE,VhdlDocGen::SIGNAL);
1784 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ATTRIBUTE,FALSE),0,FALSE,VhdlDocGen::ATTRIBUTE);
1785 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCEDURE,FALSE),0,FALSE,VhdlDocGen::PROCEDURE);
1786 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::RECORD,FALSE),0,FALSE,VhdlDocGen::RECORD);
1787 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UNITS,FALSE),0,FALSE,VhdlDocGen::UNITS);
1788 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE);
1789 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE);
1790 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP);
1791 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION);
1792 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS);
1793 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS);
1795 // configurations must be added to global file definitions.
1796 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG);
1797 VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
1801 static void setGlobalType(MemberList *ml)
1805 MemberListIterator mmli(*ml);
1806 for ( ; (mdd=mmli.current()); ++mmli )
1808 if (qstrcmp(mdd->argsString(),"package")==0)
1810 mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
1812 else if (qstrcmp(mdd->argsString(),"configuration")==0)
1814 mdd->setMemberSpecifiers(VhdlDocGen::CONFIG);
1816 else if (qstrcmp(mdd->typeString(),"library")==0)
1818 mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY);
1820 else if (qstrcmp(mdd->typeString(),"use")==0)
1822 mdd->setMemberSpecifiers(VhdlDocGen::USE);
1824 else if (qstricmp(mdd->typeString(),"misc")==0)
1826 mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
1828 else if (qstricmp(mdd->typeString(),"ucf_const")==0)
1830 mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
1835 /* writes a vhdl type documentation */
1836 bool VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol)
1838 ClassDef *cd=(ClassDef*)d;
1839 bool hasParams = FALSE;
1841 if (cd==0) return hasParams;
1843 QCString ttype=mdef->typeString();
1844 QCString largs=mdef->argsString();
1846 if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
1848 QCString nn=mdef->typeString();
1849 nn=nn.stripWhiteSpace();
1850 QCString na=cd->name();
1851 MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1852 if (memdef && memdef->isLinkable())
1857 writeLink(memdef,ol);
1864 VhdlDocGen::formatString(ttype,ol,mdef);
1867 ol.docify(mdef->name());
1868 hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
1872 if (mdef->isVariable())
1874 if (VhdlDocGen::isConstraint(mdef))
1879 largs=largs.replace(QRegExp("#")," ");
1880 VhdlDocGen::formatString(largs,ol,mdef);
1886 if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
1893 // QCString largs=mdef->argsString();
1895 bool c=largs=="context";
1896 bool brec=largs.stripPrefix("record") ;
1899 VhdlDocGen::formatString(ttype,ol,mdef);
1901 if (c || brec || largs.stripPrefix("units"))
1905 VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1910 if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1912 // QCString largs=mdef->argsString();
1913 VhdlDocGen::formatString(largs,ol,mdef);
1920 void VhdlDocGen::writeTagFile(MemberDef *mdef,FTextStream &tagFile)
1922 tagFile << " <member kind=\"";
1923 if (VhdlDocGen::isGeneric(mdef)) tagFile << "generic";
1924 if (VhdlDocGen::isPort(mdef)) tagFile << "port";
1925 if (VhdlDocGen::isEntity(mdef)) tagFile << "entity";
1926 if (VhdlDocGen::isComponent(mdef)) tagFile << "component";
1927 if (VhdlDocGen::isVType(mdef)) tagFile << "type";
1928 if (VhdlDocGen::isConstant(mdef)) tagFile << "constant";
1929 if (VhdlDocGen::isSubType(mdef)) tagFile << "subtype";
1930 if (VhdlDocGen::isVhdlFunction(mdef)) tagFile << "function";
1931 if (VhdlDocGen::isProcedure(mdef)) tagFile << "procedure";
1932 if (VhdlDocGen::isProcess(mdef)) tagFile << "process";
1933 if (VhdlDocGen::isSignals(mdef)) tagFile << "signal";
1934 if (VhdlDocGen::isAttribute(mdef)) tagFile << "attribute";
1935 if (VhdlDocGen::isRecord(mdef)) tagFile << "record";
1936 if (VhdlDocGen::isLibrary(mdef)) tagFile << "library";
1937 if (VhdlDocGen::isPackage(mdef)) tagFile << "package";
1938 if (VhdlDocGen::isVariable(mdef)) tagFile << "shared variable";
1939 if (VhdlDocGen::isFile(mdef)) tagFile << "file";
1940 if (VhdlDocGen::isGroup(mdef)) tagFile << "group";
1941 if (VhdlDocGen::isCompInst(mdef)) tagFile << "instantiation";
1942 if (VhdlDocGen::isAlias(mdef)) tagFile << "alias";
1943 if (VhdlDocGen::isCompInst(mdef)) tagFile << "configuration";
1945 tagFile << "\">" << endl;
1946 tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
1947 tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
1948 tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
1949 tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
1951 if (VhdlDocGen::isVhdlFunction(mdef))
1952 tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),TRUE)) << "</arglist>" << endl;
1953 else if (VhdlDocGen::isProcedure(mdef))
1954 tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),FALSE)) << "</arglist>" << endl;
1956 tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
1958 mdef->writeDocAnchorsToTagFile(tagFile);
1959 tagFile << " </member>" << endl;
1962 /* writes a vhdl type declaration */
1964 void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
1965 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1970 ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
1971 mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY ||
1972 mdef->getMemberSpecifiers()==VhdlDocGen::USE
1973 ); // member should belong to something
1978 else d=(Definition*)mdef;
1980 // write search index info
1981 if (Doxygen::searchIndex)
1983 Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
1984 Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
1985 Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
1988 QCString cname = d->name();
1989 QCString cfname = d->getOutputFileBase();
1991 //HtmlHelp *htmlHelp=0;
1992 // bool hasHtmlHelp = Config_getBool(GENERATE_HTML) && Config_getBool(GENERATE_HTMLHELP);
1993 // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1995 // search for the last anonymous scope in the member type
1996 ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
1998 // start a new member declaration
1999 uint isAnonymous = (bool)(annoClassDef); // || m_impl->annMemb || m_impl->annEnumType;
2000 ///printf("startMemberItem for %s\n",name().data());
2001 int mm=mdef->getMemberSpecifiers();
2002 if (mm==VhdlDocGen::MISCELLANEOUS)
2005 ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
2007 // If there is no detailed description we need to write the anchor here.
2008 bool detailsVisible = mdef->isDetailedSectionLinkable();
2009 if (!detailsVisible) // && !m_impl->annMemb)
2011 QCString doxyName=mdef->name().copy();
2012 if (!cname.isEmpty()) doxyName.prepend(cname+"::");
2013 QCString doxyArgs=mdef->argsString();
2014 ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
2016 ol.pushGeneratorState();
2017 ol.disable(OutputGenerator::Man);
2018 ol.disable(OutputGenerator::Latex);
2020 ol.popGeneratorState();
2026 QCString ltype(mdef->typeString());
2027 // ltype=ltype.replace(reg," ");
2028 QCString largs(mdef->argsString());
2029 // largs=largs.replace(reg," ");
2030 mdef->setType(ltype.data());
2031 mdef->setArgsString(largs.data());
2032 //ClassDef * plo=mdef->getClassDef();
2034 ArgumentList *alp = mdef->argumentList();
2036 //VhdlDocGen::adjustRecordMember(mdef);
2040 case VhdlDocGen::MISCELLANEOUS:
2041 VhdlDocGen::writeSource(mdef,ol,nn);
2043 case VhdlDocGen::PROCEDURE:
2044 case VhdlDocGen::FUNCTION:
2046 VhdlDocGen::formatString(ltype,ol,mdef);
2048 ol.insertMemberAlign();
2052 if (alp!=0 && mm==VhdlDocGen::FUNCTION)
2053 VhdlDocGen::writeFunctionProto(ol,alp,mdef);
2055 if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
2056 VhdlDocGen::writeProcedureProto(ol,alp,mdef);
2059 case VhdlDocGen::USE:
2060 kl=VhdlDocGen::getClass(mdef->name());
2061 if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
2063 ol.insertMemberAlign();
2068 nn=kl->getOutputFileBase();
2069 ol.pushGeneratorState();
2070 ol.disableAllBut(OutputGenerator::Html);
2072 QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
2074 ol.docify(name.data());
2077 name+=" <"+mdef->name()+">";
2079 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2080 ol.popGeneratorState();
2083 case VhdlDocGen::LIBRARY:
2085 ol.insertMemberAlign();
2086 if (largs=="context")
2088 VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
2093 case VhdlDocGen::GENERIC:
2094 case VhdlDocGen::PORT:
2095 case VhdlDocGen::ALIAS:
2099 ol.insertMemberAlign();
2100 if (mm==VhdlDocGen::GENERIC)
2103 VhdlDocGen::formatString(largs,ol,mdef);
2110 VhdlDocGen::formatString(ltype,ol,mdef);
2113 VhdlDocGen::formatString(largs,ol,mdef);
2116 case VhdlDocGen::PROCESS:
2118 ol.insertMemberAlign();
2119 VhdlDocGen::writeProcessProto(ol,alp,mdef);
2121 case VhdlDocGen::PACKAGE:
2122 case VhdlDocGen::ENTITY:
2123 case VhdlDocGen::COMPONENT:
2124 case VhdlDocGen::INSTANTIATION:
2125 case VhdlDocGen::CONFIG:
2126 if (VhdlDocGen::isCompInst(mdef) )
2129 if(nn.stripPrefix("function") || nn.stripPrefix("package"))
2131 VhdlDocGen::formatString(largs,ol,mdef);
2132 ol.insertMemberAlign();
2135 VhdlDocGen::formatString(ltype,ol,mdef);
2139 largs.prepend("::");
2140 largs.prepend(mdef->name().data());
2141 ol.writeObjectLink(mdef->getReference(),
2149 ol.insertMemberAlign();
2156 if (VhdlDocGen::isComponent(mdef) ||
2157 VhdlDocGen::isConfig(mdef) ||
2158 VhdlDocGen::isCompInst(mdef))
2160 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2168 kl=getClass(nn.data());
2171 nn=kl->getOutputFileBase();
2172 ol.pushGeneratorState();
2173 ol.disableAllBut(OutputGenerator::Html);
2175 QCString name("<Entity ");
2176 if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2182 name+=mdef->name()+"> ";
2184 ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2186 ol.popGeneratorState();
2190 case VhdlDocGen::UCF_CONST:
2191 mm=mdef->name().findRev('_');
2194 mdef->setName(mdef->name().left(mm));
2196 writeUCFLink(mdef,ol);
2198 case VhdlDocGen::SIGNAL:
2199 case VhdlDocGen::ATTRIBUTE:
2200 case VhdlDocGen::SUBTYPE:
2201 case VhdlDocGen::CONSTANT:
2202 case VhdlDocGen::SHAREDVARIABLE:
2203 case VhdlDocGen::VFILE:
2204 case VhdlDocGen::GROUP:
2207 ol.insertMemberAlign();
2208 VhdlDocGen::formatString(ltype,ol,mdef);
2210 case VhdlDocGen::RECORD:
2211 case VhdlDocGen::UNITS:
2215 if (ltype.isEmpty()) {
2218 ol.insertMemberAlign();
2219 if (!ltype.isEmpty())
2220 VhdlDocGen::formatString(ltype,ol,mdef);
2223 case VhdlDocGen::TYPE:
2224 bRec=largs.stripPrefix("record") ;
2225 bUnit=largs.stripPrefix("units") ;
2227 if (bRec) ol.docify("record: ");
2228 if (bUnit) ol.docify("units: ");
2230 ol.insertMemberAlign();
2231 if (!bRec && !bUnit) VhdlDocGen::formatString(ltype,ol,mdef);
2232 if (bUnit) ol.lineBreak();
2235 writeRecorUnit(largs,ol,mdef);
2244 bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2245 if (htmlOn && /*Config_getBool(HTML_ALIGN_MEMBERS) &&*/ !ltype.isEmpty())
2247 ol.disable(OutputGenerator::Html);
2249 if (!ltype.isEmpty()) ol.docify(" ");
2253 ol.enable(OutputGenerator::Html);
2256 if (!detailsVisible)// && !m_impl->annMemb)
2258 ol.endDoxyAnchor(cfname,mdef->anchor());
2261 // name().data(),annoClassDef,annEnumType);
2262 // if(mm!=VhdlDocGen::MISCELLANEOUS)
2264 if (!mdef->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC) /* && !annMemb */)
2266 QCString s=mdef->briefDescription();
2267 ol.startMemberDescription(mdef->anchor());
2268 ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
2269 mdef->getOuterScope()?mdef->getOuterScope():d,
2270 mdef,s.data(),TRUE,FALSE,0,TRUE,FALSE);
2273 ol.pushGeneratorState();
2274 ol.disableAllBut(OutputGenerator::Html);
2277 if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
2279 ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
2283 ol.startTextLink(0,mdef->anchor());
2286 //ol.startEmphasis();
2287 ol.popGeneratorState();
2289 //ol.newParagraph();
2290 ol.endMemberDescription();
2292 mdef->warnIfUndocumented();
2294 }// end writeVhdlDeclaration
2297 void VhdlDocGen::writePlainVHDLDeclarations(
2298 MemberList* mlist,OutputList &ol,
2299 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
2302 SDict<QCString> pack(1009);
2303 pack.setAutoDelete(TRUE);
2307 MemberListIterator mli(*mlist);
2308 for ( ; (md=mli.current()); ++mli )
2310 int mems=md->getMemberSpecifiers();
2311 if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
2313 if (first) { ol.startMemberList();first=FALSE; }
2314 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2316 else if (md->isBriefSectionVisible() && (mems==specifier))
2318 if (!pack.find(md->name().data()))
2320 if (first) ol.startMemberList(),first=FALSE;
2321 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2322 pack.append(md->name().data(),new QCString(md->name().data()));
2326 if (!first) ol.endMemberList();
2330 static bool membersHaveSpecificType(MemberList *ml,uint64 type)
2332 if (ml==0) return FALSE;
2334 MemberListIterator mmli(*ml);
2335 for ( ; (mdd=mmli.current()); ++mmli )
2337 if (mdd->getMemberSpecifiers()==type) //is type in class
2342 if (ml->getMemberGroupList())
2344 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2346 while ((mg=mgli.current()))
2350 if (membersHaveSpecificType(mg->members(),type)) return TRUE;
2358 void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
2359 ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
2360 const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
2363 if (!membersHaveSpecificType(ml,type)) return;
2367 ol.startMemberHeader(title);
2368 ol.parseText(title);
2369 ol.endMemberHeader();
2372 if (subtitle && subtitle[0]!=0)
2374 ol.startMemberSubtitle();
2375 ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
2376 ol.endMemberSubtitle();
2377 } //printf("memberGroupList=%p\n",memberGroupList);
2379 VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
2381 if (ml->getMemberGroupList())
2383 MemberGroupListIterator mgli(*ml->getMemberGroupList());
2385 while ((mg=mgli.current()))
2387 if (membersHaveSpecificType(mg->members(),type))
2389 //printf("mg->header=%s\n",mg->header().data());
2390 bool hasHeader=mg->header()!="[NOHEADER]";
2391 ol.startMemberGroupHeader(hasHeader);
2394 ol.parseText(mg->header());
2396 ol.endMemberGroupHeader();
2397 if (!mg->documentation().isEmpty())
2399 //printf("Member group has docs!\n");
2400 ol.startMemberGroupDocs();
2401 ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
2402 ol.endMemberGroupDocs();
2404 ol.startMemberGroup();
2405 //printf("--- mg->writePlainDeclarations ---\n");
2406 VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
2407 ol.endMemberGroup(hasHeader);
2412 }// writeVHDLDeclarations
2415 bool VhdlDocGen::writeClassType( ClassDef *& cd,
2416 OutputList &ol ,QCString & cname)
2418 int id=cd->protection();
2419 QCString qcs = VhdlDocGen::trTypeString(id+2);
2420 cname=VhdlDocGen::getClassName(cd);
2422 ol.writeString(qcs.data());
2423 ol.writeString(" ");
2425 //ol.insertMemberAlign();
2429 QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
2433 case VhdlDocGen::LIBRARY:
2434 if (sing) return "Library";
2435 else return "Libraries";
2436 case VhdlDocGen::PACKAGE:
2437 if (sing) return "Package";
2438 else return "Packages";
2439 case VhdlDocGen::SIGNAL:
2440 if (sing) return "Signal";
2441 else return "Signals";
2442 case VhdlDocGen::COMPONENT:
2443 if (sing) return "Component";
2444 else return "Components";
2445 case VhdlDocGen::CONSTANT:
2446 if (sing) return "Constant";
2447 else return "Constants";
2448 case VhdlDocGen::ENTITY:
2449 if (sing) return "Entity";
2450 else return "Entities";
2451 case VhdlDocGen::TYPE:
2452 if (sing) return "Type";
2453 else return "Types";
2454 case VhdlDocGen::SUBTYPE:
2455 if (sing) return "Subtype";
2456 else return "Subtypes";
2457 case VhdlDocGen::FUNCTION:
2458 if (sing) return "Function";
2459 else return "Functions";
2460 case VhdlDocGen::RECORD:
2461 if (sing) return "Record";
2462 else return "Records";
2463 case VhdlDocGen::PROCEDURE:
2464 if (sing) return "Procedure";
2465 else return "Procedures";
2466 case VhdlDocGen::ARCHITECTURE:
2467 if (sing) return "Architecture";
2468 else return "Architectures";
2469 case VhdlDocGen::ATTRIBUTE:
2470 if (sing) return "Attribute";
2471 else return "Attributes";
2472 case VhdlDocGen::PROCESS:
2473 if (sing) return "Process";
2474 else return "Processes";
2475 case VhdlDocGen::PORT:
2476 if (sing) return "Port";
2477 else return "Ports";
2478 case VhdlDocGen::USE:
2479 if (sing) return "use clause";
2480 else return "Use Clauses";
2481 case VhdlDocGen::GENERIC:
2482 if (sing) return "Generic";
2483 else return "Generics";
2484 case VhdlDocGen::PACKAGE_BODY:
2485 return "Package Body";
2486 case VhdlDocGen::UNITS:
2488 case VhdlDocGen::SHAREDVARIABLE:
2489 if (sing) return "Shared Variable";
2490 return "Shared Variables";
2491 case VhdlDocGen::VFILE:
2492 if (sing) return "File";
2494 case VhdlDocGen::GROUP:
2495 if (sing) return "Group";
2497 case VhdlDocGen::INSTANTIATION:
2498 if (sing) return "Instantiation";
2499 else return "Instantiations";
2500 case VhdlDocGen::ALIAS:
2501 if (sing) return "Alias";
2503 case VhdlDocGen::CONFIG:
2504 if (sing) return "Configuration";
2505 return "Configurations";
2506 case VhdlDocGen::MISCELLANEOUS:
2507 return "Miscellaneous";
2508 case VhdlDocGen::UCF_CONST:
2509 return "Constraints";
2515 QCString VhdlDocGen::trDesignUnitHierarchy()
2517 return "Design Unit Hierarchy";
2520 QCString VhdlDocGen::trDesignUnitList()
2522 return "Design Unit List";
2525 QCString VhdlDocGen::trDesignUnitMembers()
2527 return "Design Unit Members";
2530 QCString VhdlDocGen::trDesignUnitListDescription()
2532 return "Here is a list of all design unit members with links to "
2533 "the Entities they belong to:";
2536 QCString VhdlDocGen::trDesignUnitIndex()
2538 return "Design Unit Index";
2541 QCString VhdlDocGen::trDesignUnits()
2543 return "Design Units";
2546 QCString VhdlDocGen::trFunctionAndProc()
2548 return "Functions/Procedures/Processes";
2552 /*! writes a link if the string is linkable else a formatted string */
2554 void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
2558 ClassDef *cd=mdef->getClassDef();
2561 QCString n=cd->name();
2562 MemberDef* memdef=VhdlDocGen::findMember(n,mem);
2563 if (memdef && memdef->isLinkable())
2566 writeLink(memdef,ol);
2573 startFonts(mem,"vhdlchar",ol);
2578 void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
2580 ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd");
2581 // pIntf->resetCodeParserState();
2583 QCString codeFragment=mdef->documentation();
2585 if (cname.isEmpty())
2592 fi=codeFragment.find("\n",++fi);
2593 } while(fi>=0 && j++ <3);
2595 // show only the first four lines
2598 codeFragment=codeFragment.left(fi);
2599 codeFragment.append("\n .... ");
2603 codeFragment.prepend("\n");
2604 ol.pushGeneratorState();
2605 ol.startCodeFragment();
2606 pIntf->parseCode(ol, // codeOutIntf
2608 codeFragment, // input
2609 SrcLangExt_VHDL, // lang
2612 mdef->getFileDef(), // fileDef
2613 mdef->getStartBodyLine(), // startLine
2614 mdef->getEndBodyLine(), // endLine
2615 TRUE, // inlineFragment
2617 TRUE // show line numbers
2620 ol.endCodeFragment();
2621 ol.popGeneratorState();
2623 if (cname.isEmpty()) return;
2625 mdef->writeSourceDef(ol,cname);
2626 mdef->writeSourceRefs(ol,cname);
2627 mdef->writeSourceReffedBy(ol,cname);
2632 QCString VhdlDocGen::convertFileNameToClassName(QCString name)
2640 while((i=n.find("__"))>0)
2645 while((i=n.find("_1"))>0)
2647 n=n.replace(i,2,":");
2653 void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,bool altera)
2655 QCString ucFile(input);
2657 QCString comment("#!");
2660 while (!ucFile.isEmpty())
2662 int i=ucFile.find("\n");
2665 QCString temp=ucFile.left(i);
2666 temp=temp.stripWhiteSpace();
2667 bool bb=temp.stripPrefix("//");
2669 if (!temp.isEmpty())
2671 if (temp.stripPrefix(comment) )
2674 brief.append("\\n");
2676 else if (!temp.stripPrefix("#") && !bb)
2680 int i=temp.find("-name");
2683 temp=temp.remove(0,i+5);
2686 temp.stripPrefix("set_location_assignment");
2688 initUCF(entity,0,temp,lineNo,fileName,brief);
2692 QRegExp ee("[\\s=]");
2693 int i=temp.find(ee);
2694 QCString ff=temp.left(i);
2695 temp.stripPrefix(ff.data());
2697 if (!temp.isEmpty())
2699 initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
2705 ucFile=ucFile.remove(0,i+1);
2709 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief)
2711 if (qcs.isEmpty())return;
2712 QRegExp reg("[\\s=]");
2714 // bool bo=(qstricmp(type,qcs.data())==0);
2716 VhdlDocGen::deleteAllChars(qcs,';');
2717 qcs=qcs.stripWhiteSpace();
2719 int i= qcs.find(reg);
2724 VhdlDocGen::deleteAllChars(n,'#');
2731 qcs=qcs.remove(0,i+1);
2732 // qcs.prepend("|");
2734 qcs.stripPrefix("=");
2736 Entry* current=new Entry;
2737 current->spec=VhdlDocGen::UCF_CONST;
2738 current->section=Entry::VARIABLE_SEC;
2739 current->bodyLine=line;
2740 current->fileName=fileName;
2741 current->type="ucf_const";
2743 current->lang= SrcLangExt_VHDL ;
2745 // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2749 n+=VhdlDocGen::getRecordNumber();
2752 current->name= n+"_";
2753 current->name.append(VhdlDocGen::getRecordNumber().data());
2755 if (!brief.isEmpty())
2757 current->brief=brief;
2758 current->briefLine=line;
2759 current->briefFile=fileName;
2763 root->addSubEntry(current);
2767 static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2770 QCString largs(mdef->argsString());
2771 QCString n= splitString(largs, '#');
2772 // VhdlDocGen::adjustRecordMember(mdef);
2773 bool equ=(n.length()==largs.length());
2777 ol.writeString(n.data());
2779 ol.insertMemberAlign();
2782 if (mdef->name().contains("dummy")==0)
2788 ol.insertMemberAlign();
2791 VhdlDocGen::formatString(largs,ol,mdef);
2794 bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne)
2796 FileName *fn=Doxygen::inputNameList->getFirst();
2797 //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
2798 uint count=Doxygen::inputNameList->count();
2799 LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files);
2800 // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files);
2802 QCString co("Constraints");
2804 QCString imgExt = getDotImageExtension();
2805 if (Config_getBool(HAVE_DOT) && imgExt=="svg")
2807 QCString ov = theTranslator->trDesignOverview();
2808 QCString ofile("vhdl_design_overview");
2809 LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,"");
2816 FileDef *fd=fn->at(i);
2817 if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
2819 file = convertNameToFile(fd->name().data(),FALSE,FALSE);
2820 LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
2830 // for cell_inst : [entity] work.proto [ (label|expr) ]
2831 QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
2835 if (!entity.contains(":")) return "";
2837 QRegExp exp("[:()\\s]");
2838 QStringList ql=QStringList::split(exp,entity,FALSE);
2839 //int ii=ql.findIndex(ent);
2840 assert(ql.count()>=2);
2841 label = ql[0].utf8();
2842 entity = ql[1].utf8();
2843 if ((index=entity.findRev("."))>=0)
2845 entity.remove(0,index+1);
2851 ql=QStringList::split(exp,arch,FALSE);
2852 if (ql.count()>1) // expression
2857 return label; // label
2860 // use (configuration|entity|open) work.test [(cellfor)];
2862 QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
2865 QRegExp exp("[()\\s]");
2868 QStringList ql=QStringList::split(exp,entity,FALSE);
2870 if (ql.contains("open"))
2877 entity = ql[1].utf8();
2878 if ((index=entity.findRev("."))>=0)
2880 entity.remove(0,index+1);
2892 // find class with upper/lower letters
2893 ClassDef* VhdlDocGen::findVhdlClass(const char *className )
2896 ClassSDict::Iterator cli(*Doxygen::classSDict);
2898 for (;(cd=cli.current());++cli)
2900 if (qstricmp(className,cd->name().data())==0)
2909 //@param arch bit0:flipflop
2910 //@param binding e.g entity work.foo(bar)
2911 //@param label |label0|label1
2912 // label0:architecture name
2913 //@param confVhdl of configuration file (identifier::entity_name) or
2914 // the architecture if isInlineConf TRUE
2915 //@param isInlineConf
2916 //@param confN List of configurations
2918 void assignBinding(VhdlConfNode * conf)
2920 QList<Entry> instList=getVhdlInstList();
2921 QListIterator<Entry> eli(instList);
2923 ClassDef *archClass=0,*entClass=0;
2925 QCString arcBind,entBind;
2928 entBind=conf->binding;
2929 QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind);
2931 if (qstricmp(conf2,"configuration")==0)
2933 QList<VhdlConfNode> confList = getVhdlConfiguration();
2934 VhdlConfNode* vconf;
2935 // bool found=false;
2936 for (uint iter=0;iter<confList.count(); iter++)
2938 vconf= (VhdlConfNode *)confList.at(iter);
2939 QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0);
2943 entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1);
2944 QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2945 QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2947 archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data());
2948 entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data());
2953 else // conf2!=configuration
2956 if (conf->isInlineConf)
2959 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0);
2963 a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2964 e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2967 archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data());
2968 entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data());
2971 QCString label=conf->compSpec.lower();
2972 //label.prepend("|");
2976 // err("architecture %s not found ! ",conf->confVhdl.data());
2980 archName=archClass->name();
2981 QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
2982 all=allOt.lower()=="all" ;
2983 others= allOt.lower()=="others";
2985 for (;(cur=eli.current());++eli)
2987 if (cur->exception.lower()==label || conf->isInlineConf)
2993 archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
3000 QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower();
3001 QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower();
3003 QStringList ql=QStringList::split(",",inst1);
3005 for (uint j=0;j<ql.count();j++)
3007 QCString archy1,sign1;
3010 archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1);
3015 archy1=comp+":"+ql[j].utf8();
3016 sign1=cur->type+":"+cur->name;
3019 if (archy1==sign1.lower() && !cur->stat)
3021 // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
3022 ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data());
3024 if (entClass==0 || ent==0)
3029 addInstance(ent,archClass,entClass,cur);
3035 }//for each element in instList
3046 // file foo_arch.vhd
3047 // architecture xxx of foo is
3052 void VhdlDocGen::computeVhdlComponentRelations()
3055 QCString entity,arch,inst;
3056 QList<VhdlConfNode> confList = getVhdlConfiguration();
3058 for (uint iter=0;iter<confList.count(); iter++)
3060 VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
3061 if (!(conf->isInlineConf || conf->isLeaf))
3065 assignBinding(conf);
3068 QList<Entry> qsl= getVhdlInstList();
3069 QListIterator<Entry> eli(qsl);
3072 for (eli.toFirst();(cur=eli.current());++eli)
3074 if (cur->stat ) // was bind
3079 if (cur->includeName=="entity" || cur->includeName=="component" )
3081 entity=cur->includeName+" "+cur->type;
3082 QCString rr=VhdlDocGen::parseForBinding(entity,arch);
3084 else if (cur->includeName.isEmpty())
3089 ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity);
3090 inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
3091 ClassDef *cd=Doxygen::classSDict->find(inst);
3092 ClassDef *ar=Doxygen::classSDict->find(cur->args);
3099 // if (classEntity==0)
3100 // err("%s:%d:Entity:%s%s",cur->fileName.data(),cur->startLine,entity.data()," could not be found");
3102 addInstance(classEntity,ar,cd,cur);
3107 static void addInstance(ClassDef* classEntity, ClassDef* ar,
3108 ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
3116 //add component inst
3121 if (classEntity==cd) return;
3123 bName=classEntity->name();
3124 // fprintf(stderr,"\naddInstance %s to %s %s %s\n", classEntity->name().data(),cd->name().data(),ar->name().data(),cur->name);
3125 n1=classEntity->name().data();
3127 if (!cd->isBaseClass(classEntity, true, 0))
3129 cd->insertBaseClass(classEntity,n1,Public,Normal,0);
3133 VhdlDocGen::addBaseClass(cd,classEntity);
3136 if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
3138 classEntity->insertSubClass(cd,Public,Normal,0);
3139 classEntity->setLanguage(SrcLangExt_VHDL);
3143 QCString uu=cur->name;
3144 MemberDef *md=new MemberDef(
3145 ar->getDefFileName(), cur->startLine,cur->startColumn,
3147 Public, Normal, cur->stat,Member,
3148 MemberType_Variable,
3152 if (ar->getOutputFileBase())
3156 tg.fileName = ar->getOutputFileBase();
3158 md->setTagInfo(&tg);
3161 //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
3163 md->setLanguage(SrcLangExt_VHDL);
3164 md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
3165 md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
3166 md->setBodySegment(cur->startLine,-1) ;
3167 md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine);
3168 FileDef *fd=ar->getFileDef();
3172 QCString info="Info: Elaborating entity "+n1;
3173 fd=ar->getFileDef();
3174 info+=" for hierarchy ";
3176 QCString label=cur->type+":"+cur->write+":"+cur->name;
3177 label.replace(epr,":");
3179 fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data());
3182 ar->insertMember(md);
3187 void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
3189 QStringList ql=QStringList::split("#",largs,FALSE);
3190 uint len=ql.count();
3191 for(uint i=0;i<len;i++)
3193 QCString n=ql[i].utf8();
3194 VhdlDocGen::formatString(n,ol,mdef);
3195 if ((len-i)>1) ol.lineBreak();
3200 void VhdlDocGen::writeRecUnitDocu(
3201 const MemberDef *md,
3206 QStringList ql=QStringList::split("#",largs,FALSE);
3207 uint len=ql.count();
3208 ol.startParameterList(TRUE);
3211 for(uint i=0;i<len;i++)
3213 QCString n=ql[i].utf8();
3214 ol.startParameterType(first,"");
3215 ol.endParameterType();
3216 ol.startParameterName(TRUE);
3217 VhdlDocGen::formatString(n,ol,md);
3220 ol.endParameterName(FALSE,FALSE,FALSE);
3224 ol.endParameterName(TRUE,FALSE,TRUE);
3234 bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
3237 //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3240 err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
3245 if (cd->subClasses())
3247 BaseClassListIterator bcli(*cd->subClasses());
3248 for ( ; bcli.current() && !found ; ++bcli)
3250 ClassDef *ccd=bcli.current()->classDef;
3251 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3252 //printf("isSubClass() subclass %s\n",ccd->name().data());
3261 found=ccd->isBaseClass(scd,followInstances,level+1);
3269 void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
3271 if (cd->baseClasses())
3273 BaseClassListIterator bcli(*cd->baseClasses());
3274 for ( ; bcli.current() ; ++bcli)
3276 ClassDef *ccd=bcli.current()->classDef;
3279 QCString n = bcli.current()->usedName;
3280 int i = n.find('(');
3283 bcli.current()->usedName.append("(2)");
3286 static QRegExp reg("[0-9]+");
3287 QCString s=n.left(i);
3288 QCString r=n.right(n.length()-i);
3290 VhdlDocGen::deleteAllChars(r,')');
3291 VhdlDocGen::deleteAllChars(r,'(');
3292 r.setNum(r.toInt()+1);
3293 t.replace(reg,r.data());
3295 bcli.current()->usedName=s;
3296 bcli.current()->templSpecifiers=t;
3303 static QList<MemberDef> mdList;
3305 static MemberDef* findMemFlow(const MemberDef* mdef)
3307 for(uint j=0;j<mdList.count();j++)
3309 MemberDef* md=(MemberDef*)mdList.at(j);
3310 if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
3316 void VhdlDocGen::createFlowChart(const MemberDef *mdef)
3318 if (mdef==0) return;
3320 QCString codeFragment;
3322 if((mm=findMemFlow(mdef))!=0)
3324 // don't create the same flowchart twice
3325 VhdlDocGen::setFlowMember(mm);
3330 mdList.append(mdef);
3333 //fprintf(stderr,"\n create flow mem %s %p\n",mdef->name().data(),mdef);
3335 int actualStart= mdef->getStartBodyLine();
3336 int actualEnd=mdef->getEndBodyLine();
3337 FileDef* fd=mdef->getFileDef();
3338 bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment);
3341 VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd");
3342 VhdlDocGen::setFlowMember(mdef);
3344 QStrList filesInSameTu;
3345 pIntf->startTranslationUnit("");
3346 pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu);
3347 pIntf->finishTranslationUnit();
3350 void VhdlDocGen::resetCodeVhdlParserState()
3357 bool VhdlDocGen::isConstraint(const MemberDef *mdef)
3358 { return mdef->getMemberSpecifiers()==VhdlDocGen::UCF_CONST; }
3359 bool VhdlDocGen::isConfig(const MemberDef *mdef)
3360 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; }
3361 bool VhdlDocGen::isAlias(const MemberDef *mdef)
3362 { return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; }
3363 bool VhdlDocGen::isLibrary(const MemberDef *mdef)
3364 { return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; }
3365 bool VhdlDocGen::isGeneric(const MemberDef *mdef)
3366 { return mdef->getMemberSpecifiers()==VhdlDocGen::GENERIC; }
3367 bool VhdlDocGen::isPort(const MemberDef *mdef)
3368 { return mdef->getMemberSpecifiers()==VhdlDocGen::PORT; }
3369 bool VhdlDocGen::isComponent(const MemberDef *mdef)
3370 { return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT; }
3371 bool VhdlDocGen::isPackage(const MemberDef *mdef)
3372 { return mdef->getMemberSpecifiers()==VhdlDocGen::USE; }
3373 bool VhdlDocGen::isEntity(const MemberDef *mdef)
3374 { return mdef->getMemberSpecifiers()==VhdlDocGen::ENTITY; }
3375 bool VhdlDocGen::isConstant(const MemberDef *mdef)
3376 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONSTANT; }
3377 bool VhdlDocGen::isVType(const MemberDef *mdef)
3378 { return mdef->getMemberSpecifiers()==VhdlDocGen::TYPE; }
3379 bool VhdlDocGen::isSubType(const MemberDef *mdef)
3380 { return mdef->getMemberSpecifiers()==VhdlDocGen::SUBTYPE; }
3381 bool VhdlDocGen::isVhdlFunction(const MemberDef *mdef)
3382 { return mdef->getMemberSpecifiers()==VhdlDocGen::FUNCTION; }
3383 bool VhdlDocGen::isProcess(const MemberDef *mdef)
3384 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCESS; }
3385 bool VhdlDocGen::isSignal(const MemberDef *mdef)
3386 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3387 bool VhdlDocGen::isAttribute(const MemberDef *mdef)
3388 { return mdef->getMemberSpecifiers()==VhdlDocGen::ATTRIBUTE; }
3389 bool VhdlDocGen::isSignals(const MemberDef *mdef)
3390 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3391 bool VhdlDocGen::isProcedure(const MemberDef *mdef)
3392 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCEDURE; }
3393 bool VhdlDocGen::isRecord(const MemberDef *mdef)
3394 { return mdef->getMemberSpecifiers()==VhdlDocGen::RECORD; }
3395 bool VhdlDocGen::isArchitecture(const MemberDef *mdef)
3396 { return mdef->getMemberSpecifiers()==VhdlDocGen::ARCHITECTURE; }
3397 bool VhdlDocGen::isUnit(const MemberDef *mdef)
3398 { return mdef->getMemberSpecifiers()==VhdlDocGen::UNITS; }
3399 bool VhdlDocGen::isPackageBody(const MemberDef *mdef)
3400 { return mdef->getMemberSpecifiers()==VhdlDocGen::PACKAGE_BODY; }
3401 bool VhdlDocGen::isVariable(const MemberDef *mdef)
3402 { return mdef->getMemberSpecifiers()==VhdlDocGen::SHAREDVARIABLE; }
3403 bool VhdlDocGen::isFile(const MemberDef *mdef)
3404 { return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; }
3405 bool VhdlDocGen::isGroup(const MemberDef *mdef)
3406 { return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; }
3407 bool VhdlDocGen::isCompInst(const MemberDef *mdef)
3408 { return mdef->getMemberSpecifiers()==VhdlDocGen::INSTANTIATION; }
3409 bool VhdlDocGen::isMisc(const MemberDef *mdef)
3410 { return mdef->getMemberSpecifiers()==VhdlDocGen::MISCELLANEOUS; }
3414 //############################## Flowcharts #################################################
3416 #define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
3417 FlowChart::FOR_NO | FlowChart::CASE_NO | \
3418 FlowChart::LOOP_NO | WHEN_NO)
3419 #define DECLN (FlowChart::WHEN_NO | \
3420 FlowChart::ELSIF_NO | FlowChart::IF_NO | \
3421 FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3422 FlowChart::CASE_NO | FlowChart::LOOP_NO )
3423 #define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
3424 #define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3425 FlowChart::LOOP_NO )
3426 #define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
3427 #define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
3428 #define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
3429 #define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
3430 #define EMPTY (EEND | FlowChart::ELSIF_NO)
3431 #define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
3432 #define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
3433 #define FLOWLEN (flowList.count()-1)
3435 static int ifcounter=0;
3436 static int nodeCounter=0;
3441 const char *textNodeLink;
3442 const char *yesNodeLink;
3443 const char *noNodeLink;
3446 const char* comment;
3447 const char* decisionNode;
3448 const char* varNode;
3449 const char *startEndNode;
3450 const char* textNode;
3452 { "green", // textNodeLink
3453 "red", // yesNodeLink
3454 "black", // noNodeLink
3456 "0.7 0.3 1.0", // decisionNode
3457 "lightyellow", // varNode
3458 "white", // startEndNode
3459 "lightcyan" // textNode
3462 QList<FlowChart> FlowChart::flowList;
3465 static QMap<QCString,int> keyMap;
3468 void alignText(QCString & q)
3470 if (q.length()<=80) return;
3479 QRegExp reg("[\\s|]");
3480 QCString str(q.data());
3483 while (str.length()>80)
3485 int j=str.findRev(reg,80);
3494 QCString qcs=str.left(j);
3505 void FlowChart::printNode(const FlowChart* flo)
3510 QRegExp ep("[\t\n\r]");
3514 if (flo->type & STARTL)
3518 q=ui.left(2*flo->stamp);
3524 QCString nn=flo->exp.stripWhiteSpace();
3525 printf("\nYES: %s%s[%d,%d]",q.data(),nn.data(),flo->stamp,flo->id);
3529 if (flo->type & COMMENT_NO)
3544 q=ui.left(2*flo->stamp);
3550 if (flo->type & EMPTNODE)
3552 printf("\n NO: %s%s[%d,%d]",q.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3554 else if (flo->type & COMMENT_NO)
3556 printf("\n NO: %s%s[%d,%d]",t.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3560 printf("\n NO: %s[%d,%d]",t.data(),flo->stamp,flo->id);
3565 void FlowChart::printFlowTree()
3567 uint size=flowList.count();
3568 for (uint j=0;j<size;j++)
3570 printNode(flowList.at(j));
3574 void FlowChart::colTextNodes()
3579 for (uint j=0;j<flowList.count();j++)
3581 FlowChart *flo=flowList.at(j);
3582 if (flo->type&TEXT_NO)
3584 text+=flo->text+'\n';
3591 flno->text+=flo->text;
3592 flowList.remove(flo);
3601 // find if..endif without text
3602 // if..elseif without text
3603 for (uint j=0;j<flowList.count()-1;j++)
3605 FlowChart *flo=flowList.at(j);
3607 if ( (kind & IFF) || (flo->type & ELSE_NO))
3609 FlowChart *ftemp=flowList.at(j+1);
3610 if (ftemp->type & EMPTY)
3612 FlowChart *fNew = new FlowChart(TEXT_NO,"empty ",0);
3613 fNew->stamp=flo->stamp;
3614 flowList.insert(j+1,fNew);
3621 QCString FlowChart::getNodeName(int n)
3625 return node.prepend("node");
3628 void FlowChart::delFlowList()
3632 uint size=flowList.count();
3634 for (uint j=0;j <size ;j++)
3636 FlowChart *fll=flowList.at(j);
3642 void FlowChart::alignCommentNode(FTextStream &t,QCString com)
3646 QStringList ql=QStringList::split("\n",com);
3647 for (uint j=0;j<ql.count();j++)
3649 s=(QCString)ql[j].utf8();
3650 if (max<s.length()) max=s.length();
3654 int diff=max-s.length();
3662 ql.remove(ql.last());
3666 for (uint j=0;j<ql.count();j++)
3668 s=(QCString)ql[j].utf8();
3673 FlowChart::codify(t,s.data());
3678 void FlowChart::buildCommentNodes(FTextStream & t)
3680 uint size=flowList.count();
3683 for (uint j=0;j < size-1 ;j++)
3685 FlowChart *fll=flowList.at(j);
3686 if (fll->type & COMMENT_NO)
3688 FlowChart* to=flowList.at(j+1);
3689 if (to->type & COMMENT_NO)
3692 QCString temp=fll->label+to->label;
3701 for (uint j=0;j <flowList.count() ;j++)
3703 FlowChart *fll=flowList.at(j);
3705 if (fll->type & BEGIN_NO)
3711 if (fll->type & COMMENT_NO)
3716 // comment between function/process .. begin is linked to start node
3721 if (j>0 && flowList.at(j-1)->line==fll->line)
3722 to=flowList.at(j-1);
3724 to=flowList.at(j+1);
3726 t << getNodeName(fll->id);
3727 t << "[shape=none, label=<\n";
3728 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
3729 t << "<TR><TD BGCOLOR=\"";
3730 t << flowCol.comment;
3733 FlowChart::alignCommentNode(t,fll->label);
3734 t << " </TD></TR></TABLE>>];";
3735 writeEdge(t,fll->id,to->id,2);
3739 // delete comment nodes;
3740 size=flowList.count();
3741 for (uint j=0;j < size;j++)
3743 FlowChart *fll=flowList.at(j);
3744 if (fll->type & (COMMENT_NO | BEGIN_NO))
3746 int diff=FLOWLEN-(j+1);
3749 if ((fll->type & COMMENT_NO) && diff > 1)
3750 flowList.at(j+1)->label=fll->label;
3760 void FlowChart::codify(FTextStream &t,const char *str)
3771 case '<': t << "<"; break;
3772 case '>': t << ">"; break;
3773 case '&': t << "&"; break;
3774 case '\'': t << "'"; break;
3775 case '"': t << """; break;
3776 case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
3777 default: t << c; break;
3783 FlowChart::~FlowChart()
3787 FlowChart::FlowChart(int typ,const char * t,const char* ex,const char* lab)
3801 if (typ & (ELSE_NO | ELSIF_NO))
3806 if (typ & (START_NO | END_NO | VARIABLE_NO))
3814 void FlowChart::addFlowChart(int type,const char* text,const char* exp, const char *label)
3816 static QRegExp reg("[;]");
3817 static QRegExp reg1("[\"]");
3819 if (!VhdlDocGen::getFlowMember()) return;
3821 QCString typeString(text);
3822 QCString expression(exp);
3827 typeString=typeString.replace(reg,"\n");
3832 expression=expression.replace(reg1,"\\\"");
3835 FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label);
3837 fl->line=vhdl::parser::VhdlParser::getLine();
3839 if (type & (START_NO | VARIABLE_NO))
3841 flowList.prepend(fl);
3845 flowList.append(fl);
3849 void FlowChart::moveToPrevLevel()
3851 if (!VhdlDocGen::getFlowMember()) return;
3855 QCString FlowChart::printPlantUmlNode(const FlowChart *flo,bool ca,bool endL)
3858 QCString exp=flo->exp.stripWhiteSpace();
3859 QCString text=flo->text.stripWhiteSpace();
3862 case START_NO: t=":"+text+"|"; break;
3863 case IF_NO : t="\nif ("+exp+") then (yes)"; break;
3864 case ELSIF_NO: t="\nelseif ("+exp+") then (yes)"; break;
3865 case ELSE_NO: t="\nelse"; break;
3866 case CASE_NO: t="\n:"+exp+";"; break;
3867 case WHEN_NO: t="\n";
3869 t+="if ("+exp+") then (yes)";
3871 case EXIT_NO: break;
3872 case END_NO: if (text.contains(" function")==0) t="\n:"+text+";";
3874 case TEXT_NO: t="\n:"+text+"]"; break;
3875 case ENDIF_NO: t="\nendif"; break;
3876 case FOR_NO: t="\nwhile ("+exp+") is (yes)"; break;
3877 case WHILE_NO: t="\nwhile ("+exp+") is (yes)"; break;
3878 case END_LOOP: t="\nendwhile"; break;
3879 case END_CASE: t="\nendif\n:end case;"; break;
3880 case VARIABLE_NO:t="\n:"+text+";"; break;
3881 case RETURN_NO: t="\n:"+text+";";
3882 if (!endL) t+="\nstop";
3884 case LOOP_NO: t="\nwhile (infinite loop)"; break;
3885 case NEXT_NO: break;
3886 case EMPTY_NO: break;
3887 case COMMENT_NO: t="\n note left \n "+flo->label+"\nend note \n"; break;
3888 case BEGIN_NO: t="\n:begin;"; break;
3889 default: assert(false); break;
3894 void FlowChart::printUmlTree()
3896 int caseCounter = 0;
3897 int whenCounter = 0;
3900 uint size=flowList.count();
3902 for (uint j=0;j<size;j++)
3905 FlowChart *flo=flowList.at(j);
3906 if (flo->type==CASE_NO)
3912 if (flo->type==END_CASE)
3917 bool ca = (caseCounter>0 && whenCounter==0);
3919 qcs+=printPlantUmlNode(flo,ca,endList);
3921 if (flo->type==WHEN_NO)
3929 QCString & htmlOutDir = Config_getString(HTML_OUTPUT);
3931 QCString n=convertNameToFileName();
3932 QCString tmp=htmlOutDir;
3933 n=writePlantUMLSource(tmp,n,qcs);
3934 generatePlantUMLOutput(n.data(),tmp.data(),PUML_SVG);
3937 QCString FlowChart::convertNameToFileName()
3939 static QRegExp exp ("[^][a-z_A-Z0-9]");
3941 const MemberDef* md=VhdlDocGen::getFlowMember();
3943 // temp.sprintf("%p",md);
3947 if (qcs.find(exp,0)>=0)
3950 qcs=qcs.replace(exp,"_");
3954 //QCString tt= qcs;VhdlDocGen::getRecordNumber();
3958 const char* FlowChart::getNodeType(int c)
3962 case IF_NO: return "if ";
3963 case ELSIF_NO: return "elsif ";
3964 case ELSE_NO: return "else ";
3965 case CASE_NO: return "case ";
3966 case WHEN_NO: return "when ";
3967 case EXIT_NO: return "exit ";
3968 case END_NO: return "end ";
3969 case TEXT_NO: return "text ";
3970 case START_NO: return "start ";
3971 case ENDIF_NO: return "endif ";
3972 case FOR_NO: return "for ";
3973 case WHILE_NO: return "while ";
3974 case END_LOOP: return "end_loop ";
3975 case END_CASE: return "end_case ";
3976 case VARIABLE_NO: return "variable_decl ";
3977 case RETURN_NO: return "return ";
3978 case LOOP_NO: return "infinite loop ";
3979 case NEXT_NO: return "next ";
3980 case COMMENT_NO: return "comment ";
3981 case EMPTY_NO: return "empty ";
3982 case BEGIN_NO: return "<begin> ";
3983 default: return "--failure--";
3987 void FlowChart::createSVG()
3990 QCString ov = Config_getString(HTML_OUTPUT);
3992 qcs+=FlowChart::convertNameToFileName()+".svg";
3994 //const MemberDef *m=VhdlDocGen::getFlowMember();
3996 // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data());
3998 QCString dir=" -o \""+ov+qcs+"\"";
3999 ov+="/flow_design.dot";
4001 QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
4003 if (portable_system("dot",vlargs)!=0)
4005 err("could not create dot file");
4009 void FlowChart::startDot(FTextStream &t)
4011 t << " digraph G { \n";
4012 t << "rankdir=TB \n";
4013 t << "concentrate=true\n";
4014 t << "stylesheet=\"doxygen.css\"\n";
4017 void FlowChart::endDot(FTextStream &t)
4022 void FlowChart::writeFlowChart()
4024 // assert(VhdlDocGen::flowMember);
4026 QCString ov = Config_getString(HTML_OUTPUT);
4027 QCString fileName = ov+"/flow_design.dot";
4031 if (!f.open(IO_WriteOnly))
4033 err("Cannot open file %s for writing\n",fileName.data());
4038 // buildCommentNodes(t);
4043 const MemberDef *p=VhdlDocGen::getFlowMember();
4054 buildCommentNodes(t);
4055 uint size=flowList.count();
4057 for (uint j=0;j <size ;j++)
4059 FlowChart *fll=flowList.at(j);
4064 FlowChart::endDot(t);
4067 FlowChart::createSVG();
4070 void FlowChart::writeShape(FTextStream &t,const FlowChart* fl)
4072 if (fl->type & EEND) return;
4074 if (fl->type & LOOP)
4078 else if (fl->type & IFF)
4087 t<<getNodeName(fl->id).data();
4090 QCString qq(getNodeName(fl->id).data());
4091 keyMap.insert(qq,fl->id);
4094 bool dec=(fl->type & DECLN);
4095 bool exit=(fl->type & EXITNEXT);
4096 if (exit && !fl->exp.isEmpty())
4102 QCString exp=fl->exp;
4105 t << " [shape=diamond,style=filled,color=\"";
4106 t << flowCol.decisionNode;
4107 t << "\",label=\" ";
4109 if (exit) kl=fl->text+" ";
4113 kl+=fl->label+":"+exp+var;
4120 FlowChart::alignCommentNode(t,kl);
4123 else if (fl->type & ENDCL)
4125 QCString val=fl->text;
4126 t << " [shape=ellipse ,label=\""+val+"\"]\n";
4128 else if (fl->type & STARTFIN)
4130 QCString val=fl->text;
4131 t << "[shape=box , style=rounded label=<\n";
4132 t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
4133 t << "<TR><TD BGCOLOR=\"";
4134 t<< flowCol.startEndNode;
4136 FlowChart::alignCommentNode(t,val);
4137 t << " </TD></TR></TABLE>>];";
4141 if (fl->text.isEmpty()) return;
4142 bool var=(fl->type & FlowChart::VARIABLE_NO);
4143 QCString q=fl->text;
4150 int z=q.findRev("\n");
4152 if (z==(int)q.length()-1)
4156 t << "[shape=none margin=0.1, label=<\n";
4157 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
4160 t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
4164 t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
4166 FlowChart::alignCommentNode(t,q);
4167 t << " </TD></TR></TABLE>>];";
4172 void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i)
4174 bool b=fl_from->type & STARTL;
4175 bool c=fl_to->type & STARTL;
4178 QCString s1(getNodeName(fl_from->id).data());
4179 QCString s2(getNodeName(fl_to->id).data());
4180 QMap<QCString, int>::Iterator it = keyMap.find(s1);
4181 QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
4182 // checks if the link is connected to a valid node
4187 writeEdge(t,fl_from->id,fl_to->id,i,b,c);
4190 void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
4196 col=flowCol.yesNodeLink;
4201 col=flowCol.noNodeLink;
4206 col=flowCol.textNodeLink;
4210 t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
4211 t << getNodeName(fl_from).data();
4212 if (bFrom) t << ":s";
4214 t << getNodeName(fl_to).data();
4219 void FlowChart::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc)
4223 ArgumentListIterator ali(*al);
4224 int index=ali.count();
4225 if (index==0) return;
4227 int len=q.length()+VhdlDocGen::getFlowMember()->name().length();
4229 prev.fill(' ',len+1);
4233 for (;(arg=ali.current());++ali)
4235 QCString attl=arg->defval+" ";
4236 attl+=arg->name+" ";
4240 attl+=arg->attrib+" ";
4247 if (--index) attl+=",\n"; else attl+="\n";
4249 attl.prepend(prev.data());
4256 int FlowChart::findNextLoop(int index,int stamp)
4258 for (uint j=index+1;j<flowList.count();j++)
4260 FlowChart *flo=flowList.at(j);
4261 if (flo->stamp==stamp)
4265 if (flo->type&END_LOOP)
4270 return flowList.count()-1;
4273 int FlowChart::findPrevLoop(int index,int stamp,bool endif)
4275 for (uint j=index;j>0;j--)
4277 FlowChart *flo=flowList.at(j);
4278 if (flo->type & LOOP)
4280 if (flo->stamp==stamp && endif)
4286 if (flo->stamp<stamp)
4293 return flowList.count()-1;
4296 int FlowChart::findLabel(int index,QCString &label)
4298 for (uint j=index;j>0;j--)
4300 FlowChart *flo=flowList.at(j);
4301 if ((flo->type & LOOP) && !flo->label.isEmpty() && qstricmp(flo->label,label)==0)
4306 err("could not find label: ",label.data());
4310 int FlowChart::findNode(int index,int stamp,int type)
4312 for (uint j=index+1;j<flowList.count();j++)
4314 FlowChart *flo=flowList.at(j);
4315 if (flo->type==type && flo->stamp==stamp)
4323 int FlowChart::getNextNode(int index,int stamp)
4325 for (uint j=index+1;j<flowList.count();j++)
4327 FlowChart *flo=flowList.at(j);
4334 if (kind & ENDIF_NO)
4336 if (s<stamp && stamp>0)
4342 if (kind & (ELSE_NO | ELSIF_NO))
4344 if (s<stamp && stamp>0)
4348 j=findNode(j,stamp,ENDIF_NO);
4353 if (s<stamp && stamp>0)
4357 return findNode(j,stamp-1,END_CASE);
4364 int FlowChart::getNextIfLink(const FlowChart* fl,uint index)
4366 int stamp=fl->stamp;
4367 uint start = index+1;
4368 int endifNode = findNode(start,stamp,ENDIF_NO);
4369 int elseifNode = findNode(start,stamp,ELSIF_NO);
4370 int elseNode = findNode(start,stamp,ELSE_NO);
4372 assert(endifNode>-1);
4374 if (elseifNode>0 && elseifNode<endifNode)
4379 if (elseNode>0 && elseNode<endifNode)
4384 stamp=flowList.at(endifNode)->stamp;
4385 return getNextNode(endifNode,stamp);
4388 void FlowChart::writeFlowLinks(FTextStream &t)
4390 uint size=flowList.count();
4394 writeEdge(t,flowList.at(0),flowList.at(1),2);
4396 for (uint j=0;j<size;j++)
4398 FlowChart *fll=flowList.at(j);
4400 int stamp=fll->stamp;
4408 writeEdge(t,fll,flowList.at(j+1),0);
4409 int z=getNextIfLink(fll,j);
4411 writeEdge(t,fll,flowList.at(z),1);
4413 else if (kind & LOOP_NO)
4415 writeEdge(t,fll,flowList.at(j+1),2);
4418 else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
4422 writeEdge(t,fll,flowList.at(j+1),2);
4427 writeEdge(t,fll,flowList.at(j+1),0);
4431 int z=findNode(j+1,fll->stamp,kind);
4432 z=getNextNode(z,flowList.at(z)->stamp);
4435 writeEdge(t,fll,flowList.at(z),1);
4438 else if (kind & (TEXT_NO | VARIABLE_NO))
4440 int z=getNextNode(j,stamp);
4441 writeEdge(t,fll,flowList.at(z),2);
4443 else if (kind & WHEN_NO)
4446 if (qstricmp(fll->text.simplifyWhiteSpace().data(),"others")==0)
4448 writeEdge(t,fll,flowList.at(j+1),2);
4453 writeEdge(t,fll,flowList.at(j+1),0);
4454 int u=findNode(j,stamp,WHEN_NO);
4455 int v=findNode(j,stamp-1,END_CASE);
4459 writeEdge(t,fll,flowList.at(u),1);
4463 writeEdge(t,fll,flowList.at(v),1);
4466 else if (kind & END_CASE)
4468 int z=FlowChart::getNextNode(j,fll->stamp);
4469 writeEdge(t,fll,flowList.at(z),2);
4471 else if (kind & END_LOOP)
4473 int z=findPrevLoop(j,fll->stamp,true);
4474 writeEdge(t,fll,flowList.at(z),2);
4476 else if (kind & RETURN_NO)
4478 writeEdge(t,fll,FlowChart::flowList.at(size-1),2);
4480 else if (kind & (EXIT_NO | NEXT_NO))
4483 bool b = kind==NEXT_NO;
4486 writeEdge(t,fll,flowList.at(j+1),1);
4488 if (!fll->label.isEmpty())
4490 z=findLabel(j,fll->label);
4493 writeEdge(t,fll,flowList.at(z),0);
4497 z=findNode(z,flowList.at(z)->stamp,END_LOOP);
4498 z=getNextNode(z,flowList.at(z)->stamp);
4499 writeEdge(t,fll,flowList.at(z),0);
4507 z=findPrevLoop(j,fll->stamp);
4508 writeEdge(t,fll,flowList.at(z),0);
4513 z =findNextLoop(j,fll->stamp-1);
4515 z=getNextNode(z,flowList.at(z)->stamp);
4517 writeEdge(t,fll,flowList.at(z),0);
4523 void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
4524 const char *scopeName,
4525 const QCString &input,
4527 bool isExampleBlock,
4528 const char *exampleName,
4532 bool inlineFragment,
4533 MemberDef *memberDef,
4534 bool showLineNumbers,
4535 Definition *searchCtx,
4540 parseVhdlCode(codeOutIntf,