Fix for UBSan build
[platform/upstream/doxygen.git] / src / vhdldocgen.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2012 by Dimitri van Heesch.
4  *
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.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 /******************************************************************************
16  * Parser for VHDL subset
17  * written by M. Kreis
18  * supports VHDL-87/93/2002
19  * does not support VHDL-AMS
20  ******************************************************************************/
21
22 // global includes
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <assert.h>
26 #include <string.h>
27 #include <qcstring.h>
28 #include <qfileinfo.h>
29 #include <qstringlist.h>
30 #include "memberdef.h"
31 /* --------------------------------------------------------------- */
32
33 // local includes
34 #include "vhdldocgen.h"
35 #include "message.h"
36 #include "config.h"
37 #include "doxygen.h"
38 #include "util.h"
39 #include "language.h"
40 #include "commentscan.h"
41 #include "index.h"
42 #include "definition.h"
43 #include "searchindex.h"
44 #include "outputlist.h"
45 #include "parserintf.h"
46 #include "vhdlscanner.h"
47 #include "layout.h"
48 #include "arguments.h"
49 #include "portable.h"
50
51 #define theTranslator_vhdlType VhdlDocGen::trVhdlType
52
53 static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
54 static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
55 static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
56
57 static QDict<QCString> g_xilinxUcfDict(17,FALSE);
58
59 static void initUCF(Entry* root,const char* type,QCString &  qcs,int line,QCString & fileName,QCString & brief);
60 static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
61 static void assignConfiguration(VhdlConfNode* ,QCString);
62 static void assignBinding(VhdlConfNode* conf,QCString label);
63 static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
64
65 //---------- create svg ------------------------------------------------------------- 
66 static void createSVG();
67 static void startDot(FTextStream &t);
68 static void startTable(FTextStream &t,const QCString &className);
69 static QList<MemberDef>* getPorts(ClassDef *cd);
70 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
71 static void endDot(FTextStream &t);
72 static void writeTable(QList<MemberDef>* port,FTextStream & t);
73 static void endTabel(FTextStream &t);
74 static void writeClassToDot(FTextStream &t,ClassDef* cd);
75 static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
76 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
77
78
79
80
81
82 //--------------------------------------------------------------------------------------------------
83 static void codify(FTextStream &t,const char *str)
84 {
85
86   if (str)
87   { 
88     const char *p=str;
89     char c;
90       while (*p)
91     {
92       c=*p++;
93       switch(c)
94       {
95         case '<':  t << "&lt;"; 
96                    break;
97         case '>':  t << "&gt;"; 
98                    break;
99         case '&':  t << "&amp;"; 
100                    break;
101         case '\'': t << "&#39;";
102                    break;
103         case '"':  t << "&quot;"; 
104                    break;
105         default:   t << c;                  
106                    break;
107       }
108     }
109   }
110 }
111
112 static void createSVG()
113 {
114     QCString ov =Config_getString("HTML_OUTPUT");
115     QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
116     ov+="/vhdl_design.dot";
117
118     QRegExp ep("[\\s]");
119     QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
120
121     if (portable_system("dot",vlargs)!=0)
122     {
123       err("could not create dot file");
124     }
125 }
126
127 // Creates a svg image. All in/out/inout  ports are shown with  brief description and direction.
128 // Brief descriptions for entities are shown too.
129 void VhdlDocGen::writeOverview()
130 {
131   ClassSDict::Iterator cli(*Doxygen::classSDict);
132   ClassDef *cd;
133   bool found=false;
134   for ( ; (cd=cli.current()) ; ++cli )
135   {
136     if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )
137     {
138       found=true;
139       break;
140     }
141   }
142
143   if (!found) return;
144
145   QCString ov =Config_getString("HTML_OUTPUT");
146   QCString fileName=ov+"/vhdl_design.dot";
147   QFile f(fileName);
148   QStringList qli;
149   FTextStream  t(&f);
150
151   if (!f.open(IO_WriteOnly))
152   {
153     fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
154     return;
155   }
156
157   startDot(t);
158
159   for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
160   {
161     if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS )
162     {
163       continue;
164     }
165
166     QList<MemberDef>* port= getPorts(cd);
167     if (port==0) 
168     {
169       continue;
170     }
171     if (port->count()==0)
172     {
173       delete port;
174       port=NULL;
175       continue;
176     }
177
178     startTable(t,cd->name());
179     writeClassToDot(t,cd);
180     writeTable(port,t);
181     endTabel(t);
182
183     writeVhdlPortToolTip(t,port,cd);
184     writeVhdlEntityToolTip(t,cd);
185     delete port;
186
187     BaseClassList *bl=cd->baseClasses();
188     if (bl)
189     {
190       BaseClassListIterator bcli(*bl);
191       BaseClassDef *bcd;
192       for ( ; (bcd=bcli.current()) ; ++bcli )
193       {
194         ClassDef *bClass=bcd->classDef; 
195         QCString dotn=cd->name()+":";
196         dotn+=cd->name();
197         QCString csc=bClass->name()+":";
198         csc+=bClass->name();
199         //  fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
200         writeVhdlDotLink(t,dotn,csc,0);
201       }
202     }// if bl
203   }// for
204
205   endDot(t);
206   //  writePortLinks(t);
207   f.close();
208   createSVG();
209 }
210
211 //------------------------------------------------------------------------------------------------------------------------------------------------------
212
213 static void startDot(FTextStream &t)
214 {
215   t << " digraph G { \n"; 
216   t << "rankdir=LR \n";
217   t << "concentrate=true\n";
218   t << "stylesheet=\"doxygen.css\"\n";
219 }
220
221 static void endDot(FTextStream &t)
222 {
223   t <<" } \n"; 
224 }
225
226 static void startTable(FTextStream &t,const QCString &className)
227 {
228   t << className <<" [ shape=none , fontname=\"arial\",  fontcolor=\"blue\" , \n"; 
229   t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
230 }
231
232 static void writeVhdlDotLink(FTextStream &t,
233     const QCString &a,const QCString &b,const QCString &style)
234 {
235   t << a << "->" << b;
236   if (!style.isEmpty())
237   {
238     t << "[style=" << style << "];\n";
239   }
240   t << "\n";
241 }
242
243
244 static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
245 {
246   QRegExp ep("[\n]");
247   QCString vForm;  
248   QCString repl("<BR ALIGN=\"LEFT\"/>");
249   QCString file=cd->getDefFileName();
250
251   int k=cd->briefLine();
252
253   QStringList qsl=QStringList::split(ep,brief);
254   for(uint j=0;j<qsl.count();j++)
255   {
256     QCString qcs=qsl[j].data();
257     vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
258     k++;
259     vForm+='\n';
260   }
261
262   vForm.replace(ep,repl.data());
263   return vForm;
264 }
265
266
267 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
268 {
269
270   uint len=port->count();
271   MemberDef *md;
272   return; //????
273
274   for (uint j=0;j<len;j++)
275   {
276     md=(MemberDef*)port->at(j);
277     QCString brief=md->briefDescriptionAsTooltip();
278     if (brief.isEmpty()) continue;
279
280     QCString node="node";
281     node+=VhdlDocGen::getRecordNumber();
282     t << node <<"[shape=box margin=0.1, label=<\n";
283     t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
284     t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
285     t<<brief;
286     t<<" </TD></TR></TABLE>>];";
287     QCString dotn=cd->name()+":";
288     dotn+=md->name();
289     //  writeVhdlDotLink(t,dotn,node,"dotted");
290   }
291 }
292
293
294 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd)
295 {
296
297   QCString brief=cd->briefDescription();
298
299   if (brief.isEmpty()) return;  
300
301   brief=formatBriefNote(brief,cd);
302
303   QCString node="node";
304   node+=VhdlDocGen::getRecordNumber();
305   t << node <<"[shape=none margin=0.1, label=<\n";
306   t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
307   t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
308   t << brief;
309   t << " </TD></TR></TABLE>>];";
310   QCString dotn=cd->name()+":";
311   dotn+=cd->name();
312   writeVhdlDotLink(t,dotn,node,"dotted");
313 }
314
315 static void writeColumn(FTextStream &t,MemberDef *md,bool start)
316 {
317   QCString toolTip;
318
319   static QRegExp reg("[%]");
320   bool bidir=(md!=0 &&( stricmp(md->typeString(),"inout")==0));
321
322   if (md)
323   {
324     toolTip=md->briefDescriptionAsTooltip();
325     if (!toolTip.isEmpty())
326     {
327       QCString largs = md->argsString();
328       if (!largs.isEmpty())
329         largs=largs.replace(reg," ");
330       toolTip+=" [";
331       toolTip+=largs;
332       toolTip+="]";      
333     }
334   }
335   if (start) 
336   {
337     t <<"<TR>\n";
338   }
339
340   t << "<TD ALIGN=\"LEFT\" ";
341   if (md)
342   {
343     t << "href=\"";
344     t << md->getOutputFileBase()<< Doxygen::htmlFileExtension;
345     t << "#" << md->anchor();
346     t<<"\" ";
347
348     t<<" TOOLTIP=\"";
349     if(!toolTip.isEmpty())
350       codify(t,toolTip.data());
351     else{
352       QCString largs = md->argsString();
353       if(!largs.isEmpty()){ 
354         largs=largs.replace(reg," ");
355         codify(t,largs.data());
356       }
357     }
358     t << "\" ";
359
360     t << " PORT=\"";
361     t << md->name();
362     t << "\" ";
363   }
364   if (!toolTip.isEmpty())
365   {
366     // if (!toolTip.isEmpty()) 
367
368     if (bidir)
369       t << "BGCOLOR=\"orange\">";
370     else
371       t << "BGCOLOR=\"azure\">";
372   }
373   else if (bidir)
374   {
375     t << "BGCOLOR=\"pink\">";
376   }
377   else
378   {
379     t << "BGCOLOR=\"lightgrey\">";
380   }
381   if (md)
382   {
383     t << md->name();
384   }
385   else
386   {
387     t << " \n";
388   }
389   t << "</TD>\n";
390
391   if (!start)
392   {
393     t << "</TR>\n";
394   }
395 }
396
397 static void endTabel(FTextStream &t)
398 {
399   t << "</TABLE>>\n";
400   t << "] \n"; 
401 }
402
403 static void writeClassToDot(FTextStream &t,ClassDef* cd)
404 {
405   t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
406   t << "PORT=\"";
407   t << cd->name();
408   t << "\" ";
409   t << "href=\"";
410   t << cd->getOutputFileBase() << Doxygen::htmlFileExtension;
411   t << "\" ";
412   t << ">";
413   t << cd->name();
414   t << " </TD></TR>\n"; 
415 }
416
417 static QList<MemberDef>* getPorts(ClassDef *cd)
418 {
419   MemberDef* md;
420   QList<MemberDef> *portList=new QList<MemberDef>;
421   MemberList *ml=cd->getMemberList(MemberList::variableMembers);
422
423   if (ml==0) return NULL;
424
425   MemberListIterator fmni(*ml);
426
427   for (fmni.toFirst();(md=fmni.current());++fmni)
428   {
429     if (md->getMemberSpecifiers()==VhdlDocGen::PORT)
430     {
431       portList->append(md);
432     }
433   } 
434
435   return portList;
436 }
437
438 //writeColumn(FTextStream &t,QCString name,bool start)
439
440 static void writeTable(QList<MemberDef>* port,FTextStream & t)
441 {
442   QCString space(" ");
443   MemberDef *md;
444   uint len=port->count();
445
446   QList<MemberDef> inPorts;
447   QList<MemberDef> outPorts;
448
449   uint j;
450   for (j=0;j<len;j++)
451   {
452     md=(MemberDef*)port->at(j);
453     QCString qc=md->typeString();
454     if(qc=="in")
455     {
456       inPorts.append(md);
457     }
458     else
459     {
460       outPorts.append(md);
461     }
462   }
463
464   int inp  = inPorts.count();
465   int outp = outPorts.count();
466   int maxLen;
467
468   if (inp>=outp) 
469   {
470     maxLen=inp;
471   }
472   else
473   {
474     maxLen=outp;
475   }
476
477   int i;
478   for(i=0;i<maxLen;i++)
479   {
480     //write inports
481     if (i<inp)
482     {
483       md=(MemberDef*)inPorts.at(i);
484       writeColumn(t,md,true);
485     }
486     else
487     {
488       writeColumn(t,NULL,true);
489     }
490
491     if (i<outp)
492     {
493       md=(MemberDef*)outPorts.at(i);
494       writeColumn(t,md,false);
495     }
496     else
497     {
498       writeColumn(t,NULL,false);
499     }
500   }     
501 }
502
503 //--------------------------------------------------------------------------------------------------
504
505
506 VhdlDocGen::VhdlDocGen()
507 {
508 }
509
510 VhdlDocGen::~VhdlDocGen()
511 {
512 }
513
514 void VhdlDocGen::init()
515 {
516
517  // vhdl keywords inlcuded VHDL 2008
518 const char* g_vhdlKeyWordMap0[] =
519 {
520   "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
521   "begin","block","body","buffer","bus",
522   "case","component","configuration","constant","context","cover",
523   "default","disconnect","downto",
524   "else","elsif","end","entity","exit",
525   "fairness","file","for","force","function",
526   "generate","generic","group","guarded",
527   "if","impure","in","inertial","inout","is",
528   "label","library","linkage","literal","loop",
529   "map","mod",
530   "nand","new","next","nor","not","null",
531   "of","on","open","or","others","out",
532   "package","parameter","port","postponed","procedure","process","property","proctected","pure",
533   "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
534   "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
535   "then","to","transport","type",
536   "unaffected","units","until","use",
537   "variable","vmode","vprop","vunit",
538   "wait","when","while","with",
539   "xor","xnor",
540   0
541 };
542
543 // type
544 const char* g_vhdlKeyWordMap1[] =
545 {
546   "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
547   "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
548   "real","float","ufixed","sfixed","time",0
549 };
550
551 // logic
552 const char* g_vhdlKeyWordMap2[] =
553 {
554   "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
555   "sll",0
556 };
557
558   int j=0;
559   g_vhdlKeyDict0.setAutoDelete(TRUE);
560   g_vhdlKeyDict1.setAutoDelete(TRUE);
561   g_vhdlKeyDict2.setAutoDelete(TRUE);
562
563   j=0;
564   while (g_vhdlKeyWordMap0[j])
565   {
566     g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
567                        new QCString(g_vhdlKeyWordMap0[j]));
568     j++;
569   }
570
571   j=0;
572   while (g_vhdlKeyWordMap1[j])
573   {
574     g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
575                        new QCString(g_vhdlKeyWordMap1[j]));
576     j++;
577   }
578
579   j=0;
580   while (g_vhdlKeyWordMap2[j])
581   {
582     g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
583                        new QCString(g_vhdlKeyWordMap2[j]));
584     j++;
585   }
586
587 }// buildKeyMap
588
589 /*!
590  * returns the color of a keyword
591  */
592
593 QCString* VhdlDocGen::findKeyWord(const QCString& word)
594 {
595   static  QCString g_vhdlkeyword("vhdlkeyword");
596   static  QCString g_vhdltype("comment");
597   static  QCString g_vhdllogic("vhdllogic");
598
599   if (word.isEmpty() || word.at(0)=='\0') return 0;
600   //printf("VhdlDocGen::findKeyWord(%s)\n",word.data());
601
602   if (g_vhdlKeyDict0.find(word.lower()))
603     return &g_vhdlkeyword;
604
605   if (g_vhdlKeyDict1.find(word.lower()))
606     return &g_vhdltype;
607
608   if (g_vhdlKeyDict2.find(word.lower()))
609     return &g_vhdllogic;
610
611   return 0;
612 }
613
614 /*!
615  * returns the parsed entry at line xxx
616  */
617
618
619
620 bool found =FALSE;
621 static Entry eMerge;
622
623 ClassDef *VhdlDocGen::getClass(const char *name)
624 {
625   if (name==0 || name[0]=='\0') return 0;
626
627   ClassDef *cd=0;
628   QCString temp(name);
629   //temp=temp.lower();
630   temp=temp.stripWhiteSpace();
631   cd= Doxygen::classSDict->find(temp.data());
632   return cd;
633 }
634
635
636
637
638 ClassDef* VhdlDocGen::getPackageName(const QCString & name)
639 {
640   ClassDef* cd=0;
641   QStringList ql=QStringList::split(".",name,FALSE);
642   cd=getClass(name);
643
644   return cd;
645 }
646
647 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
648 {
649   QDict<QCString> packages(17,FALSE);
650   packages.setAutoDelete(TRUE);
651   ClassDef* cd;
652   MemberDef *mdef=0;
653
654   cd=getClass(className);
655   //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
656   if (cd==0) return 0;
657
658   mdef=VhdlDocGen::findMemberDef(cd,memName,MemberList::variableMembers);
659   if (mdef) return mdef;
660   mdef=VhdlDocGen::findMemberDef(cd,memName,MemberList::pubMethods);
661   if (mdef) return mdef;
662
663   // nothing found so far
664   // if we are an architecture or package body search in entitiy
665
666   if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
667       (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
668   {
669     Definition *d = cd->getOuterScope();
670     // searching upper/lower case names
671
672     QCString tt=d->name();
673     ClassDef *ecd =getClass(tt);
674     if (!ecd)
675     {
676       tt=tt.upper();
677       ecd =getClass(tt);
678     }
679     if (!ecd)
680     {
681       tt=tt.lower();
682       ecd =getClass(tt);
683     }
684
685     if (ecd) //d && d->definitionType()==Definition::TypeClass)
686     {
687       //ClassDef *ecd = (ClassDef*)d;
688       mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberList::variableMembers);
689       if (mdef) return mdef;
690       mdef=VhdlDocGen::findMemberDef(cd,memName,MemberList::pubMethods);
691       if (mdef) return mdef;
692     }
693     //cd=getClass(getClassName(cd));
694     //if (!cd) return 0;
695   }
696   // nothing found , so we are now searching all included packages
697   VhdlDocGen::findAllPackages(className,packages);
698   //cd=getClass(className.data());
699   if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS ||
700       (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
701   {
702     Definition *d = cd->getOuterScope();
703
704     QCString tt=d->name();
705     ClassDef *ecd =getClass(tt);
706     if (!ecd)
707     {
708       tt=tt.upper();
709       ecd =getClass(tt);
710     }
711     if (!ecd)
712     {
713       tt=tt.lower();
714       ecd =getClass(tt);
715     }
716
717     if (ecd) //d && d->definitionType()==Definition::TypeClass)
718     {
719       VhdlDocGen::findAllPackages(ecd->className(),packages);
720     }
721   }
722
723   QDictIterator<QCString> packli(packages);
724   QCString *curString;
725   for (packli.toFirst();(curString=packli.current());++packli)
726   {
727     if (curString)
728     {
729       cd=VhdlDocGen::getPackageName(*curString);
730       if (!cd)
731       {
732         *curString=curString->upper();
733         cd=VhdlDocGen::getPackageName(*curString);
734       }
735       if (!cd)
736       {
737         *curString=curString->lower();
738         cd=VhdlDocGen::getPackageName(*curString);
739       }
740     }
741     if (cd)
742     {
743       mdef=VhdlDocGen::findMemberDef(cd,memName,MemberList::variableMembers);
744       if (mdef)  return mdef;
745       mdef=VhdlDocGen::findMemberDef(cd,memName,MemberList::pubMethods);
746       if (mdef) return mdef;
747     }
748   } // for
749   return 0;
750 }//findMember
751
752 /**
753  *  This function returns the entity|package
754  *  in which the key (type) is found
755  */
756
757 MemberDef* VhdlDocGen::findMemberDef(ClassDef* cd,const QCString& key,MemberList::ListType type)
758 {
759   //    return cd->getMemberByName(key);//does not work
760   MemberDef *md=0;
761
762   MemberList *ml=    cd->getMemberList(type);
763   if (ml==0) return 0;
764
765   MemberListIterator fmni(*ml);
766
767   for (fmni.toFirst();(md=fmni.current());++fmni)
768   {
769     if (stricmp(key.data(),md->name().data())==0)
770     {
771       return md;
772     }
773   }
774   return 0;
775 }//findMemberDef
776
777 /*!
778  * finds all included packages of an Entity or Package
779  */
780
781 void VhdlDocGen::findAllPackages(const QCString& className,QDict<QCString>& qdict)
782 {
783   ClassDef *cdef=getClass(className);
784   if (cdef)
785   {
786     MemberList *mem=cdef->getMemberList(MemberList::variableMembers);
787     MemberDef *md;
788
789     if (mem)
790     {
791       MemberListIterator fmni(*mem);
792       for (fmni.toFirst();(md=fmni.current());++fmni)
793       {
794         if (VhdlDocGen::isPackage(md))
795         {
796           QCString *temp1=new QCString(md->name().data());
797           //*temp1=temp1->lower();
798           QCString p(md->name().data());
799           //p=p.lower();
800           ClassDef* cd=VhdlDocGen::getPackageName(*temp1);
801           if (cd)
802           {
803             QCString *ss=qdict.find(*temp1);
804             if (ss==0)
805             {
806               qdict.insert(p,temp1);
807               QCString tmp=cd->className();
808               VhdlDocGen::findAllPackages(tmp,qdict);
809             }
810             else delete temp1;
811           }
812           else delete temp1;
813         }
814       }//for
815     }//if
816   }//cdef
817 }// findAllPackages
818
819 /*!
820  * returns the function with the matching argument list
821  * is called in vhdlcode.l
822  */
823
824 MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
825     const QCString& funcname,
826     const QCString& package, bool /*type*/)
827 {
828   MemberDef* mdef=0;
829   //int funcType;
830   ClassDef *cdef=getClass(package.data());
831   if (cdef==0) return 0;
832
833   //if (type)
834   //  funcType=VhdlDocGen::PROCEDURE;
835   //else
836   //  funcType=VhdlDocGen::FUNCTION;
837
838   MemberList *mem=cdef->getMemberList(MemberList::pubMethods);
839
840   if (mem)
841   {
842     MemberListIterator fmni(*mem);
843     for (fmni.toFirst();(mdef=fmni.current());++fmni)
844     {
845       QCString mname=mdef->name();
846       if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (VhdlDocGen::compareString(funcname,mname)==0))
847       {
848         LockingPtr<ArgumentList> alp = mdef->argumentList();
849
850         //  ArgumentList* arg2=mdef->getArgumentList();
851         if (alp==0) break;
852         ArgumentListIterator ali(*alp.pointer());
853         ArgumentListIterator ali1(ql);
854
855         if (ali.count() != ali1.count()) break;
856
857         Argument *arg,*arg1;
858         int equ=0;
859
860         for (;(arg=ali.current());++ali)
861         {
862           arg1=ali1.current(); ++ali1;
863           equ+=abs(VhdlDocGen::compareString(arg->type,arg1->type));
864
865           QCString s1=arg->type;
866           QCString s2=arg1->type;
867           VhdlDocGen::deleteAllChars(s1,' ');
868           VhdlDocGen::deleteAllChars(s2,' ');
869           equ+=abs(VhdlDocGen::compareString(s1,s2));
870           s1=arg->attrib;
871           s2=arg1->attrib;
872           VhdlDocGen::deleteAllChars(s1,' ');
873           VhdlDocGen::deleteAllChars(s2,' ');
874           equ+=abs(VhdlDocGen::compareString(s1,s2));
875           // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
876           // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
877         } // for
878         if (equ==0) return mdef;
879       }//if
880     }//for
881   }//if
882   return mdef;
883 } //findFunction
884
885
886
887
888 /*!
889  * returns the class title+ref
890  */
891
892 QCString VhdlDocGen::getClassTitle(const ClassDef *cd)
893 {
894   QCString pageTitle;
895   if (cd==0) return "";
896   pageTitle+=cd->displayName();
897   pageTitle=VhdlDocGen::getClassName(cd);
898   int ii=cd->protection();
899   pageTitle+=" ";
900   pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
901   pageTitle+=" ";
902   return pageTitle;
903 } // getClassTitle
904
905 /* returns the class name without their prefixes */
906
907 QCString VhdlDocGen::getClassName(const ClassDef* cd)
908 {
909   QCString temp;
910   if (cd==0) return "";
911
912   if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
913   {
914     temp=cd->name();
915     temp.stripPrefix("_");
916     return temp;
917   }
918   //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
919   //{
920   //  QStringList qlist=QStringList::split("-",cd->className(),FALSE);
921   //  if (qlist.count()>1)
922   //    return (QCString)qlist[1];
923   //  return "";
924   //}
925   return substitute(cd->className(),"::",".");
926 }
927
928 /*!
929  * writes an inline link form entity|package to architecture|package body and vice verca
930  */
931
932 void VhdlDocGen::writeInlineClassLink(const ClassDef* cd ,OutputList& ol)
933 {
934   QList<QCString> ql;
935   ql.setAutoDelete(TRUE);
936   QCString nn=cd->className();
937   int ii=(int)cd->protection()+2;
938
939   QCString type;
940   if (ii==VhdlDocGen::ENTITY)
941     type+=theTranslator_vhdlType(VhdlDocGen::ARCHITECTURE,TRUE);
942   else if (ii==VhdlDocGen::ARCHITECTURE)
943     type+=theTranslator_vhdlType(VhdlDocGen::ENTITY,TRUE);
944   else if (ii==VhdlDocGen::PACKAGE_BODY)
945     type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
946   else if (ii==VhdlDocGen::PACKAGE)
947     type+=theTranslator_vhdlType(VhdlDocGen::PACKAGE_BODY,TRUE);
948   else
949     type+="";
950
951   //type=type.lower();
952   type+=" >> ";
953   ol.disable(OutputGenerator::RTF);
954   ol.disable(OutputGenerator::Man);
955
956   if (ii==VhdlDocGen::PACKAGE_BODY)
957   {
958     nn.stripPrefix("_");
959     cd=getClass(nn.data());
960   }
961   else  if (ii==VhdlDocGen::PACKAGE)
962   {
963     nn.prepend("_");
964     cd=getClass(nn.data());
965   }
966   else if (ii==VhdlDocGen::ARCHITECTURE)
967   {
968     QStringList qlist=QStringList::split("-",nn,FALSE);
969     nn=qlist[1].utf8();
970     cd=VhdlDocGen::getClass(nn.data());
971   }
972
973   QCString opp;
974   if (ii==VhdlDocGen::ENTITY)
975   {
976     VhdlDocGen::findAllArchitectures(ql,cd);
977     int j=ql.count();
978     for (int i=0;i<j;i++)
979     {
980       QCString *temp=ql.at(i);
981       QStringList qlist=QStringList::split("-",*temp,FALSE);
982       QCString s1=qlist[0].utf8();
983       QCString s2=qlist[1].utf8();
984       s1.stripPrefix("_");
985       if (j==1) s1.resize(0);
986       ClassDef*cc = getClass(temp->data());
987       if (cc)
988       {
989         VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
990       }
991     }
992   }
993   else
994   {
995     VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
996   }
997
998   ol.enable(OutputGenerator::Man);
999   ol.enable(OutputGenerator::RTF);
1000
1001 }// write
1002
1003 /*
1004  * finds all architectures which belongs to an entiy
1005  */
1006 void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
1007 {
1008   ClassDef *citer;
1009   ClassSDict::Iterator cli(*Doxygen::classSDict);
1010   for ( ; (citer=cli.current()) ; ++cli )
1011   {
1012     QCString jj=citer->className();
1013     if (cd != citer && jj.contains('-')!=-1)
1014     {
1015       QStringList ql=QStringList::split("-",jj,FALSE);
1016       QCString temp=ql[1].utf8();
1017       if (stricmp(cd->className().data(),temp.data())==0)
1018       {
1019         QCString *cl=new QCString(jj.data());
1020         qll.insert(0,cl);
1021       }
1022     }
1023   }// for
1024 }//findAllArchitectures
1025
1026 ClassDef* VhdlDocGen::findArchitecture(const ClassDef *cd)
1027 {
1028   ClassDef *citer;
1029   QCString nn=cd->name();
1030   ClassSDict::Iterator cli(*Doxygen::classSDict);
1031
1032   for ( ; (citer=cli.current()) ; ++cli )
1033   {
1034     QCString jj=citer->name();
1035     QStringList ql=QStringList::split(":",jj,FALSE);
1036     if (ql.count()>1)
1037     {
1038       if (ql[0].utf8()==nn )
1039       {
1040         return citer;
1041       }
1042     }
1043   }
1044   return 0;
1045 }
1046 /*
1047  * writes the link entity >> .... or architecture >> ...
1048  */
1049
1050 void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
1051 {
1052   if (ccd==0)  return;
1053   QCString temp=ccd->getOutputFileBase();
1054   ol.startBold();
1055   ol.docify(type.data());
1056   ol.endBold();
1057   nn.stripPrefix("_");
1058   ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
1059
1060   if (!behav.isEmpty())
1061   {
1062     behav.prepend("  ");
1063     ol.startBold();
1064     ol.docify(behav.data());
1065     ol.endBold();
1066   }
1067
1068   ol.lineBreak();
1069 }
1070
1071 bool VhdlDocGen::compareString(const QCString& s1,const QCString& s2)
1072 {
1073   QCString str1=s1.stripWhiteSpace();
1074   QCString str2=s2.stripWhiteSpace();
1075
1076   return stricmp(str1.data(),str2.data());
1077 }
1078
1079
1080 /*!
1081  * strips the "--" prefixes of vhdl comments
1082  */
1083 void VhdlDocGen::prepareComment(QCString& qcs)
1084 {
1085   const char* s="--!";
1086   //const char *start="--!{";
1087   //const char *end="--!}";
1088   int index=0;
1089
1090   while (TRUE)
1091   {
1092     index=qcs.find(s,0,TRUE);
1093     if (index<0) break;
1094     qcs=qcs.remove(index,strlen(s));
1095   }
1096   qcs=qcs.stripWhiteSpace();
1097 }
1098
1099
1100 /*!
1101  * parses a function proto
1102  * @param text function string
1103  * @param qlist stores the function types
1104  * @param name points to the function name
1105  * @param ret Stores the return type
1106  * @param doc ???
1107  */
1108 void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
1109     QCString& name,QCString& ret,bool doc)
1110 {
1111   (void)qlist; //unused
1112   int index,end;
1113   QCString s1(text);
1114   QCString temp;
1115
1116   index=s1.find("(");
1117   end=s1.findRev(")");
1118
1119   if ((end-index)>0)
1120   {
1121     QCString tt=s1.mid(index,(end-index+1));
1122     temp=s1.mid(index+1,(end-index-1));
1123     //getFuncParams(qlist,temp);
1124   }
1125   if (doc)
1126   {
1127     name=s1.left(index);
1128     name=name.stripWhiteSpace();
1129     if ((end-index)>0)
1130     {
1131       ret="function";
1132     }
1133     return;
1134   }
1135   else
1136   {
1137     QCString s1(text);
1138     s1=s1.stripWhiteSpace();
1139     int i=s1.find("(",0,FALSE);
1140     int s=s1.find(QRegExp("[ \\t]"));
1141     if (i==-1 || i<s)
1142       s1=VhdlDocGen::getIndexWord(s1.data(),1);
1143     else // s<i, s=start of name, i=end of name
1144       s1=s1.mid(s,(i-s));
1145
1146     name=s1.stripWhiteSpace();
1147   }
1148   index=s1.findRev("return",-1,FALSE);
1149   if (index !=-1)
1150   {
1151     ret=s1.mid(index+6,s1.length());
1152     ret=ret.stripWhiteSpace();
1153     VhdlDocGen::deleteCharRev(ret,';');
1154   }
1155 }
1156
1157 /*
1158  *  returns the n'th word of a string
1159  */
1160
1161 QCString VhdlDocGen::getIndexWord(const char* c,int index)
1162 {
1163   QStringList ql;
1164   QCString temp(c);
1165   QRegExp reg("[\\s:|]");
1166
1167   ql=QStringList::split(reg,temp,FALSE);
1168
1169   if (ql.count() > (unsigned int)index)
1170   {
1171     return ql[index].utf8();
1172   }
1173
1174   return "";
1175 }
1176
1177
1178 QCString VhdlDocGen::getProtectionName(int prot)
1179 {
1180   if (prot==VhdlDocGen::ENTITYCLASS)
1181     return "entity";
1182   else if (prot==VhdlDocGen::ARCHITECTURECLASS)
1183     return "architecture";
1184   else if (prot==VhdlDocGen::PACKAGECLASS)
1185     return "package";
1186   else if (prot==VhdlDocGen::PACKBODYCLASS)
1187     return "package body";
1188
1189   return "";
1190 }
1191
1192 QCString VhdlDocGen::trTypeString(int type)
1193 {
1194   switch(type)
1195   {
1196     case VhdlDocGen::LIBRARY:        return "Library";
1197     case VhdlDocGen::ENTITY:         return "Entity";
1198     case VhdlDocGen::PACKAGE_BODY:   return "Package Body";
1199     case VhdlDocGen::ATTRIBUTE:      return "Attribute";
1200     case VhdlDocGen::PACKAGE:        return "Package";
1201     case VhdlDocGen::SIGNAL:         return "Signal";
1202     case VhdlDocGen::COMPONENT:      return "Component";
1203     case VhdlDocGen::CONSTANT:       return "Constant";
1204     case VhdlDocGen::TYPE:           return "Type";
1205     case VhdlDocGen::SUBTYPE:        return "Subtype";
1206     case VhdlDocGen::FUNCTION:       return "Function";
1207     case VhdlDocGen::RECORD:         return "Record";
1208     case VhdlDocGen::PROCEDURE:      return "Procedure";
1209     case VhdlDocGen::ARCHITECTURE:   return "Architecture";
1210     case VhdlDocGen::USE:            return "Package";
1211     case VhdlDocGen::PROCESS:        return "Process";
1212     case VhdlDocGen::PORT:           return "Port";
1213     case VhdlDocGen::GENERIC:        return "Generic";
1214     case VhdlDocGen::UNITS:          return "Units";
1215                                      //case VhdlDocGen::PORTMAP:        return "Port Map";
1216     case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
1217     case VhdlDocGen::GROUP:          return "Group";
1218     case VhdlDocGen::VFILE:          return "File";
1219     case VhdlDocGen::INSTANTIATION: return "Instantiation";
1220     case VhdlDocGen::ALIAS:          return "Alias";
1221     case VhdlDocGen::CONFIG:         return "Configuration";
1222     case VhdlDocGen::MISCELLANEOUS:  return "Miscellaneous";
1223     case VhdlDocGen::UCF_CONST:      return "Constraints";
1224     default:                         return "";
1225   }
1226 } // convertType
1227
1228 /*!
1229  * deletes a char backwards in a string
1230  */
1231
1232 bool VhdlDocGen::deleteCharRev(QCString &s,char c)
1233 {
1234   int index=s.findRev(c,-1,FALSE);
1235   if (index > -1)
1236   {
1237     QCString qcs=s.remove(index,1);
1238     s=qcs;
1239     return TRUE;
1240   }
1241   return FALSE;
1242 }
1243
1244 void VhdlDocGen::deleteAllChars(QCString &s,char c)
1245 {
1246   int index=s.findRev(c,-1,FALSE);
1247   while (index > -1)
1248   {
1249     QCString qcs=s.remove(index,1);
1250     s=qcs;
1251     index=s.findRev(c,-1,FALSE);
1252   }
1253 }
1254
1255
1256 static int recordCounter=0;
1257
1258 /*!
1259  * returns the next number of a record|unit member
1260  */
1261
1262 QCString VhdlDocGen::getRecordNumber()
1263 {
1264   char buf[12];
1265   sprintf(buf,"%d",recordCounter++);
1266   QCString qcs(&buf[0]);
1267   return qcs;
1268 }
1269
1270 /*!
1271  * returns the next number of an anonymous process
1272  */
1273
1274 QCString VhdlDocGen::getProcessNumber()
1275 {
1276   static int stringCounter;
1277   char buf[8];
1278   QCString qcs("PROCESS_");
1279   sprintf(buf,"%d",stringCounter++);
1280   qcs.append(&buf[0]);
1281   return qcs;
1282 }
1283
1284 /*!
1285  * writes a colored and formatted string
1286  */
1287
1288 void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
1289 {
1290   QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
1291   QCString qcs = s;
1292   qcs+=QCString(" ");// parsing the last sign
1293   QCString *ss;
1294   QCString find=qcs;
1295   QCString temp=qcs;
1296   char buf[2];
1297   buf[1]='\0';
1298
1299   int j;
1300   int len;
1301   j = reg.match(temp.data(),0,&len);
1302
1303   ol.startBold();
1304   if (j>=0)
1305   {
1306     while (j>=0)
1307     {
1308       find=find.left(j);
1309       buf[0]=temp[j];
1310       ss=VhdlDocGen::findKeyWord(find);
1311       bool k=VhdlDocGen::isNumber(find); // is this a number
1312       if (k)
1313       {
1314         ol.docify(" ");
1315         VhdlDocGen::startFonts(find,"vhdldigit",ol);
1316         ol.docify(" ");
1317       }
1318       else if (j != 0 && ss)
1319       {
1320         VhdlDocGen::startFonts(find,ss->data(),ol);
1321       }
1322       else
1323       {
1324         if (j>0)
1325         {
1326           VhdlDocGen::writeStringLink(mdef,find,ol);
1327         }
1328       }
1329       VhdlDocGen::startFonts(&buf[0],"vhdlchar",ol);
1330
1331       QCString st=temp.remove(0,j+1);
1332       find=st;
1333       if (!find.isEmpty() && find.at(0)=='"')
1334       {
1335         int ii=find.find('"',2);
1336         if (ii>1)
1337         {
1338           QCString com=find.left(ii+1);
1339           VhdlDocGen::startFonts(com,"keyword",ol);
1340           temp=find.remove(0,ii+1);
1341         }
1342       }
1343       else
1344       {
1345         temp=st;
1346       }
1347       j = reg.match(temp.data(),0,&len);
1348     }//while
1349   }//if
1350   else
1351   {
1352     VhdlDocGen::startFonts(find,"vhdlchar",ol);
1353   }
1354   ol.endBold();
1355 }// writeFormatString
1356
1357 /*!
1358  * returns TRUE if this string is a number
1359  */
1360
1361 bool VhdlDocGen::isNumber(const QCString& s)
1362 {
1363   static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
1364
1365   if (s.isEmpty()) return FALSE;
1366   int j,len;
1367   j = regg.match(s.data(),0,&len);
1368   if ((j==0) && (len==(int)s.length())) return TRUE;
1369   return FALSE;
1370
1371 }// isNumber
1372
1373 void VhdlDocGen::startFonts(const QCString& q, const char *keyword,OutputList& ol)
1374 {
1375   ol.startFontClass(keyword);
1376   ol.docify(q.data());
1377   ol.endFontClass();
1378 }
1379
1380 /*!
1381  * inserts white spaces for  better readings
1382  * and writes a colored string to the output
1383  */
1384
1385 void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
1386 {
1387   QCString qcs = s;
1388   QCString temp(qcs.length());
1389   qcs.stripPrefix(":");
1390   qcs.stripPrefix("is");
1391   qcs.stripPrefix("IS");
1392   qcs.stripPrefix("of");
1393   qcs.stripPrefix("OF");
1394
1395   // VhdlDocGen::deleteCharRev(qcs,';');
1396   //char white='\t';
1397   int len = qcs.length();
1398   unsigned int index=1;//temp.length();
1399
1400   for (int j=0;j<len;j++)
1401   {
1402     char c=qcs[j];
1403     char b=c;
1404     if (j>0) b=qcs[j-1];
1405     if (c=='"' || c==',' || c=='\''|| c=='(' || c==')'  || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
1406     {
1407       if (temp.at(index-1) != ' ')
1408       {
1409         temp+=" ";
1410       }
1411       temp+=c;
1412       temp+=" ";
1413     }
1414     else if (c=='=')
1415     {
1416       if (b==':') // := operator
1417       {
1418         temp.replace(index-1,1,"=");
1419         temp+=" ";
1420       }
1421       else // = operator
1422       {
1423         temp+=" ";
1424         temp+=c;
1425         temp+=" ";
1426       }
1427     }
1428     else
1429     {
1430       temp+=c;
1431     }
1432
1433     index=temp.length();
1434   }// for
1435   temp=temp.stripWhiteSpace();
1436   // printf("\n [%s]",qcs.data());
1437   VhdlDocGen::writeFormatString(temp,ol,mdef);
1438 }
1439
1440 /*!
1441  * writes a procedure prototype to the output
1442  */
1443
1444 void VhdlDocGen::writeProcedureProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1445 {
1446   ArgumentListIterator ali(*al);
1447   Argument *arg;
1448   bool sem=FALSE;
1449   int len=al->count();
1450   ol.docify("( ");
1451   if (len > 2)
1452   {
1453     ol.lineBreak();
1454   }
1455   for (;(arg=ali.current());++ali)
1456   {
1457     ol.startBold();
1458     if (sem && len <3)
1459       ol.writeChar(',');
1460
1461     QCString nn=arg->name;
1462     nn+=": ";
1463
1464     QCString *str=VhdlDocGen::findKeyWord(arg->defval);
1465     arg->defval+=" ";
1466     if (str)
1467     {
1468       VhdlDocGen::startFonts(arg->defval,str->data(),ol);
1469     }
1470     else
1471     {
1472       VhdlDocGen::startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
1473     }
1474
1475     VhdlDocGen::startFonts(nn,"vhdlchar",ol); // write name
1476     if (stricmp(arg->attrib.data(),arg->type.data()) != 0)
1477       VhdlDocGen::startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
1478     ol.docify(" ");
1479     VhdlDocGen::formatString(arg->type,ol,mdef);
1480     sem=TRUE;
1481     ol.endBold();
1482     if (len > 2)
1483     {
1484       ol.lineBreak();
1485       ol.docify("  ");
1486     }
1487   }//for
1488
1489   ol.docify(" )");
1490
1491
1492 }
1493
1494 /*!
1495  * writes a function prototype to the output
1496  */
1497
1498 void VhdlDocGen::writeFunctionProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1499 {
1500   if (al==0) return;
1501   ArgumentListIterator ali(*al);
1502   Argument *arg;
1503   bool sem=FALSE;
1504   int len=al->count();
1505   ol.startBold();
1506   ol.docify(" ( ");
1507   ol.endBold();
1508   if (len>2)
1509   {
1510     ol.lineBreak();
1511   }
1512   for (;(arg=ali.current());++ali)
1513   {
1514     ol.startBold();
1515     QCString att=arg->defval;
1516     bool bGen=att.stripPrefix("gen!");
1517
1518     if (sem && len < 3)
1519     {
1520       ol.docify(" , ");
1521     }
1522
1523     if (bGen) {
1524       VhdlDocGen::formatString(QCString("generic "),ol,mdef);
1525     }
1526     if (!att.isEmpty())
1527     {
1528       QCString *str=VhdlDocGen::findKeyWord(att);
1529       att+=" ";
1530       if (str)
1531         VhdlDocGen::formatString(att,ol,mdef);
1532       else
1533         VhdlDocGen::startFonts(att,"vhdlchar",ol);
1534     }
1535
1536     QCString nn=arg->name;
1537     nn+=": ";
1538     QCString ss=arg->type.stripWhiteSpace(); //.lower();
1539     QCString w=ss.stripWhiteSpace();//.upper();
1540     VhdlDocGen::startFonts(nn,"vhdlchar",ol);
1541     VhdlDocGen::startFonts("in ","stringliteral",ol);
1542     QCString *str=VhdlDocGen::findKeyWord(ss);
1543     if (str)
1544       VhdlDocGen::formatString(w,ol,mdef);
1545     else
1546       VhdlDocGen::startFonts(w,"vhdlchar",ol);
1547
1548     if (arg->attrib)
1549       VhdlDocGen::startFonts(arg->attrib,"vhdlchar",ol);
1550
1551
1552     sem=TRUE;
1553     ol.endBold();
1554     if (len > 2)
1555     {
1556       ol.lineBreak();
1557     }
1558   }
1559   ol.startBold();
1560   ol.docify(" )");
1561   const char *exp=mdef->excpString();
1562   if (exp)
1563   {
1564     ol.insertMemberAlign();
1565     ol.startBold();
1566     ol.docify("[ ");
1567     ol.docify(exp);
1568     ol.docify(" ]");
1569     ol.endBold();
1570   }
1571   ol.endBold();
1572 }
1573
1574 /*!
1575  * writes a process prototype to the output
1576  */
1577
1578 void VhdlDocGen::writeProcessProto(OutputList& ol,const ArgumentList* al,const MemberDef* mdef)
1579 {
1580   if (al==0) return;
1581   ArgumentListIterator ali(*al);
1582   Argument *arg;
1583   bool sem=FALSE;
1584   ol.startBold();
1585   ol.docify(" ( ");
1586   for (;(arg=ali.current());++ali)
1587   {
1588     if (sem)
1589     {
1590       ol.docify(" , ");
1591     }
1592     QCString nn=arg->name;
1593     // VhdlDocGen::startFonts(nn,"vhdlchar",ol);
1594     VhdlDocGen::writeFormatString(nn,ol,mdef);
1595     sem=TRUE;
1596   }
1597   ol.docify(" )");
1598   ol.endBold();
1599 }
1600
1601
1602 /*!
1603  * writes a function|procedure documentation to the output
1604  */
1605
1606 void VhdlDocGen::writeFuncProcDocu(
1607     const MemberDef *md,
1608     OutputList& ol,
1609     const ArgumentList* al,
1610     bool /*type*/)
1611 {
1612   if (al==0) return;
1613   //bool sem=FALSE;
1614   ol.enableAll();
1615
1616   ArgumentListIterator ali(*al);
1617   int index=ali.count();
1618   if (index==0)
1619   {
1620     ol.docify(" ( ) ");
1621     return;
1622   }
1623   ol.startParameterList(TRUE);
1624   //ol.startParameterName(FALSE);
1625   Argument *arg;
1626   bool first=TRUE;
1627   for (;(arg=ali.current());++ali)
1628   {
1629     ol.startParameterType(first,"");
1630     //   if (first) ol.writeChar('(');
1631     QCString attl=arg->defval;
1632     bool bGen=attl.stripPrefix("gen!");
1633     if (bGen)
1634       VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
1635
1636
1637     if (VhdlDocGen::isProcedure(md))
1638     {
1639       startFonts(arg->defval,"keywordtype",ol);
1640       ol.docify(" ");
1641     }
1642     ol.endParameterType();
1643
1644     ol.startParameterName(TRUE);
1645     VhdlDocGen::writeFormatString(arg->name,ol,md);
1646     ol.docify(" : ");
1647
1648     if (VhdlDocGen::isProcedure(md))
1649     {
1650       startFonts(arg->attrib,"stringliteral",ol);
1651     }
1652     else if (VhdlDocGen::isVhdlFunction(md))
1653     {
1654       startFonts(QCString("in"),"stringliteral",ol);
1655     }
1656
1657     ol.docify(" ");
1658     ol.disable(OutputGenerator::Man);
1659     ol.startEmphasis();
1660     ol.enable(OutputGenerator::Man);
1661     if (!VhdlDocGen::isProcess(md))
1662     {
1663      // startFonts(arg->type,"vhdlkeyword",ol);
1664                 VhdlDocGen::writeFormatString(arg->type,ol,md);
1665     }
1666     ol.disable(OutputGenerator::Man);
1667     ol.endEmphasis();
1668     ol.enable(OutputGenerator::Man);
1669
1670     if (--index)
1671     {
1672       ol.docify(" , ");
1673     }
1674     else
1675     {
1676       //    ol.docify(" ) ");
1677       ol.endParameterName(TRUE,FALSE,TRUE);
1678       break;
1679     }
1680     ol.endParameterName(FALSE,FALSE,FALSE);
1681
1682     //sem=TRUE;
1683     first=FALSE;
1684   }
1685   //ol.endParameterList();
1686
1687 } // writeDocFunProc
1688
1689
1690
1691
1692 QCString VhdlDocGen::convertArgumentListToString(const ArgumentList* al,bool func)
1693 {
1694   QCString argString;
1695   bool sem=FALSE;
1696   ArgumentListIterator ali(*al);
1697   Argument *arg;
1698
1699   for (;(arg=ali.current());++ali)
1700   {
1701     if (sem) argString.append(", ");
1702     if (func)
1703     {
1704       argString+=arg->name;
1705       argString+=":";
1706       argString+=arg->type;
1707     }
1708     else
1709     {
1710       argString+=arg->defval+" ";
1711       argString+=arg->name+" :";
1712       argString+=arg->attrib+" ";
1713       argString+=arg->type;
1714     }
1715     sem=TRUE;
1716   }
1717   return argString;
1718 }
1719
1720
1721 void VhdlDocGen::writeVhdlDeclarations(MemberList* ml,
1722     OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
1723 {
1724   static ClassDef *cdef;
1725   //static GroupDef* gdef;
1726   if (cd && cdef!=cd)
1727   { // only one inline link
1728     VhdlDocGen::writeInlineClassLink(cd,ol);
1729     cdef=cd;
1730   }
1731
1732   /*
1733      if (gd && gdef==gd) return;
1734      if (gd && gdef!=gd)
1735      {
1736      gdef=gd;
1737      }
1738    */
1739   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::LIBRARY,FALSE),0,FALSE,VhdlDocGen::LIBRARY);
1740   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::USE,FALSE),0,FALSE,VhdlDocGen::USE);
1741   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::FUNCTION,FALSE),0,FALSE,VhdlDocGen::FUNCTION);
1742   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::COMPONENT,FALSE),0,FALSE,VhdlDocGen::COMPONENT);
1743   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONSTANT,FALSE),0,FALSE,VhdlDocGen::CONSTANT);
1744   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::TYPE,FALSE),0,FALSE,VhdlDocGen::TYPE);
1745   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SUBTYPE,FALSE),0,FALSE,VhdlDocGen::SUBTYPE);
1746   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GENERIC,FALSE),0,FALSE,VhdlDocGen::GENERIC);
1747   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PORT,FALSE),0,FALSE,VhdlDocGen::PORT);
1748   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCESS,FALSE),0,FALSE,VhdlDocGen::PROCESS);
1749   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SIGNAL,FALSE),0,FALSE,VhdlDocGen::SIGNAL);
1750   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ATTRIBUTE,FALSE),0,FALSE,VhdlDocGen::ATTRIBUTE);
1751   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::PROCEDURE,FALSE),0,FALSE,VhdlDocGen::PROCEDURE);
1752   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::RECORD,FALSE),0,FALSE,VhdlDocGen::RECORD);
1753   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UNITS,FALSE),0,FALSE,VhdlDocGen::UNITS);
1754   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::SHAREDVARIABLE,FALSE),0,FALSE,VhdlDocGen::SHAREDVARIABLE);
1755   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::VFILE,FALSE),0,FALSE,VhdlDocGen::VFILE);
1756   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::GROUP,FALSE),0,FALSE,VhdlDocGen::GROUP);
1757   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::INSTANTIATION,FALSE),0,FALSE,VhdlDocGen::INSTANTIATION);
1758   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::ALIAS,FALSE),0,FALSE,VhdlDocGen::ALIAS);
1759   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::MISCELLANEOUS),0,FALSE,VhdlDocGen::MISCELLANEOUS);
1760
1761   // configurations must be added to global file definitions.
1762   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::CONFIG,FALSE),0,FALSE,VhdlDocGen::CONFIG);
1763   VhdlDocGen::writeVHDLDeclarations(ml,ol,cd,nd,fd,gd,theTranslator_vhdlType(VhdlDocGen::UCF_CONST,FALSE),0,FALSE,VhdlDocGen::UCF_CONST);
1764
1765 }
1766
1767 static void setGlobalType(MemberList *ml)
1768 {
1769   if (ml==0) return;
1770   MemberDef *mdd=0;
1771   MemberListIterator mmli(*ml);
1772   for ( ; (mdd=mmli.current()); ++mmli )
1773   {
1774     QCString l=mdd->typeString();
1775
1776     if (strcmp(mdd->argsString(),"package")==0)
1777     {
1778         mdd->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
1779     }
1780     else if (strcmp(mdd->argsString(),"configuration")==0)
1781     {
1782       mdd->setMemberSpecifiers(VhdlDocGen::CONFIG);
1783     }
1784     else if (strcmp(mdd->typeString(),"library")==0)
1785     {
1786       mdd->setMemberSpecifiers(VhdlDocGen::LIBRARY);
1787     }
1788     else if (strcmp(mdd->typeString(),"use")==0)
1789     {
1790       mdd->setMemberSpecifiers(VhdlDocGen::USE);
1791     }
1792     else if (stricmp(mdd->typeString(),"misc")==0)
1793     {
1794       mdd->setMemberSpecifiers(VhdlDocGen::MISCELLANEOUS);
1795     }
1796     else if (stricmp(mdd->typeString(),"ucf_const")==0)
1797     {
1798       mdd->setMemberSpecifiers(VhdlDocGen::UCF_CONST);
1799     }
1800   }
1801 }
1802
1803 /* writes a vhdl type documentation */
1804 void VhdlDocGen::writeVHDLTypeDocumentation(const MemberDef* mdef, const Definition *d, OutputList &ol)
1805 {
1806   ClassDef *cd=(ClassDef*)d;
1807
1808   if (cd==0) return;
1809
1810   QCString ttype=mdef->typeString();
1811   QCString largs=mdef->argsString();
1812
1813   if ((VhdlDocGen::isVhdlFunction(mdef) || VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isProcess(mdef)))
1814   {
1815     QCString nn=mdef->typeString();
1816     nn=nn.stripWhiteSpace();
1817     QCString na=cd->name();
1818     MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1819     if (memdef && memdef->isLinkable())
1820     {
1821       ol.docify(" ");
1822
1823       ol.startBold();
1824       writeLink(memdef,ol);
1825       ol.endBold();
1826       ol.docify(" ");
1827     }
1828     else
1829     {
1830       ol.docify(" ");
1831       VhdlDocGen::formatString(ttype,ol,mdef);
1832       ol.docify(" ");
1833     }
1834     ol.docify(mdef->name());
1835     VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList().pointer());
1836   }
1837
1838
1839   if (mdef->isVariable())
1840   {
1841     if (VhdlDocGen::isConstraint(mdef))
1842     {
1843       writeLink(mdef,ol);
1844       ol.docify(" ");
1845
1846       largs=largs.replace(QRegExp("#")," ");
1847       VhdlDocGen::formatString(largs,ol,mdef);
1848       return;
1849     }
1850     else
1851     {
1852       writeLink(mdef,ol);
1853       if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
1854       {
1855         return;
1856       }
1857       ol.docify(" ");
1858     }
1859
1860     // QCString largs=mdef->argsString();
1861
1862     bool c=largs=="context";
1863     bool brec=largs.stripPrefix("record")  ;
1864
1865     if (!brec && !c)
1866       VhdlDocGen::formatString(ttype,ol,mdef);
1867
1868     if (c || brec || largs.stripPrefix("units"))
1869     {
1870       if (c)
1871           largs=ttype;
1872       VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1873       return;
1874     }
1875
1876     ol.docify(" ");
1877     if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1878     {
1879       // QCString largs=mdef->argsString();
1880       VhdlDocGen::formatString(largs,ol,mdef);
1881       ol.docify(" ");
1882     }
1883   }
1884 }
1885
1886 /* writes a vhdl type declaration */
1887
1888 void VhdlDocGen::writeVHDLDeclaration(MemberDef* mdef,OutputList &ol,
1889     ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1890     bool /*inGroup*/)
1891 {
1892   static QRegExp reg("[%]");
1893   LockingPtr<MemberDef> lock(mdef,mdef);
1894
1895   Definition *d=0;
1896
1897   /* some vhdl files contain only a configuration  description
1898
1899      library work;
1900      configuration cfg_tb_jtag_gotoBackup of tb_jtag_gotoBackup is
1901      for RTL
1902      end for;
1903      end cfg_tb_jtag_gotoBackup;
1904
1905      in this case library work does not belong to an entity, package ...
1906
1907    */
1908
1909   ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
1910       mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY ||
1911       mdef->getMemberSpecifiers()==VhdlDocGen::USE
1912       ); // member should belong to something
1913   if (cd) d=cd;
1914   else if (nd) d=nd;
1915   else if (fd) d=fd;
1916   else if (gd) d=gd;
1917   else d=(Definition*)mdef;
1918
1919   // write tag file information of this member
1920   if (!Config_getString("GENERATE_TAGFILE").isEmpty())
1921   {
1922     Doxygen::tagFile << "    <member kind=\"";
1923     if (VhdlDocGen::isGeneric(mdef))      Doxygen::tagFile << "generic";
1924     if (VhdlDocGen::isPort(mdef))         Doxygen::tagFile << "port";
1925     if (VhdlDocGen::isEntity(mdef))       Doxygen::tagFile << "entity";
1926     if (VhdlDocGen::isComponent(mdef))    Doxygen::tagFile << "component";
1927     if (VhdlDocGen::isVType(mdef))        Doxygen::tagFile << "type";
1928     if (VhdlDocGen::isConstant(mdef))     Doxygen::tagFile << "constant";
1929     if (VhdlDocGen::isSubType(mdef))      Doxygen::tagFile << "subtype";
1930     if (VhdlDocGen::isVhdlFunction(mdef)) Doxygen::tagFile << "function";
1931     if (VhdlDocGen::isProcedure(mdef))    Doxygen::tagFile << "procedure";
1932     if (VhdlDocGen::isProcess(mdef))      Doxygen::tagFile << "process";
1933     if (VhdlDocGen::isSignals(mdef))      Doxygen::tagFile << "signal";
1934     if (VhdlDocGen::isAttribute(mdef))    Doxygen::tagFile << "attribute";
1935     if (VhdlDocGen::isRecord(mdef))       Doxygen::tagFile << "record";
1936     if (VhdlDocGen::isLibrary(mdef))      Doxygen::tagFile << "library";
1937     if (VhdlDocGen::isPackage(mdef))      Doxygen::tagFile << "package";
1938     if (VhdlDocGen::isVariable(mdef))     Doxygen::tagFile << "shared variable";
1939     if (VhdlDocGen::isFile(mdef))         Doxygen::tagFile << "file";
1940     if (VhdlDocGen::isGroup(mdef))        Doxygen::tagFile << "group";
1941     if (VhdlDocGen::isCompInst(mdef))     Doxygen::tagFile << " instantiation";
1942     if (VhdlDocGen::isAlias(mdef))        Doxygen::tagFile << "alias";
1943     if (VhdlDocGen::isCompInst(mdef))     Doxygen::tagFile << "configuration";
1944
1945     Doxygen::tagFile << "\">" << endl;
1946     Doxygen::tagFile << "      <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
1947     Doxygen::tagFile << "      <name>" << convertToXML(mdef->name()) << "</name>" << endl;
1948     Doxygen::tagFile << "      <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
1949     Doxygen::tagFile << "      <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
1950
1951     if (VhdlDocGen::isVhdlFunction(mdef))
1952       Doxygen::tagFile << "      <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList().pointer(),TRUE)) << "</arglist>" << endl;
1953     else if (VhdlDocGen::isProcedure(mdef))
1954       Doxygen::tagFile << "      <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList().pointer(),FALSE)) << "</arglist>" << endl;
1955     else
1956       Doxygen::tagFile << "      <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
1957
1958     mdef->writeDocAnchorsToTagFile();
1959     Doxygen::tagFile << "    </member>" << endl;
1960
1961   }
1962
1963   // write search index info
1964   if (Doxygen::searchIndex)
1965   {
1966     Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
1967     Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
1968     Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
1969   }
1970
1971   QCString cname  = d->name();
1972   QCString cfname = d->getOutputFileBase();
1973
1974   //HtmlHelp *htmlHelp=0;
1975   //  bool hasHtmlHelp = Config_getBool("GENERATE_HTML") && Config_getBool("GENERATE_HTMLHELP");
1976   //  if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1977
1978   // search for the last anonymous scope in the member type
1979   ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
1980
1981   // start a new member declaration
1982   bool isAnonymous = annoClassDef; // || m_impl->annMemb || m_impl->annEnumType;
1983   ///printf("startMemberItem for %s\n",name().data());
1984   ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
1985
1986   // If there is no detailed description we need to write the anchor here.
1987   bool detailsVisible = mdef->isDetailedSectionLinkable();
1988   if (!detailsVisible) // && !m_impl->annMemb)
1989   {
1990     QCString doxyName=mdef->name().copy();
1991     if (!cname.isEmpty()) doxyName.prepend(cname+"::");
1992     QCString doxyArgs=mdef->argsString();
1993     ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
1994
1995     ol.pushGeneratorState();
1996     ol.disable(OutputGenerator::Man);
1997     ol.disable(OutputGenerator::Latex);
1998     ol.docify("\n");
1999     ol.popGeneratorState();
2000
2001   }
2002   // *** write type
2003   /*VHDL CHANGE */
2004   bool bRec,bUnit;
2005   QCString ltype(mdef->typeString());
2006   ltype=ltype.replace(reg," ");
2007   QCString largs(mdef->argsString());
2008   largs=largs.replace(reg," ");
2009   int mm=mdef->getMemberSpecifiers();
2010   mdef->setType(ltype.data());
2011   mdef->setArgsString(largs.data());
2012   //ClassDef * plo=mdef->getClassDef();
2013   ClassDef *kl=0;
2014   LockingPtr<ArgumentList> alp = mdef->argumentList();
2015   QCString nn;
2016   //VhdlDocGen::adjustRecordMember(mdef);
2017   if (gd) gd=0;
2018   switch(mm)
2019   {
2020     case VhdlDocGen::MISCELLANEOUS:
2021       VhdlDocGen::writeCodeFragment(mdef,ol);
2022       break;
2023     case VhdlDocGen::PROCEDURE:
2024     case VhdlDocGen::FUNCTION:
2025       ol.startBold();
2026       VhdlDocGen::formatString(ltype,ol,mdef);
2027       ol.endBold();
2028       ol.insertMemberAlign();
2029       ol.docify(" ");
2030
2031       writeLink(mdef,ol);
2032       if (alp!=0 && mm==VhdlDocGen::FUNCTION)
2033         VhdlDocGen::writeFunctionProto(ol,alp.pointer(),mdef);
2034
2035       if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
2036         VhdlDocGen::writeProcedureProto(ol,alp.pointer(),mdef);
2037
2038       break;
2039     case VhdlDocGen::USE:
2040       kl=VhdlDocGen::getClass(mdef->name());
2041       if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
2042       writeLink(mdef,ol);
2043       ol.insertMemberAlign();
2044       ol.docify("  ");
2045
2046       if (kl)
2047       {
2048         nn=kl->getOutputFileBase();
2049         ol.pushGeneratorState();
2050         ol.disableAllBut(OutputGenerator::Html);
2051         ol.docify(" ");
2052         QCString name=theTranslator_vhdlType(VhdlDocGen::PACKAGE,TRUE);
2053         ol.startBold();
2054         ol.docify(name.data());
2055         name.resize(0);
2056         ol.endBold();
2057         name+=" <"+mdef->name()+">";
2058         ol.startEmphasis();
2059         ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2060         ol.popGeneratorState();
2061       }
2062       break;
2063     case VhdlDocGen::LIBRARY:
2064       writeLink(mdef,ol);
2065       ol.insertMemberAlign();
2066       if (largs=="context")
2067       {
2068         VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
2069       }
2070
2071       break;
2072
2073     case VhdlDocGen::GENERIC:
2074     case VhdlDocGen::PORT:
2075     case VhdlDocGen::ALIAS:
2076
2077       writeLink(mdef,ol);
2078       ol.docify(" ");
2079       ol.insertMemberAlign();
2080       if (mm==VhdlDocGen::GENERIC)
2081       {
2082         ol.startBold();
2083         VhdlDocGen::formatString(largs,ol,mdef);
2084         ol.endBold();
2085       }
2086       else
2087       {
2088         ol.docify(" ");
2089         ol.startBold();
2090         VhdlDocGen::formatString(ltype,ol,mdef);
2091         ol.endBold();
2092         ol.docify(" ");
2093         VhdlDocGen::formatString(largs,ol,mdef);
2094       }
2095       break;
2096     case VhdlDocGen::PROCESS:
2097       writeLink(mdef,ol);
2098       ol.insertMemberAlign();
2099       VhdlDocGen::writeProcessProto(ol,alp.pointer(),mdef);
2100       break;
2101     case VhdlDocGen::PACKAGE:
2102     case VhdlDocGen::ENTITY:
2103     case VhdlDocGen::COMPONENT:
2104     case VhdlDocGen::INSTANTIATION:
2105     case VhdlDocGen::CONFIG:
2106       if (VhdlDocGen::isCompInst(mdef) )
2107       {
2108         nn=largs;
2109         if(nn.stripPrefix("function") || nn.stripPrefix("package"))
2110         {
2111           VhdlDocGen::formatString(largs,ol,mdef);
2112           ol.insertMemberAlign();
2113           writeLink(mdef,ol);
2114           ol.docify(" ");
2115           VhdlDocGen::formatString(ltype,ol,mdef);
2116           break;
2117         }
2118
2119         largs.prepend("::");
2120         largs.prepend(mdef->name().data());
2121         ol.writeObjectLink(mdef->getReference(),
2122             cfname,
2123             mdef->anchor(),
2124             mdef->name());
2125       }
2126       else
2127         writeLink(mdef,ol);
2128
2129       ol.insertMemberAlign();
2130       ol.docify("  ");
2131
2132       ol.startBold();
2133       ol.docify(ltype);
2134       ol.endBold();
2135       ol.docify("  ");
2136       if (VhdlDocGen::isComponent(mdef) ||
2137           VhdlDocGen::isConfig(mdef)    ||
2138           VhdlDocGen::isCompInst(mdef))
2139       {
2140         if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2141         {
2142           nn=mdef->getOutputFileBase();
2143           nn=ltype;
2144         }
2145         else
2146         {
2147           nn=mdef->name();
2148         }
2149         kl=getClass(nn.data());
2150         if (kl)
2151         {
2152           nn=kl->getOutputFileBase();
2153           ol.pushGeneratorState();
2154           ol.disableAllBut(OutputGenerator::Html);
2155           ol.startEmphasis();
2156           QCString name("<Entity ");
2157           if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2158           {
2159             name+=ltype+">";
2160           }
2161           else
2162           {
2163             name+=mdef->name()+"> ";
2164           }
2165           ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2166           ol.endEmphasis();
2167           ol.popGeneratorState();
2168         }
2169       }
2170       break;
2171     case VhdlDocGen::UCF_CONST:
2172       mm=mdef->name().findRev('_');
2173       if (mm>0)
2174       {
2175         mdef->setName(mdef->name().left(mm));
2176       }
2177       writeUCFLink(mdef,ol);
2178       break;
2179     case VhdlDocGen::SIGNAL:
2180     case VhdlDocGen::ATTRIBUTE:
2181     case VhdlDocGen::SUBTYPE:
2182     case VhdlDocGen::CONSTANT:
2183     case VhdlDocGen::SHAREDVARIABLE:
2184     case VhdlDocGen::VFILE:
2185     case VhdlDocGen::GROUP:
2186       writeLink(mdef,ol);
2187       ol.docify(" ");
2188       ol.insertMemberAlign();
2189       VhdlDocGen::formatString(ltype,ol,mdef);
2190       break;
2191     case VhdlDocGen::TYPE:
2192       bRec=largs.stripPrefix("record") ;
2193       bUnit=largs.stripPrefix("units") ;
2194       ol.startBold();
2195       if (bRec)
2196         ol.docify("record: ");
2197       if (bUnit)
2198         ol.docify("units: ");
2199       writeLink(mdef,ol);
2200       ol.insertMemberAlign();
2201       if (!bRec)
2202         VhdlDocGen::formatString(ltype,ol,mdef);
2203       if (bUnit) ol.lineBreak();
2204       if (bRec || bUnit)
2205         writeRecorUnit(largs,ol,mdef);
2206       ol.endBold();
2207       break;
2208
2209     default: break;
2210   }
2211
2212   bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2213   if (htmlOn && /*Config_getBool("HTML_ALIGN_MEMBERS") &&*/ !ltype.isEmpty())
2214   {
2215     ol.disable(OutputGenerator::Html);
2216   }
2217   if (!ltype.isEmpty()) ol.docify(" ");
2218
2219   if (htmlOn)
2220   {
2221     ol.enable(OutputGenerator::Html);
2222   }
2223
2224   if (!detailsVisible)// && !m_impl->annMemb)
2225   {
2226     ol.endDoxyAnchor(cfname,mdef->anchor());
2227   }
2228
2229   //printf("endMember %s annoClassDef=%p annEnumType=%p\n",
2230   //    name().data(),annoClassDef,annEnumType);
2231   ol.endMemberItem();
2232   if (!mdef->briefDescription().isEmpty() &&   Config_getBool("BRIEF_MEMBER_DESC") /* && !annMemb */)
2233   {
2234     ol.startMemberDescription(mdef->anchor());
2235     ol.parseDoc(mdef->briefFile(),mdef->briefLine(),
2236         mdef->getOuterScope()?mdef->getOuterScope():d,
2237         mdef,mdef->briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
2238     if (detailsVisible)
2239     {
2240       ol.pushGeneratorState();
2241       ol.disableAllBut(OutputGenerator::Html);
2242       //ol.endEmphasis();
2243       ol.docify(" ");
2244       if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
2245       {
2246         ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
2247       }
2248       else // local link
2249       {
2250         ol.startTextLink(0,mdef->anchor());
2251       }
2252       ol.endTextLink();
2253       //ol.startEmphasis();
2254       ol.popGeneratorState();
2255     }
2256     //ol.newParagraph();
2257     ol.endMemberDescription();
2258   }
2259   mdef->warnIfUndocumented();
2260
2261 }// end writeVhdlDeclaration
2262
2263
2264 void VhdlDocGen::writeLink(const MemberDef* mdef,OutputList &ol)
2265 {
2266   ol.writeObjectLink(mdef->getReference(),
2267       mdef->getOutputFileBase(),
2268       mdef->anchor(),
2269       mdef->name());
2270 }
2271
2272 void VhdlDocGen::writePlainVHDLDeclarations(
2273     MemberList* mlist,OutputList &ol,
2274     ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
2275 {
2276
2277   SDict<QCString> pack(1009);
2278
2279   ol.pushGeneratorState();
2280
2281   bool first=TRUE;
2282   MemberDef *md;
2283   MemberListIterator mli(*mlist);
2284   for ( ; (md=mli.current()); ++mli )
2285   {
2286     int mems=md->getMemberSpecifiers();
2287     if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
2288     {
2289       if (first) {ol.startMemberList();first=FALSE;}
2290       VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2291     } //if
2292     else if (md->isBriefSectionVisible() && (mems==specifier))
2293     {
2294       if (!pack.find(md->name().data()))
2295       {
2296         if (first) ol.startMemberList(),first=FALSE;
2297         VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2298         pack.append(md->name().data(),new QCString(md->name().data()));
2299       }
2300     } //if
2301   } //for
2302   if (!first) ol.endMemberList();
2303   pack.clear();
2304 }//plainDeclaration
2305
2306 bool VhdlDocGen::membersHaveSpecificType(MemberList *ml,int type)
2307 {
2308   if (ml==0) return FALSE;
2309   MemberDef *mdd=0;
2310   MemberListIterator mmli(*ml);
2311   for ( ; (mdd=mmli.current()); ++mmli )
2312   {
2313     if (mdd->getMemberSpecifiers()==type) //is type in class
2314     {
2315       return TRUE;
2316     }
2317   }
2318   if (ml->getMemberGroupList())
2319   {
2320     MemberGroupListIterator mgli(*ml->getMemberGroupList());
2321     MemberGroup *mg;
2322     while ((mg=mgli.current()))
2323     {
2324       if (mg->members())
2325       {
2326         if (membersHaveSpecificType(mg->members(),type)) return TRUE;
2327       }
2328       ++mgli;
2329     }
2330   }
2331   return FALSE;
2332 }
2333
2334 void VhdlDocGen::writeVHDLDeclarations(MemberList* ml,OutputList &ol,
2335     ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
2336     const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
2337 {
2338   setGlobalType(ml);
2339   if (!membersHaveSpecificType(ml,type)) return;
2340
2341   if (title)
2342   {
2343     ol.startMemberHeader(title);
2344     ol.parseText(title);
2345     ol.endMemberHeader();
2346     ol.docify(" ");
2347   }
2348   if (subtitle && subtitle[0]!=0)
2349   {
2350     ol.startMemberSubtitle();
2351     ol.parseDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
2352     ol.endMemberSubtitle();
2353   } //printf("memberGroupList=%p\n",memberGroupList);
2354
2355   VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
2356
2357   if (ml->getMemberGroupList())
2358   {
2359     MemberGroupListIterator mgli(*ml->getMemberGroupList());
2360     MemberGroup *mg;
2361     while ((mg=mgli.current()))
2362     {
2363       if (membersHaveSpecificType(mg->members(),type))
2364       {
2365         //printf("mg->header=%s\n",mg->header().data());
2366         bool hasHeader=mg->header()!="[NOHEADER]";
2367         ol.startMemberGroupHeader(hasHeader);
2368         if (hasHeader)
2369         {
2370           ol.parseText(mg->header());
2371         }
2372         ol.endMemberGroupHeader();
2373         if (!mg->documentation().isEmpty())
2374         {
2375           //printf("Member group has docs!\n");
2376           ol.startMemberGroupDocs();
2377           ol.parseDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
2378           ol.endMemberGroupDocs();
2379         }
2380         ol.startMemberGroup();
2381         //printf("--- mg->writePlainDeclarations ---\n");
2382         VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
2383         ol.endMemberGroup(hasHeader);
2384       }
2385       ++mgli;
2386     }
2387   }
2388 }// writeVHDLDeclarations
2389
2390 #if 0
2391 /* strips the prefix for record and unit members*/
2392 void VhdlDocGen::adjustRecordMember(MemberDef *mdef)
2393 { //,OutputList & ol) {
2394   QRegExp regg("[_a-zA-Z\"]");
2395   QCString nn=mdef->name();
2396   int j=nn.find(regg,0);
2397   if (j>0)
2398   {
2399     nn=nn.mid(j,nn.length());
2400     mdef->setName(nn.data());
2401   }
2402 }//adjustRecordMember
2403 #endif
2404 /* strips the prefix for package and package body */
2405
2406 bool VhdlDocGen::writeClassType( ClassDef *& cd,
2407     OutputList &ol ,QCString & cname)
2408 {
2409   //static ClassDef *prev = 0;
2410   //if (prev == cd)  return TRUE;
2411   //if (cd != prev) prev=cd;
2412
2413   int id=cd->protection();
2414   QCString qcs = VhdlDocGen::trTypeString(id+2);
2415   cname=VhdlDocGen::getClassName(cd);
2416   ol.startBold();
2417   ol.writeString(qcs.data());
2418   ol.writeString(" ");
2419   ol.endBold();
2420   //ol.insertMemberAlign();
2421   return FALSE;
2422 }// writeClassLink
2423
2424 QCString VhdlDocGen::trVhdlType(int type,bool sing)
2425 {
2426   switch(type)
2427   {
2428     case VhdlDocGen::LIBRARY:
2429       if (sing) return "Library";
2430       else      return "Libraries";
2431     case VhdlDocGen::PACKAGE:
2432       if (sing) return "Package";
2433       else      return "Packages";
2434     case VhdlDocGen::SIGNAL:
2435       if (sing) return "Signal";
2436       else      return "Signals";
2437     case VhdlDocGen::COMPONENT:
2438       if (sing) return "Component";
2439       else      return "Components";
2440     case VhdlDocGen::CONSTANT:
2441       if (sing) return "Constant";
2442       else      return "Constants";
2443     case VhdlDocGen::ENTITY:
2444       if (sing) return "Entity";
2445       else      return "Entities";
2446     case VhdlDocGen::TYPE:
2447       if (sing) return "Type";
2448       else      return "Types";
2449     case VhdlDocGen::SUBTYPE:
2450       if (sing) return "Subtype";
2451       else      return "Subtypes";
2452     case VhdlDocGen::FUNCTION:
2453       if (sing) return "Function";
2454       else      return "Functions";
2455     case VhdlDocGen::RECORD:
2456       if (sing) return "Record";
2457       else      return "Records";
2458     case VhdlDocGen::PROCEDURE:
2459       if (sing) return "Procedure";
2460       else      return "Procedures";
2461     case VhdlDocGen::ARCHITECTURE:
2462       if (sing) return "Architecture";
2463       else      return "Architectures";
2464     case VhdlDocGen::ATTRIBUTE:
2465       if (sing) return "Attribute";
2466       else      return "Attributes";
2467     case VhdlDocGen::PROCESS:
2468       if (sing) return "Process";
2469       else      return "Processes";
2470     case VhdlDocGen::PORT:
2471       if (sing) return "Port";
2472       else      return "Ports";
2473     case VhdlDocGen::USE:
2474       if (sing) return "use clause";
2475       else      return "Use Clauses";
2476     case VhdlDocGen::GENERIC:
2477       if (sing) return "Generic";
2478       else      return "Generics";
2479     case VhdlDocGen::PACKAGE_BODY:
2480       return "Package Body";
2481     case VhdlDocGen::UNITS:
2482       return "Units";
2483     case VhdlDocGen::SHAREDVARIABLE:
2484       if (sing) return "Shared Variable";
2485       return "Shared Variables";
2486     case VhdlDocGen::VFILE:
2487       if (sing) return "File";
2488       return "Files";
2489     case VhdlDocGen::GROUP:
2490       if (sing) return "Group";
2491       return "Groups";
2492     case VhdlDocGen::INSTANTIATION:
2493       if (sing) return "Instantiation";
2494       else      return "Instantiations";
2495     case VhdlDocGen::ALIAS:
2496       if (sing) return "Alias";
2497       return "Aliases";
2498     case VhdlDocGen::CONFIG:
2499       if (sing) return "Configuration";
2500       return "Configurations";
2501     case VhdlDocGen::MISCELLANEOUS:
2502       return "Miscellaneous";
2503     case VhdlDocGen::UCF_CONST:
2504       return "Constraints";
2505     default:
2506       return "Class";
2507   }
2508 }
2509
2510 QCString VhdlDocGen::trDesignUnitHierarchy()
2511 {
2512   return "Design Unit Hierarchy";
2513 }
2514
2515 QCString VhdlDocGen::trDesignUnitList()
2516 {
2517   return "Design Unit List";
2518 }
2519
2520 QCString VhdlDocGen::trDesignUnitMembers()
2521 {
2522   return "Design Unit Members";
2523 }
2524
2525 QCString VhdlDocGen::trDesignUnitListDescription()
2526 {
2527   return "Here is a list of all design unit members with links to "
2528     "the Entities  they belong to:";
2529 }
2530
2531 QCString VhdlDocGen::trDesignUnitIndex()
2532 {
2533   return "Design Unit Index";
2534 }
2535
2536 QCString VhdlDocGen::trDesignUnits()
2537 {
2538   return "Design Units";
2539 }
2540
2541 QCString VhdlDocGen::trFunctionAndProc()
2542 {
2543   return "Functions/Procedures/Processes";
2544 }
2545
2546
2547
2548
2549
2550 /* do not insert the same component twice */
2551
2552 bool VhdlDocGen::foundInsertedComponent(const QCString & name,Entry* root)
2553 {
2554   QListIterator<BaseInfo> bii(*root->extends);
2555   BaseInfo *bi=0;
2556   for (bii.toFirst();(bi=bii.current());++bii)
2557   {
2558     if (bi->name==name)
2559     {
2560       return TRUE; //
2561     }
2562   }
2563
2564   return FALSE;
2565 }// found component
2566
2567 /*! writes a link if the string is linkable else a formatted string */
2568
2569 void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
2570 {
2571   if (mdef)
2572   {
2573     ClassDef *cd=mdef->getClassDef();
2574     if (cd)
2575     {
2576       QCString n=cd->name();
2577       MemberDef* memdef=VhdlDocGen::findMember(n,mem);
2578       if (memdef && memdef->isLinkable())
2579       {
2580         ol.startBold();
2581         writeLink(memdef,ol);
2582         ol.endBold();
2583         ol.docify(" ");
2584         return;
2585       }
2586     }
2587   }
2588   VhdlDocGen::startFonts(mem,"vhdlchar",ol);
2589 }// found component
2590
2591 void VhdlDocGen::writeCodeFragment( MemberDef *mdef,OutputList& ol)
2592 {
2593   //  Definition d=(Definition)mdef;
2594   //    QCString fdd=mdef->getDefFileExtension();
2595   //    QCString scope=mdef->getScopeString();
2596   QCString codeFragment=mdef->documentation();
2597   //FileDef *fd=mdef->getFileDef();
2598
2599   //int start=mdef->getStartBodyLine();
2600   //int end=mdef->getEndBodyLine();
2601   QStringList qsl=QStringList::split("\n",codeFragment);
2602   writeLink(mdef,ol);
2603   ol.docify(" ");
2604   ol.insertMemberAlign();
2605   int len= qsl.count();
2606   for(int j=0;j<len;j++)
2607   {
2608     QCString q=qsl[j].utf8();
2609     VhdlDocGen::writeFormatString(q,ol,mdef);
2610     ol.lineBreak();
2611     if (j==2) // only the first three lines are shown
2612     {
2613       q = "...";
2614       VhdlDocGen::writeFormatString(q,ol,mdef);
2615       break;
2616     }
2617   }
2618 }
2619
2620 void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
2621 {
2622   QCString codeFragment=mdef->documentation();
2623   int start=mdef->getStartBodyLine();
2624   QStringList qsl=QStringList::split("\n",codeFragment);
2625   ol.startCodeFragment();
2626   int len = qsl.count();
2627   QCString lineNumber;
2628   int j;
2629   for (j=0;j<len;j++)
2630   {
2631     lineNumber.sprintf("%05d",start++);
2632     lineNumber+=" ";
2633     ol.startBold();
2634     ol.docify(lineNumber.data());
2635     ol.endBold();
2636     ol.insertMemberAlign();
2637     QCString q=qsl[j].utf8();
2638     VhdlDocGen::writeFormatString(q,ol,mdef);
2639     ol.lineBreak();
2640   }
2641   ol.endCodeFragment();
2642
2643   mdef->writeSourceDef(ol,cname);
2644   mdef->writeSourceRefs(ol,cname);
2645   mdef->writeSourceReffedBy(ol,cname);
2646 }
2647
2648
2649 QCString VhdlDocGen::convertFileNameToClassName(QCString name)
2650 {
2651
2652   QCString n=name;
2653   n=n.remove(0,6);
2654
2655   int i=0;
2656
2657   while((i=n.find("__"))>0)
2658   {
2659     n=n.remove(i,1);
2660   }
2661
2662   while((i=n.find("_1"))>0)
2663   {
2664     n=n.replace(i,2,":");
2665   }
2666
2667   return n;
2668 }
2669
2670 void VhdlDocGen::parseUCF(const char*  input,  Entry* entity,QCString fileName,bool altera)
2671 {
2672   QCString ucFile(input);
2673   int lineNo=0;
2674   QCString newLine="\n";
2675   QCString comment("#!");
2676   QCString brief;
2677
2678   while(!ucFile.isEmpty())
2679   {
2680     int i=ucFile.find("\n");
2681     if (i<0) break;
2682     lineNo++;
2683     QCString temp=ucFile.left(i);
2684     temp=temp.stripWhiteSpace();
2685     bool bb=temp.stripPrefix("//");
2686
2687     if (!temp.isEmpty())
2688     {
2689       if (temp.stripPrefix(comment) )
2690       {
2691         brief+=temp;
2692         brief.append("\\n");
2693       }
2694       else if (!temp.stripPrefix("#") && !bb)
2695       {
2696         if (altera)
2697         {
2698           int i=temp.find("-name");
2699           if (i>0)
2700             temp=temp.remove(0,i+5);
2701
2702           temp.stripPrefix("set_location_assignment");
2703
2704           initUCF(entity,0,temp,lineNo,fileName,brief);
2705         }
2706         else
2707         {
2708           QRegExp ee("[\\s=]");
2709           int i=temp.find(ee);
2710           QCString ff=temp.left(i);
2711           temp.stripPrefix(ff.data());
2712           ff.append("#");
2713           if (!temp.isEmpty())
2714           {
2715             initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
2716           }
2717         }
2718       }
2719     }//temp
2720
2721     ucFile=ucFile.remove(0,i+1);
2722   }// while
2723 }
2724
2725 static void initUCF(Entry* root,const char*  type,QCString &  qcs,int line,QCString & fileName,QCString & brief)
2726 {
2727   if (qcs.isEmpty())return;
2728   QRegExp sp("\\s");
2729   QRegExp reg("[\\s=]");
2730   QCString n;
2731   // bool bo=(stricmp(type,qcs.data())==0);
2732
2733   VhdlDocGen::deleteAllChars(qcs,';');
2734   qcs=qcs.stripWhiteSpace();
2735
2736   int i= qcs.find(reg);
2737   if (i<0) return;
2738   if (i==0)
2739   {
2740     n=type;
2741     VhdlDocGen::deleteAllChars(n,'#');
2742     type="";
2743   }
2744   else
2745   {
2746     n=qcs.left(i);
2747   }
2748   qcs=qcs.remove(0,i+1);
2749   //  qcs.prepend("|");
2750
2751   qcs.stripPrefix("=");
2752
2753   Entry* current=new Entry;
2754   current->spec=VhdlDocGen::UCF_CONST;
2755   current->section=Entry::VARIABLE_SEC;
2756   current->bodyLine=line;
2757   current->fileName=fileName;
2758   current->type="ucf_const";
2759   //if (!bo)
2760   //current->args=type;
2761   current->args+=qcs;
2762   current->lang=  SrcLangExt_VHDL ;
2763
2764   // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2765   if (n.isEmpty())
2766   {
2767     n="dummy";
2768     n+=VhdlDocGen::getRecordNumber();
2769   }
2770
2771   current->name= n+"_";
2772   current->name.append(VhdlDocGen::getRecordNumber().data());
2773
2774   if (!brief.isEmpty())
2775   {
2776     current->brief=brief;
2777     current->briefLine=line;
2778     current->briefFile=fileName;
2779     brief.resize(0);
2780   }
2781
2782   root->addSubEntry(current);
2783 }
2784
2785
2786 static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2787 {
2788
2789   QCString largs(mdef->argsString());
2790   QCString n= VhdlDocGen::splitString(largs, '#');
2791   // VhdlDocGen::adjustRecordMember(mdef);
2792   bool equ=(n.length()==largs.length());
2793
2794   if (!equ)
2795   {
2796     ol.writeString(n.data());
2797     ol.docify(" ");
2798     ol.insertMemberAlign();
2799   }
2800
2801   if (mdef->name().contains("dummy")==0)
2802     VhdlDocGen::writeLink(mdef,ol);
2803   if (equ)
2804     ol.insertMemberAlign();
2805   ol.docify(" ");
2806   VhdlDocGen::formatString(largs,ol,mdef);
2807 }
2808
2809 QCString VhdlDocGen::splitString(QCString& str,  char c)
2810 {
2811   QCString n=str;
2812   int i=str.find(c);
2813   if (i>0)
2814   {
2815     n=str.left(i);
2816     str=str.remove(0,i+1);
2817   }
2818   return n;
2819 }
2820
2821 bool VhdlDocGen::findConstraintFile(LayoutNavEntry *lne)
2822 {
2823   FileName *fn=Doxygen::inputNameList->first();
2824   //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
2825
2826   LayoutNavEntry *kk = lne->parent();//   find(LayoutNavEntry::Files);
2827   // LayoutNavEntry *kks = kk->parent();//   find(LayoutNavEntry::Files);
2828   QCString file;
2829   QCString co("Constraints");
2830
2831   if (Config_getBool("HAVE_DOT") && Config_getEnum("DOT_IMAGE_FORMAT")=="svg")
2832   {
2833      QCString ov = theTranslator->trDesignOverview();
2834      QCString ofile("vhdl_design_overview");
2835      LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,true,ofile,ov,"");  
2836      kk->addChild(oo); 
2837   }
2838
2839   while (fn)
2840   {
2841     FileDef *fd=fn->first();
2842     if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
2843     {
2844       file = convertNameToFile(fd->name().data(),FALSE,FALSE);
2845       LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
2846       kk->addChild(ucf);
2847       break;
2848     }
2849     fn=Doxygen::inputNameList->next();
2850   }
2851   return  FALSE;
2852 }
2853
2854 void VhdlDocGen::writeAlphbeticalClass(OutputList& ol,const ClassDef* cd,const QCString & cname)
2855 {
2856   if (cname.contains("::")==0)
2857   {
2858     ClassDef*oo=        VhdlDocGen::findArchitecture(cd);
2859     ol.writeObjectLink(cd->getReference(),
2860         cd->getOutputFileBase(),0,cname);
2861     if (oo)
2862     {
2863       ol.docify(" [");
2864       ol.writeObjectLink(oo->getReference(),
2865           oo->getOutputFileBase(),0,"arch");
2866       ol.docify("] ");
2867     }
2868   }
2869 }
2870
2871
2872
2873
2874 //        for cell_inst : [entity] work.proto [ (label|expr) ]
2875 QCString  VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
2876 {
2877   int index;
2878   QCString label;
2879   QCString ent("entity");
2880   if (!entity.contains(":")) return "";
2881
2882   QRegExp exp("[:()\\s]");
2883   QStringList ql=QStringList::split(exp,entity,FALSE);
2884   //int ii=ql.findIndex(ent);
2885   assert(ql.count()>=2);
2886   label = ql[0].utf8();
2887   entity = ql[1].utf8();
2888   if ((index=entity.findRev("."))>=0)
2889   {
2890     entity.remove(0,index+1);
2891   }
2892
2893   if (ql.count()==3)
2894   {
2895     arch= ql[2].utf8();
2896     ql=QStringList::split(exp,arch,FALSE);
2897     if (ql.count()>1) // expression
2898       arch="";
2899   }
2900   return label; // label
2901 }
2902
2903
2904 //        use (configuration|entity|open) work.test [(cellfor)];
2905
2906 QCString  VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
2907 {
2908   int index;
2909   QRegExp exp("[()\\s]");
2910
2911   QCString label="";
2912   QStringList ql=QStringList::split(exp,entity,FALSE);
2913
2914   if (ql.contains("open"))
2915     return "open";
2916
2917   label=ql[0].utf8();
2918
2919   entity = ql[1].utf8();
2920   if ((index=entity.findRev("."))>=0)
2921     entity.remove(0,index+1);
2922
2923   if (ql.count()==3)
2924     arch=ql[2].utf8();
2925   return label;
2926 }
2927
2928 ClassDef*  VhdlDocGen::findArchitecture(QCString identifier, QCString entity_name)
2929 {
2930   QCString archName=entity_name+"::"+identifier;
2931   return  Doxygen::classSDict->find(archName.data());
2932 }
2933
2934
2935 //@param arch bit0:flipflop
2936 //@param binding  e.g entity work.foo(bar)
2937 //@param label  |label0|label1
2938 //                          label0:architecture name
2939 //@param confVhdl of configuration file (identifier::entity_name) or
2940 //               the architecture if isInlineConf TRUE
2941 //@param isInlineConf
2942 //@param confN List of configurations
2943
2944 void assignBinding(VhdlConfNode * conf,QCString label)
2945 {
2946   QList<Entry> instList= getVhdlInstList();
2947   QListIterator<Entry> eli(instList);
2948   Entry *cur;
2949   ClassDef *archClass;
2950   QCString archName,entityName;
2951   bool allOthers=FALSE;
2952
2953   if (conf->isInlineConf)
2954   {
2955     archClass=Doxygen::classSDict->find(conf->confVhdl.data());
2956   }
2957   else
2958   {
2959     archName= VhdlDocGen::getIndexWord(label.data(),0);
2960     entityName= VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2961     archClass=VhdlDocGen::findArchitecture(archName,entityName);
2962   }
2963
2964   if (!archClass)
2965   {
2966     fprintf(stderr,"\n architecture %s not found ! ",conf->confVhdl.data());
2967     return;
2968   }
2969
2970   archName=archClass->name();
2971
2972   QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
2973
2974   if (allOt=="all" || allOt=="others")
2975     allOthers=TRUE;
2976
2977   for (;(cur=eli.current());++eli)
2978   {
2979     if (conf->isInlineConf &&  (conf->confVhdl!=cur->args))
2980       continue;
2981
2982     if (!conf->isInlineConf &&  (archName!=cur->args))
2983       continue;
2984
2985     if (cur->exception==label || conf->isInlineConf)
2986     {
2987       QCString sign,archy;
2988
2989       if (allOthers==FALSE)
2990       {
2991         archy=conf->arch;
2992         sign=cur->name+":"+cur->type;
2993       }
2994       else
2995       {
2996         sign=cur->type;
2997         archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
2998       }
2999
3000
3001       if (archy==sign && !cur->stat)
3002       {
3003         // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
3004         QCString ent1=conf->binding;
3005         QCString arch1;
3006         QCString rr=VhdlDocGen::parseForBinding(ent1,arch1);
3007         arch1=ent1+"::"+arch1;
3008         //ClassDef *archBind=Doxygen::classSDict->find(arch1.data());
3009         ClassDef *ent=Doxygen::classSDict->find(ent1.data());
3010         QCString          inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
3011         ClassDef *cd=Doxygen::classSDict->find(inst.data());
3012
3013         if (cd==0 || ent==0)
3014           continue;
3015
3016         addInstance(ent,archClass,cd,cur);
3017         cur->stat=TRUE;
3018       }
3019     }
3020   }//for
3021 }//assignBinding
3022
3023
3024 void assignConfiguration(VhdlConfNode* rootNode,QCString label)
3025 {
3026   if (rootNode==NULL) return;
3027   uint iter;
3028
3029   if (!rootNode->isBinding())
3030   {
3031     //   printf("\n ARCH %s  BIND %s \n",rootNode->arch.data(),rootNode->binding.data());
3032     assignBinding(rootNode,label);
3033     return;
3034   }
3035   else
3036     label+="|"+rootNode->arch;
3037
3038
3039   for(iter=0;iter<rootNode->confN.count();iter++)
3040   {
3041     VhdlConfNode* conf= (VhdlConfNode *)rootNode->confN.at(iter);
3042     assignConfiguration(conf,label);
3043   }
3044 }
3045
3046 /*
3047
3048 // file foo.vhd
3049 // enitity foo
3050 //        .....
3051 // end entity
3052
3053 // file foo_arch.vhd
3054 // architecture xxx of foo is
3055 //          ........
3056 //  end architecture
3057
3058  */
3059 void VhdlDocGen::computeVhdlComponentRelations()
3060 {
3061
3062   QCString entity,inst,arch,vhd;
3063
3064   QList<VhdlConfNode> confList =  getVhdlConfiguration();
3065   for (uint iter=0;iter<confList.count(); iter++)
3066   {
3067     VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
3068     assignConfiguration(conf,"");
3069   }
3070
3071   QList<Entry> qsl= getVhdlInstList();
3072   QListIterator<Entry> eli(qsl);
3073   Entry *cur;
3074
3075   for (eli.toFirst();(cur=eli.current());++eli)
3076   {
3077     if (cur->stat ) //  was bind
3078       continue;
3079
3080     if (cur->includeName=="entity" || cur->includeName=="component" )
3081     {
3082       entity=cur->includeName+" "+cur->type;
3083       QCString rr=VhdlDocGen::parseForBinding(entity,arch);
3084     }
3085     else if (cur->includeName.isEmpty())
3086     {
3087       entity=cur->type;
3088     }
3089     ClassDef *classEntity=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);
3093
3094     if (cd==0 || classEntity==0 )
3095       continue;
3096
3097     addInstance(classEntity,ar,cd,cur);
3098
3099   }
3100 }
3101
3102 static void addInstance(ClassDef* classEntity, ClassDef* ar,
3103                         ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
3104 {
3105   if (classEntity==cd) return;
3106
3107   QCString bName=classEntity->name();
3108   //printf("addInstance %s to %s\n", cd->name().data(), classEntity->name().data());
3109   QCString n1=cur->type;
3110
3111   if (!cd->isBaseClass(classEntity, true, 0))
3112   {
3113     cd->insertBaseClass(classEntity,n1,Public,Normal,0);
3114   }
3115   else
3116   {
3117     VhdlDocGen::addBaseClass(cd,classEntity);
3118   }
3119
3120   if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
3121   {
3122     classEntity->insertSubClass(cd,Public,Normal,0);
3123   }
3124
3125   if (ar==0) return;
3126
3127   QCString uu=cur->name;
3128   MemberDef *md=new MemberDef(
3129       ar->getDefFileName(), cur->startLine,
3130       cur->type,uu,uu, 0,
3131       Public, Normal, cur->stat,Member,
3132       MemberDef::Variable,
3133       0,
3134       0);
3135
3136   if (ar->getOutputFileBase()) 
3137   {
3138     TagInfo tg;
3139     tg.anchor = 0;
3140     tg.fileName = ar->getOutputFileBase();
3141     tg.tagName = 0;
3142     md->setTagInfo(&tg);
3143   }
3144
3145   //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
3146
3147   md->setLanguage(SrcLangExt_VHDL);
3148   md->setMemberSpecifiers(VhdlDocGen::INSTANTIATION);
3149   md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
3150   md->setBodySegment(cur->startLine,-1) ;
3151   md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine); 
3152   FileDef *fd=ar->getFileDef();
3153   md->setBodyDef(fd);
3154   ar->insertMember(md);
3155   //    printf("\nMemberreference [%p]",md);
3156 }
3157
3158
3159 void  VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
3160 {
3161   QStringList ql=QStringList::split("#",largs,FALSE);
3162   uint len=ql.count();
3163   for(uint i=0;i<len;i++)
3164   {
3165     QCString n=ql[i].utf8();
3166     VhdlDocGen::formatString(n,ol,mdef);
3167     if ((len-i)>1) ol.lineBreak();
3168   }
3169 }
3170
3171
3172 void VhdlDocGen::writeRecUnitDocu(
3173     const MemberDef *md,
3174     OutputList& ol,
3175     QCString largs
3176     )
3177 {
3178
3179   QStringList ql=QStringList::split("#",largs,FALSE);
3180   uint len=ql.count();
3181   ol.startParameterList(TRUE);
3182   bool first=TRUE;
3183   for(uint i=0;i<len;i++)
3184   {
3185     QCString n=ql[i].utf8();
3186     ol.startParameterType(first,"");
3187     VhdlDocGen::formatString(n,ol,md);
3188     if ((len-i)>1)
3189     {
3190       ol.endParameterName(FALSE,FALSE,FALSE);
3191     }
3192     else
3193     {
3194       ol.endParameterName(TRUE,FALSE,TRUE);
3195     }
3196
3197     first=FALSE;
3198   }
3199 }//#
3200
3201 void VhdlDocGen::writeCodeFragment(OutputList& ol,int start, QCString & codeFragment,const MemberDef* mdef)
3202 {
3203   QStringList qsl=QStringList::split("\n",codeFragment);
3204   ol.startCodeFragment();
3205   int len = qsl.count();
3206   QCString lineNumber;
3207   int j;
3208   for (j=0;j<len;j++)
3209   {
3210     lineNumber.sprintf("%05d",start++);
3211     lineNumber+=" ";
3212     ol.startBold();
3213     ol.docify(lineNumber.data());
3214     ol.endBold();
3215     ol.insertMemberAlign();
3216     QCString q=qsl[j].utf8();
3217     VhdlDocGen::writeFormatString(q,ol,mdef);
3218     ol.docify("\n");
3219   }
3220   ol.endCodeFragment();
3221 }
3222
3223 bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
3224 {
3225   bool found=FALSE;
3226   //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3227   if (level>255)
3228   {
3229     err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
3230     abort();
3231     return FALSE;
3232   }
3233
3234   if (cd->subClasses())
3235   {
3236     // Beware: trying to optimise the iterator away using ->first() & ->next()
3237     // causes bug 625531
3238     BaseClassListIterator bcli(*cd->subClasses());
3239     for ( ; bcli.current() && !found ; ++bcli)
3240     {
3241       ClassDef *ccd=bcli.current()->classDef;
3242       if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3243       //printf("isSubClass() subclass %s\n",ccd->name().data());
3244       if (ccd==scd)
3245       {
3246         found=TRUE;
3247       }
3248       else 
3249       {
3250         if (level <256)
3251         {
3252           found=ccd->isBaseClass(scd,followInstances,level+1);
3253         }
3254       }
3255     }
3256   }
3257   return found;
3258 }
3259
3260 void VhdlDocGen::addBaseClass(ClassDef* cd,ClassDef *ent)
3261 {
3262   if (cd->baseClasses())
3263   {
3264     BaseClassListIterator bcli(*cd->baseClasses());
3265     for ( ; bcli.current()  ; ++bcli)
3266     {
3267       ClassDef *ccd=bcli.current()->classDef;
3268       if (ccd==ent) 
3269       {
3270         QCString n = bcli.current()->usedName;
3271         int i = n.find('(');
3272         if(i<0)
3273         {
3274           bcli.current()->usedName.append("(2)");
3275           return;
3276         }
3277         static QRegExp reg("[0-9]+");
3278         QCString s=n.left(i);
3279         QCString r=n.right(n.length()-i);
3280         QCString t=r;
3281         VhdlDocGen::deleteAllChars(r,')');
3282         VhdlDocGen::deleteAllChars(r,'(');
3283         r.setNum(r.toInt()+1);
3284         t.replace(reg,r.data());
3285         s.append(t.data());
3286         bcli.current()->usedName=s;
3287         bcli.current()->templSpecifiers=t;
3288       }
3289     }
3290   }
3291 }
3292