Fix for UBSan build
[platform/upstream/doxygen.git] / src / vhdlcode.l
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2012 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby 
7  * granted. No representations are made about the suitability of this software 
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 /******************************************************************************
16  * Parser for syntax hightlighting and references for vhdl subset
17  * written by M. Kreis
18  * supports VHDL-87
19  * does not support VHDL-AMS 
20  ******************************************************************************/
21
22 %{
23
24 /*
25  *        includes
26  */
27 #include <stdio.h>
28 #include <assert.h>
29 #include <ctype.h>
30 #include <qregexp.h>
31 #include <qdir.h>
32 #include <qstringlist.h>
33
34 #include "qtbc.h"
35 #include "entry.h"
36 #include "doxygen.h"
37 #include "message.h"
38 #include "outputlist.h"
39 #include "util.h"
40 #include "membername.h"
41 #include "searchindex.h"
42 #include "vhdldocgen.h"
43 #include "arguments.h"
44
45 #define YY_NEVER_INTERACTIVE 1
46 #define YY_NO_INPUT 1
47   
48 // Toggle for some debugging info
49 //#define DBG_CTX(x) fprintf x
50 #define DBG_CTX(x) do { } while(0)
51   
52
53 /* -----------------------------------------------------------------
54  *        statics
55  */
56
57 // ----------------- <vhdl> ----------------------------------
58
59 //static bool isPackBody=FALSE;
60 //static bool isStartMap;
61 static bool isFuncProto=FALSE;
62 static bool isComponent=FALSE;
63 static bool isPackageBody=FALSE;
64 static bool isProto = FALSE;
65
66 static QCString   g_PrevString;
67 static QCString   g_CurrClass;
68 static QDict<QCString>g_vhdlKeyDict;   
69 static QCString   g_tempClass;
70 static QCString   g_tempComp;
71 static QCString   g_PortMapComp;
72 static MemberDef *g_vhdlMember;
73 static QCString   g_FuncProto;
74
75 //-----------------------------------------------------------
76   
77 static CodeOutputInterface * g_code;
78 static QCString      g_curClassName;
79 static QCString      g_parmType;
80 static QCString      g_parmName;
81 static const char *  g_inputString;     //!< the code fragment as text
82 static int           g_inputPosition;   //!< read offset during parsing 
83 static int           g_inputLines;      //!< number of line in the code fragment
84 static int           g_yyLineNr;        //!< current line number
85 static bool          g_needsTermination;
86 static Definition   *g_searchCtx;
87
88 static QCString      g_exampleName;
89 static QCString      g_exampleFile;
90
91 static QCString      g_type;
92 static QCString      g_name;
93 static QCString      g_args;
94 static QCString      g_classScope;
95    
96 static QCString      g_CurrScope;
97    
98 static FileDef *     g_sourceFileDef;
99 static Definition *  g_currentDefinition;
100 static MemberDef *   g_currentMemberDef;
101 static bool          g_includeCodeFragment;
102 static const char *  g_currentFontClass;
103
104 static bool          g_lexInit = FALSE;
105 static int           g_braceCount=0;
106
107
108 static void writeFont(const char *s,const char* text);
109 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
110 static bool writeColoredWord(QCString& word );
111 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE);
112 static void endFontClass();
113 static void startFontClass(const char *s);
114 //-------------------------------------------------------------------
115
116
117 static void setCurrentDoc(const QCString &anchor)
118 {
119   if (Doxygen::searchIndex)
120   {
121     if (g_searchCtx)
122     {
123       Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
124     }
125     else
126     {
127       Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
128     }
129   }
130 }
131
132 static bool checkVhdlString(QCString &name)
133 {
134   if (name.isEmpty()) return FALSE;
135   static QRegExp regg("[\\s\"]");
136
137   int len=name.length();
138   if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
139   {
140     QStringList qrl=QStringList::split(regg,name,FALSE);
141     if (VhdlDocGen::isNumber(qrl[0].utf8()))
142     {
143       g_code->codify("\""); 
144       startFontClass("vhdllogic");
145       QCString mid=name.mid(1,len-2); //" 1223 "
146       g_code->codify(mid.data());
147       endFontClass();
148       g_code->codify("\""); 
149     }
150     else
151     {
152       startFontClass("keyword");
153       g_code->codify(name.data());
154       endFontClass();
155     }
156     return TRUE;
157   }
158
159   if (VhdlDocGen::isNumber(name))
160   {
161     startFontClass("vhdllogic");
162     g_code->codify(name.data());
163     endFontClass();
164     return TRUE;
165   }
166   return FALSE;
167 }
168
169 static void addToSearchIndex(const char *text)
170 {
171   if (Doxygen::searchIndex)
172   {
173     Doxygen::searchIndex->addWord(text,FALSE);
174   }
175 }
176
177
178 /*! start a new line of code, inserting a line number if g_sourceFileDef
179  * is TRUE. If a definition starts at the current line, then the line
180  * number is linked to the documentation of that definition.
181  */
182 static void startCodeLine()
183 {
184   //if (g_currentFontClass) { g_code->endFontClass(); }
185   if (g_sourceFileDef)
186   {
187     //QCString lineNumber,lineAnchor;
188     //lineNumber.sprintf("%05d",g_yyLineNr);
189     //lineAnchor.sprintf("l%05d",g_yyLineNr);
190     //  if ((g_yyLineNr % 500) == 0) 
191     //         fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
192     Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
193     //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
194     if (!g_includeCodeFragment && d)
195     {
196       g_currentDefinition = d;
197       g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
198       if (!g_tempComp.isEmpty() && g_currentMemberDef )
199       {
200         //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
201         QCString nn=g_currentMemberDef->name();
202         MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
203         if (mdeff)
204         {
205           g_currentMemberDef=mdeff;
206         }
207       }
208
209       g_parmType.resize(0);
210       g_parmName.resize(0);
211       QCString lineAnchor;
212       lineAnchor.sprintf("l%05d",g_yyLineNr);
213       if (g_currentMemberDef)
214       {
215         g_code->writeLineNumber(g_currentMemberDef->getReference(),
216                                 g_currentMemberDef->getOutputFileBase(),
217                                 g_currentMemberDef->anchor(),g_yyLineNr);
218         setCurrentDoc(lineAnchor);
219       }
220       else if (d->isLinkableInProject())
221       {
222         g_code->writeLineNumber(d->getReference(),
223                                 d->getOutputFileBase(),
224                                 0,g_yyLineNr);
225         setCurrentDoc(lineAnchor);
226       }
227     }
228     else
229     {
230       g_code->writeLineNumber(0,0,0,g_yyLineNr);
231     }
232   }
233   g_code->startCodeLine(g_sourceFileDef); 
234   if (g_currentFontClass)
235   {
236     g_code->startFontClass(g_currentFontClass);
237   }
238 }
239
240 static void endFontClass();
241 static void endCodeLine()
242 {
243   endFontClass();
244   g_code->endCodeLine();
245 }
246
247 static void nextCodeLine()
248 {
249   const char *fc = g_currentFontClass;
250   endCodeLine();
251   if (g_yyLineNr<g_inputLines) 
252   {
253     g_currentFontClass = fc;
254     startCodeLine();
255   }
256 }
257
258 /*! writes a word to the output.
259  *  If curr_class is defined, the word belongs to a class
260  *  and will be linked.
261  */
262
263 static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
264 {
265   bool found=FALSE;
266   QCString temp; 
267   QCString tclass(curr_class);
268   QCString ttt(word);
269   if (ttt.isEmpty()) return;
270   for (unsigned int j=0;j<ttt.length();j++)
271   {
272     char c=ttt.at(j);
273     if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
274     {
275       if (found)
276       {
277         if (!writeColoredWord(temp)) // is it a keyword ?
278         {
279           //if (VhdlDocGen::findKeyWord(temp))
280           // writeFont("vhdlkeyword",temp.data());
281           //printf("writeWord: %s\n",temp.data());
282           if (!tclass.isEmpty())
283           {
284             if (!classLink)
285             {
286               generateMemLink(*g_code,tclass,temp);
287             }
288             else
289             {
290               generateClassOrGlobalLink(*g_code,temp);
291             }
292           }
293           else                                                                          
294           {
295           if (!checkVhdlString(temp))
296             g_code->codify(temp.data());
297           }
298         }
299         temp.resize(0);
300         found=FALSE;
301       }
302
303       char cc[2];
304       cc[0]=c;
305       cc[1]=0;
306       g_code->codify(cc);
307     }
308     else
309     {
310       found=TRUE;
311       temp+=c;
312     }
313   } // for
314
315   if (!temp.isEmpty())
316   {
317     if (!writeColoredWord(temp))
318     {
319       if (!tclass.isEmpty())
320       {
321         if (!classLink)
322         {
323           generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left); 
324         }
325         else
326         {
327           generateClassOrGlobalLink(*g_code,temp);
328         }
329       }
330       else                 
331       {
332          QCString qc(temp.data());
333          if (VhdlDocGen::isNumber(qc)){
334                          startFontClass("vhdllogic");
335                          g_code->codify(temp.data());
336                          endFontClass();
337                               }
338          else     
339         g_code->codify(temp.data());
340       }
341     }
342   }
343 }// writeWord
344
345
346 /*! write a code fragment `text' that may span multiple lines, inserting
347  * line numbers for each line.
348  */
349 static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE)
350 {
351   if (text==0) return;
352   //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
353   const char *p=text,*sp=p;
354   char c;
355   bool done=FALSE;
356   while (!done)
357   {
358     sp=p;
359     while ((c=*p++) && c!='\n') {}
360     if (c=='\n')
361     {
362       g_yyLineNr++;
363       QCString line = sp;
364       line = line.left(p-sp-1);
365       //*(p-1)='\0';
366       //g_code->codify(sp);
367       writeWord(line,cl,classlink);
368       nextCodeLine();
369     }
370     else
371     {
372       //g_code->codify(sp);
373       writeWord(sp,cl,classlink);
374       done=TRUE;
375     }
376   }
377 }
378
379 /*! writes a link to a fragment \a text that may span multiple lines, inserting
380  * line numbers for each line. If \a text contains newlines, the link will be 
381  * split into multiple links with the same destination, one for each line.
382  */
383 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
384                   const char *ref,const char *file,
385                   const char *anchor,const char *text,
386                   const char *tooltip)
387 {
388   bool done=FALSE;
389   char *p=(char *)text;
390   while (!done)
391   {
392     char *sp=p;
393     char c;
394     while ((c=*p++) && c!='\n') {}
395     if (c=='\n')
396     {
397       g_yyLineNr++;
398       *(p-1)='\0';
399       // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
400       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
401       nextCodeLine();
402     }
403     else
404     {
405       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
406       done=TRUE;
407     }
408   }
409 }
410
411 static void setParameterList(MemberDef *md)
412 {
413   g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
414   LockingPtr<ArgumentList> al = md->argumentList();
415   if (al==0) return; 
416   Argument *a = al->first();
417   while (a)
418   {
419     g_parmName = a->name.copy();
420     g_parmType = a->type.copy();
421     int i = g_parmType.find('*');
422     if (i!=-1) g_parmType = g_parmType.left(i);
423     i = g_parmType.find('&');
424     if (i!=-1) g_parmType = g_parmType.left(i);
425     g_parmType.stripPrefix("const ");
426     g_parmType=g_parmType.stripWhiteSpace();
427    // g_theVarContext.addVariable(g_parmType,g_parmName);
428     a = al->next();
429   }
430 }
431
432
433 /*! writes a link to a function or procedure
434  */
435
436 static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
437 {
438
439   //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
440   QCString memberName=mdef->name();
441
442   if (mdef && mdef->isLinkable()) // is it a linkable class
443   {
444     writeMultiLineCodeLink(ol,mdef->getReference(),
445                               mdef->getOutputFileBase(),
446                               mdef->anchor(),
447                               mdef->name(),
448                               mdef->briefDescriptionAsTooltip());
449     addToSearchIndex(memberName);
450     return;
451   }
452   ol.linkableSymbol(g_yyLineNr,memberName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
453   codifyLines(memberName.data());
454   addToSearchIndex(memberName);
455 } // generateFuncLink
456
457
458 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
459 {
460   if (memberName.isEmpty()) return; 
461   if (clName.isEmpty())
462   {
463     codifyLines(memberName.data());
464
465    return;
466   }
467   
468   QCString className=clName;
469
470   MemberDef *md=0;
471   //MemberDef *comp=0;
472   //bool isLocal=FALSE;
473
474   md=VhdlDocGen::findMember(className,memberName);
475   ClassDef *po=VhdlDocGen::getClass(className.data());
476
477   if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS) 
478   {
479     QCString temp=className;//.stripPrefix("_");
480     temp.stripPrefix("_");
481     md=VhdlDocGen::findMember(temp,memberName);
482   }
483
484   if (md && md->isLinkable()) // is it a linkable class
485   {
486     writeMultiLineCodeLink(ol,md->getReference(),
487                               md->getOutputFileBase(),
488                               md->anchor(),
489                               memberName,
490                               md->briefDescriptionAsTooltip());
491     addToSearchIndex(memberName);
492     return;
493   }
494   // nothing found, just write out the word
495   ol.linkableSymbol(g_yyLineNr,memberName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
496   codifyLines(memberName.data());
497   addToSearchIndex(memberName);
498 }// generateMemLink
499
500
501 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/)
502 {
503   QCString className=clName;
504
505   if (className.isEmpty()) return;
506
507   ClassDef *cd=0;
508   //MemberDef *md=0;
509   //bool isLocal=FALSE;
510   className.stripPrefix("_");
511   cd = getClass(className.data()); 
512   while (cd)
513   {
514     //className.stripPrefix("_");
515     QCString temp(clName);
516     temp.stripPrefix("_");
517     if (cd && cd->isLinkable()) // is it a linkable class
518     {
519       //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
520       //{
521       //  temp=VhdlDocGen::getClassName(cd);
522       //}
523       ol.linkableSymbol(g_yyLineNr,temp,cd,
524                         g_currentMemberDef ? 
525                         g_currentMemberDef : 
526                         g_currentDefinition);
527       writeMultiLineCodeLink(ol,cd->getReference(),
528                                 cd->getOutputFileBase(),
529                                 cd->anchor(),
530                                 temp,
531                                 cd->briefDescriptionAsTooltip());
532       addToSearchIndex(className);
533       return;
534     }
535     Definition *d = cd->getOuterScope();
536     if (d && d->definitionType()==Definition::TypeClass)
537     {
538       cd = (ClassDef*)d;
539     }
540     else
541     {
542       cd = 0;
543     }
544   }
545
546   // nothing found, just write out the word
547   ol.linkableSymbol(g_yyLineNr,clName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
548   codifyLines(clName);
549   addToSearchIndex(clName);
550 }// generateClasss or global link
551
552
553 /*! counts the number of lines in the input */
554 static int countLines()
555 {
556   const char *p=g_inputString;
557   char c;
558   int count=1;
559   while ((c=*p)) 
560   { 
561     p++ ; 
562     if (c=='\n') count++;  
563   }
564   if (p>g_inputString && *(p-1)!='\n') 
565   { // last line does not end with a \n, so we add an extra
566     // line and explicitly terminate the line after parsing.
567     count++, 
568     g_needsTermination=TRUE; 
569   } 
570   return count;
571 }
572
573 static void endFontClass()
574 {
575   if (g_currentFontClass)
576   {
577     g_code->endFontClass();
578     g_currentFontClass=0;
579   }
580 }
581
582 static void startFontClass(const char *s)
583 {
584   if (s==0) return;
585   endFontClass();
586   g_code->startFontClass(s);
587   g_currentFontClass=s;
588 }
589
590 static void writeFont(const char *s,const char* text)
591 {
592   if (s==0 || text==0) return;
593   //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
594   g_code->startFontClass(s);
595   g_code->codify(text);
596   g_code->endFontClass();
597 }
598
599 //----------------------------------------------------------------------------
600
601 static void appStringLower(QCString& qcs,const char* text)
602 {
603   qcs.resize(0);
604   qcs.append(text);
605   //qcs=qcs.lower();
606   qcs=qcs.stripWhiteSpace();
607 }
608
609 //static void appString(QCString& qcs,const char* text)
610 //{
611 //  qcs.resize(0);
612 //  qcs.append(text);
613 //}
614
615 static QCString g_temp;
616
617 /* writes and links a port map statement */
618 static void codifyMapLines(char *text)
619 {
620   if (text==0) return;
621   g_temp.resize(0);       
622   //bool dot=FALSE;
623   int wordCounter=0;
624   QCString ctemp;
625   //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
626   char *p=text; //,*sp=p;
627   char c;
628   bool done=FALSE;
629   while (!done)
630   {
631     //sp=p;
632     while ((c=*p++) &&  c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
633     { 
634       if (c!=0x9)
635         g_temp+=c; 
636     }
637     if (c=='\0') return;
638     if (!g_temp.isEmpty()) wordCounter++;
639
640     if (!g_temp.isEmpty())
641     {
642       // different kinds of component instantiations
643       // xxx:yyy (generic/port) map(
644       // xxx:(entity/component/configuration) yyy (generic/port) map(
645       // xxx: entity yyy(zzz) (generic/port) map(
646       if (wordCounter==2 || wordCounter==3)
647       {
648         QCString q=g_temp.lower(); // consider (upper/lower) cases
649         if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
650         {
651           generateMemLink(*g_code,g_CurrClass,g_temp); 
652         }
653         else
654         {
655           g_PortMapComp=g_temp;
656           generateClassOrGlobalLink(*g_code,g_temp);
657         }
658       }
659       else 
660       {
661         generateMemLink(*g_code,g_CurrClass,g_temp); 
662       }
663     }
664     ctemp.fill(c,1);
665     codifyLines(ctemp.data()); 
666     ctemp.resize(0);
667     g_temp.resize(0); 
668   }//while
669 }//codifymaplines
670
671 /*
672 * writes a function|procedure prototype  and links the function|procedure name 
673 */
674
675 static void writeFuncProto()
676 {
677   QList<Argument> ql;
678   QCString name,ret;
679   VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
680
681   if (name.isEmpty())
682   {
683     codifyLines(g_FuncProto.data(),g_CurrClass.data());
684     return;
685   }
686   QStringList qlist=QStringList::split(name,g_FuncProto,FALSE);
687   QCString temp=qlist[0].utf8();
688   codifyLines(temp.data(),g_CurrClass.data());
689   g_FuncProto.stripPrefix(temp.data());
690   temp.resize(0);
691   temp=g_CurrClass;
692   if (isPackageBody) 
693   {
694     temp.stripPrefix("_");// _{package body name}
695   }
696   MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
697
698   if (mdef)
699   {
700     generateFuncLink(*g_code,mdef);
701     g_FuncProto.stripPrefix(name.data());
702     codifyLines(g_FuncProto.data(),g_CurrClass.data());
703   }
704   else
705   {
706     codifyLines(g_FuncProto.data(),g_CurrClass.data());
707   }
708 }// writeFuncProto
709
710 /* writes a process prototype to the ouput */
711
712  static void writeProcessProto(){
713  codifyLines(g_FuncProto.data(),g_CurrClass.data());
714  g_vhdlKeyDict.clear();
715 }// writeProcessProto
716
717 /* writes a keyword */
718
719 static bool writeColoredWord(QCString& word )
720 {
721   QCString qcs=word.lower();
722   QCString *ss=VhdlDocGen::findKeyWord(qcs);
723   if (ss) 
724   {
725     writeFont(ss->data(),word.data());
726     return TRUE;
727   }
728   return FALSE;
729 }
730
731 #undef        YY_INPUT
732 #define       YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
733
734 static int yyread(char *buf,int max_size)
735 {
736   int c=0;
737   while( c < max_size && g_inputString[g_inputPosition] )
738   {
739     *buf = g_inputString[g_inputPosition++] ;
740     c++; buf++;
741   }
742   return c;
743 }
744
745 %}
746
747
748 B             [ \t]
749 BN            [ \t\n\r]
750 STRING      ["][^"\n]*["]
751 NAME          [a-z_A-Z][ a-z_A-Z0-9]*
752 FUNCNAME      [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
753 ID            "$"?[a-z_A-Z][a-z_A-Z0-9]*
754 SPECSIGN      [:;, +*&\/=<>'\t]*
755 DIGITSS       [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
756 ALLTYPESMAP   {B}*[_a-zA-Z0-9. ]+{BN}*
757 ALLTYPESMAP1  {BN}*[_a-zA-Z0-9.() ]+{BN}*
758
759 ARCHITECTURE  ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}
760 PROCESS       ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
761
762 END1          {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
763 END2          [^a-zA-Z_]("end"){BN}*[;]
764 END3          {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
765 END4          {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
766 ENDEFUNC      {END3}|{END4}|{END2}
767
768 KEYWORD       ("new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
769 TYPEKW        ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
770 FUNC          ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
771
772 ARITHOP       "+"|"-"|"/"|"*"|"%"|"/="|":="
773 ASSIGNOP      "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
774 LOGICOP       "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
775 BITOP         "&"|"|"|"^"|"<<"|">>"|"~"
776 OPERATOR      {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
777
778 PORT          {B}*("port"){BN}*("(")
779 GENERIC       {B}*("generic"){BN}*("(")
780
781 BRACEOPEN     [(]{1}
782 BRACECLOSE    [)]{1}
783
784 TEXTT         {B}*"--"[^\n]*
785
786 MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
787 MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
788 MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
789 MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
790
791 XILINX      "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFIG"|"CONFIG_MODE"|"COOL_CLK"|"DATA_GATE"|"DCI_VALUE"|"DISABLE"|"DRIVE"|"DROP_SPEC"|"ENABLE"|"FAST"|"FEEDBACK"|"FILE"|"FLOAT"|"FROM-THRU-TO"|"FROM-TO"|"HBLKNM"|"HU_SET"|"INREG"|"IOB"|"IOBDELAY"|"IOSTANDARD"|"KEEP"|"KEEPER"|"LOC"|"LOCATE"|"LOCK_PINS"|"MAP"|"MAXDELAY"|"MAXPT"|"MAXSKEW"|"NODELAY"|"NOREDUCE"|"OFFSET"|"OPEN_DRAIN"|"OPT_EFFORT"|"OPTIMIZE"|"PERIOD"|"PIN"|"PRIORITY"|"PROHIBIT"|"PULLDOWN"|"PULLUP"|"PWR_MODE"|"REG"|"RLOC"|"RLOC_ORIGIN"|"RLOC_RANGE"|"SAVE NET"|"FLAG"|"SYSTEM_JITTER"|"TEMPERATURE"|"TIMEGRP"|"TIMESPEC"|"VOLTAGE"
792
793 %option noyywrap
794 %option nounput
795
796 %x Bases
797 %x ParseType
798 %x ParseFuncProto
799 %x ParseComponent
800 %x ParsePackage
801 %x ParseProcessProto
802 %x ClassName
803 %x PackageName
804 %x ClassVar
805 %x ClassesName
806 %x Map
807 %x Body
808         
809 %%
810
811 .                     { 
812                         BEGIN(Bases); 
813                       }
814
815 <Map>{BRACEOPEN}      {
816                         g_braceCount++;
817                         writeFont("vhdlchar",vhdlcodeYYtext);
818                         BEGIN(Map);
819                       }
820
821 <Map>[^()\n,--]*        { /* write and link a port map lines */
822                         QCString tt(vhdlcodeYYtext);
823                         VhdlDocGen::deleteAllChars(tt,',');
824                         QRegExp r("=>");
825                         QStringList ql=QStringList::split(r,tt,FALSE);
826                         if (ql.count()>=2)
827                         {
828                           unsigned int index=0;
829                           QCString t1=ql[0].utf8();
830                           char cc=t1.at(index);
831                           while (cc==' ' || cc=='\t') 
832                           {
833                             char c2[2];
834                             c2[0]=cc;
835                             c2[1]=0;
836                             g_code->codify(c2);
837                             index++;
838                             if (index>=t1.size()) break;
839                             cc=t1.at(index);
840                           }        
841
842                           QCString s1=t1;
843                           s1=s1.stripWhiteSpace();
844
845                           //         if (!g_PortMapComp.isEmpty())
846                           generateMemLink(*g_code,g_PortMapComp,s1); 
847                           while (index++<t1.size()) 
848                           { 
849                             char cc=t1.at(index);
850                             if (cc==' ' || cc=='\t')
851                             {
852                               char c2[2];
853                               c2[0]=cc;
854                               c2[1]=0;
855                               g_code->codify(c2);
856                             }
857                           }        
858                           codifyLines("=>");
859                           index=0;
860                           QCString s2=ql[1].utf8();
861                           t1=s2;
862                           cc=t1.at(index);
863                           while (cc==' ' || cc=='\t') 
864                           {
865                             char c2[2];
866                             c2[0]=cc;
867                             c2[1]=0;
868                             g_code->codify(c2);
869                             index++;
870                             if (index>=t1.size()) break;
871                             cc=t1.at(index);
872                           }        
873                           s2=s2.stripWhiteSpace();
874                             if (!checkVhdlString(s2))
875                           generateMemLink(*g_code,g_CurrClass,s2); 
876                           while (index++<t1.size()) 
877                           { 
878                             if (t1.at(index)==' ')
879                             {
880                               g_code->codify(" "); 
881                             }
882                           }        
883                         }
884                         else
885                         {
886                           codifyLines(vhdlcodeYYtext,g_CurrClass.data());
887                         }
888                         BEGIN(Map);
889                       }
890
891 <Map>"\n"|","         {
892                         codifyLines(vhdlcodeYYtext);
893                         BEGIN(Map);
894                       }
895
896 <Map>{BRACECLOSE}     {
897                         g_braceCount--;
898                         writeFont("vhdlchar",vhdlcodeYYtext);
899                         if (g_braceCount==0)
900                         {
901                           BEGIN(Bases);
902                         }
903                       }
904
905 <ParseFuncProto>{NAME} {
906                          QCString tmp(vhdlcodeYYtext);
907                          tmp=tmp.stripWhiteSpace();
908                          appStringLower(g_PrevString,vhdlcodeYYtext);
909                          g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
910                          if (!writeColoredWord(tmp))
911                          {
912                            generateMemLink(*g_code,g_CurrClass,tmp); 
913                          }
914                          BEGIN(Bases);
915                        }
916
917 <ParseType>{STRING} {
918                        QCString qcs(vhdlcodeYYtext);
919                        VhdlDocGen::deleteAllChars(qcs,'"');
920                        VhdlDocGen::deleteAllChars(qcs,' ');
921                         if (VhdlDocGen::isNumber(qcs))
922                        writeFont("vhdllogic",vhdlcodeYYtext);
923                        else
924                        writeFont("keyword",vhdlcodeYYtext);
925                 }
926
927 <ParseType>"\n"       {
928                         g_FuncProto.append(vhdlcodeYYtext);
929                         if (isProto)
930                         {
931                           codifyLines(vhdlcodeYYtext);
932                         }
933                         BEGIN(ParseType);
934                       }
935
936
937 <ParseType>{TEXTT}    {
938                         g_FuncProto.append(vhdlcodeYYtext);                
939                         if (isProto)                                                                 
940                         {
941                           writeFont("keyword",vhdlcodeYYtext);
942                         }
943                         BEGIN(ParseType); 
944                        }
945
946 <ParseType>{ENDEFUNC} {
947                         QRegExp regg("[\\s]");
948                         QCString tt(vhdlcodeYYtext);
949                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
950                         tt=tt.lower();
951                         VhdlDocGen::deleteAllChars(tt,';');
952                         tt.stripWhiteSpace();
953                         QStringList ql=QStringList::split(regg,tt,FALSE);
954                         int index=ql.findIndex(QCString("if"))+1;
955                         index+=ql.findIndex(QCString("case"))+1;
956                         index+=ql.findIndex(QCString("loop"))+1;
957                         index+=ql.findIndex(QCString("generate"))+1;                        
958                         if (index==0)
959                         {
960                           BEGIN(Bases);
961                         }
962                         else
963                         {
964                           BEGIN(ParseType);
965                         }
966                       }
967
968 <ParseType>{END1}     {
969                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
970                         g_vhdlKeyDict.clear();
971                       }
972
973 <ParseType>^{B}*("begin "|"begin") {
974                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
975                         isFuncProto=FALSE;
976                       }
977
978 <ParseType>{SPECSIGN} {
979                         g_FuncProto.append(vhdlcodeYYtext);
980                         if (isProto)
981                         {
982                           codifyLines(vhdlcodeYYtext,g_CurrClass.data());
983                         }
984                       }
985
986 <ParseType>["_a-zA-Z0-9]* {
987                         QCString val(vhdlcodeYYtext);
988                         g_FuncProto.append(vhdlcodeYYtext);
989                         appStringLower(g_PrevString,vhdlcodeYYtext);
990                                                         
991                         if (isFuncProto && g_braceCount==0)
992                         {
993                           g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
994                         }
995                                 
996                         if (isProto) 
997                         { 
998                           if (!writeColoredWord(val))
999                           {
1000                             if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
1001                             {
1002                               val=val.stripWhiteSpace();
1003                               if (VhdlDocGen::isNumber(val))
1004                               {
1005                                 startFontClass("vhdllogic");
1006                                 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1007                                 endFontClass();
1008                               }
1009                              else
1010                               generateMemLink(*g_code,g_CurrClass,val); 
1011                             }
1012                             else
1013                             {
1014                               codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1015                             }
1016                           }
1017                         }
1018                         BEGIN(ParseType); 
1019                       }
1020
1021 <ParseType>{BRACEOPEN} {
1022                         g_braceCount++;
1023                         g_FuncProto+='(';
1024                         if (isProto)
1025                         {
1026                           writeFont("vhdlchar",vhdlcodeYYtext);
1027                         }
1028                         BEGIN(ParseType);
1029                       }
1030
1031 <ParseType>{BRACECLOSE} {
1032                         g_braceCount--;
1033                         g_FuncProto+=')';
1034                         if (isProto)
1035                         {
1036                           writeFont("vhdlchar",vhdlcodeYYtext);
1037                         }
1038                         if (g_braceCount==0 && !isProto)// && !isPackageBody)
1039                         {
1040                           isProto=TRUE;
1041                           appStringLower(g_PrevString,vhdlcodeYYtext);
1042                           writeFuncProto();
1043                           BEGIN(Bases);
1044                         }
1045                         if (isPackageBody)
1046                         {
1047                           BEGIN(ParseType);
1048                         }
1049                       }
1050
1051
1052 <ClassesName>{FUNCNAME} {
1053                          QDict<QCString> mem;
1054                          appStringLower(g_PrevString,vhdlcodeYYtext);
1055                          g_CurrClass.resize(0);
1056                          g_CurrClass.append(vhdlcodeYYtext);
1057                          g_CurrClass=g_CurrClass.stripWhiteSpace();
1058                                                   
1059                          if (!writeColoredWord(g_CurrScope))
1060                          {
1061                            generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
1062                          }
1063                          else
1064                          {
1065                            codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1066                          }
1067                          BEGIN(Bases);
1068                        }
1069
1070
1071 <ParseComponent>{BRACEOPEN} {
1072                          g_braceCount++;
1073                          g_code->codify(vhdlcodeYYtext);
1074                        }
1075
1076
1077 <ParseComponent>{BRACECLOSE} {
1078                          g_braceCount--;
1079                          g_code->codify(vhdlcodeYYtext);  
1080                          if (g_braceCount==0 && !isComponent)
1081                          {
1082                            g_tempComp.resize(0);
1083                            BEGIN(Bases);
1084                          }
1085                          else
1086                          {
1087                            BEGIN(ParseComponent);
1088                          }
1089                        }
1090
1091 <ParseComponent>{B}*"-" {    
1092                          if (strlen(vhdlcodeYYtext)>=2) // found text ?
1093                          {
1094                            writeFont("keyword",vhdlcodeYYtext);
1095                          }
1096                          else
1097                          {
1098                            writeFont("vhdlchar",vhdlcodeYYtext); 
1099                          }
1100                        }
1101
1102 <ParseComponent>{SPECSIGN} {
1103                          codifyLines(vhdlcodeYYtext);
1104                        }
1105
1106
1107
1108 <ParseComponent>"\n"|" " {
1109                            codifyLines(vhdlcodeYYtext);
1110                          }
1111
1112 <ParseComponent>{DIGITSS} { 
1113                          startFontClass("vhdllogic");
1114                          codifyLines(vhdlcodeYYtext);
1115                          endFontClass();
1116                        }
1117
1118 <ParseComponent>{PORT} { 
1119                          codifyLines(vhdlcodeYYtext);
1120                          g_braceCount=1;
1121                          isComponent=FALSE;
1122                        }
1123
1124 <ParseComponent>{GENERIC} { 
1125                          codifyLines(vhdlcodeYYtext);
1126                          g_braceCount=1;
1127                        }
1128
1129 <ParseComponent>[_a-zA_Z][_a-zA-Z0-9]*  {
1130                          QCString temp(vhdlcodeYYtext);
1131                          appStringLower(g_PrevString,vhdlcodeYYtext);
1132                          if (!checkVhdlString(temp)){
1133                          if (!writeColoredWord(g_PrevString))
1134                          {
1135                            generateMemLink(*g_code,g_tempComp,temp); 
1136                          }
1137                        }
1138                        }
1139
1140 <ParseComponent>{STRING} { 
1141                             QCString temp(vhdlcodeYYtext);
1142                         if (!checkVhdlString(temp))
1143                          codifyLines(vhdlcodeYYtext);
1144                         }
1145
1146
1147 <ParseProcessProto>[^()]* { 
1148                          g_FuncProto.append(vhdlcodeYYtext);
1149                        }
1150
1151
1152
1153 <ParseProcessProto>{BRACEOPEN} {
1154                          g_FuncProto.append(vhdlcodeYYtext);
1155                          g_braceCount++;
1156                        }
1157
1158 <ParseProcessProto>{BRACECLOSE} {
1159                          g_FuncProto.append(vhdlcodeYYtext);
1160                          g_braceCount--;
1161                          if (g_braceCount==0) 
1162                          {
1163                             writeProcessProto();
1164                             BEGIN(Bases);
1165                           }
1166                         }
1167
1168 <ParsePackage>[^:;]*    { //found package 
1169                           QCString temp(vhdlcodeYYtext);
1170                           QStringList strl=QStringList::split(".",temp,FALSE);
1171                                 
1172                           if (strl.count()>2) 
1173                           {
1174                              QCString s1=strl[0].utf8();  
1175                              QCString s2=strl[1].utf8();  
1176                              QCString s3=strl[2].utf8();  
1177                              s1.append(".");
1178                              s3.prepend(".");
1179                              codifyLines(s1.data(),g_CurrClass.data());  
1180                              ClassDef *cd=VhdlDocGen::getPackageName(s2);
1181                              if (cd)
1182                              {
1183                                generateClassOrGlobalLink(*g_code,s2.data());
1184                              }
1185                              else 
1186                              {
1187                                codifyLines(s2.data());
1188                              }
1189                              codifyLines(s3.data());
1190                            }
1191                            else
1192                            {
1193                              writeFont("keywordflow",vhdlcodeYYtext);
1194                            }
1195                            BEGIN(Bases);
1196                          }
1197
1198 <Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4}  { // found port or generic map
1199                            QCString tt(vhdlcodeYYtext);
1200              /*
1201                            if (tt.contains(':',FALSE))
1202                            {
1203                              isStartMap=TRUE;
1204                            }
1205                            else
1206                            {
1207                              isStartMap=FALSE;                                        
1208                            }
1209                            */
1210                            int j=tt.find('.');
1211                                                     
1212                            if (j>0)
1213                            {
1214                              QCString left=tt.left(j+1); 
1215                              codifyLines(left.data());
1216                              tt=tt.right(tt.length()-j-1);
1217                              left=VhdlDocGen::getIndexWord(tt.data(),0);
1218                              if (!left.isEmpty())
1219                              {          
1220                                if (left.contains('('))
1221                                {
1222                                  j=left.find('(',FALSE);
1223                                  QCString name=left.left(j);
1224                                  generateClassOrGlobalLink(*g_code,name.data()); 
1225                                  g_PortMapComp=name;
1226                                  name=tt.right(tt.length()-name.length());
1227                                  codifyLines(name.data());
1228                                }
1229                                else
1230                                {
1231                                  generateClassOrGlobalLink(*g_code,left.data()); 
1232                                  tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
1233                                  
1234                                  g_PortMapComp=left;
1235                                  codifyLines(tt.data());
1236                                }
1237                              }
1238                            }
1239                            else
1240                            {
1241                            if (tt.contains(':',FALSE)) 
1242                              codifyMapLines(tt.data());
1243                               else
1244                              codifyLines(tt.data()); 
1245                            }
1246                            g_braceCount=1;
1247                            BEGIN(Map);
1248                          }
1249
1250 <Bases>^{B}*("component"){BN}+{FUNCNAME}  { // found component
1251                            appStringLower(g_PrevString,vhdlcodeYYtext);
1252                            //  writeFont("keywordflow",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1253                            //  writeFont("vhdlkeyword"," ");
1254                            QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1255                            temp=temp.stripWhiteSpace();
1256                            VhdlDocGen::deleteAllChars(temp,'\n');
1257                            g_tempComp=temp;
1258                            codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1259                            g_braceCount=0;
1260                          
1261                            //if (getClass(temp.data()))
1262                            //  generateClassOrGlobalLink(*g_code,temp.data());
1263                            //else
1264                            //  generateMemLink(*g_code,g_CurrClass,temp);
1265                          
1266                            isComponent=TRUE;
1267                            BEGIN(ParseComponent);
1268                          }
1269                                                 
1270
1271
1272 <Bases>{ARCHITECTURE}    { // found architecture
1273                            g_PortMapComp.resize(0);
1274                            //        writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1275                            //        writeFont("vhdlkeyword"," ");
1276                            //        writeFont("vhdlchar",VhdlDocGen::getIndexWord(vhdlcodeYYtext,1).data());
1277                            //        writeFont("vhdlkeyword"," ");
1278                            //        writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,2).data());
1279                            //        writeFont("vhdlkeyword"," ");
1280                            //QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1281                            //temp=temp.stripWhiteSpace();
1282                            //temp+=("-");
1283                            //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1284                            QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1285                            temp+="::";
1286                            temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1287                            g_CurrClass=temp;
1288                            VhdlDocGen::deleteAllChars(temp,'\n');
1289                            codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1290                            //generateClassOrGlobalLink(*g_code,temp.data());
1291                            isPackageBody=FALSE;
1292                            BEGIN(ClassName);
1293                          }
1294
1295
1296 <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME}  { // found package body  
1297                            QCString ss(vhdlcodeYYtext);
1298                            QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
1299                            QStringList ql=QStringList::split(temp,ss,FALSE);
1300                            QCString ll=ql[0].utf8();
1301                            codifyLines(ll.data(),g_CurrClass.data());
1302                            temp=temp.stripWhiteSpace();
1303                                      temp.prepend("_");
1304                            generateClassOrGlobalLink(*g_code,temp.data());
1305                            g_CurrClass.resize(0);
1306                            g_CurrClass=temp;
1307                            isProto=FALSE;
1308                            isPackageBody=TRUE;
1309                            // BEGIN(ClassesName);
1310                          }
1311
1312 <Bases>{PROCESS}         { // found process
1313                            isFuncProto=TRUE;
1314                            g_FuncProto.resize(0);
1315                            g_FuncProto.append(vhdlcodeYYtext);
1316                            g_vhdlKeyDict.clear();
1317                            appStringLower(g_PrevString,vhdlcodeYYtext);
1318                            if (g_PrevString.contains('(')) 
1319                            {
1320                              g_braceCount=1;
1321                              BEGIN(ParseProcessProto);
1322                            }
1323                            else
1324                            {
1325                              writeProcessProto();
1326                            }
1327                          }
1328
1329 <Bases>("end"){BN}+("process") { // end of process
1330                            isFuncProto=FALSE;
1331                            codifyLines(vhdlcodeYYtext);
1332                            BEGIN(Bases);
1333                          }
1334
1335
1336 <Bases>^{B}*("begin "|"begin") { 
1337                            isFuncProto=FALSE;
1338                            writeFont("vhdlkeyword",vhdlcodeYYtext);
1339                          }
1340
1341 <Bases>^{B}*("use"|"library"){BN}+ { //found  package or library
1342                            writeFont("vhdlkeyword",vhdlcodeYYtext);
1343                            BEGIN(ParsePackage);
1344                          }
1345
1346
1347 <Bases>^{B}*("use"){BN}+("configuration")[^\n]* { 
1348                            codifyLines(vhdlcodeYYtext);
1349                          }
1350
1351
1352
1353 <Bases>{FUNC}            {  // found function|procedure
1354                            g_vhdlKeyDict.clear();
1355                            g_FuncProto.resize(0);
1356                            isProto=FALSE;
1357                            g_FuncProto.append(vhdlcodeYYtext);
1358                            g_braceCount=1;
1359                            BEGIN(ParseType);
1360                          }
1361                                         
1362
1363
1364 <Bases>^{B}*("entity"|"package"){BN}+ { 
1365                            appStringLower(g_PrevString,vhdlcodeYYtext);
1366                            writeFont("keywordflow",vhdlcodeYYtext);
1367                            isPackageBody=FALSE;
1368                            BEGIN(ClassesName);
1369                          }
1370                                         
1371
1372 <Bases>{KEYWORD}         { // found keyword
1373                            QCString qcs(vhdlcodeYYtext);
1374                            if (!writeColoredWord(qcs))
1375                            {
1376                              startFontClass("vhdlchar");
1377                              g_code->codify(vhdlcodeYYtext);
1378                              endFontClass();
1379                            }
1380                          }
1381
1382
1383 <Bases>{ID}              {
1384                            appStringLower(g_PrevString,vhdlcodeYYtext);
1385                            QCString temp(vhdlcodeYYtext);
1386                            temp=temp.stripWhiteSpace();
1387                         
1388                            if (!writeColoredWord(temp))
1389                            {
1390                              startFontClass("vhdlchar");
1391                              generateMemLink(*g_code,g_CurrClass,temp);
1392                              endFontClass();
1393                            }
1394                          }
1395
1396 <Bases,ParseComponent>{DIGITSS} { 
1397                            startFontClass("vhdllogic");
1398                            codifyLines(vhdlcodeYYtext);
1399                            endFontClass();
1400                          }
1401
1402 <Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* { 
1403                             codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1404                          }
1405
1406
1407 <Bases>{TYPEKW}          { 
1408                            codifyLines(vhdlcodeYYtext);
1409                            if (isFuncProto)
1410                            {
1411                              BEGIN(ParseFuncProto);
1412                            }
1413                            else 
1414                            {
1415                              BEGIN(Bases);
1416                            }
1417                          }
1418
1419 <Bases>{OPERATOR}        {                            
1420                            startFontClass("vhdlchar");
1421                            g_code->codify(vhdlcodeYYtext);
1422                            endFontClass();
1423                          }
1424    
1425 <Bases>","|"."|":"|"'"|"("|")" { 
1426                            startFontClass("vhdlchar");
1427                            g_code->codify(vhdlcodeYYtext);
1428                            endFontClass();
1429                          }
1430                                           
1431 <Bases>{STRING} {
1432                        QCString qcs(vhdlcodeYYtext);
1433                        VhdlDocGen::deleteAllChars(qcs,'"');
1434                        VhdlDocGen::deleteAllChars(qcs,' ');
1435                     
1436                        if (VhdlDocGen::isNumber(qcs))
1437                        writeFont("vhdllogic",vhdlcodeYYtext);
1438                        else
1439                        writeFont("keyword",vhdlcodeYYtext);
1440                 }
1441
1442 <Bases>{B}*"#"[^\n]*  { 
1443                                       writeFont("keyword",vhdlcodeYYtext);
1444                                     }
1445                                      
1446 <Bases>^{B}*{XILINX}[^\n]*  { 
1447                             writeWord(yytext);
1448                             //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1449                          }           
1450                              
1451 <Bases>^{B}*"set_"[^\n]*  { 
1452                                       writeWord(yytext);
1453                                     }
1454                                     
1455 <*>\n                    {
1456                            codifyLines(vhdlcodeYYtext);
1457                            BEGIN(Bases);
1458                          }
1459
1460 <*>.                     {
1461                            g_code->codify(vhdlcodeYYtext);
1462                          }
1463
1464 <*>\n{TEXTT}             { // found normal or special comment on its own line
1465                            QCString text(vhdlcodeYYtext);
1466                            int i=text.find("--");
1467                            if (text.mid(i,3)=="--!" && // hide special comment
1468                                Config_getBool("STRIP_CODE_COMMENTS")) 
1469                            { 
1470                              g_yyLineNr++; // skip complete line
1471                            }  
1472                            else // normal comment
1473                            {
1474                              startFontClass("keyword");
1475                              codifyLines(text);
1476                              endFontClass();
1477                            }
1478                          }
1479 <*>{TEXTT}               { // found normal or special comment after something
1480                            QCString text(vhdlcodeYYtext);
1481                            int i=text.find("--");
1482                            if (text.mid(i,3)=="--!" &&
1483                                Config_getBool("STRIP_CODE_COMMENTS")) 
1484                            { 
1485                               // hide special comment
1486                            }  
1487                            else // normal comment
1488                            {
1489                              startFontClass("keyword");
1490                              codifyLines(text);
1491                              endFontClass();
1492                            }
1493                          }
1494
1495
1496 %%
1497
1498 /*@ ----------------------------------------------------------------------------
1499  */
1500
1501 void resetVhdlCodeParserState()
1502 {
1503   g_vhdlKeyDict.setAutoDelete(TRUE);
1504   g_vhdlKeyDict.clear();
1505 }
1506
1507 void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s, 
1508                   bool /*exBlock*/, const char *exName,FileDef *fd,
1509                   int startLine,int endLine,bool inlineFragment,
1510                   MemberDef *memberDef,bool,Definition *searchCtx)
1511 {
1512   //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1513   if (s.isEmpty()) return;
1514   if (memberDef)
1515   {
1516     ClassDef *dd=memberDef->getClassDef();
1517     if (dd) g_CurrClass=dd->className();
1518     startLine--;
1519   }
1520   resetVhdlCodeParserState();
1521   g_code = &od;
1522   g_inputString   = s;
1523   g_inputPosition = 0;
1524   g_currentFontClass = 0;
1525   g_needsTermination = FALSE;
1526   g_searchCtx = searchCtx;
1527
1528   if (endLine!=-1)
1529     g_inputLines  = endLine+1;
1530   else
1531     g_inputLines  = countLines();
1532
1533   if (startLine!=-1)
1534     g_yyLineNr    = startLine;
1535   else
1536     g_yyLineNr    = 1;
1537
1538
1539   // g_theCallContext.clear();
1540   g_classScope    = className;
1541   g_exampleName   = exName;
1542   g_sourceFileDef = fd;
1543   bool cleanupSourceDef = FALSE;
1544   if (fd==0)
1545   {
1546     // create a dummy filedef for the example
1547     g_sourceFileDef = new FileDef("",exName);
1548     cleanupSourceDef = TRUE;
1549   }
1550   if (g_sourceFileDef) 
1551   {
1552     setCurrentDoc("l00001");
1553   }
1554   g_currentDefinition = 0;
1555   g_currentMemberDef = 0;
1556   g_vhdlMember=0;
1557   if (!g_exampleName.isEmpty())
1558   {
1559     g_exampleFile = convertNameToFile(g_exampleName+"-example");
1560   }
1561   g_includeCodeFragment = inlineFragment;
1562   if (!memberDef)
1563   {
1564     startCodeLine();
1565   }
1566   // g_type.resize(0);
1567   // g_name.resize(0);
1568   // g_args.resize(0);
1569   g_parmName.resize(0);
1570   g_parmType.resize(0);
1571   if (memberDef) 
1572   {
1573     setParameterList(memberDef);
1574   }
1575   int iLine=countLines();
1576   vhdlcodeYYrestart( vhdlcodeYYin );
1577   BEGIN( Bases );
1578   vhdlcodeYYlex();
1579   g_lexInit=TRUE;
1580   if (g_needsTermination)
1581   {
1582     endCodeLine();
1583   }
1584   if (cleanupSourceDef)
1585   {
1586     // delete the temporary file definition used for this example
1587     delete g_sourceFileDef;
1588     g_sourceFileDef=0;
1589   }
1590   assert(g_yyLineNr==iLine);
1591   return;
1592 }
1593
1594 void codeFreeVhdlScanner()
1595 {
1596 #if defined(YY_FLEX_SUBMINOR_VERSION) 
1597   if (g_lexInit)
1598   {
1599     vhdlcodeYYlex_destroy();
1600   }
1601 #endif
1602 }
1603
1604 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
1605 extern "C" { // some bogus code to keep the compiler happy
1606   void vhdlcodeYYdummy() { yy_flex_realloc(0,0); } 
1607 }
1608 #elif YY_FLEX_SUBMINOR_VERSION<33
1609 #error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
1610 #endif
1611
1612
1613
1614