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