Fix for UBSan build
[platform/upstream/doxygen.git] / src / vhdlscanner.l
1 /************** VHDL scanner in LEX format **********
2  *
3  * Version 0.2 Wed Aug 11, 1993
4  *
5  * This scanner is derived from a scanner of the ALLIANCE CAD toolset,
6  * release 1.1. That toolset was written from:
7  *   MASI/CAO-VLSI CAD Team  
8  *   Laboratoire MASI/CAO-VLSI
9  *   Tour 55-65, 2eme etage, Porte 13
10  *   Universite Pierre et Marie Curie (PARIS VI)
11  *   4, place Jussieu 75252 PARIS Cedex 05, FRANCE
12  * The ALLIANCE CAD Toolset can be obtained from ftp site : ftp-masi.ibp.fr    
13  *
14  * This scanner is avail at: ftp.cs.utwente.nl in pub/src/VHDL/Grammar
15  * A corresponding Yacc grammar is available at the same site
16  *
17  * author of this derived scanner version:
18  * Thomas Dettmer
19  * Dortmund University
20  * Dept. of Computer Scienc, LS1
21  * PB 500 500
22  * D-44221 Dortmund (Germany)
23  * Phone: +49-231-755-6464
24  * e-mail: dettmer@ls1.informatik.uni-dortmund.de
25  *
26  *
27  ****************************************************************
28  * 
29  * This file is intended not to be used for commercial purposes
30  * without permission of the University of Dortmund
31  *   
32  * NOTE THAT THERE IS NO WARRANTY FOR CORRECTNES, COMPLETENESS, SUPPORT
33  * OR ANYTHING ELSE.
34  *******************************************************/
35 /******************************************************************************
36  * modified for doxygen by M. Kreis
37  * extended to VHDL 93/2002/2008 
38  ******************************************************************************/
39 %{
40
41 #ifndef YYSTYPE
42         typedef int YYSTYPE;
43 #endif
44
45 #include <ctype.h>
46 #include <search.h>
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <assert.h>
51 #include <string.h>
52 #include <ctype.h>
53 #include "commentscan.h"
54 #include "vhdlparser.h"
55 #include "vhdlscanner.h"
56
57 #include "doxygen.h"
58 #include "searchindex.h"
59 #include <ctype.h>
60 #include "scanner.h"
61 #include "vhdldocgen.h"
62 #include "util.h"
63 #include "bufstr.h"
64 #include "message.h"
65 #include "vhdlcode.h"
66 #include <qmap.h>
67 #include "entry.h"
68
69 #define YY_NO_INPUT 1
70
71 extern void vhdlParse(); // defined in vhdlparser.y
72
73 static bool          g_lexInit = FALSE;
74 static ParserInterface *g_thisParser;
75 static VhdlContainer* yycont=NULL;
76 static Entry* current_root;
77 static Entry   gBlock;
78
79 static int yyLineNr =1;
80 static int   g_lastCommentContext;
81 static int              inputPosition;
82 static int startComment;
83 static QCString inputVhdlString;
84 static QFile            inputFile;
85 static QCString         yyFileName;
86 static QList<QCString> qlist;
87 static QCString lastLetter;
88
89 static bool doxComment=FALSE; // doxygen comment ? 
90 static QCString strComment;
91 static int iDocLine=-1;
92 static int* lineIndex=NULL;
93 static int num_chars;
94 static  int prevToken;
95 static int iCodeLen;
96
97 static QMap<QCString, int> keyMap;
98 static QList<Entry>  lineEntry;
99 static bool  checkMultiComment(QCString& qcs,int line);
100 static void handleCommentBlock(const QCString &doc,bool brief);
101 static void mapLibPackage(const Entry* ce);
102 static QList<Entry>* getEntryAtLine(const Entry* ce,int line);
103 static bool addLibUseClause(const QCString &type);
104 static Entry* oldEntry;
105 static bool varr=FALSE;
106 static QCString varName;
107
108 static struct 
109 {
110   QCString doc;
111   bool brief;
112   bool pending;
113   int iDocLine;
114 } str_doc;
115
116 #define YY_NEVER_INTERACTIVE 1
117 #define YY_USER_ACTION num_chars += vhdlScanYYleng;
118
119 #define MAX_KEYWORD_LEN 20
120
121 typedef struct 
122 {
123   char nom[MAX_KEYWORD_LEN];
124   int kval;
125 } el_mc;
126
127 static el_mc tab_mc []=
128 {
129     { "abs",                t_ABS                },
130     { "access",             t_ACCESS             },
131     { "after",              t_AFTER              },
132     { "alias",              t_ALIAS              },
133     { "all",                t_ALL                },
134     { "and",                t_AND                },
135     { "architecture",       t_ARCHITECTURE       },
136     { "array",              t_ARRAY              },
137     { "assert",             t_ASSERT             },
138     { "assume",             t_ASSUME             },
139     { "assume_guarantee",   t_ASSUME_GUARANTEE   },
140     { "attribute",          t_ATTRIBUTE          },
141
142     { "begin",              t_BEGIN              },
143     { "block",              t_BLOCK              },
144     { "body",               t_BODY               },
145     { "buffer",             t_BUFFER             },
146     { "bus",                t_BUS                },
147
148     { "case",               t_CASE               },
149     { "component",          t_COMPONENT          },
150     { "configuration",      t_CONFIGURATION      },
151     { "constant",           t_CONSTANT           },
152     { "context",            t_CONTEXT            },
153     { "cover",              t_COVER              },
154
155     { "default",            t_DEFAULT            },
156     { "disconnect",         t_DISCONNECT         },
157     { "downto",             t_DOWNTO             },
158
159     { "else",               t_ELSE               },
160     { "elsif",              t_ELSIF              },
161     { "end",                t_END                },
162     { "entity",             t_ENTITY             },
163     { "exit",               t_EXIT               },
164
165     { "fairness",           t_FAIRNESS           },
166     { "file",               t_FILE               },
167     { "for",                t_FOR                },
168     { "force",              t_FORCE              },
169     { "function",           t_FUNCTION           },
170
171     { "generate",           t_GENERATE           },
172     { "generic",            t_GENERIC            },
173     { "group",              t_GROUP              },
174     { "guarded",            t_GUARDED            },
175
176     { "if",                 t_IF                 },
177     { "impure",             t_IMPURE             },
178     { "in",                 t_IN                 },
179     { "inertial",           t_INERTIAL           },
180     { "inout",              t_INOUT              },
181     { "is",                 t_IS                 },
182   
183     { "label",              t_LABEL              },
184     { "library",            t_LIBRARY            },
185     { "linkage",            t_LINKAGE            },
186     { "literal",            t_LITERAL            },
187     { "loop",               t_LOOP               },
188
189     { "map",                t_MAP                },
190     { "mod",                t_MOD                },
191
192     { "nand",               t_NAND               },
193     { "new",                t_NEW                },
194     { "next",               t_NEXT               },
195     { "nor",                t_NOR                },
196     { "not",                t_NOT                },
197     { "null",               t_NULL               },
198
199     { "of",                 t_OF                 },
200     { "on",                 t_ON                 },
201     { "open",               t_OPEN               },
202     { "or",                 t_OR                 },
203     { "others",             t_OTHERS             },
204     { "out",                t_OUT                },
205
206     { "package",            t_PACKAGE            },
207     { "parameter",          t_PARAMETER          },
208     { "port",               t_PORT               },
209     { "postponed",          t_POSTPONED          },
210     { "procedure",          t_PROCEDURE          },
211     { "process",            t_PROCESS            },
212     { "property",           t_PROPERTY           },
213     { "protected",          t_PROTECTED          },
214     { "pure",               t_PURE               },
215   
216     { "range",              t_RANGE              },
217     { "record",             t_RECORD             },
218     { "register",           t_REGISTER           },
219     { "reject",             t_REJECT             },
220     { "release",            t_RELEASE            },
221     { "restrict",           t_RESTRICT           },
222     { "restrict_guarantee", t_RESTRICT_GUARANTEE },
223     { "rem",                t_REM                },
224     { "report",             t_REPORT             },
225     { "rol",                t_ROL                },
226     { "ror",                t_ROR                },
227     { "return",             t_RETURN             },
228
229     { "select",             t_SELECT             },
230     { "sequence",           t_SEQUENCE           },
231     { "severity",           t_SEVERITY           },
232     { "signal",             t_SIGNAL             },
233     { "shared",             t_SHARED             },
234     { "sla",                t_SLA                },
235     { "sll",                t_SLL                },
236     { "sra",                t_SRA                },
237     { "srl",                t_SRL                },
238     { "strong",             t_STRONG             },
239     { "subtype",            t_SUBTYPE            },
240
241     { "then",               t_THEN               },
242     { "to",                 t_TO                 },
243     { "transport",          t_TRANSPORT          },
244     { "type",               t_TYPE               },
245
246     { "unaffected",         t_UNAFFECTED         },
247     { "units",              t_UNITS              },
248     { "until",              t_UNTIL              },
249     { "use",                t_USE                },
250
251     { "variable",           t_VARIABLE           },
252     { "vmode",              t_VMODE              },
253     { "vprop",              t_VPROP              },
254     { "vunit",              t_VUNIT              },
255
256     { "wait",               t_WAIT               },
257     { "when",               t_WHEN               },
258     { "while",              t_WHILE              },
259     { "with",               t_WITH               },
260
261     { "xor",                t_XOR                },
262     { "xnor",               t_XNOR               },
263     { "zz",                 -1                   } // list end
264 };
265
266    
267 static int find_keyword(char *s)
268 {
269   QCString word(s);
270   // keyword ?
271   if (word.length() >  MAX_KEYWORD_LEN) 
272         return -1;
273
274   word=word.lower();
275   QMap<QCString, int>::Iterator it = keyMap.find(word);
276   if (it.key())
277         return it.data();
278
279   return -1;
280 }
281
282 // update current line
283 static void lineCount()
284 {
285   for (const char* c=vhdlScanYYtext ; *c ; ++c )
286   {
287     yyLineNr += (*c == '\n') ;
288   }
289 }
290
291
292 static void startCodeBlock(int index){
293   int ll=strComment.length();
294   iCodeLen=inputVhdlString.findRev(strComment.data())+ll;
295   // fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll);
296   //assert(false);
297   gBlock.reset();
298   int len=strComment.length();
299   QCString name=strComment.right(len-index);// 
300   name=VhdlDocGen::getIndexWord(name.data(),1);
301   if (!name)
302     gBlock.name="misc"+ VhdlDocGen::getRecordNumber(); 
303   else
304     gBlock.name=name;
305   strComment=strComment.left(index);
306   gBlock.startLine=yyLineNr+1;
307   gBlock.bodyLine=yyLineNr+1;
308   VhdlDocGen::prepareComment(strComment);
309   gBlock.brief+=strComment;
310 }
311 static void makeInlineDoc(int endCode)
312 {
313   int len=endCode-iCodeLen;
314   QCString par=inputVhdlString.mid(iCodeLen,len);
315   gBlock.doc=par;
316   gBlock.inbodyDocs=par;
317   gBlock.section=Entry::VARIABLE_SEC;
318   gBlock.spec=VhdlDocGen::MISCELLANEOUS;
319   gBlock.fileName = yyFileName;
320   gBlock.endBodyLine=yyLineNr-1;
321   gBlock.lang=SrcLangExt_VHDL;
322   Entry *temp=new Entry(gBlock);
323
324   Entry* compound=getVhdlCompound();
325
326   if (compound)
327   {
328     compound->addSubEntry(temp);
329   }
330   else
331   {
332     temp->type="misc"; // global code like library ieee...
333     current_root->addSubEntry(temp);
334   }
335   strComment.resize(0);
336   gBlock.reset();
337
338
339 }// makeInlineDoc
340
341 static bool isConstraintFile(const QCString &fileName,const QCString &ext)
342 {
343   return fileName.right(ext.length())==ext;
344 }
345
346 //static void resetScanner(const char* s,MyParserVhdl* parse);
347
348 #undef  YY_INPUT
349 #define YY_INPUT(buf,result,max_size) result=vhdlScanYYread(buf,max_size);
350
351
352 static int vhdlScanYYread(char *buf,int max_size)
353 {
354   int c=0;
355   while ( c < max_size && inputVhdlString.at(inputPosition) )
356   {
357         *buf = inputVhdlString.at(inputPosition++) ;
358         c++; buf++;
359   }
360   return c;
361 }
362
363 %}
364
365 upper_case_letter          [A-Z]
366 digit                      [0-9]
367 special_character          [\#\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\_\|]
368 space_character            [ \t]
369 format_effector            [\t\v\r\l\f]
370 end_of_line                \n
371 lower_case_letter          [a-z]
372 other_special_character    [\!\$\@\?\[\\\]\^\`\{\}\~]
373
374 graphic_character          ({basic_graphic_character}|{lower_case_letter}|{other_special_character})
375 basic_graphic_character    ({upper_case_letter}|{digit}|{special_character}|{space_character})
376 letter                     ({upper_case_letter}|{lower_case_letter})
377 letter_or_digit            ({letter}|{digit})
378 decimal_literal            {integer}(\.{integer})?({exponent})?
379 integer                    {digit}(_?{digit})*
380 exponent                   ([eE][-+]?{integer})
381 base                       {integer}
382 based_integer              {extended_digit}(_?{extended_digit})*
383 extended_digit             ({digit}|[a-fA-F])
384
385 extended_character         [\\]{graphic_character}*[\\] 
386
387 base_specifier             {digit}*(B|b|D|O|o|X|x|"UB"|"UO"|"UX"|"SB"|"SO"|"SX")
388
389 vhdl2008tooldir            `{graphic_character}+
390
391 B                          [ \t]
392 BR                         [ \t\n\r]
393
394
395 %option noyywrap
396 %x Comment
397 %x Vhdl2008Comment
398 %x EndVhdl2008Comment
399 %%
400
401 {space_character}  { /* nothing */ }
402 \&                 { return(t_Ampersand); }
403 \'                 { return(t_Apostrophe); }
404 \(                 { return(t_LeftParen); }
405 \)                 { return(t_RightParen); }
406 "**"               { return(t_DoubleStar); }
407 \*                 { return(t_Star); }
408 \+                 { return(t_Plus); }
409 \,                 { return(t_Comma); }
410 \-                 { return(t_Minus); }
411 ":="               { return(t_VarAsgn); }
412 \:                 { return(t_Colon); }
413 \;                 { return(t_Semicolon); }
414 "<="               { return(t_LESym); }
415 ">="               { return(t_GESym); }
416 \<                 { return(t_LTSym); }
417 \>                 { return(t_GTSym); }
418 \=                 { return(t_EQSym); }
419 \/=                { return(t_NESym); }
420 "=>"               { return(t_Arrow); }
421 "<>"               { return(t_Box); }
422 "<<"               { return(t_SLSL); }
423 ">>"               { return(t_SRSR); }
424 "??"               { return(t_QQ); }
425 "?>="              { return(t_QGT); }
426 "?<="              { return(t_QLT); }
427 "?>"               { return(t_QG); }
428 "?<"               { return(t_QL); }
429 "?="               { return(t_QEQU); }
430 "?/="              { return(t_QNEQU); }
431 \?                 { return(t_Q); }
432 \|                 { return(t_Bar); }
433 \.                 { return(t_Dot); }
434 \/                 { return(t_Slash); }
435 \@                 { return(t_At); }
436 \^                 { return(t_Neg); }
437 \[                 { return(t_LEFTBR); }
438 \]                 { return(t_RIGHTBR); }
439
440
441 {letter}(_?{letter_or_digit})*|{extended_character}     {
442           int itoken=find_keyword(vhdlScanYYtext);
443         
444           //    fprintf(stderr,"\n <<<< search tok:  %s %d %d>>>\n",vhdlScanYYtext,itoken,yyLineNr);
445         
446           // tokens in vhdlparser.hpp 258..412
447           if (itoken>200  && itoken<500 && prevToken!=t_END)
448           {
449             //          printf("\n <<<< insert tok:  %s %d %d>>>\n",vhdlScanYYtext,itoken,yyLineNr);
450             lineIndex[itoken]=yyLineNr;
451           }
452          
453          // global members
454          if (( itoken==t_ARCHITECTURE )  || 
455              ( itoken==t_ENTITY)         || 
456              ( itoken==t_PACKAGE )       || 
457              ( itoken==t_LIBRARY )       ||  
458              ( itoken==t_USE )           ||  
459              ( itoken==t_CONFIGURATION ) ||  
460              ( itoken==t_CONTEXT ) )
461          {
462            lineIndex[itoken]=yyLineNr;
463          }
464          
465           prevToken=itoken;
466         
467           yycont->qstr=vhdlScanYYtext;
468           yycont->yyLineNr=yyLineNr;
469           if (itoken== -1)  
470           {
471             yycont->iLine=yyLineNr;
472             return ( t_LETTER );
473           }
474           else 
475           {
476             return ( itoken );
477           }
478         }
479
480 ({decimal_literal})|({base}#{based_integer}(\.{based_integer})?#({exponent})?)|({base}:{based_integer}(\.{based_integer})?:({exponent})?) {
481           yycont->qstr=vhdlScanYYtext;
482           return ( t_ABSTRLIST );
483         }
484
485 '({graphic_character}|\"|\%)'   {
486           QCString q(vhdlScanYYtext);          
487           yycont->qstr=vhdlScanYYtext; 
488         
489           if (q=="'('") // std_logic'('1') ?
490           {
491             char c=yy_hold_char;
492             if (isalpha(c) || isdigit(c))
493             {
494               unput('\'');
495               unput('(');
496               return(t_Apostrophe);
497             }
498             else
499             {
500               return ( t_CHARLIST );
501             }
502           }
503           return ( t_CHARLIST );
504         }
505
506 (\"({graphic_character}|(\"\")|\%)*\")|(\%({graphic_character}|(\%\%)|\")*\%) {
507           yycont->qstr=vhdlScanYYtext;
508           yycont->iLine=yyLineNr;
509           return ( t_STRING );
510         } 
511
512 {base_specifier}(\"{extended_digit}(_?{extended_digit})*\"|\%{extended_digit}(_?{extended_digit})*\%)                                                   {
513           yycont->qstr=vhdlScanYYtext;
514           yycont->iLine=yyLineNr;
515           return ( t_DIGIT );
516         }
517
518 {vhdl2008tooldir} {
519           yycont->qstr=vhdlScanYYtext;
520           yycont->iLine=yyLineNr;
521           return(t_ToolDir);
522         }       
523
524 \n      {
525           yyLineNr++;
526           yycont->yyLineNr=yyLineNr;
527         }
528
529 <*>"--"[^\n]* {
530           /* comment */
531           QCString qcs(vhdlScanYYtext);
532           //  vhdl comment ?
533           if (qcs.stripPrefix("--!"))
534           {
535             REJECT;
536           }
537         }               
538 .       { /* unknown characters */ }
539                                                                         
540
541 <*>{BR}*"--!"[^{}\n][^\n]*\n/{B}*"--!" { // multi line comment
542   if (iDocLine==-1) iDocLine=yyLineNr;
543   QCString qc(vhdlScanYYtext);
544   int len=qc.contains('\n')+yyLineNr-1;
545   if (YY_START!=Comment) // Start of the comment block
546   {
547     startComment=yyLineNr;
548     g_lastCommentContext=YY_START;
549   }
550   
551    if(!checkMultiComment(qc,len))
552   {
553     strComment+=vhdlScanYYtext;
554   }
555   lineCount();
556   BEGIN(Comment);
557 }
558
559 <Comment>^{B}*"--!"[^\n]* {
560   if (iDocLine==-1) iDocLine=yyLineNr;
561   strComment+=vhdlScanYYtext;
562   int index=strComment.find("\\code");
563   if (index>0)
564   {
565     startCodeBlock(index);
566     doxComment=TRUE;
567   }
568   lineCount();
569   BEGIN(Comment);
570 }
571
572 <Comment>.|\n {
573           // found end of comment block
574           
575           int index =strComment.find("\\code");
576           if (index>0)
577           {
578             startCodeBlock(index);
579           }
580
581           VhdlDocGen::prepareComment(strComment);
582
583
584           if (index==-1 && !doxComment) 
585           {
586             handleCommentBlock(strComment,FALSE);
587           }
588           strComment.resize(0);;
589           unput(*vhdlScanYYtext);
590           doxComment=FALSE;
591           BEGIN(g_lastCommentContext);
592         }
593         
594 <*>"--!"[^\n]* { // one line comment
595           if (iDocLine==-1) iDocLine=yyLineNr;
596           QCString qcs(vhdlScanYYtext);
597
598           bool isEndCode=qcs.contains("\\endcode");
599
600           int index = qcs.find("\\code");
601           if (isEndCode)
602           {
603             int end=inputVhdlString.find(qcs.data(),iCodeLen);
604             makeInlineDoc(end);
605           }
606           else if (index > 0 ) 
607           {
608             // assert(false);
609             strComment=qcs;
610             startCodeBlock(index);
611             strComment.resize(0);
612           }
613
614           //printf("--> handleCommentBlock line %d\n",yyLineNr);
615           if (!isEndCode && index==-1)
616           {
617             int j=qcs.find("--!");
618             qcs=qcs.right(qcs.length()-3-j);
619
620             if(!checkMultiComment(qcs,yyLineNr))
621             {
622               handleCommentBlock(qcs,TRUE);
623             }
624           }//endcode
625        }
626
627 <*>"/*" {
628           strComment+=vhdlScanYYtext;
629           if (yy_hold_char=='!') // found  comment starting with "/*!"
630           {
631             doxComment=TRUE;
632           }
633           BEGIN(Vhdl2008Comment); 
634         }
635
636 <Vhdl2008Comment>[^*]*[*]+    {
637           QCString tt(vhdlScanYYtext);
638           int len=tt.length();
639           yyLineNr+=tt.contains('\n');
640
641           // delete * from comments 
642           // /*! 
643           // *   see vim !
644           // */
645
646           if (yytext[len-1]=='*' && tt.contains('\n'))
647           {
648             QCString ss=tt;
649             VhdlDocGen::deleteAllChars(ss,' ');
650             VhdlDocGen::deleteAllChars(ss,'\t');
651             if (ss.data()  && ss.at(ss.length()-2)=='\n')
652             {
653               tt=tt.left(len-1);
654               len--;
655             }
656           }
657
658           //       fprintf(stderr,"\n << %s  >>",tt.data());
659           strComment+=tt;
660           char c=yy_hold_char;
661           if (c =='/')
662           {
663             unput('*');
664             BEGIN(EndVhdl2008Comment);
665           }
666           else 
667           {
668             BEGIN(Vhdl2008Comment);
669           }
670         }
671
672 <EndVhdl2008Comment>"*/" {       
673           if (doxComment)
674           {  
675             strComment.stripPrefix("/*!");
676             strComment= strComment.left(  strComment.length()-1);
677             handleCommentBlock( strComment,TRUE);
678           }
679           doxComment=FALSE;
680           strComment.resize(0);
681           BEGIN(INITIAL);
682         }
683
684
685 %%
686
687 static void parserInit()
688 {
689   num_chars=0;
690   lineIndex=(int*)malloc(500*sizeof(int));
691
692   if (!g_lexInit) 
693   {
694     VhdlDocGen::init();
695     el_mc oop;
696     int p=0;
697     while ((oop=tab_mc[p++]).kval!=-1)
698     {
699       QCString q(&oop.nom[0]);
700       keyMap.insert(q,oop.kval);
701     }
702   }
703 }
704
705 void vhdlscanFreeScanner()
706 {
707 #if defined(YY_FLEX_SUBMINOR_VERSION)
708   if (g_lexInit)
709   {
710     vhdlScanYYlex_destroy();
711   }
712 #endif
713 }
714
715 void VHDLLanguageScanner::resetCodeParserState()
716 {
717 }
718
719 bool VHDLLanguageScanner::needsPreprocessing(const QCString & /*extension*/)
720
721   return TRUE; 
722 }
723
724 void VHDLLanguageScanner::parsePrototype(const char *text)
725
726   varName=text;
727   varr=TRUE;
728 }
729
730 // do parsing
731 //int VhdlParser::doLex()
732 //{
733 //  int token=vhdlScanYYlex();
734 //  //fprintf(stderr,"\ntoken: %d at line: %d",token,yyLineNr);
735 //  return token;
736 //}
737
738 void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root)
739 {
740   yyFileName=QCString(fileName);
741
742   bool xilinx_ucf=isConstraintFile(yyFileName,".ucf");
743   bool altera_qsf=isConstraintFile(yyFileName,".qsf");
744
745   // support XILINX(ucf) and ALTERA (qsf) file
746
747   if (xilinx_ucf) 
748   { 
749     VhdlDocGen::parseUCF(fileBuf,root,yyFileName,FALSE);  
750     return; 
751   }
752   if (altera_qsf) 
753   { 
754     VhdlDocGen::parseUCF(fileBuf,root,yyFileName,TRUE); 
755     return; 
756   }
757
758   ::parserInit();
759   yycont=getVhdlCont();
760   yycont->root=root;
761   yycont->fileName=fileName;
762   initVhdlParser();
763   QCString pPuffer(" ");
764   pPuffer+=fileBuf;
765
766   inputFile.setName(fileName);
767   if (g_lexInit)
768   {
769     vhdlScanYYrestart( vhdlScanYYin );
770   }
771   g_lexInit=TRUE;
772   g_thisParser=this;
773   inputPosition=0;
774   inputVhdlString=fileBuf;
775   yyLineNr=1;
776   current_root=root;
777   groupEnterFile(fileName,yyLineNr);
778   vhdlParse();
779   Entry* curr=getCurrentVhdlEntry(); // delete last current
780   delete curr;
781   curr=0;
782   free(lineIndex);
783   inputFile.close();
784   mapLibPackage(root);
785 }
786
787 void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf,
788     const char *scopeName,
789     const QCString &input,
790     bool isExampleBlock,
791     const char *exampleName,
792     FileDef *fileDef,
793     int startLine,
794     int endLine,
795     bool inlineFragment,
796     MemberDef *memberDef,
797     bool showLineNumbers,
798     Definition *searchCtx
799     )
800 {
801   ::parseVhdlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
802                   fileDef,startLine,endLine,inlineFragment,memberDef,
803                   showLineNumbers,searchCtx);
804 }
805
806 /*
807  * adds the library|use statements to the next class (entity|package|architecture|package body
808  * library ieee
809  * entity xxx
810  * .....
811  * library
812  * package
813  * enity zzz
814  * .....
815  * and so on..
816  */
817 static void mapLibPackage(const Entry* ce)
818 {
819   Entry *lastComp=0;
820   while (TRUE)
821   {
822     bool found = FALSE;
823     Entry *rt=0;
824     //const QList<Entry> *epp=ce->children();
825     EntryListIterator eli(*ce->children());
826     EntryListIterator eli1=eli;
827     for (;(rt=eli.current()),eli1=eli;++eli)
828     {
829       if (rt->spec==VhdlDocGen::LIBRARY || rt->spec==VhdlDocGen::USE)
830         // top level library or use statement
831       {
832         Entry *temp=0;
833         if(!addLibUseClause(rt->name))
834         {
835           rt->spec=-1;
836           rt->section=0;
837           //  continue;
838         }
839
840         for (;(temp=eli1.current());++eli1) // find next entity
841         {
842           if (temp->spec==VhdlDocGen::ENTITY || 
843               temp->spec==VhdlDocGen::PACKAGE || 
844               temp->spec==VhdlDocGen::ARCHITECTURE || 
845               temp->spec==VhdlDocGen::PACKAGE_BODY)
846           {
847             Entry *ee=new Entry(*rt); //append a copy to entries sublist
848             temp->addSubEntry(ee);
849             found=TRUE;
850             rt->spec=-1; //nullify entry
851             rt->section=0;
852             lastComp=temp;
853             break;
854           }
855         }//for
856         if (lastComp && rt->spec!=-1)
857         {
858           Entry *ee=new Entry(*rt); //append a copy to entries sublist
859           lastComp->addSubEntry(ee);
860           found=TRUE;
861           rt->spec=-1; //nullify entry
862           rt->section=0;
863         }
864       }//if
865     }//for
866     if (!found) // nothing left to do
867     {
868       return; 
869     }
870   }//while
871 }//MapLib
872
873 static bool addLibUseClause(const QCString &type)
874 {
875   static bool show=Config_getBool("SHOW_INCLUDE_FILES");
876   static bool showIEEESTD=Config_getBool("FORCE_LOCAL_INCLUDES");
877
878   if (!show)  // all libraries and included packages will not  be shown
879   {
880     return FALSE;
881   }
882
883   if (!showIEEESTD) // all standard packages and libraries will not be shown
884   {  
885     if (type.lower().stripPrefix("ieee")) return FALSE;
886     if (type.lower().stripPrefix("std")) return FALSE;
887   }  
888   return TRUE;
889 }
890
891 static void handleCommentBlock(const QCString &doc,bool brief)
892 {
893   int position=0;
894
895   // empty comment  --!
896   if (doc.isEmpty()) return;
897
898   bool needsEntry=FALSE;
899   Protection protection=Public;
900   int lineNr = iDocLine;
901
902   Entry* current=getCurrentVhdlEntry();
903
904   if (oldEntry==current)
905   {
906     //printf("\n find pending message  < %s > at line: %d \n ",doc.data(),iDocLine);
907     str_doc.doc=doc;
908     str_doc.iDocLine=iDocLine;
909     str_doc.brief=brief;
910     str_doc.pending=TRUE;
911     return;
912   }
913
914   oldEntry=current;
915
916   if (brief) 
917   {
918     current->briefLine = iDocLine; 
919   }
920   else 
921   {
922     current->docLine = iDocLine;
923   }
924   
925 //  printf("parseCommentBlock file<%s>\n [%s]\n",yyFileName.data(),doc.data());
926   while (parseCommentBlock(
927         g_thisParser,
928         current,
929         doc,        // text
930         yyFileName, // file
931         lineNr,     // line of block start
932         brief, 
933         0,
934         FALSE,
935         protection,
936         position,
937         needsEntry
938         )
939      ) 
940   {
941  //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
942     if (needsEntry) newVhdlEntry();
943   }
944   if (needsEntry)
945   {
946     if (varr)
947     {
948       varr=FALSE;
949       current->name=varName;
950       current->section=Entry::VARIABLEDOC_SEC;
951       varName="";
952       strComment.resize(0);
953     }
954    
955     newVhdlEntry();
956   }
957   iDocLine=-1;
958   strComment.resize(0);
959 }
960
961 // returns the vhdl parsed types at line xxx
962 QList<Entry>* getEntryAtLine(const Entry* ce,int line)
963 {
964   EntryListIterator eli(*ce->children());
965   Entry *rt;
966   for (;(rt=eli.current());++eli)
967   {
968     if (rt->bodyLine==line)
969     {
970       lineEntry.insert(0,rt);
971     } // if
972
973     getEntryAtLine(rt,line);
974   }
975   return &lineEntry;
976 }
977
978 // token index in vhdlparser.hpp 258..416
979 int getParsedLine(int object)
980 {
981   //assert(object>254 && object <416);
982   return lineIndex [object];
983 }
984
985 void isVhdlDocPending()
986 {
987   if (!str_doc.pending)
988     return;
989   str_doc.pending=FALSE;
990   oldEntry=0; // prevents endless recursion
991   iDocLine=str_doc.iDocLine;
992   handleCommentBlock(str_doc.doc,str_doc.brief);
993   iDocLine=-1;
994 }
995
996 static bool  checkMultiComment(QCString& qcs,int line)
997 {
998   QList<Entry> *pTemp=getEntryAtLine(current_root,line);
999
1000   if (pTemp->isEmpty()) return false;
1001
1002   //int ii=pTemp->count();
1003   qcs.stripPrefix("--!");
1004   while (!pTemp->isEmpty())
1005   {
1006     Entry *e=(Entry*)pTemp->first();
1007     e->briefLine=line;
1008     e->brief+=qcs;
1009     iDocLine=-1;
1010     pTemp->removeFirst();
1011     //ii=pTemp->count();
1012   }
1013   return true; 
1014 }
1015  
1016