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