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