Doxygen
Loading...
Searching...
No Matches
xmlcode.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 XML
17 * written by Weston Thayer
18 ******************************************************************************/
19
20%option never-interactive
21%option prefix="xmlcodeYY"
22%option reentrant
23%option extra-type="struct xmlcodeYY_state *"
24%option noyy_top_state
25%option nounput
26%option noyywrap
27%top{
28#include <stdint.h>
29// forward declare yyscan_t to improve type safety
30#define YY_TYPEDEF_YY_SCANNER_T
31struct yyguts_t;
32typedef yyguts_t *yyscan_t;
yyguts_t * yyscan_t
Definition code.l:24
33}
34
35%{
36
37#include <stdio.h>
38
39#include "xmlcode.h"
40
41#include "entry.h"
42#include "doxygen.h"
43#include "outputlist.h"
44#include "util.h"
45#include "membername.h"
46#include "searchindex.h"
47#include "config.h"
48#include "filedef.h"
49#include "tooltip.h"
50#include "message.h"
51#include "debug.h"
52
53#define YY_NEVER_INTERACTIVE 1
54#define YY_NO_INPUT 1
55#define YY_NO_UNISTD_H 1
56
58{
63 const char * inputString = nullptr; //!< the code fragment as text
64 int inputPosition = 0; //!< read offset during parsing
66 int inputLines = 0; //!< number of line in the code fragment
67 int yyLineNr = 0; //!< current line number
68 bool insideCodeLine = false;
69 const Definition *searchCtx = nullptr;
70
71 bool stripCodeComments = true;
72 bool exampleBlock = false;
75
80
82
83 std::unique_ptr<FileDef> exampleFileDef;
84 const FileDef * sourceFileDef = nullptr;
86 const Definition * currentDefinition = nullptr;
87 const MemberDef * currentMemberDef = nullptr;
88 bool includeCodeFragment = false;
89 const char * currentFontClass = nullptr;
90};
91
92[[maybe_unused]] static const char *stateToString(int state);
93
94static void codify(yyscan_t yyscanner,const char* text);
95static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor);
96static void startCodeLine(yyscan_t yyscanner);
97static void endFontClass(yyscan_t yyscanner);
98static void endCodeLine(yyscan_t yyscanner);
99static void nextCodeLine(yyscan_t yyscanner);
100static void codifyLines(yyscan_t yyscanner,const char *text);
101static void startFontClass(yyscan_t yyscanner,const char *s);
102static int countLines(yyscan_t yyscanner);
103static int yyread(yyscan_t yyscanner,char *buf,int max_size);
104
105#undef YY_INPUT
106#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
107
108// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
109static inline const char *getLexerFILE() {return __FILE__;}
110#include "doxygen_lex.h"
111
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
#define FALSE
Definition qcstring.h:34
Web server based search engine.
QCString exampleName
Definition xmlcode.l:73
bool lineNumbers
Definition xmlcode.l:85
QCString fileName
Definition xmlcode.l:65
QCString args
Definition xmlcode.l:78
const char * currentFontClass
Definition xmlcode.l:89
OutputCodeList * code
Definition xmlcode.l:59
QCString name
Definition xmlcode.l:77
QCString CurrScope
Definition xmlcode.l:81
const Definition * currentDefinition
Definition xmlcode.l:86
const FileDef * sourceFileDef
Definition xmlcode.l:84
const MemberDef * currentMemberDef
Definition xmlcode.l:87
int yyLineNr
current line number
Definition xmlcode.l:67
int inputPosition
read offset during parsing
Definition xmlcode.l:64
std::unique_ptr< FileDef > exampleFileDef
Definition xmlcode.l:83
QCString parmType
Definition xmlcode.l:61
QCString exampleFile
Definition xmlcode.l:74
const char * inputString
the code fragment as text
Definition xmlcode.l:63
QCString classScope
Definition xmlcode.l:79
QCString parmName
Definition xmlcode.l:62
int inputLines
number of line in the code fragment
Definition xmlcode.l:66
QCString type
Definition xmlcode.l:76
bool includeCodeFragment
Definition xmlcode.l:88
bool stripCodeComments
Definition xmlcode.l:71
QCString curClassName
Definition xmlcode.l:60
const Definition * searchCtx
Definition xmlcode.l:69
bool exampleBlock
Definition xmlcode.l:72
bool insideCodeLine
Definition xmlcode.l:68
A bunch of utility functions.
static void endCodeLine(yyscan_t yyscanner)
Definition xmlcode.l:311
static void nextCodeLine(yyscan_t yyscanner)
Definition xmlcode.l:319
static void startCodeLine(yyscan_t yyscanner)
Definition xmlcode.l:253
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition xmlcode.l:212
static int countLines(yyscan_t yyscanner)
Definition xmlcode.l:368
static const char * stateToString(int state)
static void startFontClass(yyscan_t yyscanner, const char *s)
Definition xmlcode.l:359
static void codifyLines(yyscan_t yyscanner, const char *text)
Definition xmlcode.l:334
static const char * getLexerFILE()
Definition xmlcode.l:109
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition xmlcode.l:233
static void codify(yyscan_t yyscanner, const char *text)
Definition xmlcode.l:227
static void endFontClass(yyscan_t yyscanner)
Definition xmlcode.l:301
112%}
113
114nl (\r\n|\r|\n)
115ws [ \t]+
116open "<"
117close ">"
118namestart [A-Za-z\200-\377_]
119namechar [:A-Za-z\200-\377_0-9.-]
120esc "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";"
121name {namestart}{namechar}*
122comment {open}"!--"([^-]|"-"[^-])*"--"{close}
123cdata {open}"![CDATA["([^\‍]]|"\‍]"[^\‍]])*"]]"{close}
124string \"([^\"&]|{esc})*\"|\'([^'&]|{esc})*\'
125
126%option noyywrap
127%option nounput
128
130
131<INITIAL>{ws} {
132 codifyLines(yyscanner,yytext);
133 }
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2516
134<INITIAL>"/" {
135 endFontClass(yyscanner);
136 codify(yyscanner,yytext);
137 }
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
Definition code.l:3491
static void codify(yyscan_t yyscanner, const QCString &text)
Definition pycode.l:1017
138<INITIAL>"=" {
139 endFontClass(yyscanner);
140 codify(yyscanner,yytext);
141 }
142<INITIAL>{close} {
143 endFontClass(yyscanner);
144 codify(yyscanner,yytext);
145 }
146<INITIAL>{name} {
147 startFontClass(yyscanner,"keyword");
148 codify(yyscanner,yytext);
149 endFontClass(yyscanner);
150 }
static void startFontClass(yyscan_t yyscanner, const char *s, bool specialComment=false)
Definition code.l:3506
151<INITIAL>{string} {
152 startFontClass(yyscanner,"stringliteral");
153 codifyLines(yyscanner,yytext);
154 endFontClass(yyscanner);
155 }
156{cdata} {
157 startFontClass(yyscanner,"xmlcdata");
158 codifyLines(yyscanner,yytext);
159 endFontClass(yyscanner);
160 }
161
162{open}{ws}?{name} {
163 // Write the < in a different color
164 char openBracket[] = { yytext[0], '\0' };
165 codify(yyscanner,openBracket);
166
167 // Then write the rest
168 yytext++;
169 startFontClass(yyscanner,"keywordtype");
170 codify(yyscanner,yytext);
171 endFontClass(yyscanner);
172
173 BEGIN(INITIAL);
174 }
175{open}{ws}?"/"{name} {
176 // Write the "</" in a different color
177 char closeBracket[] = { yytext[0], yytext[1], '\0' };
178 endFontClass(yyscanner);
179 codify(yyscanner,closeBracket);
180
181 // Then write the rest
182 yytext++; // skip the '<'
183 yytext++; // skip the '/'
184 startFontClass(yyscanner,"keywordtype");
185 codify(yyscanner,yytext);
186 endFontClass(yyscanner);
187
188 BEGIN(INITIAL);
189 }
190{comment} {
191 // Strip off the extra '!'
192 // yytext++; // <
193 // *yytext = '<'; // replace '!' with '<'
194
195 startFontClass(yyscanner,"comment");
196 codifyLines(yyscanner,yytext);
197 endFontClass(yyscanner);
198 }
199{nl} {
200 codifyLines(yyscanner,yytext);
201 }
202
203. {
204 //printf("!ERROR(%c)\n", *yytext);
205 codifyLines(yyscanner,yytext);
206 }
207
208%%
209
210//----------------------------------------------------------------------------------------
211
212static int yyread(yyscan_t yyscanner,char *buf,int max_size)
213{
214 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
215 int inputPosition = yyextra->inputPosition;
216 const char *s = yyextra->inputString + inputPosition;
217 int c=0;
218 while( c < max_size && *s)
219 {
220 *buf++ = *s++;
221 c++;
222 }
223 yyextra->inputPosition += c;
224 return c;
225}
226
227static void codify(yyscan_t yyscanner,const char* text)
228{
229 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
230 yyextra->code->codify(text);
231}
232
233static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
234{
235 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
236 if (Doxygen::searchIndex.enabled())
237 {
238 if (yyextra->searchCtx)
239 {
240 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
241 }
242 else
243 {
244 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,true);
245 }
246 }
247}
248
249/*! start a new line of code, inserting a line number if yyextra->sourceFileDef
250 * is true. If a definition starts at the current line, then the line
251 * number is linked to the documentation of that definition.
252 */
253static void startCodeLine(yyscan_t yyscanner)
254{
255 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
256 if (yyextra->sourceFileDef && yyextra->lineNumbers)
257 {
258 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
259
260 if (!yyextra->includeCodeFragment && d && d->isLinkableInProject())
261 {
262 yyextra->currentDefinition = d;
263 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
264 //yyextra->insideBody = false;
265 yyextra->classScope = d->name();
266 QCString lineAnchor;
267 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
268 if (yyextra->currentMemberDef)
269 {
270 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
271 yyextra->currentMemberDef->getOutputFileBase(),
272 yyextra->currentMemberDef->anchor(),yyextra->yyLineNr,
273 !yyextra->includeCodeFragment);
274 setCurrentDoc(yyscanner,lineAnchor);
275 }
276 else
277 {
278 yyextra->code->writeLineNumber(d->getReference(),
280 QCString(),yyextra->yyLineNr,
281 !yyextra->includeCodeFragment);
282 setCurrentDoc(yyscanner,lineAnchor);
283 }
284 }
285 else
286 {
287 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
288 !yyextra->includeCodeFragment);
289 }
290 }
291
292 yyextra->code->startCodeLine(yyextra->yyLineNr);
293 yyextra->insideCodeLine = true;
294
295 if (yyextra->currentFontClass)
296 {
297 yyextra->code->startFontClass(yyextra->currentFontClass);
298 }
299}
300
301static void endFontClass(yyscan_t yyscanner)
302{
303 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
304 if (yyextra->currentFontClass)
305 {
306 yyextra->code->endFontClass();
307 yyextra->currentFontClass=0;
308 }
309}
310
311static void endCodeLine(yyscan_t yyscanner)
312{
313 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
314 endFontClass(yyscanner);
315 yyextra->code->endCodeLine();
316 yyextra->insideCodeLine = false;
317}
318
319static void nextCodeLine(yyscan_t yyscanner)
320{
321 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
322 const char *fc = yyextra->currentFontClass;
323 if (yyextra->insideCodeLine)
324 {
325 endCodeLine(yyscanner);
326 }
327 if (yyextra->yyLineNr<yyextra->inputLines)
328 {
329 yyextra->currentFontClass = fc;
330 startCodeLine(yyscanner);
331 }
332}
333
334static void codifyLines(yyscan_t yyscanner,const char *text)
335{
336 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
337 const char *p=text,*sp=p;
338 char c;
339 bool done=false;
340 while (!done)
341 {
342 sp=p;
343 while ((c=*p++) && c!='\n') { }
344 if (c=='\n')
345 {
346 yyextra->yyLineNr++;
347 size_t l = static_cast<size_t>(p-sp-1);
348 yyextra->code->codify(QCString(sp,l));
349 nextCodeLine(yyscanner);
350 }
351 else
352 {
353 yyextra->code->codify(sp);
354 done=true;
355 }
356 }
357}
358
359static void startFontClass(yyscan_t yyscanner,const char *s)
360{
361 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
362 endFontClass(yyscanner);
363 yyextra->code->startFontClass(s);
364 yyextra->currentFontClass=s;
365}
366
367/*! counts the number of lines in the input */
368static int countLines(yyscan_t yyscanner)
369{
370 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
371 const char *p=yyextra->inputString;
372 char c;
373 int count=1;
374 while ((c=*p))
375 {
376 p++ ;
377 if (c=='\n') count++;
378 }
379 if (p>yyextra->inputString && *(p-1)!='\n')
380 { // last line does not end with a \n, so we add an extra
381 // line and explicitly terminate the line after parsing.
382 count++;
383 }
384 return count;
385}
386
387//----------------------------------------------------------------------------------------
388
394
395XMLCodeParser::XMLCodeParser() : p(std::make_unique<Private>())
396{
397 xmlcodeYYlex_init_extra(&p->state,&p->yyscanner);
398#ifdef FLEX_DEBUG
399 xmlcodeYYset_debug(Debug::isFlagSet(Debug::Lex_xmlcode)?1:0,p->yyscanner);
400#endif
402}
403
405{
406 xmlcodeYYlex_destroy(p->yyscanner);
407}
408
410{
411 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
412 yyextra->currentDefinition = nullptr;
413 yyextra->currentMemberDef = nullptr;
414}
415
417 const QCString &/* scopeName */,
418 const QCString &input,
420 bool stripCodeComments,
421 const CodeParserOptions &options
422 )
423{
424 yyscan_t yyscanner = p->yyscanner;
425 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
426
427 if (input.isEmpty()) return;
428
429 DebugLex debugLex(Debug::Lex_xmlcode, __FILE__, options.fileDef() ? qPrint(options.fileDef()->fileName()): nullptr);
430 yyextra->fileName = options.fileDef() ? options.fileDef()->fileName():"";
431 yyextra->code = &codeOutIntf;
432 yyextra->inputString = input.data();
433 yyextra->inputPosition = 0;
434 yyextra->currentFontClass = nullptr;
435 yyextra->insideCodeLine = false;
436 yyextra->searchCtx = options.searchCtx();
437 yyextra->yyLineNr = options.startLine()!=-1 ? options.startLine() : 1;
438 yyextra->inputLines = options.endLine()!=-1 ? options.endLine()+1 : yyextra->yyLineNr + countLines(yyscanner) - 1;
439 yyextra->stripCodeComments = stripCodeComments;
440 yyextra->exampleBlock = options.isExample();
441 yyextra->exampleName = options.exampleName();
442 yyextra->sourceFileDef = options.fileDef();
443 yyextra->lineNumbers = options.fileDef() && options.showLineNumbers();
444
445 if (options.isExample() && options.fileDef()==nullptr)
446 {
447 // create a dummy filedef for the example
448 yyextra->exampleFileDef = createFileDef("",(!options.exampleName().isEmpty()?options.exampleName():QCString("generated")));
449 yyextra->sourceFileDef = yyextra->exampleFileDef.get();
450 }
451
452 if (yyextra->sourceFileDef)
453 {
454 setCurrentDoc(yyscanner,"l00001");
455 }
456
457 yyextra->includeCodeFragment = options.inlineFragment();
458 // Starts line 1 on the output
459 startCodeLine(yyscanner);
460
461 xmlcodeYYrestart( nullptr, yyscanner );
462
463 xmlcodeYYlex(yyscanner);
464
465 if (yyextra->insideCodeLine)
466 {
467 endCodeLine(yyscanner);
468 }
469 if (yyextra->exampleFileDef)
470 {
471 // delete the temporary file definition used for this example
472 yyextra->exampleFileDef.reset();
473 yyextra->sourceFileDef=nullptr;
474 }
475}
476
477
478#include "xmlcode.l.h"
@ Lex_xmlcode
Definition debug.h:72
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:133
virtual bool isLinkableInProject() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
virtual const QCString & name() const =0
static SearchIndexIntf searchIndex
Definition doxygen.h:124
virtual QCString fileName() const =0
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
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
std::unique_ptr< Private > p
Definition xmlcode.h:48
~XMLCodeParser() override
Definition xmlcode.l:404
void resetCodeParserState() override
Resets the state of the code parser.
Definition xmlcode.l:409
void parseCode(OutputCodeList &codeOutIntf, const QCString &scopeName, const QCString &input, SrcLangExt, bool stripCodeComments, const CodeParserOptions &options) override
Parses a source file or fragment with the goal to produce highlighted and cross-referenced output.
Definition xmlcode.l:416
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 setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition code.l:2288
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
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
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
xmlcodeYY_state state
Definition xmlcode.l:392
SrcLangExt
Definition types.h:207