Doxygen
Loading...
Searching...
No Matches
vhdlcode.l
Go to the documentation of this file.
-1/******************************************************************************
2 *
3 * Copyright (C) 1997-2020 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 */
13/******************************************************************************
14 * Parser for syntax highlighting and references for vhdl subset
15 * written by M. Kreis
16 * supports VHDL-87/93/2008
17 ******************************************************************************/
18%option never-interactive
19%option case-insensitive
20%option prefix="vhdlcodeYY"
21%option reentrant
22%option extra-type="struct vhdlcodeYY_state *"
23%top{
24#include <stdint.h>
25// forward declare yyscan_t to improve type safety
26#define YY_TYPEDEF_YY_SCANNER_T
27struct yyguts_t;
28typedef yyguts_t *yyscan_t;
yyguts_t * yyscan_t
Definition code.l:24
29}
31%{
32
33#include <unordered_set>
34#include <string>
35
36/*
37 * includes
38 */
39#include <stdio.h>
40#include <assert.h>
41#include <ctype.h>
42
43#include "vhdlcode.h"
44#include "entry.h"
45#include "doxygen.h"
46#include "message.h"
47#include "outputlist.h"
48#include "util.h"
49#include "membername.h"
50#include "searchindex.h"
51#include "vhdldocgen.h"
52#include "arguments.h"
53#include "config.h"
54#include "classdef.h"
55#include "filedef.h"
56#include "tooltip.h"
57#include "regex.h"
58#include "debug.h"
59
60#define YY_NO_INPUT 1
61#define YY_NO_UNISTD_H 1
63// Toggle for some debugging info
64//#define DBG_CTX(x) fprintf x
65#define DBG_CTX(x) do { } while(0)
66
68/* -----------------------------------------------------------------
69 * statics
70 */
71
72// ----------------- <vhdl> ----------------------------------
73
75{
76 bool isFuncProto = false;
77 bool isComponent = false;
78 bool isPackageBody = false;
79 bool isProto = false;
82 std::unordered_set<std::string> vhdlKeyDict;
85 const MemberDef * vhdlMember = nullptr;
88 OutputCodeList * code = nullptr;
89 const char * inputString = nullptr; //!< the code fragment as text
90 int inputPosition = 0; //!< read offset during parsing
92 int inputLines = 0; //!< number of line in the code fragment
93 int yyLineNr = 0; //!< current line number
94 bool insideCodeLine = false;
95 const Definition *searchCtx = nullptr;
97 bool exampleBlock = false;
101 bool currArch = false;
102
103 std::unique_ptr<FileDef> exampleFileDef;
104 const FileDef * sourceFileDef = nullptr;
105 const Definition * currentDefinition = nullptr;
106 const MemberDef * currentMemberDef = nullptr;
108 const char * currentFontClass = nullptr;
112 bool lexInit = false;
113 int braceCount = 0;
115 std::vector<const Definition *> foldStack;
118static void writeFont(yyscan_t yyscanner,const char *s,const QCString &text,bool specialComment=false);
119static void generateMemLink(yyscan_t yyscanner,OutputCodeList &ol,QCString &clName,QCString& memberName);
120static bool writeColoredWord(yyscan_t yyscanner,QCString& word );
121static void generateClassOrGlobalLink(yyscan_t yyscanner,OutputCodeList &ol,const QCString &clName, bool typeOnly=false, const QCString &curr_class=QCString());
122static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor);
123static bool checkVhdlString(yyscan_t yyscanner,QCString &name);
124static void addToSearchIndex(yyscan_t yyscanner,const QCString &text);
125static void startCodeLine(yyscan_t yyscanner);
126static void endCodeLine(yyscan_t yyscanner);
127static void nextCodeLine(yyscan_t yyscanner);
128static void writeWord(yyscan_t yyscanner,const QCString &word,const QCString &curr_class=QCString(),bool classLink=false);
129static void codifyLines(yyscan_t yyscanner,const QCString &text,const QCString &cl=QCString(),bool classlink=false,bool comment=false);
130static void writeMultiLineCodeLink(yyscan_t yyscanner,OutputCodeList &ol,
131 const Definition *d,
132 const QCString &text);
133static void generateFuncLink(yyscan_t yyscanner,OutputCodeList &ol,const MemberDef* mdef);
134static int countLines(yyscan_t yyscanner);
135static void startFontClass(yyscan_t yyscanner,const char *s,bool specialComment=false);
136static void endFontClass(yyscan_t yyscanner,bool specialComment=false);
137static void appStringLower(QCString& qcs,const char* text);
138static void codifyMapLines(yyscan_t yyscanner,const QCString &text);
139static void writeFuncProto(yyscan_t yyscanner);
140static void writeProcessProto(yyscan_t yyscanner);
141static int yyread(yyscan_t yyscanner,char *buf,int max_size);
142
143[[maybe_unused]] static const char *stateToString(int state);
144//-------------------------------------------------------------------
146
147#undef YY_INPUT
148#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
149
150// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
151static inline const char *getLexerFILE() {return __FILE__;}
152#include "doxygen_lex.h"
The common base class of all entity definitions found in the sources.
Definition definition.h:76
A model of a file symbol.
Definition filedef.h:99
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
Class representing a list of different code generators.
Definition outputlist.h:165
This is an alternative implementation of QCString.
Definition qcstring.h:101
Class that manages the tooltips for a source file.
Definition tooltip.h:26
static void writeMultiLineCodeLink(yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const QCString &text)
Definition code.l:2550
static void endCodeLine(yyscan_t yyscanner)
Definition code.l:2478
static void generateClassOrGlobalLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE, bool varOnly=FALSE)
Definition code.l:2907
static void nextCodeLine(yyscan_t yyscanner)
Definition code.l:2487
static void startCodeLine(yyscan_t yyscanner)
Definition code.l:2409
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2505
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3971
static int countLines(yyscan_t yyscanner)
Definition code.l:3462
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition code.l:2293
static const char * stateToString(int state)
static void startFontClass(yyscan_t yyscanner, const char *s, bool specialComment=false)
Definition code.l:3495
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
Definition code.l:3480
static const char * getLexerFILE()
Definition code.l:263
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition code.l:2277
Web server based search engine.
bool insideCodeLine
Definition vhdlcode.l:96
const Definition * searchCtx
Definition vhdlcode.l:97
int yyLineNr
current line number
Definition vhdlcode.l:95
std::vector< const Definition * > foldStack
Definition vhdlcode.l:117
std::unique_ptr< FileDef > exampleFileDef
Definition vhdlcode.l:105
const MemberDef * vhdlMember
Definition vhdlcode.l:87
QCString funcProto
Definition vhdlcode.l:88
QCString exampleFile
Definition vhdlcode.l:101
OutputCodeList * code
Definition vhdlcode.l:90
TooltipManager tooltipManager
Definition vhdlcode.l:116
QCString PortMapComp
Definition vhdlcode.l:86
int lastCopyCommentContext
Definition vhdlcode.l:112
std::unordered_set< std::string > vhdlKeyDict
Definition vhdlcode.l:84
const Definition * currentDefinition
Definition vhdlcode.l:107
QCString fileName
Definition vhdlcode.l:93
QCString tempComp
Definition vhdlcode.l:85
QCString currClass
Definition vhdlcode.l:83
bool insideSpecialComment
Definition vhdlcode.l:111
int inputPosition
read offset during parsing
Definition vhdlcode.l:92
const FileDef * sourceFileDef
Definition vhdlcode.l:106
const MemberDef * currentMemberDef
Definition vhdlcode.l:108
QCString prevString
Definition vhdlcode.l:82
const char * inputString
the code fragment as text
Definition vhdlcode.l:91
const char * currentFontClass
Definition vhdlcode.l:110
QCString exampleName
Definition vhdlcode.l:100
bool includeCodeFragment
Definition vhdlcode.l:109
int inputLines
number of line in the code fragment
Definition vhdlcode.l:94
A bunch of utility functions.
static void generateMemLink(yyscan_t yyscanner, OutputCodeList &ol, QCString &clName, QCString &memberName)
Definition vhdlcode.l:1340
static void appStringLower(QCString &qcs, const char *text)
Definition vhdlcode.l:1500
static void writeWord(yyscan_t yyscanner, const QCString &word, const QCString &curr_class=QCString(), bool classLink=false)
Definition vhdlcode.l:1146
static bool writeColoredWord(yyscan_t yyscanner, QCString &word)
Definition vhdlcode.l:1612
static void generateFuncLink(yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *mdef)
Definition vhdlcode.l:1324
yyguts_t * yyscan_t
Definition vhdlcode.l:30
static void writeProcessProto(yyscan_t yyscanner)
Definition vhdlcode.l:1603
static void codifyMapLines(yyscan_t yyscanner, const QCString &text)
Definition vhdlcode.l:1508
static bool checkVhdlString(yyscan_t yyscanner, QCString &name)
Definition vhdlcode.l:966
static void writeFuncProto(yyscan_t yyscanner)
Definition vhdlcode.l:1566
static void writeFont(yyscan_t yyscanner, const char *s, const QCString &text, bool specialComment=false)
Definition vhdlcode.l:1488
const char * comment
154%}
155
156
157B [ \t]
158BN [ \t\n\r]
159STRING ["][^"\n]*["]
160NAME [a-z_A-Z][ a-z_A-Z0-9]*
161FUNCNAME [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
162ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
163SPECSIGN [:;, +*&\/=<>'\t]*
164DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
165ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}*
166ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}*
167
168ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}{BN}+("is")
169PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
170
171END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
172END2 [^a-zA-Z_]("end"){BN}*[;]
173END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
174END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
175ENDEFUNC {END3}|{END4}|{END2}
176
177KEYWORD ("of"|"new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
178TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
179FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
180
181ARITHOP "+"|"-"|"/"|"*"|"%"|"/="|":="
182ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
183LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
184BITOP "&"|"|"|"^"|"<<"|">>"|"~"
185OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
186
187PORT {B}*("port"){BN}*("(")
188GENERIC {B}*("generic"){BN}*("(")
189
190BRACEOPEN [(]{1}
191BRACECLOSE [)]{1}
192
193TEXTT {B}*"--"[^\n]*
194
195MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
196MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
197MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
198MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
199
200XILINX "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"
201
202%option noyywrap
203%option nounput
204
205%x Bases
206%x ParseType
207%x ParseFuncProto
208%x ParseComponent
209%x ParsePackage
210%x ParseProcessProto
211%x ClassesName
212%x Map
213%x End
214%x CopyComment
215
216%%
217
218. {
219 BEGIN(Bases);
220 }
221
222<Map>{BRACEOPEN} {
223 yyextra->braceCount++;
224 writeFont(yyscanner,"vhdlchar",yytext);
225 BEGIN(Map);
226 }
227
228<Map>[^()\n,--]* { /* write and link a port map lines */
229 QCString tt(yytext);
231 auto ql = split(tt.str(),"=>");
232 if (ql.size()>=2)
233 {
234 unsigned int index=0;
235 QCString t1(ql[0]);
236 char cc=t1.at(index);
237 while (cc==' ' || cc=='\t')
238 {
239 char c2[2];
240 c2[0]=cc;
241 c2[1]=0;
242 yyextra->code->codify(c2);
243 index++;
244 if (index>=t1.size()) break;
245 cc=t1.at(index);
246 }
247
248 QCString s1=t1;
249 s1=s1.stripWhiteSpace();
250
251 // if (!yyextra->PortMapComp.isEmpty())
252 generateMemLink(yyscanner,*yyextra->code,yyextra->PortMapComp,s1);
253 while (index++<t1.size())
254 {
255 cc=t1.at(index);
256 if (cc==' ' || cc=='\t')
257 {
258 char c2[2];
259 c2[0]=cc;
260 c2[1]=0;
261 yyextra->code->codify(c2);
262 }
263 }
264 codifyLines(yyscanner,"=>");
265 index=0;
266 QCString s2(ql[1]);
267 t1=s2;
268 cc=t1.at(index);
269 while (cc==' ' || cc=='\t')
270 {
271 char c2[2];
272 c2[0]=cc;
273 c2[1]=0;
274 yyextra->code->codify(c2);
275 index++;
276 if (index>=t1.size()) break;
277 cc=t1.at(index);
278 }
279 s2=s2.stripWhiteSpace();
280 if (!checkVhdlString(yyscanner,s2))
281 {
282 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,s2);
283 }
284 while (index++<t1.size())
285 {
286 if (t1.at(index)==' ')
287 {
288 yyextra->code->codify(" ");
289 }
290 }
291 }
292 else
293 {
294 codifyLines(yyscanner,yytext,yyextra->currClass);
295 }
296 BEGIN(Map);
297 }
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
static void deleteAllChars(QCString &s, char c)
StringVector split(const std::string &s, const std::string &delimiter)
split input string s by string delimiter delimiter.
Definition util.cpp:6568
298
299<Map>"\n"|"," {
300 codifyLines(yyscanner,yytext);
301 BEGIN(Map);
302 }
303
304<Map>{BRACECLOSE} {
305 yyextra->braceCount--;
306 writeFont(yyscanner,"vhdlchar",yytext);
307 if (yyextra->braceCount==0)
308 {
309 BEGIN(Bases);
310 }
311 }
312
313<ParseFuncProto>{NAME} {
314 QCString tmp(yytext);
315 tmp=tmp.stripWhiteSpace();
316 appStringLower(yyextra->prevString,yytext);
317 yyextra->vhdlKeyDict.insert(yyextra->prevString.str());
318 if (!writeColoredWord(yyscanner,tmp))
319 {
320 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,tmp);
321 }
322 BEGIN(Bases);
323 }
324
325<ParseType>{STRING} {
326 QCString qcs(yytext);
329 if (VhdlDocGen::isNumber(qcs.str()))
330 {
331 writeFont(yyscanner,"vhdllogic",yytext);
332 }
333 else
334 {
335 writeFont(yyscanner,"keyword",yytext);
336 }
337 }
static bool isNumber(const std::string &s)
338
339<ParseType>"\n" {
340 yyextra->funcProto.append(yytext);
341 if (yyextra->isProto)
342 {
343 codifyLines(yyscanner,yytext);
344 }
345 BEGIN(ParseType);
346 }
347
348
349<ParseType>{TEXTT} {
350 yyextra->funcProto.append(yytext);
351 if (yyextra->isProto)
352 {
353 writeFont(yyscanner,"keyword",yytext);
354 }
355 BEGIN(ParseType);
356 }
357
358<ParseType>{ENDEFUNC} {
359 QCString tt(yytext);
360 codifyLines(yyscanner,yytext,yyextra->currClass);
361 tt=tt.lower();
363 tt.stripWhiteSpace();
364 static const reg::Ex regg(R"(\s+)"); // any number of whitespace
365 auto ql = split(tt.str(),regg);
366 int index=findIndex(ql,"if")+1;
367 index+=findIndex(ql,"case")+1;
368 index+=findIndex(ql,"loop")+1;
369 index+=findIndex(ql,"generate")+1;
370 if (index==0)
371 {
372 BEGIN(Bases);
373 }
374 else
375 {
376 BEGIN(ParseType);
377 }
378 }
Class representing a regular expression.
Definition regex.h:39
int findIndex(const StringVector &sv, const std::string &s)
find the index of a string in a vector of strings, returns -1 if the string could not be found
Definition util.cpp:6604
379
380<ParseType>{END1} {
381 codifyLines(yyscanner,yytext,yyextra->currClass);
382 yyextra->vhdlKeyDict.clear();
383 }
384
385<ParseType>^{B}*("begin "|"begin") {
386 codifyLines(yyscanner,yytext,yyextra->currClass);
387 yyextra->isFuncProto=false;
388 }
389
390<ParseType>{SPECSIGN} {
391 yyextra->funcProto.append(yytext);
392 if (yyextra->isProto)
393 {
394 codifyLines(yyscanner,yytext,yyextra->currClass);
395 }
396 }
397
398<ParseType>["_a-zA-Z0-9]* {
399 QCString val(yytext);
400 yyextra->funcProto.append(yytext);
401 appStringLower(yyextra->prevString,yytext);
402
403 if (yyextra->isFuncProto && yyextra->braceCount==0)
404 {
405 yyextra->vhdlKeyDict.insert(yyextra->prevString.str());
406 }
407
408 if (yyextra->isProto)
409 {
410 if (!writeColoredWord(yyscanner,val))
411 {
412 if (!yyextra->isFuncProto &&
413 yyextra->vhdlKeyDict.find(yyextra->prevString.str())==yyextra->vhdlKeyDict.end())
414 {
415 val=val.stripWhiteSpace();
416 if (VhdlDocGen::isNumber(val.str()))
417 {
418 startFontClass(yyscanner,"vhdllogic");
419 codifyLines(yyscanner,yytext,yyextra->currClass);
420 endFontClass(yyscanner);
421 }
422 else
423 {
424 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,val);
425 }
426 }
427 else
428 {
429 codifyLines(yyscanner,yytext,yyextra->currClass);
430 }
431 }
432 }
433 BEGIN(ParseType);
434 }
435
436<ParseType>{BRACEOPEN} {
437 yyextra->braceCount++;
438 yyextra->funcProto+='(';
439 if (yyextra->isProto)
440 {
441 writeFont(yyscanner,"vhdlchar",yytext);
442 }
443 BEGIN(ParseType);
444 }
445
446<ParseType>{BRACECLOSE} {
447 yyextra->braceCount--;
448 yyextra->funcProto+=')';
449 if (yyextra->isProto)
450 {
451 writeFont(yyscanner,"vhdlchar",yytext);
452 }
453 if (yyextra->braceCount==0 && !yyextra->isProto)// && !yyextra->isPackageBody)
454 {
455 yyextra->isProto=true;
456 appStringLower(yyextra->prevString,yytext);
457 writeFuncProto(yyscanner);
458 BEGIN(Bases);
459 }
460 if (yyextra->isPackageBody)
461 {
462 BEGIN(ParseType);
463 }
464 }
465
466
467<ClassesName>{FUNCNAME} {
468 appStringLower(yyextra->prevString,yytext);
469 yyextra->currClass.clear();
470 yyextra->currClass.append(yytext);
471 yyextra->currClass=yyextra->currClass.stripWhiteSpace();
472
473 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
474 BEGIN(Bases);
475 }
476
477
478<ParseComponent>{BRACEOPEN} {
479 yyextra->braceCount++;
480 yyextra->code->codify(yytext);
481 }
482
483
484<ParseComponent>{BRACECLOSE} {
485 yyextra->braceCount--;
486 yyextra->code->codify(yytext);
487 if (yyextra->braceCount==0 && !yyextra->isComponent)
488 {
489 yyextra->tempComp.clear();
490 BEGIN(Bases);
491 }
492 else
493 {
494 BEGIN(ParseComponent);
495 }
496 }
497
498<ParseComponent>{B}*"-" {
499 if (strlen(yytext)>=2) // found text ?
500 {
501 writeFont(yyscanner,"keyword",yytext);
502 }
503 else
504 {
505 writeFont(yyscanner,"vhdlchar",yytext);
506 }
507 }
508
509<ParseComponent>{SPECSIGN} {
510 codifyLines(yyscanner,yytext);
511 }
512
513
514
515<ParseComponent>"\n"|" " {
516 codifyLines(yyscanner,yytext);
517 }
518
519<ParseComponent>{DIGITSS} {
520 startFontClass(yyscanner,"vhdllogic");
521 codifyLines(yyscanner,yytext);
522 endFontClass(yyscanner);
523 }
524
525<ParseComponent>{PORT} {
526 codifyLines(yyscanner,yytext);
527 yyextra->braceCount=1;
528 yyextra->isComponent=false;
529 }
530
531<ParseComponent>{GENERIC} {
532 codifyLines(yyscanner,yytext);
533 yyextra->braceCount=1;
534 }
535
536<ParseComponent>[_a-zA_Z][_a-zA-Z0-9]* {
537 QCString temp(yytext);
538 appStringLower(yyextra->prevString,yytext);
539 if (!checkVhdlString(yyscanner,temp))
540 {
541 if (!writeColoredWord(yyscanner,yyextra->prevString))
542 {
543 generateMemLink(yyscanner,*yyextra->code,yyextra->tempComp,temp);
544 }
545 }
546 }
547
548<ParseComponent>{STRING} {
549 QCString temp(yytext);
550 if (!checkVhdlString(yyscanner,temp))
551 {
552 codifyLines(yyscanner,yytext);
553 }
554 }
555
556
557<ParseProcessProto>[^()]* {
558 yyextra->funcProto.append(yytext);
559 }
560
561
562
563<ParseProcessProto>{BRACEOPEN} {
564 yyextra->funcProto.append(yytext);
565 yyextra->braceCount++;
566 }
567
568<ParseProcessProto>{BRACECLOSE} {
569 yyextra->funcProto.append(yytext);
570 yyextra->braceCount--;
571 if (yyextra->braceCount==0)
572 {
573 writeProcessProto(yyscanner);
574 BEGIN(Bases);
575 }
576 }
577
578<ParsePackage>[^:;]* { //found package
579 StringVector strl=split(yytext,".");
580 if (strl.size()>2)
581 {
582 QCString s1 = strl[0];
583 QCString s2 = strl[1];
584 QCString s3 = strl[2];
585 s1.append(".");
586 s3.prepend(".");
587 codifyLines(yyscanner,s1,yyextra->currClass);
589 if (cd)
590 {
591 generateClassOrGlobalLink(yyscanner,*yyextra->code,s2);
592 }
593 else
594 {
595 codifyLines(yyscanner,s2);
596 }
597 codifyLines(yyscanner,s3);
598 }
599 else
600 {
601 writeFont(yyscanner,"keywordflow",yytext);
602 }
603 BEGIN(Bases);
604 }
A abstract class representing of a compound symbol.
Definition classdef.h:104
QCString & prepend(const char *s)
Definition qcstring.h:422
QCString & append(char c)
Definition qcstring.h:396
static ClassDef * getPackageName(const QCString &name)
std::vector< std::string > StringVector
Definition containers.h:33
605
606<Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4} { // found port or generic map
607 QCString tt(yytext);
608 int j=tt.find('.');
609
610 if (j>0)
611 {
612 QCString left=tt.left(j+1);
613 codifyLines(yyscanner,left);
614 tt=tt.right(tt.length()-j-1);
615 left=VhdlDocGen::getIndexWord(tt,0);
616 if (!left.isEmpty())
617 {
618 j=left.find('(',false);
619 if (j>=0)
620 {
621 QCString name=left.left(j);
622 generateClassOrGlobalLink(yyscanner,*yyextra->code,name);
623 yyextra->PortMapComp=name;
624 name=tt.right(tt.length()-name.length());
625 codifyLines(yyscanner,name);
626 }
627 else
628 {
629 generateClassOrGlobalLink(yyscanner,*yyextra->code,left);
630 tt.stripPrefix(left); //=tt.right(tt.length()-left.length()-1);
631
632 yyextra->PortMapComp=left;
633 codifyLines(yyscanner,tt);
634 }
635 }
636 }
637 else
638 {
639 if (tt.contains(':',false))
640 {
641 codifyMapLines(yyscanner,tt);
642 }
643 else
644 {
645 codifyLines(yyscanner,tt);
646 }
647 }
648 yyextra->braceCount=1;
649 BEGIN(Map);
650 }
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
QCString right(size_t len) const
Definition qcstring.h:234
QCString left(size_t len) const
Definition qcstring.h:229
static QCString getIndexWord(const QCString &, int index)
651
652<Bases>^{B}*("component"){BN}+{FUNCNAME} { // found component
653 appStringLower(yyextra->prevString,yytext);
654 QCString temp=VhdlDocGen::getIndexWord(yytext,1);
655 temp=temp.stripWhiteSpace();
657 yyextra->tempComp=temp;
658 codifyLines(yyscanner,yytext,temp,true);
659 yyextra->braceCount=0;
660 yyextra->isComponent=true;
661 BEGIN(ParseComponent);
662 }
663
664
665
666<Bases>{ARCHITECTURE} { // found architecture
667 yyextra->PortMapComp.clear();
668 QCString temp = VhdlDocGen::getIndexWord(yytext,3);
669 yyextra->currArch = true;
670 temp+="::";
671 temp+=VhdlDocGen::getIndexWord(yytext,1);
672 yyextra->currClass=temp;
674 codifyLines(yyscanner,yytext,temp,true);
675 yyextra->isPackageBody=false;
676 }
677
678
679<Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body
680 QCString ss(yytext);
681 QCString temp=VhdlDocGen::getIndexWord(yytext,2);
682 StringVector ql=split(yytext,temp.str());
683 QCString ll = ql[0];
684 codifyLines(yyscanner,ll,yyextra->currClass);
685 temp=temp.stripWhiteSpace();
686 temp.prepend("_");
687 generateClassOrGlobalLink(yyscanner,*yyextra->code,temp);
688 yyextra->currClass.clear();
689 yyextra->currClass=temp;
690 yyextra->isProto=false;
691 yyextra->isPackageBody=true;
692 }
const std::string & str() const
Definition qcstring.h:552
693
694<Bases>{PROCESS} { // found process
695 yyextra->isFuncProto=true;
696 yyextra->funcProto.clear();
697 yyextra->funcProto.append(yytext);
698 yyextra->vhdlKeyDict.clear();
699 appStringLower(yyextra->prevString,yytext);
700 if (yyextra->prevString.contains('('))
701 {
702 yyextra->braceCount=1;
703 BEGIN(ParseProcessProto);
704 }
705 else
706 {
707 writeProcessProto(yyscanner);
708 }
709 }
710
711<Bases>("end"){BN}+("process") { // end of process
712 yyextra->isFuncProto=false;
713 codifyLines(yyscanner,yytext);
714 BEGIN(Bases);
715 }
716
717
718<Bases>^{B}*("begin "|"begin") {
719 yyextra->isFuncProto=false;
720 writeFont(yyscanner,"vhdlkeyword",yytext);
721 }
722
723<Bases>^{B}*("use"|"library"){BN}+ { //found package or library
724 writeFont(yyscanner,"vhdlkeyword",yytext);
725 BEGIN(ParsePackage);
726 }
727
728
729<Bases>^{B}*("use"){BN}+("configuration")[^\n]* {
730 codifyLines(yyscanner,yytext);
731 }
732
733<Bases>{FUNC} { // found function|procedure
734 yyextra->vhdlKeyDict.clear();
735 yyextra->funcProto.clear();
736 yyextra->isProto=false;
737 yyextra->funcProto.append(yytext);
738 yyextra->braceCount=1;
739 BEGIN(ParseType);
740 }
741
742<Bases>^{B}*("entity"|"package"){BN}+ {
743 appStringLower(yyextra->prevString,yytext);
744 writeFont(yyscanner,"keywordflow",yytext);
745 yyextra->isPackageBody=false;
746 BEGIN(ClassesName);
747 }
748
749<Bases>"end"{BN}+"architecture"{BN}+{FUNCNAME} {
750 codifyLines(yyscanner,yytext,yyextra->currClass,true);
751 yyextra->currArch = false;
752 }
753<Bases>"end"{BN}+{FUNCNAME} {
754 if (yyextra->currArch)
755 {
756 codifyLines(yyscanner,yytext,yyextra->currClass,true);
757 yyextra->currArch = false;
758 }
759 else
760 {
761 REJECT;
762 }
763 }
764<Bases>"end" {
765 appStringLower(yyextra->prevString,yytext);
766 QCString temp(yytext);
767 temp=temp.stripWhiteSpace();
768
769 writeColoredWord(yyscanner,temp);
770 BEGIN(End);
771 }
772<End>{ID} {
773 appStringLower(yyextra->prevString,yytext);
774 QCString temp(yytext);
775 temp=temp.stripWhiteSpace();
776
777 if (!writeColoredWord(yyscanner,temp))
778 {
779 generateClassOrGlobalLink(yyscanner,*yyextra->code,temp);
780 }
781 }
782<End>";" {
783 codifyLines(yyscanner,yytext);
784 BEGIN(Bases);
785 }
786<Bases>{KEYWORD} { // found keyword
787 QCString qcs(yytext);
788 if (!writeColoredWord(yyscanner,qcs))
789 {
790 startFontClass(yyscanner,"vhdlchar");
791 yyextra->code->codify(yytext);
792 endFontClass(yyscanner);
793 }
794 }
795
796
797<Bases>{ID} {
798 appStringLower(yyextra->prevString,yytext);
799 QCString temp(yytext);
800 temp=temp.stripWhiteSpace();
801
802 if (!writeColoredWord(yyscanner,temp))
803 {
804 startFontClass(yyscanner,"vhdlchar");
805 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,temp);
806 endFontClass(yyscanner);
807 }
808 }
809
810<Bases,ParseComponent>{DIGITSS} {
811 startFontClass(yyscanner,"vhdllogic");
812 codifyLines(yyscanner,yytext);
813 endFontClass(yyscanner);
814 }
815
816<Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* {
817 codifyLines(yyscanner,yytext,yyextra->currClass,true);
818 }
819
820
821<Bases>{TYPEKW} {
822 codifyLines(yyscanner,yytext);
823 if (yyextra->isFuncProto)
824 {
825 BEGIN(ParseFuncProto);
826 }
827 else
828 {
829 BEGIN(Bases);
830 }
831 }
832
833<Bases>{OPERATOR} {
834 startFontClass(yyscanner,"vhdlchar");
835 yyextra->code->codify(yytext);
836 endFontClass(yyscanner);
837 }
838
839<Bases>","|"."|":"|"'"|"("|")" {
840 startFontClass(yyscanner,"vhdlchar");
841 yyextra->code->codify(yytext);
842 endFontClass(yyscanner);
843 }
844
845<Bases>{STRING} {
846 QCString qcs(yytext);
849
850 if (VhdlDocGen::isNumber(qcs.str()))
851 {
852 writeFont(yyscanner,"vhdllogic",yytext);
853 }
854 else
855 {
856 writeFont(yyscanner,"keyword",yytext);
857 }
858 }
859
860<Bases>{B}*"#"[^\n]* {
861 writeFont(yyscanner,"keyword",yytext);
862 }
863
864<Bases>^{B}*{XILINX}/[^a-zA-Z0-9_] {
865 writeWord(yyscanner,yytext);
866 //codifyLines(yyscanner,yytext,yyextra->currClass,true);
867 }
868
869<Bases>^{B}*"set_"[^\n]* {
870 writeWord(yyscanner,yytext);
871 }
872
873<*>\n {
874 codifyLines(yyscanner,yytext);
875 BEGIN(Bases);
876 }
877
878<*>[\x80-\xFF]* { // keep utf8 characters together...
879 yyextra->code->codify(yytext);
880 }
881<*>. {
882 yyextra->code->codify(yytext);
883 }
884
885
886<*>\n?"--!"[^\n]*/\n{B}*"--!" { // found special multi-line comment on its own line
887 if (YY_START!=CopyComment)
888 {
889 startFontClass(yyscanner,"comment",true);
890 yyextra->lastCopyCommentContext=YY_START;
891 BEGIN(CopyComment);
892 }
893 codifyLines(yyscanner,yytext,QCString(),false,true);
894 }
895<*>\n{TEXTT} { // found normal or special comment on its own line
896 QCString text(yytext);
897 int i=text.find("--");
898 bool isSpecialComment = i!=-1 && yytext[i+2]=='!';
899 if (isSpecialComment && YY_START!=CopyComment)
900 {
901 startFontClass(yyscanner,"comment",true);
902 }
903 codifyLines(yyscanner,text,QCString(),false,true);
904 if (isSpecialComment)
905 {
906 endFontClass(yyscanner,true);
907 }
908 if (YY_START==CopyComment)
909 {
910 BEGIN(yyextra->lastCopyCommentContext);
911 }
912 }
913<*>{TEXTT} { // found normal or special comment after something
914 QCString text(yytext);
915 int i=text.find("--");
916 bool isSpecialComment = i!=-1 && yytext[i+2]=='!';
917 if (isSpecialComment)
918 {
919 startFontClass(yyscanner,"comment",true);
920 }
921 codifyLines(yyscanner,yytext,QCString(),false,true);
922 if (isSpecialComment)
923 {
924 endFontClass(yyscanner,true);
925 }
926 }
927
928%%
929
930/*@ ----------------------------------------------------------------------------
931 */
932
933static int yyread(yyscan_t yyscanner,char *buf,int max_size)
934{
935 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
936 int inputPosition = yyextra->inputPosition;
937 const char *s = yyextra->inputString + inputPosition;
938 int c=0;
939 while( c < max_size && *s)
940 {
941 *buf++ = *s++;
942 c++;
943 }
944 yyextra->inputPosition += c;
945 return c;
946}
947
948static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
949{
950 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
951 if (Doxygen::searchIndex.enabled())
952 {
953 if (yyextra->searchCtx)
954 {
955 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
956 }
957 else
958 {
959 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,true);
960 }
961 }
962}
963
964static bool checkVhdlString(yyscan_t yyscanner,QCString &name)
965{
966 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
967 if (name.isEmpty()) return false;
968
969 size_t len=name.length();
970 if (len>2 && name.at(0)=='"' && name.at(len-1)=='"')
971 {
972 QCString inside = name.mid(1,len-2);
973 static const reg::Ex regg(R"(\s+)"); // any number of whitespace
974 auto qrl=split(inside.str(),regg);
975 if (!qrl.empty() && VhdlDocGen::isNumber(qrl[0]))
976 {
977 yyextra->code->codify("\"");
978 startFontClass(yyscanner,"vhdllogic");
979 yyextra->code->codify(inside);
980 endFontClass(yyscanner);
981 yyextra->code->codify("\"");
982 }
983 else
984 {
985 startFontClass(yyscanner,"keyword");
986 yyextra->code->codify(name);
987 endFontClass(yyscanner);
988 }
989 return true;
990 }
991
992 if (VhdlDocGen::isNumber(name.str()))
993 {
994 startFontClass(yyscanner,"vhdllogic");
995 yyextra->code->codify(name);
996 endFontClass(yyscanner);
997 return true;
998 }
999 return false;
1000}
1001
1002static void addToSearchIndex(yyscan_t /*yyscanner*/,const QCString &text)
1003{
1005 {
1006 Doxygen::searchIndex.addWord(text,false);
1007 }
1008}
1009
1010static void codeFolding(yyscan_t yyscanner,const Definition *d)
1011{
1012 // TODO: the VHDL parse doesn't seem to record startLine and endBodyLine for many of the constructs, preventing folding from working.
1013 if (Config_getBool(HTML_CODE_FOLDING))
1014 {
1015 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1016 while (!yyextra->foldStack.empty())
1017 {
1018 const Definition *dd = yyextra->foldStack.back();
1019 if (dd->getEndBodyLine()+1==yyextra->yyLineNr) // +1 to close the section after the end of the body
1020 {
1021 yyextra->code->endFold();
1022 //printf("%d: end codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(dd->name()),dd->getStartDefLine(),dd->getEndBodyLine());
1023 yyextra->foldStack.pop_back();
1024 }
1025 else
1026 {
1027 break;
1028 }
1029 }
1030 if (d)
1031 {
1032 int startLine = d->getStartDefLine();
1033 int endLine = d->getEndBodyLine();
1034 if (endLine!=-1 && startLine!=endLine && (yyextra->foldStack.empty() || yyextra->foldStack.back()->getEndBodyLine()!=startLine))
1035 {
1036 //printf("%d: start codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->name()),d->getStartDefLine(),d->getEndBodyLine());
1037 yyextra->code->startFold(yyextra->yyLineNr,"","");
1038 yyextra->foldStack.push_back(d);
1039 }
1040 }
1041 }
1042}
1043
1044/*! start a new line of code, inserting a line number if yyextra->sourceFileDef
1045 * is true. If a definition starts at the current line, then the line
1046 * number is linked to the documentation of that definition.
1047 */
1048static void startCodeLine(yyscan_t yyscanner)
1049{
1050 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1051 //if (yyextra->currentFontClass) { yyextra->code->endFontClass(); }
1052 if (yyextra->sourceFileDef)
1053 {
1054 //QCString lineNumber,lineAnchor;
1055 //lineNumber.sprintf("%05d",yyextra->yyLineNr);
1056 //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
1057 // if ((yyextra->yyLineNr % 500) == 0)
1058 // fprintf(stderr,"\n starting Line %d:",yyextra->yyLineNr);
1059 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
1060 //printf("startCodeLine %d d=%s\n", yyextra->yyLineNr,qPrint(d ? d->name()) : "<null>");
1061 if (!yyextra->includeCodeFragment && d)
1062 {
1063 yyextra->currentDefinition = d;
1064 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
1065 if (!yyextra->tempComp.isEmpty() && yyextra->currentMemberDef )
1066 {
1067 //ClassDef *cf=VhdlDocGen::getClass(yyextra->tempComp);
1068 QCString nn=yyextra->currentMemberDef->name();
1069 const MemberDef* mdeff=VhdlDocGen::findMember(yyextra->tempComp,nn);
1070 if (mdeff)
1071 {
1072 yyextra->currentMemberDef=mdeff;
1073 }
1074 }
1075
1076 QCString lineAnchor;
1077 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
1078 if (yyextra->currentMemberDef)
1079 {
1080 codeFolding(yyscanner,yyextra->currentMemberDef);
1081 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
1082 yyextra->currentMemberDef->getOutputFileBase(),
1083 yyextra->currentMemberDef->anchor(),yyextra->yyLineNr,
1084 !yyextra->includeCodeFragment);
1085 setCurrentDoc(yyscanner,lineAnchor);
1086 }
1087 else if (d->isLinkableInProject())
1088 {
1089 codeFolding(yyscanner,yyextra->currentMemberDef);
1090 yyextra->code->writeLineNumber(d->getReference(),
1091 d->getOutputFileBase(),
1092 QCString(),yyextra->yyLineNr,
1093 !yyextra->includeCodeFragment);
1094 setCurrentDoc(yyscanner,lineAnchor);
1095 }
1096 else
1097 {
1098 codeFolding(yyscanner,nullptr);
1099 }
1100 }
1101 else
1102 {
1103 codeFolding(yyscanner,nullptr);
1104 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
1105 !yyextra->includeCodeFragment);
1106 }
1107 }
1108 yyextra->code->startCodeLine(yyextra->yyLineNr);
1109 yyextra->insideCodeLine=true;
1110 if (yyextra->currentFontClass)
1111 {
1112 yyextra->code->startFontClass(yyextra->currentFontClass);
1113 }
1114}
1115
1116static void endCodeLine(yyscan_t yyscanner)
1117{
1118 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1119 endFontClass(yyscanner);
1120 yyextra->code->endCodeLine();
1121 yyextra->insideCodeLine=false;
1122}
1123
1124static void nextCodeLine(yyscan_t yyscanner)
1125{
1126 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1127 if (yyextra->insideCodeLine)
1128 {
1129 endCodeLine(yyscanner); // </div>
1130 }
1131 const char *fc = yyextra->currentFontClass;
1132 if (yyextra->yyLineNr<yyextra->inputLines)
1133 {
1134 yyextra->currentFontClass = fc;
1135 startCodeLine(yyscanner); //<div>
1136 }
1137}
1138
1139/*! writes a word to the output.
1140 * If curr_class is defined, the word belongs to a class
1141 * and will be linked.
1142 */
1143
1144static void writeWord(yyscan_t yyscanner,const QCString &word,const QCString &curr_class,bool classLink)
1145{
1146 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1147 bool found=false;
1148 QCString temp;
1149 QCString tclass(curr_class);
1150 QCString ttt(word);
1151 if (ttt.isEmpty()) return;
1152 for (unsigned int j=0;j<ttt.length();j++)
1153 {
1154 char c=ttt.at(j);
1155 if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
1156 {
1157 if (found)
1158 {
1159 if (!writeColoredWord(yyscanner,temp)) // is it a keyword ?
1160 {
1161 //if (VhdlDocGen::findKeyWord(temp))
1162 // writeFont(yyscanner,"vhdlkeyword",temp);
1163 //printf("writeWord: %s\n",qPrint(temp));
1164 if (!tclass.isEmpty())
1165 {
1166 if (!classLink)
1167 {
1168 generateMemLink(yyscanner,*yyextra->code,tclass,temp);
1169 }
1170 else
1171 {
1172 generateClassOrGlobalLink(yyscanner,*yyextra->code,temp,false,curr_class);
1173 }
1174 }
1175 else
1176 {
1177 if (!checkVhdlString(yyscanner,temp))
1178 {
1179 yyextra->code->codify(temp);
1180 }
1181 }
1182 }
1183 temp.clear();
1184 found=false;
1185 }
1186
1187 char cc[2];
1188 cc[0]=c;
1189 cc[1]=0;
1190 yyextra->code->codify(cc);
1191 }
1192 else
1193 {
1194 found=true;
1195 temp+=c;
1196 }
1197 } // for
1198
1199 if (!temp.isEmpty())
1200 {
1201 if (!writeColoredWord(yyscanner,temp))
1202 {
1203 if (!tclass.isEmpty())
1204 {
1205 if (!classLink)
1206 {
1207 generateMemLink(yyscanner,*yyextra->code,tclass,temp); // generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,left);
1208 }
1209 else
1210 {
1211 generateClassOrGlobalLink(yyscanner,*yyextra->code,temp,false,curr_class);
1212 }
1213 }
1214 else
1215 {
1216 QCString qc(temp);
1217 if (VhdlDocGen::isNumber(qc.str()))
1218 {
1219 startFontClass(yyscanner,"vhdllogic");
1220 yyextra->code->codify(temp);
1221 endFontClass(yyscanner);
1222 }
1223 else
1224 {
1225 yyextra->code->codify(temp);
1226 }
1227 }
1228 }
1229 }
1230}// writeWord
1231
1232
1233/*! write a code fragment 'text' that may span multiple lines, inserting
1234 * line numbers for each line.
1235 */
1236static void codifyLines(yyscan_t yyscanner,const QCString &text,const QCString &cl,bool classlink,bool comment)
1237{
1238 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1239 if (text.isEmpty()) return;
1240 //printf("codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,text);
1241 const char *p=text.data(),*sp=p;
1242 char c;
1243 bool done=false;
1244 while (!done)
1245 {
1246 sp=p;
1247 while ((c=*p++) && c!='\n') {}
1248 if (c=='\n')
1249 {
1250 yyextra->yyLineNr++;
1251 QCString line = sp;
1252 line = line.left((int)(p-sp)-1);
1253 if (comment)
1254 {
1255 writeFont(yyscanner,"comment",line);
1256 }
1257 else
1258 {
1259 writeWord(yyscanner,line,cl,classlink);
1260 }
1261 nextCodeLine(yyscanner);
1262 }
1263 else
1264 {
1265 if (comment)
1266 {
1267 writeFont(yyscanner,"comment",sp);
1268 }
1269 else
1270 {
1271 writeWord(yyscanner,sp,cl,classlink);
1272 }
1273 done=true;
1274 }
1275 }
1276}
1277
1278/*! writes a link to a fragment \a text that may span multiple lines, inserting
1279 * line numbers for each line. If \a text contains newlines, the link will be
1280 * split into multiple links with the same destination, one for each line.
1281 */
1282static void writeMultiLineCodeLink(yyscan_t yyscanner,OutputCodeList &ol,
1283 const Definition *d,
1284 const QCString &text)
1285{
1286 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1287 if (text.isEmpty()) return;
1288 bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
1289 yyextra->tooltipManager.addTooltip(d);
1290 QCString ref = d->getReference();
1291 QCString file = d->getOutputFileBase();
1292 QCString anchor = d->anchor();
1293 QCString tooltip;
1294 if (!sourceTooltips) // fall back to simple "title" tooltips
1295 {
1296 tooltip = d->briefDescriptionAsTooltip();
1297 }
1298 bool done=false;
1299 const char *p=text.data();
1300 while (!done)
1301 {
1302 const char *sp=p;
1303 char c;
1304 while ((c=*p++) && c!='\n') {}
1305 if (c=='\n')
1306 {
1307 yyextra->yyLineNr++;
1308 // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
1309 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip);
1310 nextCodeLine(yyscanner);
1311 }
1312 else
1313 {
1314 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,sp,tooltip);
1315 done=true;
1316 }
1317 }
1318}
1319
1320/*! writes a link to a function or procedure
1321 */
1322static void generateFuncLink(yyscan_t yyscanner,OutputCodeList &ol,const MemberDef* mdef)
1323{
1324 //printf("generateFuncLink(FuncName=%s)\n",qPrint(mdef->name()));
1325 QCString memberName=mdef->name();
1326
1327 if (mdef->isLinkable()) // is it a linkable class
1328 {
1329 writeMultiLineCodeLink(yyscanner,ol,mdef,mdef->name());
1330 addToSearchIndex(yyscanner,memberName);
1331 return;
1332 }
1333 codifyLines(yyscanner,memberName);
1334 addToSearchIndex(yyscanner,memberName);
1335} // generateFuncLink
1336
1337
1338static void generateMemLink(yyscan_t yyscanner,OutputCodeList &ol,QCString &clName,QCString& memberName)
1339{
1340 if (memberName.isEmpty()) return;
1341 if (clName.isEmpty())
1342 {
1343 codifyLines(yyscanner,memberName);
1344
1345 return;
1346 }
1347
1348 QCString className=clName;
1349
1350 //MemberDef *comp=nullptr;
1351 //bool isLocal=false;
1352
1353 const MemberDef *md=VhdlDocGen::findMember(className,memberName);
1354 ClassDef *po=VhdlDocGen::getClass(className);
1355
1356 if (md==nullptr && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS)
1357 {
1358 QCString temp=className;//.stripPrefix("_");
1359 temp.stripPrefix("_");
1360 md=VhdlDocGen::findMember(temp,memberName);
1361 }
1362
1363 if (md && md->isLinkable()) // is it a linkable class
1364 {
1365 writeMultiLineCodeLink(yyscanner,ol,md,memberName);
1366 addToSearchIndex(yyscanner,memberName);
1367 return;
1368 }
1369 // nothing found, just write out the word
1370 codifyLines(yyscanner,memberName);
1371 addToSearchIndex(yyscanner,memberName);
1372}// generateMemLink
1373
1374
1375static void generateClassOrGlobalLink(yyscan_t yyscanner,OutputCodeList &ol,
1376 const QCString &clName, bool /*typeOnly*/, const QCString &curr_class)
1378 QCString className=clName;
1379
1380 if (className.isEmpty()) return;
1381
1382 ClassDef *cd=nullptr;
1383 //MemberDef *md=nullptr;
1384 //bool isLocal=false;
1385 className.stripPrefix("_");
1386 cd = getClass(className);
1387 if (!cd && !curr_class.isEmpty())
1388 {
1389 QCString cls = curr_class;
1390 QCString suffix = "::";
1391 suffix+=clName;
1392 if (cls.right(suffix.length())==suffix)
1393 {
1394 cd = getClass(curr_class);
1395 }
1396 }
1397
1398 while (cd)
1399 {
1400 //className.stripPrefix("_");
1401 QCString temp(clName);
1402 temp.stripPrefix("_");
1403 if (cd && cd->isLinkable()) // is it a linkable class
1404 {
1405 //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
1406 //{
1407 // temp=VhdlDocGen::getClassName(cd);
1408 //}
1409 writeMultiLineCodeLink(yyscanner,ol,cd,temp);
1410 addToSearchIndex(yyscanner,className);
1411 return;
1412 }
1413 Definition *d = cd->getOuterScope();
1415 {
1416 cd = toClassDef(d);
1417 }
1418 else
1419 {
1420 cd = nullptr;
1421 }
1422 }
1423
1424 // nothing found, just write out the word
1425 codifyLines(yyscanner,clName);
1426 addToSearchIndex(yyscanner,clName);
1427}// generateClasss or global link
1428
1429
1430/*! counts the number of lines in the input */
1431static int countLines(yyscan_t yyscanner)
1432{
1433 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1434 const char *p=yyextra->inputString;
1435 char c;
1436 int count=1;
1437 while ((c=*p))
1438 {
1439 p++ ;
1440 if (c=='\n') count++;
1441 }
1442 if (p>yyextra->inputString && *(p-1)!='\n')
1443 { // last line does not end with a \n, so we add an extra
1444 // line and explicitly terminate the line after parsing.
1445 count++;
1446 }
1447 return count;
1448}
1449
1450static void endFontClass(yyscan_t yyscanner,bool specialComment)
1451{
1452 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1453 //printf("endFontClass: specialComment=%d insideSpecialComment=%d\n",
1454 // specialComment,yyextra->insideSpecialComment);
1455 if (yyextra->currentFontClass)
1456 {
1457 yyextra->code->endFontClass();
1458 yyextra->currentFontClass=0;
1459 }
1460 if (specialComment && yyextra->insideSpecialComment)
1461 {
1462 yyextra->code->endSpecialComment();
1463 yyextra->insideSpecialComment=false;
1464 }
1465}
1466
1467static void startFontClass(yyscan_t yyscanner,const char *s,bool specialComment)
1468{
1469 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1470 if (s==nullptr) return;
1471 //printf("startFontClass(%s): specialComment=%d insideSpecialComment=%d\n",s,
1472 // specialComment,yyextra->insideSpecialComment);
1473 if (specialComment)
1474 {
1475 yyextra->code->startSpecialComment();
1476 yyextra->insideSpecialComment = true;
1477 }
1478 if (qstrcmp(yyextra->currentFontClass,s)!=0)
1479 {
1480 endFontClass(yyscanner);
1481 yyextra->code->startFontClass(s);
1482 yyextra->currentFontClass=s;
1483 }
1484}
1485
1486static void writeFont(yyscan_t yyscanner,const char *s,const QCString &text,bool specialComment)
1487{
1488 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1489 if (s==nullptr || text.isEmpty()) return;
1490 //printf("writeFont(yyscanner,%d,\"%s\")\n",yyextra->yyLineNr,text);
1491 startFontClass(yyscanner,s,specialComment);
1492 yyextra->code->codify(text);
1493 endFontClass(yyscanner,specialComment);
1494}
1495
1496//----------------------------------------------------------------------------
1497
1498static void appStringLower(QCString& qcs,const char* text)
1499{
1500 qcs.clear();
1501 qcs.append(text);
1502 qcs=qcs.stripWhiteSpace();
1503}
1504
1505/* writes and links a port map statement */
1506static void codifyMapLines(yyscan_t yyscanner,const QCString &text)
1507{
1508 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1509 if (text.isEmpty()) return;
1510 QCString temp;
1511 //bool dot=false;
1512 int wordCounter=0;
1513 QCString ctemp;
1514 //printf("codifyMapLines(%d,\"%s\")\n",yyextra->yyLineNr,qPrint(text));
1515 const char *p=text.data();
1516 char c;
1517 bool done=false;
1518 while (!done)
1519 {
1520 //sp=p;
1521 while ((c=*p++) && c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
1522 {
1523 if (c!=0x9)
1524 temp+=c;
1525 }
1526 if (c=='\0') return;
1527 if (!temp.isEmpty()) wordCounter++;
1528
1529 if (!temp.isEmpty())
1530 {
1531 // different kinds of component instantiations
1532 // xxx:yyy (generic/port) map(
1533 // xxx:(entity/component/configuration) yyy (generic/port) map(
1534 // xxx: entity yyy(zzz) (generic/port) map(
1535 if (wordCounter==2 || wordCounter==3)
1536 {
1537 QCString q=temp.lower(); // consider (upper/lower) cases
1538 if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
1539 {
1540 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,temp);
1541 }
1542 else
1543 {
1544 yyextra->PortMapComp=temp;
1545 generateClassOrGlobalLink(yyscanner,*yyextra->code,temp);
1546 }
1547 }
1548 else
1549 {
1550 generateMemLink(yyscanner,*yyextra->code,yyextra->currClass,temp);
1551 }
1552 }
1553 ctemp.fill(c,1);
1554 codifyLines(yyscanner,ctemp);
1555 ctemp.clear();
1556 temp.clear();
1557 }//while
1558}//codifyMapLines
1559
1560/*
1561* writes a function|procedure prototype and links the function|procedure name
1562*/
1563
1564static void writeFuncProto(yyscan_t yyscanner)
1565{
1566 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1567 QCString name,ret;
1568 VhdlDocGen::parseFuncProto(yyextra->funcProto,name,ret,false);
1569
1570 if (name.isEmpty())
1571 {
1572 codifyLines(yyscanner,yyextra->funcProto,yyextra->currClass);
1573 return;
1574 }
1575 StringVector qlist=split(yyextra->funcProto.str(),name.str());
1576 QCString temp(qlist[0]);
1577 codifyLines(yyscanner,temp,yyextra->currClass);
1578 yyextra->funcProto.stripPrefix(temp);
1579 temp.clear();
1580 temp=yyextra->currClass;
1581 if (yyextra->isPackageBody)
1582 {
1583 temp.stripPrefix("_");// _{package body name}
1584 }
1585 const MemberDef *mdef=VhdlDocGen::findFunction(name,temp);
1586
1587 if (mdef)
1588 {
1589 generateFuncLink(yyscanner,*yyextra->code,mdef);
1590 yyextra->funcProto.stripPrefix(name);
1591 codifyLines(yyscanner,yyextra->funcProto,yyextra->currClass);
1592 }
1593 else
1594 {
1595 codifyLines(yyscanner,yyextra->funcProto,yyextra->currClass);
1596 }
1597}// writeFuncProto
1598
1599/* writes a process prototype to the output */
1600
1601static void writeProcessProto(yyscan_t yyscanner)
1602{
1603 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1604 codifyLines(yyscanner,yyextra->funcProto,yyextra->currClass);
1605 yyextra->vhdlKeyDict.clear();
1606}// writeProcessProto
1607
1608/* writes a keyword */
1609
1610static bool writeColoredWord(yyscan_t yyscanner,QCString& word )
1611{
1612 QCString qcs=word.lower();
1613 const char *ss=VhdlDocGen::findKeyWord(qcs);
1614 if (ss)
1615 {
1616 writeFont(yyscanner,ss,word);
1617 return true;
1618 }
1619 return false;
1620}
1621
1622//-----------------------------------------------------------------------------------
1623
1625{
1631{
1632 vhdlcodeYYlex_init_extra(&p->state,&p->yyscanner);
1633#ifdef FLEX_DEBUG
1634 vhdlcodeYYset_debug(Debug::isFlagSet(Debug::Lex_vhdlcode)?1:0,p->yyscanner);
1635#endif
1637}
1638
1640{
1641 vhdlcodeYYlex_destroy(p->yyscanner);
1642}
1643
1645{
1646 p->state.vhdlKeyDict.clear();
1647}
1648
1650 const QCString &/* className */,
1651 const QCString &s,
1652 SrcLangExt,
1653 bool stripCodeComments,
1654 const CodeParserOptions &options
1655 )
1656{
1657 yyscan_t yyscanner = p->yyscanner;
1658 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1659 //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1660 if (s.isEmpty()) return;
1661 DebugLex debugLex(Debug::Lex_vhdlcode, __FILE__, options.fileDef() ? qPrint(options.fileDef()->fileName()): nullptr);
1662 yyextra->fileName = options.fileDef() ? options.fileDef()->fileName():"";
1663 if (options.memberDef())
1664 {
1665 const ClassDef *dd=options.memberDef()->getClassDef();
1666 if (dd) yyextra->currClass = dd->name();
1667 }
1668 od.stripCodeComments(stripCodeComments);
1670 yyextra->code = &od;
1671 yyextra->inputString = s.data();
1672 yyextra->inputPosition = 0;
1673 yyextra->currentFontClass = nullptr;
1674 yyextra->insideCodeLine = false;
1675 yyextra->searchCtx = options.searchCtx();
1676 yyextra->insideSpecialComment = false;
1677 yyextra->yyLineNr = options.startLine()!=-1 ? options.startLine() : 1;
1678 yyextra->inputLines = options.endLine()!=-1 ? options.endLine()+1 : yyextra->yyLineNr + countLines(yyscanner) - 1;
1679 yyextra->foldStack.clear();
1680
1681 // yyextra->theCallContext.clear();
1682 yyextra->exampleBlock = options.isExample();
1683 yyextra->exampleName = options.exampleName();
1684 yyextra->sourceFileDef = options.fileDef();
1685 if (options.isExample() && options.fileDef()==nullptr)
1686 {
1687 // create a dummy filedef for the example
1688 yyextra->exampleFileDef = createFileDef("",options.exampleName());
1689 yyextra->sourceFileDef = yyextra->exampleFileDef.get();
1690 }
1691 if (yyextra->sourceFileDef)
1692 {
1693 setCurrentDoc(yyscanner,"l00001");
1694 }
1695 yyextra->currentDefinition = nullptr;
1696 yyextra->currentMemberDef = nullptr;
1697 yyextra->vhdlMember = nullptr;
1698 if (!yyextra->exampleName.isEmpty())
1699 {
1700 yyextra->exampleFile = convertNameToFile(yyextra->exampleName+"-example");
1701 }
1702 yyextra->includeCodeFragment = options.inlineFragment();
1703 startCodeLine(yyscanner);
1704 if (!yyextra->lexInit)
1705 {
1707 yyextra->lexInit=true;
1708 }
1709 vhdlcodeYYrestart( nullptr, yyscanner );
1710 BEGIN( Bases );
1711 vhdlcodeYYlex(yyscanner);
1712 if (yyextra->insideCodeLine)
1713 {
1714 endCodeLine(yyscanner);
1715 }
1716 if (Config_getBool(HTML_CODE_FOLDING))
1717 {
1718 while (!yyextra->foldStack.empty())
1719 {
1720 yyextra->code->endFold();
1721 yyextra->foldStack.pop_back();
1722 }
1723 }
1724 if (yyextra->exampleFileDef)
1725 {
1726 // delete the temporary file definition used for this example
1727 yyextra->exampleFileDef.reset();
1728 yyextra->sourceFileDef = nullptr;
1729 }
1730
1731 // write the tooltips
1732 yyextra->tooltipManager.writeTooltips(od);
1733}
1734
1735#include "vhdlcode.l.h"
virtual Protection protection() const =0
Return the protection level (Public,Protected,Private) in which this compound was found.
@ Lex_vhdlcode
Definition debug.h:69
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
virtual int getEndBodyLine() const =0
virtual bool isLinkable() const =0
virtual DefType definitionType() const =0
virtual QCString anchor() const =0
virtual QCString briefDescriptionAsTooltip() const =0
virtual bool isLinkableInProject() const =0
virtual int getStartDefLine() const =0
virtual QCString getReference() const =0
virtual CodeSymbolType codeSymbolType() const =0
virtual QCString getOutputFileBase() const =0
virtual Definition * getOuterScope() const =0
virtual const QCString & name() const =0
static SearchIndexIntf searchIndex
Definition doxygen.h:123
virtual QCString fileName() const =0
virtual const ClassDef * getClassDef() const =0
void writeCodeLink(CodeSymbolType type, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip)
Definition outputlist.h:250
void stripCodeComments(bool b)
Definition outputlist.h:238
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:241
QCString lower() const
Definition qcstring.h:249
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:593
QCString fill(char c, int len=-1)
Fills a string with a predefined character.
Definition qcstring.h:193
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:172
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:213
void clear()
Definition qcstring.h:182
void resetCodeParserState() override
Resets the state of the code parser.
Definition vhdlcode.l:1646
void parseCode(OutputCodeList &codeOutIntf, const QCString &scopeName, const QCString &input, SrcLangExt lang, bool stripCodeComments, const CodeParserOptions &options) override
Parses a source file or fragment with the goal to produce highlighted and cross-referenced output.
Definition vhdlcode.l:1651
~VHDLCodeParser() override
Definition vhdlcode.l:1641
std::unique_ptr< Private > p
Definition vhdlcode.h:42
static const MemberDef * findFunction(const QCString &name, const QCString &package)
static void init()
static void parseFuncProto(const QCString &text, QCString &name, QCString &ret, bool doc=false)
static ClassDef * getClass(const QCString &name)
static const MemberDef * findMember(const QCString &className, const QCString &memName)
static const char * findKeyWord(const QCString &word)
ClassDef * getClass(const QCString &n)
ClassDef * toClassDef(Definition *d)
static void codeFolding(yyscan_t yyscanner, const Definition *d)
Definition code.l:2351
#define Config_getBool(name)
Definition config.h:33
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:268
const char * qPrint(const char *s)
Definition qcstring.h:687
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
Options to configure the code parser.
Definition parserintf.h:78
bool isExample() const
Definition parserintf.h:81
const Definition * searchCtx() const
Definition parserintf.h:89
const FileDef * fileDef() const
Definition parserintf.h:83
int endLine() const
Definition parserintf.h:85
const MemberDef * memberDef() const
Definition parserintf.h:87
bool inlineFragment() const
Definition parserintf.h:86
QCString exampleName() const
Definition parserintf.h:82
int startLine() const
Definition parserintf.h:84
vhdlcodeYY_state state
Definition vhdlcode.l:1629
SrcLangExt
Definition types.h:207
QCString convertNameToFile(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3446