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