Doxygen
Loading...
Searching...
No Matches
sqlcode.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 */
13
14%option never-interactive
15%option prefix="sqlcodeYY"
16%option noyywrap
17%option nounput
18%option reentrant
19%option extra-type="struct sqlcodeYY_state *"
20%top{
21#include <stdint.h>
22// forward declare yyscan_t to improve type safety
23#define YY_TYPEDEF_YY_SCANNER_T
24struct yyguts_t;
25typedef yyguts_t *yyscan_t;
yyguts_t * yyscan_t
Definition code.l:24
26}
28%{
29
30#include <stdio.h>
31
32#include "sqlcode.h"
33
34#include "entry.h"
35#include "doxygen.h"
36#include "outputlist.h"
37#include "util.h"
38#include "membername.h"
39#include "searchindex.h"
40#include "config.h"
41#include "filedef.h"
42#include "tooltip.h"
43#include "message.h"
44#include "debug.h"
45
46#define YY_NEVER_INTERACTIVE 1
47#define YY_NO_INPUT 1
48#define YY_NO_UNISTD_H 1
51{
52 OutputCodeList * code = nullptr;
53 const char *inputString = nullptr; //!< the code fragment as text
54 int inputPosition = 0; //!< read offset during parsing
56 int inputLines = 0; //!< number of line in the code fragment
57 int yyLineNr = 1; //!< current line number
58 bool insideCodeLine = false;
59 const Definition *searchCtx = nullptr;
61 bool stripCodeComments = true;
62 bool exampleBlock = false;
66 std::unique_ptr<FileDef> exampleFileDef;
67 const FileDef *sourceFileDef = nullptr;
69 const Definition *currentDefinition = nullptr;
70 const MemberDef *currentMemberDef = nullptr;
71 bool includeCodeFragment = false;
72 const char *currentFontClass = nullptr;
73};
75[[maybe_unused]] static const char *stateToString(int state);
76
77static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor);
78static void startCodeLine(yyscan_t yyscanner);
79static void endFontClass(yyscan_t yyscanner);
80static void endCodeLine(yyscan_t yyscanner);
81static void nextCodeLine(yyscan_t yyscanner);
82static void codifyLines(yyscan_t yyscanner,const char *text);
83static void startFontClass(yyscan_t yyscanner,const char *s);
84static int countLines(yyscan_t yyscanner);
85static int yyread(yyscan_t yyscanner,char *buf,int max_size);
86
87#undef YY_INPUT
88#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
89
90// otherwise the filename would be the name of the converted file (*.cpp instead of *.l)
91static inline const char *getLexerFILE() {return __FILE__;}
92#include "doxygen_lex.h"
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
static void endCodeLine(yyscan_t yyscanner)
Definition code.l:2489
static void nextCodeLine(yyscan_t yyscanner)
Definition code.l:2498
static void startCodeLine(yyscan_t yyscanner)
Definition code.l:2420
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2516
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 const char * stateToString(int state)
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
static const char * getLexerFILE()
Definition code.l:263
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition code.l:2288
#define FALSE
Definition qcstring.h:34
Web server based search engine.
const char * currentFontClass
Definition sqlcode.l:74
const Definition * searchCtx
Definition sqlcode.l:61
bool includeCodeFragment
Definition sqlcode.l:73
bool exampleBlock
Definition sqlcode.l:64
const char * inputString
the code fragment as text
Definition sqlcode.l:55
QCString fileName
Definition sqlcode.l:57
const MemberDef * currentMemberDef
Definition sqlcode.l:72
bool lineNumbers
Definition sqlcode.l:70
bool insideCodeLine
Definition sqlcode.l:60
QCString classScope
Definition sqlcode.l:66
int yyLineNr
current line number
Definition sqlcode.l:59
QCString exampleName
Definition sqlcode.l:65
OutputCodeList * code
Definition sqlcode.l:54
int inputLines
number of line in the code fragment
Definition sqlcode.l:58
const FileDef * sourceFileDef
Definition sqlcode.l:69
std::unique_ptr< FileDef > exampleFileDef
Definition sqlcode.l:68
int inputPosition
read offset during parsing
Definition sqlcode.l:56
bool stripCodeComments
Definition sqlcode.l:63
const Definition * currentDefinition
Definition sqlcode.l:71
A bunch of utility functions.
94%}
95
96nl (\r\n|\r|\n)
97idchar [A-Za-z0-9\-_]+
98keywords1 ("ADD"|"ALL"|"ALLOCATE"|"ALTER"|"AND"|"ANY"|"ARE"|"AS"|"ASENSITIVE"|"ASYMMETRIC"|"AT"|"ATOMIC"|"AUTHORIZATION"|"BETWEEN"|"BOTH"|"BY"|"CALL"|"CALLED"|"CASCADED"|"CAST")
99keywords2 ("CHECK"|"CLOSE"|"COLLATE"|"COLUMN"|"COMMIT"|"CONNECT"|"CONSTRAINT"|"CONTINUE"|"CORRESPONDING"|"CREATE"|"CROSS"|"CUBE"|"CURRENT"|"CURRENT_DATE"|"CURRENT_DEFAULT_TRANSFORM_GROUP")
100keywords3 ("CURRENT_PATH"|"CURRENT_ROLE"|"CURRENT_TIME"|"CURRENT_TIMESTAMP"|"CURRENT_TRANSFORM_GROUP_FOR_TYPE"|"CURRENT_USER")
101keywords4 ("CURSOR"|"CYCLE"|"DAY"|"DEALLOCATE"|"DECLARE"|"DEFAULT"|"DELETE"|"DEREF"|"DESCRIBE"|"DETERMINISTIC"|"DISCONNECT"|"DISTINCT"|"DROP"|"DYNAMIC")
102keywords5 ("EACH"|"ELEMENT"|"END-EXEC"|"ESCAPE"|"EXCEPT"|"EXEC"|"EXECUTE"|"EXISTS"|"EXTERNAL"|"FETCH"|"FILTER"|"FOR"|"FOREIGN"|"FREE"|"FROM"|"FULL"|"FUNCTION")
103keywords6 ("GET"|"GLOBAL"|"GRANT"|"GROUP"|"GROUPING"|"HAVING"|"HOLD"|"HOUR"|"IDENTITY"|"IMMEDIATE"|"IN"|"INDICATOR"|"INNER"|"INOUT"|"INPUT"|"INSENSITIVE"|"INSERT"|"INTERSECT")
104keywords7 ("INTERVAL"|"INTO"|"IS"|"ISOLATION"|"JOIN"|"LANGUAGE"|"LARGE"|"LATERAL"|"LEADING"|"LEFT"|"LIKE"|"LOCAL"|"LOCALTIME"|"LOCALTIMESTAMP"|"MATCH"|"MEMBER"|"MERGE"|"METHOD"|"MINUTE")
105keywords8 ("MODIFIES"|"MODULE"|"MONTH"|"MULTISET"|"NATIONAL"|"NATURAL"|"NEW"|"NO"|"NONE"|"NOT"|"OF"|"OLD"|"ON"|"ONLY"|"OPEN"|"OR"|"ORDER"|"OUT"|"OUTER"|"OUTPUT")
106keywords9 ("OVER"|"OVERLAPS"|"PARAMETER"|"PARTITION"|"PRECISION"|"PREPARE"|"PRIMARY"|"PROCEDURE"|"RANGE"|"READS"|"RECURSIVE"|"REF"|"REFERENCES"|"REFERENCING"|"REGR_AVGX"|"REGR_AVGY")
107keywords10 ("REGR_COUNT"|"REGR_INTERCEPT"|"REGR_R2"|"REGR_SLOPE"|"REGR_SXX"|"REGR_SXY"|"REGR_SYY"|"RELEASE"|"RESULT"|"RETURN"|"RETURNS"|"REVOKE"|"RIGHT"|"ROLLBACK"|"ROLLUP"|"ROW"|"ROWS"|"SAVEPOINT")
108keywords11 ("SCROLL"|"SEARCH"|"SECOND"|"SELECT"|"SENSITIVE"|"SESSION_USER"|"SET"|"SIMILAR"|"SOME"|"SPECIFIC"|"SPECIFICTYPE"|"SQL"|"SQLEXCEPTION"|"SQLSTATE"|"SQLWARNING"|"START"|"STATIC")
109keywords12 ("SUBMULTISET"|"SYMMETRIC"|"SYSTEM"|"SYSTEM_USER"|"TABLE"|"THEN"|"TIMEZONE_HOUR"|"TIMEZONE_MINUTE"|"TO"|"TRAILING"|"TRANSLATION"|"TREAT"|"TRIGGER"|"UESCAPE"|"UNION")
110keywords13 ("UNIQUE"|"UNNEST"|"UPDATE"|"UPPER"|"USER"|"USING"|"VALUE"|"VALUES"|"VAR_POP"|"VAR_SAMP"|"VARYING"|"WHEN"|"WHENEVER"|"WHERE"|"WIDTH_BUCKET"|"WINDOW"|"WITH"|"WITHIN"|"WITHOUT"|"YEAR")
111
112/* Need multiple keyword definitions due to max length */
113keyword (?i:{keywords1}|{keywords2}|{keywords3}|{keywords4}|{keywords5}|{keywords6}|{keywords7}|{keywords8}|{keywords9}|{keywords10}|{keywords11}|{keywords12}|{keywords13})
114
115typekeyword (?i:"ARRAY"|"BIGINT"|"BINARY"|"BLOB"|"BOOLEAN"|"CHAR"|"CHARACTER"|"CLOB"|"DATE"|"DEC"|"DECIMAL"|"DOUBLE"|"FLOAT"|"INT"|"INTEGER"|"NCHAR"|"NCLOB"|"NUMERIC"|"NVARCHAR"|"REAL"|"SMALLINT"|"TIME"|"TIMESTAMP"|"VARCHAR")
116
117flowkeyword (?i:"CASE"|"IF"|"ELSE"|"BEGIN"|"END"|"WHILE")
118
119literalkeyword (?i:"false"|"true"|"NULL"|"UNKNOWN")
120stringliteral (\"[^\"]*\")|('[^']*')
121number [0-9]+
122literals ({literalkeyword}|{stringliteral}|{number})
123
124variable @{idchar}+
125
126simplecomment --.*
127commentopen "/\*"
128commentclose "\*\/"
129
130%x COMMENT
131
132%%
133
134{literals} {
135 startFontClass(yyscanner,"stringliteral");
136 codifyLines(yyscanner,yytext);
137 endFontClass(yyscanner);
138 }
139
140
141{keyword} {
142 startFontClass(yyscanner,"keyword");
143 codifyLines(yyscanner,yytext);
144 endFontClass(yyscanner);
145 }
146
147{flowkeyword} {
148 startFontClass(yyscanner,"keywordflow");
149 codifyLines(yyscanner,yytext);
150 endFontClass(yyscanner);
151 }
152
153{typekeyword} {
154 startFontClass(yyscanner,"keywordtype");
155 codifyLines(yyscanner,yytext);
156 endFontClass(yyscanner);
157 }
158
159{variable} {
160 startFontClass(yyscanner,"preprocessor");
161 codifyLines(yyscanner,yytext);
162 endFontClass(yyscanner);
163 }
164
165{simplecomment} {
166 startFontClass(yyscanner,"comment");
167 codifyLines(yyscanner,yytext);
168 endFontClass(yyscanner);
169 }
170
171{commentopen} {
172 startFontClass(yyscanner,"comment");
173 codifyLines(yyscanner,yytext);
174 BEGIN(COMMENT);
175 }
176
177<COMMENT>. {
178 codifyLines(yyscanner,yytext);
179
180 }
181<COMMENT>{nl} {
182 codifyLines(yyscanner,yytext);
183 }
184
185<COMMENT>{commentclose} {
186 codifyLines(yyscanner,yytext);
187 endFontClass(yyscanner);
188 BEGIN(INITIAL);
189 }
190
191{idchar} {
192 codifyLines(yyscanner,yytext);
193 }
194
195{nl} {
196 codifyLines(yyscanner,yytext);
197 }
198
199[\x80-\xFF]* { // keep utf8 characters together...
200 codifyLines(yyscanner,yytext);
201 }
202. {
203 codifyLines(yyscanner,yytext);
204 }
205
206%%
207
208
209static void setCurrentDoc(yyscan_t yyscanner,const QCString &anchor)
210{
211 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
212 if (Doxygen::searchIndex.enabled())
213 {
214 if (yyextra->searchCtx)
215 {
216 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
217 }
218 else
219 {
220 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,true);
221 }
222 }
223}
224
225/*! start a new line of code, inserting a line number if yyextra->sourceFileDef
226 * is true. If a definition starts at the current line, then the line
227 * number is linked to the documentation of that definition.
228 */
229static void startCodeLine(yyscan_t yyscanner)
230{
231 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
232 if (yyextra->sourceFileDef && yyextra->lineNumbers)
233 {
234 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
235
236 if (!yyextra->includeCodeFragment && d && d->isLinkableInProject())
237 {
238 yyextra->currentDefinition = d;
239 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
240 yyextra->classScope = d->name();
241 QCString lineAnchor;
242 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
243 if (yyextra->currentMemberDef)
244 {
245 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
246 yyextra->currentMemberDef->getOutputFileBase(),
247 yyextra->currentMemberDef->anchor(),yyextra->yyLineNr,
248 !yyextra->includeCodeFragment);
249 setCurrentDoc(yyscanner,lineAnchor);
250 }
251 else
252 {
253 yyextra->code->writeLineNumber(d->getReference(),
255 QCString(),yyextra->yyLineNr,
256 !yyextra->includeCodeFragment);
257 setCurrentDoc(yyscanner,lineAnchor);
258 }
259 }
260 else
261 {
262 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
263 !yyextra->includeCodeFragment);
264 }
265 }
266
267 yyextra->code->startCodeLine(yyextra->yyLineNr);
268 yyextra->insideCodeLine=true;
269
270 if (yyextra->currentFontClass)
271 {
272 yyextra->code->startFontClass(yyextra->currentFontClass);
273 }
274}
275
276static void endFontClass(yyscan_t yyscanner)
277{
278 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
279 if (yyextra->currentFontClass)
280 {
281 yyextra->code->endFontClass();
282 yyextra->currentFontClass=0;
283 }
284}
285
286static void endCodeLine(yyscan_t yyscanner)
287{
288 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
289 endFontClass(yyscanner);
290 yyextra->code->endCodeLine();
291 yyextra->insideCodeLine=false;
292}
293
294static void nextCodeLine(yyscan_t yyscanner)
295{
296 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
297 const char *fc = yyextra->currentFontClass;
298 if (yyextra->insideCodeLine)
299 {
300 endCodeLine(yyscanner);
301 }
302 if (yyextra->yyLineNr<yyextra->inputLines)
303 {
304 yyextra->currentFontClass = fc;
305 startCodeLine(yyscanner);
306 }
307}
308
309static void codifyLines(yyscan_t yyscanner,const char *text)
310{
311 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
312 const char *p=text,*sp=p;
313 char c;
314 bool done=false;
315 while (!done)
316 {
317 sp=p;
318 while ((c=*p++) && c!='\n') { }
319 if (c=='\n')
320 {
321 yyextra->yyLineNr++;
322 size_t l = static_cast<size_t>(p-sp-1);
323 yyextra->code->codify(QCString(sp,l));
324 nextCodeLine(yyscanner);
325 }
326 else
327 {
328 yyextra->code->codify(sp);
329 done=true;
330 }
331 }
332}
333
334static void startFontClass(yyscan_t yyscanner,const char *s)
335{
336 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
337 endFontClass(yyscanner);
338 yyextra->code->startFontClass(s);
339 yyextra->currentFontClass=s;
340}
341
342/*! counts the number of lines in the input */
343static int countLines(yyscan_t yyscanner)
344{
345 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
346 const char *p=yyextra->inputString;
347 char c;
348 int count=1;
349 while ((c=*p))
350 {
351 p++ ;
352 if (c=='\n') count++;
353 }
354 if (p>yyextra->inputString && *(p-1)!='\n')
355 { // last line does not end with a \n, so we add an extra
356 // line and explicitly terminate the line after parsing.
357 count++;
358 }
359 return count;
360}
361
362static int yyread(yyscan_t yyscanner,char *buf,int max_size)
363{
364 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
365 int inputPosition = yyextra->inputPosition;
366 const char *s = yyextra->inputString + inputPosition;
367 int c=0;
368 while( c < max_size && *s )
369 {
370 *buf++ = *s++;
371 c++;
372 }
373 yyextra->inputPosition += c;
374 return c;
375}
376
377
378// public interface -----------------------------------------------------------
379
381{
387{
388 sqlcodeYYlex_init_extra(&p->state, &p->yyscanner);
389#ifdef FLEX_DEBUG
390 sqlcodeYYset_debug(Debug::isFlagSet(Debug::Lex_sqlcode)?1:0,p->yyscanner);
391#endif
393}
394
396{
397 sqlcodeYYlex_destroy(p->yyscanner);
398}
399
401{
402 struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
403 yyextra->currentDefinition = nullptr;
404 yyextra->currentMemberDef = nullptr;
405}
406
408 const QCString &/* scopeName */,
409 const QCString &input,
411 bool stripCodeComments,
412 const CodeParserOptions &options
413 )
414{
415 yyscan_t yyscanner = p->yyscanner;
416 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
417
418 if (input.isEmpty()) return;
419
420 DebugLex debugLex(Debug::Lex_sqlcode, __FILE__, options.fileDef() ? qPrint(options.fileDef()->fileName()): nullptr);
421 yyextra->fileName = options.fileDef() ? options.fileDef()->fileName():"";
422 yyextra->code = &codeOutIntf;
423 yyextra->inputString = input.data();
424 yyextra->inputPosition = 0;
425 yyextra->currentFontClass = nullptr;
426 yyextra->insideCodeLine = false;
427 yyextra->searchCtx = options.searchCtx();
428 yyextra->yyLineNr = options.startLine()!=-1 ? options.startLine() : 1;
429 yyextra->inputLines = options.endLine()!=-1 ? options.endLine()+1 : yyextra->yyLineNr + countLines(yyscanner) - 1;
430 yyextra->stripCodeComments = stripCodeComments;
431 yyextra->exampleBlock = options.isExample();
432 yyextra->exampleName = options.exampleName();
433 yyextra->sourceFileDef = options.fileDef();
434 yyextra->lineNumbers = options.fileDef() && options.showLineNumbers();
435
436 if (options.isExample() && options.fileDef()==0)
437 {
438 // create a dummy filedef for the example
439 yyextra->exampleFileDef = createFileDef(QCString(),!options.exampleName().isEmpty() ? options.exampleName() : QCString("generated"));
440 yyextra->sourceFileDef = yyextra->exampleFileDef.get();
441 }
442
443 if (yyextra->sourceFileDef)
444 {
445 setCurrentDoc(yyscanner,"l00001");
446 }
447
448 yyextra->includeCodeFragment = options.inlineFragment();
449 // Starts line 1 on the output
450 startCodeLine(yyscanner);
451
452 sqlcodeYYrestart( nullptr, yyscanner );
453
454 sqlcodeYYlex(yyscanner);
455
456 if (yyextra->insideCodeLine)
457 {
458 endCodeLine(yyscanner);
459 }
460 if (yyextra->exampleFileDef)
461 {
462 // delete the temporary file definition used for this example
463 yyextra->exampleFileDef.reset();
464 yyextra->sourceFileDef=nullptr;
465 }
466}
467
468//---------------------------------------------------------------------------------
469
470#include "sqlcode.l.h"
@ Lex_sqlcode
Definition debug.h:68
static bool isFlagSet(const DebugMask mask)
Definition debug.cpp:132
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:123
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 sqlcode.h:46
void resetCodeParserState() override
Resets the state of the code parser.
Definition sqlcode.l:402
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 sqlcode.l:409
~SQLCodeParser() override
Definition sqlcode.l:397
std::unique_ptr< FileDef > createFileDef(const QCString &p, const QCString &n, const QCString &ref, const QCString &dn)
Definition filedef.cpp:269
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
sqlcodeYY_state state
Definition sqlcode.l:385
SrcLangExt
Definition types.h:207