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