My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vhdldocgen.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 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/2008
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 <qmap.h>
31 
32 /* --------------------------------------------------------------- */
33 
34 // local includes
35 #include "vhdldocgen.h"
36 #include "message.h"
37 #include "config.h"
38 #include "doxygen.h"
39 #include "util.h"
40 #include "language.h"
41 #include "commentscan.h"
42 #include "index.h"
43 #include "definition.h"
44 #include "searchindex.h"
45 #include "outputlist.h"
46 #include "parserintf.h"
47 #include "layout.h"
48 #include "arguments.h"
49 #include "portable.h"
50 #include "memberlist.h"
51 #include "memberdef.h"
52 #include "groupdef.h"
53 #include "classlist.h"
54 #include "namespacedef.h"
55 #include "filename.h"
56 #include "membergroup.h"
57 #include "memberdef.h"
58 #include "plantuml.h"
59 #include "vhdljjparser.h"
60 #include "VhdlParser.h"
61 #include "vhdlcode.h"
62 #include "plantuml.h"
63 //#define DEBUGFLOW
64 #define theTranslator_vhdlType VhdlDocGen::trVhdlType
65 
66 static QDict<QCString> g_vhdlKeyDict0(17,FALSE);
67 static QDict<QCString> g_vhdlKeyDict1(17,FALSE);
68 static QDict<QCString> g_vhdlKeyDict2(17,FALSE);
69 static QDict<QCString> g_vhdlKeyDict3(17,FALSE);
70 
71 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief);
72 static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
73 static void assignBinding(VhdlConfNode* conf);
74 static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst,Entry *cur,ClassDef* archBind=NULL);
75 
76 //---------- create svg -------------------------------------------------------------
77 static void createSVG();
78 static void startDot(FTextStream &t);
79 static void startTable(FTextStream &t,const QCString &className);
80 static QList<MemberDef>* getPorts(ClassDef *cd);
81 static void writeVhdlEntityToolTip(FTextStream& t,ClassDef *cd);
82 static void endDot(FTextStream &t);
83 static void writeTable(QList<MemberDef>* port,FTextStream & t);
84 static void endTabel(FTextStream &t);
85 static void writeClassToDot(FTextStream &t,ClassDef* cd);
86 static void writeVhdlDotLink(FTextStream &t,const QCString &a,const QCString &b,const QCString &style);
87 //static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd);
88 static const MemberDef *flowMember=0;
89 
91 {
92  flowMember=mem;
93 }
94 
96 {
97  return flowMember;
98 }
99 
100 
101 
102 //--------------------------------------------------------------------------------------------------
103 static void codify(FTextStream &t,const char *str)
104 {
105  if (str)
106  {
107  const char *p=str;
108  char c;
109  while (*p)
110  {
111  c=*p++;
112  switch(c)
113  {
114  case '<': t << "&lt;";
115  break;
116  case '>': t << "&gt;";
117  break;
118  case '&': t << "&amp;";
119  break;
120  case '\'': t << "&#39;";
121  break;
122  case '"': t << "&quot;";
123  break;
124  default: t << c;
125  break;
126  }
127  }
128  }
129 }
130 
131 static void writeLink(const MemberDef* mdef,OutputList &ol)
132 {
133  ol.writeObjectLink(mdef->getReference(),
134  mdef->getOutputFileBase(),
135  mdef->anchor(),
136  mdef->name());
137 }
138 
139 static void startFonts(const QCString& q, const char *keyword,OutputList& ol)
140 {
141  ol.startFontClass(keyword);
142  ol.docify(q.data());
143  ol.endFontClass();
144 }
145 
146 static QCString splitString(QCString& str,char c)
147 {
148  QCString n=str;
149  int i=str.find(c);
150  if (i>0)
151  {
152  n=str.left(i);
153  str=str.remove(0,i+1);
154  }
155  return n;
156 }
157 
158 static int compareString(const QCString& s1,const QCString& s2)
159 {
160  return qstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
161 }
162 
163 static void createSVG()
164 {
165  QCString ov =Config_getString(HTML_OUTPUT);
166  QCString dir="-o \""+ov+"/vhdl_design_overview.html\"";
167  ov+="/vhdl_design.dot";
168 
169  QCString vlargs="-Tsvg \""+ov+"\" "+dir ;
170 
171  if (portable_system("dot",vlargs)!=0)
172  {
173  err("could not create dot file");
174  }
175 }
176 
177 // Creates a svg image. All in/out/inout ports are shown with brief description and direction.
178 // Brief descriptions for entities are shown too.
180 {
182  ClassDef *cd;
183  bool found=FALSE;
184  for ( ; (cd=cli.current()) ; ++cli )
185  {
187  {
188  found=TRUE;
189  break;
190  }
191  }
192 
193  if (!found) return;
194 
195  QCString ov =Config_getString(HTML_OUTPUT);
196  QCString fileName=ov+"/vhdl_design.dot";
197  QFile f(fileName);
198  FTextStream t(&f);
199 
200  if (!f.open(IO_WriteOnly))
201  {
202  fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
203  return;
204  }
205 
206  startDot(t);
207 
208  for (cli.toFirst() ; (cd=cli.current()) ; ++cli )
209  {
211  {
212  continue;
213  }
214 
215  QList<MemberDef>* port= getPorts(cd);
216  if (port==0)
217  {
218  continue;
219  }
220  if (port->count()==0)
221  {
222  delete port;
223  port=NULL;
224  continue;
225  }
226 
227  startTable(t,cd->name());
228  writeClassToDot(t,cd);
229  writeTable(port,t);
230  endTabel(t);
231 
232  // writeVhdlPortToolTip(t,port,cd);
234  delete port;
235 
236  BaseClassList *bl=cd->baseClasses();
237  if (bl)
238  {
239  BaseClassListIterator bcli(*bl);
240  BaseClassDef *bcd;
241  for ( ; (bcd=bcli.current()) ; ++bcli )
242  {
243  ClassDef *bClass=bcd->classDef;
244  QCString dotn=cd->name()+":";
245  dotn+=cd->name();
246  QCString csc=bClass->name()+":";
247  csc+=bClass->name();
248  // fprintf(stderr,"\n <%s| %s>",dotn.data(),csc.data());
249  writeVhdlDotLink(t,dotn,csc,0);
250  }
251  }// if bl
252  }// for
253 
254  endDot(t);
255  // writePortLinks(t);
256  f.close();
257  createSVG();
258 }
259 
260 //------------------------------------------------------------------------------------------------------------------------------------------------------
261 
262 static void startDot(FTextStream &t)
263 {
264  t << " digraph G { \n";
265  t << "rankdir=LR \n";
266  t << "concentrate=TRUE\n";
267  t << "stylesheet=\"doxygen.css\"\n";
268 }
269 
270 static void endDot(FTextStream &t)
271 {
272  t <<" } \n";
273 }
274 
275 static void startTable(FTextStream &t,const QCString &className)
276 {
277  t << className <<" [ shape=none , fontname=\"arial\", fontcolor=\"blue\" , \n";
278  t << "label=<<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n";
279 }
280 
282  const QCString &a,const QCString &b,const QCString &style)
283 {
284  t << a << "->" << b;
285  if (!style.isEmpty())
286  {
287  t << "[style=" << style << "];\n";
288  }
289  t << "\n";
290 }
291 
292 
293 static QCString formatBriefNote(const QCString &brief,ClassDef * cd)
294 {
295  QRegExp ep("[\n]");
296  QCString vForm;
297  QCString repl("<BR ALIGN=\"LEFT\"/>");
298  QCString file=cd->getDefFileName();
299 
300  int k=cd->briefLine();
301 
302  QStringList qsl=QStringList::split(ep,brief);
303  for(uint j=0;j<qsl.count();j++)
304  {
305  QCString qcs=qsl[j].data();
306  vForm+=parseCommentAsText(cd,NULL,qcs,file,k);
307  k++;
308  vForm+='\n';
309  }
310 
311  vForm.replace(ep,repl.data());
312  return vForm;
313 }
314 
315 #if 0
316 static void writeVhdlPortToolTip(FTextStream& t,QList<MemberDef>* port,ClassDef *cd)
317 {
318 /*
319  uint len=port->count();
320  MemberDef *md;
321 
322  for (uint j=0;j<len;j++)
323  {
324  md=(MemberDef*)port->at(j);
325  QCString brief=md->briefDescriptionAsTooltip();
326  if (brief.isEmpty()) continue;
327 
328  QCString node="node";
329  node+=VhdlDocGen::getRecordNumber();
330  t << node <<"[shape=box margin=0.1, label=<\n";
331  t<<"<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
332  t<<"<TR><TD BGCOLOR=\"lightcyan\"> ";
333  t<<brief;
334  t<<" </TD></TR></TABLE>>];";
335  QCString dotn=cd->name()+":";
336  dotn+=md->name();
337  // writeVhdlDotLink(t,dotn,node,"dotted");
338  }
339 */
340 }
341 #endif
342 
344 {
345 
346  QCString brief=cd->briefDescription();
347 
348  if (brief.isEmpty()) return;
349 
350  brief=formatBriefNote(brief,cd);
351 
352  QCString node="node";
354  t << node <<"[shape=none margin=0.1, label=<\n";
355  t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
356  t << "<TR><TD BGCOLOR=\"lightcyan\"> ";
357  t << brief;
358  t << " </TD></TR></TABLE>>];";
359  QCString dotn=cd->name()+":";
360  dotn+=cd->name();
361  writeVhdlDotLink(t,dotn,node,"dotted");
362 }
363 
364 static void writeColumn(FTextStream &t,MemberDef *md,bool start)
365 {
366  QCString toolTip;
367 
368  static QRegExp reg("[%]");
369  bool bidir=(md!=0 &&( qstricmp(md->typeString(),"inout")==0));
370 
371  if (md)
372  {
373  toolTip=md->briefDescriptionAsTooltip();
374  if (!toolTip.isEmpty())
375  {
376  QCString largs = md->argsString();
377  if (!largs.isEmpty())
378  largs=largs.replace(reg," ");
379  toolTip+=" [";
380  toolTip+=largs;
381  toolTip+="]";
382  }
383  }
384  if (start)
385  {
386  t <<"<TR>\n";
387  }
388 
389  t << "<TD ALIGN=\"LEFT\" ";
390  if (md)
391  {
392  t << "href=\"";
394  t << "#" << md->anchor();
395  t<<"\" ";
396 
397  t<<" TOOLTIP=\"";
398  if (!toolTip.isEmpty())
399  {
400  codify(t,toolTip.data());
401  }
402  else
403  {
404  QCString largs = md->argsString();
405  if (!largs.isEmpty())
406  {
407  largs=largs.replace(reg," ");
408  codify(t,largs.data());
409  }
410  }
411  t << "\" ";
412 
413  t << " PORT=\"";
414  t << md->name();
415  t << "\" ";
416  }
417  if (!toolTip.isEmpty())
418  {
419  // if (!toolTip.isEmpty())
420 
421  if (bidir)
422  t << "BGCOLOR=\"orange\">";
423  else
424  t << "BGCOLOR=\"azure\">";
425  }
426  else if (bidir)
427  {
428  t << "BGCOLOR=\"pink\">";
429  }
430  else
431  {
432  t << "BGCOLOR=\"lightgrey\">";
433  }
434  if (md)
435  {
436  t << md->name();
437  }
438  else
439  {
440  t << " \n";
441  }
442  t << "</TD>\n";
443 
444  if (!start)
445  {
446  t << "</TR>\n";
447  }
448 }
449 
450 static void endTabel(FTextStream &t)
451 {
452  t << "</TABLE>>\n";
453  t << "] \n";
454 }
455 
457 {
458  t << "<TR><TD COLSPAN=\"2\" BGCOLOR=\"yellow\" ";
459  t << "PORT=\"";
460  t << cd->name();
461  t << "\" ";
462  t << "href=\"";
464  t << "\" ";
465  t << ">";
466  t << cd->name();
467  t << " </TD></TR>\n";
468 }
469 
470 static QList<MemberDef>* getPorts(ClassDef *cd)
471 {
472  MemberDef* md;
473  QList<MemberDef> *portList=new QList<MemberDef>;
475 
476  if (ml==0)
477  {
478  delete portList;
479  return 0;
480  }
481 
482  MemberListIterator fmni(*ml);
483 
484  for (fmni.toFirst();(md=fmni.current());++fmni)
485  {
487  {
488  portList->append(md);
489  }
490  }
491 
492  return portList;
493 }
494 
495 //writeColumn(FTextStream &t,QCString name,bool start)
496 
497 static void writeTable(QList<MemberDef>* port,FTextStream & t)
498 {
499  MemberDef *md;
500  uint len=port->count();
501 
502  QList<MemberDef> inPorts;
503  QList<MemberDef> outPorts;
504 
505  uint j;
506  for (j=0;j<len;j++)
507  {
508  md=(MemberDef*)port->at(j);
509  QCString qc=md->typeString();
510  if(qc=="in")
511  {
512  inPorts.append(md);
513  }
514  else
515  {
516  outPorts.append(md);
517  }
518  }
519 
520  int inp = inPorts.count();
521  int outp = outPorts.count();
522  int maxLen;
523 
524  if (inp>=outp)
525  {
526  maxLen=inp;
527  }
528  else
529  {
530  maxLen=outp;
531  }
532 
533  int i;
534  for(i=0;i<maxLen;i++)
535  {
536  //write inports
537  if (i<inp)
538  {
539  md=(MemberDef*)inPorts.at(i);
540  writeColumn(t,md,TRUE);
541  }
542  else
543  {
544  writeColumn(t,NULL,TRUE);
545  }
546 
547  if (i<outp)
548  {
549  md=(MemberDef*)outPorts.at(i);
550  writeColumn(t,md,FALSE);
551  }
552  else
553  {
554  writeColumn(t,NULL,FALSE);
555  }
556  }
557 }
558 
559 //--------------------------------------------------------------------------------------------------
560 
561 
563 {
564 }
565 
567 {
568 }
569 
571 {
572 
573  // vhdl keywords included VHDL 2008
574 const char* g_vhdlKeyWordMap0[] =
575 {
576  "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
577  "begin","block","body","buffer","bus",
578  "case","component","configuration","constant","context","cover",
579  "default","disconnect","downto",
580  "else","elsif","end","entity","exit",
581  "fairness","file","for","force","function",
582  "generate","generic","group","guarded",
583  "if","impure","in","inertial","inout","is",
584  "label","library","linkage","literal","loop",
585  "map","mod",
586  "nand","new","next","nor","not","null",
587  "of","on","open","or","others","out",
588  "package","parameter","port","postponed","procedure","process","property","proctected","pure",
589  "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
590  "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
591  "then","to","transport","type",
592  "unaffected","units","until","use",
593  "variable","vmode","vprop","vunit",
594  "wait","when","while","with",
595  "xor","xnor",
596  0
597 };
598 
599 
600 // type
601 const char* g_vhdlKeyWordMap1[] =
602 {
603  "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
604  "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
605  "real","float","ufixed","sfixed","time",0
606 };
607 
608 // logic
609 const char* g_vhdlKeyWordMap2[] =
610 {
611  "abs","and","or","not","mod", "xor","rem","xnor","ror","rol","sla",
612  "sll",0
613 };
614 
615 // predefined attributes
616 const char* g_vhdlKeyWordMap3[] =
617 {
618 "base","left","right","high","low","ascending",
619 "image","value","pos","val","succ","pred","leftof","rightof","left","right","high","low",
620 "range","reverse_range","length","ascending","delayed","stable","quiet","transaction","event",
621 "active","last_event","last_active","last_value","driving","driving_value","simple_name","instance_name","path_name",0
622 };
623 
624  int j=0;
625  g_vhdlKeyDict0.setAutoDelete(TRUE);
626  g_vhdlKeyDict1.setAutoDelete(TRUE);
627  g_vhdlKeyDict2.setAutoDelete(TRUE);
628  g_vhdlKeyDict3.setAutoDelete(TRUE);
629 
630  while (g_vhdlKeyWordMap0[j])
631  {
632  g_vhdlKeyDict0.insert(g_vhdlKeyWordMap0[j],
633  new QCString(g_vhdlKeyWordMap0[j]));
634  j++;
635  }
636 
637  j=0;
638  while (g_vhdlKeyWordMap1[j])
639  {
640  g_vhdlKeyDict1.insert(g_vhdlKeyWordMap1[j],
641  new QCString(g_vhdlKeyWordMap1[j]));
642  j++;
643  }
644 
645  j=0;
646  while (g_vhdlKeyWordMap2[j])
647  {
648  g_vhdlKeyDict2.insert(g_vhdlKeyWordMap2[j],
649  new QCString(g_vhdlKeyWordMap2[j]));
650  j++;
651  }
652 
653  j=0;
654  while (g_vhdlKeyWordMap3[j])
655  {
656  g_vhdlKeyDict3.insert(g_vhdlKeyWordMap3[j],
657  new QCString(g_vhdlKeyWordMap3[j]));
658  j++;
659  }
660 
661 }// buildKeyMap
662 
667 QCString* VhdlDocGen::findKeyWord(const QCString& tmp)
668 {
669  static QCString vhdlkeyword("vhdlkeyword");
670  static QCString vhdltype("comment");
671  static QCString vhdllogic("vhdllogic");
672  static QCString preprocessor("keywordflow");
673 
674  QCString word=tmp.lower();
675 
676  if (word.isEmpty() || word.at(0)=='\0') return 0;
677 
678  if (g_vhdlKeyDict0.find(word))
679  return &preprocessor;
680 
681  if (g_vhdlKeyDict1.find(word))
682  return &vhdltype;
683 
684  if (g_vhdlKeyDict2.find(word))
685  return &vhdllogic;
686 
687  if (g_vhdlKeyDict3.find(word))
688  return &vhdlkeyword;
689 
690  return 0;
691 }
692 
694 {
695  if (name==0 || name[0]=='\0') return 0;
696 
697  ClassDef *cd=0;
698  QCString temp(name);
699  //temp=temp.lower();
700  temp=temp.stripWhiteSpace();
701  cd= Doxygen::classSDict->find(temp.data());
702  return cd;
703 }
704 
706 {
707  ClassDef* cd=0;
708  cd=getClass(name);
709 
710  return cd;
711 }
712 
713 static QMap<QCString,MemberDef*> varMap;
714 static QList<ClassDef> qli;
715 static QMap<ClassDef*,QList<ClassDef> > packages;
716 
717 MemberDef* VhdlDocGen::findMember(const QCString& className, const QCString& memName)
718 {
719  ClassDef* cd,*ecd;
720  MemberDef *mdef=0;
721 
722  cd=getClass(className);
723  //printf("VhdlDocGen::findMember(%s,%s)=%p\n",className.data(),memName.data(),cd);
724  if (cd==0) return 0;
725 
727  if (mdef) return mdef;
729  if (mdef) return mdef;
730 
731  // nothing found so far
732  // if we are an architecture or package body search in entity
733 
736  {
737  Definition *d = cd->getOuterScope();
738  // searching upper/lower case names
739 
740  QCString tt=d->name();
741  ecd =getClass(tt);
742  if (!ecd)
743  {
744  tt=tt.upper();
745  ecd =getClass(tt);
746  }
747  if (!ecd)
748  {
749  tt=tt.lower();
750  ecd =getClass(tt);
751  }
752 
753  if (ecd) //d && d->definitionType()==Definition::TypeClass)
754  {
755  //ClassDef *ecd = (ClassDef*)d;
757  if (mdef) return mdef;
759  if (mdef) return mdef;
760  }
761  }
762 
763 
766  {
767  Definition *d = cd->getOuterScope();
768 
769  QCString tt=d->name();
770  ClassDef *ecd =getClass(tt);
771  if (!ecd)
772  {
773  tt=tt.upper();
774  ecd =getClass(tt);
775  }
776  if (!ecd)
777  {
778  tt=tt.lower();
779  ecd =getClass(tt);
780  }
781  if (ecd) //d && d->definitionType()==Definition::TypeClass)
782  {
783  if(!packages.contains(ecd))
784  {
786  }
787  }
788  }
789  else
790  {
791  ecd=cd;
792  if (!packages.contains(ecd)) VhdlDocGen::findAllPackages(ecd);
793  }
794 
795  QMap<ClassDef*,QList<ClassDef> >::Iterator cList=packages.find(ecd);
796  if (cList.key()!=0)
797  {
798  QList<ClassDef> mlist=cList.data();
799  for (uint j=0;j<mlist.count();j++)
800  {
802  if (mdef) return mdef;
803  mdef=VhdlDocGen::findMemberDef(mlist.at(j),memName,MemberListType_pubMethods);
804  if (mdef) return mdef;
805  }
806  }
807  return 0;
808 
809 }//findMember
810 
816 {
817  MemberDef *md=0;
818  MemberList *ml=0;
819  QCString keyType=cd->symbolName()+"@"+key;
820  //printf("\n %s | %s | %s",cd->symbolName().data(),key.data(,),keyType.data());
821 
822  QMap<QCString, MemberDef*>::Iterator it =varMap.find(keyType);
823  if (it.key())
824  {
825  md=it.data();
826  if (md)
827  {
828  return md;
829  }
830  }
831  if (qli.contains(cd))
832  {
833  return 0;
834  }
835  ml=cd->getMemberList(type);
836  qli.append(cd);
837  if (!ml)
838  {
839  return 0;
840  }
841  MemberListIterator fmni(*ml);
842  //int l=ml->count();
843  // fprintf(stderr,"\n loading entity %s %s: %d",cd->symbolName().data(),keyType.data(),l);
844 
845  for (fmni.toFirst();(md=fmni.current());++fmni)
846  {
847  QCString tkey=cd->symbolName()+"@"+md->name();
848  if (varMap.contains(tkey))
849  {
850  continue;
851  }
852  varMap.insert(tkey.data(),md);
853  }
854  it=varMap.find(keyType.data());
855  if (it.key())
856  {
857  md=it.data();
858  if (md)
859  {
860  return md;
861  }
862  }
863  return 0;
864 }//findMemberDef
865 
871 {
872  QList<ClassDef> cList;
873  if (packages.contains(cdef)) return;
875  MemberDef *md;
876 
877  if (!mem) return;
878 
879  MemberListIterator fmni(*mem);
880  for (fmni.toFirst();(md=fmni.current());++fmni)
881  {
882  if (VhdlDocGen::isPackage(md))
883  {
885  if (cd)
886  {
887  cList.append(cd);
889  packages.insert(cdef,cList);
890  }
891  }
892  }//for
893 
894 }// findAllPackages
895 
901 MemberDef* VhdlDocGen::findFunction(const QList<Argument> &ql,
902  const QCString& funcname,
903  const QCString& package, bool /*type*/)
904 {
905  MemberDef* mdef=0;
906  //int funcType;
907  ClassDef *cdef=getClass(package.data());
908  if (cdef==0) return 0;
909 
911 
912  if (mem)
913  {
914  MemberListIterator fmni(*mem);
915  for (fmni.toFirst();(mdef=fmni.current());++fmni)
916  {
917  QCString mname=mdef->name();
918  if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
919  {
920  ArgumentList *alp = mdef->argumentList();
921 
922  // ArgumentList* arg2=mdef->getArgumentList();
923  if (alp==0) break;
924  ArgumentListIterator ali(*alp);
925  ArgumentListIterator ali1(ql);
926 
927  if (ali.count() != ali1.count()) break;
928 
929  Argument *arg,*arg1;
930  int equ=0;
931 
932  for (;(arg=ali.current()) && (arg1=ali1.current());++ali,++ali1)
933  {
934  equ+=abs(compareString(arg->type,arg1->type));
935 
936  QCString s1=arg->type;
937  QCString s2=arg1->type;
940  equ+=abs(compareString(s1,s2));
941  s1=arg->attrib;
942  s2=arg1->attrib;
945  equ+=abs(compareString(s1,s2));
946  // printf("\n 1. type [%s] name [%s] attrib [%s]",arg->type,arg->name,arg->attrib);
947  // printf("\n 2. type [%s] name [%s] attrib [%s]",arg1->type,arg1->name,arg1->attrib);
948  } // for
949  if (equ==0) return mdef;
950  }//if
951  }//for
952  }//if
953  return mdef;
954 } //findFunction
955 
956 
957 
958 
964 {
965  QCString pageTitle;
966  if (cd==0) return "";
967  pageTitle=VhdlDocGen::getClassName(cd);
968  int ii=cd->protection();
969  pageTitle+=" ";
970  pageTitle+=theTranslator_vhdlType(ii+2,TRUE);
971  pageTitle+=" ";
972  return pageTitle;
973 } // getClassTitle
974 
975 /* returns the class name without their prefixes */
976 
978 {
979  QCString temp;
980  if (cd==0) return "";
981 
983  {
984  temp=cd->name();
985  temp.stripPrefix("_");
986  return temp;
987  }
988 
989  return substitute(cd->className(),"::",".");
990 }
991 
997 {
998  QList<QCString> ql;
999  ql.setAutoDelete(TRUE);
1000  QCString nn=cd->className();
1001  int ii=(int)cd->protection()+2;
1002 
1003  QCString type;
1004  if (ii==VhdlDocGen::ENTITY)
1006  else if (ii==VhdlDocGen::ARCHITECTURE)
1008  else if (ii==VhdlDocGen::PACKAGE_BODY)
1010  else if (ii==VhdlDocGen::PACKAGE)
1012  else
1013  type+="";
1014 
1015  //type=type.lower();
1016  type+=" >> ";
1019 
1020  if (ii==VhdlDocGen::PACKAGE_BODY)
1021  {
1022  nn.stripPrefix("_");
1023  cd=getClass(nn.data());
1024  }
1025  else if (ii==VhdlDocGen::PACKAGE)
1026  {
1027  nn.prepend("_");
1028  cd=getClass(nn.data());
1029  }
1030  else if (ii==VhdlDocGen::ARCHITECTURE)
1031  {
1032  QStringList qlist=QStringList::split("-",nn,FALSE);
1033  nn=qlist[1].utf8();
1034  cd=VhdlDocGen::getClass(nn.data());
1035  }
1036 
1037  QCString opp;
1038  if (ii==VhdlDocGen::ENTITY)
1039  {
1041  int j=ql.count();
1042  for (int i=0;i<j;i++)
1043  {
1044  QCString *temp=ql.at(i);
1045  QStringList qlist=QStringList::split("-",*temp,FALSE);
1046  QCString s1=qlist[0].utf8();
1047  QCString s2=qlist[1].utf8();
1048  s1.stripPrefix("_");
1049  if (j==1) s1.resize(0);
1050  ClassDef*cc = getClass(temp->data());
1051  if (cc)
1052  {
1053  VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
1054  }
1055  }
1056  }
1057  else
1058  {
1059  VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
1060  }
1061 
1064 
1065 }// write
1066 
1067 /*
1068  * finds all architectures which belongs to an entity
1069  */
1070 void VhdlDocGen::findAllArchitectures(QList<QCString>& qll,const ClassDef *cd)
1071 {
1072  ClassDef *citer;
1074  for ( ; (citer=cli.current()) ; ++cli )
1075  {
1076  QCString jj=citer->className();
1077  if (cd != citer && jj.contains('-')!=-1)
1078  {
1079  QStringList ql=QStringList::split("-",jj,FALSE);
1080  QCString temp=ql[1].utf8();
1081  if (qstricmp(cd->className(),temp)==0)
1082  {
1083  QCString *cl=new QCString(jj);
1084  qll.insert(0,cl);
1085  }
1086  }
1087  }// for
1088 }//findAllArchitectures
1089 
1091 {
1092  ClassDef *citer;
1093  QCString nn=cd->name();
1095 
1096  for ( ; (citer=cli.current()) ; ++cli )
1097  {
1098  QCString jj=citer->name();
1099  QStringList ql=QStringList::split(":",jj,FALSE);
1100  if (ql.count()>1)
1101  {
1102  if (ql[0].utf8()==nn )
1103  {
1104  return citer;
1105  }
1106  }
1107  }
1108  return 0;
1109 }
1110 /*
1111  * writes the link entity >> .... or architecture >> ...
1112  */
1113 
1114 void VhdlDocGen::writeVhdlLink(const ClassDef* ccd ,OutputList& ol,QCString& type,QCString& nn,QCString& behav)
1115 {
1116  if (ccd==0) return;
1117  ol.startBold();
1118  ol.docify(type.data());
1119  ol.endBold();
1120  nn.stripPrefix("_");
1121  ol.writeObjectLink(ccd->getReference(),ccd->getOutputFileBase(),0,nn.data());
1122 
1123  if (!behav.isEmpty())
1124  {
1125  behav.prepend(" ");
1126  ol.startBold();
1127  ol.docify(behav.data());
1128  ol.endBold();
1129  }
1130 
1131  ol.lineBreak();
1132 }
1133 
1134 
1138 void VhdlDocGen::prepareComment(QCString& qcs)
1139 {
1140  const char* s="--!";
1141  int index=0;
1142 
1143  while (TRUE)
1144  {
1145  index=qcs.find(s,0,TRUE);
1146  if (index<0) break;
1147  qcs=qcs.remove(index,qstrlen(s));
1148  }
1149  qcs=qcs.stripWhiteSpace();
1150 }
1151 
1152 
1161 void VhdlDocGen::parseFuncProto(const char* text,QList<Argument>& qlist,
1162  QCString& name,QCString& ret,bool doc)
1163 {
1164  (void)qlist; //unused
1165  int index,end;
1166  QCString s1(text);
1167  QCString temp;
1168 
1169  index=s1.find("(");
1170  end=s1.findRev(")");
1171 
1172  if ((end-index)>0)
1173  {
1174  temp=s1.mid(index+1,(end-index-1));
1175  //getFuncParams(qlist,temp);
1176  }
1177  if (doc)
1178  {
1179  name=s1.left(index);
1180  name=name.stripWhiteSpace();
1181  if ((end-index)>0)
1182  {
1183  ret="function";
1184  }
1185  return;
1186  }
1187  else
1188  {
1189  QCString s1(text);
1190  s1=s1.stripWhiteSpace();
1191  int i=s1.find("(",0,FALSE);
1192  int s=s1.find(QRegExp("[ \\t]"));
1193  if (i==-1 || i<s)
1194  s1=VhdlDocGen::getIndexWord(s1.data(),1);
1195  else // s<i, s=start of name, i=end of name
1196  s1=s1.mid(s,(i-s));
1197 
1198  name=s1.stripWhiteSpace();
1199  }
1200  index=s1.findRev("return",-1,FALSE);
1201  if (index !=-1)
1202  {
1203  ret=s1.mid(index+6,s1.length());
1204  ret=ret.stripWhiteSpace();
1205  VhdlDocGen::deleteCharRev(ret,';');
1206  }
1207 }
1208 
1209 /*
1210  * returns the n'th word of a string
1211  */
1212 
1213 QCString VhdlDocGen::getIndexWord(const char* c,int index)
1214 {
1215  QStringList ql;
1216  QCString temp(c);
1217  QRegExp reg("[\\s:|]");
1218 
1219  ql=QStringList::split(reg,temp,FALSE);
1220 
1221  if (ql.count() > (unsigned int)index)
1222  {
1223  return ql[index].utf8();
1224  }
1225 
1226  return "";
1227 }
1228 
1229 
1231 {
1232  if (prot==VhdlDocGen::ENTITYCLASS)
1233  return "entity";
1234  else if (prot==VhdlDocGen::ARCHITECTURECLASS)
1235  return "architecture";
1236  else if (prot==VhdlDocGen::PACKAGECLASS)
1237  return "package";
1238  else if (prot==VhdlDocGen::PACKBODYCLASS)
1239  return "package body";
1240 
1241  return "";
1242 }
1243 
1244 QCString VhdlDocGen::trTypeString(uint64 type)
1245 {
1246  switch(type)
1247  {
1248  case VhdlDocGen::LIBRARY: return "Library";
1249  case VhdlDocGen::ENTITY: return "Entity";
1250  case VhdlDocGen::PACKAGE_BODY: return "Package Body";
1251  case VhdlDocGen::ATTRIBUTE: return "Attribute";
1252  case VhdlDocGen::PACKAGE: return "Package";
1253  case VhdlDocGen::SIGNAL: return "Signal";
1254  case VhdlDocGen::COMPONENT: return "Component";
1255  case VhdlDocGen::CONSTANT: return "Constant";
1256  case VhdlDocGen::TYPE: return "Type";
1257  case VhdlDocGen::SUBTYPE: return "Subtype";
1258  case VhdlDocGen::FUNCTION: return "Function";
1259  case VhdlDocGen::RECORD: return "Record";
1260  case VhdlDocGen::PROCEDURE: return "Procedure";
1261  case VhdlDocGen::ARCHITECTURE: return "Architecture";
1262  case VhdlDocGen::USE: return "Package";
1263  case VhdlDocGen::PROCESS: return "Process";
1264  case VhdlDocGen::PORT: return "Port";
1265  case VhdlDocGen::GENERIC: return "Generic";
1266  case VhdlDocGen::UNITS: return "Units";
1267  //case VhdlDocGen::PORTMAP: return "Port Map";
1268  case VhdlDocGen::SHAREDVARIABLE: return "Shared Variable";
1269  case VhdlDocGen::GROUP: return "Group";
1270  case VhdlDocGen::VFILE: return "File";
1271  case VhdlDocGen::INSTANTIATION: return "Instantiation";
1272  case VhdlDocGen::ALIAS: return "Alias";
1273  case VhdlDocGen::CONFIG: return "Configuration";
1274  case VhdlDocGen::MISCELLANEOUS: return "Miscellaneous";
1275  case VhdlDocGen::UCF_CONST: return "Constraints";
1276  default: return "";
1277  }
1278 } // convertType
1279 
1284 bool VhdlDocGen::deleteCharRev(QCString &s,char c)
1285 {
1286  int index=s.findRev(c,-1,FALSE);
1287  if (index > -1)
1288  {
1289  QCString qcs=s.remove(index,1);
1290  s=qcs;
1291  return TRUE;
1292  }
1293  return FALSE;
1294 }
1295 
1296 void VhdlDocGen::deleteAllChars(QCString &s,char c)
1297 {
1298  int index=s.findRev(c,-1,FALSE);
1299  while (index > -1)
1300  {
1301  QCString qcs=s.remove(index,1);
1302  s=qcs;
1303  index=s.findRev(c,-1,FALSE);
1304  }
1305 }
1306 
1307 
1308 static int recordCounter=0;
1309 
1315 {
1316  char buf[12];
1317  sprintf(buf,"%d",recordCounter++);
1318  QCString qcs(&buf[0]);
1319  return qcs;
1320 }
1321 
1327 {
1328  static int stringCounter;
1329  char buf[8];
1330  QCString qcs("PROCESS_");
1331  sprintf(buf,"%d",stringCounter++);
1332  qcs.append(&buf[0]);
1333  return qcs;
1334 }
1335 
1340 void VhdlDocGen::writeFormatString(const QCString& s,OutputList&ol,const MemberDef* mdef)
1341 {
1342  QRegExp reg("[\\[\\]\\.\\/\\:\\<\\>\\:\\s\\,\\;\\'\\+\\-\\*\\|\\&\\=\\(\\)\"]");
1343  QCString qcs = s;
1344  qcs+=QCString(" ");// parsing the last sign
1345  QCString *ss;
1346  QCString find=qcs;
1347  QCString temp=qcs;
1348  char buf[2];
1349  buf[1]='\0';
1350 
1351  int j;
1352  int len;
1353  j = reg.match(temp.data(),0,&len);
1354 
1355  ol.startBold();
1356  if (j>=0)
1357  {
1358  while (j>=0)
1359  {
1360  find=find.left(j);
1361  buf[0]=temp[j];
1362  ss=VhdlDocGen::findKeyWord(find);
1363  bool k=isNumber(find); // is this a number
1364  if (k)
1365  {
1366  ol.docify(" ");
1367  startFonts(find,"vhdldigit",ol);
1368  ol.docify(" ");
1369  }
1370  else if (j != 0 && ss)
1371  {
1372  startFonts(find,ss->data(),ol);
1373  }
1374  else
1375  {
1376  if (j>0)
1377  {
1378  VhdlDocGen::writeStringLink(mdef,find,ol);
1379  }
1380  }
1381  startFonts(&buf[0],"vhdlchar",ol);
1382 
1383  QCString st=temp.remove(0,j+1);
1384  find=st;
1385  if (!find.isEmpty() && find.at(0)=='"')
1386  {
1387  int ii=find.find('"',2);
1388  if (ii>1)
1389  {
1390  QCString com=find.left(ii+1);
1391  startFonts(com,"keyword",ol);
1392  temp=find.remove(0,ii+1);
1393  }
1394  }
1395  else
1396  {
1397  temp=st;
1398  }
1399  j = reg.match(temp.data(),0,&len);
1400  }//while
1401  }//if
1402  else
1403  {
1404  startFonts(find,"vhdlchar",ol);
1405  }
1406  ol.endBold();
1407 }// writeFormatString
1408 
1412 bool VhdlDocGen::isNumber(const QCString& s)
1413 {
1414  static QRegExp regg("[0-9][0-9eEfFbBcCdDaA_.#-+?xXzZ]*");
1415 
1416  if (s.isEmpty()) return FALSE;
1417  int j,len;
1418  j = regg.match(s.data(),0,&len);
1419  if ((j==0) && (len==(int)s.length())) return TRUE;
1420  return FALSE;
1421 
1422 }// isNumber
1423 
1424 
1430 void VhdlDocGen::formatString(const QCString &s, OutputList& ol,const MemberDef* mdef)
1431 {
1432  QCString qcs = s;
1433  QCString temp;
1434  qcs.stripPrefix(":");
1435  qcs.stripPrefix("is");
1436  qcs.stripPrefix("IS");
1437  qcs.stripPrefix("of");
1438  qcs.stripPrefix("OF");
1439 
1440  // VhdlDocGen::deleteCharRev(qcs,';');
1441  //char white='\t';
1442  int len = qcs.length();
1443  unsigned int index=1;//temp.length();
1444 
1445  for (int j=0;j<len;j++)
1446  {
1447  char c=qcs[j];
1448  char b=c;
1449  if (j>0) b=qcs[j-1];
1450  if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
1451  {
1452  if (temp.length()>=index && temp.at(index-1) != ' ')
1453  {
1454  temp+=" ";
1455  }
1456  temp+=c;
1457  temp+=" ";
1458  }
1459  else if (c=='=')
1460  {
1461  if (b==':') // := operator
1462  {
1463  temp.replace(index-1,1,"=");
1464  temp+=" ";
1465  }
1466  else // = operator
1467  {
1468  temp+=" ";
1469  temp+=c;
1470  temp+=" ";
1471  }
1472  }
1473  else
1474  {
1475  temp+=c;
1476  }
1477 
1478  index=temp.length();
1479  }// for
1480  temp=temp.stripWhiteSpace();
1481  // printf("\n [%s]",qcs.data());
1482  VhdlDocGen::writeFormatString(temp,ol,mdef);
1483 }
1484 
1490 {
1491  ArgumentListIterator ali(*al);
1492  Argument *arg;
1493  bool sem=FALSE;
1494  int len=al->count();
1495  ol.docify("( ");
1496  if (len > 2)
1497  {
1498  ol.lineBreak();
1499  }
1500  for (;(arg=ali.current());++ali)
1501  {
1502  ol.startBold();
1503  if (sem && len <3)
1504  ol.writeChar(',');
1505 
1506  QCString nn=arg->name;
1507  nn+=": ";
1508 
1509  QCString *str=VhdlDocGen::findKeyWord(arg->defval);
1510  arg->defval+=" ";
1511  if (str)
1512  {
1513  startFonts(arg->defval,str->data(),ol);
1514  }
1515  else
1516  {
1517  startFonts(arg->defval,"vhdlchar",ol); // write type (variable,constant etc.)
1518  }
1519 
1520  startFonts(nn,"vhdlchar",ol); // write name
1521  if (qstricmp(arg->attrib,arg->type) != 0)
1522  {
1523  startFonts(arg->attrib.lower(),"stringliteral",ol); // write in|out
1524  }
1525  ol.docify(" ");
1526  VhdlDocGen::formatString(arg->type,ol,mdef);
1527  sem=TRUE;
1528  ol.endBold();
1529  if (len > 2)
1530  {
1531  ol.lineBreak();
1532  ol.docify(" ");
1533  }
1534  }//for
1535 
1536  ol.docify(" )");
1537 
1538 
1539 }
1540 
1546 {
1547  if (al==0) return;
1548  ArgumentListIterator ali(*al);
1549  Argument *arg;
1550  bool sem=FALSE;
1551  int len=al->count();
1552  ol.startBold();
1553  ol.docify(" ( ");
1554  ol.endBold();
1555  if (len>2)
1556  {
1557  ol.lineBreak();
1558  }
1559  for (;(arg=ali.current());++ali)
1560  {
1561  ol.startBold();
1562  QCString att=arg->defval;
1563  bool bGen=att.stripPrefix("gen!");
1564 
1565  if (sem && len < 3)
1566  {
1567  ol.docify(" , ");
1568  }
1569 
1570  if (bGen)
1571  {
1572  VhdlDocGen::formatString(QCString("generic "),ol,mdef);
1573  }
1574  if (!att.isEmpty())
1575  {
1576  QCString *str=VhdlDocGen::findKeyWord(att);
1577  att+=" ";
1578  if (str)
1579  VhdlDocGen::formatString(att,ol,mdef);
1580  else
1581  startFonts(att,"vhdlchar",ol);
1582  }
1583 
1584  QCString nn=arg->name;
1585  nn+=": ";
1586  QCString ss=arg->type.stripWhiteSpace(); //.lower();
1587  QCString w=ss.stripWhiteSpace();//.upper();
1588  startFonts(nn,"vhdlchar",ol);
1589  startFonts("in ","stringliteral",ol);
1590  QCString *str=VhdlDocGen::findKeyWord(ss);
1591  if (str)
1592  VhdlDocGen::formatString(w,ol,mdef);
1593  else
1594  startFonts(w,"vhdlchar",ol);
1595 
1596  if (arg->attrib)
1597  startFonts(arg->attrib,"vhdlchar",ol);
1598 
1599 
1600  sem=TRUE;
1601  ol.endBold();
1602  if (len > 2)
1603  {
1604  ol.lineBreak();
1605  }
1606  }
1607  ol.startBold();
1608  ol.docify(" )");
1609  const char *exp=mdef->excpString();
1610  if (exp)
1611  {
1612  ol.insertMemberAlign();
1613  ol.startBold();
1614  ol.docify("[ ");
1615  ol.docify(exp);
1616  ol.docify(" ]");
1617  ol.endBold();
1618  }
1619  ol.endBold();
1620 }
1621 
1627 {
1628  if (al==0) return;
1629  ArgumentListIterator ali(*al);
1630  Argument *arg;
1631  bool sem=FALSE;
1632  ol.startBold();
1633  ol.docify(" ( ");
1634  for (;(arg=ali.current());++ali)
1635  {
1636  if (sem)
1637  {
1638  ol.docify(" , ");
1639  }
1640  QCString nn=arg->name;
1641  // startFonts(nn,"vhdlchar",ol);
1642  VhdlDocGen::writeFormatString(nn,ol,mdef);
1643  sem=TRUE;
1644  }
1645  ol.docify(" )");
1646  ol.endBold();
1647 }
1648 
1649 
1655  const MemberDef *md,
1656  OutputList& ol,
1657  const ArgumentList* al,
1658  bool /*type*/)
1659 {
1660  if (al==0) return FALSE;
1661  //bool sem=FALSE;
1662  ol.enableAll();
1663 
1664  ArgumentListIterator ali(*al);
1665  int index=ali.count();
1666  if (index==0)
1667  {
1668  ol.docify(" ( ) ");
1669  return FALSE;
1670  }
1671  ol.endMemberDocName();
1672  ol.startParameterList(TRUE);
1673  //ol.startParameterName(FALSE);
1674  Argument *arg;
1675  bool first=TRUE;
1676  for (;(arg=ali.current());++ali)
1677  {
1678  ol.startParameterType(first,"");
1679  // if (first) ol.writeChar('(');
1680  QCString attl=arg->defval;
1681  bool bGen=attl.stripPrefix("gen!");
1682  if (bGen)
1683  VhdlDocGen::writeFormatString(QCString("generic "),ol,md);
1684 
1685 
1686  if (VhdlDocGen::isProcedure(md))
1687  {
1688  startFonts(arg->defval,"keywordtype",ol);
1689  ol.docify(" ");
1690  }
1691  ol.endParameterType();
1692 
1693  ol.startParameterName(TRUE);
1694  VhdlDocGen::writeFormatString(arg->name,ol,md);
1695 
1696  if (VhdlDocGen::isProcedure(md))
1697  {
1698  startFonts(arg->attrib,"stringliteral",ol);
1699  }
1700  else if (VhdlDocGen::isVhdlFunction(md))
1701  {
1702  startFonts(QCString("in"),"stringliteral",ol);
1703  }
1704 
1705  ol.docify(" ");
1707  ol.startEmphasis();
1709  if (!VhdlDocGen::isProcess(md))
1710  {
1711  // startFonts(arg->type,"vhdlkeyword",ol);
1712  VhdlDocGen::writeFormatString(arg->type,ol,md);
1713  }
1715  ol.endEmphasis();
1717 
1718  if (--index)
1719  {
1720  ol.docify(" , ");
1721  }
1722  else
1723  {
1724  // ol.docify(" ) ");
1725  ol.endParameterName(TRUE,FALSE,TRUE);
1726  break;
1727  }
1728  ol.endParameterName(FALSE,FALSE,FALSE);
1729 
1730  //sem=TRUE;
1731  first=FALSE;
1732  }
1733  //ol.endParameterList();
1734  return TRUE;
1735 
1736 } // writeDocFunProc
1737 
1738 
1739 
1740 
1742 {
1743  QCString argString;
1744  bool sem=FALSE;
1745  ArgumentListIterator ali(*al);
1746  Argument *arg;
1747 
1748  for (;(arg=ali.current());++ali)
1749  {
1750  if (sem) argString.append(", ");
1751  if (func)
1752  {
1753  argString+=arg->name;
1754  argString+=":";
1755  argString+=arg->type;
1756  }
1757  else
1758  {
1759  argString+=arg->defval+" ";
1760  argString+=arg->name+" :";
1761  argString+=arg->attrib+" ";
1762  argString+=arg->type;
1763  }
1764  sem=TRUE;
1765  }
1766  return argString;
1767 }
1768 
1769 
1771  OutputList& ol,GroupDef* gd,ClassDef* cd,FileDef *fd,NamespaceDef* nd)
1772 {
1794 
1795  // configurations must be added to global file definitions.
1798 
1799 }
1800 
1801 static void setGlobalType(MemberList *ml)
1802 {
1803  if (ml==0) return;
1804  MemberDef *mdd=0;
1805  MemberListIterator mmli(*ml);
1806  for ( ; (mdd=mmli.current()); ++mmli )
1807  {
1808  if (qstrcmp(mdd->argsString(),"package")==0)
1809  {
1811  }
1812  else if (qstrcmp(mdd->argsString(),"configuration")==0)
1813  {
1815  }
1816  else if (qstrcmp(mdd->typeString(),"library")==0)
1817  {
1819  }
1820  else if (qstrcmp(mdd->typeString(),"use")==0)
1821  {
1823  }
1824  else if (qstricmp(mdd->typeString(),"misc")==0)
1825  {
1827  }
1828  else if (qstricmp(mdd->typeString(),"ucf_const")==0)
1829  {
1831  }
1832  }
1833 }
1834 
1835 /* writes a vhdl type documentation */
1837 {
1838  ClassDef *cd=(ClassDef*)d;
1839  bool hasParams = FALSE;
1840 
1841  if (cd==0) return hasParams;
1842 
1843  QCString ttype=mdef->typeString();
1844  QCString largs=mdef->argsString();
1845 
1847  {
1848  QCString nn=mdef->typeString();
1849  nn=nn.stripWhiteSpace();
1850  QCString na=cd->name();
1851  MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1852  if (memdef && memdef->isLinkable())
1853  {
1854  ol.docify(" ");
1855 
1856  ol.startBold();
1857  writeLink(memdef,ol);
1858  ol.endBold();
1859  ol.docify(" ");
1860  }
1861  else
1862  {
1863  ol.docify(" ");
1864  VhdlDocGen::formatString(ttype,ol,mdef);
1865  ol.docify(" ");
1866  }
1867  ol.docify(mdef->name());
1868  hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
1869  }
1870 
1871 
1872  if (mdef->isVariable())
1873  {
1874  if (VhdlDocGen::isConstraint(mdef))
1875  {
1876  writeLink(mdef,ol);
1877  ol.docify(" ");
1878 
1879  largs=largs.replace(QRegExp("#")," ");
1880  VhdlDocGen::formatString(largs,ol,mdef);
1881  return hasParams;
1882  }
1883  else
1884  {
1885  writeLink(mdef,ol);
1886  if (VhdlDocGen::isLibrary(mdef) || VhdlDocGen::isPackage(mdef))
1887  {
1888  return hasParams;
1889  }
1890  ol.docify(" ");
1891  }
1892 
1893  // QCString largs=mdef->argsString();
1894 
1895  bool c=largs=="context";
1896  bool brec=largs.stripPrefix("record") ;
1897 
1898  if (!brec && !c)
1899  VhdlDocGen::formatString(ttype,ol,mdef);
1900 
1901  if (c || brec || largs.stripPrefix("units"))
1902  {
1903  if (c)
1904  largs=ttype;
1905  VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1906  return hasParams;
1907  }
1908 
1909  ol.docify(" ");
1910  if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1911  {
1912  // QCString largs=mdef->argsString();
1913  VhdlDocGen::formatString(largs,ol,mdef);
1914  ol.docify(" ");
1915  }
1916  }
1917  return hasParams;
1918 }
1919 
1921 {
1922  tagFile << " <member kind=\"";
1923  if (VhdlDocGen::isGeneric(mdef)) tagFile << "generic";
1924  if (VhdlDocGen::isPort(mdef)) tagFile << "port";
1925  if (VhdlDocGen::isEntity(mdef)) tagFile << "entity";
1926  if (VhdlDocGen::isComponent(mdef)) tagFile << "component";
1927  if (VhdlDocGen::isVType(mdef)) tagFile << "type";
1928  if (VhdlDocGen::isConstant(mdef)) tagFile << "constant";
1929  if (VhdlDocGen::isSubType(mdef)) tagFile << "subtype";
1930  if (VhdlDocGen::isVhdlFunction(mdef)) tagFile << "function";
1931  if (VhdlDocGen::isProcedure(mdef)) tagFile << "procedure";
1932  if (VhdlDocGen::isProcess(mdef)) tagFile << "process";
1933  if (VhdlDocGen::isSignals(mdef)) tagFile << "signal";
1934  if (VhdlDocGen::isAttribute(mdef)) tagFile << "attribute";
1935  if (VhdlDocGen::isRecord(mdef)) tagFile << "record";
1936  if (VhdlDocGen::isLibrary(mdef)) tagFile << "library";
1937  if (VhdlDocGen::isPackage(mdef)) tagFile << "package";
1938  if (VhdlDocGen::isVariable(mdef)) tagFile << "shared variable";
1939  if (VhdlDocGen::isFile(mdef)) tagFile << "file";
1940  if (VhdlDocGen::isGroup(mdef)) tagFile << "group";
1941  if (VhdlDocGen::isCompInst(mdef)) tagFile << "instantiation";
1942  if (VhdlDocGen::isAlias(mdef)) tagFile << "alias";
1943  if (VhdlDocGen::isCompInst(mdef)) tagFile << "configuration";
1944 
1945  tagFile << "\">" << endl;
1946  tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>" << endl;
1947  tagFile << " <name>" << convertToXML(mdef->name()) << "</name>" << endl;
1948  tagFile << " <anchorfile>" << convertToXML(mdef->getOutputFileBase()+Doxygen::htmlFileExtension) << "</anchorfile>" << endl;
1949  tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>" << endl;
1950 
1951  if (VhdlDocGen::isVhdlFunction(mdef))
1952  tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),TRUE)) << "</arglist>" << endl;
1953  else if (VhdlDocGen::isProcedure(mdef))
1954  tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),FALSE)) << "</arglist>" << endl;
1955  else
1956  tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>" << endl;
1957 
1958  mdef->writeDocAnchorsToTagFile(tagFile);
1959  tagFile << " </member>" << endl;
1960 }
1961 
1962 /* writes a vhdl type declaration */
1963 
1965  ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
1966  bool /*inGroup*/)
1967 {
1968  Definition *d=0;
1969 
1970  ASSERT(cd!=0 || nd!=0 || fd!=0 || gd!=0 ||
1973  ); // member should belong to something
1974  if (cd) d=cd;
1975  else if (nd) d=nd;
1976  else if (fd) d=fd;
1977  else if (gd) d=gd;
1978  else d=(Definition*)mdef;
1979 
1980  // write search index info
1982  {
1983  Doxygen::searchIndex->setCurrentDoc(mdef,mdef->anchor(),FALSE);
1984  Doxygen::searchIndex->addWord(mdef->localName(),TRUE);
1985  Doxygen::searchIndex->addWord(mdef->qualifiedName(),FALSE);
1986  }
1987 
1988  QCString cname = d->name();
1989  QCString cfname = d->getOutputFileBase();
1990 
1991  //HtmlHelp *htmlHelp=0;
1992  // bool hasHtmlHelp = Config_getBool(GENERATE_HTML) && Config_getBool(GENERATE_HTMLHELP);
1993  // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1994 
1995  // search for the last anonymous scope in the member type
1996  ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
1997 
1998  // start a new member declaration
1999  uint isAnonymous = (bool)(annoClassDef); // || m_impl->annMemb || m_impl->annEnumType;
2001  int mm=mdef->getMemberSpecifiers();
2002  if (mm==VhdlDocGen::MISCELLANEOUS)
2003  isAnonymous=3;
2004 
2005  ol.startMemberItem( mdef->anchor(), isAnonymous ); //? 1 : m_impl->tArgList ? 3 : 0);
2006 
2007  // If there is no detailed description we need to write the anchor here.
2008  bool detailsVisible = mdef->isDetailedSectionLinkable();
2009  if (!detailsVisible) // && !m_impl->annMemb)
2010  {
2011  QCString doxyName=mdef->name().copy();
2012  if (!cname.isEmpty()) doxyName.prepend(cname+"::");
2013  QCString doxyArgs=mdef->argsString();
2014  ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
2015 
2016  ol.pushGeneratorState();
2019  ol.docify("\n");
2020  ol.popGeneratorState();
2021 
2022  }
2023  // *** write type
2024  /*VHDL CHANGE */
2025  bool bRec,bUnit;
2026  QCString ltype(mdef->typeString());
2027  // ltype=ltype.replace(reg," ");
2028  QCString largs(mdef->argsString());
2029  // largs=largs.replace(reg," ");
2030  mdef->setType(ltype.data());
2031  mdef->setArgsString(largs.data());
2032  //ClassDef * plo=mdef->getClassDef();
2033  ClassDef *kl=0;
2034  ArgumentList *alp = mdef->argumentList();
2035  QCString nn;
2036  //VhdlDocGen::adjustRecordMember(mdef);
2037  if (gd) gd=0;
2038  switch (mm)
2039  {
2041  VhdlDocGen::writeSource(mdef,ol,nn);
2042  break;
2043  case VhdlDocGen::PROCEDURE:
2044  case VhdlDocGen::FUNCTION:
2045  ol.startBold();
2046  VhdlDocGen::formatString(ltype,ol,mdef);
2047  ol.endBold();
2048  ol.insertMemberAlign();
2049  ol.docify(" ");
2050 
2051  writeLink(mdef,ol);
2052  if (alp!=0 && mm==VhdlDocGen::FUNCTION)
2053  VhdlDocGen::writeFunctionProto(ol,alp,mdef);
2054 
2055  if (alp!=0 && mm==VhdlDocGen::PROCEDURE)
2056  VhdlDocGen::writeProcedureProto(ol,alp,mdef);
2057 
2058  break;
2059  case VhdlDocGen::USE:
2060  kl=VhdlDocGen::getClass(mdef->name());
2061  if (kl && ((VhdlDocGen::VhdlClasses)kl->protection()==VhdlDocGen::ENTITYCLASS)) break;
2062  writeLink(mdef,ol);
2063  ol.insertMemberAlign();
2064  ol.docify(" ");
2065 
2066  if (kl)
2067  {
2068  nn=kl->getOutputFileBase();
2069  ol.pushGeneratorState();
2071  ol.docify(" ");
2073  ol.startBold();
2074  ol.docify(name.data());
2075  name.resize(0);
2076  ol.endBold();
2077  name+=" <"+mdef->name()+">";
2078  ol.startEmphasis();
2079  ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2080  ol.popGeneratorState();
2081  }
2082  break;
2083  case VhdlDocGen::LIBRARY:
2084  writeLink(mdef,ol);
2085  ol.insertMemberAlign();
2086  if (largs=="context")
2087  {
2088  VhdlDocGen::writeRecorUnit(ltype,ol,mdef);
2089  }
2090 
2091  break;
2092 
2093  case VhdlDocGen::GENERIC:
2094  case VhdlDocGen::PORT:
2095  case VhdlDocGen::ALIAS:
2096 
2097  writeLink(mdef,ol);
2098  ol.docify(" ");
2099  ol.insertMemberAlign();
2100  if (mm==VhdlDocGen::GENERIC)
2101  {
2102  ol.startBold();
2103  VhdlDocGen::formatString(largs,ol,mdef);
2104  ol.endBold();
2105  }
2106  else
2107  {
2108  ol.docify(" ");
2109  ol.startBold();
2110  VhdlDocGen::formatString(ltype,ol,mdef);
2111  ol.endBold();
2112  ol.docify(" ");
2113  VhdlDocGen::formatString(largs,ol,mdef);
2114  }
2115  break;
2116  case VhdlDocGen::PROCESS:
2117  writeLink(mdef,ol);
2118  ol.insertMemberAlign();
2119  VhdlDocGen::writeProcessProto(ol,alp,mdef);
2120  break;
2121  case VhdlDocGen::PACKAGE:
2122  case VhdlDocGen::ENTITY:
2123  case VhdlDocGen::COMPONENT:
2125  case VhdlDocGen::CONFIG:
2126  if (VhdlDocGen::isCompInst(mdef) )
2127  {
2128  nn=largs;
2129  if(nn.stripPrefix("function") || nn.stripPrefix("package"))
2130  {
2131  VhdlDocGen::formatString(largs,ol,mdef);
2132  ol.insertMemberAlign();
2133  writeLink(mdef,ol);
2134  ol.docify(" ");
2135  VhdlDocGen::formatString(ltype,ol,mdef);
2136  break;
2137  }
2138 
2139  largs.prepend("::");
2140  largs.prepend(mdef->name().data());
2141  ol.writeObjectLink(mdef->getReference(),
2142  cfname,
2143  mdef->anchor(),
2144  mdef->name());
2145  }
2146  else
2147  writeLink(mdef,ol);
2148 
2149  ol.insertMemberAlign();
2150  ol.docify(" ");
2151 
2152  ol.startBold();
2153  ol.docify(ltype);
2154  ol.endBold();
2155  ol.docify(" ");
2156  if (VhdlDocGen::isComponent(mdef) ||
2157  VhdlDocGen::isConfig(mdef) ||
2158  VhdlDocGen::isCompInst(mdef))
2159  {
2160  if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2161  {
2162  nn=ltype;
2163  }
2164  else
2165  {
2166  nn=mdef->name();
2167  }
2168  kl=getClass(nn.data());
2169  if (kl)
2170  {
2171  nn=kl->getOutputFileBase();
2172  ol.pushGeneratorState();
2174  ol.startEmphasis();
2175  QCString name("<Entity ");
2176  if (VhdlDocGen::isConfig(mdef) || VhdlDocGen::isCompInst(mdef))
2177  {
2178  name+=ltype+">";
2179  }
2180  else
2181  {
2182  name+=mdef->name()+"> ";
2183  }
2184  ol.writeObjectLink(kl->getReference(),kl->getOutputFileBase(),0,name.data());
2185  ol.endEmphasis();
2186  ol.popGeneratorState();
2187  }
2188  }
2189  break;
2190  case VhdlDocGen::UCF_CONST:
2191  mm=mdef->name().findRev('_');
2192  if (mm>0)
2193  {
2194  mdef->setName(mdef->name().left(mm));
2195  }
2196  writeUCFLink(mdef,ol);
2197  break;
2198  case VhdlDocGen::SIGNAL:
2199  case VhdlDocGen::ATTRIBUTE:
2200  case VhdlDocGen::SUBTYPE:
2201  case VhdlDocGen::CONSTANT:
2203  case VhdlDocGen::VFILE:
2204  case VhdlDocGen::GROUP:
2205  writeLink(mdef,ol);
2206  ol.docify(" ");
2207  ol.insertMemberAlign();
2208  VhdlDocGen::formatString(ltype,ol,mdef);
2209  break;
2210  case VhdlDocGen::RECORD:
2211  case VhdlDocGen::UNITS:
2212  writeLink(mdef,ol);
2213  ol.docify(" ");
2214  ol.startBold();
2215  if (ltype.isEmpty()) {
2216  ol.docify(" ");
2217  }
2218  ol.insertMemberAlign();
2219  if (!ltype.isEmpty())
2220  VhdlDocGen::formatString(ltype,ol,mdef);
2221  ol.endBold();
2222  break;
2223  case VhdlDocGen::TYPE:
2224  bRec=largs.stripPrefix("record") ;
2225  bUnit=largs.stripPrefix("units") ;
2226  ol.startBold();
2227  if (bRec) ol.docify("record: ");
2228  if (bUnit) ol.docify("units: ");
2229  writeLink(mdef,ol);
2230  ol.insertMemberAlign();
2231  if (!bRec && !bUnit) VhdlDocGen::formatString(ltype,ol,mdef);
2232  if (bUnit) ol.lineBreak();
2233  if (bRec || bUnit)
2234  {
2235  writeRecorUnit(largs,ol,mdef);
2236  mdef->setType("");
2237  }
2238  ol.endBold();
2239  break;
2240 
2241  default: break;
2242  }
2243 
2244  bool htmlOn = ol.isEnabled(OutputGenerator::Html);
2245  if (htmlOn && /*Config_getBool(HTML_ALIGN_MEMBERS) &&*/ !ltype.isEmpty())
2246  {
2248  }
2249  if (!ltype.isEmpty()) ol.docify(" ");
2250 
2251  if (htmlOn)
2252  {
2254  }
2255 
2256  if (!detailsVisible)// && !m_impl->annMemb)
2257  {
2258  ol.endDoxyAnchor(cfname,mdef->anchor());
2259  }
2260 
2261  // name().data(),annoClassDef,annEnumType);
2262  // if(mm!=VhdlDocGen::MISCELLANEOUS)
2263  ol.endMemberItem();
2264  if (!mdef->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC) /* && !annMemb */)
2265  {
2266  QCString s=mdef->briefDescription();
2267  ol.startMemberDescription(mdef->anchor());
2268  ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
2269  mdef->getOuterScope()?mdef->getOuterScope():d,
2270  mdef,s.data(),TRUE,FALSE,0,TRUE,FALSE);
2271  if (detailsVisible)
2272  {
2273  ol.pushGeneratorState();
2275  //ol.endEmphasis();
2276  ol.docify(" ");
2277  if (mdef->getGroupDef()!=0 && gd==0) // forward link to the group
2278  {
2279  ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
2280  }
2281  else // local link
2282  {
2283  ol.startTextLink(0,mdef->anchor());
2284  }
2285  ol.endTextLink();
2286  //ol.startEmphasis();
2287  ol.popGeneratorState();
2288  }
2289  //ol.newParagraph();
2290  ol.endMemberDescription();
2291  }
2292  mdef->warnIfUndocumented();
2293 
2294 }// end writeVhdlDeclaration
2295 
2296 
2298  MemberList* mlist,OutputList &ol,
2299  ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,int specifier)
2300 {
2301 
2302  SDict<QCString> pack(1009);
2303  pack.setAutoDelete(TRUE);
2304 
2305  bool first=TRUE;
2306  MemberDef *md;
2307  MemberListIterator mli(*mlist);
2308  for ( ; (md=mli.current()); ++mli )
2309  {
2310  int mems=md->getMemberSpecifiers();
2311  if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlDocGen::LIBRARY) )
2312  {
2313  if (first) { ol.startMemberList();first=FALSE; }
2314  VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2315  } //if
2316  else if (md->isBriefSectionVisible() && (mems==specifier))
2317  {
2318  if (!pack.find(md->name().data()))
2319  {
2320  if (first) ol.startMemberList(),first=FALSE;
2321  VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,FALSE);
2322  pack.append(md->name().data(),new QCString(md->name().data()));
2323  }
2324  } //if
2325  } //for
2326  if (!first) ol.endMemberList();
2327  pack.clear();
2328 }//plainDeclaration
2329 
2330 static bool membersHaveSpecificType(MemberList *ml,uint64 type)
2331 {
2332  if (ml==0) return FALSE;
2333  MemberDef *mdd=0;
2334  MemberListIterator mmli(*ml);
2335  for ( ; (mdd=mmli.current()); ++mmli )
2336  {
2337  if (mdd->getMemberSpecifiers()==type) //is type in class
2338  {
2339  return TRUE;
2340  }
2341  }
2342  if (ml->getMemberGroupList())
2343  {
2345  MemberGroup *mg;
2346  while ((mg=mgli.current()))
2347  {
2348  if (mg->members())
2349  {
2350  if (membersHaveSpecificType(mg->members(),type)) return TRUE;
2351  }
2352  ++mgli;
2353  }
2354  }
2355  return FALSE;
2356 }
2357 
2359  ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
2360  const char *title,const char *subtitle,bool /*showEnumValues*/,int type)
2361 {
2362  setGlobalType(ml);
2363  if (!membersHaveSpecificType(ml,type)) return;
2364 
2365  if (title)
2366  {
2367  ol.startMemberHeader(title);
2368  ol.parseText(title);
2369  ol.endMemberHeader();
2370  ol.docify(" ");
2371  }
2372  if (subtitle && subtitle[0]!=0)
2373  {
2374  ol.startMemberSubtitle();
2375  ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
2376  ol.endMemberSubtitle();
2377  } //printf("memberGroupList=%p\n",memberGroupList);
2378 
2379  VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,type);
2380 
2381  if (ml->getMemberGroupList())
2382  {
2384  MemberGroup *mg;
2385  while ((mg=mgli.current()))
2386  {
2387  if (membersHaveSpecificType(mg->members(),type))
2388  {
2389  //printf("mg->header=%s\n",mg->header().data());
2390  bool hasHeader=mg->header()!="[NOHEADER]";
2391  ol.startMemberGroupHeader(hasHeader);
2392  if (hasHeader)
2393  {
2394  ol.parseText(mg->header());
2395  }
2396  ol.endMemberGroupHeader();
2397  if (!mg->documentation().isEmpty())
2398  {
2399  //printf("Member group has docs!\n");
2400  ol.startMemberGroupDocs();
2401  ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
2402  ol.endMemberGroupDocs();
2403  }
2404  ol.startMemberGroup();
2405  //printf("--- mg->writePlainDeclarations ---\n");
2406  VhdlDocGen::writePlainVHDLDeclarations(mg->members(),ol,cd,nd,fd,gd,type);
2407  ol.endMemberGroup(hasHeader);
2408  }
2409  ++mgli;
2410  }
2411  }
2412 }// writeVHDLDeclarations
2413 
2414 
2416  OutputList &ol ,QCString & cname)
2417 {
2418  int id=cd->protection();
2419  QCString qcs = VhdlDocGen::trTypeString(id+2);
2420  cname=VhdlDocGen::getClassName(cd);
2421  ol.startBold();
2422  ol.writeString(qcs.data());
2423  ol.writeString(" ");
2424  ol.endBold();
2425  //ol.insertMemberAlign();
2426  return FALSE;
2427 }// writeClassLink
2428 
2429 QCString VhdlDocGen::trVhdlType(uint64 type,bool sing)
2430 {
2431  switch(type)
2432  {
2433  case VhdlDocGen::LIBRARY:
2434  if (sing) return "Library";
2435  else return "Libraries";
2436  case VhdlDocGen::PACKAGE:
2437  if (sing) return "Package";
2438  else return "Packages";
2439  case VhdlDocGen::SIGNAL:
2440  if (sing) return "Signal";
2441  else return "Signals";
2442  case VhdlDocGen::COMPONENT:
2443  if (sing) return "Component";
2444  else return "Components";
2445  case VhdlDocGen::CONSTANT:
2446  if (sing) return "Constant";
2447  else return "Constants";
2448  case VhdlDocGen::ENTITY:
2449  if (sing) return "Entity";
2450  else return "Entities";
2451  case VhdlDocGen::TYPE:
2452  if (sing) return "Type";
2453  else return "Types";
2454  case VhdlDocGen::SUBTYPE:
2455  if (sing) return "Subtype";
2456  else return "Subtypes";
2457  case VhdlDocGen::FUNCTION:
2458  if (sing) return "Function";
2459  else return "Functions";
2460  case VhdlDocGen::RECORD:
2461  if (sing) return "Record";
2462  else return "Records";
2463  case VhdlDocGen::PROCEDURE:
2464  if (sing) return "Procedure";
2465  else return "Procedures";
2467  if (sing) return "Architecture";
2468  else return "Architectures";
2469  case VhdlDocGen::ATTRIBUTE:
2470  if (sing) return "Attribute";
2471  else return "Attributes";
2472  case VhdlDocGen::PROCESS:
2473  if (sing) return "Process";
2474  else return "Processes";
2475  case VhdlDocGen::PORT:
2476  if (sing) return "Port";
2477  else return "Ports";
2478  case VhdlDocGen::USE:
2479  if (sing) return "use clause";
2480  else return "Use Clauses";
2481  case VhdlDocGen::GENERIC:
2482  if (sing) return "Generic";
2483  else return "Generics";
2485  return "Package Body";
2486  case VhdlDocGen::UNITS:
2487  return "Units";
2489  if (sing) return "Shared Variable";
2490  return "Shared Variables";
2491  case VhdlDocGen::VFILE:
2492  if (sing) return "File";
2493  return "Files";
2494  case VhdlDocGen::GROUP:
2495  if (sing) return "Group";
2496  return "Groups";
2498  if (sing) return "Instantiation";
2499  else return "Instantiations";
2500  case VhdlDocGen::ALIAS:
2501  if (sing) return "Alias";
2502  return "Aliases";
2503  case VhdlDocGen::CONFIG:
2504  if (sing) return "Configuration";
2505  return "Configurations";
2507  return "Miscellaneous";
2508  case VhdlDocGen::UCF_CONST:
2509  return "Constraints";
2510  default:
2511  return "Class";
2512  }
2513 }
2514 
2516 {
2517  return "Design Unit Hierarchy";
2518 }
2519 
2521 {
2522  return "Design Unit List";
2523 }
2524 
2526 {
2527  return "Design Unit Members";
2528 }
2529 
2531 {
2532  return "Here is a list of all design unit members with links to "
2533  "the Entities they belong to:";
2534 }
2535 
2537 {
2538  return "Design Unit Index";
2539 }
2540 
2542 {
2543  return "Design Units";
2544 }
2545 
2547 {
2548  return "Functions/Procedures/Processes";
2549 }
2550 
2551 
2554 void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& ol)
2555 {
2556  if (mdef)
2557  {
2558  ClassDef *cd=mdef->getClassDef();
2559  if (cd)
2560  {
2561  QCString n=cd->name();
2562  MemberDef* memdef=VhdlDocGen::findMember(n,mem);
2563  if (memdef && memdef->isLinkable())
2564  {
2565  ol.startBold();
2566  writeLink(memdef,ol);
2567  ol.endBold();
2568  ol.docify(" ");
2569  return;
2570  }
2571  }
2572  }
2573  startFonts(mem,"vhdlchar",ol);
2574 }// found component
2575 
2576 
2577 
2578 void VhdlDocGen::writeSource(MemberDef *mdef,OutputList& ol,QCString & cname)
2579 {
2581  // pIntf->resetCodeParserState();
2582 
2583  QCString codeFragment=mdef->documentation();
2584 
2585  if (cname.isEmpty())
2586  {
2587  writeLink(mdef,ol);
2588  int fi=0;
2589  int j=0;
2590  do
2591  {
2592  fi=codeFragment.find("\n",++fi);
2593  } while(fi>=0 && j++ <3);
2594 
2595  // show only the first four lines
2596  if (j==4)
2597  {
2598  codeFragment=codeFragment.left(fi);
2599  codeFragment.append("\n .... ");
2600  }
2601  }
2602 
2603  codeFragment.prepend("\n");
2604  ol.pushGeneratorState();
2605  ol.startCodeFragment();
2606  pIntf->parseCode(ol, // codeOutIntf
2607  0, // scope
2608  codeFragment, // input
2609  SrcLangExt_VHDL, // lang
2610  FALSE, // isExample
2611  0, // exampleName
2612  mdef->getFileDef(), // fileDef
2613  mdef->getStartBodyLine(), // startLine
2614  mdef->getEndBodyLine(), // endLine
2615  TRUE, // inlineFragment
2616  mdef, // memberDef
2617  TRUE // show line numbers
2618  );
2619 
2620  ol.endCodeFragment();
2621  ol.popGeneratorState();
2622 
2623  if (cname.isEmpty()) return;
2624 
2625  mdef->writeSourceDef(ol,cname);
2626  mdef->writeSourceRefs(ol,cname);
2627  mdef->writeSourceReffedBy(ol,cname);
2628 }
2629 
2630 
2631 
2633 {
2634 
2635  QCString n=name;
2636  n=n.remove(0,6);
2637 
2638  int i=0;
2639 
2640  while((i=n.find("__"))>0)
2641  {
2642  n=n.remove(i,1);
2643  }
2644 
2645  while((i=n.find("_1"))>0)
2646  {
2647  n=n.replace(i,2,":");
2648  }
2649 
2650  return n;
2651 }
2652 
2653 void VhdlDocGen::parseUCF(const char* input, Entry* entity,QCString fileName,bool altera)
2654 {
2655  QCString ucFile(input);
2656  int lineNo=0;
2657  QCString comment("#!");
2658  QCString brief;
2659 
2660  while (!ucFile.isEmpty())
2661  {
2662  int i=ucFile.find("\n");
2663  if (i<0) break;
2664  lineNo++;
2665  QCString temp=ucFile.left(i);
2666  temp=temp.stripWhiteSpace();
2667  bool bb=temp.stripPrefix("//");
2668 
2669  if (!temp.isEmpty())
2670  {
2671  if (temp.stripPrefix(comment) )
2672  {
2673  brief+=temp;
2674  brief.append("\\n");
2675  }
2676  else if (!temp.stripPrefix("#") && !bb)
2677  {
2678  if (altera)
2679  {
2680  int i=temp.find("-name");
2681  if (i>0)
2682  {
2683  temp=temp.remove(0,i+5);
2684  }
2685 
2686  temp.stripPrefix("set_location_assignment");
2687 
2688  initUCF(entity,0,temp,lineNo,fileName,brief);
2689  }
2690  else
2691  {
2692  QRegExp ee("[\\s=]");
2693  int i=temp.find(ee);
2694  QCString ff=temp.left(i);
2695  temp.stripPrefix(ff.data());
2696  ff.append("#");
2697  if (!temp.isEmpty())
2698  {
2699  initUCF(entity,ff.data(),temp,lineNo,fileName,brief);
2700  }
2701  }
2702  }
2703  }//temp
2704 
2705  ucFile=ucFile.remove(0,i+1);
2706  }// while
2707 }
2708 
2709 static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCString & fileName,QCString & brief)
2710 {
2711  if (qcs.isEmpty())return;
2712  QRegExp reg("[\\s=]");
2713  QCString n;
2714  // bool bo=(qstricmp(type,qcs.data())==0);
2715 
2716  VhdlDocGen::deleteAllChars(qcs,';');
2717  qcs=qcs.stripWhiteSpace();
2718 
2719  int i= qcs.find(reg);
2720  if (i<0) return;
2721  if (i==0)
2722  {
2723  n=type;
2725  type="";
2726  }
2727  else
2728  {
2729  n=qcs.left(i);
2730  }
2731  qcs=qcs.remove(0,i+1);
2732  // qcs.prepend("|");
2733 
2734  qcs.stripPrefix("=");
2735 
2736  Entry* current=new Entry;
2737  current->spec=VhdlDocGen::UCF_CONST;
2738  current->section=Entry::VARIABLE_SEC;
2739  current->bodyLine=line;
2740  current->fileName=fileName;
2741  current->type="ucf_const";
2742  current->args+=qcs;
2743  current->lang= SrcLangExt_VHDL ;
2744 
2745  // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2746  if (n.isEmpty())
2747  {
2748  n="dummy";
2750  }
2751 
2752  current->name= n+"_";
2753  current->name.append(VhdlDocGen::getRecordNumber().data());
2754 
2755  if (!brief.isEmpty())
2756  {
2757  current->brief=brief;
2758  current->briefLine=line;
2759  current->briefFile=fileName;
2760  brief.resize(0);
2761  }
2762 
2763  root->addSubEntry(current);
2764 }
2765 
2766 
2767 static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2768 {
2769 
2770  QCString largs(mdef->argsString());
2771  QCString n= splitString(largs, '#');
2772  // VhdlDocGen::adjustRecordMember(mdef);
2773  bool equ=(n.length()==largs.length());
2774 
2775  if (!equ)
2776  {
2777  ol.writeString(n.data());
2778  ol.docify(" ");
2779  ol.insertMemberAlign();
2780  }
2781 
2782  if (mdef->name().contains("dummy")==0)
2783  {
2784  writeLink(mdef,ol);
2785  }
2786  if (equ)
2787  {
2788  ol.insertMemberAlign();
2789  }
2790  ol.docify(" ");
2791  VhdlDocGen::formatString(largs,ol,mdef);
2792 }
2793 
2795 {
2796  FileName *fn=Doxygen::inputNameList->getFirst();
2797  //LayoutNavEntry *cc = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
2798  uint count=Doxygen::inputNameList->count();
2799  LayoutNavEntry *kk = lne->parent();// find(LayoutNavEntry::Files);
2800  // LayoutNavEntry *kks = kk->parent();// find(LayoutNavEntry::Files);
2801  QCString file;
2802  QCString co("Constraints");
2803 
2804  QCString imgExt = getDotImageExtension();
2805  if (Config_getBool(HAVE_DOT) && imgExt=="svg")
2806  {
2807  QCString ov = theTranslator->trDesignOverview();
2808  QCString ofile("vhdl_design_overview");
2809  LayoutNavEntry *oo=new LayoutNavEntry( lne,LayoutNavEntry::MainPage,TRUE,ofile,ov,"");
2810  kk->addChild(oo);
2811  }
2812 
2813  uint i=0;
2814  while (i<count)
2815  {
2816  FileDef *fd=fn->at(i);
2817  if (fd->name().contains(".ucf") || fd->name().contains(".qsf"))
2818  {
2819  file = convertNameToFile(fd->name().data(),FALSE,FALSE);
2820  LayoutNavEntry *ucf=new LayoutNavEntry(lne,LayoutNavEntry::MainPage,TRUE,file,co,"");
2821  kk->addChild(ucf);
2822  break;
2823  }
2824  i++;
2825  }
2826  return FALSE;
2827 }
2828 
2829 
2830 // for cell_inst : [entity] work.proto [ (label|expr) ]
2831 QCString VhdlDocGen::parseForConfig(QCString & entity,QCString & arch)
2832 {
2833  int index;
2834  QCString label;
2835  if (!entity.contains(":")) return "";
2836 
2837  QRegExp exp("[:()\\s]");
2838  QStringList ql=QStringList::split(exp,entity,FALSE);
2839  //int ii=ql.findIndex(ent);
2840  assert(ql.count()>=2);
2841  label = ql[0].utf8();
2842  entity = ql[1].utf8();
2843  if ((index=entity.findRev("."))>=0)
2844  {
2845  entity.remove(0,index+1);
2846  }
2847 
2848  if (ql.count()==3)
2849  {
2850  arch= ql[2].utf8();
2851  ql=QStringList::split(exp,arch,FALSE);
2852  if (ql.count()>1) // expression
2853  {
2854  arch="";
2855  }
2856  }
2857  return label; // label
2858 }
2859 
2860 // use (configuration|entity|open) work.test [(cellfor)];
2861 
2862 QCString VhdlDocGen::parseForBinding(QCString & entity,QCString & arch)
2863 {
2864  int index;
2865  QRegExp exp("[()\\s]");
2866 
2867  QCString label="";
2868  QStringList ql=QStringList::split(exp,entity,FALSE);
2869 
2870  if (ql.contains("open"))
2871  {
2872  return "open";
2873  }
2874 
2875  label=ql[0].utf8();
2876 
2877  entity = ql[1].utf8();
2878  if ((index=entity.findRev("."))>=0)
2879  {
2880  entity.remove(0,index+1);
2881  }
2882 
2883  if (ql.count()==3)
2884  {
2885  arch=ql[2].utf8();
2886  }
2887  return label;
2888 }
2889 
2890 
2891 
2892  // find class with upper/lower letters
2893  ClassDef* VhdlDocGen::findVhdlClass(const char *className )
2894  {
2895 
2897  ClassDef *cd;
2898  for (;(cd=cli.current());++cli)
2899  {
2900  if (qstricmp(className,cd->name().data())==0)
2901  {
2902  return cd;
2903  }
2904  }
2905  return 0;
2906  }
2907 
2908 
2909 //@param arch bit0:flipflop
2910 //@param binding e.g entity work.foo(bar)
2911 //@param label |label0|label1
2912 // label0:architecture name
2913 //@param confVhdl of configuration file (identifier::entity_name) or
2914 // the architecture if isInlineConf TRUE
2915 //@param isInlineConf
2916 //@param confN List of configurations
2917 
2919 {
2920  QList<Entry> instList=getVhdlInstList();
2921  QListIterator<Entry> eli(instList);
2922  Entry *cur=0;
2923  ClassDef *archClass=0,*entClass=0;
2924  QCString archName;
2925  QCString arcBind,entBind;
2926 
2927  bool others,all;
2928  entBind=conf->binding;
2929  QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind);
2930 
2931  if (qstricmp(conf2,"configuration")==0)
2932  {
2933  QList<VhdlConfNode> confList = getVhdlConfiguration();
2934  VhdlConfNode* vconf;
2935  // bool found=false;
2936  for (uint iter=0;iter<confList.count(); iter++)
2937  {
2938  vconf= (VhdlConfNode *)confList.at(iter);
2939  QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0);
2940  if (n==entBind)
2941  {
2942  // found=true;
2943  entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1);
2944  QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2945  QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2946  a=e+"::"+a;
2947  archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data());
2948  entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data());
2949  break;
2950  }
2951  }
2952  }
2953  else // conf2!=configuration
2954  {
2955  QCString a,c,e;
2956  if (conf->isInlineConf)
2957  {
2958  c=conf->confVhdl;
2959  e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),0);
2960  }
2961  else
2962  {
2963  a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0);
2964  e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1);
2965  c=e+"::"+a;
2966  }
2967  archClass= VhdlDocGen::findVhdlClass(c.data());//Doxygen::classSDict->find(a.data());
2968  entClass= VhdlDocGen::findVhdlClass(e.data()); //Doxygen::classSDict->find(e.data());
2969  }
2970 
2971  QCString label=conf->compSpec.lower();
2972  //label.prepend("|");
2973 
2974  if (!archClass)
2975  {
2976  // err("architecture %s not found ! ",conf->confVhdl.data());
2977  return;
2978  }
2979 
2980  archName=archClass->name();
2981  QCString allOt=VhdlDocGen::getIndexWord(conf->arch.data(),0);
2982  all=allOt.lower()=="all" ;
2983  others= allOt.lower()=="others";
2984 
2985  for (;(cur=eli.current());++eli)
2986  {
2987  if (cur->exception.lower()==label || conf->isInlineConf)
2988  {
2989  QCString archy;
2990 
2991  if (all || others)
2992  {
2993  archy=VhdlDocGen::getIndexWord(conf->arch.data(),1);
2994  }
2995  else
2996  {
2997  archy=conf->arch;
2998  }
2999 
3000  QCString inst1=VhdlDocGen::getIndexWord(archy.data(),0).lower();
3001  QCString comp=VhdlDocGen::getIndexWord(archy.data(),1).lower();
3002 
3003  QStringList ql=QStringList::split(",",inst1);
3004 
3005  for (uint j=0;j<ql.count();j++)
3006  {
3007  QCString archy1,sign1;
3008  if (all || others)
3009  {
3010  archy1=VhdlDocGen::getIndexWord(conf->arch.data(),1);
3011  sign1=cur->type;
3012  }
3013  else
3014  {
3015  archy1=comp+":"+ql[j].utf8();
3016  sign1=cur->type+":"+cur->name;
3017  }
3018 
3019  if (archy1==sign1.lower() && !cur->stat)
3020  {
3021  // fprintf(stderr," \n label [%s] [%s] [%s]",cur->exception.data(),cur->type.data(),cur->name.data());
3022  ClassDef *ent= VhdlDocGen::findVhdlClass(entBind.data());//Doxygen::classSDict->find(entBind.data());
3023 
3024  if (entClass==0 || ent==0)
3025  {
3026  continue;
3027  }
3028 
3029  addInstance(ent,archClass,entClass,cur);
3030  cur->stat=TRUE;
3031  break;
3032  }
3033  }// for
3034  }
3035  }//for each element in instList
3036 
3037 }//assignBinding
3038 
3039 /*
3040 
3041 // file foo.vhd
3042 // enitity foo
3043 // .....
3044 // end entity
3045 
3046 // file foo_arch.vhd
3047 // architecture xxx of foo is
3048 // ........
3049 // end architecture
3050 
3051 */
3053 {
3054 
3055  QCString entity,arch,inst;
3056  QList<VhdlConfNode> confList = getVhdlConfiguration();
3057 
3058  for (uint iter=0;iter<confList.count(); iter++)
3059  {
3060  VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter);
3061  if (!(conf->isInlineConf || conf->isLeaf))
3062  {
3063  continue;
3064  }
3065  assignBinding(conf);
3066  }
3067 
3068  QList<Entry> qsl= getVhdlInstList();
3069  QListIterator<Entry> eli(qsl);
3070  Entry *cur;
3071 
3072  for (eli.toFirst();(cur=eli.current());++eli)
3073  {
3074  if (cur->stat ) // was bind
3075  {
3076  continue;
3077  }
3078 
3079  if (cur->includeName=="entity" || cur->includeName=="component" )
3080  {
3081  entity=cur->includeName+" "+cur->type;
3082  QCString rr=VhdlDocGen::parseForBinding(entity,arch);
3083  }
3084  else if (cur->includeName.isEmpty())
3085  {
3086  entity=cur->type;
3087  }
3088 
3089  ClassDef *classEntity= VhdlDocGen::findVhdlClass(entity.data());//Doxygen::classSDict->find(entity);
3090  inst=VhdlDocGen::getIndexWord(cur->args.data(),0);
3091  ClassDef *cd=Doxygen::classSDict->find(inst);
3093 
3094  if (cd==0)
3095  {
3096  continue;
3097  }
3098 
3099  // if (classEntity==0)
3100  // err("%s:%d:Entity:%s%s",cur->fileName.data(),cur->startLine,entity.data()," could not be found");
3101 
3102  addInstance(classEntity,ar,cd,cur);
3103  }
3104 
3105 }
3106 
3107 static void addInstance(ClassDef* classEntity, ClassDef* ar,
3108  ClassDef *cd , Entry *cur,ClassDef* /*archBind*/)
3109 {
3110 
3111  QCString bName,n1;
3112  if (ar==0) return;
3113 
3114  if (classEntity==0)
3115  {
3116  //add component inst
3117  n1=cur->type;
3118  goto ferr;
3119  }
3120 
3121  if (classEntity==cd) return;
3122 
3123  bName=classEntity->name();
3124  // fprintf(stderr,"\naddInstance %s to %s %s %s\n", classEntity->name().data(),cd->name().data(),ar->name().data(),cur->name);
3125  n1=classEntity->name().data();
3126 
3127  if (!cd->isBaseClass(classEntity, true, 0))
3128  {
3129  cd->insertBaseClass(classEntity,n1,Public,Normal,0);
3130  }
3131  else
3132  {
3133  VhdlDocGen::addBaseClass(cd,classEntity);
3134  }
3135 
3136  if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
3137  {
3138  classEntity->insertSubClass(cd,Public,Normal,0);
3139  classEntity->setLanguage(SrcLangExt_VHDL);
3140  }
3141 
3142 ferr:
3143  QCString uu=cur->name;
3144  MemberDef *md=new MemberDef(
3145  ar->getDefFileName(), cur->startLine,cur->startColumn,
3146  n1,uu,uu, 0,
3147  Public, Normal, cur->stat,Member,
3149  0,
3150  0);
3151 
3152  if (ar->getOutputFileBase())
3153  {
3154  TagInfo tg;
3155  tg.anchor = 0;
3156  tg.fileName = ar->getOutputFileBase();
3157  tg.tagName = 0;
3158  md->setTagInfo(&tg);
3159  }
3160 
3161  //fprintf(stderr,"\n%s%s%s\n",md->name().data(),cur->brief.data(),cur->doc.data());
3162 
3165  md->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
3166  md->setBodySegment(cur->startLine,-1) ;
3167  md->setDocumentation(cur->doc.data(),cur->docFile.data(),cur->docLine);
3168  FileDef *fd=ar->getFileDef();
3169  md->setBodyDef(fd);
3170 
3171 
3172  QCString info="Info: Elaborating entity "+n1;
3173  fd=ar->getFileDef();
3174  info+=" for hierarchy ";
3175  QRegExp epr("[|]");
3176  QCString label=cur->type+":"+cur->write+":"+cur->name;
3177  label.replace(epr,":");
3178  info+=label;
3179  fprintf(stderr,"\n[%s:%d:%s]\n",fd->fileName().data(),cur->startLine,info.data());
3180 
3181 
3182  ar->insertMember(md);
3183 
3184 }
3185 
3186 
3187 void VhdlDocGen::writeRecorUnit(QCString & largs,OutputList& ol ,const MemberDef *mdef)
3188 {
3189  QStringList ql=QStringList::split("#",largs,FALSE);
3190  uint len=ql.count();
3191  for(uint i=0;i<len;i++)
3192  {
3193  QCString n=ql[i].utf8();
3194  VhdlDocGen::formatString(n,ol,mdef);
3195  if ((len-i)>1) ol.lineBreak();
3196  }
3197 }
3198 
3199 
3201  const MemberDef *md,
3202  OutputList& ol,
3203  QCString largs)
3204 {
3205 
3206  QStringList ql=QStringList::split("#",largs,FALSE);
3207  uint len=ql.count();
3208  ol.startParameterList(TRUE);
3209  bool first=TRUE;
3210 
3211  for(uint i=0;i<len;i++)
3212  {
3213  QCString n=ql[i].utf8();
3214  ol.startParameterType(first,"");
3215  ol.endParameterType();
3216  ol.startParameterName(TRUE);
3217  VhdlDocGen::formatString(n,ol,md);
3218  if ((len-i)>1)
3219  {
3220  ol.endParameterName(FALSE,FALSE,FALSE);
3221  }
3222  else
3223  {
3224  ol.endParameterName(TRUE,FALSE,TRUE);
3225  }
3226 
3227  first=FALSE;
3228  }
3229 
3230 }//#
3231 
3232 
3233 
3234 bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
3235 {
3236  bool found=FALSE;
3237  //printf("isBaseClass(cd=%s) looking for %s\n",name().data(),bcd->name().data());
3238  if (level>255)
3239  {
3240  err("Possible recursive class relation while inside %s and looking for %s\n",qPrint(cd->name()),qPrint(scd->name()));
3241  abort();
3242  return FALSE;
3243  }
3244 
3245  if (cd->subClasses())
3246  {
3247  BaseClassListIterator bcli(*cd->subClasses());
3248  for ( ; bcli.current() && !found ; ++bcli)
3249  {
3250  ClassDef *ccd=bcli.current()->classDef;
3251  if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
3252  //printf("isSubClass() subclass %s\n",ccd->name().data());
3253  if (ccd==scd)
3254  {
3255  found=TRUE;
3256  }
3257  else
3258  {
3259  if (level <256)
3260  {
3261  found=ccd->isBaseClass(scd,followInstances,level+1);
3262  }
3263  }
3264  }
3265  }
3266  return found;
3267 }
3268 
3270 {
3271  if (cd->baseClasses())
3272  {
3273  BaseClassListIterator bcli(*cd->baseClasses());
3274  for ( ; bcli.current() ; ++bcli)
3275  {
3276  ClassDef *ccd=bcli.current()->classDef;
3277  if (ccd==ent)
3278  {
3279  QCString n = bcli.current()->usedName;
3280  int i = n.find('(');
3281  if(i<0)
3282  {
3283  bcli.current()->usedName.append("(2)");
3284  return;
3285  }
3286  static QRegExp reg("[0-9]+");
3287  QCString s=n.left(i);
3288  QCString r=n.right(n.length()-i);
3289  QCString t=r;
3292  r.setNum(r.toInt()+1);
3293  t.replace(reg,r.data());
3294  s.append(t.data());
3295  bcli.current()->usedName=s;
3296  bcli.current()->templSpecifiers=t;
3297  }
3298  }
3299  }
3300 }
3301 
3302 
3303 static QList<MemberDef> mdList;
3304 
3305 static MemberDef* findMemFlow(const MemberDef* mdef)
3306 {
3307  for(uint j=0;j<mdList.count();j++)
3308  {
3309  MemberDef* md=(MemberDef*)mdList.at(j);
3310  if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
3311  return md;
3312  }
3313  return 0;
3314 }
3315 
3317 {
3318  if (mdef==0) return;
3319 
3320  QCString codeFragment;
3321  MemberDef* mm=0;
3322  if((mm=findMemFlow(mdef))!=0)
3323  {
3324  // don't create the same flowchart twice
3326  return;
3327  }
3328  else
3329  {
3330  mdList.append(mdef);
3331  }
3332 
3333  //fprintf(stderr,"\n create flow mem %s %p\n",mdef->name().data(),mdef);
3334 
3335  int actualStart= mdef->getStartBodyLine();
3336  int actualEnd=mdef->getEndBodyLine();
3337  FileDef* fd=mdef->getFileDef();
3338  bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment);
3339  if (!b) return;
3340 
3341  VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd");
3343  Entry root;
3344  QStrList filesInSameTu;
3345  pIntf->startTranslationUnit("");
3346  pIntf->parseInput("",codeFragment.data(),&root,FALSE,filesInSameTu);
3347  pIntf->finishTranslationUnit();
3348 }
3349 
3351 {
3352  varMap.clear();
3353  qli.clear();
3354  packages.clear();
3355 }
3356 
3358 { return mdef->getMemberSpecifiers()==VhdlDocGen::UCF_CONST; }
3360 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONFIG; }
3362 { return mdef->getMemberSpecifiers()==VhdlDocGen::ALIAS; }
3364 { return mdef->getMemberSpecifiers()==VhdlDocGen::LIBRARY; }
3366 { return mdef->getMemberSpecifiers()==VhdlDocGen::GENERIC; }
3368 { return mdef->getMemberSpecifiers()==VhdlDocGen::PORT; }
3370 { return mdef->getMemberSpecifiers()==VhdlDocGen::COMPONENT; }
3372 { return mdef->getMemberSpecifiers()==VhdlDocGen::USE; }
3374 { return mdef->getMemberSpecifiers()==VhdlDocGen::ENTITY; }
3376 { return mdef->getMemberSpecifiers()==VhdlDocGen::CONSTANT; }
3378 { return mdef->getMemberSpecifiers()==VhdlDocGen::TYPE; }
3380 { return mdef->getMemberSpecifiers()==VhdlDocGen::SUBTYPE; }
3382 { return mdef->getMemberSpecifiers()==VhdlDocGen::FUNCTION; }
3384 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCESS; }
3386 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3388 { return mdef->getMemberSpecifiers()==VhdlDocGen::ATTRIBUTE; }
3390 { return mdef->getMemberSpecifiers()==VhdlDocGen::SIGNAL; }
3392 { return mdef->getMemberSpecifiers()==VhdlDocGen::PROCEDURE; }
3394 { return mdef->getMemberSpecifiers()==VhdlDocGen::RECORD; }
3396 { return mdef->getMemberSpecifiers()==VhdlDocGen::ARCHITECTURE; }
3398 { return mdef->getMemberSpecifiers()==VhdlDocGen::UNITS; }
3400 { return mdef->getMemberSpecifiers()==VhdlDocGen::PACKAGE_BODY; }
3404 { return mdef->getMemberSpecifiers()==VhdlDocGen::VFILE; }
3406 { return mdef->getMemberSpecifiers()==VhdlDocGen::GROUP; }
3411 
3412 
3413 
3414 //############################## Flowcharts #################################################
3415 
3416 #define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
3417  FlowChart::FOR_NO | FlowChart::CASE_NO | \
3418  FlowChart::LOOP_NO | WHEN_NO)
3419 #define DECLN (FlowChart::WHEN_NO | \
3420  FlowChart::ELSIF_NO | FlowChart::IF_NO | \
3421  FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3422  FlowChart::CASE_NO | FlowChart::LOOP_NO )
3423 #define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
3424 #define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
3425  FlowChart::LOOP_NO )
3426 #define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
3427 #define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
3428 #define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
3429 #define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
3430 #define EMPTY (EEND | FlowChart::ELSIF_NO)
3431 #define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
3432 #define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
3433 #define FLOWLEN (flowList.count()-1)
3434 
3435 static int ifcounter=0;
3436 static int nodeCounter=0;
3437 
3438 static struct
3439 {
3440  // link colors
3441  const char *textNodeLink;
3442  const char *yesNodeLink;
3443  const char *noNodeLink;
3444 
3445  // node colors
3446  const char* comment;
3447  const char* decisionNode;
3448  const char* varNode;
3449  const char *startEndNode;
3450  const char* textNode;
3451 } flowCol =
3452 { "green", // textNodeLink
3453  "red", // yesNodeLink
3454  "black", // noNodeLink
3455  "khaki", // comment
3456  "0.7 0.3 1.0", // decisionNode
3457  "lightyellow", // varNode
3458  "white", // startEndNode
3459  "lightcyan" // textNode
3460 };
3461 
3462 QList<FlowChart> FlowChart::flowList;
3463 
3464 #ifdef DEBUGFLOW
3465 static QMap<QCString,int> keyMap;
3466 #endif
3467 
3468 void alignText(QCString & q)
3469 {
3470  if (q.length()<=80) return;
3471 
3472  if (q.length()>200)
3473  {
3474  q.resize(200);
3475  }
3476 
3477  q.append(" ...");
3478 
3479  QRegExp reg("[\\s|]");
3480  QCString str(q.data());
3481  QCString temp;
3482 
3483  while (str.length()>80)
3484  {
3485  int j=str.findRev(reg,80);
3486  if (j<=0)
3487  {
3488  temp+=str;
3489  q=temp;
3490  return;
3491  }
3492  else
3493  {
3494  QCString qcs=str.left(j);
3495  temp+=qcs+"\\";
3496  temp+="n";
3497  str.remove(0,j);
3498  }
3499  }//while
3500 
3501  q=temp+str;
3502 // #endif
3503 }
3504 
3506 {
3507  if (flo==0) return;
3508  QCString ui="-";
3509  QCString q,t;
3510  QRegExp ep("[\t\n\r]");
3511 
3512  ui.fill('-',255);
3513 
3514  if (flo->type & STARTL)
3515  {
3516  if (flo->stamp>0)
3517  {
3518  q=ui.left(2*flo->stamp);
3519  }
3520  else
3521  {
3522  q=" ";
3523  }
3524  QCString nn=flo->exp.stripWhiteSpace();
3525  printf("\nYES: %s%s[%d,%d]",q.data(),nn.data(),flo->stamp,flo->id);
3526  }
3527  else
3528  {
3529  if (flo->type & COMMENT_NO)
3530  {
3531  t=flo->label;
3532  }
3533  else
3534  {
3535  t=flo->text;
3536  }
3537  t=t.replace(ep,"");
3538  if (t.isEmpty())
3539  {
3540  t=" ";
3541  }
3542  if (flo->stamp>0)
3543  {
3544  q=ui.left(2*flo->stamp);
3545  }
3546  else
3547  {
3548  q=" ";
3549  }
3550  if (flo->type & EMPTNODE)
3551  {
3552  printf("\n NO: %s%s[%d,%d]",q.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3553  }
3554  else if (flo->type & COMMENT_NO)
3555  {
3556  printf("\n NO: %s%s[%d,%d]",t.data(),FlowChart::getNodeType(flo->type),flo->stamp,flo->id);
3557  }
3558  else
3559  {
3560  printf("\n NO: %s[%d,%d]",t.data(),flo->stamp,flo->id);
3561  }
3562  }
3563 }
3564 
3566 {
3567  uint size=flowList.count();
3568  for (uint j=0;j<size;j++)
3569  {
3570  printNode(flowList.at(j));
3571  }
3572 }
3573 
3575 {
3576  QCString text;
3577  FlowChart *flno;
3578  bool found=FALSE;
3579  for (uint j=0;j<flowList.count();j++)
3580  {
3581  FlowChart *flo=flowList.at(j);
3582  if (flo->type&TEXT_NO)
3583  {
3584  text+=flo->text+'\n';
3585  if (!found)
3586  {
3587  flno=flo;
3588  }
3589  if (found)
3590  {
3591  flno->text+=flo->text;
3592  flowList.remove(flo);
3593  if (j>0) j=j-1;
3594  }
3595  found=TRUE;
3596  }
3597  else
3598  found=FALSE;
3599  }
3600 
3601  // find if..endif without text
3602  // if..elseif without text
3603  for (uint j=0;j<flowList.count()-1;j++)
3604  {
3605  FlowChart *flo=flowList.at(j);
3606  int kind=flo->type;
3607  if ( (kind & IFF) || (flo->type & ELSE_NO))
3608  {
3609  FlowChart *ftemp=flowList.at(j+1);
3610  if (ftemp->type & EMPTY)
3611  {
3612  FlowChart *fNew = new FlowChart(TEXT_NO,"empty ",0);
3613  fNew->stamp=flo->stamp;
3614  flowList.insert(j+1,fNew);
3615  }
3616  }
3617  }
3618 
3619 }// colTextNode
3620 
3621 QCString FlowChart::getNodeName(int n)
3622 {
3623  QCString node;
3624  node.setNum(n);
3625  return node.prepend("node");
3626 }
3627 
3629 {
3630  ifcounter=0;
3631  nodeCounter=0;
3632  uint size=flowList.count();
3633 
3634  for (uint j=0;j <size ;j++)
3635  {
3636  FlowChart *fll=flowList.at(j);
3637  delete fll;
3638  }
3639  flowList.clear();
3640 }
3641 
3643 {
3644  uint max=0;
3645  QCString s;
3646  QStringList ql=QStringList::split("\n",com);
3647  for (uint j=0;j<ql.count();j++)
3648  {
3649  s=(QCString)ql[j].utf8();
3650  if (max<s.length()) max=s.length();
3651  }
3652 
3653  s=ql.last().utf8();
3654  int diff=max-s.length();
3655 
3656  QCString n(1);
3657  if (diff>0)
3658  {
3659  n.fill(' ',2*diff);
3660  n.append(".");
3661  s+=n;
3662  ql.remove(ql.last());
3663  ql.append(s);
3664  }
3665 
3666  for (uint j=0;j<ql.count();j++)
3667  {
3668  s=(QCString)ql[j].utf8();
3669  if (j<ql.count()-1)
3670  {
3671  s+="\n";
3672  }
3673  FlowChart::codify(t,s.data());
3674  }
3675 }
3676 
3677 
3679 {
3680  uint size=flowList.count();
3681  bool begin=false;
3682 
3683  for (uint j=0;j < size-1 ;j++)
3684  {
3685  FlowChart *fll=flowList.at(j);
3686  if (fll->type & COMMENT_NO)
3687  {
3688  FlowChart* to=flowList.at(j+1);
3689  if (to->type & COMMENT_NO)
3690  {
3691  fll->label+="\n";
3692  QCString temp=fll->label+to->label;
3693  to->label=temp;
3694  flowList.remove(j);
3695  size--;
3696  if (j>0) j--;
3697  }
3698  }
3699  }// for
3700 
3701  for (uint j=0;j <flowList.count() ;j++)
3702  {
3703  FlowChart *fll=flowList.at(j);
3704 
3705  if (fll->type & BEGIN_NO)
3706  {
3707  begin = true;
3708  continue;
3709  }
3710 
3711  if (fll->type & COMMENT_NO)
3712  {
3713  FlowChart* to;
3714  if (!begin)
3715  {
3716  // comment between function/process .. begin is linked to start node
3717  to=flowList.at(0);
3718  }
3719  else
3720  {
3721  if (j>0 && flowList.at(j-1)->line==fll->line)
3722  to=flowList.at(j-1);
3723  else
3724  to=flowList.at(j+1);
3725  }
3726  t << getNodeName(fll->id);
3727  t << "[shape=none, label=<\n";
3728  t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
3729  t << "<TR><TD BGCOLOR=\"";
3730  t << flowCol.comment;
3731  t << "\" > ";
3732 
3734  t << " </TD></TR></TABLE>>];";
3735  writeEdge(t,fll->id,to->id,2);
3736  }
3737  }// for
3738 
3739  // delete comment nodes;
3740  size=flowList.count();
3741  for (uint j=0;j < size;j++)
3742  {
3743  FlowChart *fll=flowList.at(j);
3744  if (fll->type & (COMMENT_NO | BEGIN_NO))
3745  {
3746  int diff=FLOWLEN-(j+1);
3747  flowList.remove(j);
3748 
3749  if ((fll->type & COMMENT_NO) && diff > 1)
3750  flowList.at(j+1)->label=fll->label;
3751 
3752  delete fll;
3753  fll=0;
3754  size--;
3755  if (j>0) j--;
3756  }
3757  }// for;
3758 }
3759 
3760 void FlowChart::codify(FTextStream &t,const char *str)
3761 {
3762  if (str)
3763  {
3764  const char *p=str;
3765  char c;
3766  while (*p)
3767  {
3768  c=*p++;
3769  switch(c)
3770  {
3771  case '<': t << "&lt;"; break;
3772  case '>': t << "&gt;"; break;
3773  case '&': t << "&amp;"; break;
3774  case '\'': t << "&#39;"; break;
3775  case '"': t << "&quot;"; break;
3776  case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
3777  default: t << c; break;
3778  }
3779  }
3780  }
3781 }//codify
3782 
3784 {
3785 }
3786 
3787 FlowChart::FlowChart(int typ,const char * t,const char* ex,const char* lab)
3788 {
3789  stamp=ifcounter;
3790 
3791  if (typ & STARTL)
3792  {
3793  ifcounter++;
3794  }
3795 
3796  text=t;
3797  exp=ex;
3798  type=typ;
3799  label=lab;
3800 
3801  if (typ & (ELSE_NO | ELSIF_NO))
3802  {
3803  stamp--;
3804  }
3805 
3806  if (typ & (START_NO | END_NO | VARIABLE_NO))
3807  {
3808  stamp=0;
3809  }
3810 
3811  id=nodeCounter++;
3812 }
3813 
3814 void FlowChart::addFlowChart(int type,const char* text,const char* exp, const char *label)
3815 {
3816  static QRegExp reg("[;]");
3817  static QRegExp reg1("[\"]");
3818 
3819  if (!VhdlDocGen::getFlowMember()) return;
3820 
3821  QCString typeString(text);
3822  QCString expression(exp);
3823 
3824 
3825  if (text)
3826  {
3827  typeString=typeString.replace(reg,"\n");
3828  }
3829 
3830  if (exp)
3831  {
3832  expression=expression.replace(reg1,"\\\"");
3833  }
3834 
3835  FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label);
3836 
3837  fl->line=vhdl::parser::VhdlParser::getLine();
3838 
3839  if (type & (START_NO | VARIABLE_NO))
3840  {
3841  flowList.prepend(fl);
3842  }
3843  else
3844  {
3845  flowList.append(fl);
3846  }
3847 }
3848 
3850 {
3851  if (!VhdlDocGen::getFlowMember()) return;
3852  ifcounter--;
3853 }
3854 
3855 QCString FlowChart::printPlantUmlNode(const FlowChart *flo,bool ca,bool endL)
3856 {
3857  QCString t;
3858  QCString exp=flo->exp.stripWhiteSpace();
3859  QCString text=flo->text.stripWhiteSpace();
3860  switch (flo->type)
3861  {
3862  case START_NO: t=":"+text+"|"; break;
3863  case IF_NO : t="\nif ("+exp+") then (yes)"; break;
3864  case ELSIF_NO: t="\nelseif ("+exp+") then (yes)"; break;
3865  case ELSE_NO: t="\nelse"; break;
3866  case CASE_NO: t="\n:"+exp+";"; break;
3867  case WHEN_NO: t="\n";
3868  if (!ca) t+="else";
3869  t+="if ("+exp+") then (yes)";
3870  break;
3871  case EXIT_NO: break;
3872  case END_NO: if (text.contains(" function")==0) t="\n:"+text+";";
3873  break;
3874  case TEXT_NO: t="\n:"+text+"]"; break;
3875  case ENDIF_NO: t="\nendif"; break;
3876  case FOR_NO: t="\nwhile ("+exp+") is (yes)"; break;
3877  case WHILE_NO: t="\nwhile ("+exp+") is (yes)"; break;
3878  case END_LOOP: t="\nendwhile"; break;
3879  case END_CASE: t="\nendif\n:end case;"; break;
3880  case VARIABLE_NO:t="\n:"+text+";"; break;
3881  case RETURN_NO: t="\n:"+text+";";
3882  if (!endL) t+="\nstop";
3883  break;
3884  case LOOP_NO: t="\nwhile (infinite loop)"; break;
3885  case NEXT_NO: break;
3886  case EMPTY_NO: break;
3887  case COMMENT_NO: t="\n note left \n "+flo->label+"\nend note \n"; break;
3888  case BEGIN_NO: t="\n:begin;"; break;
3889  default: assert(false); break;
3890  }
3891  return t;
3892 }
3893 
3895 {
3896  int caseCounter = 0;
3897  int whenCounter = 0;
3898 
3899  QCString qcs;
3900  uint size=flowList.count();
3901  bool endList;
3902  for (uint j=0;j<size;j++)
3903  {
3904  endList=j==FLOWLEN;
3905  FlowChart *flo=flowList.at(j);
3906  if (flo->type==CASE_NO)
3907  {
3908  caseCounter++;
3909  whenCounter=0;
3910  }
3911 
3912  if (flo->type==END_CASE)
3913  {
3914  caseCounter--;
3915  }
3916 
3917  bool ca = (caseCounter>0 && whenCounter==0);
3918 
3919  qcs+=printPlantUmlNode(flo,ca,endList);
3920 
3921  if (flo->type==WHEN_NO)
3922  {
3923  whenCounter++;
3924  }
3925 
3926  }
3927  qcs+="\n";
3928 
3929  QCString & htmlOutDir = Config_getString(HTML_OUTPUT);
3930 
3931  QCString n=convertNameToFileName();
3932  QCString tmp=htmlOutDir;
3933  n=writePlantUMLSource(tmp,n,qcs);
3934  generatePlantUMLOutput(n.data(),tmp.data(),PUML_SVG);
3935 }
3936 
3938 {
3939  static QRegExp exp ("[^][a-z_A-Z0-9]");
3940  QCString temp,qcs;
3942 
3943  // temp.sprintf("%p",md);
3944  qcs=md->name();
3945 
3946  #if 0
3947  if (qcs.find(exp,0)>=0)
3948  {
3949  qcs.prepend("Z");
3950  qcs=qcs.replace(exp,"_");
3951  }
3952  #endif
3953 
3954  //QCString tt= qcs;VhdlDocGen::getRecordNumber();
3955  return qcs;
3956 }
3957 
3958 const char* FlowChart::getNodeType(int c)
3959 {
3960  switch(c)
3961  {
3962  case IF_NO: return "if ";
3963  case ELSIF_NO: return "elsif ";
3964  case ELSE_NO: return "else ";
3965  case CASE_NO: return "case ";
3966  case WHEN_NO: return "when ";
3967  case EXIT_NO: return "exit ";
3968  case END_NO: return "end ";
3969  case TEXT_NO: return "text ";
3970  case START_NO: return "start ";
3971  case ENDIF_NO: return "endif ";
3972  case FOR_NO: return "for ";
3973  case WHILE_NO: return "while ";
3974  case END_LOOP: return "end_loop ";
3975  case END_CASE: return "end_case ";
3976  case VARIABLE_NO: return "variable_decl ";
3977  case RETURN_NO: return "return ";
3978  case LOOP_NO: return "infinite loop ";
3979  case NEXT_NO: return "next ";
3980  case COMMENT_NO: return "comment ";
3981  case EMPTY_NO: return "empty ";
3982  case BEGIN_NO: return "<begin> ";
3983  default: return "--failure--";
3984  }
3985 }
3986 
3988 {
3989  QCString qcs("/");
3990  QCString ov = Config_getString(HTML_OUTPUT);
3991 
3992  qcs+=FlowChart::convertNameToFileName()+".svg";
3993 
3994  //const MemberDef *m=VhdlDocGen::getFlowMember();
3995  //if (m)
3996  // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",VhdlDocGen::trTypeString(m->getMemberSpecifiers()),m->name().data(),m->getFileDef()->name().data());
3997 
3998  QCString dir=" -o "+ov+qcs;
3999  ov+="/flow_design.dot";
4000 
4001  QCString vlargs="-Tsvg "+ov+dir ;
4002 
4003  if (portable_system("dot",vlargs)!=0)
4004  {
4005  err("could not create dot file");
4006  }
4007 }
4008 
4010 {
4011  t << " digraph G { \n";
4012  t << "rankdir=TB \n";
4013  t << "concentrate=true\n";
4014  t << "stylesheet=\"doxygen.css\"\n";
4015 }
4016 
4018 {
4019  t << " } \n";
4020 }
4021 
4023 {
4024  // assert(VhdlDocGen::flowMember);
4025 
4026  QCString ov = Config_getString(HTML_OUTPUT);
4027  QCString fileName = ov+"/flow_design.dot";
4028  QFile f(fileName);
4029  FTextStream t(&f);
4030 
4031  if (!f.open(IO_WriteOnly))
4032  {
4033  err("Cannot open file %s for writing\n",fileName.data());
4034  return;
4035  }
4036 
4037  colTextNodes();
4038  // buildCommentNodes(t);
4039 
4040 #ifdef DEBUGFLOW
4041  printFlowTree();
4042 #endif
4044 
4045  if (p->isStatic())
4046  {
4047  printUmlTree();
4048  delFlowList();
4049  f.close();
4050  return;
4051  }
4052 
4053  startDot(t);
4054  buildCommentNodes(t);
4055  uint size=flowList.count();
4056 
4057  for (uint j=0;j <size ;j++)
4058  {
4059  FlowChart *fll=flowList.at(j);
4060  writeShape(t,fll);
4061  }
4062  writeFlowLinks(t);
4063 
4064  FlowChart::endDot(t);
4065  delFlowList();
4066  f.close();
4068 }// writeFlowChart
4069 
4071 {
4072  if (fl->type & EEND) return;
4073  QCString var;
4074  if (fl->type & LOOP)
4075  {
4076  var=" loop";
4077  }
4078  else if (fl->type & IFF)
4079  {
4080  var=" then";
4081  }
4082  else
4083  {
4084  var="";
4085  }
4086 
4087  t<<getNodeName(fl->id).data();
4088 
4089 #ifdef DEBUGFLOW
4090  QCString qq(getNodeName(fl->id).data());
4091  keyMap.insert(qq,fl->id);
4092 #endif
4093 
4094  bool dec=(fl->type & DECLN);
4095  bool exit=(fl->type & EXITNEXT);
4096  if (exit && !fl->exp.isEmpty())
4097  {
4098  dec=TRUE;
4099  }
4100  if (dec)
4101  {
4102  QCString exp=fl->exp;
4103  alignText(exp);
4104 
4105  t << " [shape=diamond,style=filled,color=\"";
4106  t << flowCol.decisionNode;
4107  t << "\",label=\" ";
4108  QCString kl;
4109  if (exit) kl=fl->text+" ";
4110 
4111  if (fl->label)
4112  {
4113  kl+=fl->label+":"+exp+var;
4114  }
4115  else
4116  {
4117  kl+=exp+var;
4118  }
4119 
4121  t << "\"]\n";
4122  }
4123  else if (fl->type & ENDCL)
4124  {
4125  QCString val=fl->text;
4126  t << " [shape=ellipse ,label=\""+val+"\"]\n";
4127  }
4128  else if (fl->type & STARTFIN)
4129  {
4130  QCString val=fl->text;
4131  t << "[shape=box , style=rounded label=<\n";
4132  t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
4133  t << "<TR><TD BGCOLOR=\"";
4134  t<< flowCol.startEndNode;
4135  t<< "\"> ";
4137  t << " </TD></TR></TABLE>>];";
4138  }
4139  else
4140  {
4141  if (fl->text.isEmpty()) return;
4142  bool var=(fl->type & FlowChart::VARIABLE_NO);
4143  QCString q=fl->text;
4144 
4145  if (exit)
4146  {
4147  q+=" "+fl->label;
4148  }
4149 
4150  int z=q.findRev("\n");
4151 
4152  if (z==(int)q.length()-1)
4153  {
4154  q=q.remove(z,2);
4155  }
4156  t << "[shape=none margin=0.1, label=<\n";
4157  t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
4158  if (var)
4159  {
4160  t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
4161  }
4162  else
4163  {
4164  t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
4165  }
4167  t << " </TD></TR></TABLE>>];";
4168  }
4169 }
4170 
4171 
4172 void FlowChart::writeEdge(FTextStream &t,const FlowChart* fl_from,const FlowChart* fl_to,int i)
4173 {
4174  bool b=fl_from->type & STARTL;
4175  bool c=fl_to->type & STARTL;
4176 
4177 #ifdef DEBUGFLOW
4178  QCString s1(getNodeName(fl_from->id).data());
4179  QCString s2(getNodeName(fl_to->id).data());
4180  QMap<QCString, int>::Iterator it = keyMap.find(s1);
4181  QMap<QCString, int>::Iterator it1 = keyMap.find(s2);
4182  // checks if the link is connected to a valid node
4183  assert(it.key());
4184  assert(it1.key());
4185 #endif
4186 
4187  writeEdge(t,fl_from->id,fl_to->id,i,b,c);
4188 }
4189 
4190 void FlowChart::writeEdge(FTextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
4191 {
4192  QCString label,col;
4193 
4194  if (i==0)
4195  {
4196  col=flowCol.yesNodeLink;
4197  label="yes";
4198  }
4199  else if (i==1)
4200  {
4201  col=flowCol.noNodeLink;
4202  label="no";
4203  }
4204  else
4205  {
4206  col=flowCol.textNodeLink;
4207  label="";
4208  }
4209 
4210  t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
4211  t << getNodeName(fl_from).data();
4212  if (bFrom) t << ":s";
4213  t << "->";
4214  t << getNodeName(fl_to).data();
4215  if (bTo) t << ":n";
4216  t << "\n";
4217 }
4218 
4219 void FlowChart::alignFuncProc( QCString & q,const ArgumentList* al,bool isFunc)
4220 {
4221  if (al==0) return;
4222 
4223  ArgumentListIterator ali(*al);
4224  int index=ali.count();
4225  if (index==0) return;
4226 
4227  int len=q.length()+VhdlDocGen::getFlowMember()->name().length();
4228  QCString prev,temp;
4229  prev.fill(' ',len+1);
4230 
4231  Argument *arg;
4232  q+="\n";
4233  for (;(arg=ali.current());++ali)
4234  {
4235  QCString attl=arg->defval+" ";
4236  attl+=arg->name+" ";
4237 
4238  if (!isFunc)
4239  {
4240  attl+=arg->attrib+" ";
4241  }
4242  else
4243  {
4244  attl+=" in ";
4245  }
4246  attl+=arg->type;
4247  if (--index) attl+=",\n"; else attl+="\n";
4248 
4249  attl.prepend(prev.data());
4250  temp+=attl;
4251  }
4252 
4253  q+=temp;
4254 }
4255 
4256 int FlowChart::findNextLoop(int index,int stamp)
4257 {
4258  for (uint j=index+1;j<flowList.count();j++)
4259  {
4260  FlowChart *flo=flowList.at(j);
4261  if (flo->stamp==stamp)
4262  {
4263  continue;
4264  }
4265  if (flo->type&END_LOOP)
4266  {
4267  return j;
4268  }
4269  }
4270  return flowList.count()-1;
4271 }
4272 
4273 int FlowChart::findPrevLoop(int index,int stamp,bool endif)
4274 {
4275  for (uint j=index;j>0;j--)
4276  {
4277  FlowChart *flo=flowList.at(j);
4278  if (flo->type & LOOP)
4279  {
4280  if (flo->stamp==stamp && endif)
4281  {
4282  return j;
4283  }
4284  else
4285  {
4286  if (flo->stamp<stamp)
4287  {
4288  return j;
4289  }
4290  }
4291  }
4292  }
4293  return flowList.count()-1;
4294 }
4295 
4296 int FlowChart::findLabel(int index,QCString &label)
4297 {
4298  for (uint j=index;j>0;j--)
4299  {
4300  FlowChart *flo=flowList.at(j);
4301  if ((flo->type & LOOP) && !flo->label.isEmpty() && qstricmp(flo->label,label)==0)
4302  {
4303  return j;
4304  }
4305  }
4306  err("could not find label: ",label.data());
4307  return 0;
4308 }
4309 
4310 int FlowChart::findNode(int index,int stamp,int type)
4311 {
4312  for (uint j=index+1;j<flowList.count();j++)
4313  {
4314  FlowChart *flo=flowList.at(j);
4315  if (flo->type==type && flo->stamp==stamp)
4316  {
4317  return j;
4318  }
4319  }
4320  return 0;
4321 }// findNode
4322 
4323 int FlowChart::getNextNode(int index,int stamp)
4324 {
4325  for (uint j=index+1;j<flowList.count();j++)
4326  {
4327  FlowChart *flo=flowList.at(j);
4328  int kind=flo->type;
4329  int s=flo->stamp;
4330  if (s>stamp)
4331  {
4332  continue;
4333  }
4334  if (kind & ENDIF_NO)
4335  {
4336  if (s<stamp && stamp>0)
4337  {
4338  stamp--;
4339  continue;
4340  }
4341  }
4342  if (kind & (ELSE_NO | ELSIF_NO))
4343  {
4344  if (s<stamp && stamp>0)
4345  {
4346  stamp--;
4347  }
4348  j=findNode(j,stamp,ENDIF_NO);
4349  continue;
4350  }
4351  if (kind & WHEN_NO)
4352  {
4353  if (s<stamp && stamp>0)
4354  {
4355  stamp--;
4356  }
4357  return findNode(j,stamp-1,END_CASE);
4358  }
4359  return j;
4360  }
4361  return FLOWLEN;
4362 }
4363 
4364 int FlowChart::getNextIfLink(const FlowChart* fl,uint index)
4365 {
4366  int stamp=fl->stamp;
4367  uint start = index+1;
4368  int endifNode = findNode(start,stamp,ENDIF_NO);
4369  int elseifNode = findNode(start,stamp,ELSIF_NO);
4370  int elseNode = findNode(start,stamp,ELSE_NO);
4371 
4372  assert(endifNode>-1);
4373 
4374  if (elseifNode>0 && elseifNode<endifNode)
4375  {
4376  return elseifNode;
4377  }
4378 
4379  if (elseNode>0 && elseNode<endifNode)
4380  {
4381  return elseNode+1;
4382  }
4383 
4384  stamp=flowList.at(endifNode)->stamp;
4385  return getNextNode(endifNode,stamp);
4386 }
4387 
4389 {
4390  uint size=flowList.count();
4391  if (size<2) return;
4392 
4393  // write start link
4394  writeEdge(t,flowList.at(0),flowList.at(1),2);
4395 
4396  for (uint j=0;j<size;j++)
4397  {
4398  FlowChart *fll=flowList.at(j);
4399  int kind=fll->type;
4400  int stamp=fll->stamp;
4401  if (kind & EEND)
4402  {
4403  continue;
4404  }
4405 
4406  if (kind & IFF)
4407  {
4408  writeEdge(t,fll,flowList.at(j+1),0);
4409  int z=getNextIfLink(fll,j);
4410  // assert(z>-1);
4411  writeEdge(t,fll,flowList.at(z),1);
4412  }
4413  else if (kind & LOOP_NO)
4414  {
4415  writeEdge(t,fll,flowList.at(j+1),2);
4416  continue;
4417  }
4418  else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
4419  {
4420  if (kind & CASE_NO)
4421  {
4422  writeEdge(t,fll,flowList.at(j+1),2);
4423  continue;
4424  }
4425  else
4426  {
4427  writeEdge(t,fll,flowList.at(j+1),0);
4428  }
4429 
4430  kind=END_LOOP;
4431  int z=findNode(j+1,fll->stamp,kind);
4432  z=getNextNode(z,flowList.at(z)->stamp);
4433 
4434  // assert(z>-1);
4435  writeEdge(t,fll,flowList.at(z),1);
4436  continue;
4437  }
4438  else if (kind & (TEXT_NO | VARIABLE_NO))
4439  {
4440  int z=getNextNode(j,stamp);
4441  writeEdge(t,fll,flowList.at(z),2);
4442  }
4443  else if (kind & WHEN_NO)
4444  {
4445  // default value
4446  if (qstricmp(fll->text.simplifyWhiteSpace().data(),"others")==0)
4447  {
4448  writeEdge(t,fll,flowList.at(j+1),2);
4449  continue;
4450  }
4451 
4452 
4453  writeEdge(t,fll,flowList.at(j+1),0);
4454  int u=findNode(j,stamp,WHEN_NO);
4455  int v=findNode(j,stamp-1,END_CASE);
4456 
4457  if (u>0 && u<v)
4458  {
4459  writeEdge(t,fll,flowList.at(u),1);
4460  }
4461  else
4462  {
4463  writeEdge(t,fll,flowList.at(v),1);
4464  }
4465  }
4466  else if (kind & END_CASE)
4467  {
4468  int z=FlowChart::getNextNode(j,fll->stamp);
4469  writeEdge(t,fll,flowList.at(z),2);
4470  }
4471  else if (kind & END_LOOP)
4472  {
4473  int z=findPrevLoop(j,fll->stamp,true);
4474  writeEdge(t,fll,flowList.at(z),2);
4475  }
4476  else if (kind & RETURN_NO)
4477  {
4478  writeEdge(t,fll,FlowChart::flowList.at(size-1),2);
4479  }
4480  else if (kind & (EXIT_NO | NEXT_NO))
4481  {
4482  int z;
4483  bool b = kind==NEXT_NO;
4484  if (fll->exp)
4485  {
4486  writeEdge(t,fll,flowList.at(j+1),1);
4487  }
4488  if (!fll->label.isEmpty())
4489  {
4490  z=findLabel(j,fll->label);
4491  if (b)
4492  {
4493  writeEdge(t,fll,flowList.at(z),0);
4494  }
4495  else
4496  {
4497  z=findNode(z,flowList.at(z)->stamp,END_LOOP);
4498  z=getNextNode(z,flowList.at(z)->stamp);
4499  writeEdge(t,fll,flowList.at(z),0);
4500  }
4501  continue;
4502  }
4503  else
4504  {
4505  if (b)
4506  {
4507  z=findPrevLoop(j,fll->stamp);
4508  writeEdge(t,fll,flowList.at(z),0);
4509  continue;
4510  }
4511  else
4512  {
4513  z =findNextLoop(j,fll->stamp-1);
4514  }
4515  z=getNextNode(z,flowList.at(z)->stamp);
4516  }
4517  writeEdge(t,fll,flowList.at(z),0);
4518  }
4519  } //for
4520 } //writeFlowLinks
4521 
4522 
4524  const char *scopeName,
4525  const QCString &input,
4526  SrcLangExt, // lang
4527  bool isExampleBlock,
4528  const char *exampleName,
4529  FileDef *fileDef,
4530  int startLine,
4531  int endLine,
4532  bool inlineFragment,
4533  MemberDef *memberDef,
4534  bool showLineNumbers,
4535  Definition *searchCtx,
4536  bool collectXRefs
4537  )
4538 {
4539 
4540 parseVhdlCode(codeOutIntf,
4541  scopeName,
4542  input,
4543  isExampleBlock,
4544  exampleName,
4545  fileDef,
4546  startLine,
4547  endLine,
4548  inlineFragment,
4549  memberDef,
4550  showLineNumbers,
4551  searchCtx,
4552  collectXRefs
4553 
4554 );
4555 
4556 
4557 
4558 
4559 
4560 
4561 }// class