Doxygen
Loading...
Searching...
No Matches
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 <map>
28#include <algorithm>
29#include <unordered_set>
30#include <mutex>
31
32/* --------------------------------------------------------------- */
33
34// local includes
35#include "dstring.h"
36#include "vhdldocgen.h"
37#include "message.h"
38#include "config.h"
39#include "doxygen.h"
40#include "util.h"
41#include "language.h"
42#include "commentscan.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 "membername.h"
58#include "plantuml.h"
59#include "vhdljjparser.h"
60#include "VhdlParser.h"
61#include "regex.h"
62#include "textstream.h"
63#include "moduledef.h"
64
65//#define DEBUGFLOW
66#define theTranslator_vhdlType theTranslator->trVhdlType
67
68static void initUCF(Entry* root,const DString &type,DString &qcs,int line,const DString & fileName,DString & brief);
69static void writeUCFLink(const MemberDef* mdef,OutputList &ol);
70static void addInstance(ClassDefMutable* entity, ClassDefMutable* arch, ClassDefMutable *inst,
71 const std::shared_ptr<Entry> &cur);
72
73static const MemberDef *flowMember=nullptr;
74
76{
77 flowMember=mem;
78}
79
81{
82 return flowMember;
83}
84
85//--------------------------------------------------------------------------------------------------
86
87static void writeLink(const MemberDef* mdef,OutputList &ol)
88{
90 mdef->getOutputFileBase(),
91 mdef->anchor(),
92 mdef->name());
93}
94
95static void startFonts(const DString& q, const char *keyword,OutputList& ol)
96{
97 auto &codeOL = ol.codeGenerators();
98 codeOL.startFontClass(keyword);
99 codeOL.codify(q);
100 codeOL.endFontClass();
101}
102
103static DString splitString(DString& str,char c)
104{
105 DString n=str;
106 size_t i=str.find(c);
107 if (i!=DString::npos && i>0)
108 {
109 n=str.left(i);
110 str=str.remove(0,i+1);
111 }
112 return n;
113}
114
115static int compareString(const DString& s1,const DString& s2)
116{
117 return dstricmp(s1.stripWhiteSpace(),s2.stripWhiteSpace());
118}
119
120//--------------------------------------------------------------------------------------------------
121
122 // vhdl keywords included VHDL 2008
123static const std::unordered_set< std::string > g_vhdlKeyWordSet0 =
124{
125 "abs","access","after","alias","all","and","architecture","array","assert","assume","assume_guarantee","attribute",
126 "begin","block","body","buffer","bus",
127 "case","component","configuration","constant","context","cover",
128 "default","disconnect","downto",
129 "else","elsif","end","entity","exit",
130 "fairness","file","for","force","function",
131 "generate","generic","group","guarded",
132 "if","impure","in","inertial","inout","is",
133 "label","library","linkage","literal","loop",
134 "map","mod",
135 "nand","new","next","nor","not","null",
136 "of","on","open","or","others","out",
137 "package","parameter","port","postponed","procedure","process","property","protected","pure",
138 "range","record","register","reject","release","restrict","restrict_guarantee","rem","report","rol","ror","return",
139 "select","sequence","severity","signal","shared","sla","sll","sra","srl","strong","subtype",
140 "then","to","transport","type",
141 "unaffected","units","until","use",
142 "variable","vmode","vprop","vunit",
143 "wait","when","while","with",
144 "xor","xnor"
145};
146
147
148// type
149static const std::unordered_set< std::string> g_vhdlKeyWordSet1 =
150{
151 "natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
152 "std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
153 "real","float","ufixed","sfixed","time","positive"
154};
155
156// logic
157static const std::unordered_set< std::string > g_vhdlKeyWordSet2 =
158{
159 "abs","and","or","not","mod","xor","rem","xnor","ror","rol","sla","sll"
160};
161
162// predefined attributes
163static const std::unordered_set< std::string > g_vhdlKeyWordSet3 =
164{
165 "base","left","right","high","low","ascending",
166 "image","value","pos","val","succ","pred","leftof","rightof","left","right","high","low",
167 "range","reverse_range","length","ascending","delayed","stable","quiet","transaction","event",
168 "active","last_event","last_active","last_value","driving","driving_value","simple_name","instance_name","path_name"
169};
170
172{
173}
174
175/*!
176 * returns the color of a keyword
177 */
178const char* VhdlDocGen::findKeyWord(const DString& kw)
179{
180 std::string word=kw.lower().str();
181
182 if (word.empty()) return nullptr;
183
184 if (g_vhdlKeyWordSet0.find(word)!=g_vhdlKeyWordSet0.end())
185 return "keywordflow";
186
187 if (g_vhdlKeyWordSet1.find(word)!=g_vhdlKeyWordSet1.end())
188 return "keywordtype";
189
190 if (g_vhdlKeyWordSet2.find(word)!=g_vhdlKeyWordSet2.end())
191 return "vhdllogic";
192
193 if (g_vhdlKeyWordSet3.find(word)!=g_vhdlKeyWordSet3.end())
194 return "vhdlkeyword";
195
196 return nullptr;
197}
198
200{
201 if (name.empty()) return nullptr;
203}
204
206{
207 return getClass(name);
208}
209
210static std::recursive_mutex g_vhdlMutex;
211static std::map<std::string,const MemberDef*> g_varMap;
212static std::vector<ClassDef*> g_classList;
213static std::map<ClassDef*,std::vector<ClassDef*> > g_packages;
214
215const MemberDef* VhdlDocGen::findMember(const DString& className, const DString& memName)
216{
217 std::lock_guard lock(g_vhdlMutex);
218 ClassDef *ecd=nullptr;
219 const MemberDef *mdef=nullptr;
220
221 ClassDef *cd=getClass(className);
222 //printf("VhdlDocGen::findMember(%s,%s)=%p\n",qPrint(className),qPrint(memName),cd);
223 if (cd==nullptr) return nullptr;
224
225 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType::VariableMembers());
226 if (mdef) return mdef;
227 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType::PubMethods());
228 if (mdef) return mdef;
229
230 // nothing found so far
231 // if we are an architecture or package body search in entity
232
235 {
236 Definition *d = cd->getOuterScope();
237 // searching upper/lower case names
238
239 DString tt=d->name();
240 ecd =getClass(tt);
241 if (!ecd)
242 {
243 tt=tt.upper();
244 ecd =getClass(tt);
245 }
246 if (!ecd)
247 {
248 tt=tt.lower();
249 ecd =getClass(tt);
250 }
251
252 if (ecd) //d && d->definitionType()==Definition::TypeClass)
253 {
254 //ClassDef *ecd = (ClassDef*)d;
255 mdef=VhdlDocGen::findMemberDef(ecd,memName,MemberListType::VariableMembers());
256 if (mdef) return mdef;
257 mdef=VhdlDocGen::findMemberDef(cd,memName,MemberListType::PubMethods());
258 if (mdef) return mdef;
259 }
260 }
261
262
265 {
266 Definition *d = cd->getOuterScope();
267
268 DString tt=d->name();
269 ClassDef *acd =getClass(tt);
270 if (!acd)
271 {
272 tt=tt.upper();
273 acd =getClass(tt);
274 }
275 if (!acd)
276 {
277 tt=tt.lower();
278 acd =getClass(tt);
279 }
280 if (acd) //d && d->definitionType()==Definition::TypeClass)
281 {
282 if(g_packages.find(acd)==g_packages.end())
283 {
285 }
286 }
287 }
288 else
289 {
290 ecd=cd;
291 if (g_packages.find(ecd)==g_packages.end()) VhdlDocGen::findAllPackages(ecd);
292 }
293
294 if (ecd)
295 {
296 auto cList_it = g_packages.find(ecd);
297 if (cList_it!=g_packages.end())
298 {
299 for (const auto &cdp : cList_it->second)
300 {
301 mdef=VhdlDocGen::findMemberDef(cdp,memName,MemberListType::VariableMembers());
302 if (mdef) return mdef;
303 mdef=VhdlDocGen::findMemberDef(cdp,memName,MemberListType::PubMethods());
304 if (mdef) return mdef;
305 }
306 }
307 }
308 return nullptr;
309
310}//findMember
311
312/**
313 * This function returns the entity|package
314 * in which the key (type) is found
315 */
317{
318 std::lock_guard lock(g_vhdlMutex);
319 DString keyType=cd->symbolName()+"@"+key;
320 //printf("\n %s | %s | %s",qPrint(cd->symbolName()),key.data(,),qPrint(keyType));
321
322 auto it = g_varMap.find(keyType.str());
323 if (it!=g_varMap.end())
324 {
325 return it->second;
326 }
327 if (std::find(g_classList.begin(),g_classList.end(),cd)!=g_classList.end())
328 {
329 return nullptr;
330 }
331 const MemberList *ml=cd->getMemberList(type);
332 g_classList.push_back(cd);
333 if (!ml)
334 {
335 return nullptr;
336 }
337 //int l=ml->count();
338 //fprintf(stderr,"\n loading entity %s %s: %d",qPrint(cd->symbolName()),qPrint(keyType),l);
339
340 for (const auto &md : *ml)
341 {
342 DString tkey=cd->symbolName()+"@"+md->name();
343 if (g_varMap.find(tkey.str())==g_varMap.end())
344 {
345 g_varMap.emplace(tkey.str(),md);
346 }
347 }
348 it=g_varMap.find(keyType.str());
349 if (it!=g_varMap.end())
350 {
351 return it->second;
352 }
353 return nullptr;
354}//findMemberDef
355
356/*!
357 * finds all included packages of an Entity or Package
358 */
359
361{
362 std::lock_guard lock(g_vhdlMutex);
363 if (g_packages.find(cdef)!=g_packages.end()) return;
364 std::vector<ClassDef*> cList;
365 MemberList *mem=cdef->getMemberList(MemberListType::VariableMembers());
366 if (mem)
367 {
368 for (const auto &md : *mem)
369 {
370 if (VhdlDocGen::isPackage(md))
371 {
372 ClassDef* cd=VhdlDocGen::getPackageName(md->name());
373 if (cd)
374 {
375 cList.push_back(cd);
377 g_packages.emplace(cdef,cList);
378 }
379 }
380 }//for
381 }
382
383}// findAllPackages
384
385/*!
386 * returns the function with the matching argument list
387 * is called in vhdlcode.l
388 */
389
390const MemberDef* VhdlDocGen::findFunction(const DString& funcname, const DString& package)
391{
392 ClassDef *cdef=getClass(package);
393 if (cdef==nullptr) return nullptr;
394
395 MemberList *mem=cdef->getMemberList(MemberListType::PubMethods());
396 if (mem)
397 {
398 for (const auto &mdef : *mem)
399 {
400 DString mname=mdef->name();
401 if ((VhdlDocGen::isProcedure(mdef) || VhdlDocGen::isVhdlFunction(mdef)) && (compareString(funcname,mname)==0))
402 {
403 return mdef;
404 }//if
405 }//for
406 }//if
407 return nullptr;
408} //findFunction
409
410
411
427
428/*!
429 * returns the class title+ref
430 */
431
433{
434 DString pageTitle;
435 if (cd==nullptr) return "";
436 pageTitle=VhdlDocGen::getClassName(cd);
437 pageTitle+=" ";
439 return pageTitle;
440} // getClassTitle
441
442/* returns the class name without their prefixes */
443
445{
446 DString temp;
447 if (cd==nullptr) return "";
448
450 {
451 temp=cd->name();
452 temp.stripPrefix("_");
453 return temp;
454 }
455
456 return substitute(cd->className(),"::",".");
457}
458
459/*!
460 * writes an inline link form entity|package to architecture|package body and vice verca
461 */
462
464{
465 std::vector<DString> ql;
466 DString nn=cd->className();
468
470
471 //type=type.lower();
472 type+=" >> ";
475
477 {
478 nn.stripPrefix("_");
479 cd=getClass(nn);
480 }
481 else if (ii==VhdlDocGen::PACKAGECLASS)
482 {
483 nn.prepend("_");
484 cd=getClass(nn);
485 }
487 {
488 StringVector qlist=split(nn.str(),"-");
489 if (qlist.size()>1)
490 {
491 nn=qlist[1];
493 }
494 }
495
496 DString opp;
498 {
500 for (const auto &s : ql)
501 {
502 StringVector qlist=split(s.str(),"-");
503 if (qlist.size()>2)
504 {
505 DString s1(qlist[0]);
506 DString s2(qlist[1]);
507 s1.stripPrefix("_");
508 if (ql.size()==1) s1.clear();
509 ClassDef *cc = getClass(s);
510 if (cc)
511 {
512 VhdlDocGen::writeVhdlLink(cc,ol,type,s2,s1);
513 }
514 }
515 }
516 }
517 else
518 {
519 VhdlDocGen::writeVhdlLink(cd,ol,type,nn,opp);
520 }
521
524
525}// write
526
527/*
528 * finds all architectures which belongs to an entity
529 */
530void VhdlDocGen::findAllArchitectures(std::vector<DString>& qll,const ClassDef *cd)
531{
532 for (const auto &citer : *Doxygen::classLinkedMap)
533 {
534 DString className=citer->className();
535 size_t pos = DString::npos;
536 if (cd != citer.get() && (pos=className.find('-'))!=DString::npos)
537 {
538 DString postfix=className.mid(pos+1);
539 if (dstricmp(cd->className(),postfix)==0)
540 {
541 qll.push_back(className);
542 }
543 }
544 }// for
545}//findAllArchitectures
546
548{
549 for (const auto &citer : *Doxygen::classLinkedMap)
550 {
551 DString jj=citer->name();
552 StringVector ql=split(jj.str(),":");
553 if (ql.size()>1)
554 {
555 if (ql[0]==cd->name())
556 {
557 return citer.get();
558 }
559 }
560 }
561 return nullptr;
562}
563/*
564 * writes the link entity >> .... or architecture >> ...
565 */
566
568{
569 if (ccd==nullptr) return;
570 ol.startBold();
571 ol.docify(type);
572 ol.endBold();
573 nn.stripPrefix("_");
575
576 if (!behav.empty())
577 {
578 behav.prepend(" ");
579 ol.startBold();
580 ol.docify(behav);
581 ol.endBold();
582 }
583
584 ol.lineBreak();
585}
586
587
588/*!
589 * strips the "--!" prefixes of vhdl comments
590 */
592{
593 qcs=qcs.stripWhiteSpace();
594 if (qcs.empty()) return;
595
596 const char* sc="--!";
597 if (qcs.startsWith(sc)) qcs = qcs.mid(dstrlen(sc));
598 static const reg::Ex re(R"(\n[ \t]*--!)");
599 std::string s = qcs.str();
600 reg::Iterator iter(s,re);
602 std::string result;
603 size_t p=0;
604 size_t sl=s.length();
605 for ( ; iter!=end ; ++iter)
606 {
607 const auto &match = *iter;
608 size_t i = match.position();
609 result+="\n";
610 result+=s.substr(p,i-p);
611 p = match.position()+match.length();
612 }
613 if (p<sl)
614 {
615 result+="\n";
616 result+=s.substr(p);
617 }
618
619 qcs = result;
620 qcs=qcs.stripWhiteSpace();
621}
622
623
624/*!
625 * parses a function proto
626 * @param text function string
627 * @param name points to the function name
628 * @param ret Stores the return type
629 * @param doc ???
630 */
631void VhdlDocGen::parseFuncProto(const DString &text,DString& name,DString& ret,bool doc)
632{
633 DString s1(text);
634 DString temp;
635
636 size_t index=s1.find('(');
637 if (index==DString::npos) index=0;
638 size_t end=s1.rfind(')');
639
640 if (end!=DString::npos && end>index)
641 {
642 temp=s1.mid(index+1,(end-index-1));
643 //getFuncParams(qlist,temp);
644 }
645 if (doc)
646 {
647 name=s1.left(index);
648 name=name.stripWhiteSpace();
649 if ((end-index)>0)
650 {
651 ret="function";
652 }
653 return;
654 }
655 else
656 {
657 s1=s1.stripWhiteSpace();
658 size_t i=s1.find('(');
659 size_t s=s1.find(' ');
660 if (s==DString::npos) s=s1.find('\t');
661 if (i==DString::npos || (s!=DString::npos && (i==DString::npos || i<s)))
663 else // s<i, s=start of name, i=end of name
664 s1=s1.mid(s,(i-s));
665
666 name=s1.stripWhiteSpace();
667 }
668 index=s1.rfind_insensitive("return");
669 if (index!=DString::npos)
670 {
671 ret=s1.mid(index+6,s1.length());
672 ret=ret.stripWhiteSpace();
674 }
675}
676
677/*
678 * returns the n'th word of a string
679 */
680
682{
683 static const reg::Ex reg(R"([\s:|])");
684 auto ql=split(c.str(),reg);
685
686 if (index < static_cast<int>(ql.size()))
687 {
688 return ql[index];
689 }
690
691 return "";
692}
693
694
696{
697 if (prot==VhdlDocGen::ENTITYCLASS)
698 return "entity";
699 else if (prot==VhdlDocGen::ARCHITECTURECLASS)
700 return "architecture";
701 else if (prot==VhdlDocGen::PACKAGECLASS)
702 return "package";
703 else if (prot==VhdlDocGen::PACKBODYCLASS)
704 return "package body";
705
706 return "";
707}
708
709/*!
710 * deletes a char backwards in a string
711 */
712
714{
715 size_t index=s.rfind_insensitive(c);
716 if (index!=DString::npos)
717 {
718 s = s.remove(index,1);
719 return true;
720 }
721 return false;
722}
723
725{
726 size_t index=s.rfind_insensitive(c);
727 while (index!=DString::npos)
728 {
729 s = s.remove(index,1);
730 index=s.rfind_insensitive(c);
731 }
732}
733
734
735static int recordCounter=0;
736
737/*!
738 * returns the next number of a record|unit member
739 */
740
742{
743 char buf[12];
744 snprintf(buf,12,"%d",recordCounter++);
745 DString qcs(&buf[0]);
746 return qcs;
747}
748
749/*!
750 * returns the next number of an anonymous process
751 */
752
754{
755 static int stringCounter;
756 DString qcs("PROCESS_");
757 char buf[8];
758 snprintf(buf,8,"%d",stringCounter++);
759 qcs.append(&buf[0]);
760 return qcs;
761}
762
763/*!
764 * writes a colored and formatted string
765 */
766
768{
769 static const reg::Ex reg(R"([\‍[\‍]./<>:\s,;'+*|&=()\"-])");
770 DString qcs = s;
771 qcs+=DString(" ");// parsing the last sign
772 DString find=qcs;
773 DString temp=qcs;
774 char buf[2];
775 buf[1]='\0';
776
777 size_t j = findIndex(temp.str(),reg);
778
779 ol.startBold();
780 if (j!=std::string::npos)
781 {
782 while (j!=std::string::npos)
783 {
784 find=find.left(j);
785 buf[0]=temp[j];
786 const char *ss=VhdlDocGen::findKeyWord(find);
787 bool k=isNumber(find.str()); // is this a number
788 if (k)
789 {
790 ol.docify(" ");
791 startFonts(find,"vhdldigit",ol);
792 ol.docify(" ");
793 }
794 else if (j != 0 && ss)
795 {
796 startFonts(find,ss,ol);
797 }
798 else
799 {
800 if (j>0)
801 {
802 VhdlDocGen::writeStringLink(mdef,find,ol);
803 }
804 }
805 startFonts(&buf[0],"vhdlchar",ol);
806
807 DString st=temp.remove(0,j+1);
808 find=st;
809 if (!find.empty() && find.at(0)=='"')
810 {
811 size_t ii=find.find('"',2);
812 if (ii!=DString::npos && ii>1)
813 {
814 DString com=find.left(ii+1);
815 startFonts(com,"keyword",ol);
816 temp=find.remove(0,ii+1);
817 }
818 }
819 else
820 {
821 temp=st;
822 }
823 j = findIndex(temp.str(),reg);
824 }//while
825 }//if
826 else
827 {
828 startFonts(find,"vhdlchar",ol);
829 }
830 ol.endBold();
831}// writeFormatString
832
833/*!
834 * returns true if this string is a number
835 */
836bool VhdlDocGen::isNumber(const std::string& s)
837{
838 static const reg::Ex regg(R"([0-9][0-9eEfFbBcCdDaA_.#+?xXzZ-]*)");
839 return reg::match(s,regg);
840}// isNumber
841
842
843/*!
844 * inserts white spaces for better readings
845 * and writes a colored string to the output
846 */
847
849{
850 DString qcs = s;
851 DString temp;
852 qcs.stripPrefix(":");
853 qcs.stripPrefix("is");
854 qcs.stripPrefix("IS");
855 qcs.stripPrefix("of");
856 qcs.stripPrefix("OF");
857
858 size_t len = qcs.length();
859 size_t index=1;
860
861 for (size_t j=0;j<len;j++)
862 {
863 char c=qcs[j];
864 char b=c;
865 if (j>0) b=qcs[j-1];
866 if (c=='"' || c==',' || c=='\''|| c=='(' || c==')' || c==':' || c=='[' || c==']' ) // || (c==':' && b!='=')) // || (c=='=' && b!='>'))
867 {
868 if (temp.length()>=index && temp.at(index-1) != ' ')
869 {
870 temp+=" ";
871 }
872 temp+=c;
873 temp+=" ";
874 }
875 else if (c=='=')
876 {
877 if (b==':') // := operator
878 {
879 temp.replace(index-1,1,"=");
880 temp+=" ";
881 }
882 else // = operator
883 {
884 temp+=" ";
885 temp+=c;
886 temp+=" ";
887 }
888 }
889 else
890 {
891 temp+=c;
892 }
893
894 index=temp.length();
895 }// for
896 temp=temp.stripWhiteSpace();
897 // printf("\n [%s]",qPrint(qcs));
898 VhdlDocGen::writeFormatString(temp,ol,mdef);
899}
900
901/*!
902 * writes a procedure prototype to the output
903 */
904
906{
907 bool sem=false;
908 size_t len=al.size();
909 ol.docify("( ");
910 if (len > 2)
911 {
912 ol.lineBreak();
913 }
914 for (const Argument &arg : al)
915 {
916 ol.startBold();
917 if (sem && len <3)
918 ol.writeChar(',');
919
920 DString nn=arg.name;
921 nn+=": ";
922
923 DString defval = arg.defval;
924 const char *str=VhdlDocGen::findKeyWord(defval);
925 defval+=" ";
926 if (str)
927 {
928 startFonts(defval,str,ol);
929 }
930 else
931 {
932 startFonts(defval,"vhdlchar",ol); // write type (variable,constant etc.)
933 }
934
935 startFonts(nn,"vhdlchar",ol); // write name
936 if (dstricmp(arg.attrib,arg.type) != 0)
937 {
938 startFonts(arg.attrib.lower(),"stringliteral",ol); // write in|out
939 }
940 ol.docify(" ");
941 VhdlDocGen::formatString(arg.type,ol,mdef);
942 sem=true;
943 ol.endBold();
944 if (len > 2)
945 {
946 ol.lineBreak();
947 ol.docify(" ");
948 }
949 }//for
950
951 ol.docify(" )");
952
953
954}
955
956/*!
957 * writes a function prototype to the output
958 */
959
961{
962 if (!al.hasParameters()) return;
963 bool sem=false;
964 size_t len=al.size();
965 ol.startBold();
966 ol.docify(" ( ");
967 ol.endBold();
968 if (len>2)
969 {
970 ol.lineBreak();
971 }
972 for (const Argument &arg : al)
973 {
974 ol.startBold();
975 DString att=arg.defval;
976 bool bGen=att.stripPrefix("generic");
977
978 if (sem && len < 3)
979 {
980 ol.docify(" , ");
981 }
982
983 if (bGen)
984 {
985 VhdlDocGen::formatString(DString("generic "),ol,mdef);
986 }
987 if (!att.empty())
988 {
989 const char *str=VhdlDocGen::findKeyWord(att);
990 att+=" ";
991 if (str)
992 VhdlDocGen::formatString(att,ol,mdef);
993 else
994 startFonts(att,"vhdlchar",ol);
995 }
996
997 DString nn=arg.name;
998 nn+=": ";
999 DString ss=arg.type.stripWhiteSpace(); //.lower();
1000 DString w=ss.stripWhiteSpace();//.upper();
1001 startFonts(nn,"vhdlchar",ol);
1002 startFonts("in ","stringliteral",ol);
1003 const char *str=VhdlDocGen::findKeyWord(ss);
1004 if (str)
1005 VhdlDocGen::formatString(w,ol,mdef);
1006 else
1007 startFonts(w,"vhdlchar",ol);
1008
1009 if (!arg.attrib.empty())
1010 startFonts(arg.attrib,"vhdlchar",ol);
1011
1012 sem=true;
1013 ol.endBold();
1014 if (len > 2)
1015 {
1016 ol.lineBreak();
1017 }
1018 }
1019 ol.startBold();
1020 ol.docify(" )");
1021 DString exp=mdef->excpString();
1022 if (!exp.empty())
1023 {
1024 ol.insertMemberAlign();
1025 ol.startBold();
1026 ol.docify("[ ");
1027 ol.docify(exp);
1028 ol.docify(" ]");
1029 ol.endBold();
1030 }
1031 ol.endBold();
1032}
1033
1034/*!
1035 * writes a process prototype to the output
1036 */
1037
1039{
1040 if (!al.hasParameters()) return;
1041 bool sem=false;
1042 ol.startBold();
1043 ol.docify(" ( ");
1044 for (const Argument &arg : al)
1045 {
1046 if (sem)
1047 {
1048 ol.docify(" , ");
1049 }
1050 DString nn=arg.name;
1051 // startFonts(nn,"vhdlchar",ol);
1053 sem=true;
1054 }
1055 ol.docify(" )");
1056 ol.endBold();
1057}
1058
1059
1060/*!
1061 * writes a function|procedure documentation to the output
1062 */
1063
1065 const MemberDef *md,
1066 OutputList& ol,
1067 const ArgumentList &al,
1068 bool /*type*/)
1069{
1070 //bool sem=false;
1071 ol.enableAll();
1072
1073 size_t index=al.size();
1074 if (index==0)
1075 {
1076 ol.docify(" ( ) ");
1077 return false;
1078 }
1079 ol.endMemberDocName();
1080 ol.startParameterList(true);
1081 //ol.startParameterName(false);
1082 bool first=true;
1083 for (const Argument &arg : al)
1084 {
1085 ol.startParameterType(first,"");
1086 // if (first) ol.writeChar('(');
1087 DString attl=arg.defval;
1088
1089 //bool bGen=attl.stripPrefix("generic");
1090 //if (bGen)
1091 // VhdlDocGen::writeFormatString(DString("generic "),ol,md);
1092
1093
1095 {
1096 startFonts(arg.defval,"keywordtype",ol);
1097 ol.docify(" ");
1098 }
1099 ol.endParameterType();
1100
1101 ol.startParameterName(true);
1102 VhdlDocGen::writeFormatString(arg.name,ol,md);
1103
1105 {
1106 startFonts(arg.attrib,"stringliteral",ol);
1107 }
1108 else if (VhdlDocGen::isVhdlFunction(md))
1109 {
1110 startFonts(DString("in"),"stringliteral",ol);
1111 }
1112
1113 ol.docify(" ");
1115 ol.startEmphasis();
1117 if (!VhdlDocGen::isProcess(md))
1118 {
1119 // startFonts(arg.type,"vhdlkeyword",ol);
1120 VhdlDocGen::writeFormatString(arg.type,ol,md);
1121 }
1123 ol.endEmphasis();
1125
1126 if (--index)
1127 {
1128 ol.docify(" , ");
1129 }
1130 else
1131 {
1132 // ol.docify(" ) ");
1133 ol.endParameterName();
1135 ol.endParameterExtra(true,false,true);
1136 break;
1137 }
1138 ol.endParameterName();
1140 ol.endParameterExtra(false,false,false);
1141
1142 //sem=true;
1143 first=false;
1144 }
1145 //ol.endParameterList();
1146 return true;
1147
1148} // writeDocFunProc
1149
1150
1151
1152
1154{
1155 DString argString;
1156 bool sem=false;
1157
1158 for (const Argument &arg : al)
1159 {
1160 if (sem) argString.append(", ");
1161 if (func)
1162 {
1163 argString+=arg.name;
1164 argString+=":";
1165 argString+=arg.type;
1166 }
1167 else
1168 {
1169 argString+=arg.defval+" ";
1170 argString+=arg.name+" :";
1171 argString+=arg.attrib+" ";
1172 argString+=arg.type;
1173 }
1174 sem=true;
1175 }
1176 return argString;
1177}
1178
1179
1181 OutputList& ol,const GroupDef* gd,const ClassDef* cd,const FileDef *fd,const NamespaceDef* nd,const ModuleDef *mod)
1182{
1204
1205 // configurations must be added to global file definitions.
1208
1209}
1210
1212{
1213 if (md->argsString()=="package")
1214 {
1216 }
1217 else if (md->argsString()=="configuration")
1218 {
1220 }
1221 else if (md->typeString()=="library")
1222 {
1224 }
1225 else if (md->typeString()=="use")
1226 {
1228 }
1229 else if (md->typeString().lower()=="misc")
1230 {
1232 }
1233 else if (md->typeString().lower()=="ucf_const")
1234 {
1236 }
1237
1239 {
1240 size_t mm=md->name().rfind('_');
1241 if (mm!=DString::npos && mm>0)
1242 {
1243 md->setName(md->name().left(mm));
1244 }
1245 }
1246 else if (md->getVhdlSpecifiers()==VhdlSpecifier::TYPE)
1247 {
1248 DString largs=md->argsString();
1249 bool bRec=largs.stripPrefix("record") ;
1250 bool bUnit=largs.stripPrefix("units") ;
1251 if (bRec || bUnit)
1252 {
1253 md->setType("");
1254 }
1255 }
1256}
1257
1258/* writes a vhdl type documentation */
1260{
1261 const ClassDef *cd=toClassDef(d);
1262 bool hasParams = false;
1263
1264 if (cd==nullptr) return hasParams;
1265
1266 DString ttype=mdef->typeString();
1267 DString largs=mdef->argsString();
1268
1270 {
1271 DString nn=mdef->typeString();
1272 nn=nn.stripWhiteSpace();
1273 DString na=cd->name();
1274 const MemberDef* memdef=VhdlDocGen::findMember(na,nn);
1275 if (memdef && memdef->isLinkable())
1276 {
1277 ol.docify(" ");
1278
1279 ol.startBold();
1280 writeLink(memdef,ol);
1281 ol.endBold();
1282 ol.docify(" ");
1283 }
1284 else
1285 {
1286 ol.docify(" ");
1287 VhdlDocGen::formatString(ttype,ol,mdef);
1288 ol.docify(" ");
1289 }
1290 ol.docify(mdef->name());
1291 hasParams = VhdlDocGen::writeFuncProcDocu(mdef,ol, mdef->argumentList());
1292 }
1293
1294
1295 if (mdef->isVariable())
1296 {
1297 if (VhdlDocGen::isConstraint(mdef))
1298 {
1299 writeLink(mdef,ol);
1300 ol.docify(" ");
1301
1302 largs=substitute(largs,"#"," ");
1303 VhdlDocGen::formatString(largs,ol,mdef);
1304 return hasParams;
1305 }
1306 else
1307 {
1308 writeLink(mdef,ol);
1310 {
1311 return hasParams;
1312 }
1313 ol.docify(" ");
1314 }
1315
1316 // DString largs=mdef->argsString();
1317
1318 bool c=largs=="context";
1319 bool brec=largs.stripPrefix("record") ;
1320
1321 if (!brec && !c)
1322 VhdlDocGen::formatString(ttype,ol,mdef);
1323
1324 if (c || brec || largs.stripPrefix("units"))
1325 {
1326 if (c)
1327 largs=ttype;
1328 VhdlDocGen::writeRecUnitDocu(mdef,ol,largs);
1329 return hasParams;
1330 }
1331
1332 ol.docify(" ");
1333 if (VhdlDocGen::isPort(mdef) || VhdlDocGen::isGeneric(mdef))
1334 {
1335 // DString largs=mdef->argsString();
1336 VhdlDocGen::formatString(largs,ol,mdef);
1337 ol.docify(" ");
1338 }
1339 }
1340 return hasParams;
1341}
1342
1344{
1345 tagFile << " <member kind=\"";
1346 if (VhdlDocGen::isGeneric(mdef)) tagFile << "generic";
1347 if (VhdlDocGen::isPort(mdef)) tagFile << "port";
1348 if (VhdlDocGen::isEntity(mdef)) tagFile << "entity";
1349 if (VhdlDocGen::isComponent(mdef)) tagFile << "component";
1350 if (VhdlDocGen::isVType(mdef)) tagFile << "type";
1351 if (VhdlDocGen::isConstant(mdef)) tagFile << "constant";
1352 if (VhdlDocGen::isSubType(mdef)) tagFile << "subtype";
1353 if (VhdlDocGen::isVhdlFunction(mdef)) tagFile << "function";
1354 if (VhdlDocGen::isProcedure(mdef)) tagFile << "procedure";
1355 if (VhdlDocGen::isProcess(mdef)) tagFile << "process";
1356 if (VhdlDocGen::isSignals(mdef)) tagFile << "signal";
1357 if (VhdlDocGen::isAttribute(mdef)) tagFile << "attribute";
1358 if (VhdlDocGen::isRecord(mdef)) tagFile << "record";
1359 if (VhdlDocGen::isLibrary(mdef)) tagFile << "library";
1360 if (VhdlDocGen::isPackage(mdef)) tagFile << "package";
1361 if (VhdlDocGen::isVariable(mdef)) tagFile << "shared variable";
1362 if (VhdlDocGen::isFile(mdef)) tagFile << "file";
1363 if (VhdlDocGen::isGroup(mdef)) tagFile << "group";
1364 if (VhdlDocGen::isCompInst(mdef)) tagFile << "instantiation";
1365 if (VhdlDocGen::isAlias(mdef)) tagFile << "alias";
1366 if (VhdlDocGen::isCompInst(mdef)) tagFile << "configuration";
1367
1368 DString fn = mdef->getOutputFileBase();
1370 tagFile << "\">\n";
1371 tagFile << " <type>" << convertToXML(mdef->typeString()) << "</type>\n";
1372 tagFile << " <name>" << convertToXML(mdef->name()) << "</name>\n";
1373 tagFile << " <anchorfile>" << convertToXML(fn) << "</anchorfile>\n";
1374 tagFile << " <anchor>" << convertToXML(mdef->anchor()) << "</anchor>\n";
1375
1377 tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),true)) << "</arglist>\n";
1378 else if (VhdlDocGen::isProcedure(mdef))
1379 tagFile << " <arglist>" << convertToXML(VhdlDocGen::convertArgumentListToString(mdef->argumentList(),false)) << "</arglist>\n";
1380 else
1381 tagFile << " <arglist>" << convertToXML(mdef->argsString()) << "</arglist>\n";
1382
1383 mdef->writeDocAnchorsToTagFile(tagFile);
1384 tagFile << " </member>\n";
1385}
1386
1387/* writes a vhdl type declaration */
1388
1390 const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,const ModuleDef *mod,
1391 bool /*inGroup*/)
1392{
1393 const Definition *d=nullptr;
1394
1395 ASSERT(cd!=nullptr || nd!=nullptr || fd!=nullptr || gd!=nullptr || mod!=nullptr ||
1398 ); // member should belong to something
1399 if (cd) d=cd;
1400 else if (nd) d=nd;
1401 else if (fd) d=fd;
1402 else if (mod) d=mod;
1403 else if (gd) d=gd;
1404 else d=mdef;
1405
1406 // write search index info
1407 if (Doxygen::searchIndex.enabled())
1408 {
1409 Doxygen::searchIndex.setCurrentDoc(mdef,mdef->anchor(),false);
1412 }
1413
1414 DString cname = d->name();
1415 DString cfname = d->getOutputFileBase();
1416
1417 //HtmlHelp *htmlHelp=nullptr;
1418 // bool hasHtmlHelp = Config_getBool(GENERATE_HTML) && Config_getBool(GENERATE_HTMLHELP);
1419 // if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
1420
1421 // search for the last anonymous scope in the member type
1422 const ClassDef *annoClassDef=mdef->getClassDefOfAnonymousType();
1423
1424 // start a new member declaration
1427 ///printf("startMemberItem for %s\n",qPrint(name()));
1431
1432 ol.startMemberItem( mdef->anchor(), memType );
1433
1434 // If there is no detailed description we need to write the anchor here.
1435 bool detailsVisible = mdef->hasDetailedDescription();
1436 if (!detailsVisible)
1437 {
1438 DString doxyName=mdef->name();
1439 if (!cname.empty()) doxyName.prepend(cname+"::");
1440 DString doxyArgs=mdef->argsString();
1441 ol.startDoxyAnchor(cfname,cname,mdef->anchor(),doxyName,doxyArgs);
1442 ol.addLabel(cfname,mdef->anchor());
1443
1444 ol.pushGeneratorState();
1447 ol.docify("\n");
1448 ol.popGeneratorState();
1449
1450 }
1451 // *** write type
1452 /*VHDL CHANGE */
1453
1454 DString ltype(mdef->typeString());
1455 DString largs(mdef->argsString());
1456
1457 ClassDef *kl=nullptr;
1458 const ArgumentList &al = mdef->argumentList();
1459 DString nn;
1460 //VhdlDocGen::adjustRecordMember(mdef);
1461 if (gd) gd=nullptr;
1462 switch (mm)
1463 {
1465 VhdlDocGen::writeSource(mdef,ol,nn);
1466 break;
1469 ol.startBold();
1470 VhdlDocGen::formatString(ltype,ol,mdef);
1471 ol.endBold();
1472 ol.insertMemberAlign();
1473 ol.docify(" ");
1474
1475 writeLink(mdef,ol);
1476 if (al.hasParameters() && mm==VhdlSpecifier::FUNCTION)
1478
1481
1482 break;
1483 case VhdlSpecifier::USE:
1484 kl=VhdlDocGen::getClass(mdef->name());
1485 if (kl && (VhdlDocGen::convert(kl->protection())==VhdlDocGen::ENTITYCLASS)) break;
1486 writeLink(mdef,ol);
1487 ol.insertMemberAlign();
1488 ol.docify(" ");
1489
1490 if (kl)
1491 {
1492 nn=kl->getOutputFileBase();
1493 ol.pushGeneratorState();
1495 ol.docify(" ");
1497 ol.startBold();
1498 ol.docify(name);
1499 name.clear();
1500 ol.endBold();
1501 name+=" <"+mdef->name()+">";
1502 ol.startEmphasis();
1504 ol.popGeneratorState();
1505 }
1506 break;
1508 writeLink(mdef,ol);
1509 ol.insertMemberAlign();
1510 if (largs=="context")
1511 {
1512 VhdlDocGen::writeRecordUnit(ltype,largs,ol,mdef);
1513 }
1514
1515 break;
1516
1520
1521 writeLink(mdef,ol);
1522 ol.docify(" ");
1523 if (mm==VhdlSpecifier::GENERIC)
1524 {
1525 ol.insertMemberAlign();
1526 ol.startBold();
1527 VhdlDocGen::formatString(largs,ol,mdef);
1528 ol.endBold();
1529 }
1530 else
1531 {
1532 ol.insertMemberAlignLeft(memType, false);
1533 ol.docify(" ");
1534 ol.startBold();
1535 VhdlDocGen::formatString(ltype,ol,mdef);
1536 ol.endBold();
1537 ol.insertMemberAlign();
1538 ol.docify(" ");
1539 VhdlDocGen::formatString(largs,ol,mdef);
1540 }
1541 break;
1543 writeLink(mdef,ol);
1544 ol.insertMemberAlign();
1546 break;
1552 if (VhdlDocGen::isCompInst(mdef) )
1553 {
1554 nn=largs;
1555 if(nn.stripPrefix("function") || nn.stripPrefix("package"))
1556 {
1557 VhdlDocGen::formatString(largs,ol,mdef);
1558 ol.insertMemberAlign();
1559 writeLink(mdef,ol);
1560 ol.docify(" ");
1561 VhdlDocGen::formatString(ltype,ol,mdef);
1562 break;
1563 }
1564
1565 largs.prepend("::");
1566 largs.prepend(mdef->name());
1567 ol.writeObjectLink(mdef->getReference(),
1568 cfname,
1569 mdef->anchor(),
1570 mdef->name());
1571 }
1572 else
1573 writeLink(mdef,ol);
1574
1575 ol.insertMemberAlign();
1576 ol.docify(" ");
1577 ol.startBold();
1578 ol.docify(ltype);
1579 ol.endBold();
1580 ol.docify(" ");
1581 if (VhdlDocGen::isComponent(mdef) ||
1582 VhdlDocGen::isConfig(mdef) ||
1584 {
1586 {
1587 nn=ltype;
1588 }
1589 else
1590 {
1591 nn=mdef->name();
1592 }
1593 kl=getClass(nn);
1594 if (kl)
1595 {
1596 nn=kl->getOutputFileBase();
1597 ol.pushGeneratorState();
1599 ol.startEmphasis();
1600 DString name("<Entity ");
1602 {
1603 name+=ltype+">";
1604 }
1605 else
1606 {
1607 name+=mdef->name()+"> ";
1608 }
1610 ol.endEmphasis();
1611 ol.popGeneratorState();
1612 }
1613 }
1614 break;
1616 writeUCFLink(mdef,ol);
1617 break;
1626 writeLink(mdef,ol);
1627 ol.docify(" ");
1628 ol.insertMemberAlign();
1629 VhdlDocGen::formatString(ltype,ol,mdef);
1630 break;
1633 writeRecordUnit(largs,ltype,ol,mdef);
1634 break;
1635
1636 default: break;
1637 }
1638
1639 bool htmlOn = ol.isEnabled(OutputType::Html);
1640 if (htmlOn && /*Config_getBool(HTML_ALIGN_MEMBERS) &&*/ !ltype.empty())
1641 {
1643 }
1644 if (!ltype.empty()) ol.docify(" ");
1645
1646 if (htmlOn)
1647 {
1649 }
1650
1651 if (!detailsVisible)
1652 {
1653 ol.endDoxyAnchor(cfname,mdef->anchor());
1654 }
1655
1656 ol.endMemberItem(memType);
1657 if (!mdef->briefDescription().empty() && Config_getBool(BRIEF_MEMBER_DESC) /* && !annMemb */)
1658 {
1659 DString s=mdef->briefDescription();
1661 ol.generateDoc(mdef->briefFile(),
1662 mdef->briefLine(),
1663 mdef->getOuterScope()?mdef->getOuterScope():d,
1664 mdef,
1665 s,
1666 DocOptions()
1667 .setIndexWords(true)
1668 .setSingleLine(true));
1669 if (detailsVisible)
1670 {
1671 ol.pushGeneratorState();
1673 ol.docify(" ");
1674 if (mdef->getGroupDef()!=nullptr && gd==nullptr) // forward link to the group
1675 {
1676 ol.startTextLink(mdef->getOutputFileBase(),mdef->anchor());
1677 }
1678 else // local link
1679 {
1680 ol.startTextLink(DString(),mdef->anchor());
1681 }
1682 ol.endTextLink();
1683 ol.popGeneratorState();
1684 }
1686 }
1687 mdef->warnIfUndocumented();
1688
1689}// end writeVhdlDeclaration
1690
1691
1693 const MemberList* mlist,OutputList &ol,
1694 const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,const ModuleDef *mod,
1695 VhdlSpecifier specifier)
1696{
1697
1698 StringSet pack;
1699
1700 bool first=true;
1701 for (const auto &imd : *mlist)
1702 {
1704 if (md)
1705 {
1707 if (md->isBriefSectionVisible() && (mems==specifier) && (mems!=VhdlSpecifier::LIBRARY) )
1708 {
1709 if (first) { ol.startMemberList();first=false; }
1710 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,mod,false);
1711 } //if
1712 else if (md->isBriefSectionVisible() && (mems==specifier))
1713 {
1714 if (pack.find(md->name().str())==pack.end())
1715 {
1716 if (first) ol.startMemberList(),first=false;
1717 VhdlDocGen::writeVHDLDeclaration(md,ol,cd,nd,fd,gd,mod,false);
1718 pack.insert(md->name().str());
1719 }
1720 } //if
1721 } //if
1722 } //for
1723 if (!first) ol.endMemberList();
1724}//plainDeclaration
1725
1727{
1728 if (ml==nullptr) return false;
1729 for (const auto &mdd : *ml)
1730 {
1731 if (mdd->getVhdlSpecifiers()==type) //is type in class
1732 {
1733 return true;
1734 }
1735 }
1736 for (const auto &mg : ml->getMemberGroupList())
1737 {
1738 if (!mg->members().empty())
1739 {
1740 if (membersHaveSpecificType(&mg->members(),type)) return true;
1741 }
1742 }
1743 return false;
1744}
1745
1747 const ClassDef *cd,const NamespaceDef *nd,const FileDef *fd,const GroupDef *gd,const ModuleDef *mod,
1748 const DString &title,const DString &subtitle,bool /*showEnumValues*/,VhdlSpecifier type)
1749{
1750 if (!membersHaveSpecificType(ml,type)) return;
1751
1752 if (!title.empty())
1753 {
1754 ol.startMemberHeader(convertToId(title),type == VhdlSpecifier::PORT ? 3 : 2);
1755 ol.parseText(title);
1756 ol.endMemberHeader();
1757 ol.docify(" ");
1758 }
1759 if (!subtitle.empty())
1760 {
1762 ol.generateDoc("[generated]",
1763 -1,
1764 nullptr,
1765 nullptr,
1766 subtitle,
1767 DocOptions()
1768 .setSingleLine(true));
1769 ol.endMemberSubtitle();
1770 } //printf("memberGroupList=%p\n",memberGroupList);
1771
1772 VhdlDocGen::writePlainVHDLDeclarations(ml,ol,cd,nd,fd,gd,mod,type);
1773
1774 int groupId=0;
1775 for (const auto &mg : ml->getMemberGroupList())
1776 {
1777 if (membersHaveSpecificType(&mg->members(),type))
1778 {
1779 //printf("mg->header=%s\n",qPrint(mg->header()));
1780 bool hasHeader=!mg->header().empty();
1781 DString groupAnchor = DString(ml->listType().toLabel())+"-"+DString().setNum(groupId++);
1782 ol.startMemberGroupHeader(groupAnchor,hasHeader);
1783 if (hasHeader)
1784 {
1785 ol.parseText(mg->header());
1786 }
1787 ol.endMemberGroupHeader(hasHeader);
1788 if (!mg->documentation().empty())
1789 {
1790 //printf("Member group has docs!\n");
1792 ol.generateDoc("[generated]",
1793 -1,
1794 nullptr,
1795 nullptr,
1796 mg->documentation()+"\n",
1797 DocOptions());
1798 ol.endMemberGroupDocs();
1799 }
1800 ol.startMemberGroup();
1801 //printf("--- mg->writePlainDeclarations ---\n");
1802 VhdlDocGen::writePlainVHDLDeclarations(&mg->members(),ol,cd,nd,fd,gd,mod,type);
1803 ol.endMemberGroup(hasHeader);
1804 }
1805 }
1806}// writeVHDLDeclarations
1807
1808
1810 OutputList &ol ,DString & cname)
1811{
1813 cname=VhdlDocGen::getClassName(cd);
1814 ol.startBold();
1815 ol.writeString(qcs);
1816 ol.writeString(" ");
1817 ol.endBold();
1818 //ol.insertMemberAlign();
1819 return false;
1820}// writeClassLink
1821
1822
1823/*! writes a link if the string is linkable else a formatted string */
1824
1826{
1827 if (mdef)
1828 {
1829 const ClassDef *cd=mdef->getClassDef();
1830 if (cd)
1831 {
1832 DString n=cd->name();
1833 const MemberDef* memdef=VhdlDocGen::findMember(n,mem);
1834 if (memdef && memdef->isLinkable())
1835 {
1836 ol.startBold();
1837 writeLink(memdef,ol);
1838 ol.endBold();
1839 ol.docify(" ");
1840 return;
1841 }
1842 }
1843 }
1844 startFonts(mem,"vhdlchar",ol);
1845}// found component
1846
1847
1848
1849void VhdlDocGen::writeSource(const MemberDef* mdef,OutputList& ol,const DString &cname)
1850{
1851 auto intf = Doxygen::parserManager->getCodeParser(".vhd");
1852 // pIntf->resetCodeParserState();
1853
1854 DString codeFragment=mdef->documentation();
1855
1856 if (cname.empty())
1857 {
1858 writeLink(mdef,ol);
1859 size_t fi=0;
1860 int j=0;
1861 do { fi=codeFragment.find('\n',++fi); } while (fi!=DString::npos && j++ <3);
1862
1863 // show only the first four lines
1864 if (j==4)
1865 {
1866 codeFragment=codeFragment.left(fi);
1867 codeFragment.append("\n .... ");
1868 }
1869 }
1870
1871 codeFragment.prepend("\n");
1872 ol.pushGeneratorState();
1873 auto &codeOL = ol.codeGenerators();
1874 codeOL.startCodeFragment("DoxyCode");
1875 intf->parseCode(codeOL, // codeOutIntf
1876 DString(), // scope
1877 codeFragment, // input
1878 SrcLangExt::VHDL, // lang
1879 Config_getBool(STRIP_CODE_COMMENTS),
1881 .setFileDef(mdef->getFileDef())
1883 .setEndLine(mdef->getEndBodyLine())
1884 .setInlineFragment(true)
1885 .setMemberDef(mdef)
1886 );
1887
1888 codeOL.endCodeFragment("DoxyCode");
1889 ol.popGeneratorState();
1890
1891 if (cname.empty()) return;
1892
1893 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(mdef));
1894 if (mdm)
1895 {
1896 mdm->writeSourceDef(ol);
1897 if (mdef->hasReferencesRelation()) mdm->writeSourceRefs(ol,cname);
1898 if (mdef->hasReferencedByRelation()) mdm->writeSourceReffedBy(ol,cname);
1899 }
1900}
1901
1902
1903
1905{
1906 DString n=name;
1907 n=n.remove(0,6);
1908 size_t i=0;
1909 while ((i=n.find("__"))!=DString::npos && i>0) n=n.remove(i,1);
1910 while ((i=n.find("_1"))!=DString::npos && i>0) n=n.replace(i,2,":");
1911 return n;
1912}
1913
1914void VhdlDocGen::parseUCF(const DString &input,Entry* entity,const DString &fileName,bool altera)
1915{
1916 DString ucFile(input);
1917 int lineNo=0;
1918 DString comment("#!");
1919 DString brief;
1920
1921 while (!ucFile.empty())
1922 {
1923 size_t i=ucFile.find('\n');
1924 if (i==DString::npos) break;
1925 lineNo++;
1926 DString temp=ucFile.left(i);
1927 temp=temp.stripWhiteSpace();
1928 bool bb=temp.stripPrefix("//");
1929
1930 if (!temp.empty())
1931 {
1932 if (temp.stripPrefix(comment) )
1933 {
1934 brief+=temp;
1935 brief.append("\\n");
1936 }
1937 else if (!temp.stripPrefix("#") && !bb)
1938 {
1939 if (altera)
1940 {
1941 size_t in=temp.find("-name");
1942 if (in!=DString::npos && in>0)
1943 {
1944 temp=temp.remove(0,in+5);
1945 }
1946
1947 temp.stripPrefix("set_location_assignment");
1948
1949 initUCF(entity,DString(),temp,lineNo,fileName,brief);
1950 }
1951 else
1952 {
1953 static const reg::Ex ee(R"([\s=])");
1954 size_t in=findIndex(temp.str(),ee);
1955 if (in==std::string::npos) in=0;
1956 DString ff=temp.left(in);
1957 temp.stripPrefix(ff);
1958 ff.append("#");
1959 if (!temp.empty())
1960 {
1961 initUCF(entity,ff,temp,lineNo,fileName,brief);
1962 }
1963 }
1964 }
1965 }//temp
1966
1967 ucFile=ucFile.remove(0,i+1);
1968 }// while
1969}
1970
1971static void initUCF(Entry* root,const DString &type,DString &qcs,
1972 int line,const DString &fileName,DString & brief)
1973{
1974 if (qcs.empty())return;
1975 DString n;
1976
1978 qcs=qcs.stripWhiteSpace();
1979
1980 static const reg::Ex reg(R"([\s=])");
1981 size_t i = findIndex(qcs.str(),reg);
1982 if (i==std::string::npos) return;
1983 if (i==0)
1984 {
1985 n=type;
1987 }
1988 else
1989 {
1990 n=qcs.left(i);
1991 }
1992 qcs=qcs.remove(0,i+1);
1993 // qcs.prepend("|");
1994
1995 qcs.stripPrefix("=");
1996
1997 std::shared_ptr<Entry> current = std::make_shared<Entry>();
1998 current->vhdlSpec=VhdlSpecifier::UCF_CONST;
1999 current->section=EntryType::makeVariable();
2000 current->bodyLine=line;
2001 current->fileName=fileName;
2002 current->type="ucf_const";
2003 current->args+=qcs;
2004 current->lang= SrcLangExt::VHDL ;
2005
2006 // adding dummy name for constraints like VOLTAGE=5,TEMPERATURE=20 C
2007 if (n.empty())
2008 {
2009 n="dummy";
2011 }
2012
2013 current->name= n+"_";
2014 current->name.append(VhdlDocGen::getRecordNumber());
2015
2016 if (!brief.empty())
2017 {
2018 current->brief=brief;
2019 current->briefLine=line;
2020 current->briefFile=fileName;
2021 brief.clear();
2022 }
2023
2024 root->moveToSubEntryAndKeep(current);
2025}
2026
2027
2028static void writeUCFLink(const MemberDef* mdef,OutputList &ol)
2029{
2030
2031 DString largs(mdef->argsString());
2032 DString n= splitString(largs, '#');
2033 // VhdlDocGen::adjustRecordMember(mdef);
2034 bool equ=(n.length()==largs.length());
2035
2036 if (!equ)
2037 {
2038 ol.writeString(n);
2039 ol.docify(" ");
2040 ol.insertMemberAlign();
2041 }
2042
2043 if (mdef->name().contains("dummy")==0)
2044 {
2045 writeLink(mdef,ol);
2046 }
2047 if (equ)
2048 {
2049 ol.insertMemberAlign();
2050 }
2051 ol.docify(" ");
2052 VhdlDocGen::formatString(largs,ol,mdef);
2053}
2054
2055// for cell_inst : [entity] work.proto [ (label|expr) ]
2057{
2058 if (!entity.contains(":")) return "";
2059
2060 static const reg::Ex exp(R"([:()\s])");
2061 auto ql=split(entity.str(),exp);
2062 if (ql.size()<2)
2063 {
2064 return "";
2065 }
2066 DString label(ql[0]);
2067 entity = ql[1];
2068 if (size_t index = entity.rfind('.'); index!=DString::npos)
2069 {
2070 entity.remove(0,index+1);
2071 }
2072
2073 if (ql.size()==3)
2074 {
2075 arch = ql[2];
2076 ql=split(arch.str(),exp);
2077 if (ql.size()>1) // expression
2078 {
2079 arch="";
2080 }
2081 }
2082 return label; // label
2083}
2084
2085// use (configuration|entity|open) work.test [(cellfor)];
2086
2088{
2089 static const reg::Ex exp(R"([()\s])");
2090
2091 auto ql = split(entity.str(),exp);
2092
2093 if (findIndex(ql,"open")!=std::string::npos)
2094 {
2095 return "open";
2096 }
2097
2098 if (ql.size()<2)
2099 {
2100 return "";
2101 }
2102
2103 std::string label=ql[0];
2104 entity = ql[1];
2105 if (size_t index=entity.rfind('.'); index!=DString::npos)
2106 {
2107 entity.remove(0,index+1);
2108 }
2109
2110 if (ql.size()==3)
2111 {
2112 arch=ql[2];
2113 }
2114 return label;
2115}
2116
2117
2118
2119// find class with upper/lower letters
2121{
2122 for (const auto &cd : *Doxygen::classLinkedMap)
2123 {
2124 if (dstricmp(className.data(),qPrint(cd->name()))==0)
2125 {
2126 return cd.get();
2127 }
2128 }
2129 return nullptr;
2130}
2131
2132
2133/*
2134
2135// file foo.vhd
2136// entity foo
2137// .....
2138// end entity
2139
2140// file foo_arch.vhd
2141// architecture xxx of foo is
2142// ........
2143// end architecture
2144
2145*/
2147{
2148
2149 DString entity,arch,inst;
2150
2151 for (const auto &cur : getVhdlInstList())
2152 {
2153 if (cur->isStatic ) // was bind
2154 {
2155 continue;
2156 }
2157
2158 if (cur->includeName=="entity" || cur->includeName=="component" )
2159 {
2160 entity=cur->includeName+" "+cur->type;
2161 DString rr=VhdlDocGen::parseForBinding(entity,arch);
2162 }
2163 else if (cur->includeName.empty())
2164 {
2165 entity=cur->type;
2166 }
2167
2169 inst=VhdlDocGen::getIndexWord(cur->args,0);
2172
2173 if (cd==nullptr)
2174 {
2175 continue;
2176 }
2177
2178 addInstance(classEntity,ar,cd,cur);
2179 }
2180
2181}
2182
2183static void addInstance(ClassDefMutable* classEntity, ClassDefMutable* ar,
2184 ClassDefMutable *cd , const std::shared_ptr<Entry> &cur)
2185{
2186
2187 DString bName,n1;
2188 if (ar==nullptr) return;
2189
2190 if (classEntity==nullptr)
2191 {
2192 //add component inst
2193 n1=cur->type;
2194 goto ferr;
2195 }
2196
2197 if (classEntity==cd) return;
2198
2199 bName=classEntity->name();
2200 // fprintf(stderr,"\naddInstance %s to %s %s %s\n",qPrint( classEntity->name()),qPrint(cd->name()),qPrint(ar->name()),cur->name);
2201 n1=classEntity->name();
2202
2203 if (!cd->isBaseClass(classEntity, true))
2204 {
2205 cd->insertBaseClass(classEntity,n1,Protection::Public,Specifier::Normal,DString());
2206 }
2207 else
2208 {
2209 VhdlDocGen::addBaseClass(cd,classEntity);
2210 }
2211
2212 if (!VhdlDocGen::isSubClass(classEntity,cd,true,0))
2213 {
2214 classEntity->insertSubClass(cd,Protection::Public,Specifier::Normal,DString());
2215 classEntity->setLanguage(SrcLangExt::VHDL);
2216 }
2217
2218ferr:
2219 DString uu=cur->name;
2220 auto md = createMemberDef(
2221 ar->getDefFileName(), cur->startLine,cur->startColumn,
2222 n1,uu,uu, DString(),
2223 Protection::Public,
2224 Specifier::Normal,
2225 cur->isStatic,
2226 Relationship::Member,
2227 MemberType::Variable,
2228 ArgumentList(),
2229 ArgumentList(),
2230 "");
2231 auto mmd = toMemberDefMutable(md.get());
2232
2233 if (!ar->getOutputFileBase().empty())
2234 {
2235 TagInfo tg;
2236 tg.anchor = nullptr;
2237 tg.fileName = ar->getOutputFileBase();
2238 tg.tagName = nullptr;
2239 mmd->setTagInfo(&tg);
2240 }
2241
2242 //fprintf(stderr,"\n%s%s%s\n",qPrint(md->name()),qPrint(cur->brief),qPrint(cur->doc));
2243
2244 mmd->setLanguage(SrcLangExt::VHDL);
2245 mmd->setVhdlSpecifiers(VhdlSpecifier::INSTANTIATION);
2246 mmd->setBriefDescription(cur->brief,cur->briefFile,cur->briefLine);
2247 mmd->setBodySegment(cur->startLine,cur->startLine,-1) ;
2248 mmd->setDocumentation(cur->doc,cur->docFile,cur->docLine);
2249 FileDef *fd=ar->getFileDef();
2250 mmd->setBodyDef(fd);
2251 ar->insertMember(md.get());
2253 mn->push_back(std::move(md));
2254
2255}
2256
2257
2259{
2260 if (size_t i=mdef->name().find('~'); i!=DString::npos && i>0)
2261 {
2262 //sets the real record member name
2263 mdef->setName(mdef->name().left(i));
2264 }
2265
2266 writeLink(mdef,ol);
2267 ol.startBold();
2268 ol.insertMemberAlign();
2269 if (!ltype.empty())
2270 {
2271 VhdlDocGen::formatString(ltype,ol,mdef);
2272 }
2273 ol.endBold();
2274}
2275
2276
2278 const MemberDef *md,
2279 OutputList& ol,
2280 DString largs)
2281{
2282
2283 StringVector ql=split(largs.str(),"#");
2284 size_t len=ql.size();
2285 ol.startParameterList(true);
2286 bool first=true;
2287
2288 for(size_t i=0;i<len;i++)
2289 {
2290 DString n = ql[i];
2291 ol.startParameterType(first,"");
2292 ol.endParameterType();
2293 ol.startParameterName(true);
2294 VhdlDocGen::formatString(n,ol,md);
2295 ol.endParameterName();
2297 if ((len-i)>1)
2298 {
2299 ol.endParameterExtra(false,false,false);
2300 }
2301 else
2302 {
2303 ol.endParameterExtra(true,false,true);
2304 }
2305
2306 first=false;
2307 }
2308
2309}//#
2310
2311
2312
2313bool VhdlDocGen::isSubClass(ClassDef* cd,ClassDef *scd, bool followInstances,int level)
2314{
2315 bool found=false;
2316 //printf("isBaseClass(cd=%s) looking for %s\n",qPrint(name()),qPrint(bcd->name()));
2317 if (level>255)
2318 {
2319 err("Possible recursive class relation while inside {} and looking for {}\n",cd->name(),scd->name());
2320 abort();
2321 }
2322
2323 for (const auto &bcd :cd->subClasses())
2324 {
2325 const ClassDef *ccd=bcd.classDef;
2326 if (!followInstances && ccd->templateMaster()) ccd=ccd->templateMaster();
2327 //printf("isSubClass() subclass %s\n",qPrint(ccd->name()));
2328 if (ccd==scd)
2329 {
2330 found=true;
2331 }
2332 else
2333 {
2334 if (level <256)
2335 {
2336 level = ccd->isBaseClass(scd,followInstances);
2337 if (level>0)
2338 {
2339 found=true;
2340 }
2341 }
2342 }
2343 }
2344 return found;
2345}
2346
2348{
2349 BaseClassList bcl = cd->baseClasses();
2350 for (auto &bcd : bcl)
2351 {
2352 ClassDef *ccd = bcd.classDef;
2353 if (ccd==ent)
2354 {
2355 DString n = bcd.usedName;
2356 size_t i = n.find('(');
2357 if (i==DString::npos)
2358 {
2359 bcd.usedName.append("(2)");
2360 return;
2361 }
2362 static const reg::Ex reg(R"(\d+)");
2363 DString s=n.left(i);
2364 DString r=n.mid(i);
2365 std::string t=r.str();
2368 r.setNum(r.toInt()+1);
2369 reg::replace(t, reg, r.str());
2370 s.append(t);
2371 bcd.usedName=s;
2372 bcd.templSpecifiers=t;
2373 }
2374 }
2375 cd->updateBaseClasses(bcl);
2376}
2377
2378
2379static std::vector<const MemberDef*> mdList;
2380
2381static const MemberDef* findMemFlow(const MemberDef* mdef)
2382{
2383 for (const auto &md : mdList)
2384 {
2385 if (md->name()==mdef->name() && md->getStartBodyLine()==mdef->getStartBodyLine())
2386 {
2387 return md;
2388 }
2389 }
2390 return nullptr;
2391}
2392
2394{
2395 if (mdef==nullptr) return;
2396
2397 DString codeFragment;
2398 const MemberDef* mm=nullptr;
2399 if ((mm=findMemFlow(mdef))!=nullptr)
2400 {
2401 // don't create the same flowchart twice
2403 return;
2404 }
2405 else
2406 {
2407 mdList.push_back(mdef);
2408 }
2409
2410 //fprintf(stderr,"\n create flow mem %s %p\n",qPrint(mdef->name()),mdef);
2411
2412 int actualStart= mdef->getStartBodyLine();
2413 int actualEnd=mdef->getEndBodyLine();
2414 const FileDef* fd=mdef->getFileDef();
2415 bool b=readCodeFragment( fd->absFilePath(), false, actualStart, actualEnd, codeFragment);
2416 if (!b) return;
2417
2418 auto parser { Doxygen::parserManager->getOutlineParser(".vhd") };
2420 std::shared_ptr<Entry> root = std::make_shared<Entry>();
2421 StringVector filesInSameTu;
2422 parser->parseInput("",codeFragment.data(),root,nullptr);
2423}
2424
2426{
2427 std::lock_guard lock(g_vhdlMutex);
2428 g_varMap.clear();
2429 g_classList.clear();
2430 g_packages.clear();
2431}
2432
2438{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::ALIAS; }
2444{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::PORT; }
2448{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::USE; }
2454{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::TYPE; }
2474{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::UNITS; }
2480{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::VFILE; }
2482{ return mdef->getVhdlSpecifiers()==VhdlSpecifier::GROUP; }
2487
2488
2489
2490//############################## Flowcharts #################################################
2491
2492#define STARTL (FlowChart::WHILE_NO | FlowChart::IF_NO | \
2493 FlowChart::FOR_NO | FlowChart::CASE_NO | \
2494 FlowChart::LOOP_NO | WHEN_NO)
2495#define DECLN (FlowChart::WHEN_NO | \
2496 FlowChart::ELSIF_NO | FlowChart::IF_NO | \
2497 FlowChart::FOR_NO | FlowChart::WHILE_NO | \
2498 FlowChart::CASE_NO | FlowChart::LOOP_NO )
2499#define STARTFIN (FlowChart::START_NO | FlowChart::END_NO)
2500#define LOOP (FlowChart::FOR_NO | FlowChart::WHILE_NO | \
2501 FlowChart::LOOP_NO )
2502#define ENDCL (FlowChart::END_CASE | FlowChart::END_LOOP)
2503#define EEND (FlowChart::ENDIF_NO | FlowChart::ELSE_NO )
2504#define IFF (FlowChart::ELSIF_NO | FlowChart::IF_NO)
2505#define EXITNEXT (FlowChart::EXIT_NO | FlowChart::NEXT_NO )
2506#define EMPTY (EEND | FlowChart::ELSIF_NO)
2507#define EE (FlowChart::ELSE_NO | FlowChart::ELSIF_NO)
2508#define EMPTNODE (ENDCL | EEND | FlowChart::ELSIF_NO)
2509#define FLOWLEN (flowList.size()-1)
2510
2511static int ifcounter=0;
2512static int nodeCounter=0;
2513
2514static struct
2515{
2516 // link colors
2517 const char *textNodeLink;
2518 const char *yesNodeLink;
2519 const char *noNodeLink;
2520
2521 // node colors
2522 const char* comment;
2523 const char* decisionNode;
2524 const char* varNode;
2525 const char *startEndNode;
2526 const char* textNode;
2527} flowCol =
2528{ "green", // textNodeLink
2529 "red", // yesNodeLink
2530 "black", // noNodeLink
2531 "khaki", // comment
2532 "0.7 0.3 1.0", // decisionNode
2533 "lightyellow", // varNode
2534 "white", // startEndNode
2535 "lightcyan" // textNode
2537
2538std::vector<FlowChart> flowList;
2539
2540#ifdef DEBUGFLOW
2541static std::map<std::string,int> g_keyMap;
2542#endif
2543
2544static void alignText(DString & q)
2545{
2546 if (q.length()<=80) return;
2547
2548 if (q.length()>200)
2549 {
2550 q.resize(200);
2551 }
2552
2553 q.append(" ...");
2554
2555 DString str(q);
2556 DString temp;
2557
2558 while (str.length()>80)
2559 {
2560 size_t j0 = str.rfind(' ',80);
2561 size_t j1 = str.rfind('|',80);
2562 size_t j = j0!=DString::npos && j1!=DString::npos ? std::max(j0,j1) :
2563 j0!=DString::npos ? j0 : j1;
2564 if (j==DString::npos || j==0)
2565 {
2566 temp+=str;
2567 q=temp;
2568 return;
2569 }
2570 else
2571 {
2572 DString qcs=str.left(j);
2573 temp+=qcs+"\\";
2574 temp+="n";
2575 str.remove(0,j);
2576 }
2577 }//while
2578
2579 q=temp+str;
2580// #endif
2581}
2582
2584{
2585 DString ui="-";
2586 std::string q;
2587 std::string t;
2588
2589 ui.fill('-',255);
2590
2591 if (flo.type & STARTL)
2592 {
2593 if (flo.stamp>0)
2594 {
2595 q=ui.left(2*flo.stamp).str();
2596 }
2597 else
2598 {
2599 q=" ";
2600 }
2601 DString nn=flo.exp.stripWhiteSpace();
2602 printf("\nYES: %s%s[%d,%d]",qPrint(q),qPrint(nn),flo.stamp,flo.id);
2603 }
2604 else
2605 {
2606 if (flo.type & COMMENT_NO)
2607 {
2608 t=flo.label.str();
2609 }
2610 else
2611 {
2612 t=flo.text.str();
2613 }
2614 static const reg::Ex ep(R"(\s)");
2615 t = reg::replace(t,ep,std::string());
2616 if (t.empty())
2617 {
2618 t=" ";
2619 }
2620 if (flo.stamp>0)
2621 {
2622 q=ui.left(2*flo.stamp).str();
2623 }
2624 else
2625 {
2626 q=" ";
2627 }
2628 if (flo.type & EMPTNODE)
2629 {
2630 printf("\n NO: %s%s[%d,%d]",qPrint(q),FlowChart::getNodeType(flo.type),flo.stamp,flo.id);
2631 }
2632 else if (flo.type & COMMENT_NO)
2633 {
2634 printf("\n NO: %s%s[%d,%d]",qPrint(t),FlowChart::getNodeType(flo.type),flo.stamp,flo.id);
2635 }
2636 else
2637 {
2638 printf("\n NO: %s[%d,%d]",qPrint(t),flo.stamp,flo.id);
2639 }
2640 }
2641}
2642
2644{
2645 for (const auto &flowChart : flowList)
2646 {
2647 printNode(flowChart);
2648 }
2649}
2650
2652{
2653 FlowChart *flno = nullptr;
2654 bool found=false;
2655 for (size_t j=0;j<flowList.size();j++)
2656 {
2657 FlowChart &flo = flowList[j];
2658 if (flo.type&TEXT_NO)
2659 {
2660 if (!found)
2661 {
2662 flno=&flo;
2663 }
2664 else
2665 {
2666 flno->text+=flo.text;
2667 flowList.erase(flowList.begin()+j);
2668 if (j>0) j=j-1;
2669 }
2670 found=true;
2671 }
2672 else
2673 {
2674 found=false;
2675 }
2676 }
2677
2678 // find if..endif without text
2679 // if..elseif without text
2680 if (!flowList.empty())
2681 {
2682 for (size_t j=0;j<flowList.size()-1;j++)
2683 {
2684 const FlowChart &flo = flowList[j];
2685 int kind = flo.type;
2686 if ( (kind & IFF) || (flo.type & ELSE_NO))
2687 {
2688 const FlowChart &ftemp = flowList[j+1];
2689 if (ftemp.type & EMPTY)
2690 {
2691 FlowChart fc(TEXT_NO,"empty ",DString());
2692 fc.stamp = flo.stamp;
2693 flowList.insert(flowList.begin()+j+1,fc);
2694 }
2695 }
2696 }
2697 }
2698
2699}// colTextNode
2700
2702{
2703 DString node;
2704 node.setNum(n);
2705 return node.prepend("node");
2706}
2707
2709{
2710 ifcounter=0;
2711 nodeCounter=0;
2712 flowList.clear();
2713}
2714
2716{
2717 size_t max=0;
2718 DString s;
2719 StringVector ql=split(com.str(),"\n");
2720 for (size_t j=0;j<ql.size();j++)
2721 {
2722 s=ql[j];
2723 if (max<s.length()) max=s.length();
2724 }
2725
2726 s=ql.back();
2727 int diff=static_cast<int>(max-s.length());
2728
2729 DString n;
2730 if (diff>0)
2731 {
2732 n.fill(' ',2*diff);
2733 n.append(".");
2734 s+=n;
2735 ql.pop_back();
2736 ql.push_back(s.str());
2737 }
2738
2739 for (size_t j=0;j<ql.size();j++)
2740 {
2741 s=ql[j];
2742 if (j<ql.size()-1)
2743 {
2744 s+="\n";
2745 }
2746 FlowChart::codify(t,s);
2747 }
2748}
2749
2750
2752{
2753 size_t size=flowList.size();
2754 bool begin=false;
2755
2756 if (size>0)
2757 {
2758 for (uint32_t j=0;j < size-1 ;j++)
2759 {
2760 FlowChart &fll = flowList[j];
2761 if (fll.type & COMMENT_NO)
2762 {
2763 FlowChart &to=flowList[j+1];
2764 if (to.type & COMMENT_NO)
2765 {
2766 to.label = fll.label+"\n"+to.label;
2767 flowList.erase(flowList.begin()+j);
2768 if (size>0) size--;
2769 if (j>0) j--;
2770 }
2771 }
2772 }// for
2773 }
2774
2775 for (size_t j=0;j <flowList.size() ;j++)
2776 {
2777 const FlowChart &fll=flowList[j];
2778
2779 if (fll.type & BEGIN_NO)
2780 {
2781 begin = true;
2782 continue;
2783 }
2784
2785 if (fll.type & COMMENT_NO)
2786 {
2787 const FlowChart *to = nullptr;
2788 if (!begin)
2789 {
2790 // comment between function/process .. begin is linked to start node
2791 to = &flowList[0];
2792 }
2793 else if (j>0 && flowList[j-1].line==fll.line)
2794 {
2795 to = &flowList[j-1];
2796 }
2797 else
2798 {
2799 to = &flowList[j+1];
2800 }
2801 t << getNodeName(fll.id);
2802 t << "[shape=none, label=<\n";
2803 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
2804 t << "<TR><TD BGCOLOR=\"";
2805 t << flowCol.comment;
2806 t << "\" > ";
2807
2809 t << " </TD></TR></TABLE>>];";
2810 writeEdge(t,fll.id,to->id,2);
2811 }
2812 }// for
2813
2814 // delete comment nodes;
2815 size=flowList.size();
2816 for (size_t j=0; j<size; j++)
2817 {
2818 FlowChart &fll=flowList[j];
2819 if (fll.type & (COMMENT_NO | BEGIN_NO))
2820 {
2821 size_t diff=FLOWLEN-(j+1);
2822
2823 if ((fll.type & COMMENT_NO) && diff > 1)
2824 {
2825 flowList[j+1].label = fll.label;
2826 }
2827
2828 flowList.erase(flowList.begin()+j);
2829
2830 if (size>0) size--;
2831 if (j>0) j--;
2832 }
2833 }// for;
2834}
2835
2837{
2838 if (!str.empty())
2839 {
2840 const char *p=str.data();
2841 while (*p)
2842 {
2843 char c=*p++;
2844 switch(c)
2845 {
2846 case '<': t << "&lt;"; break;
2847 case '>': t << "&gt;"; break;
2848 case '&': t << "&amp;"; break;
2849 case '\'': t << "&#39;"; break;
2850 case '"': t << "&quot;"; break;
2851 case '\n': t <<"<BR ALIGN=\"LEFT\"/>"; break;
2852 default: t << c; break;
2853 }
2854 }
2855 }
2856}//codify
2857
2858FlowChart::FlowChart(int typ,const DString &t,const DString &ex,const DString &lab)
2859{
2861
2862 if (typ & STARTL)
2863 {
2864 ifcounter++;
2865 }
2866
2867 text=t;
2868 exp=ex;
2869 type=typ;
2870 label=lab;
2871
2872 if (typ & (ELSE_NO | ELSIF_NO))
2873 {
2874 stamp--;
2875 }
2876
2877 if (typ & (START_NO | END_NO | VARIABLE_NO))
2878 {
2879 stamp=0;
2880 }
2881
2882 id=nodeCounter++;
2883}
2884
2886{
2887 if (!VhdlDocGen::getFlowMember()) return;
2888
2889 DString typeString(text);
2890 DString expression(exp);
2891
2892
2893 if (!text.empty())
2894 {
2895 typeString=substitute(typeString,";","\n");
2896 }
2897
2898 if (!exp.empty())
2899 {
2900 expression=substitute(expression,"\"","\\\"");
2901 }
2902
2903 if (type & VARIABLE_NO)
2904 {
2905 // Ignore the empty section of the VHDL variable definition.
2906 // This is section between `process` and `begin` keywords, where any source text is missing, probably a bug in the VHDL source parser.
2907 if(text.empty()) return;
2908
2909 flowList.insert(flowList.begin(),FlowChart(type,typeString,expression,label));
2910 flowList.front().line=1; // TODO: use getLine(); of the parser
2911 }
2912 else if (type & START_NO)
2913 {
2914 flowList.insert(flowList.begin(),FlowChart(type,typeString,expression,label));
2915 flowList.front().line=1; // TODO: use getLine(); of the parser
2916 }
2917 else
2918 {
2919 flowList.emplace_back(type,typeString,expression,label);
2920 flowList.back().line=1; // TODO: use getLine(); of the parser
2921 }
2922}
2923
2925{
2926 if (!VhdlDocGen::getFlowMember()) return;
2927 ifcounter--;
2928}
2929
2931{
2932 DString t;
2935 switch (flo.type)
2936 {
2937 case START_NO: t=":"+text+"|"; break;
2938 case IF_NO : t="\nif ("+exp+") then (yes)"; break;
2939 case ELSIF_NO: t="\nelseif ("+exp+") then (yes)"; break;
2940 case ELSE_NO: t="\nelse"; break;
2941 case CASE_NO: t="\n:"+exp+";"; break;
2942 case WHEN_NO: t="\n";
2943 if (!ca) t+="else";
2944 t+="if ("+exp+") then (yes)";
2945 break;
2946 case EXIT_NO: break;
2947 case END_NO: if (text.contains(" function")==0) t="\n:"+text+";";
2948 break;
2949 case TEXT_NO: t="\n:"+text+"]"; break;
2950 case ENDIF_NO: t="\nendif"; break;
2951 case FOR_NO: t="\nwhile ("+exp+") is (yes)"; break;
2952 case WHILE_NO: t="\nwhile ("+exp+") is (yes)"; break;
2953 case END_LOOP: t="\nendwhile"; break;
2954 case END_CASE: t="\nendif\n:end case;"; break;
2955 case VARIABLE_NO:t="\n:"+text+";"; break;
2956 case RETURN_NO: t="\n:"+text+";";
2957 if (!endL) t+="\nstop";
2958 break;
2959 case LOOP_NO: t="\nwhile (infinite loop)"; break;
2960 case NEXT_NO: break;
2961 case EMPTY_NO: break;
2962 case COMMENT_NO: t="\n note left \n "+flo.label+"\nend note \n"; break;
2963 case BEGIN_NO: t="\n:begin;"; break;
2964 default: assert(false); break;
2965 }
2966 return t;
2967}
2968
2970{
2971 int caseCounter = 0;
2972 int whenCounter = 0;
2973
2974 DString qcs;
2975 size_t size=flowList.size();
2976 for (size_t j=0;j<size;j++)
2977 {
2978 bool endList = j==FLOWLEN;
2979 const FlowChart &flo = flowList[j];
2980 if (flo.type==CASE_NO)
2981 {
2982 caseCounter++;
2983 whenCounter=0;
2984 }
2985
2986 if (flo.type==END_CASE)
2987 {
2988 caseCounter--;
2989 }
2990
2991 bool ca = (caseCounter>0 && whenCounter==0);
2992
2993 qcs+=printPlantUmlNode(flo,ca,endList);
2994
2995 if (flo.type==WHEN_NO)
2996 {
2997 whenCounter++;
2998 }
2999
3000 }
3001 qcs+="\n";
3002
3003 DString htmlOutDir = Config_getString(HTML_OUTPUT);
3004
3006 auto baseNameVector=PlantumlManager::instance().writePlantUMLSource(htmlOutDir,n,qcs,PlantumlManager::PUML_SVG,"uml",n,1,true);
3007 for (const auto &baseName: baseNameVector)
3008 {
3010 }
3011}
3012
3017
3018const char* FlowChart::getNodeType(int c)
3019{
3020 switch(c)
3021 {
3022 case IF_NO: return "if ";
3023 case ELSIF_NO: return "elsif ";
3024 case ELSE_NO: return "else ";
3025 case CASE_NO: return "case ";
3026 case WHEN_NO: return "when ";
3027 case EXIT_NO: return "exit ";
3028 case END_NO: return "end ";
3029 case TEXT_NO: return "text ";
3030 case START_NO: return "start ";
3031 case ENDIF_NO: return "endif ";
3032 case FOR_NO: return "for ";
3033 case WHILE_NO: return "while ";
3034 case END_LOOP: return "end_loop ";
3035 case END_CASE: return "end_case ";
3036 case VARIABLE_NO: return "variable_decl ";
3037 case RETURN_NO: return "return ";
3038 case LOOP_NO: return "infinite loop ";
3039 case NEXT_NO: return "next ";
3040 case COMMENT_NO: return "comment ";
3041 case EMPTY_NO: return "empty ";
3042 case BEGIN_NO: return "<begin> ";
3043 default: return "--failure--";
3044 }
3045}
3046
3048{
3049 DString qcs("/");
3050 DString ov = Config_getString(HTML_OUTPUT);
3051
3053
3054 //const MemberDef *m=VhdlDocGen::getFlowMember();
3055 //if (m)
3056 // fprintf(stderr,"\n creating flowchart : %s %s in file %s \n",theTranslator->trVhdlType(m->getMemberSpecifiers(),true),qPrint(m->name()),qPrint(m->getFileDef()->name()));
3057
3058 DString dir=" -o \""+ov+qcs+"\"";
3059 ov+="/flow_design.dot";
3060
3061 DString vlargs="-Tsvg \""+ov+"\" "+dir ;
3062
3064 {
3065 err("could not create dot file\n");
3066 }
3067}
3068
3070{
3071 t << " digraph G { \n";
3072 t << "rankdir=TB \n";
3073 t << "concentrate=true\n";
3074 t << "stylesheet=\"doxygen.css\"\n";
3075}
3076
3078{
3079 t << " } \n";
3080}
3081
3083{
3084 // assert(VhdlDocGen::flowMember);
3085
3086 DString ov = Config_getString(HTML_OUTPUT);
3087 DString fileName = ov+"/flow_design.dot";
3088 std::ofstream f = Portable::openOutputStream(fileName);
3089 if (!f.is_open())
3090 {
3091 err("Cannot open file {} for writing\n",fileName);
3092 return;
3093 }
3094 TextStream t(&f);
3095
3096 colTextNodes();
3097 // buildCommentNodes(t);
3098
3099#ifdef DEBUGFLOW
3100 printFlowTree();
3101#endif
3102
3104 {
3105 printUmlTree();
3106 delFlowList();
3107 t.flush();
3108 f.close();
3109 return;
3110 }
3111
3112 startDot(t);
3114 for (const auto &fll : flowList)
3115 {
3116 writeShape(t,fll);
3117 }
3118 writeFlowLinks(t);
3119
3121 delFlowList();
3122 t.flush();
3123 f.close();
3125}// writeFlowChart
3126
3128{
3129 if (fl.type & EEND) return;
3130 DString var;
3131 if (fl.type & LOOP)
3132 {
3133 var=" loop";
3134 }
3135 else if (fl.type & IFF)
3136 {
3137 var=" then";
3138 }
3139 else
3140 {
3141 var="";
3142 }
3143
3144 t << getNodeName(fl.id);
3145
3146#ifdef DEBUGFLOW
3147 DString qq(getNodeName(fl.id));
3148 g_keyMap.emplace(qq.str(),fl.id);
3149#endif
3150
3151 bool dec=(fl.type & DECLN);
3152 bool exit=(fl.type & EXITNEXT);
3153 if (exit && !fl.exp.empty())
3154 {
3155 dec=true;
3156 }
3157 if (dec)
3158 {
3159 DString exp=fl.exp;
3160 alignText(exp);
3161
3162 t << " [shape=diamond,style=filled,color=\"";
3163 t << flowCol.decisionNode;
3164 t << "\",label=\" ";
3165 DString kl;
3166 if (exit) kl=fl.text+" ";
3167
3168 if (!fl.label.empty())
3169 {
3170 kl+=fl.label+":"+exp+var;
3171 }
3172 else
3173 {
3174 kl+=exp+var;
3175 }
3176
3178 t << "\"]\n";
3179 }
3180 else if (fl.type & ENDCL)
3181 {
3182 DString val=fl.text;
3183 t << " [shape=ellipse ,label=\""+val+"\"]\n";
3184 }
3185 else if (fl.type & STARTFIN)
3186 {
3187 DString val=fl.text;
3188 t << "[shape=box , style=rounded label=<\n";
3189 t << "<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\" >\n ";
3190 t << "<TR><TD BGCOLOR=\"";
3191 t<< flowCol.startEndNode;
3192 t<< "\"> ";
3194 t << " </TD></TR></TABLE>>];";
3195 }
3196 else
3197 {
3198 if (fl.text.empty()) return;
3199 bool isVar=(fl.type & FlowChart::VARIABLE_NO);
3200 DString q=fl.text;
3201
3202 if (exit)
3203 {
3204 q+=" "+fl.label;
3205 }
3206
3207 size_t z=q.rfind('\n');
3208
3209 if (z!=DString::npos && z==q.length()-1)
3210 {
3211 q=q.remove(z,2);
3212 }
3213 t << "[shape=none margin=0.1, label=<\n";
3214 t << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"2\" >\n ";
3215 if (isVar)
3216 {
3217 t << "<TR><TD BGCOLOR=\"" << flowCol.varNode << "\" > ";
3218 }
3219 else
3220 {
3221 t << "<TR><TD BGCOLOR=\"" << flowCol.textNode << "\" > ";
3222 }
3224 t << " </TD></TR></TABLE>>];";
3225 }
3226}
3227
3228
3229void FlowChart::writeEdge(TextStream &t,const FlowChart &fl_from,const FlowChart &fl_to,int i)
3230{
3231 bool b=fl_from.type & STARTL;
3232 bool c=fl_to.type & STARTL;
3233
3234#ifdef DEBUGFLOW
3235 DString s1(getNodeName(fl_from.id));
3236 DString s2(getNodeName(fl_to.id));
3237 auto it = g_keyMap.find(s1.str());
3238 auto it1 = g_keyMap.find(s2.str());
3239 // checks if the link is connected to a valid node
3240 assert(it!=g_keyMap.end());
3241 assert(it1!=g_keyMap.end());
3242#endif
3243
3244 writeEdge(t,fl_from.id,fl_to.id,i,b,c);
3245}
3246
3247void FlowChart::writeEdge(TextStream &t,int fl_from,int fl_to,int i,bool bFrom,bool bTo)
3248{
3249 DString label,col;
3250
3251 if (i==0)
3252 {
3253 col=flowCol.yesNodeLink;
3254 label="yes";
3255 }
3256 else if (i==1)
3257 {
3258 col=flowCol.noNodeLink;
3259 label="no";
3260 }
3261 else
3262 {
3263 col=flowCol.textNodeLink;
3264 label="";
3265 }
3266
3267 t << "edge [color=\""+col+"\",label=\""+label+"\"]\n";
3268 t << getNodeName(fl_from);
3269 if (bFrom) t << ":s";
3270 t << "->";
3271 t << getNodeName(fl_to);
3272 if (bTo) t << ":n";
3273 t << "\n";
3274}
3275
3276void FlowChart::alignFuncProc( DString & q,const ArgumentList &al,bool isFunc)
3277{
3278 size_t index=al.size();
3279 if (index==0) return;
3280
3281 size_t len=q.length()+VhdlDocGen::getFlowMember()->name().length();
3282 DString prev,temp;
3283 prev.fill(' ',static_cast<int>(len)+1);
3284
3285 q+="\n";
3286 for (const Argument &arg : al)
3287 {
3288 DString attl=arg.defval+" ";
3289 attl+=arg.name+" ";
3290
3291 if (!isFunc)
3292 {
3293 attl+=arg.attrib+" ";
3294 }
3295 else
3296 {
3297 attl+=" in ";
3298 }
3299 attl+=arg.type;
3300 if (--index) attl+=",\n"; else attl+="\n";
3301
3302 attl.prepend(prev);
3303 temp+=attl;
3304 }
3305
3306 q+=temp;
3307}
3308
3309size_t FlowChart::findNextLoop(size_t index,int stamp)
3310{
3311 for (size_t j=index+1; j<flowList.size(); j++)
3312 {
3313 const FlowChart &flo = flowList[j];
3314 if (flo.stamp==stamp)
3315 {
3316 continue;
3317 }
3318 if (flo.type&END_LOOP)
3319 {
3320 return j;
3321 }
3322 }
3323 return flowList.size()-1;
3324}
3325
3326size_t FlowChart::findPrevLoop(size_t index,int stamp,bool endif)
3327{
3328 for (size_t j=index;j>0;j--)
3329 {
3330 const FlowChart &flo = flowList[j];
3331 if (flo.type & LOOP)
3332 {
3333 if (flo.stamp==stamp && endif)
3334 {
3335 return j;
3336 }
3337 else
3338 {
3339 if (flo.stamp<stamp)
3340 {
3341 return j;
3342 }
3343 }
3344 }
3345 }
3346 return flowList.size()-1;
3347}
3348
3349size_t FlowChart::findLabel(size_t index,const DString &label)
3350{
3351 for (size_t j=index;j>0;j--)
3352 {
3353 const FlowChart &flo = flowList[j];
3354 if ((flo.type & LOOP) && !flo.label.empty() && dstricmp(flo.label,label)==0)
3355 {
3356 return j;
3357 }
3358 }
3359 err("could not find label: '{}'\n",label);
3360 return 0;
3361}
3362
3363size_t FlowChart::findNode(size_t index,int stamp,int type)
3364{
3365 for (size_t j=index+1; j<flowList.size(); j++)
3366 {
3367 const FlowChart &flo = flowList[j];
3368 if (flo.type==type && flo.stamp==stamp)
3369 {
3370 return j;
3371 }
3372 }
3373 return 0;
3374}// findNode
3375
3376size_t FlowChart::getNextNode(size_t index,int stamp)
3377{
3378 for (size_t j=index+1; j<flowList.size(); j++)
3379 {
3380 const FlowChart &flo = flowList[j];
3381 int kind = flo.type;
3382 int s = flo.stamp;
3383 if (s>stamp)
3384 {
3385 continue;
3386 }
3387 if (kind & ENDIF_NO)
3388 {
3389 if (s<stamp && stamp>0)
3390 {
3391 stamp--;
3392 continue;
3393 }
3394 }
3395 if (kind & (ELSE_NO | ELSIF_NO))
3396 {
3397 if (s<stamp && stamp>0)
3398 {
3399 stamp--;
3400 }
3401 j=findNode(j,stamp,ENDIF_NO);
3402 continue;
3403 }
3404 if (kind & WHEN_NO)
3405 {
3406 if (s<stamp && stamp>0)
3407 {
3408 stamp--;
3409 }
3410 return findNode(j,stamp-1,END_CASE);
3411 }
3412 return j;
3413 }
3414 return FLOWLEN;
3415}
3416
3417size_t FlowChart::getNextIfLink(const FlowChart &fl,size_t index)
3418{
3419 int stamp=fl.stamp;
3420 size_t start = index+1;
3421 size_t endifNode = findNode(start,stamp,ENDIF_NO);
3422 size_t elseifNode = findNode(start,stamp,ELSIF_NO);
3423 size_t elseNode = findNode(start,stamp,ELSE_NO);
3424
3425 if (elseifNode>0 && elseifNode<endifNode)
3426 {
3427 return elseifNode;
3428 }
3429
3430 if (elseNode>0 && elseNode<endifNode)
3431 {
3432 return elseNode+1;
3433 }
3434
3435 stamp=flowList[endifNode].stamp;
3436 return getNextNode(endifNode,stamp);
3437}
3438
3440{
3441 size_t size=flowList.size();
3442 if (size<2) return;
3443
3444 // write start link
3445 writeEdge(t,flowList[0],flowList[1],2);
3446
3447 for (size_t j=0;j<size;j++)
3448 {
3449 const FlowChart &fll = flowList[j];
3450 int kind = fll.type;
3451 int stamp = fll.stamp;
3452 if (kind & EEND)
3453 {
3454 continue;
3455 }
3456
3457 if (kind & IFF)
3458 {
3459 writeEdge(t,fll,flowList[j+1],0);
3460 size_t z=getNextIfLink(fll,j);
3461 // assert(z>-1);
3462 writeEdge(t,fll,flowList[z],1);
3463 }
3464 else if (kind & LOOP_NO)
3465 {
3466 writeEdge(t,fll,flowList[j+1],2);
3467 continue;
3468 }
3469 else if (kind & (CASE_NO | FOR_NO | WHILE_NO))
3470 {
3471 if (kind & CASE_NO)
3472 {
3473 writeEdge(t,fll,flowList[j+1],2);
3474 continue;
3475 }
3476 else
3477 {
3478 writeEdge(t,fll,flowList[j+1],0);
3479 }
3480
3481 kind=END_LOOP;
3482 size_t z=findNode(j+1,fll.stamp,kind);
3483 z=getNextNode(z,flowList[z].stamp);
3484
3485 // assert(z>-1);
3486 writeEdge(t,fll,flowList[z],1);
3487 continue;
3488 }
3489 else if (kind & (TEXT_NO | VARIABLE_NO))
3490 {
3491 size_t z=getNextNode(j,stamp);
3492 writeEdge(t,fll,flowList[z],2);
3493 }
3494 else if (kind & WHEN_NO)
3495 {
3496 // default value
3497 if (dstricmp(fll.text.simplifyWhiteSpace(),"others")==0)
3498 {
3499 writeEdge(t,fll,flowList[j+1],2);
3500 continue;
3501 }
3502
3503
3504 writeEdge(t,fll,flowList[j+1],0);
3505 size_t u=findNode(j,stamp,WHEN_NO);
3506 size_t v=findNode(j,stamp-1,END_CASE);
3507
3508 if (u>0 && u<v)
3509 {
3510 writeEdge(t,fll,flowList[u],1);
3511 }
3512 else
3513 {
3514 writeEdge(t,fll,flowList[v],1);
3515 }
3516 }
3517 else if (kind & END_CASE)
3518 {
3519 size_t z=FlowChart::getNextNode(j,fll.stamp);
3520 writeEdge(t,fll,flowList[z],2);
3521 }
3522 else if (kind & END_LOOP)
3523 {
3524 size_t z=findPrevLoop(j,fll.stamp,true);
3525 writeEdge(t,fll,flowList[z],2);
3526 }
3527 else if (kind & RETURN_NO)
3528 {
3529 writeEdge(t,fll,flowList[size-1],2);
3530 }
3531 else if (kind & (EXIT_NO | NEXT_NO))
3532 {
3533 size_t z = 0;
3534 bool b = kind==NEXT_NO;
3535 if (!fll.exp.empty())
3536 {
3537 writeEdge(t,fll,flowList[j+1],1);
3538 }
3539 if (!fll.label.empty())
3540 {
3541 z=findLabel(j,fll.label);
3542 if (b)
3543 {
3544 writeEdge(t,fll,flowList[z],0);
3545 }
3546 else
3547 {
3549 z=getNextNode(z,flowList[z].stamp);
3550 writeEdge(t,fll,flowList[z],0);
3551 }
3552 continue;
3553 }
3554 else
3555 {
3556 if (b)
3557 {
3558 z=findPrevLoop(j,fll.stamp);
3559 writeEdge(t,fll,flowList[z],0);
3560 continue;
3561 }
3562 else
3563 {
3564 z =findNextLoop(j,fll.stamp-1);
3565 }
3566 z=getNextNode(z,flowList[z].stamp);
3567 }
3568 writeEdge(t,fll,flowList[z],0);
3569 }
3570 } //for
3571} //writeFlowLinks
This class represents an function or template argument list.
Definition arguments.h:65
bool hasParameters() const
Definition arguments.h:76
size_t size() const
Definition arguments.h:100
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual void updateBaseClasses(const BaseClassList &bcd)=0
Update the list of base classes to the one passed.
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual int isBaseClass(const ClassDef *bcd, bool followInstances, const DString &templSpec=DString()) const =0
Returns true iff bcd is a direct or indirect base class of this class.
virtual DString className() const =0
Returns the name of the class including outer classes, but not including namespaces.
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
virtual MemberList * getMemberList(MemberListType lt) const =0
Returns the members in the list identified by lt.
virtual const ClassDef * templateMaster() const =0
Returns the template master of which this class is an instance.
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class.
virtual void insertMember(MemberDef *)=0
virtual void insertSubClass(ClassDef *, Protection p, Specifier s, const DString &t=DString())=0
virtual void insertBaseClass(ClassDef *, const DString &name, Protection p, Specifier s, const DString &t=DString())=0
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:89
void clear()
Definition dstring.h:219
DString & setNum(short n)
Definition dstring.h:557
void resize(size_t newlen)
Definition dstring.h:214
DString()=default
DString upper() const
Definition dstring.h:336
size_t rfind(char c, size_t pos=npos) const
Definition dstring.h:249
DString fill(char c, size_t len)
Fills a string with a predefined character.
Definition dstring.h:283
DString mid(size_t index, size_t len=npos) const
Definition dstring.h:323
DString lower() const
Definition dstring.h:331
DString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple internal white...
Definition dstring.cpp:123
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:153
DString & replace(size_t index, size_t len, const char *s)
Definition dstring.cpp:150
DString & remove(size_t index, size_t len)
Definition dstring.h:540
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:183
char & at(size_t i)
Returns a reference to the character at index i.
Definition dstring.h:691
DString & append(char c)
Definition dstring.h:494
size_t rfind_insensitive(char c, size_t pos=npos) const
Definition dstring.cpp:44
DString & prepend(const char *s)
Definition dstring.h:520
int contains(char c, bool cs=true) const
Definition dstring.cpp:81
size_t find(char c, size_t pos=0) const
Definition dstring.h:244
int toInt(bool *ok=nullptr, int base=10) const
Definition dstring.cpp:187
DString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition dstring.h:342
DString left(size_t len) const
Definition dstring.h:311
const std::string & str() const
Definition dstring.h:650
bool stripPrefix(const DString &prefix)
Definition dstring.h:295
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:162
bool startsWith(const char *s) const
Definition dstring.h:605
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:156
The common base class of all entity definitions found in the sources.
Definition definition.h:77
virtual DString briefDescription(bool abbreviate=false) const =0
virtual int getEndBodyLine() const =0
virtual DString briefFile() const =0
virtual DString getDefFileName() const =0
virtual DString documentation() const =0
virtual bool isLinkable() const =0
virtual const DString & name() const =0
virtual const DString & localName() const =0
virtual int briefLine() const =0
virtual DString symbolName() const =0
virtual DString qualifiedName() const =0
virtual DString anchor() const =0
virtual DString getReference() const =0
virtual Definition * getOuterScope() const =0
virtual int getStartBodyLine() const =0
virtual DString getOutputFileBase() const =0
virtual void setName(const DString &name)=0
virtual void writeSourceReffedBy(OutputList &ol, const DString &scopeName) const =0
virtual void writeSourceDef(OutputList &ol) const =0
virtual void setLanguage(SrcLangExt lang)=0
virtual void writeDocAnchorsToTagFile(TextStream &) const =0
virtual void setBodyDef(const FileDef *fd)=0
virtual void writeSourceRefs(OutputList &ol, const DString &scopeName) const =0
static ParserManager * parserManager
Definition doxygen.h:129
static DString verifiedDotPath
Definition doxygen.h:137
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:95
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static SearchIndexIntf searchIndex
Definition doxygen.h:124
Represents an unstructured piece of information, about an entity found in the sources.
Definition entry.h:117
void moveToSubEntryAndKeep(Entry *e)
Definition entry.cpp:146
A model of a file symbol.
Definition filedef.h:99
virtual DString absFilePath() const =0
static DString printPlantUmlNode(const FlowChart &flo, bool, bool)
DString text
Definition vhdldocgen.h:312
DString exp
Definition vhdldocgen.h:313
static DString convertNameToFileName()
static void alignCommentNode(TextStream &t, DString com)
static void printFlowTree()
static void addFlowChart(int type, const DString &text, const DString &exp, const DString &label=DString())
static void startDot(TextStream &t)
DString label
Definition vhdldocgen.h:311
static const char * getNodeType(int c)
static void writeEdge(TextStream &t, int fl_from, int fl_to, int i, bool bFrom=false, bool bTo=false)
static void codify(TextStream &t, const DString &str)
static void delFlowList()
static size_t getNextNode(size_t index, int stamp)
static void writeFlowChart()
static void colTextNodes()
static void createSVG()
static size_t findNextLoop(size_t j, int stamp)
static size_t findPrevLoop(size_t j, int stamp, bool endif=false)
static void alignFuncProc(DString &q, const ArgumentList &al, bool isFunc)
static void writeShape(TextStream &t, const FlowChart &fl)
static size_t getNextIfLink(const FlowChart &, size_t)
static void printNode(const FlowChart &n)
FlowChart(int typ, const DString &t, const DString &ex, const DString &label=DString())
static void moveToPrevLevel()
static size_t findLabel(size_t j, const DString &)
static size_t findNode(size_t index, int stamp, int type)
static void buildCommentNodes(TextStream &t)
static void printUmlTree()
static void writeFlowLinks(TextStream &t)
static void endDot(TextStream &t)
static DString getNodeName(int n)
A model of a group of symbols.
Definition groupdef.h:52
T * add(const char *k, Args &&... args)
Definition linkedmap.h:90
const T * find(const std::string &key) const
Definition linkedmap.h:47
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual bool hasDetailedDescription() const =0
virtual void warnIfUndocumented() const =0
virtual DString argsString() const =0
virtual const ClassDef * getClassDef() const =0
virtual bool hasReferencesRelation() const =0
virtual DString excpString() const =0
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
virtual const ArgumentList & argumentList() const =0
virtual VhdlSpecifier getVhdlSpecifiers() const =0
virtual const ClassDef * getClassDefOfAnonymousType() const =0
virtual bool hasReferencedByRelation() const =0
virtual bool isBriefSectionVisible() const =0
virtual bool isVariable() const =0
virtual DString typeString() const =0
virtual void setVhdlSpecifiers(VhdlSpecifier s)=0
virtual void setType(const DString &t)=0
A list of MemberDef objects as shown in documentation sections.
Definition memberlist.h:125
MemberListType listType() const
Definition memberlist.h:130
const MemberGroupRefList & getMemberGroupList() const
Definition memberlist.h:166
Wrapper class for the MemberListType type.
Definition types.h:346
constexpr const char * toLabel() const noexcept
Definition types.h:402
void push_back(Ptr &&p)
Definition membername.h:54
An abstract interface of a namespace symbol.
void startCodeFragment(const DString &style)
Definition outputlist.h:280
void startFontClass(const DString &c)
Definition outputlist.h:271
Class representing a list of output generators that are written to in parallel.
Definition outputlist.h:315
bool isEnabled(OutputType o)
void parseText(const DString &textStr)
void endParameterExtra(bool last, bool one, bool bracket)
Definition outputlist.h:694
void writeChar(char c)
Definition outputlist.h:529
void disable(OutputType o)
void writeObjectLink(const DString &ref, const DString &file, const DString &anchor, const DString &name)
Definition outputlist.h:439
void endMemberDocName()
Definition outputlist.h:682
void startParameterExtra()
Definition outputlist.h:692
const OutputCodeList & codeGenerators() const
Definition outputlist.h:358
void startParameterList(bool openBracket)
Definition outputlist.h:700
void enable(OutputType o)
void endMemberDescription()
Definition outputlist.h:567
void endMemberGroupDocs()
Definition outputlist.h:511
void docify(const DString &s)
Definition outputlist.h:437
void startMemberHeader(const DString &anchor, int typ=2)
Definition outputlist.h:469
void lineBreak(const DString &style=DString())
Definition outputlist.h:559
void endMemberGroupHeader(bool b)
Definition outputlist.h:507
void insertMemberAlign(bool templ=false)
Definition outputlist.h:517
void insertMemberAlignLeft(OutputGenerator::MemberItemType typ=OutputGenerator::MemberItemType::Normal, bool templ=false)
Definition outputlist.h:519
void endEmphasis()
Definition outputlist.h:527
void writeString(const DString &text)
Definition outputlist.h:411
void endDoxyAnchor(const DString &fn, const DString &anchor)
Definition outputlist.h:541
void startMemberGroup()
Definition outputlist.h:513
void startMemberGroupHeader(const DString &id, bool b)
Definition outputlist.h:505
void startMemberList()
Definition outputlist.h:481
void endTextLink()
Definition outputlist.h:444
void addLabel(const DString &fName, const DString &anchor)
Definition outputlist.h:543
void startBold()
Definition outputlist.h:561
void endMemberItem(OutputGenerator::MemberItemType type)
Definition outputlist.h:495
void endMemberList()
Definition outputlist.h:483
void pushGeneratorState()
void disableAllBut(OutputType o)
void endParameterName()
Definition outputlist.h:690
void popGeneratorState()
void startTextLink(const DString &file, const DString &anchor)
Definition outputlist.h:442
void endBold()
Definition outputlist.h:563
void startMemberItem(const DString &anchor, OutputGenerator::MemberItemType type, const DString &id=DString())
Definition outputlist.h:493
void startMemberDescription(const DString &anchor, const DString &inheritId=DString(), bool typ=false)
Definition outputlist.h:565
void startEmphasis()
Definition outputlist.h:525
void generateDoc(const DString &fileName, int startLine, const Definition *ctx, const MemberDef *md, const DString &docStr, const DocOptions &options)
void endMemberGroup(bool last)
Definition outputlist.h:515
void startMemberGroupDocs()
Definition outputlist.h:509
void endParameterType()
Definition outputlist.h:686
void startParameterName(bool one)
Definition outputlist.h:688
void enableAll()
void endMemberHeader()
Definition outputlist.h:471
void endMemberSubtitle()
Definition outputlist.h:475
void startParameterType(bool first, const DString &key)
Definition outputlist.h:684
void startMemberSubtitle()
Definition outputlist.h:473
void startDoxyAnchor(const DString &fName, const DString &manName, const DString &anchor, const DString &name, const DString &args)
Definition outputlist.h:537
std::unique_ptr< CodeParserInterface > getCodeParser(const DString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:254
std::unique_ptr< OutlineParserInterface > getOutlineParser(const DString &extension)
Gets the interface to the parser associated with a given extension.
Definition parserintf.h:245
void generatePlantUMLOutput(const DString &baseName, const DString &outDir, OutputFormat format, bool toIndex)
Convert a PlantUML file to an image.
Definition plantuml.cpp:201
StringVector writePlantUMLSource(const DString &outDirArg, const DString &fileName, const DString &content, OutputFormat format, const DString &engine, const DString &srcFile, int srcLine, bool inlineCode)
Write a PlantUML compatible file.
Definition plantuml.cpp:31
static bool isEnabled()
Returns true if doxygen has been configured to run PlantUML, i.e.
Definition plantuml.cpp:240
static PlantumlManager & instance()
Definition plantuml.cpp:230
void addWord(const DString &word, bool hiPriority)
void setCurrentDoc(const Definition *ctx, const DString &anchor, bool isSourceFile)
Text streaming class that buffers data.
Definition textstream.h:36
void flush()
Flushes the buffer.
Definition textstream.h:212
virtual DString trVhdlType(VhdlSpecifier type, bool single)=0
static void findAllPackages(ClassDef *)
@ ARCHITECTURECLASS
Definition vhdldocgen.h:77
static const char * findKeyWord(const DString &word)
static bool writeVHDLTypeDocumentation(const MemberDef *mdef, const Definition *d, OutputList &ol)
static bool isArchitecture(const MemberDef *mdef)
static DString getClassTitle(const ClassDef *)
static bool isGroup(const MemberDef *mdef)
static bool isSignal(const MemberDef *mdef)
static void correctMemberProperties(MemberDefMutable *md)
static const MemberDef * findFunction(const DString &name, const DString &package)
static const MemberDef * getFlowMember()
static void writeStringLink(const MemberDef *mdef, DString mem, OutputList &ol)
static bool isProcess(const MemberDef *mdef)
static DString getProtectionName(int prot)
static void prepareComment(DString &)
static void parseFuncProto(const DString &text, DString &name, DString &ret, bool doc=false)
static void deleteAllChars(DString &s, char c)
static bool isConstant(const MemberDef *mdef)
static bool isAttribute(const MemberDef *mdef)
static void createFlowChart(const MemberDef *)
static void writeVHDLDeclarations(const MemberList *ml, OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, const DString &title, const DString &subtitle, bool showEnumValues, VhdlSpecifier type)
static void writeProcessProto(OutputList &ol, const ArgumentList &al, const MemberDef *)
static const MemberDef * findMember(const DString &className, const DString &memName)
static void writeRecordUnit(DString &largs, DString &ltype, OutputList &ol, MemberDefMutable *mdef)
static bool isLibrary(const MemberDef *mdef)
static ClassDef * findVhdlClass(const DString &className)
static bool isUnit(const MemberDef *mdef)
static void addBaseClass(ClassDef *cd, ClassDef *ent)
static void writeProcedureProto(OutputList &ol, const ArgumentList &al, const MemberDef *)
static DString convertArgumentListToString(const ArgumentList &al, bool f)
static DString convertFileNameToClassName(const DString &name)
static bool isMisc(const MemberDef *mdef)
static bool isConfig(const MemberDef *mdef)
static void writeRecUnitDocu(const MemberDef *md, OutputList &ol, DString largs)
static void resetCodeVhdlParserState()
static void writeVhdlLink(const ClassDef *cdd, OutputList &ol, DString &type, DString &name, DString &beh)
static bool isEntity(const MemberDef *mdef)
static void writeInlineClassLink(const ClassDef *, OutputList &ol)
static bool deleteCharRev(DString &s, char c)
static bool isNumber(const std::string &s)
static DString getIndexWord(const DString &, int index)
static bool isPort(const MemberDef *mdef)
static void writeSource(const MemberDef *mdef, OutputList &ol, const DString &cname)
static void writeTagFile(MemberDefMutable *mdef, TextStream &tagFile)
static void setFlowMember(const MemberDef *flowMember)
static bool isFile(const MemberDef *mdef)
static bool isSignals(const MemberDef *mdef)
static DString getClassName(const ClassDef *)
static bool isVariable(const MemberDef *mdef)
static bool isVhdlFunction(const MemberDef *mdef)
static bool isVType(const MemberDef *mdef)
static ClassDef * getPackageName(const DString &name)
static void parseUCF(const DString &input, Entry *entity, const DString &f, bool vendor)
static void formatString(const DString &, OutputList &ol, const MemberDef *)
static void init()
static void writeVHDLDeclaration(MemberDefMutable *mdef, OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, bool inGroup)
static void writeFunctionProto(OutputList &ol, const ArgumentList &al, const MemberDef *)
static DString parseForBinding(DString &entity, DString &arch)
static DString getProcessNumber()
static DString getRecordNumber()
static void writeVhdlDeclarations(const MemberList *, OutputList &, const GroupDef *, const ClassDef *, const FileDef *, const NamespaceDef *, const ModuleDef *)
static const ClassDef * findArchitecture(const ClassDef *cd)
static VhdlClasses convert(Protection prot)
Definition vhdldocgen.h:80
static DString parseForConfig(DString &entity, DString &arch)
static bool isSubType(const MemberDef *mdef)
static bool isPackageBody(const MemberDef *mdef)
static void computeVhdlComponentRelations()
static bool isCompInst(const MemberDef *mdef)
static bool isRecord(const MemberDef *mdef)
static void writeFormatString(const DString &, OutputList &ol, const MemberDef *)
static bool isSubClass(ClassDef *cd, ClassDef *scd, bool followInstances, int level)
static bool isPackage(const MemberDef *mdef)
static const MemberDef * findMemberDef(ClassDef *cd, const DString &key, MemberListType type)
This function returns the entity|package in which the key (type) is found.
static void findAllArchitectures(std::vector< DString > &ql, const ClassDef *cd)
static bool isComponent(const MemberDef *mdef)
static bool isConstraint(const MemberDef *mdef)
static bool writeClassType(const ClassDef *, OutputList &ol, DString &cname)
static bool isGeneric(const MemberDef *mdef)
static ClassDef * getClass(const DString &name)
static bool isProcedure(const MemberDef *mdef)
static bool writeFuncProcDocu(const MemberDef *mdef, OutputList &ol, const ArgumentList &al, bool type=false)
static bool isAlias(const MemberDef *mdef)
static void writePlainVHDLDeclarations(const MemberList *ml, OutputList &ol, const ClassDef *cd, const NamespaceDef *nd, const FileDef *fd, const GroupDef *gd, const ModuleDef *mod, VhdlSpecifier specifier)
ClassDefMutable * toClassDefMutable(Definition *d)
ClassDef * toClassDef(Definition *d)
std::vector< BaseClassDef > BaseClassList
Definition classdef.h:81
Class representing a regular expression.
Definition regex.h:39
Class to iterate through matches.
Definition regex.h:239
Interface for the comment block scanner.
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
std::set< std::string > StringSet
Definition containers.h:31
std::vector< std::string > StringVector
Definition containers.h:33
bool readCodeFragment(const DString &fileName, bool isMacro, int &startLine, int &endLine, DString &result)
Reads a fragment from file fileName starting with line startLine and ending with line endLine.
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:170
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:175
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:481
int dstricmp(const char *s1, const char *s2)
Definition dstring.cpp:440
uint32_t dstrlen(const char *str)
Returns the length of string str, or 0 if a null pointer is passed.
Definition dstring.h:44
const char * qPrint(const char *s)
Definition dstring.h:788
#define ASSERT(x)
Definition dstring.h:29
Translator * theTranslator
Definition language.cpp:71
std::unique_ptr< MemberDef > createMemberDef(const DString &defFileName, int defLine, size_t defColumn, const DString &type, const DString &name, const DString &args, const DString &excp, Protection prot, Specifier virt, bool stat, Relationship related, MemberType t, const ArgumentList &tal, const ArgumentList &al, const DString &metaData)
Factory method to create a new instance of a MemberDef.
MemberDefMutable * toMemberDefMutable(Definition *d)
#define err(fmt,...)
Definition message.h:127
int system(const DString &command, const DString &args, bool commandHasConsole=true)
Definition portable.cpp:105
std::ofstream openOutputStream(const DString &name, bool append=false)
Definition portable.cpp:665
Namespace for the regular expression functions.
Definition regex.cpp:31
std::string replace(std::string_view str, const Ex &re, std::string_view replacement)
Searching in a given input string for parts that match regular expression re and replaces those parts...
Definition regex.cpp:869
bool match(std::string_view str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition regex.cpp:858
Portable versions of functions that are platform dependent.
Web server based search engine.
size_t findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns std::string::npos if the string could not ...
Definition stringutil.h:167
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition stringutil.h:117
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
Definition stringutil.h:75
const char * varNode
const char * yesNodeLink
const char * textNode
const char * textNodeLink
const char * noNodeLink
const char * decisionNode
const char * startEndNode
const char * comment
This class contains the information about the argument of a function or template.
Definition arguments.h:27
Options to configure the code parser.
Definition parserintf.h:78
CodeParserOptions & setStartLine(int lineNr)
Definition parserintf.h:101
CodeParserOptions & setInlineFragment(bool enable)
Definition parserintf.h:107
CodeParserOptions & setEndLine(int lineNr)
Definition parserintf.h:104
CodeParserOptions & setMemberDef(const MemberDef *md)
Definition parserintf.h:110
Helper class to pass options when calling OutputList::generateDoc().
Definition docoptions.h:24
This struct is used to capture the tag file information for an Entry.
Definition entry.h:104
DString tagName
Definition entry.h:105
DString anchor
Definition entry.h:107
DString fileName
Definition entry.h:106
VhdlSpecifier
Definition types.h:770
@ INSTANTIATION
Definition types.h:791
@ MISCELLANEOUS
Definition types.h:797
@ SHAREDVARIABLE
Definition types.h:794
DString convertToId(const DString &s)
Definition util.cpp:3204
void addHtmlExtensionIfMissing(DString &fName)
Definition util.cpp:3933
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
Definition util.cpp:3234
A bunch of utility functions.
static DString splitString(DString &str, char c)
static std::vector< ClassDef * > g_classList
static void alignText(DString &q)
static const MemberDef * findMemFlow(const MemberDef *mdef)
static void writeUCFLink(const MemberDef *mdef, OutputList &ol)
#define FLOWLEN
#define IFF
#define EMPTY
static void startFonts(const DString &q, const char *keyword, OutputList &ol)
static const std::unordered_set< std::string > g_vhdlKeyWordSet0
static std::vector< const MemberDef * > mdList
static int nodeCounter
static std::map< std::string, const MemberDef * > g_varMap
static std::map< ClassDef *, std::vector< ClassDef * > > g_packages
#define ENDCL
static const MemberDef * flowMember
static int recordCounter
std::vector< FlowChart > flowList
#define theTranslator_vhdlType
static void writeLink(const MemberDef *mdef, OutputList &ol)
static struct @262143045100337216022015277174266365223104043217 flowCol
#define EMPTNODE
#define LOOP
static int compareString(const DString &s1, const DString &s2)
static bool membersHaveSpecificType(const MemberList *ml, VhdlSpecifier type)
static const std::unordered_set< std::string > g_vhdlKeyWordSet2
#define DECLN
static int ifcounter
static VhdlSpecifier getSpecifierTypeFromClass(const ClassDef *cd)
static void addInstance(ClassDefMutable *entity, ClassDefMutable *arch, ClassDefMutable *inst, const std::shared_ptr< Entry > &cur)
static void initUCF(Entry *root, const DString &type, DString &qcs, int line, const DString &fileName, DString &brief)
#define STARTFIN
static const std::unordered_set< std::string > g_vhdlKeyWordSet3
#define EEND
static std::recursive_mutex g_vhdlMutex
#define EXITNEXT
static const std::unordered_set< std::string > g_vhdlKeyWordSet1
#define STARTL
std::vector< FlowChart > flowList
const EntryList & getVhdlInstList()