Doxygen
Loading...
Searching...
No Matches
code.l File Reference
#include <stdint.h>
#include <utility>
#include <memory>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <vector>
#include <string>
#include <mutex>
#include <sstream>
#include <cstdint>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "code.h"
#include "entry.h"
#include "doxygen.h"
#include "message.h"
#include "outputlist.h"
#include "util.h"
#include "membername.h"
#include "searchindex.h"
#include "arguments.h"
#include "config.h"
#include "groupdef.h"
#include "classlist.h"
#include "filedef.h"
#include "filename.h"
#include "namespacedef.h"
#include "tooltip.h"
#include "scopedtypevariant.h"
#include "symbolresolver.h"
#include "dir.h"
#include "debug.h"
#include "moduledef.h"
#include "doxygen_lex.h"
#include "code.l.h"
+ Include dependency graph for code.l:

Go to the source code of this file.

Classes

struct  ObjCCallCtx
 
struct  codeYY_state
 
struct  CCodeParser::Private
 

Macros

#define YY_TYPEDEF_YY_SCANNER_T
 
#define DBG_CTX(x)
 
#define YY_NO_UNISTD_H   1
 
#define CLASSBLOCK   1
 
#define SCOPEBLOCK   2
 
#define INNERBLOCK   3
 
#define YY_INPUT(buf, result, max_size)
 

Typedefs

typedef yyguts_t * yyscan_t
 

Functions

static bool isCastKeyword (const char *s)
 
static const char * stateToString (int state)
 
static void saveObjCContext (yyscan_t yyscanner)
 
static void restoreObjCContext (yyscan_t yyscanner)
 
static void pushScope (yyscan_t yyscanner, const QCString &s)
 
static void popScope (yyscan_t yyscanner)
 
static void setCurrentDoc (yyscan_t yyscanner, const QCString &anchor)
 
static void addToSearchIndex (yyscan_t yyscanner, const QCString &text)
 
static void addToSearchIndex (yyscan_t yyscanner, const char *text)
 
static void setClassScope (yyscan_t yyscanner, const QCString &name)
 
static void startCodeLine (yyscan_t yyscanner)
 
static void endCodeLine (yyscan_t yyscanner)
 
static void nextCodeLine (yyscan_t yyscanner)
 
static void startFontClass (yyscan_t yyscanner, const char *s, bool specialComment=false)
 
static void endFontClass (yyscan_t yyscanner, bool specialComment=false)
 
static void codifyLines (yyscan_t yyscanner, const QCString &text)
 
static void codifyLines (yyscan_t yyscanner, const char *text)
 
static void incrementFlowKeyWordCount (yyscan_t yyscanner)
 
static void writeMultiLineCodeLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const QCString &text)
 
static void addType (yyscan_t yyscanner)
 
static void addParmType (yyscan_t yyscanner)
 
static void addUsingDirective (yyscan_t yyscanner, const QCString &name)
 
static void setParameterList (yyscan_t yyscanner, const MemberDef *md)
 
static const ClassDefstripClassName (yyscan_t yyscanner, const QCString &s, const Definition *d)
 
static const MemberDefsetCallContextForVar (yyscan_t yyscanner, const QCString &name)
 
static void updateCallContextForSmartPointer (yyscan_t yyscanner)
 
static bool getLinkInScope (yyscan_t yyscanner, const QCString &c, const QCString &m, const QCString &memberText, OutputCodeList &ol, const QCString &text, bool varOnly=FALSE)
 
static bool getLink (yyscan_t yyscanner, const QCString &className, const QCString &memberName, OutputCodeList &ol, const QCString &text=QCString(), bool varOnly=FALSE)
 
static void generateClassOrGlobalLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE, bool varOnly=FALSE)
 
static void generateClassOrGlobalLink (yyscan_t yyscanner, OutputCodeList &ol, const char *clName, bool typeOnly=FALSE, bool varOnly=FALSE)
 
static bool generateClassMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const QCString &memName)
 
static bool generateClassMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *def, const QCString &memName)
 
static void generateMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &varName, const QCString &memName)
 
static void generatePHPVariableLink (yyscan_t yyscanner, OutputCodeList &ol, const char *varName)
 
static void generateFunctionLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
 
static void generateFunctionLink (yyscan_t yyscanner, OutputCodeList &ol, const char *funcName)
 
static int countLines (yyscan_t yyscanner)
 
static void writeObjCMethodCall (yyscan_t yyscanner, ObjCCallCtx *ctx)
 
static QCString escapeName (yyscan_t yyscanner, const char *s)
 
static QCString escapeObject (yyscan_t yyscanner, const char *s)
 
static QCString escapeWord (yyscan_t yyscanner, const char *s)
 
static QCString escapeComment (yyscan_t yyscanner, const char *s)
 
static bool skipLanguageSpecificKeyword (yyscan_t yyscanner, const char *kw)
 
static int yyread (yyscan_t yyscanner, char *buf, int max_size)
 
static void addVariable (yyscan_t yyscanner, QCString type, QCString name)
 
static bool startsWithKeyword (const QCString &str, const QCString &kw)
 
static void endCodeFold (yyscan_t yyscanner)
 
static const char * getLexerFILE ()
 
int yylex (yyscan_t yyscanner)
 
static void codeFolding (yyscan_t yyscanner, const Definition *d)
 

Macro Definition Documentation

◆ CLASSBLOCK

#define CLASSBLOCK   1

Definition at line 77 of file code.l.

Referenced by setCallContextForVar().

◆ DBG_CTX

◆ INNERBLOCK

#define INNERBLOCK   3

Definition at line 79 of file code.l.

◆ SCOPEBLOCK

#define SCOPEBLOCK   2

Definition at line 78 of file code.l.

◆ YY_INPUT

#define YY_INPUT ( buf,
result,
max_size )
Value:
result=yyread(yyscanner,buf,max_size);
static int yyread(yyscan_t yyscanner, char *buf, int max_size)
Definition code.l:3974

Definition at line 265 of file code.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 75 of file code.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 22 of file code.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 24 of file code.l.

Function Documentation

◆ addParmType()

static void addParmType ( yyscan_t yyscanner)
static

Definition at line 2609 of file code.l.

2610{
2611 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2612 if (yyextra->parmName=="const") { yyextra->parmName.clear(); return; }
2613 if (!yyextra->parmType.isEmpty()) yyextra->parmType += ' ' ;
2614 yyextra->parmType += yyextra->parmName ;
2615 yyextra->parmName.clear() ;
2616}

◆ addToSearchIndex() [1/2]

static void addToSearchIndex ( yyscan_t yyscanner,
const char * text )
static

Definition at line 2298 of file code.l.

2299{
2300 addToSearchIndex(yyscanner,QCString(text));
This is an alternative implementation of QCString.
Definition qcstring.h:101
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition code.l:2290
2301}

References addToSearchIndex().

◆ addToSearchIndex() [2/2]

static void addToSearchIndex ( yyscan_t yyscanner,
const QCString & text )
static

◆ addType()

static void addType ( yyscan_t yyscanner)
static

Definition at line 2597 of file code.l.

2598{
2599 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2600 if (yyextra->name=="const") { yyextra->name.clear(); return; }
2601 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2602 yyextra->type += yyextra->name ;
2603 yyextra->name.clear() ;
2604 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2605 yyextra->type += yyextra->args ;
2606 yyextra->args.clear() ;
2607}

◆ addUsingDirective()

static void addUsingDirective ( yyscan_t yyscanner,
const QCString & name )
static

Definition at line 2618 of file code.l.

2619{
2620 //printf("AddUsingDirective(%s)\n",qPrint(name));
2621 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2622 if (yyextra->sourceFileDef && !name.isEmpty())
2623 {
2624 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name);
2625 if (nd)
2626 {
2627 yyextra->theUsingContext.emplace(name.str(),nd);
2628 }
2629 }
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
An abstract interface of a namespace symbol.
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:526
2630}

References QCString::isEmpty(), Doxygen::namespaceLinkedMap, and QCString::str().

◆ addVariable()

static void addVariable ( yyscan_t yyscanner,
QCString type,
QCString name )
static

Definition at line 2175 of file code.l.

2176{
2177 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2178 DBG_CTX((stderr,"VariableContext::addVariable(%s,%s)\n",qPrint(type),qPrint(name)));
2179 QCString ltype = type.simplifyWhiteSpace();
2180 QCString lname = name.simplifyWhiteSpace();
2181 ltype.stripPrefix("struct ");
2182 ltype.stripPrefix("union ");
2183 if (ltype.isEmpty() || lname.isEmpty()) return;
2184 ltype = substitute(ltype,".","::");
2185 DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n",
2186 qPrint(ltype),qPrint(lname),yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>"));
2187 auto it = yyextra->codeClassMap.find(ltype.str());
2188 if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block
2189 {
2190 DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname)));
2191 yyextra->theVarContext.addVariable(lname,std::move(it->second)); // add it to a list
2192 }
2193 else
2194 {
2195 auto findVariableType = [&yyscanner,&yyg,&ltype,&lname,&name](const Definition *d) -> const ClassDef *
2196 {
2197 const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype,true);
2198 int i=0;
2199 if (varDef)
2200 {
2201 DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname)));
2202 yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list
2203 }
2204 else if ((i=ltype.find('<'))!=-1)
2205 {
2206 // probably a template class
2207 addVariable(yyscanner,ltype.left(i),name);
2208 }
2209 return varDef;
2210 };
2211 const ClassDef *varDef = findVariableType(yyextra->currentDefinition);
2212 if (varDef==nullptr) // also check via using directive
2213 {
2214 for (const auto &[usingName,namespaceDef] : yyextra->theUsingContext)
2215 {
2216 varDef = findVariableType(namespaceDef);
2217 if (varDef) break;
2218 }
2219 }
2220 if (varDef==nullptr)
2221 {
2222 if (!yyextra->theVarContext.atGlobalScope()) // for local variables add a dummy entry so the name
2223 // is hidden to avoid false links to global variables with the same name
2224 // TODO: make this work for namespaces as well!
2225 {
2226 DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",qPrint(lname)));
2227 yyextra->theVarContext.addVariable(lname,ScopedTypeVariant());
2228 }
2229 else
2230 {
2231 DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
2232 }
2233 }
2234 }
A abstract class representing of a compound symbol.
Definition classdef.h:104
The common base class of all entity definitions found in the sources.
Definition definition.h:76
QCString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple whitespace cha...
Definition qcstring.cpp:185
bool stripPrefix(const QCString &prefix)
Definition qcstring.h:198
#define DBG_CTX(x)
Definition code.l:73
static void addVariable(yyscan_t yyscanner, QCString type, QCString name)
Definition code.l:2175
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
const char * qPrint(const char *s)
Definition qcstring.h:661
2235}

References addVariable(), DBG_CTX, QCString::isEmpty(), qPrint(), QCString::simplifyWhiteSpace(), QCString::str(), QCString::stripPrefix(), and substitute().

Referenced by addVariable(), and setParameterList().

◆ codeFolding()

static void codeFolding ( yyscan_t yyscanner,
const Definition * d )
static

Definition at line 2354 of file code.l.

2355{
2356 if (Config_getBool(HTML_CODE_FOLDING))
2357 {
2358 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2359 //fprintf(stderr,"codeFolding at %d\n",yyextra->yyLineNr);
2360 //if (d)
2361 // fprintf(stderr,"%d: codeFolding: candidate=%s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->qualifiedName()),d->getStartDefLine(),d->getEndBodyLine());
2362 endCodeFold(yyscanner);
2363 if (d)
2364 {
2365 int startLine = d->getStartDefLine();
2366 int endLine = d->getEndBodyLine();
2367 if (endLine!=-1 && startLine!=endLine &&
2368 // since the end of a section is closed after the last line, we need to avoid starting a
2369 // new section if the previous section ends at the same line, i.e. something like
2370 // struct X {
2371 // ...
2372 // }; struct S { <- start of S and end of X at the same line
2373 // ...
2374 // };
2375 (yyextra->foldStack.empty() || yyextra->foldStack.back()->getEndBodyLine()!=startLine))
2376 {
2377 //printf("%d: start codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->name()),d->getStartDefLine(),d->getEndBodyLine());
2379 {
2380 const MemberDef *md = toMemberDef(d);
2381 if (md && md->isDefine())
2382 {
2383 yyextra->code->startFold(yyextra->yyLineNr,"",""); // #define X ...
2384 }
2385 else if (md && md->isCallable())
2386 {
2387 yyextra->code->startFold(yyextra->yyLineNr,"{","}"); // func() { ... }
2388 }
2389 else
2390 {
2391 yyextra->code->startFold(yyextra->yyLineNr,"{","};"); // enum X { ... }
2392 }
2393 }
2395 {
2396 yyextra->code->startFold(yyextra->yyLineNr,"{","};"); // class X { ... };
2397 }
2398 else
2399 {
2400 yyextra->code->startFold(yyextra->yyLineNr,"{","}"); // namespace X {...}
2401 }
2402 yyextra->foldStack.push_back(d);
2403 }
2404 }
2405 }
virtual int getEndBodyLine() const =0
virtual DefType definitionType() const =0
virtual int getStartDefLine() const =0
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
virtual bool isDefine() const =0
virtual bool isCallable() const =0
static void endCodeFold(yyscan_t yyscanner)
Definition code.l:2333
#define Config_getBool(name)
Definition config.h:33
MemberDef * toMemberDef(Definition *d)
2406}

References Config_getBool, Definition::definitionType(), endCodeFold(), Definition::getEndBodyLine(), Definition::getStartDefLine(), MemberDef::isCallable(), MemberDef::isDefine(), toMemberDef(), Definition::TypeClass, and Definition::TypeMember.

Referenced by startCodeLine(), startCodeLine(), startCodeLine(), and startCodeLine().

◆ codifyLines() [1/2]

static void codifyLines ( yyscan_t yyscanner,
const char * text )
static

Definition at line 2536 of file code.l.

2537{
2538 codifyLines(yyscanner,QCString(text));
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2508
2539}

References codifyLines().

◆ codifyLines() [2/2]

static void codifyLines ( yyscan_t yyscanner,
const QCString & text )
static

write a code fragment 'text' that may span multiple lines, inserting line numbers for each line.

Definition at line 2508 of file code.l.

2509{
2510 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2511 DBG_CTX((stderr,"codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,qPrint(text)));
2512 if (text.isEmpty()) return;
2513 const char *p=text.data(),*sp=p;
2514 char c;
2515 bool done=FALSE;
2516 while (!done)
2517 {
2518 sp=p;
2519 while ((c=*p++) && c!='\n');
2520 if (c=='\n')
2521 {
2522 yyextra->yyLineNr++;
2523 size_t l = static_cast<size_t>(p-sp-1);
2524 std::string tmp(sp,l);
2525 yyextra->code->codify(tmp.c_str());
2526 nextCodeLine(yyscanner);
2527 }
2528 else
2529 {
2530 yyextra->code->codify(QCString(sp));
2531 done=TRUE;
2532 }
2533 }
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
static void nextCodeLine(yyscan_t yyscanner)
Definition code.l:2490
#define TRUE
Definition qcstring.h:37
2534}

References QCString::data(), DBG_CTX, FALSE, QCString::isEmpty(), nextCodeLine(), qPrint(), and TRUE.

Referenced by codifyLines(), codifyMapLines(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFuncLink(), generateLink(), generateMemberLink(), generateMemLink(), generatePHPVariableLink(), handleCCode(), writeFuncProto(), writeObjCMethodCall(), and writeProcessProto().

◆ countLines()

static int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3465 of file code.l.

3466{
3467 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3468 const char *p=yyextra->inputString;
3469 char c = 0;
3470 int count=1;
3471 while ((c=*p))
3472 {
3473 p++ ;
3474 if (c=='\n') count++;
3475 }
3476 if (p>yyextra->inputString && *(p-1)!='\n')
3477 { // last line does not end with a \n, so we add an extra
3478 count++;
3479 }
3480 return count;
3481}

Referenced by CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ endCodeFold()

static void endCodeFold ( yyscan_t yyscanner)
static

Definition at line 2333 of file code.l.

2334{
2335 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2336 while (!yyextra->foldStack.empty())
2337 {
2338 const Definition *dd = yyextra->foldStack.back();
2339 if (dd->getEndBodyLine()+1==yyextra->yyLineNr) // +1 to close the section after the end of the body
2340 {
2341 yyextra->code->endFold();
2342 //fprintf(stderr,"%d: end codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(dd->name()),dd->getStartDefLine(),dd->getEndBodyLine());
2343 yyextra->foldStack.pop_back();
2344 }
2345 else
2346 {
2347 //fprintf(stderr,"no end of block dd=%s end=%d\n",qPrint(dd->qualifiedName()),dd->getEndBodyLine());
2348 break;
2349 }
2350 }
2351}

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

static void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2481 of file code.l.

2482{
2483 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2484 DBG_CTX((stderr,"endCodeLine(%d)\n",yyextra->yyLineNr));
2485 endFontClass(yyscanner);
2486 yyextra->code->endCodeLine();
2487 yyextra->insideCodeLine = false;
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
Definition code.l:3483
2488}

References DBG_CTX, and endFontClass().

Referenced by nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ endFontClass()

static void endFontClass ( yyscan_t yyscanner,
bool specialComment = false )
static

Definition at line 3483 of file code.l.

3484{
3485 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3486 if (yyextra->currentFontClass)
3487 {
3488 yyextra->code->endFontClass();
3489 yyextra->currentFontClass=nullptr;
3490 }
3491 if (specialComment && yyextra->insideSpecialComment)
3492 {
3493 yyextra->code->endSpecialComment();
3494 yyextra->insideSpecialComment = false;
3495 }
3496}

Referenced by checkVhdlString(), endCodeLine(), endCodeLine(), endCodeLine(), endCodeLine(), endCodeLine(), endCodeLine(), endCodeLine(), startFontClass(), startFontClass(), startFontClass(), startFontClass(), startFontClass(), startFontClass(), startFontClass(), writeFont(), writeObjCMethodCall(), and writeWord().

◆ escapeComment()

static QCString escapeComment ( yyscan_t yyscanner,
const char * s )
static

Definition at line 3914 of file code.l.

3915{
3916 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3917 QCString result;
3918 result.sprintf("$d%d",yyextra->currentCommentId);
3919 yyextra->commentMap.emplace(yyextra->currentCommentId,s);
3920 yyextra->currentCommentId++;
3921 return result;
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
3922}

References QCString::sprintf().

◆ escapeName()

static QCString escapeName ( yyscan_t yyscanner,
const char * s )
static

Definition at line 3884 of file code.l.

3885{
3886 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3887 QCString result;
3888 result.sprintf("$n%d",yyextra->currentNameId);
3889 yyextra->nameMap.emplace(yyextra->currentNameId,s);
3890 yyextra->currentNameId++;
3891 return result;
3892}

References QCString::sprintf().

◆ escapeObject()

static QCString escapeObject ( yyscan_t yyscanner,
const char * s )
static

Definition at line 3894 of file code.l.

3895{
3896 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3897 QCString result;
3898 result.sprintf("$o%d",yyextra->currentObjId);
3899 yyextra->objectMap.emplace(yyextra->currentObjId,s);
3900 yyextra->currentObjId++;
3901 return result;
3902}

References QCString::sprintf().

◆ escapeWord()

static QCString escapeWord ( yyscan_t yyscanner,
const char * s )
static

Definition at line 3904 of file code.l.

3905{
3906 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3907 QCString result;
3908 result.sprintf("$w%d",yyextra->currentWordId);
3909 yyextra->wordMap.emplace(yyextra->currentWordId,s);
3910 yyextra->currentWordId++;
3911 return result;
3912}

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

static bool generateClassMemberLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const Definition * def,
const QCString & memName )
static

Definition at line 3201 of file code.l.

3205{
3206 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3207 if (def && def->definitionType()==Definition::TypeClass)
3208 {
3209 const ClassDef *cd = toClassDef(def);
3210 const MemberDef *xmd = cd->getMemberByName(memName);
3211 DBG_CTX((stderr,"generateClassMemberLink(class=%s,member=%s)=%p\n",qPrint(def->name()),qPrint(memName),(void*)xmd));
3212 if (xmd)
3213 {
3214 return generateClassMemberLink(yyscanner,ol,xmd,memName);
3215 }
3216 else
3217 {
3218 const Definition *innerDef = cd->findInnerCompound(memName);
3219 if (innerDef)
3220 {
3221 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3222 addToSearchIndex(yyscanner,memName);
3223 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3224 return TRUE;
3225 }
3226 }
3227 }
3228 else if (def && def->definitionType()==Definition::TypeNamespace)
3229 {
3230 const NamespaceDef *nd = toNamespaceDef(def);
3231 DBG_CTX((stderr,"Looking for %s inside namespace %s\n",qPrint(memName),qPrint(nd->name())));
3232 const Definition *innerDef = nd->findInnerCompound(memName);
3233 if (innerDef)
3234 {
3235 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3236 addToSearchIndex(yyscanner,memName);
3237 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3238 return TRUE;
3239 }
3240 }
3241 return FALSE;
virtual const MemberDef * getMemberByName(const QCString &) const =0
Returns the member with the given name.
virtual const Definition * findInnerCompound(const QCString &name) const =0
virtual const QCString & name() const =0
ClassDef * toClassDef(Definition *d)
static void writeMultiLineCodeLink(yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const QCString &text)
Definition code.l:2559
static bool generateClassMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const QCString &memName)
Definition code.l:3139
NamespaceDef * toNamespaceDef(Definition *d)
3242}

References addToSearchIndex(), DBG_CTX, Definition::definitionType(), FALSE, Definition::findInnerCompound(), generateClassMemberLink(), ClassDef::getMemberByName(), Definition::name(), qPrint(), toClassDef(), toNamespaceDef(), TRUE, Definition::TypeClass, Definition::TypeNamespace, and writeMultiLineCodeLink().

◆ generateClassMemberLink() [2/2]

static bool generateClassMemberLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const MemberDef * xmd,
const QCString & memName )
static

Definition at line 3139 of file code.l.

3143{
3144 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3145 // extract class definition of the return type in order to resolve
3146 // a->b()->c() like call chains
3147
3148 DBG_CTX((stderr,"type='%s' args='%s' class=%s\n",
3149 qPrint(xmd->typeString()),qPrint(xmd->argsString()),
3150 qPrint(xmd->getClassDef()->name())));
virtual QCString typeString() const =0
virtual const ClassDef * getClassDef() const =0
virtual QCString argsString() const =0
3151
3152 if (yyextra->exampleBlock)
3153 {
3154 std::lock_guard<std::mutex> lock(Doxygen::addExampleMutex);
3155 QCString anchor;
3156 anchor.sprintf("a%d",yyextra->anchorCount);
3157 DBG_CTX((stderr,"addExampleFile(%s,%s,%s)\n",qPrint(anchor),qPrint(yyextra->exampleName),
3158 qPrint(yyextra->exampleFile)));
3159 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(xmd));
3160 if (mdm && mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
3161 {
3162 ol.writeCodeAnchor(anchor);
3163 yyextra->anchorCount++;
3164 }
3165 }
static std::mutex addExampleMutex
Definition doxygen.h:142
virtual bool addExample(const QCString &anchor, const QCString &name, const QCString &file)=0
void writeCodeAnchor(const QCString &name)
Definition outputlist.h:275
MemberDefMutable * toMemberDefMutable(Definition *d)
3166
3167 const ClassDef *typeClass = stripClassName(yyscanner,removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope());
3168 DBG_CTX((stderr,"%s -> typeName=%p\n",qPrint(xmd->typeString()),(void*)typeClass));
3169 yyextra->theCallContext.setScope(ScopedTypeVariant(typeClass));
virtual Definition * getOuterScope() const =0
static const ClassDef * stripClassName(yyscan_t yyscanner, const QCString &s, const Definition *d)
Definition code.l:2649
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:172
3170
3171 const Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
3172 xmd->getFileDef() : xmd->getOuterScope();
3173 if (xmd->getGroupDef()) xd = xmd->getGroupDef();
3174 if (xd && xd->isLinkable())
3175 {
virtual bool isLinkable() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
3176
3177 DBG_CTX((stderr,"yyextra->currentDefinition=%p yyextra->currentMemberDef=%p xmd=%p yyextra->insideBody=%d\n",
3178 (void*)yyextra->currentDefinition,(void*)yyextra->currentMemberDef,(void*)xmd,yyextra->insideBody));
3179
3180 if (xmd->templateMaster()) xmd = xmd->templateMaster();
virtual const MemberDef * templateMaster() const =0
3181
3182 if (xmd->isLinkable())
3183 {
3184 // add usage reference
3185 if (yyextra->currentDefinition && yyextra->currentMemberDef &&
3186 yyextra->insideBody && yyextra->collectXRefs)
3187 {
3188 addDocCrossReference(yyextra->currentMemberDef,xmd);
3189 }
void addDocCrossReference(const MemberDef *s, const MemberDef *d)
3190
3191 // write the actual link
3192 writeMultiLineCodeLink(yyscanner,ol,xmd,memName);
3193 addToSearchIndex(yyscanner,memName);
3194 return TRUE;
3195 }
3196 }
3197
3198 return FALSE;
3199}

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), MemberDef::argsString(), DBG_CTX, FALSE, MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), Definition::getOuterScope(), Doxygen::globalScope, Definition::isLinkable(), Definition::name(), qPrint(), removeAnonymousScopes(), QCString::sprintf(), stripClassName(), toMemberDefMutable(), TRUE, MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by generateClassMemberLink(), generateFunctionLink(), and generateMemberLink().

◆ generateClassOrGlobalLink() [1/2]

static void generateClassOrGlobalLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const char * clName,
bool typeOnly = FALSE,
bool varOnly = FALSE )
static

Definition at line 3133 of file code.l.

3135{
3136 generateClassOrGlobalLink(yyscanner,ol,QCString(clName),typeOnly,varOnly);
static void generateClassOrGlobalLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE, bool varOnly=FALSE)
Definition code.l:2916
3137}

References generateClassOrGlobalLink().

◆ generateClassOrGlobalLink() [2/2]

static void generateClassOrGlobalLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const QCString & clName,
bool typeOnly = FALSE,
bool varOnly = FALSE )
static

Definition at line 2916 of file code.l.

2921{
2922 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2923 QCString scopeName=scName;
2924 if (!scopeName.isEmpty() && scopeName[0]=='~') // correct for matching negated values i.s.o. destructors.
2925 {
2926 scopeName=scopeName.mid(1);
2927 }
2928 if (scopeName.isEmpty())
2929 {
2930 yyextra->code->codify("~");
2931 return;
2932 }
2933 if (yyextra->insideProtocolList) // for Obj-C
2934 {
2935 scopeName+="-p";
2936 }
2937 if (yyextra->lang==SrcLangExt::PHP)
2938 {
2939 scopeName = substitute(scopeName,"\\","::"); // for PHP namespaces
2940 }
2941 else if (yyextra->lang==SrcLangExt::CSharp || yyextra->lang==SrcLangExt::Java)
2942 {
2943 scopeName = substitute(scopeName,".","::"); // for C#/Java namespaces
2944 }
2945 if (!yyextra->scopeName.isEmpty())
2946 {
2947 scopeName = yyextra->scopeName+"::"+scopeName;
2948 }
2949 const ScopedTypeVariant *lcd=nullptr;
2950 const Definition *sym=nullptr;
2951 bool isLocal=FALSE;
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
@ CSharp
Definition types.h:46
2952
2953 DBG_CTX((stderr,"generateClassOrGlobalLink(name=%s) yyextra->scopeName=%s scopeName=%s\n",qPrint(scName),qPrint(yyextra->scopeName),qPrint(scopeName)));
2954 if (!yyextra->isPrefixedWithThis || (lcd=yyextra->theVarContext.findVariable(scopeName))==nullptr) // not a local variable
2955 {
2956 int i=scopeName.find('<');
2957 QCString bareName = scopeName;
2958 if (i!=-1) bareName = bareName.left(i);
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString left(size_t len) const
Definition qcstring.h:214
2959
2960 auto checkForSymbol = [&yyg,&bareName,&scopeName](const Definition *parent,
2961 const Definition *&sym_)
2962 {
2963 sym_ = yyextra->symbolResolver.resolveSymbol(parent,scopeName,QCString(),false,true);
2964 DBG_CTX((stderr,"non-local variable name=%s sym=%s!\n",
2965 qPrint(scopeName),sym_?qPrint(sym_->name()):"<none>"));
2966 if (sym_==nullptr && !bareName.isEmpty())
2967 {
2968 DBG_CTX((stderr,"bareName=%s\n",qPrint(bareName)));
2969 if (bareName!=scopeName)
2970 {
2971 sym_ = yyextra->symbolResolver.resolveSymbol(parent,bareName,QCString(),false,true); // try unspecialized version
2972 }
2973 }
2974 };
2975 const Definition *d = yyextra->currentDefinition;
2976 DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",d?qPrint(d->name()):"<none>",yyextra->sourceFileDef?qPrint(yyextra->sourceFileDef->name()):"<none>"));
2977 checkForSymbol(d,sym);
2978 if (sym==nullptr && d && d->definitionType()==Definition::TypeClass)
2979 {
2980 const FileDef *fd = toClassDef(d)->getFileDef();
2981 if (fd)
2982 {
2983 // also check for using directive in the file that defines this class
2984 for (const auto &nd : fd->getUsedNamespaces())
2985 {
2986 checkForSymbol(nd,sym);
2987 if (sym) break;
2988 }
2989 }
2990 }
2991 if (sym==nullptr)
2992 {
2993 // also check via using directive
2994 for (const auto &[usingName,namespaceDef] : yyextra->theUsingContext)
2995 {
2996 checkForSymbol(namespaceDef,sym);
2997 if (sym) break;
2998 }
2999 }
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
A model of a file symbol.
Definition filedef.h:99
virtual const LinkedRefMap< NamespaceDef > & getUsedNamespaces() const =0
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1310
3000
3001 const NamespaceDef *nd = getResolvedNamespace(scopeName);
3002 if (nd && nd->isLinkable())
3003 {
3004 yyextra->theCallContext.setScope(ScopedTypeVariant(nd));
3005 addToSearchIndex(yyscanner,scopeName);
3006 writeMultiLineCodeLink(yyscanner,*yyextra->code,nd,scName);
3007 return;
3008 }
3009 const ConceptDef *conceptDef = getResolvedConcept(d,bareName);
3010 if (conceptDef && conceptDef->isLinkable())
3011 {
3012 yyextra->theCallContext.setScope(ScopedTypeVariant(conceptDef));
3013 addToSearchIndex(yyscanner,scopeName);
3014 writeMultiLineCodeLink(yyscanner,*yyextra->code,conceptDef,scName);
3015 return;
3016 }
3017 DBG_CTX((stderr,"sym=%s\n",sym?qPrint(sym->name()):"<none>"));
3018 DBG_CTX((stderr,"is found as a type sym=%s nd=%s\n",
3019 sym?qPrint(sym->name()):"<null>",
3020 nd?qPrint(nd->name()):"<null>"));
3021 if (sym==nullptr) // also see if it is variable or enum or enum value
3022 {
3023 if (getLink(yyscanner,yyextra->scopeName,scName,ol,scName,varOnly))
3024 {
3025 return;
3026 }
3027 }
3028 }
3029 else
3030 {
3031 DBG_CTX((stderr,"local variable!\n"));
3032 if (!lcd->isDummy())
3033 {
3034 DBG_CTX((stderr,"non-dummy context lcd=%s!\n",qPrint(lcd->name())));
3035 yyextra->theCallContext.setScope(*lcd);
QCString name() const
static bool getLink(yyscan_t yyscanner, const QCString &className, const QCString &memberName, OutputCodeList &ol, const QCString &text=QCString(), bool varOnly=FALSE)
Definition code.l:2891
ConceptDef * getResolvedConcept(const Definition *d, const QCString &name)
NamespaceDef * getResolvedNamespace(const QCString &name)
3036
3037 // to following is needed for links to a global variable, but is
3038 // no good for a link to a local variable that is also a global symbol.
3039
3040 //if (getLink(yyscanner,yyextra->scopeName,scName,ol,scName))
3041 //{
3042 //return;
3043 //}
3044 }
3045 isLocal=TRUE;
3046 DBG_CTX((stderr,"is a local variable sym=%p!\n",(void*)sym));
3047 }
3048 yyextra->isPrefixedWithThis = FALSE; // discard the "this" prefix for the next calls
3049
3050 if (sym && sym->isLinkable()) // is it a linkable class
3051 {
3052 DBG_CTX((stderr,"is linkable class %s\n",qPrint(scName)));
3053 if (yyextra->exampleBlock)
3054 {
3055 std::lock_guard<std::mutex> lock(Doxygen::addExampleMutex);
3056 QCString anchor;
3057 anchor.sprintf("_a%d",yyextra->anchorCount);
3058 DBG_CTX((stderr,"addExampleClass(%s,%s,%s)\n",qPrint(anchor),qPrint(yyextra->exampleName),
3059 qPrint(yyextra->exampleFile)));
3061 {
3062 ClassDefMutable *cdm = toClassDefMutable(const_cast<Definition*>(sym));
3063 if (cdm && cdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
3064 {
3065 ol.writeCodeAnchor(anchor);
3066 yyextra->anchorCount++;
3067 }
3068 }
3069 }
3070 writeMultiLineCodeLink(yyscanner,ol,sym,scName);
3071 addToSearchIndex(yyscanner,scopeName);
3072 yyextra->theCallContext.setScope(ScopedTypeVariant(sym));
3073 if (sym && sym->definitionType()==Definition::TypeMember)
3074 {
3075 const MemberDef *md = toMemberDef(sym);
3076 const Definition *d = sym->getOuterScope()==Doxygen::globalScope ?
3077 md->getFileDef() : md->getOuterScope();
3078 if (md->getGroupDef()) d = md->getGroupDef();
3079 if (d && d->isLinkable() && md->isLinkable() &&
3080 yyextra->currentMemberDef && yyextra->collectXRefs)
3081 {
3082 addDocCrossReference(yyextra->currentMemberDef,md);
3083 }
3084 }
3085 }
3086 else // not a class, maybe a global member
3087 {
3088 const MemberDef *md = sym && sym->definitionType()==Definition::TypeMember ? toMemberDef(sym) : nullptr;
3089 DBG_CTX((stderr,"class %s not linkable! cd=%p typeOnly=%d\n",qPrint(scName),(void*)sym,typeOnly));
3090 if (!isLocal && (md || (!sym && !typeOnly))) // not a class, see if it is a global enum/variable/typedef.
3091 {
3092 if (md==nullptr) // not found as a typedef
3093 {
3094 md = setCallContextForVar(yyscanner,scName);
3095 DBG_CTX((stderr,"setCallContextForVar(%s) md=%p yyextra->currentDefinition=%s\n",qPrint(scName),(void*)md,yyextra->currentDefinition ? qPrint(yyextra->currentDefinition->name()) : "<none>"));
3096 if (md && yyextra->currentDefinition)
3097 {
3098 DBG_CTX((stderr,"%s accessible from %s? %d md->getOuterScope=%s\n",
3099 qPrint(md->name()),qPrint(yyextra->currentDefinition->name()),
3100 yyextra->symbolResolver.isAccessibleFrom(yyextra->currentDefinition,md),
3101 qPrint(md->getOuterScope()->name())));
3102 }
virtual bool addExample(const QCString &anchor, const QCString &name, const QCString &file)=0
ClassDefMutable * toClassDefMutable(Definition *d)
static const MemberDef * setCallContextForVar(yyscan_t yyscanner, const QCString &name)
Definition code.l:2680
3103
3104 if (md && yyextra->currentDefinition &&
3105 yyextra->symbolResolver.isAccessibleFrom(yyextra->currentDefinition,md)==-1)
3106 {
3107 md=nullptr; // variable not accessible
3108 }
3109 }
3110 if (md && (!varOnly || md->isVariable()))
3111 {
3112 DBG_CTX((stderr,"is a global md=%p yyextra->currentDefinition=%s linkable=%d\n",(void*)md,yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>",md->isLinkable()));
3113 if (md->isLinkable())
3114 {
3115 writeMultiLineCodeLink(yyscanner,ol,md,scName);
3116 addToSearchIndex(yyscanner,scName);
3117 if (yyextra->currentMemberDef && yyextra->collectXRefs)
3118 {
3119 addDocCrossReference(yyextra->currentMemberDef,md);
3120 }
3121 return;
3122 }
3123 }
3124 }
3125
3126 // nothing found, just write out the word
3127 DBG_CTX((stderr,"not found!\n"));
3128 codifyLines(yyscanner,scName);
3129 addToSearchIndex(yyscanner,scName);
3130 }
3131}

References addDocCrossReference(), ClassDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), codifyLines(), CSharp, DBG_CTX, Definition::definitionType(), FALSE, QCString::find(), ClassDef::getFileDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), getLink(), Definition::getOuterScope(), getResolvedConcept(), getResolvedNamespace(), FileDef::getUsedNamespaces(), Doxygen::globalScope, ScopedTypeVariant::isDummy(), QCString::isEmpty(), Definition::isLinkable(), MemberDef::isVariable(), Java, QCString::left(), QCString::mid(), Definition::name(), ScopedTypeVariant::name(), parent(), PHP, qPrint(), setCallContextForVar(), QCString::sprintf(), substitute(), toClassDef(), toClassDefMutable(), toMemberDef(), TRUE, Definition::TypeClass, Definition::TypeMember, OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by codifyMapLines(), generateClassOrGlobalLink(), generateFunctionLink(), generateFunctionLink(), and writeWord().

◆ generateFunctionLink() [1/2]

static void generateFunctionLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const char * funcName )
static

Definition at line 3459 of file code.l.

3460{
3461 generateFunctionLink(yyscanner,ol,QCString(funcName));
static void generateFunctionLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
Definition code.l:3350
3462}

References generateFunctionLink().

◆ generateFunctionLink() [2/2]

static void generateFunctionLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const QCString & funcName )
static

Definition at line 3350 of file code.l.

3351{
3352 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3353 //CodeClassDef *ccd=nullptr;
3354 QCString locScope=yyextra->scopeName;
3355 QCString locFunc=removeRedundantWhiteSpace(funcName);
3356 if (yyextra->lang==SrcLangExt::PHP && locFunc.startsWith("self::")) locFunc=locFunc.mid(4);
3357 QCString funcScope;
3358 QCString funcWithScope=locFunc;
3359 QCString funcWithFullScope=locFunc;
3360 QCString fullScope=locScope;
3361 DBG_CTX((stderr,"*** locScope=%s locFunc=%s\n",qPrint(locScope),qPrint(locFunc)));
3362 int len=2;
3363 int i=locFunc.findRev("::");
3364 if (yyextra->currentMemberDef && yyextra->currentMemberDef->resolveAlias()->getClassDef() &&
3365 funcName==yyextra->currentMemberDef->localName() &&
3366 yyextra->currentMemberDef->getDefLine()==yyextra->yyLineNr &&
3367 generateClassMemberLink(yyscanner,ol,yyextra->currentMemberDef,funcName)
3368 )
3369 {
3370 // special case where funcName is the name of a method that is also
3371 // defined on this line. In this case we can directly link to
3372 // yyextra->currentMemberDef, which is not only faster, but
3373 // in case of overloaded methods, this will make sure that we link to
3374 // the correct method, and thereby get the correct reimplemented relations.
3375 // See also bug 549022.
3376 goto exit;
3377 }
3378 if (i==-1) i=locFunc.findRev("."),len=1;
3379 if (i==-1) i=locFunc.findRev("\\"),len=1; // for PHP
3380 if (i>0)
3381 {
3382 funcScope=locFunc.left(i);
3383 locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace();
3384 int ts=locScope.find('<'); // start of template
3385 int te=locScope.findRev('>'); // end of template
3386 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
3387 if (ts!=-1 && te!=-1 && te>ts)
3388 {
3389 // remove template from scope
3390 locScope=locScope.left(ts)+locScope.right(locScope.length()-te-1);
3391 }
3392 ts=funcScope.find('<'); // start of template
3393 te=funcScope.findRev('>'); // end of template
3394 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
3395 if (ts!=-1 && te!=-1 && te>ts)
3396 {
3397 // remove template from scope
3398 funcScope=funcScope.left(ts)+funcScope.right(funcScope.length()-te-1);
3399 }
3400 if (!funcScope.isEmpty())
3401 {
3402 funcWithScope = funcScope+"::"+locFunc;
3403 if (!locScope.isEmpty())
3404 {
3405 fullScope=locScope+"::"+funcScope;
3406 }
3407 }
3408 if (!locScope.isEmpty())
3409 {
3410 funcWithFullScope = locScope+"::"+funcWithScope;
3411 }
3412 }
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool startsWith(const char *s) const
Definition qcstring.h:492
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
QCString right(size_t len) const
Definition qcstring.h:219
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
3413
3414 if (!fullScope.isEmpty())
3415 {
3416 auto it = yyextra->codeClassMap.find(fullScope.str());
3417 if (it!=yyextra->codeClassMap.end())
3418 {
3419 ScopedTypeVariant ccd = it->second;
3420 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
3421 {
3422 for (const auto &bcName : ccd.localDef()->baseClasses())
3423 {
3424 if (getLink(yyscanner,bcName,locFunc,ol,funcName))
3425 {
3426 goto exit;
3427 }
3428 }
3429 }
3430 }
3431 }
std::vector< QCString > baseClasses() const
3432
3433 if (!locScope.isEmpty() && fullScope!=locScope)
3434 {
3435 auto it = yyextra->codeClassMap.find(locScope.str());
3436 if (it!=yyextra->codeClassMap.end())
3437 {
3438 ScopedTypeVariant ccd = it->second;
3439 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
3440 {
3441 for (const auto &bcName : ccd.localDef()->baseClasses())
3442 {
3443 if (getLink(yyscanner,bcName,funcWithScope,ol,funcName))
3444 {
3445 goto exit;
3446 }
3447 }
3448 }
3449 }
3450 }
3451 if (!getLink(yyscanner,locScope,funcWithScope,ol,funcName))
3452 {
3453 generateClassOrGlobalLink(yyscanner,ol,funcName);
3454 }
3455exit:
3456 return;
3457}

References LocalDef::baseClasses(), DBG_CTX, QCString::find(), QCString::findRev(), generateClassMemberLink(), generateClassOrGlobalLink(), getLink(), QCString::isEmpty(), QCString::left(), QCString::length(), ScopedTypeVariant::localDef(), QCString::mid(), PHP, qPrint(), removeRedundantWhiteSpace(), QCString::right(), QCString::startsWith(), QCString::str(), and QCString::stripWhiteSpace().

Referenced by generateFunctionLink().

◆ generateMemberLink()

static void generateMemberLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const QCString & varName,
const QCString & memName )
static

Definition at line 3244 of file code.l.

3248{
3249 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3250 DBG_CTX((stderr,"generateMemberLink(object=%s,mem=%s) classScope=%s\n",
3251 qPrint(varName),qPrint(memName),qPrint(yyextra->scopeName)));
3252
3253 if (varName.isEmpty()) return;
3254
3255 // look for the variable in the current context
3256 const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(varName);
3257 if (stv)
3258 {
3259 if (!stv->isDummy())
3260 {
3261 DBG_CTX((stderr,"Class found!\n"));
3262 if (getLink(yyscanner,stv->name(),memName,ol))
3263 {
3264 DBG_CTX((stderr,"Found result!\n"));
3265 return;
3266 }
3267 if (stv->localDef() && !stv->localDef()->baseClasses().empty())
3268 {
3269 for (const auto &bcName : stv->localDef()->baseClasses())
3270 {
3271 if (getLink(yyscanner,bcName,memName,ol))
3272 {
3273 DBG_CTX((stderr,"Found result!\n"));
3274 return;
3275 }
3276 }
3277 }
3278 }
3279 }
3280 else // variable not in current context, maybe it is in a parent context
3281 {
3282 const ClassDef *vcd = yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->scopeName,true);
3283 if (vcd && vcd->isLinkable())
3284 {
3285 DBG_CTX((stderr,"Found class %s for variable '%s'\n",qPrint(yyextra->scopeName),qPrint(varName)));
3286 MemberName *vmn=Doxygen::memberNameLinkedMap->find(varName);
3287 if (vmn==nullptr)
3288 {
3289 int vi = 0;
3290 QCString vn=varName;
3291 if ((vi=vn.findRev("::"))!=-1 || (vi=vn.findRev('.'))!=-1) // explicit scope A::b(), probably static member
3292 {
3293 const ClassDef *jcd = getClass(vn.left(vi));
3294 vn=vn.right(vn.length()-vi-2);
3295 vmn=Doxygen::memberNameLinkedMap->find(vn);
3296 //printf("Trying name '%s' scope=%s\n",qPrint(vn),qPrint(scope));
3297 if (vmn)
3298 {
3299 for (const auto &vmd : *vmn)
3300 {
3301 if (vmd->getClassDef()==jcd)
3302 {
3303 DBG_CTX((stderr,"Found variable type=%s\n",qPrint(vmd->typeString())));
3304 const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope());
3305 if (mcd && mcd->isLinkable())
3306 {
3307 if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return;
3308 }
3309 }
3310 }
3311 }
3312 }
3313 }
3314 if (vmn)
3315 {
3316 DBG_CTX((stderr,"There is a variable with name '%s'\n",qPrint(varName)));
3317 for (const auto &vmd : *vmn)
3318 {
3319 if (vmd->getClassDef()==vcd)
3320 {
3321 DBG_CTX((stderr,"Found variable type=%s\n",qPrint(vmd->typeString())));
3322 const ClassDef *mcd=stripClassName(yyscanner,vmd->typeString(),vmd->getOuterScope());
3323 if (mcd && mcd->isLinkable())
3324 {
3325 if (generateClassMemberLink(yyscanner,ol,mcd,memName)) return;
3326 }
3327 }
3328 }
3329 }
3330 }
3331 }
3332 // nothing found -> write result as is
3333 codifyLines(yyscanner,memName);
3334 addToSearchIndex(yyscanner,memName);
3335 return;
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
ClassDef * getClass(const QCString &n)
3336}

References addToSearchIndex(), LocalDef::baseClasses(), codifyLines(), DBG_CTX, QCString::findRev(), generateClassMemberLink(), getClass(), getLink(), ScopedTypeVariant::isDummy(), QCString::isEmpty(), Definition::isLinkable(), QCString::left(), QCString::length(), ScopedTypeVariant::localDef(), Doxygen::memberNameLinkedMap, ScopedTypeVariant::name(), qPrint(), QCString::right(), and stripClassName().

◆ generatePHPVariableLink()

static void generatePHPVariableLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const char * varName )
static

Definition at line 3338 of file code.l.

3339{
3340 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3341 QCString name(varName+7); // strip $this->
3342 name.prepend("$");
3343 DBG_CTX((stderr,"generatePHPVariableLink(%s) name=%s scope=%s\n",varName,qPrint(name),qPrint(yyextra->scopeName)));
3344 if (!getLink(yyscanner,yyextra->scopeName,name,ol,QCString(varName)))
3345 {
3346 codifyLines(yyscanner,varName);
3347 }
3348}

References codifyLines(), DBG_CTX, getLink(), QCString::prepend(), and qPrint().

◆ getLexerFILE()

static const char * getLexerFILE ( )
inlinestatic

Definition at line 268 of file code.l.

268{return __FILE__;}

◆ getLink()

static bool getLink ( yyscan_t yyscanner,
const QCString & className,
const QCString & memberName,
OutputCodeList & ol,
const QCString & text = QCString(),
bool varOnly = FALSE )
static

Definition at line 2891 of file code.l.

2897{
2898 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2899 DBG_CTX((stderr,"getLink(%s,%s) yyextra->curClassName=%s\n",
2900 qPrint(className),qPrint(memberName),qPrint(yyextra->curClassName)));
2901 QCString m=removeRedundantWhiteSpace(memberName);
2902 QCString c=className;
2903 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2904 {
2905 if (!yyextra->curClassName.isEmpty())
2906 {
2907 if (!c.isEmpty()) c.prepend("::");
2908 c.prepend(yyextra->curClassName);
2909 return getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly);
2910 }
2911 return FALSE;
2912 }
2913 return TRUE;
QCString & prepend(const char *s)
Definition qcstring.h:407
static bool getLinkInScope(yyscan_t yyscanner, const QCString &c, const QCString &m, const QCString &memberText, OutputCodeList &ol, const QCString &text, bool varOnly=FALSE)
Definition code.l:2807
2914}

References DBG_CTX, FALSE, getLinkInScope(), QCString::isEmpty(), QCString::prepend(), qPrint(), removeRedundantWhiteSpace(), and TRUE.

Referenced by generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFunctionLink(), generateFunctionLink(), generateLink(), generateMemberLink(), and generatePHPVariableLink().

◆ getLinkInScope()

static bool getLinkInScope ( yyscan_t yyscanner,
const QCString & c,
const QCString & m,
const QCString & memberText,
OutputCodeList & ol,
const QCString & text,
bool varOnly = FALSE )
static

Definition at line 2807 of file code.l.

2815{
2816 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2817 DBG_CTX((stderr,"getLinkInScope: trying '%s'::'%s' varOnly=%d\n",qPrint(c),qPrint(m),varOnly));
2818 GetDefInput input(c,m,"()");
2819 input.currentFile = yyextra->sourceFileDef;
2820 input.insideCode = true;
2821 GetDefResult result = getDefs(input);
2822 DBG_CTX((stderr,"scopeNameLengthStack.size()=%zu\n",yyextra->scopeNameLengthStack.size()));
2823 if (!result.found && !yyextra->scopeNameLengthStack.empty() && c==yyextra->scopeName)
2824 {
2825 QCString localName = yyextra->scopeName.mid(yyextra->scopeNameLengthStack[0]+2); // try also without leading scope
2826 auto it = yyextra->codeClassMap.find(localName.str());
2827 if (it!=yyextra->codeClassMap.end())
2828 {
2829 ScopedTypeVariant ccd = it->second;
2830 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
2831 {
2832 for (const auto &bcName : ccd.localDef()->baseClasses())
2833 {
2834 DBG_CTX((stderr,"trying lookup via base class %s\n",qPrint(bcName)));
2835 input.scopeName = bcName;
2836 result = getDefs(input);
2837 if (result.found) break;
2838 }
2839 }
2840 }
2841 }
2842 if (result.found && (!varOnly || result.md->isVariable()))
2843 {
2844 if (result.md->isLinkable())
2845 {
2846 DBG_CTX((stderr,"found it %s!\n",qPrint(result.md->qualifiedName())));
2847 if (yyextra->exampleBlock)
2848 {
2849 std::lock_guard<std::mutex> lock(Doxygen::addExampleMutex);
2850 QCString anchor;
2851 anchor.sprintf("a%d",yyextra->anchorCount);
2852 DBG_CTX((stderr,"addExampleFile(%s,%s,%s)\n",qPrint(anchor),qPrint(yyextra->exampleName),
2853 qPrint(yyextra->exampleFile)));
2854 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(result.md));
2855 if (mdm && mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
2856 {
2857 ol.writeCodeAnchor(anchor);
2858 yyextra->anchorCount++;
2859 }
2860 }
virtual QCString qualifiedName() const =0
virtual bool isVariable() const =0
const MemberDef * md
Definition util.h:125
bool found
Definition util.h:124
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2742
2861
2862 const Definition *d = result.md->getOuterScope()==Doxygen::globalScope ?
2863 result.md->resolveAlias()->getFileDef() : result.md->getOuterScope();
2864 if (result.md->resolveAlias()->getGroupDef()) d = result.md->resolveAlias()->getGroupDef();
2865 if (d && d->isLinkable())
2866 {
2867 const ClassDef *ncd = stripClassName(yyscanner,result.md->typeString(),result.md->getOuterScope());
2868 if (ncd)
2869 {
2870 yyextra->theCallContext.setScope(ScopedTypeVariant(ncd));
2871 }
2872 DBG_CTX((stderr,"yyextra->currentDefinition=%p yyextra->currentMemberDef=%p yyextra->insideBody=%d\n",
2873 (void*)yyextra->currentDefinition,(void*)yyextra->currentMemberDef,yyextra->insideBody));
virtual MemberDef * resolveAlias()=0
2874
2875 if (yyextra->currentDefinition && yyextra->currentMemberDef &&
2876 yyextra->insideBody && yyextra->collectXRefs)
2877 {
2878 addDocCrossReference(yyextra->currentMemberDef,result.md);
2879 }
2880 DBG_CTX((stderr,"d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",qPrint(d->getReference()),qPrint(d->getOutputFileBase()),qPrint(d->name()),qPrint(result.md->name())));
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
2881
2882 writeMultiLineCodeLink(yyscanner,ol,result.md, !text.isEmpty() ? text : memberText);
2883 addToSearchIndex(yyscanner,!text.isEmpty() ? text : memberText);
2884 return TRUE;
2885 }
2886 }
2887 }
2888 return FALSE;
2889}

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), LocalDef::baseClasses(), GetDefInput::currentFile, DBG_CTX, FALSE, QCString::find(), GetDefResult::found, getDefs(), MemberDef::getFileDef(), MemberDef::getGroupDef(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), Doxygen::globalScope, GetDefInput::insideCode, QCString::isEmpty(), Definition::isLinkable(), MemberDef::isVariable(), ScopedTypeVariant::localDef(), GetDefResult::md, QCString::mid(), Definition::name(), qPrint(), Definition::qualifiedName(), MemberDef::resolveAlias(), GetDefInput::scopeName, QCString::sprintf(), QCString::str(), stripClassName(), toMemberDefMutable(), TRUE, MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by getLink(), and getLink().

◆ incrementFlowKeyWordCount()

static void incrementFlowKeyWordCount ( yyscan_t yyscanner)
static

Definition at line 2541 of file code.l.

2542{
2543 std::lock_guard<std::mutex> lock(Doxygen::countFlowKeywordsMutex);
2544 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2545 if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction())
2546 {
2547 MemberDefMutable *md = toMemberDefMutable(const_cast<MemberDef*>(yyextra->currentMemberDef));
2548 if (md)
2549 {
2551 }
2552 }
static std::mutex countFlowKeywordsMutex
Definition doxygen.h:141
virtual void incrementFlowKeyWordCount()=0
2553}

References Doxygen::countFlowKeywordsMutex, MemberDefMutable::incrementFlowKeyWordCount(), and toMemberDefMutable().

◆ isCastKeyword()

static bool isCastKeyword ( const char * s)
static

Definition at line 3965 of file code.l.

3966{
3967 QCString s(keyword);
3968 int i=s.find('<');
3969 if (i==-1) return FALSE;
3970 QCString kw = s.left(i).stripWhiteSpace();
3971 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3972}

References FALSE, QCString::find(), QCString::left(), and QCString::stripWhiteSpace().

◆ nextCodeLine()

static void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2490 of file code.l.

2491{
2492 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2493 const char * fc = yyextra->currentFontClass;
2494 if (yyextra->insideCodeLine)
2495 {
2496 endCodeLine(yyscanner);
2497 }
2498 if (yyextra->yyLineNr<yyextra->inputLines)
2499 {
2500 yyextra->currentFontClass = fc;
2501 startCodeLine(yyscanner);
2502 }
static void endCodeLine(yyscan_t yyscanner)
Definition code.l:2481
static void startCodeLine(yyscan_t yyscanner)
Definition code.l:2412
2503}

References endCodeLine(), and startCodeLine().

Referenced by codifyLines(), codifyLines(), codifyLines(), codifyLines(), codifyLines(), codifyLines(), codifyLines(), writeMultiLineCodeLink(), writeMultiLineCodeLink(), writeMultiLineCodeLink(), and writeMultiLineCodeLink().

◆ popScope()

static void popScope ( yyscan_t yyscanner)
static

remove the top class/namespace name from the scope

Definition at line 2258 of file code.l.

2259{
2260 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2261 if (!yyextra->scopeNameLengthStack.empty())
2262 {
2263 int length = yyextra->scopeNameLengthStack.back();
2264 yyextra->scopeNameLengthStack.pop_back();
2265 yyextra->scopeName.resize(length);
2266 }
2267 else
2268 {
2269 //err("Too many end of scopes found!\n");
2270 }
2271 DBG_CTX((stderr,"popScope() result: '%s'\n",qPrint(yyextra->scopeName)));
2272}

References DBG_CTX, and qPrint().

Referenced by setClassScope().

◆ pushScope()

static void pushScope ( yyscan_t yyscanner,
const QCString & s )
static

add class/namespace name s to the scope

Definition at line 2240 of file code.l.

2241{
2242 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2243 yyextra->scopeNameLengthStack.push_back(int(yyextra->scopeName.length()));
2244 if (yyextra->scopeName.isEmpty() || leftScopeMatch(s,yyextra->scopeName))
2245 {
2246 yyextra->scopeName = s;
2247 }
2248 else
2249 {
2250 yyextra->scopeName += "::";
2251 yyextra->scopeName += s;
2252 }
2253 DBG_CTX((stderr,"pushScope(%s) result: '%s'\n",qPrint(s),qPrint(yyextra->scopeName)));
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:892
2254}

References DBG_CTX, leftScopeMatch(), and qPrint().

Referenced by setClassScope().

◆ restoreObjCContext()

static void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4021 of file code.l.

4022{
4023 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4024 DBG_CTX((stderr,"restore state=%d->%d\n",YY_START,yyextra->currentCtx->lexState));
4025 BEGIN(yyextra->currentCtx->lexState);
4026 yyextra->braceCount = yyextra->currentCtx->braceCount;
4027 if (!yyextra->contextStack.empty())
4028 {
4029 yyextra->currentCtx = yyextra->contextStack.top();
4030 yyextra->contextStack.pop();
4031 }
4032 else
4033 {
4034 yyextra->currentCtx = nullptr;
4035 DBG_CTX((stderr,"Trying to pop context while yyextra->contextStack is empty!\n"));
4036 }
4037}

References DBG_CTX.

◆ saveObjCContext()

static void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 3990 of file code.l.

3991{
3992 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3993 if (yyextra->currentCtx)
3994 {
3995 yyextra->currentCtx->format+=QCString().sprintf("$c%d",yyextra->currentCtxId);
3996 if (yyextra->braceCount==0 && YY_START==ObjCCall)
3997 {
3998 yyextra->currentCtx->objectTypeOrName=yyextra->currentCtx->format.mid(1);
3999 DBG_CTX((stderr,"new type=%s\n",qPrint(yyextra->currentCtx->objectTypeOrName)));
4000 }
4001 yyextra->contextStack.push(yyextra->currentCtx);
4002 }
4003 else
4004 {
4005 DBG_CTX((stderr,"Trying to save NULL context!\n"));
4006 }
4007 auto newCtx = std::make_unique<ObjCCallCtx>();
4008 newCtx->id = yyextra->currentCtxId;
4009 newCtx->lexState = YY_START;
4010 newCtx->braceCount = yyextra->braceCount;
4011 newCtx->objectType = nullptr;
4012 newCtx->objectVar = nullptr;
4013 newCtx->method = nullptr;
4014 DBG_CTX((stderr,"save state=%d\n",YY_START));
4015 yyextra->currentCtx = newCtx.get();
4016 yyextra->contextMap.emplace(yyextra->currentCtxId,std::move(newCtx));
4017 yyextra->braceCount = 0;
4018 yyextra->currentCtxId++;
4019}

References DBG_CTX, qPrint(), and QCString::sprintf().

◆ setCallContextForVar()

static const MemberDef * setCallContextForVar ( yyscan_t yyscanner,
const QCString & name )
static

Definition at line 2680 of file code.l.

2681{
2682 if (name.isEmpty()) return nullptr;
2683 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2684 DBG_CTX((stderr,"setCallContextForVar(%s) yyextra->scopeName=%s\n",qPrint(name),qPrint(yyextra->scopeName)));
2685
2686 int scopeEnd = name.findRev("::");
2687 if (scopeEnd!=-1) // name with explicit scope
2688 {
2689 QCString scope = name.left(scopeEnd);
2690 QCString locName = name.right(name.length()-scopeEnd-2);
2691 DBG_CTX((stderr,"explicit scope: name=%s scope=%s\n",qPrint(locName),qPrint(scope)));
2692 const ClassDef *mcd = getClass(scope);
2693 if (mcd && !locName.isEmpty())
2694 {
2695 const MemberDef *md=mcd->getMemberByName(locName);
2696 if (md)
2697 {
2698 DBG_CTX((stderr,"name=%s scope=%s\n",qPrint(locName),qPrint(scope)));
2699 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
2700 return md;
2701 }
2702 }
2703 else // check namespace as well
2704 {
2705 const NamespaceDef *mnd = getResolvedNamespace(scope);
2706 if (mnd && !locName.isEmpty())
2707 {
2708 const MemberDef *md=mnd->getMemberByName(locName);
2709 if (md)
2710 {
2711 DBG_CTX((stderr,"name=%s scope=%s\n",qPrint(locName),qPrint(scope)));
2712 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
2713 return md;
2714 }
2715 }
2716 }
2717 }
virtual const MemberDef * getMemberByName(const QCString &) const =0
2718
2719 const ScopedTypeVariant *mcv = yyextra->theVarContext.findVariable(name);
2720 if (mcv)
2721 {
2722 DBG_CTX((stderr,"local variable?\n"));
2723 if (!mcv->isDummy()) // locally found variable
2724 {
2725 DBG_CTX((stderr,"local var '%s' mcd=%s\n",qPrint(name),qPrint(mcv->name())));
2726 yyextra->theCallContext.setScope(*mcv);
2727 }
2728 }
2729 else
2730 {
2731 DBG_CTX((stderr,"class member? scope=%s\n",qPrint(yyextra->scopeName)));
2732 // look for a class member
2733 const ClassDef *mcd = getClass(yyextra->scopeName);
2734 if (mcd)
2735 {
2736 DBG_CTX((stderr,"Inside class %s\n",qPrint(mcd->name())));
2737 const MemberDef *md=mcd->getMemberByName(name);
2738 if (md)
2739 {
2740 DBG_CTX((stderr,"Found member %s\n",qPrint(md->name())));
2741 if (yyextra->scopeStack.empty() || yyextra->scopeStack.top()!=CLASSBLOCK)
2742 {
2743 DBG_CTX((stderr,"class member '%s' mcd=%s\n",qPrint(name),qPrint(mcd->name())));
2744 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
2745 }
2746 return md;
2747 }
2748 }
2749 }
#define CLASSBLOCK
Definition code.l:77
2750
2751 // look for a global member
2752 const MemberName *mn = Doxygen::functionNameLinkedMap->find(name);
2753 if (mn)
2754 {
2755 DBG_CTX((stderr,"global var '%s'\n",qPrint(name)));
2756 if (mn->size()==1) // global defined only once
2757 {
2758 const std::unique_ptr<MemberDef> &md=mn->front();
2759 if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef)
2760 {
2761 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
2762 return md.get();
2763 }
2764 return nullptr;
2765 }
2766 else if (mn->size()>1) // global defined more than once
2767 {
2768 for (const auto &md : *mn)
2769 {
2770 //printf("mn=%p md=%p md->getBodyDef()=%p yyextra->sourceFileDef=%p\n",
2771 // mn,md,
2772 // md->getBodyDef(),yyextra->sourceFileDef);
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
Ptr & front()
Definition membername.h:51
size_t size() const
Definition membername.h:48
2773
2774 // in case there are multiple members we could link to, we
2775 // only link to members if defined in the same file or
2776 // defined as external.
2777 if (!md->isStatic() || md->getBodyDef()==yyextra->sourceFileDef)
2778 {
2779 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,md->typeString(),md->getOuterScope())));
2780 DBG_CTX((stderr,"returning member %s in source file %s\n",qPrint(md->name()),qPrint(yyextra->sourceFileDef->name())));
2781 return md.get();
2782 }
2783 }
2784 return nullptr;
2785 }
2786 }
2787 return nullptr;
2788}

References CLASSBLOCK, DBG_CTX, QCString::findRev(), MemberName::front(), Doxygen::functionNameLinkedMap, getClass(), ClassDef::getMemberByName(), NamespaceDef::getMemberByName(), Definition::getOuterScope(), getResolvedNamespace(), ScopedTypeVariant::isDummy(), QCString::isEmpty(), QCString::left(), QCString::length(), Definition::name(), ScopedTypeVariant::name(), qPrint(), QCString::right(), MemberName::size(), stripClassName(), and MemberDef::typeString().

Referenced by generateClassOrGlobalLink().

◆ setClassScope()

static void setClassScope ( yyscan_t yyscanner,
const QCString & name )
static

Definition at line 2304 of file code.l.

2305{
2306 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2307 DBG_CTX((stderr,"setClassScope(%s)\n",qPrint(name)));
2308 QCString n=name;
2309 n=n.simplifyWhiteSpace();
2310 int ts=n.find('<'); // start of template
2311 int te=n.findRev('>'); // end of template
2312 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
2313 if (ts!=-1 && te!=-1 && te>ts)
2314 {
2315 // remove template from scope
2316 n=n.left(ts)+n.right(n.length()-te-1);
2317 }
2318 while (!yyextra->scopeNameLengthStack.empty())
2319 {
2320 popScope(yyscanner);
2321 }
2322 yyextra->scopeName.clear();
2323 int i;
2324 while ((i=n.find("::"))!=-1)
2325 {
2326 pushScope(yyscanner,n.left(i));
2327 n = n.mid(i+2);
2328 }
2329 pushScope(yyscanner,n);
2330 DBG_CTX((stderr,"--->New class scope '%s'\n",qPrint(yyextra->scopeName)));
static void pushScope(yyscan_t yyscanner, const QCString &s)
Definition code.l:2240
static void popScope(yyscan_t yyscanner)
Definition code.l:2258
2331}

References DBG_CTX, QCString::find(), QCString::findRev(), QCString::left(), QCString::length(), QCString::mid(), popScope(), pushScope(), qPrint(), QCString::right(), and QCString::simplifyWhiteSpace().

◆ setCurrentDoc()

static void setCurrentDoc ( yyscan_t yyscanner,
const QCString & anchor )
static

Definition at line 2274 of file code.l.

2275{
2276 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2277 if (Doxygen::searchIndex.enabled())
2278 {
2279 if (yyextra->searchCtx)
2280 {
2281 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
2282 }
2283 else
2284 {
2285 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,TRUE);
2286 }
2287 }
2288}

References FALSE, Doxygen::searchIndex, and TRUE.

Referenced by CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), XMLCodeParser::parseCode(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), and startCodeLine().

◆ setParameterList()

static void setParameterList ( yyscan_t yyscanner,
const MemberDef * md )
static

Definition at line 2632 of file code.l.

2633{
2634 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2635 for (const Argument &a : md->argumentList())
2636 {
2637 yyextra->parmName = a.name;
2638 yyextra->parmType = a.type;
2639 int i = yyextra->parmType.find('*');
2640 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2641 i = yyextra->parmType.find('&');
2642 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2643 yyextra->parmType.stripPrefix("const ");
2644 yyextra->parmType=yyextra->parmType.stripWhiteSpace();
2645 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
2646 }
virtual const ArgumentList & argumentList() const =0
This class contains the information about the argument of a function or template.
Definition arguments.h:27
2647}

References addVariable(), and MemberDef::argumentList().

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

static bool skipLanguageSpecificKeyword ( yyscan_t yyscanner,
const char * kw )
static

Definition at line 3924 of file code.l.

3925{
3926 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3927 static const std::unordered_set<std::string> non_cpp_keywords = {
3928 "__assume", "__super", "abstract", "function",
3929 "gcnew", "gcroot", "generic", "get",
3930 "internal", "null", "pin_ptr", "raise",
3931 "remove", "self", "set", "transient",
3932 "sealed"
3933 };
3934 static const std::unordered_set<std::string> non_java_keywords = {
3935 "alignas", "alignof", "and", "and_eq", "asm",
3936 "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto", "bitand",
3937 "bitor", "bool", "char8_t", "char16_t", "char32_t",
3938 "compl", "concept", "consteval", "constexpr", "constinit",
3939 "const_cast", "co_await", "co_return", "co_yield", "decltype",
3940 "delete", "dynamic_cast", "explicit", "export", "extern",
3941 "friend", "inline", "mutable", "namespace", "noexcept",
3942 "not", "not_eq", "nullptr", "operator", "or",
3943 "or_eq", "reflexpr", "register", "reinterpret_cast", "requires",
3944 "signed", "sizeof", "static_assert", "_Static_assert", "static_cast", "struct",
3945 "template", "thread_local", "typedef", "typeid", "typename",
3946 "union", "unsigned", "using", "virtual", "wchar_t",
3947 "xor", "xor_eq", "override", "sealed"
3948 };
3949 bool retval = false;
3950 switch (yyextra->lang)
3951 {
3952 case SrcLangExt::Cpp:
3953 retval = (non_cpp_keywords.find(keyword) != non_cpp_keywords.end());
3954 break;
3955 case SrcLangExt::Java:
3956 retval = (non_java_keywords.find(keyword) != non_java_keywords.end());
3957 break;
3958 default:
3959 retval = false;
3960 break;
3961 }
3962 return retval;
3963}

References Cpp, and Java.

◆ startCodeLine()

static void startCodeLine ( yyscan_t yyscanner)
static

start a new line of code, inserting a line number if yyextra->sourceFileDef is TRUE. If a definition starts at the current line, then the line number is linked to the documentation of that definition.

Definition at line 2412 of file code.l.

2413{
2414 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2415 //if (yyextra->currentFontClass) { yyextra->code->endFontClass(yyscanner); }
2416 if (yyextra->sourceFileDef && yyextra->lineNumbers)
2417 {
2418 //QCString lineNumber,lineAnchor;
2419 //lineNumber.sprintf("%05d",yyextra->yyLineNr);
2420 //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
2421
2422 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
2423 //printf("%s:startCodeLine(%d)=%p\n",qPrint(yyextra->sourceFileDef->name()),yyextra->yyLineNr,(void*)d);
2424 DBG_CTX((stderr,"%s:startCodeLine(%d)=%p\n",qPrint(yyextra->sourceFileDef->name()),yyextra->yyLineNr,(void*)d));
2425 if (!yyextra->includeCodeFragment && d)
2426 {
2427 yyextra->currentDefinition = d;
2428 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
2429 yyextra->insideBody = FALSE;
2430 yyextra->searchingForBody = TRUE;
2431 yyextra->realScope = d!=Doxygen::globalScope ? d->name() : "";
2432 yyextra->type.clear();
2433 yyextra->name.clear();
2434 yyextra->args.clear();
2435 yyextra->parmType.clear();
2436 yyextra->parmName.clear();
2437 DBG_CTX((stderr,"Real scope: '%s'\n",qPrint(yyextra->realScope)));
2438 yyextra->bodyCurlyCount = 0;
2439 QCString lineAnchor;
2440 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
2441 if (yyextra->currentMemberDef)
2442 {
2443 codeFolding(yyscanner,yyextra->currentMemberDef);
2444 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
2445 yyextra->currentMemberDef->getOutputFileBase(),
2446 yyextra->currentMemberDef->anchor(),
2447 yyextra->yyLineNr,!yyextra->includeCodeFragment);
2448 setCurrentDoc(yyscanner,lineAnchor);
2449 }
2450 else if (d->isLinkableInProject())
2451 {
2452 codeFolding(yyscanner,d);
2453 yyextra->code->writeLineNumber(d->getReference(),
2454 d->getOutputFileBase(),
2455 QCString(),yyextra->yyLineNr,!yyextra->includeCodeFragment);
2456 setCurrentDoc(yyscanner,lineAnchor);
2457 }
2458 else
2459 {
2460 codeFolding(yyscanner,nullptr);
2461 }
2462 }
2463 else
2464 {
2465 codeFolding(yyscanner,nullptr);
2466 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
2467 !yyextra->includeCodeFragment);
2468 }
2469 }
2470 DBG_CTX((stderr,"startCodeLine(%d)\n",yyextra->yyLineNr));
2471 yyextra->code->startCodeLine(yyextra->yyLineNr);
2472 yyextra->insideCodeLine = true;
2473 if (yyextra->currentFontClass)
2474 {
2475 yyextra->code->startFontClass(QCString(yyextra->currentFontClass));
2476 }
virtual bool isLinkableInProject() const =0
void clear()
Definition qcstring.h:169
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition code.l:2274
static void codeFolding(yyscan_t yyscanner, const Definition *d)
Definition code.l:2354
2477}

References QCString::clear(), codeFolding(), DBG_CTX, FALSE, Definition::getOutputFileBase(), Definition::getReference(), Doxygen::globalScope, Definition::isLinkableInProject(), Definition::name(), qPrint(), setCurrentDoc(), QCString::sprintf(), and TRUE.

Referenced by nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ startFontClass()

static void startFontClass ( yyscan_t yyscanner,
const char * s,
bool specialComment = false )
static

Definition at line 3498 of file code.l.

3499{
3500 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3501 endFontClass(yyscanner);
3502 if (specialComment)
3503 {
3504 yyextra->code->startSpecialComment();
3505 yyextra->insideSpecialComment = true;
3506 }
3507 yyextra->code->startFontClass(QCString(s));
3508 yyextra->currentFontClass=s;
3509}

References endFontClass().

Referenced by checkVhdlString(), writeFont(), writeObjCMethodCall(), and writeWord().

◆ startsWithKeyword()

static bool startsWithKeyword ( const QCString & str,
const QCString & kw )
static

Definition at line 2168 of file code.l.

2169{
2170 if (str.length()<kw.length()) return false; // string too short to match
2171 return str==kw || // exact match
2172 (str.startsWith(kw) && !isId(str.at(kw.length()))); // match that is not a substring
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:567
bool isId(int c)
Definition util.h:202
2173}

References QCString::at(), isId(), QCString::length(), and QCString::startsWith().

◆ stateToString()

static const char * stateToString ( int state)
static

References FALSE.

Referenced by scanner_abort().

◆ stripClassName()

static const ClassDef * stripClassName ( yyscan_t yyscanner,
const QCString & s,
const Definition * d )
static

Definition at line 2649 of file code.l.

2650{
2651 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2652 DBG_CTX((stderr,"stripClassName(scope=%s,type=%s) scopeName=%s\n",
2653 qPrint(d?d->name():""),qPrint(s),qPrint(yyextra->scopeName)));
2654 int pos=0;
2655 QCString type = s;
2656 QCString className;
2657 QCString templSpec;
2658 while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
2659 {
2660 QCString clName=className+templSpec;
2661 const ClassDef *cd=nullptr;
2662 if (!yyextra->scopeName.isEmpty())
2663 {
2664 cd=yyextra->symbolResolver.resolveClass(d,yyextra->scopeName+"::"+clName,true);
2665 }
2666 if (cd==nullptr)
2667 {
2668 cd=yyextra->symbolResolver.resolveClass(d,clName,true);
2669 }
2670 DBG_CTX((stderr,"stripClass trying '%s' = %p\n",qPrint(clName),(void*)cd));
2671 if (cd)
2672 {
2673 return cd;
2674 }
2675 }
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4566
2676
2677 return nullptr;
2678}

References DBG_CTX, extractClassNameFromType(), Definition::name(), and qPrint().

Referenced by generateClassMemberLink(), generateClassOrGlobalLink(), generateMemberLink(), getLinkInScope(), getLinkInScope(), setCallContextForVar(), updateCallContextForSmartPointer(), and writeObjCMethodCall().

◆ updateCallContextForSmartPointer()

static void updateCallContextForSmartPointer ( yyscan_t yyscanner)
static

Definition at line 2790 of file code.l.

2791{
2792 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2793 const Definition *d = yyextra->theCallContext.getScope().globalDef();
2794 //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? qPrint(d->name()) : "<none>");
2795 const MemberDef *md = nullptr;
2796 if (d && d->definitionType()==Definition::TypeClass && (md=(toClassDef(d))->isSmartPointer()))
2797 {
2798 const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope());
2799 if (ncd)
2800 {
2801 yyextra->theCallContext.setScope(ScopedTypeVariant(ncd));
2802 //printf("Found smart pointer call %s->%s!\n",qPrint(cd->name()),qPrint(ncd->name()));
2803 }
2804 }
2805}

References Definition::definitionType(), Definition::getOuterScope(), stripClassName(), toClassDef(), Definition::TypeClass, and MemberDef::typeString().

◆ writeMultiLineCodeLink()

static void writeMultiLineCodeLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const Definition * d,
const QCString & text )
static

writes a link to a fragment text that may span multiple lines, inserting line numbers for each line. If text contains newlines, the link will be split into multiple links with the same destination, one for each line.

Definition at line 2559 of file code.l.

2562{
2563 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2564 bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
2565 yyextra->tooltipManager.addTooltip(d);
2566 QCString ref = d->getReference();
2567 QCString file = d->getOutputFileBase();
2568 QCString anchor = d->anchor();
2569 QCString tooltip;
2570 if (!sourceTooltips) // fall back to simple "title" tooltips
2571 {
2572 tooltip = d->briefDescriptionAsTooltip();
2573 }
2574 bool done=FALSE;
2575 const char *p=text.data();
2576 while (!done)
2577 {
2578 const char *sp=p;
2579 char c = 0;
2580 while ((c=*p++) && c!='\n') { }
2581 if (c=='\n')
2582 {
2583 yyextra->yyLineNr++;
2584 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),qPrint(QCString(sp,p-sp-1))));
2585 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip);
2586 nextCodeLine(yyscanner);
2587 }
2588 else
2589 {
2590 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),sp));
2591 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp),tooltip);
2592 done=TRUE;
2593 }
2594 }
virtual QCString anchor() const =0
virtual QCString briefDescriptionAsTooltip() const =0
virtual CodeSymbolType codeSymbolType() const =0
void writeCodeLink(CodeSymbolType type, const QCString &ref, const QCString &file, const QCString &anchor, const QCString &name, const QCString &tooltip)
Definition outputlist.h:249
2595}

References Definition::anchor(), Definition::briefDescriptionAsTooltip(), Definition::codeSymbolType(), Config_getBool, QCString::data(), DBG_CTX, FALSE, Definition::getOutputFileBase(), Definition::getReference(), nextCodeLine(), qPrint(), TRUE, and OutputCodeList::writeCodeLink().

Referenced by findMemberLink(), generateClassMemberLink(), generateClassMemberLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFuncLink(), generateLink(), generateMemLink(), getLink(), getLinkInScope(), getLinkInScope(), and writeObjCMethodCall().

◆ writeObjCMethodCall()

static void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3514 of file code.l.

3515{
3516 if (ctx==nullptr) return;
3517 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3518 char c = 0;
3519 if (!ctx->methodName.isEmpty())
3520 {
3521 DBG_CTX((stderr,"writeObjCMethodCall(%s) obj=%s method=%s\n",
3523 if (!ctx->objectTypeOrName.isEmpty() && ctx->objectTypeOrName.at(0)!='$')
3524 {
3525 DBG_CTX((stderr,"Looking for object=%s method=%s\n",qPrint(ctx->objectTypeOrName),
3526 qPrint(ctx->methodName)));
3527 const ScopedTypeVariant *stv = yyextra->theVarContext.findVariable(ctx->objectTypeOrName);
3528 if (stv!=nullptr) // local variable
3529 {
3530 DBG_CTX((stderr," object is local variable\n"));
3531 if (stv->globalDef() && !ctx->methodName.isEmpty())
3532 {
3533 const ClassDef *cd = toClassDef(stv->globalDef());
3534 if (cd)
3535 {
3536 ctx->method = cd->getMemberByName(ctx->methodName);
3537 }
3538 DBG_CTX((stderr," class=%p method=%p\n",(void*)cd,(void*)ctx->method));
3539 }
3540 }
3541 }
3542 }
const Definition * globalDef() const
const MemberDef * method
Definition code.l:90
QCString objectTypeOrName
Definition code.l:86
QCString methodName
Definition code.l:85
QCString format
Definition code.l:91
3543
3544 DBG_CTX((stderr,"["));
3545 if (!ctx->format.isEmpty())
3546 {
3547 const char *p = ctx->format.data();
3548 bool skip = false;
3549 char skipChar = ' ';
3550 while ((c=*p++)) // for each character in ctx->format
3551 {
3552 if (skip)
3553 {
3554 char s[2];
3555 s[0]=c;s[1]=0;
3556 codifyLines(yyscanner,s);
3557 if (c==skipChar)
3558 {
3559 skip = false;
3560 skipChar = ' ';
3561 }
3562 else if (c=='\\')
3563 {
3564 c = *p++;
3565 s[0]=c;
3566 codifyLines(yyscanner,s);
3567 }
3568 }
3569 else if (c=='$')
3570 {
3571 char nc=*p++;
3572 if (nc=='$') // escaped $
3573 {
3574 yyextra->code->codify("$");
3575 }
3576 else // name fragment or reference to a nested call
3577 {
3578 if (nc=='n') // name fragment
3579 {
3580 nc=*p++;
3581 QCString refIdStr;
3582 while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
3583 p--;
3584 int refId=refIdStr.toInt();
3585 auto it = yyextra->nameMap.find(refId);
3586 if (it!=yyextra->nameMap.end())
3587 {
3588 QCString name = it->second;
3589 if (ctx->method && ctx->method->isLinkable())
3590 {
3591 writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->method,name);
3592 if (yyextra->currentMemberDef && yyextra->collectXRefs)
3593 {
3594 addDocCrossReference(yyextra->currentMemberDef,ctx->method);
3595 }
3596 }
3597 else
3598 {
3599 codifyLines(yyscanner,name);
3600 }
3601 }
3602 else
3603 {
3604 DBG_CTX((stderr,"Invalid name: id=%d\n",refId));
3605 }
3606 }
3607 else if (nc=='o') // reference to potential object name, e.g. 'self', or 'self.var1' or 'self.var1.var2'
3608 {
3609 nc=*p++;
3610 QCString refIdStr;
3611 while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
3612 p--;
3613 int refId=refIdStr.toInt();
3614 auto it = yyextra->objectMap.find(refId);
3615 if (it!=yyextra->objectMap.end())
3616 {
3617 QCString object = it->second;
3618 if (object=="self")
3619 {
3620 if (yyextra->currentDefinition &&
3621 yyextra->currentDefinition->definitionType()==Definition::TypeClass)
3622 {
3623 ctx->objectType = toClassDef(yyextra->currentDefinition);
3624 if (ctx->objectType->categoryOf())
3625 {
3626 ctx->objectType = ctx->objectType->categoryOf();
3627 }
3628 if (ctx->objectType && !ctx->methodName.isEmpty())
3629 {
3630 ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
3631 }
3632 }
3633 startFontClass(yyscanner,"keyword");
3634 codifyLines(yyscanner,object);
3635 endFontClass(yyscanner);
3636 }
3637 else if (object=="super")
3638 {
3639 if (yyextra->currentDefinition &&
3640 yyextra->currentDefinition->definitionType()==Definition::TypeClass)
3641 {
3642 const ClassDef *cd = toClassDef(yyextra->currentDefinition);
3643 if (cd->categoryOf())
3644 {
3645 cd = cd->categoryOf();
3646 }
3647 for (const auto &bclass : cd->baseClasses())
3648 {
3649 if (bclass.classDef->compoundType()!=ClassDef::Protocol)
3650 {
3651 ctx->objectType = bclass.classDef;
3652 if (ctx->objectType && !ctx->methodName.isEmpty())
3653 {
3654 ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
3655 }
3656 }
3657 }
3658 }
3659 startFontClass(yyscanner,"keyword");
3660 codifyLines(yyscanner,object);
3661 endFontClass(yyscanner);
3662 }
3663 else if (ctx->objectVar && ctx->objectVar->isLinkable()) // object is class variable
3664 {
3665 writeMultiLineCodeLink(yyscanner,*yyextra->code,ctx->objectVar,object);
3666 if (yyextra->currentMemberDef && yyextra->collectXRefs)
3667 {
3668 addDocCrossReference(yyextra->currentMemberDef,ctx->objectVar);
3669 }
3670 }
3671 else if (ctx->objectType && ctx->objectType->isLinkable()) // object is class name
3672 {
3673 const ClassDef *cd = ctx->objectType;
3674 writeMultiLineCodeLink(yyscanner,*yyextra->code,cd,object);
3675 }
3676 else // object still needs to be resolved
3677 {
3678 int pp=0;
3679 int dotPos=object.find('.',pp);
3680 int len = static_cast<int>(object.length());
3681 if (dotPos==-1) dotPos=len;
3682 const Definition *scope = yyextra->currentDefinition;
3683 //printf("initial scope=%s\n",scope?qPrint(scope->name()):"none");
3684 for (;;)
3685 {
3686 QCString fragment = object.mid(pp,dotPos-pp);
3687 QCString fragmentStripped = fragment.stripWhiteSpace();
3688 //printf("fragment=%s\n",qPrint(fragment));
3689 if (fragmentStripped=="self")
3690 {
3691 if (scope && scope->definitionType()==Definition::TypeClass)
3692 {
3693 scope = ctx->objectType = toClassDef(scope);
3694 }
3695 //printf("self scope=%s\n",scope?qPrint(scope->name()):"none");
3696 startFontClass(yyscanner,"keyword");
3697 codifyLines(yyscanner,fragment);
3698 endFontClass(yyscanner);
3699 }
3700 else
3701 {
3702 const Definition *symbol = yyextra->symbolResolver.resolveSymbol(scope,fragmentStripped,QCString(),false,true);
3703 //printf("scope=%s name=%s -> symbol=%s\n",scope?qPrint(scope->name()):"none",qPrint(fragment),
3704 // symbol?qPrint(symbol->name()):"none");
3705 if (symbol && symbol->definitionType()==Definition::TypeClass)
3706 {
3707 scope = ctx->objectType = toClassDef(symbol);
3708 ctx->method = yyextra->symbolResolver.getTypedef();
3709 }
3710 else if (symbol && symbol->definitionType()==Definition::TypeMember)
3711 {
3712 scope = ctx->objectType = stripClassName(yyscanner,toMemberDef(symbol)->typeString(),scope);
3713 }
3714 if (scope && scope!=Doxygen::globalScope)
3715 {
3716 writeMultiLineCodeLink(yyscanner,*yyextra->code,scope,fragment);
3717 }
3718 else
3719 {
3720 codifyLines(yyscanner,fragment);
3721 }
3722 //printf("new scope=%s\n",scope?qPrint(scope->name()):"none");
3723 }
3724 if (dotPos==len)
3725 {
3726 break;
3727 }
3728 else // find next fragment
3729 {
3730 codifyLines(yyscanner,".");
3731 pp=dotPos+1;
3732 dotPos=object.find('.',pp);
3733 if (dotPos==-1) dotPos=len;
3734 }
3735 }
3736 DBG_CTX((stderr," object is class? %p\n",(void*)ctx->objectType));
3737 if (ctx->objectType) // found class
3738 {
3739 ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
3740 DBG_CTX((stderr," yes->method=%s\n",ctx->method?qPrint(ctx->method->name()):"<none>"));
3741 }
3742 else if (ctx->method==nullptr) // search for class variable with the same name
3743 {
3744 DBG_CTX((stderr," no\n"));
3745 DBG_CTX((stderr,"yyextra->currentDefinition=%p\n",(void*)yyextra->currentDefinition));
3746 if (yyextra->currentDefinition &&
3747 yyextra->currentDefinition->definitionType()==Definition::TypeClass)
3748 {
3749 ctx->objectVar = (toClassDef(yyextra->currentDefinition))->getMemberByName(ctx->objectTypeOrName);
3750 DBG_CTX((stderr," ctx->objectVar=%p\n",(void*)ctx->objectVar));
3751 if (ctx->objectVar)
3752 {
3753 ctx->objectType = stripClassName(yyscanner,ctx->objectVar->typeString(),yyextra->currentDefinition);
3754 DBG_CTX((stderr," ctx->objectType=%p\n",(void*)ctx->objectType));
3755 if (ctx->objectType && !ctx->methodName.isEmpty())
3756 {
3757 ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
3758 DBG_CTX((stderr," ctx->method=%p\n",(void*)ctx->method));
3759 }
3760 }
3761 }
3762 }
3763 }
3764 }
3765 else
3766 {
3767 DBG_CTX((stderr,"Invalid object: id=%d\n",refId));
3768 }
3769 }
3770 else if (nc=='c') // reference to nested call
3771 {
3772 nc=*p++;
3773 QCString refIdStr;
3774 while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
3775 p--;
3776 int refId=refIdStr.toInt();
3777 auto it = yyextra->contextMap.find(refId);
3778 if (it!=yyextra->contextMap.end()) // recurse into nested call
3779 {
3780 ObjCCallCtx *ictx = it->second.get();
3781 writeObjCMethodCall(yyscanner,ictx);
3782 if (ictx->method) // link to nested call successfully
3783 {
3784 // get the ClassDef representing the method's return type
3785 if (QCString(ictx->method->typeString())=="id")
3786 {
3787 // see if the method name is unique, if so we link to it
3789 //printf("mn->count=%d ictx->method=%s ctx->methodName=%s\n",
3790 // mn==0?-1:(int)mn->count(),
3791 // qPrint(ictx->method->name()),
3792 // qPrint(ctx->methodName));
3793 if (mn && mn->size()==1) // member name unique
3794 {
3795 ctx->method = mn->front().get();
3796 }
3797 }
3798 else
3799 {
3800 ctx->objectType = stripClassName(yyscanner,ictx->method->typeString(),yyextra->currentDefinition);
3801 if (ctx->objectType && !ctx->methodName.isEmpty())
3802 {
3803 ctx->method = ctx->objectType->getMemberByName(ctx->methodName);
3804 }
3805 }
3806 DBG_CTX((stderr," ***** method=%s -> object=%p\n",qPrint(ictx->method->name()),(void*)ctx->objectType));
3807 }
3808 }
3809 else
3810 {
3811 DBG_CTX((stderr,"Invalid context: id=%d\n",refId));
3812 }
3813 }
3814 else if (nc=='w') // some word
3815 {
3816 nc=*p++;
3817 QCString refIdStr;
3818 while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
3819 p--;
3820 int refId=refIdStr.toInt();
3821 auto it = yyextra->wordMap.find(refId);
3822 if (it!=yyextra->wordMap.end())
3823 {
3824 QCString word = it->second;
3825 bool isKeyword = word=="self";
3826 if (isKeyword)
3827 {
3828 startFontClass(yyscanner,"keyword");
3829 }
3830 codifyLines(yyscanner,word);
3831 if (isKeyword)
3832 {
3833 endFontClass(yyscanner);
3834 }
3835 }
3836 }
3837 else if (nc=='d') // comment block
3838 {
3839 nc=*p++;
3840 QCString refIdStr;
3841 while (nc!=0 && isdigit(nc)) { refIdStr+=nc; nc=*p++; }
3842 p--;
3843 int refId=refIdStr.toInt();
3844 auto it = yyextra->commentMap.find(refId);
3845 if (it!=yyextra->commentMap.end())
3846 {
3847 QCString comment = it->second;
3848 startFontClass(yyscanner,"comment");
3849 codifyLines(yyscanner,comment);
3850 endFontClass(yyscanner);
3851 }
3852 }
3853 else // illegal marker
3854 {
3855 ASSERT(0); // "invalid escape sequence"
3856 }
3857 }
3858 }
3859 else if (c=='\'' || c == '"')
3860 {
3861 char s[2];
3862 s[0]=c;s[1]=0;
3863 codifyLines(yyscanner,s);
3864 skip = true;
3865 skipChar = c;
3866 }
3867 else // normal non-marker character
3868 {
3869 char s[2];
3870 s[0]=c;s[1]=0;
3871 codifyLines(yyscanner,s);
3872 }
3873 }
3874 }
3875 DBG_CTX((stderr,"%s %s]\n",qPrint(ctx->objectTypeOrName),qPrint(ctx->methodName)));
3876 DBG_CTX((stderr,"}=(type='%s',name='%s')",
3878 qPrint(ctx->methodName)));
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
virtual ClassDef * categoryOf() const =0
Returns the class of which this is a category (Objective-C only)
int toInt(bool *ok=nullptr, int base=10) const
Definition qcstring.cpp:249
static void startFontClass(yyscan_t yyscanner, const char *s, bool specialComment=false)
Definition code.l:3498
static void writeObjCMethodCall(yyscan_t yyscanner, ObjCCallCtx *ctx)
Definition code.l:3514
#define ASSERT(x)
Definition qcstring.h:39
const MemberDef * objectVar
Definition code.l:89
const ClassDef * objectType
Definition code.l:88
std::string_view word
Definition util.cpp:980
const char * comment
3879}

References addDocCrossReference(), ASSERT, QCString::at(), ClassDef::baseClasses(), ClassDef::categoryOf(), codifyLines(), comment, QCString::data(), DBG_CTX, Definition::definitionType(), endFontClass(), ObjCCallCtx::format, MemberName::front(), ClassDef::getMemberByName(), ScopedTypeVariant::globalDef(), Doxygen::globalScope, QCString::isEmpty(), Definition::isLinkable(), Doxygen::memberNameLinkedMap, ObjCCallCtx::method, ObjCCallCtx::methodName, QCString::mid(), Definition::name(), ObjCCallCtx::objectType, ObjCCallCtx::objectTypeOrName, ObjCCallCtx::objectVar, ClassDef::Protocol, qPrint(), MemberName::size(), startFontClass(), stripClassName(), QCString::stripWhiteSpace(), toClassDef(), QCString::toInt(), toMemberDef(), Definition::TypeClass, Definition::TypeMember, MemberDef::typeString(), word, writeMultiLineCodeLink(), and writeObjCMethodCall().

Referenced by writeObjCMethodCall().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 382 of file code.l.

385 {
386 startFontClass(yyscanner,"preprocessor");
387 yyextra->code->codify(yytext);
388 BEGIN( ReadInclude );
389 }
390<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ {
391 yyextra->insideObjC=TRUE;
392 startFontClass(yyscanner,"keyword");
393 codifyLines(yyscanner,yytext);
394 endFontClass(yyscanner);
395 if (!yyextra->insideTemplate)
396 BEGIN( ClassName );
397 }
398<Body>(("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") {
399 if (yyextra->insideTemplate) REJECT;
400 startFontClass(yyscanner,"keyword");
401 codifyLines(yyscanner,yytext);
402 endFontClass(yyscanner);
403 BEGIN( ClassName );
404 }
405<Body>"property"|"event"/{BN}* {
406 if (yyextra->insideTemplate) REJECT;
407 startFontClass(yyscanner,"keyword");
408 codifyLines(yyscanner,yytext);
409 endFontClass(yyscanner);
410 }
411<Body>("partial"{B}+)?("class"|"struct"|"union"|"namespace"|"interface"){B}+ {
412 startFontClass(yyscanner,"keyword");
413 codifyLines(yyscanner,yytext);
414 endFontClass(yyscanner);
415 if (!yyextra->insideTemplate)
416 BEGIN( ClassName );
417 }
418<Body>("package")[ \t\n]+ {
419 startFontClass(yyscanner,"keyword");
420 codifyLines(yyscanner,yytext);
421 endFontClass(yyscanner);
422 BEGIN( PackageName );
423 }
424<ClassVar>\n {
425 if (!yyextra->insideObjC) REJECT;
426 codifyLines(yyscanner,yytext);
427 BEGIN(Body);
428 }
429<Body,ClassVar,Bases>"-"|"+" {
430 if (!yyextra->insideObjC || yyextra->insideBody)
431 {
432 yyextra->code->codify(yytext);
433 }
434 else // Start of Objective-C method
435 {
436 DBG_CTX((stderr,"Start of Objective-C method!\n"));
437 yyextra->code->codify(yytext);
438 BEGIN(ObjCMethod);
439 }
440 }
441<ObjCMethod>":" {
442 yyextra->code->codify(yytext);
443 BEGIN(ObjCParams);
444 }
445<ObjCParams>"(" {
446 yyextra->code->codify(yytext);
447 BEGIN(ObjCParamType);
448 }
449<ObjCParams,ObjCMethod>";"|"{" {
450 yyextra->code->codify(yytext);
451 if (*yytext=='{')
452 {
453 if (yyextra->searchingForBody)
454 {
455 yyextra->searchingForBody=FALSE;
456 yyextra->insideBody=TRUE;
457 }
458 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
459 if (!yyextra->curClassName.isEmpty()) // valid class name
460 {
461 pushScope(yyscanner,yyextra->curClassName);
462 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
463 yyextra->scopeStack.push(SCOPEBLOCK);
464 }
465 }
466 yyextra->type.clear();
467 yyextra->name.clear();
468 BEGIN(Body);
469 }
#define SCOPEBLOCK
Definition code.l:78
470<ObjCParams>{ID}{B}*":" {
471 yyextra->code->codify(yytext);
472 }
473<ObjCParamType>{TYPEKW} {
474 startFontClass(yyscanner,"keywordtype");
475 yyextra->code->codify(yytext);
476 endFontClass(yyscanner);
477 yyextra->parmType=yytext;
478 }
479<ObjCParamType>{ID} {
480 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
481 yyextra->parmType=yytext;
482 }
483<ObjCParamType>")" {
484 yyextra->code->codify(yytext);
485 BEGIN(ObjCParams);
486 }
487<ObjCParams>{ID} {
488 yyextra->code->codify(yytext);
489 yyextra->parmName=yytext;
490 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
491 yyextra->parmType.clear();yyextra->parmName.clear();
492 }
493<ObjCMethod,ObjCParams,ObjCParamType>{ID} {
494 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
495 }
496<ObjCMethod,ObjCParams,ObjCParamType>. {
497 yyextra->code->codify(yytext);
498 }
499<ObjCMethod,ObjCParams,ObjCParamType>\n {
500 codifyLines(yyscanner,yytext);
501 }
502<ReadInclude>[^\n\">]+/(">"|"\"") {
503 //FileInfo *f;
504 bool found = false;
505 bool ambig = false;
506 QCString absIncFileName = determineAbsoluteIncludeName(yyextra->absFileName,yytext);
507 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
508 //printf("looking for include %s -> %s fd=%p\n",yytext,qPrint(absPath),fd);
509 if (fd && fd->isLinkable())
510 {
511 if (ambig) // multiple input files match the name
512 {
513 DBG_CTX((stderr,"===== yes %s is ambiguous\n",yytext));
514 QCString name(Dir::cleanDirPath(yytext));
515 if (!name.isEmpty() && yyextra->sourceFileDef)
516 {
517 const FileName *fn = Doxygen::inputNameLinkedMap->find(name);
518 if (fn)
519 {
520 // see if this source file actually includes the file
521 auto it = std::find_if(fn->begin(),
522 fn->end(),
523 [&sfd=yyextra->sourceFileDef]
524 (const auto &lfd)
525 { return sfd->isIncluded(lfd->absFilePath()); });
526 found = it!=fn->end();
527 }
528 }
529 }
530 else // not ambiguous
531 {
532 found = TRUE;
533 }
534 }
535 DBG_CTX((stderr," include file %s found=%d\n",fd ? qPrint(fd->absFilePath()) : "<none>",found));
536 if (found)
537 {
538 writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext);
539 }
540 else
541 {
542 yyextra->code->codify(yytext);
543 }
544 char c=(char)yyinput(yyscanner);
545 QCString text;
546 text+=c;
547 yyextra->code->codify(text);
548 endFontClass(yyscanner);
549 BEGIN( Body );
550 }
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:355
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h:105
virtual QCString absFilePath() const =0
Class representing all files with a certain base name.
Definition filename.h:30
bool found
Definition util.cpp:984
QCString determineAbsoluteIncludeName(const QCString &curFile, const QCString &incFileName)
Definition util.cpp:3954
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:3262
551<Body,Bases>^[ \t]*"#" {
552 startFontClass(yyscanner,"preprocessor");
553 yyextra->lastSkipCppContext = YY_START;
554 yyextra->code->codify(yytext);
555 BEGIN( SkipCPP ) ;
556 }
557<SkipCPP>\" {
558 yyextra->code->codify(yytext);
559 yyextra->lastStringContext=YY_START;
560 BEGIN( SkipString ) ;
561 }
562<SkipCPP>. {
563 yyextra->code->codify(yytext);
564 }
565<SkipCPP>[^\n\/\\\"]+ {
566 yyextra->code->codify(yytext);
567 }
568<SkipCPP>\\[\r]?\n {
569 codifyLines(yyscanner,yytext);
570 }
571<SkipCPP>{CPPC}/[^/!] {
572 REJECT;
573 }
574<Body,FuncCall>"{" {
575 yyextra->theVarContext.pushScope();
576 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
577 yyextra->bracketCount = 0;
578
579 DBG_CTX((stderr,"** type='%s' name='%s'\n",qPrint(yyextra->type),qPrint(yyextra->name)));
580 if (yyextra->type.find("enum ")!=-1)
581 { // for strong enums we need to start a scope
582 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
583 pushScope(yyscanner,yyextra->name);
584 yyextra->scopeStack.push(SCOPEBLOCK);
585 }
586 else
587 {
588 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
589 yyextra->scopeStack.push(INNERBLOCK);
590 }
#define INNERBLOCK
Definition code.l:79
591
592 if (yyextra->searchingForBody)
593 {
594 yyextra->searchingForBody=FALSE;
595 yyextra->insideBody=TRUE;
596 }
597 yyextra->code->codify(yytext);
598 if (yyextra->insideBody)
599 {
600 yyextra->bodyCurlyCount++;
601 }
602 yyextra->type.clear();
603 yyextra->name.clear();
604 BEGIN( Body );
605 }
606<Body,FuncCall,MemberCall,MemberCall2>"}" {
607 yyextra->theVarContext.popScope();
608 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
609 yyextra->type.clear();
610 yyextra->name.clear();
611
612 if (!yyextra->scopeStack.empty())
613 {
614 int scope = yyextra->scopeStack.top();
615 yyextra->scopeStack.pop();
616 DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
617 if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
618 {
619 popScope(yyscanner);
620 }
621 }
622
623 yyextra->code->codify(yytext);
624
625 DBG_CTX((stderr,"yyextra->bodyCurlyCount=%d\n",yyextra->bodyCurlyCount));
626 if (--yyextra->bodyCurlyCount<=0)
627 {
628 yyextra->insideBody=FALSE;
629 yyextra->currentMemberDef=nullptr;
630 if (yyextra->currentDefinition)
631 yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope();
632 }
633 BEGIN(Body);
634 }
635<Body,ClassVar>"@end" {
636 DBG_CTX((stderr,"End of objc scope fd=%s\n",qPrint(yyextra->sourceFileDef->name())));
637 if (yyextra->sourceFileDef)
638 {
639 const FileDef *fd=yyextra->sourceFileDef;
640 yyextra->insideObjC = fd->name().lower().endsWith(".m") ||
641 fd->name().lower().endsWith(".mm");
642 DBG_CTX((stderr,"insideObjC=%d\n",yyextra->insideObjC));
643 }
644 else
645 {
646 yyextra->insideObjC = FALSE;
647 }
648 if (yyextra->insideBody)
649 {
650 yyextra->theVarContext.popScope();
QCString lower() const
Definition qcstring.h:234
bool endsWith(const char *s) const
Definition qcstring.h:504
651
652 if (!yyextra->scopeStack.empty())
653 {
654 int scope = yyextra->scopeStack.top();
655 yyextra->scopeStack.pop();
656 DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
657 if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
658 {
659 popScope(yyscanner);
660 }
661 }
662 yyextra->insideBody=FALSE;
663 }
664
665 startFontClass(yyscanner,"keyword");
666 yyextra->code->codify(yytext);
667 endFontClass(yyscanner);
668
669 yyextra->currentMemberDef=nullptr;
670 if (yyextra->currentDefinition)
671 yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope();
672 BEGIN(Body);
673 }
674<ClassName,ClassVar>";" {
675 if (yyextra->lang==SrcLangExt::CSharp)
676 {
677 yyextra->code->codify(yytext);
678 yyextra->skipCodify = true;
679 unput('{');
680 }
681 else
682 {
683 yyextra->code->codify(yytext);
684 yyextra->searchingForBody=FALSE;
685 BEGIN( Body );
686 }
687 }
688<ClassName,ClassVar>[*&^%]+ {
689 yyextra->type=yyextra->curClassName;
690 yyextra->name.clear();
691 yyextra->code->codify(yytext);
692 BEGIN( Body ); // variable of type struct *
693 }
694<ClassName>"__declspec"{B}*"("{B}*{ID}{B}*")" {
695 startFontClass(yyscanner,"keyword");
696 yyextra->code->codify(yytext);
697 endFontClass(yyscanner);
698 }
699<ClassName>{ID}("."{ID})* |
700<ClassName>{ID}("::"{ID})* {
701 if (yyextra->lang==SrcLangExt::CSharp)
702 yyextra->curClassName=substitute(yytext,".","::");
703 else
704 yyextra->curClassName=yytext;
705 addType(yyscanner);
706 if (yyextra->curClassName=="alignas")
707 {
708 startFontClass(yyscanner,"keyword");
709 yyextra->code->codify(yytext);
710 endFontClass(yyscanner);
711 BEGIN( AlignAs );
712 }
713 else
714 {
715 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
716 BEGIN( ClassVar );
717 }
718 }
static void addType(yyscan_t yyscanner)
Definition code.l:2597
719<AlignAs>"(" {
720 yyextra->bracketCount=1;
721 yyextra->code->codify(yytext);
722 BEGIN( AlignAsEnd );
723 }
724<AlignAs>\n { yyextra->yyLineNr++;
725 codifyLines(yyscanner,yytext);
726 }
727<AlignAs>. { yyextra->code->codify(yytext); }
728<AlignAsEnd>"(" { yyextra->code->codify(yytext);
729 yyextra->bracketCount++;
730 }
731<AlignAsEnd>")" {
732 yyextra->code->codify(yytext);
733 if (--yyextra->bracketCount<=0)
734 {
735 BEGIN(ClassName);
736 }
737 }
738<AlignAsEnd>\n { yyextra->yyLineNr++;
739 codifyLines(yyscanner,yytext);
740 }
741<AlignAsEnd>. { yyextra->code->codify(yytext); }
742<ClassName>{ID}("\\"{ID})* { // PHP namespace
743 yyextra->curClassName=substitute(yytext,"\\","::");
744 yyextra->scopeStack.push(CLASSBLOCK);
745 pushScope(yyscanner,yyextra->curClassName);
746 addType(yyscanner);
747 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
748 BEGIN( ClassVar );
749 }
750<ClassName>{ID}{B}*"("{ID}")" { // Obj-C category
751 yyextra->curClassName=removeRedundantWhiteSpace(yytext);
752 yyextra->scopeStack.push(CLASSBLOCK);
753 pushScope(yyscanner,yyextra->curClassName);
754 addType(yyscanner);
755 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
756 BEGIN( ClassVar );
757 }
758<PackageName>{ID}("."{ID})* {
759 yyextra->curClassName=substitute(yytext,".","::");
760 DBG_CTX((stderr,"found package: %s\n",qPrint(yyextra->curClassName)));
761 addType(yyscanner);
762 codifyLines(yyscanner,yytext);
763 }
764<ClassVar>"=" {
765 unput(*yytext);
766 BEGIN( Body );
767 }
768<ClassVar>("extends"|"implements") { // Java, Slice
769 startFontClass(yyscanner,"keyword");
770 codifyLines(yyscanner,yytext);
771 endFontClass(yyscanner);
772 yyextra->curClassBases.clear();
773 BEGIN( Bases );
774 }
775<ClassVar>("sealed"|"abstract")/{BN}*(":"|"{") {
776 DBG_CTX((stderr,"***** C++/CLI modifier %s on yyextra->curClassName=%s\n",yytext,qPrint(yyextra->curClassName)));
777 startFontClass(yyscanner,"keyword");
778 codifyLines(yyscanner,yytext);
779 endFontClass(yyscanner);
780 BEGIN( CppCliTypeModifierFollowup );
781 }
782<ClassVar>{ID} {
783 yyextra->type = yyextra->curClassName;
784 yyextra->name = yytext;
785 if (yyextra->insideBody)
786 {
787 addVariable(yyscanner,yyextra->type,yyextra->name);
788 }
789 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
790 }
791<ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* {
792 codifyLines(yyscanner,yytext);
793 yyextra->curClassBases.clear();
794 BEGIN( Bases );
795 }
796<PackageName>[ \t]*";" |
797<Bases>^{Bopt}/"@"{ID} | // Objective-C interface
798<Bases,ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*"{"{B}* {
799 yyextra->theVarContext.pushScope();
800 if (!yyextra->skipCodify) yyextra->code->codify(yytext);
801 yyextra->skipCodify = false;
802 if (YY_START==ClassVar && yyextra->curClassName.isEmpty())
803 {
804 yyextra->curClassName = yyextra->name;
805 }
806 if (yyextra->searchingForBody)
807 {
808 yyextra->searchingForBody=FALSE;
809 yyextra->insideBody=TRUE;
810 }
811 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
812 if (!yyextra->curClassName.isEmpty()) // valid class name
813 {
814 DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n"));
815 yyextra->scopeStack.push(CLASSBLOCK);
816 pushScope(yyscanner,yyextra->curClassName);
817 DBG_CTX((stderr,"***** yyextra->curClassName=%s\n",qPrint(yyextra->curClassName)));
818 if (yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,yyextra->curClassName,true)==nullptr)
819 {
820 DBG_CTX((stderr,"Adding new class %s\n",qPrint(yyextra->curClassName)));
821 ScopedTypeVariant var(yyextra->curClassName);
822 // insert base classes.
823 for (const auto &s : yyextra->curClassBases)
824 {
825 const ClassDef *bcd=nullptr;
826 auto it = yyextra->codeClassMap.find(s);
827 if (it!=yyextra->codeClassMap.end())
828 {
829 bcd = toClassDef(it->second.globalDef());
830 }
831 if (bcd==nullptr) bcd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,QCString(s),true);
832 if (bcd && bcd->name()!=yyextra->curClassName)
833 {
834 var.localDef()->insertBaseClass(bcd->name());
835 }
836 }
837 yyextra->codeClassMap.emplace(yyextra->curClassName.str(),std::move(var));
838 }
839 //printf("yyextra->codeClassList.count()=%d\n",yyextra->codeClassList.count());
840 }
841 else // not a class name -> assume inner block
842 {
843 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
844 yyextra->scopeStack.push(INNERBLOCK);
845 }
846 yyextra->curClassName.clear();
847 yyextra->curClassBases.clear();
848 BEGIN( Body );
849 }
850<Bases>"virtual"|"public"|"protected"|"private"|"@public"|"@private"|"@protected" {
851 startFontClass(yyscanner,"keyword");
852 yyextra->code->codify(yytext);
853 endFontClass(yyscanner);
854 }
855<Bases>{SEP}?({ID}{SEP})*{ID} {
856 DBG_CTX((stderr,"%s:addBase(%s)\n",qPrint(yyextra->curClassName),yytext));
857 yyextra->curClassBases.emplace_back(yytext);
858 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
859 }
860<Bases>"<" {
861 yyextra->code->codify(yytext);
862 if (!yyextra->insideObjC)
863 {
864 yyextra->sharpCount=1;
865 BEGIN ( SkipSharp );
866 }
867 else
868 {
869 yyextra->insideProtocolList=TRUE;
870 }
871 }
872<Bases>">" {
873 yyextra->code->codify(yytext);
874 yyextra->insideProtocolList=FALSE;
875 }
876<SkipSharp>"<" {
877 yyextra->code->codify(yytext);
878 ++yyextra->sharpCount;
879 }
880<SkipSharp>">" {
881 yyextra->code->codify(yytext);
882 if (--yyextra->sharpCount<=0)
883 BEGIN ( Bases );
884 }
885<SkipSharp>"\"" {
886 yyextra->code->codify(yytext);
887 yyextra->lastStringContext=YY_START;
888 BEGIN(SkipString);
889 }
890<SkipSharp>"\'" {
891 yyextra->code->codify(yytext);
892 yyextra->lastStringContext=YY_START;
893 BEGIN(SkipStringS);
894 }
895<Bases>"(" {
896 yyextra->code->codify(yytext);
897 yyextra->sharpCount=1;
898 BEGIN ( SkipSharp );
899 }
900<SkipSharp>"(" {
901 yyextra->code->codify(yytext);
902 ++yyextra->sharpCount;
903 }
904<SkipSharp>")" {
905 yyextra->code->codify(yytext);
906 if (--yyextra->sharpCount<=0)
907 BEGIN ( Bases );
908 }
909
910
911<Bases>"," {
912 yyextra->code->codify(yytext);
913 }
914
915
916<Body>{SCOPEPREFIX}?"operator"{B}*"()"{Bopt}/"(" {
917 addType(yyscanner);
918 generateFunctionLink(yyscanner,*yyextra->code,yytext);
919 yyextra->bracketCount=0;
920 yyextra->args.clear();
921 yyextra->name+=yytext;
922 BEGIN( FuncCall );
923 }
924<Body>{SCOPEPREFIX}?"operator"/"(" {
925 addType(yyscanner);
926 generateFunctionLink(yyscanner,*yyextra->code,yytext);
927 yyextra->bracketCount=0;
928 yyextra->args.clear();
929 yyextra->name+=yytext;
930 BEGIN( FuncCall );
931 }
932<Body>{SCOPEPREFIX}?"operator"[^a-z_A-Z0-9\‍(\n]+/"(" {
933 addType(yyscanner);
934 generateFunctionLink(yyscanner,*yyextra->code,yytext);
935 yyextra->bracketCount=0;
936 yyextra->args.clear();
937 yyextra->name+=yytext;
938 BEGIN( FuncCall );
939 }
940<Body,TemplDecl>("template"|"generic")/([^a-zA-Z0-9]) {
941 startFontClass(yyscanner,"keyword");
942 codifyLines(yyscanner,yytext);
943 endFontClass(yyscanner);
944 yyextra->insideTemplate=TRUE;
945 yyextra->sharpCount=0;
946 }
947<Body>"concept"{BN}+ {
948 startFontClass(yyscanner,"keyword");
949 codifyLines(yyscanner,yytext);
950 endFontClass(yyscanner);
951 BEGIN(ConceptName);
952 }
953<Body>"using"{BN}+"namespace"{BN}+ {
954 startFontClass(yyscanner,"keyword");
955 codifyLines(yyscanner,yytext);
956 endFontClass(yyscanner);
957 BEGIN(UsingName);
958 }
959<Body>"using"{BN}+ {
960 startFontClass(yyscanner,"keyword");
961 codifyLines(yyscanner,yytext);
962 endFontClass(yyscanner);
963 BEGIN(UsingName);
964 }
965<Body>"module"/{B}*[:;]? { // 'module X' or 'module : private' or 'module;'
966 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
967 if (!yyextra->type.isEmpty() || !yyextra->name.isEmpty()) REJECT;
968 startFontClass(yyscanner,"keyword");
969 codifyLines(yyscanner,yytext);
970 endFontClass(yyscanner);
971 BEGIN(ModuleName);
972 }
973<Body>"import"/{B}*[<":]? {
974 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
975 startFontClass(yyscanner,"keyword");
976 codifyLines(yyscanner,yytext);
977 endFontClass(yyscanner);
978 BEGIN(ModuleImport);
979 }
980<ConceptName>{ID}("::"{ID})* {
981 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
982 }
983<ConceptName>"=" { codifyLines(yyscanner,yytext); BEGIN(Body); }
984<UsingName>{ID}(("::"|"."){ID})* {
985 addUsingDirective(yyscanner,substitute(yytext,".","::"));
986 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
987 BEGIN(Body);
988 }
static void addUsingDirective(yyscan_t yyscanner, const QCString &name)
Definition code.l:2618
989<UsingName>\n { codifyLines(yyscanner,yytext); BEGIN(Body); }
990<UsingName>. { codifyLines(yyscanner,yytext); BEGIN(Body); }
991<Body,FuncCall>"$"?"this"("->"|".") { yyextra->code->codify(yytext); // this-> for C++, this. for C#
992 yyextra->isPrefixedWithThis = TRUE;
993 }
994<Body>{KEYWORD}/([^a-z_A-Z0-9]) {
995 if (yyextra->lang==SrcLangExt::Java && qstrcmp("internal",yytext) ==0) REJECT;
996 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
997 QCString text=yytext;
998 startFontClass(yyscanner,"keyword");
999 codifyLines(yyscanner,yytext);
1000 if (text=="typedef" || text.find("enum ")!=-1) // typedef or strong enum
1001 {
1002 addType(yyscanner);
1003 yyextra->name+=yytext;
1004 }
1005 endFontClass(yyscanner);
1006 }
static bool skipLanguageSpecificKeyword(yyscan_t yyscanner, const char *kw)
Definition code.l:3924
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
1007<Body>{KEYWORD}/{B}* {
1008 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
1009 startFontClass(yyscanner,"keyword");
1010 codifyLines(yyscanner,yytext);
1011 endFontClass(yyscanner);
1012 }
1013<Body>{KEYWORD}/{BN}*"(" {
1014 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
1015 startFontClass(yyscanner,"keyword");
1016 codifyLines(yyscanner,yytext);
1017 endFontClass(yyscanner);
1018 yyextra->name.clear();yyextra->type.clear();
1019 }
1020<FuncCall>"in"/{BN}* {
1021 if (!yyextra->inForEachExpression) REJECT;
1022 startFontClass(yyscanner,"keywordflow");
1023 codifyLines(yyscanner,yytext);
1024 endFontClass(yyscanner);
1025 // insert the variable in the parent scope, see bug 546158
1026 yyextra->theVarContext.popScope();
1027 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1028 yyextra->theVarContext.pushScope();
1029 yyextra->name.clear();yyextra->type.clear();
1030 }
1031<Body>{FLOWKW}/{BN}*"(" {
1032 startFontClass(yyscanner,"keywordflow");
1033 codifyLines(yyscanner,yytext);
1034 endFontClass(yyscanner);
1035 yyextra->name.clear();yyextra->type.clear();
1036 yyextra->inForEachExpression = (qstrcmp(yytext,"for each")==0 || qstrcmp(yytext, "foreach")==0);
1037 BEGIN(FuncCall);
1038 }
1039<Body>{FLOWCONDITION}/{BN}*"(" {
1040 incrementFlowKeyWordCount(yyscanner);
1041 startFontClass(yyscanner,"keywordflow");
1042 codifyLines(yyscanner,yytext);
1043 endFontClass(yyscanner);
1044 yyextra->name.clear();yyextra->type.clear();
1045 yyextra->inForEachExpression = (strcmp(yytext,"for each")==0 || strcmp(yytext, "foreach")==0);
1046 BEGIN(FuncCall);
1047 }
static void incrementFlowKeyWordCount(yyscan_t yyscanner)
Definition code.l:2541
1048<Body>{FLOWKW}/([^a-z_A-Z0-9]) {
1049 startFontClass(yyscanner,"keywordflow");
1050 codifyLines(yyscanner,yytext);
1051 endFontClass(yyscanner);
1052 if (yyextra->inFunctionTryBlock && (qstrcmp(yytext,"catch")==0 || qstrcmp(yytext,"finally")==0))
1053 {
1054 yyextra->inFunctionTryBlock=FALSE;
1055 }
1056 }
1057<Body>{FLOWCONDITION}/([^a-z_A-Z0-9]) {
1058 incrementFlowKeyWordCount(yyscanner);
1059 startFontClass(yyscanner,"keywordflow");
1060 codifyLines(yyscanner,yytext);
1061 endFontClass(yyscanner);
1062 if (yyextra->inFunctionTryBlock && (strcmp(yytext,"catch")==0 || strcmp(yytext,"finally")==0))
1063 {
1064 yyextra->inFunctionTryBlock=FALSE;
1065 }
1066 }
1067<Body>{FLOWKW}/{B}* {
1068 startFontClass(yyscanner,"keywordflow");
1069 codifyLines(yyscanner,yytext);
1070 endFontClass(yyscanner);
1071 }
1072<Body>{FLOWCONDITION}/{B}* {
1073 incrementFlowKeyWordCount(yyscanner);
1074 startFontClass(yyscanner,"keywordflow");
1075 codifyLines(yyscanner,yytext);
1076 endFontClass(yyscanner);
1077 }
1078<Body>"*"{B}*")" { // end of cast?
1079 yyextra->code->codify(yytext);
1080 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1081 yyextra->bracketCount--;
1082 yyextra->parmType = yyextra->name;
1083 BEGIN(FuncCall);
1084 }
1085<Body>"\\‍)"|"\\‍(" {
1086 yyextra->code->codify(yytext);
1087 }
1088<Body>[\\|\‍)\+\-\/\%\~\!] {
1089 yyextra->code->codify(yytext);
1090 yyextra->name.clear();yyextra->type.clear();
1091 if (*yytext==')')
1092 {
1093 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1094 yyextra->bracketCount--;
1095 if (yyextra->bracketCount<=0)
1096 {
1097 BEGIN(FuncCall);
1098 }
1099 }
1100 }
1101<Body,TemplDecl,ObjCMethod>{TYPEKW}/{B}* {
1102 startFontClass(yyscanner,"keywordtype");
1103 yyextra->code->codify(yytext);
1104 endFontClass(yyscanner);
1105 addType(yyscanner);
1106 yyextra->name+=yytext;
1107 }
1108<Body,TemplDecl,ObjCMethod>{TYPEKWSL}/{B}* {
1109 if (yyextra->lang!=SrcLangExt::Slice)
1110 {
1111 REJECT;
1112 }
1113 else
1114 {
1115 startFontClass(yyscanner,"keywordtype");
1116 yyextra->code->codify(yytext);
1117 endFontClass(yyscanner);
1118 addType(yyscanner);
1119 yyextra->name+=yytext;
1120 }
1121 }
@ Slice
Definition types.h:59
1122<Body>"generic"/{B}*"<"[^\n\/\-\.\{\">]*">"{B}* {
1123 startFontClass(yyscanner,"keyword");
1124 yyextra->code->codify(yytext);
1125 endFontClass(yyscanner);
1126 yyextra->sharpCount=0;
1127 BEGIN(TemplDecl);
1128 }
1129<Body>"template"/{B}*"<"[^\n\/\-\.\{\">]*">"{B}* { // template<...>
1130 startFontClass(yyscanner,"keyword");
1131 yyextra->code->codify(yytext);
1132 endFontClass(yyscanner);
1133 yyextra->sharpCount=0;
1134 BEGIN(TemplDecl);
1135 }
1136<TemplDecl>"class"|"typename" {
1137 startFontClass(yyscanner,"keyword");
1138 codifyLines(yyscanner,yytext);
1139 endFontClass(yyscanner);
1140 }
1141<TemplDecl>"<" {
1142 yyextra->code->codify(yytext);
1143 yyextra->sharpCount++;
1144 }
1145<TemplDecl>">" {
1146 yyextra->code->codify(yytext);
1147 yyextra->sharpCount--;
1148 if (yyextra->sharpCount<=0)
1149 {
1150 BEGIN(Body);
1151 }
1152 }
1153<TemplCast>">" {
1154 startFontClass(yyscanner,"keyword");
1155 codifyLines(yyscanner,yytext);
1156 endFontClass(yyscanner);
1157 BEGIN( yyextra->lastTemplCastContext );
1158 }
1159<TemplCast>{ID}("::"{ID})* {
1160 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1161 }
1162<TemplCast>("const"|"volatile"){B}* {
1163 startFontClass(yyscanner,"keyword");
1164 codifyLines(yyscanner,yytext);
1165 endFontClass(yyscanner);
1166 }
1167<TemplCast>[*^]* {
1168 codifyLines(yyscanner,yytext);
1169 }
1170<Body,MemberCall2,FuncCall>{CASTKW}{B}*"<" { // static_cast<T>(
1171 startFontClass(yyscanner,"keyword");
1172 codifyLines(yyscanner,yytext);
1173 endFontClass(yyscanner);
1174 yyextra->lastTemplCastContext = YY_START;
1175 BEGIN(TemplCast);
1176 }
1177<Body>"$this->"{SCOPENAME}/{BN}*[;,)\]] { // PHP member variable
1178 addType(yyscanner);
1179 generatePHPVariableLink(yyscanner,*yyextra->code,yytext);
1180 yyextra->name+=yytext+7;
1181 }
static void generatePHPVariableLink(yyscan_t yyscanner, OutputCodeList &ol, const char *varName)
Definition code.l:3338
1182<Body,TemplCast>{SCOPENAME}{B}*"<"[^\n\/\-\.\{\">\‍(']*">"{ENDIDopt}/{B}* { // A<T> *pt;
1183 if (isCastKeyword(yytext) && YY_START==Body)
1184 {
1185 REJECT;
1186 }
1187 addType(yyscanner);
1188 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1189 yyextra->name+=yytext;
1190 }
static bool isCastKeyword(const char *s)
Definition code.l:3965
1191<ModuleName,ModuleImport>{MODULE_ID}({BN}*":"{BN}*{MODULE_ID})? {
1192 QCString name = yytext;
1193 int i = name.find(':');
1194 QCString partition;
1195 if (i!=-1)
1196 {
1197 partition = name.mid(i+1).stripWhiteSpace();
1198 name = name.left(i).stripWhiteSpace();
1199 }
1201 if (mod)
1202 {
1203 writeMultiLineCodeLink(yyscanner,*yyextra->code,mod,yytext);
1204 }
1205 else
1206 {
1207 codifyLines(yyscanner,yytext);
1208 }
1209 }
static ModuleManager & instance()
ModuleDef * getPrimaryInterface(const QCString &moduleName) const
1210<ModuleName>":"{BN}+"private" {
1211 QCString text=yytext;
1212 int i=text.find('p');
1213 codifyLines(yyscanner,text.left(i));
1214 startFontClass(yyscanner,"keyword");
1215 codifyLines(yyscanner,text.mid(i));
1216 endFontClass(yyscanner);
1217 }
1218<ModuleName>";" { yyextra->code->codify(yytext); BEGIN(Body); }
1219<ModuleName>. { yyextra->code->codify(yytext); }
1220<ModuleName>\n { codifyLines(yyscanner,yytext); }
1221<ModuleImport>["<] { yyextra->code->codify(yytext); BEGIN(ReadInclude); }
1222<ModuleImport>";" { yyextra->code->codify(yytext); BEGIN(Body); }
1223<ModuleImport>. { yyextra->code->codify(yytext); }
1224<ModuleImport>\n { codifyLines(yyscanner,yytext); }
1225
1226<Body>{SCOPENAME}/{BN}*[:;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" , or int var : 5;
1227 if (startsWithKeyword(yytext,"typedef")) REJECT;
1228 addType(yyscanner);
1229 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1230 yyextra->name+=yytext;
1231 }
static bool startsWithKeyword(const QCString &str, const QCString &kw)
Definition code.l:2168
1232<Body>{ID}("."{ID})+/{BN}+ { // CSharp/Java scope
1233 if (yyextra->lang==SrcLangExt::CSharp || yyextra->lang==SrcLangExt::Java)
1234 {
1235 addType(yyscanner);
1236 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1237 yyextra->name+=yytext;
1238 }
1239 else
1240 {
1241 REJECT;
1242 }
1243 }
1244<Body>"export"/{B}* {
1245 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
1246 startFontClass(yyscanner,"keyword");
1247 codifyLines(yyscanner,yytext);
1248 endFontClass(yyscanner);
1249 }
1250<Body>{SCOPENAME}/{B}* { // p->func()
1251 if (startsWithKeyword(yytext,"typedef")) REJECT;
1252 addType(yyscanner);
1253 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1254 yyextra->name+=yytext;
1255 }
1256<Body>"("{B}*("*"{B}*)+{SCOPENAME}+{B}*")"/{B}* { // (*p)->func() but not "if (p) ..."
1257 yyextra->code->codify(yytext);
1258 uint32_t s=0;while (s<(uint32_t)yyleng && !isId(yytext[s])) s++;
1259 uint32_t e=(uint32_t)yyleng-1;while (e>1 && !isId(yytext[e])) e--;
1260 QCString varname = ((QCString)yytext).mid(s,e-s+1);
1261 addType(yyscanner);
1262 yyextra->name=std::move(varname);
1263 }
1264<Body>{SCOPETNAME}{B}*"<"[^\n\/\-\.\{\">]*">"/{BN}*"(" |
1265<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo()
1266 if (isCastKeyword(yytext))
1267 {
1268 REJECT;
1269 }
1270 addType(yyscanner);
1271 generateFunctionLink(yyscanner,*yyextra->code,yytext);
1272 yyextra->bracketCount=0;
1273 yyextra->args.clear();
1274 yyextra->name+=yytext;
1275 BEGIN( FuncCall );
1276 }
1277<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{RAWBEGIN} {
1278 QCString text(yytext);
1279 uint32_t i=(uint32_t)text.find('R');
1280 yyextra->code->codify(text.left(i+1));
1281 startFontClass(yyscanner,"stringliteral");
1282 yyextra->code->codify(QCString(yytext+i+1));
1283 yyextra->lastStringContext=YY_START;
1284 yyextra->inForEachExpression = FALSE;
1285 yyextra->delimiter = yytext+i+2;
1286 yyextra->delimiter=yyextra->delimiter.left(yyextra->delimiter.length()-1);
1287 BEGIN( RawString );
1288 }
1289<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit,ClassVar,OldStyleArgs>\" {
1290 startFontClass(yyscanner,"stringliteral");
1291 yyextra->code->codify(yytext);
1292 yyextra->lastStringContext=YY_START;
1293 yyextra->inForEachExpression = FALSE;
1294 BEGIN( SkipString );
1295 }
1296<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{NUMBER} { //Note similar code in commentcnv.l
1297 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
1298 yyextra->code->codify(yytext);
1299 }
1300<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\' {
1301 startFontClass(yyscanner,"stringliteral");
1302 yyextra->code->codify(yytext);
1303 yyextra->lastStringContext=YY_START;
1304 yyextra->inForEachExpression = FALSE;
1305 BEGIN( SkipStringS );
1306 }
1307<SkipString>[^\"\\\r\n]* {
1308 yyextra->code->codify(yytext);
1309 }
1310<SkipStringS>[^\'\\\r\n]* {
1311 yyextra->code->codify(yytext);
1312 }
1313<SkipString,SkipStringS>{CPPC}|{CCS} {
1314 yyextra->code->codify(yytext);
1315 }
1316<SkipString>@?\" {
1317 yyextra->code->codify(yytext);
1318 if (yyextra->lastStringContext!=SkipCPP)
1319 {
1320 endFontClass(yyscanner);
1321 }
1322 BEGIN( yyextra->lastStringContext );
1323 }
1324<SkipStringS>\' {
1325 yyextra->code->codify(yytext);
1326 endFontClass(yyscanner);
1327 BEGIN( yyextra->lastStringContext );
1328 }
1329<SkipString,SkipStringS>\\. {
1330 yyextra->code->codify(yytext);
1331 }
1332<RawString>{RAWEND} {
1333 yyextra->code->codify(yytext);
1334 QCString delimiter(yytext+1);
1335 delimiter=delimiter.left(delimiter.length()-1);
1336 if (delimiter==yyextra->delimiter)
1337 {
1338 BEGIN( yyextra->lastStringContext );
1339 }
1340 }
1341<RawString>[^)\n]+ { yyextra->code->codify(yytext); }
1342<RawString>. { yyextra->code->codify(yytext); }
1343<RawString>\n { codifyLines(yyscanner,yytext); }
1344<SkipVerbString>[^"\n]+ {
1345 yyextra->code->codify(yytext);
1346 }
1347<SkipVerbString>\"\" { // escaped quote
1348 yyextra->code->codify(yytext);
1349 }
1350<SkipVerbString>\" { // end of string
1351 yyextra->code->codify(yytext);
1352 endFontClass(yyscanner);
1353 BEGIN( yyextra->lastVerbStringContext );
1354 }
1355<SkipVerbString>. {
1356 yyextra->code->codify(yytext);
1357 }
1358<SkipVerbString>\n {
1359 codifyLines(yyscanner,yytext);
1360 }
1361<Body>":" {
1362 yyextra->code->codify(yytext);
1363 yyextra->name.clear();yyextra->type.clear();
1364 }
1365<Body>"<" {
1366 if (yyextra->insideTemplate)
1367 {
1368 yyextra->sharpCount++;
1369 }
1370 yyextra->code->codify(yytext);
1371 }
1372<Body>">" {
1373 if (yyextra->insideTemplate)
1374 {
1375 if (--yyextra->sharpCount<=0)
1376 {
1377 yyextra->insideTemplate=FALSE;
1378 }
1379 }
1380 yyextra->code->codify(yytext);
1381 }
1382<Body,MemberCall,MemberCall2,FuncCall,OldStyleArgs>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" {
1383 startFontClass(yyscanner,"charliteral");
1384 yyextra->code->codify(yytext);
1385 endFontClass(yyscanner);
1386 }
1387<Body>"."|"->" {
1388 if (yytext[0]=='-') // -> could be overloaded
1389 {
1391 }
1392 yyextra->code->codify(yytext);
1393 yyextra->memCallContext = YY_START;
1394 BEGIN( MemberCall );
1395 }
static void updateCallContextForSmartPointer(yyscan_t yyscanner)
Definition code.l:2790
1396<MemberCall>{SCOPETNAME}/{BN}*"(" {
1397 if (yyextra->theCallContext.getScope().globalDef())
1398 {
1399 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1400 {
1401 codifyLines(yyscanner,yytext);
1402 addToSearchIndex(yyscanner,yytext);
1403 }
1404 yyextra->name.clear();
1405 }
1406 else
1407 {
1408 codifyLines(yyscanner,yytext);
1409 addToSearchIndex(yyscanner,yytext);
1410 yyextra->name.clear();
1411 }
1412 yyextra->type.clear();
1413 if (yyextra->memCallContext==Body)
1414 {
1415 BEGIN(FuncCall);
1416 }
1417 else
1418 {
1419 BEGIN(yyextra->memCallContext);
1420 }
1421 }
1422<MemberCall>{SCOPENAME}/{B}* {
1423 if (yyextra->theCallContext.getScope().globalDef())
1424 {
1425 DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",(void*)yyextra->theCallContext.getScope().globalDef()));
1426 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1427 {
1428 codifyLines(yyscanner,yytext);
1429 addToSearchIndex(yyscanner,yytext);
1430 }
1431 yyextra->name.clear();
1432 }
1433 else
1434 {
1435 DBG_CTX((stderr,"no class context!\n"));
1436 codifyLines(yyscanner,yytext);
1437 addToSearchIndex(yyscanner,yytext);
1438 yyextra->name.clear();
1439 }
1440 yyextra->type.clear();
1441 BEGIN(yyextra->memCallContext);
1442 }
1443<Body>[,=;\[] {
1444 if (yyextra->insideObjC && *yytext=='[')
1445 {
1446 DBG_CTX((stderr,"Found start of ObjC call!\n"));
1447 // start of a method call
1448 yyextra->contextMap.clear();
1449 yyextra->nameMap.clear();
1450 yyextra->objectMap.clear();
1451 yyextra->wordMap.clear();
1452 yyextra->commentMap.clear();
1453 yyextra->currentCtxId = 0;
1454 yyextra->currentNameId = 0;
1455 yyextra->currentObjId = 0;
1456 yyextra->currentCtx = nullptr;
1457 yyextra->braceCount = 0;
1458 unput('[');
1459 BEGIN(ObjCCall);
1460 }
1461 else
1462 {
1463 yyextra->code->codify(yytext);
1464 yyextra->saveName = yyextra->name;
1465 yyextra->saveType = yyextra->type;
1466 if (*yytext!='[' && !yyextra->type.isEmpty())
1467 {
1468 //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom());
1469 //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363
1470 {
1471 //printf("AddVariable: '%s' '%s' context=%d\n",
1472 // qPrint(yyextra->type),qPrint(yyextra->name),yyextra->theVarContext.count());
1473 addVariable(yyscanner,yyextra->type,yyextra->name);
1474 }
1475 yyextra->name.clear();
1476 }
1477 if (*yytext==';' || *yytext=='=')
1478 {
1479 yyextra->type.clear();
1480 yyextra->name.clear();
1481 }
1482 else if (*yytext=='[')
1483 {
1484 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1485 }
1486 yyextra->args.clear();
1487 yyextra->parmType.clear();
1488 yyextra->parmName.clear();
1489 }
1490 }
1491<ObjCCall,ObjCMName>"["|"{" {
1492 saveObjCContext(yyscanner);
1493 yyextra->currentCtx->format+=*yytext;
1494 BEGIN(ObjCCall);
1495 DBG_CTX((stderr,"open\n"));
1496 }
static void saveObjCContext(yyscan_t yyscanner)
Definition code.l:3990
1497<ObjCCall,ObjCMName>"]"|"}" {
1498 yyextra->currentCtx->format+=*yytext;
1499 restoreObjCContext(yyscanner);
1500 BEGIN(ObjCMName);
1501 if (yyextra->currentCtx==nullptr)
1502 {
1503 // end of call
1504 ObjCCallCtx *ctx = nullptr;
1505 auto it = yyextra->contextMap.find(0);
1506 if (it!=yyextra->contextMap.end())
1507 {
1508 ctx = it->second.get();
1509 }
1510 writeObjCMethodCall(yyscanner,ctx);
1511 BEGIN(Body);
1512 }
1513 DBG_CTX((stderr,"close\n"));
1514 }
static void restoreObjCContext(yyscan_t yyscanner)
Definition code.l:4021
1515<ObjCCall,ObjCMName>{CPPC}.* {
1516 yyextra->currentCtx->format+=escapeComment(yyscanner,yytext);
1517 }
static QCString escapeComment(yyscan_t yyscanner, const char *s)
Definition code.l:3914
1518<ObjCCall,ObjCMName>{CCS} {
1519 yyextra->lastObjCCallContext = YY_START;
1520 yyextra->currentCtx->comment.str(yytext);
1521 BEGIN(ObjCCallComment);
1522 }
1523<ObjCCallComment>{CCE} {
1524 yyextra->currentCtx->comment << yytext;
1525 std::string commentStr = yyextra->currentCtx->comment.str();
1526 yyextra->currentCtx->format+=escapeComment(yyscanner,commentStr.c_str());
1527 BEGIN(yyextra->lastObjCCallContext);
1528 }
1529<ObjCCallComment>[^*\n]+ { yyextra->currentCtx->comment << yytext; }
1530<ObjCCallComment>{CPPC}|{CCS} { yyextra->currentCtx->comment << yytext; }
1531<ObjCCallComment>\n { yyextra->currentCtx->comment << *yytext; }
1532<ObjCCallComment>. { yyextra->currentCtx->comment << *yytext; }
1533<ObjCCall>{ID}({B}*"."{B}*{ID})* {
1534 yyextra->currentCtx->format+=escapeObject(yyscanner,QCString(yytext).data());
1535 if (yyextra->braceCount==0)
1536 {
1537 yyextra->currentCtx->objectTypeOrName=yytext;
1538 DBG_CTX((stderr,"new type=%s\n",qPrint(yyextra->currentCtx->objectTypeOrName)));
1539 BEGIN(ObjCMName);
1540 }
1541 }
static QCString escapeObject(yyscan_t yyscanner, const char *s)
Definition code.l:3894
1542<ObjCMName>{ID}/{BN}*"]" {
1543 if (yyextra->braceCount==0 &&
1544 yyextra->currentCtx->methodName.isEmpty())
1545 {
1546 yyextra->currentCtx->methodName=yytext;
1547 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1548 }
1549 else
1550 {
1551 yyextra->currentCtx->format+=escapeWord(yyscanner,yytext);
1552 }
1553 }
static QCString escapeName(yyscan_t yyscanner, const char *s)
Definition code.l:3884
static QCString escapeWord(yyscan_t yyscanner, const char *s)
Definition code.l:3904
1554<ObjCMName>{ID}/{BN}*":" {
1555 if (yyextra->braceCount==0)
1556 {
1557 yyextra->currentCtx->methodName+=yytext;
1558 yyextra->currentCtx->methodName+=":";
1559 }
1560 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1561 }
1562<ObjCSkipStr>[^\n\"$\\]* { yyextra->currentCtx->format+=yytext; }
1563<ObjCSkipStr>\\. { yyextra->currentCtx->format+=yytext; }
1564<ObjCSkipStr>"\"" { yyextra->currentCtx->format+=yytext;
1565 BEGIN(yyextra->lastStringContext);
1566 }
1567<ObjCCall,ObjCMName>{CHARLIT} { yyextra->currentCtx->format+=yytext; }
1568<ObjCCall,ObjCMName>"@"?"\"" { yyextra->currentCtx->format+=yytext;
1569 yyextra->lastStringContext=YY_START;
1570 BEGIN(ObjCSkipStr);
1571 }
1572<ObjCCall,ObjCMName,ObjCSkipStr>"$" { yyextra->currentCtx->format+="$$"; }
1573<ObjCCall,ObjCMName>"(" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount++; }
1574<ObjCCall,ObjCMName>")" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount--; }
1575<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#)
1576 yyextra->currentCtx->format+=yytext;
1577 }
1578<ObjCCall,ObjCMName,ObjCSkipStr>{ID} { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); }
1579<ObjCCall,ObjCMName,ObjCSkipStr>. { yyextra->currentCtx->format+=*yytext; }
1580<ObjCCall,ObjCMName,ObjCSkipStr>\n { yyextra->currentCtx->format+=*yytext; }
1581
1582<Body>"]" {
1583 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1584 yyextra->code->codify(yytext);
1585 // TODO: nested arrays like: a[b[0]->func()]->func()
1586 yyextra->name = yyextra->saveName;
1587 yyextra->type = yyextra->saveType;
1588 }
1589<Body>[0-9]+ {
1590 yyextra->code->codify(yytext);
1591 }
1592<Body>[0-9]+[xX][0-9A-Fa-f]+ {
1593 yyextra->code->codify(yytext);
1594 }
1595<MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
1596 //addParmType(yyscanner);
1597 //yyextra->parmName=yytext;
1598 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
1599 startFontClass(yyscanner,"keyword");
1600 yyextra->code->codify(yytext);
1601 endFontClass(yyscanner);
1602 }
1603<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) {
1604 addParmType(yyscanner);
1605 yyextra->parmName=yytext;
1606 startFontClass(yyscanner,"keywordtype");
1607 yyextra->code->codify(yytext);
1608 endFontClass(yyscanner);
1609 }
static void addParmType(yyscan_t yyscanner)
Definition code.l:2609
1610<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKWSL}/([^a-z_A-Z0-9]) {
1611 if (yyextra->lang!=SrcLangExt::Slice)
1612 {
1613 REJECT;
1614 }
1615 else
1616 {
1617 addParmType(yyscanner);
1618 yyextra->parmName=yytext;
1619 startFontClass(yyscanner,"keywordtype");
1620 yyextra->code->codify(yytext);
1621 endFontClass(yyscanner);
1622 }
1623 }
1624<MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) {
1625 addParmType(yyscanner);
1626 yyextra->parmName=yytext;
1627 startFontClass(yyscanner,"keywordflow");
1628 yyextra->code->codify(yytext);
1629 endFontClass(yyscanner);
1630 }
1631<MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) {
1632 incrementFlowKeyWordCount(yyscanner);
1633 addParmType(yyscanner);
1634 yyextra->parmName=yytext;
1635 startFontClass(yyscanner,"keywordflow");
1636 yyextra->code->codify(yytext);
1637 endFontClass(yyscanner);
1638 }
1639<MemberCall2,FuncCall>("::")?{ID}(({B}*"<"[^\n\[\](){}<>']*">")?({B}*"::"{B}*{ID})?)* {
1640 if (isCastKeyword(yytext))
1641 {
1642 REJECT;
1643 }
1644 addParmType(yyscanner);
1645 yyextra->parmName=yytext;
1646 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1647 }
1648<FuncCall>";" { // probably a cast, not a function call
1649 yyextra->code->codify(yytext);
1650 yyextra->inForEachExpression = FALSE;
1651 BEGIN( Body );
1652 }
1653<MemberCall2,FuncCall>, {
1654 yyextra->code->codify(yytext);
1655 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1656 yyextra->parmType.clear();yyextra->parmName.clear();
1657 }
1658<MemberCall2,FuncCall>"{" {
1659 if (yyextra->bracketCount>0)
1660 {
1661 yyextra->code->codify(yytext);
1662 yyextra->skipInlineInitContext=YY_START;
1663 yyextra->curlyCount=0;
1664 BEGIN(InlineInit);
1665 }
1666 else
1667 {
1668 REJECT;
1669 }
1670 }
1671<InlineInit>"{" { yyextra->curlyCount++;
1672 yyextra->code->codify(yytext);
1673 }
1674<InlineInit>"}" {
1675 yyextra->code->codify(yytext);
1676 if (--yyextra->curlyCount<=0)
1677 {
1678 BEGIN(yyextra->skipInlineInitContext);
1679 }
1680 }
1681<InlineInit>\n {
1682 codifyLines(yyscanner,yytext);
1683 }
1684<InlineInit>. {
1685 yyextra->code->codify(yytext);
1686 }
1687<MemberCall2,FuncCall>"(" {
1688 yyextra->parmType.clear();yyextra->parmName.clear();
1689 yyextra->code->codify(yytext);
1690 yyextra->bracketCount++;
1691 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1692 if (YY_START==FuncCall && !yyextra->insideBody)
1693 {
1694 yyextra->theVarContext.pushScope();
1695 }
1696 }
1697<MemberCall2,FuncCall>{OPERATOR} { // operator
1698 if (qstrcmp(yytext,"*") &&
1699 qstrcmp(yytext,"&") &&
1700 qstrcmp(yytext,"^") &&
1701 qstrcmp(yytext,"%")) // typically a pointer or reference
1702 {
1703 // not a * or &, or C++/CLI's ^ or %
1704 yyextra->parmType.clear();yyextra->parmName.clear();
1705 }
1706 yyextra->code->codify(yytext);
1707 }
1708<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" {
1709 if (yytext[0]==')') // no a pointer cast
1710 {
1711 DBG_CTX((stderr,"addVariable(%s,%s)\n",qPrint(yyextra->parmType),qPrint(yyextra->parmName)));
1712 if (yyextra->parmType.isEmpty())
1713 {
1714 yyextra->parmType=yyextra->parmName;
1715 yyextra->parmName.clear();
1716 }
1717 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1718 }
1719 else
1720 {
1721 yyextra->parmType = yyextra->parmName;
1722 yyextra->parmName.clear();
1723 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1724 }
1725 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1726 yyextra->inForEachExpression = FALSE;
1727 //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b().
1728 yyextra->code->codify(yytext);
1729 if (--yyextra->bracketCount<=0)
1730 {
1731 if (yyextra->name.isEmpty())
1732 {
1733 BEGIN( Body );
1734 }
1735 else
1736 {
1737 BEGIN( CallEnd );
1738 }
1739 }
1740 }
1741<MemberCall,MemberCall2,FuncCall>[;:] { // recover from unexpected end of call
1742 //if (yytext[0]==';' || yyextra->bracketCount<=0)
1743 if (yyextra->bracketCount<=0)
1744 {
1745 unput(*yytext);
1746 BEGIN(CallEnd);
1747 }
1748 else
1749 {
1750 yyextra->code->codify(yytext);
1751 }
1752 }
1753<CallEnd>[ \t\n]* { codifyLines(yyscanner,yytext); }
1754<CallEnd>[;:] {
1755 codifyLines(yyscanner,yytext);
1756 yyextra->bracketCount=0;
1757 if (*yytext==';') yyextra->searchingForBody=FALSE;
1758 if (!yyextra->type.isEmpty())
1759 {
1760 DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",qPrint(yyextra->type),qPrint(yyextra->name)));
1761 addVariable(yyscanner,yyextra->type,yyextra->name);
1762 }
1763 yyextra->parmType.clear();yyextra->parmName.clear();
1764 yyextra->theCallContext.setScope(ScopedTypeVariant());
1765 if (*yytext==';' || yyextra->insideBody)
1766 {
1767 if (!yyextra->insideBody)
1768 {
1769 yyextra->theVarContext.popScope();
1770 }
1771 yyextra->name.clear();yyextra->type.clear();
1772 BEGIN( Body );
1773 }
1774 else
1775 {
1776 yyextra->bracketCount=0;
1777 BEGIN( SkipInits );
1778 }
1779 }
1780<CallEnd>{ENDQopt}/{BN}*(";"|"="|"throw"{BN}*"(") {
1781 startFontClass(yyscanner,"keyword");
1782 codifyLines(yyscanner,yytext);
1783 endFontClass(yyscanner);
1784 }
1785<CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
1786 if (yyextra->insideBody)
1787 {
1788 yyextra->theVarContext.pushScope();
1789 }
1790 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1791 //yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
1792 yyextra->parmType.clear();yyextra->parmName.clear();
1793 int index = yyextra->name.findRev("::");
1794 DBG_CTX((stderr,"yyextra->name=%s\n",qPrint(yyextra->name)));
1795 if (index!=-1)
1796 {
1797 QCString scope = yyextra->name.left((uint32_t)index);
1798 if (!yyextra->scopeName.isEmpty()) scope.prepend((yyextra->scopeName+"::"));
1799 const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope,true);
1800 if (cd)
1801 {
1802 setClassScope(yyscanner,cd->name());
1803 yyextra->scopeStack.push(SCOPEBLOCK);
1804 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1805 }
1806 else
1807 {
1808 //setClassScope(yyscanner,yyextra->realScope);
1809 yyextra->scopeStack.push(INNERBLOCK);
1810 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1811 }
1812 }
1813 else
1814 {
1815 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1816 yyextra->scopeStack.push(INNERBLOCK);
1817 }
1818 yytext[yyleng-1]='\0';
1819 QCString cv(yytext);
1820 if (!cv.stripWhiteSpace().isEmpty())
1821 {
1822 startFontClass(yyscanner,"keyword");
1823 codifyLines(yyscanner,yytext);
1824 endFontClass(yyscanner);
1825 }
1826 else // just whitespace
1827 {
1828 codifyLines(yyscanner,yytext);
1829 }
1830 yyextra->code->codify("{");
1831 if (yyextra->searchingForBody)
1832 {
1833 yyextra->searchingForBody=FALSE;
1834 yyextra->insideBody=TRUE;
1835 }
1836 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1837 yyextra->type.clear(); yyextra->name.clear();
1838 BEGIN( Body );
1839 }
static void setClassScope(yyscan_t yyscanner, const QCString &name)
Definition code.l:2304
1840<CallEnd>"try" { // function-try-block
1841 startFontClass(yyscanner,"keyword");
1842 yyextra->code->codify(yytext);
1843 endFontClass(yyscanner);
1844 yyextra->inFunctionTryBlock=TRUE;
1845 }
1846<CallEnd>"requires" { // function-try-block
1847 startFontClass(yyscanner,"keyword");
1848 yyextra->code->codify(yytext);
1849 endFontClass(yyscanner);
1850 }
1851<CallEnd>{ID} {
1852 if (yyextra->insideBody || !yyextra->parmType.isEmpty())
1853 {
1854 REJECT;
1855 }
1856 // could be K&R style definition
1857 addParmType(yyscanner);
1858 yyextra->parmName=yytext;
1859 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1860 BEGIN(OldStyleArgs);
1861 }
1862<OldStyleArgs>{ID} {
1863 addParmType(yyscanner);
1864 yyextra->parmName=yytext;
1865 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1866 }
1867<OldStyleArgs>[,;] {
1868 yyextra->code->codify(yytext);
1869 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1870 if (*yytext==';') yyextra->parmType.clear();
1871 yyextra->parmName.clear();
1872 }
1873<CallEnd,OldStyleArgs>"#" {
1874 startFontClass(yyscanner,"preprocessor");
1875 yyextra->lastSkipCppContext = Body;
1876 yyextra->code->codify(yytext);
1877 BEGIN( SkipCPP );
1878 }
1879<CallEnd>. {
1880 unput(*yytext);
1881 if (!yyextra->insideBody)
1882 {
1883 yyextra->theVarContext.popScope();
1884 }
1885 yyextra->name.clear();yyextra->args.clear();
1886 yyextra->parmType.clear();yyextra->parmName.clear();
1887 BEGIN( Body );
1888 }
1889<SkipInits>";" {
1890 yyextra->code->codify(yytext);
1891 yyextra->type.clear(); yyextra->name.clear();
1892 BEGIN( Body );
1893 }
1894<SkipInits>"{" {
1895 yyextra->code->codify(yytext);
1896 if (yyextra->searchingForBody)
1897 {
1898 yyextra->searchingForBody=FALSE;
1899 yyextra->insideBody=TRUE;
1900 }
1901 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1902 if (yyextra->name.find("::")!=-1)
1903 {
1904 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1905 yyextra->scopeStack.push(SCOPEBLOCK);
1906 setClassScope(yyscanner,yyextra->realScope);
1907 }
1908 else
1909 {
1910 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1911 yyextra->scopeStack.push(INNERBLOCK);
1912 }
1913 yyextra->type.clear(); yyextra->name.clear();
1914 BEGIN( Body );
1915 }
1916<SkipInits>{ID}{B}*"{" {
1917 QCString text(yytext);
1918 int bracketPos = text.find('{');
1919 int spacePos = text.find(' ');
1920 int len = spacePos==-1 ? bracketPos : spacePos;
1921 generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len));
1922 yyextra->code->codify(QCString(yytext+len));
1923 }
1924<SkipInits>{ID} {
1925 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1926 }
1927<FuncCall>{ID}/"(" {
1928 generateFunctionLink(yyscanner,*yyextra->code,yytext);
1929 }
1930<FuncCall>{ID}/("."|"->") {
1931 yyextra->name=yytext;
1932 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1933 BEGIN( MemberCall2 );
1934 }
1935<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") {
1936 yyextra->code->codify(yytext);
1937 uint32_t s=0;while (!isId(yytext[s])) s++;
1938 uint32_t e=(uint32_t)yyleng-1;while (e>1 && !isId(yytext[e])) e--;
1939 yyextra->name=((QCString)yytext).mid(s,e-s+1);
1940 BEGIN( MemberCall2 );
1941 }
1942<MemberCall2>{ID}/([ \t\n]*"(") {
1943 if (!yyextra->args.isEmpty())
1944 generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext);
1945 else
1946 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1947 yyextra->args.clear();
1948 BEGIN( FuncCall );
1949 }
static void generateMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &varName, const QCString &memName)
Definition code.l:3244
1950<MemberCall2>{ID}/([ \t\n]*("."|"->")) {
1951 //yyextra->code->codify(yytext);
1952 yyextra->name=yytext;
1953 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1954 BEGIN( MemberCall2 );
1955 }
1956<MemberCall2>"->"|"." {
1957 if (yytext[0]=='-') // -> could be overloaded
1958 {
1960 }
1961 yyextra->code->codify(yytext);
1962 yyextra->memCallContext = YY_START;
1963 BEGIN( MemberCall );
1964 }
1965<SkipComment>{CCS}("!"?){CCE} {
1966 yyextra->code->codify(yytext);
1967 endFontClass(yyscanner,true);
1968 BEGIN( yyextra->lastCContext ) ;
1969 }
1970<SkipComment>{CPPC}|{CCS} {
1971 yyextra->code->codify(yytext);
1972 }
1973<SkipComment>[^*\/\n]+ {
1974 yyextra->code->codify(yytext);
1975 }
1976<SkipComment>[ \t]*{CCE} {
1977 yyextra->code->codify(yytext);
1978 endFontClass(yyscanner,true);
1979 if (yyextra->lastCContext==SkipCPP)
1980 {
1981 startFontClass(yyscanner,"preprocessor");
1982 }
1983 BEGIN( yyextra->lastCContext ) ;
1984 }
1985<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation
1986 codifyLines(yyscanner,yytext);
1987 }
1988<SkipCxxComment>[^\r\n]+ {
1989 yyextra->code->codify(yytext);
1990 }
1991<SkipCxxComment>\r
1992<SkipCxxComment>\n {
1993 unput('\n');
1994 endFontClass(yyscanner);
1995 BEGIN( yyextra->lastCContext ) ;
1996 }
1997<SkipCxxComment>. {
1998 yyextra->code->codify(yytext);
1999 }
2000<MemberCall>[^a-z_A-Z0-9(\n] {
2001 yyextra->code->codify(yytext);
2002 yyextra->type.clear();
2003 yyextra->name.clear();
2004 BEGIN(yyextra->memCallContext);
2005 }
2006<*>\n({B}*{CPPC}[!/][^\n]*\n)+ { // remove special one-line comment
2007 if (YY_START==SkipCPP) REJECT;
2008 startFontClass(yyscanner,"comment",true);
2009 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2010 endFontClass(yyscanner,true);
2011 codifyLines(yyscanner,"\n");
2012 if (YY_START==SkipCxxComment)
2013 {
2014 BEGIN( yyextra->lastCContext ) ;
2015 }
2016 }
2017<SkipCPP>\n/(.|\n) {
2018 endFontClass(yyscanner);
2019 BEGIN( yyextra->lastSkipCppContext ) ;
2020 unput('\n');
2021 }
2022<*>\n{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2023 startFontClass(yyscanner,"comment",true);
2024 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2025 endFontClass(yyscanner,true);
2026 codifyLines(yyscanner,"\n");
2027 if (YY_START==SkipCxxComment)
2028 {
2029 BEGIN( yyextra->lastCContext ) ;
2030 }
2031 }
2032<*>\n{B}*{CCS}"@"[{}] { // remove one-line group marker
2033 // check is to prevent getting stuck in skipping C++ comments
2034 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2035 {
2036 yyextra->lastCContext = YY_START ;
2037 }
2038 startFontClass(yyscanner,"comment",true);
2039 codifyLines(yyscanner,yytext);
2040 BEGIN(SkipComment);
2041 }
2042<*>^{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2043 startFontClass(yyscanner,"comment",true);
2044 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2045 endFontClass(yyscanner,true);
2046 codifyLines(yyscanner,"\n");
2047 }
2048<*>^{B}*{CCS}"@"[{}] { // remove multi-line group marker
2049 // check is to prevent getting stuck in skipping C++ comments
2050 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2051 {
2052 yyextra->lastCContext = YY_START ;
2053 }
2054 startFontClass(yyscanner,"comment",true);
2055 yyextra->code->codify(yytext);
2056 BEGIN(SkipComment);
2057 }
2058<*>^{B}*{CPPC}[!/][^\n]* { // remove special one-line comment
2059 startFontClass(yyscanner,"comment",true);
2060 codifyLines(yyscanner,yytext);
2061 endFontClass(yyscanner,true);
2062 }
2063<*>{CPPC}[!/][^\n]* { // strip special one-line comment
2064 if (YY_START==SkipComment || YY_START==SkipString) REJECT;
2065 startFontClass(yyscanner,"comment",true);
2066 codifyLines(yyscanner,yytext);
2067 endFontClass(yyscanner,true);
2068 }
2069<*>\n{B}*{CCS}[!*]/{NCOMM} {
2070 // check is to prevent getting stuck in skipping C++ comments
2071 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2072 {
2073 yyextra->lastCContext = YY_START ;
2074 }
2075 startFontClass(yyscanner,"comment",true);
2076 codifyLines(yyscanner,yytext);
2077 BEGIN(SkipComment);
2078 }
2079<*>^{B}*{CCS}"*"[*]+/[^/] {
2080 // check is to prevent getting stuck in skipping C++ comments
2081 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2082 {
2083 yyextra->lastCContext = YY_START ;
2084 }
2085 // special C "banner" comment block at a new line
2086 startFontClass(yyscanner,"comment",Config_getBool(JAVADOC_BANNER));
2087 yyextra->code->codify(yytext);
2088 BEGIN(SkipComment);
2089 }
2090<*>^{B}*{CCS}[!*]/{NCOMM} { // special C comment block at a new line
2091 // check is to prevent getting stuck in skipping C++ comments
2092 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2093 {
2094 yyextra->lastCContext = YY_START ;
2095 }
2096 startFontClass(yyscanner,"comment",true);
2097 yyextra->code->codify(yytext);
2098 BEGIN(SkipComment);
2099 }
2100<*>{CCS}[!*]/{NCOMM} { // special C comment block half way a line
2101 if (YY_START==SkipString) REJECT;
2102 // check is to prevent getting stuck in skipping C++ comments
2103 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2104 {
2105 yyextra->lastCContext = YY_START ;
2106 }
2107 startFontClass(yyscanner,"comment",true);
2108 yyextra->code->codify(yytext);
2109 BEGIN(SkipComment);
2110 }
2111<*>{CCS}("!"?){CCE} {
2112 if (YY_START==SkipString) REJECT;
2113 bool specialComment = QCString(yytext).find('!')!=-1;
2114 startFontClass(yyscanner,"comment",specialComment);
2115 yyextra->code->codify(yytext);
2116 endFontClass(yyscanner,specialComment);
2117 }
2118<SkipComment>[^\*\n]+ {
2119 yyextra->code->codify(yytext);
2120 }
2121<*>{CCS} {
2122 startFontClass(yyscanner,"comment");
2123 yyextra->code->codify(yytext);
2124 // check is to prevent getting stuck in skipping C++ comments
2125 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2126 {
2127 yyextra->lastCContext = YY_START ;
2128 }
2129 BEGIN( SkipComment ) ;
2130 }
2131<*>[$]?@\" { // C# (interpolated) verbatim string
2132 startFontClass(yyscanner,"stringliteral");
2133 yyextra->code->codify(yytext);
2134 yyextra->lastVerbStringContext=YY_START;
2135 BEGIN(SkipVerbString);
2136 }
2137<*>{CPPC} {
2138 startFontClass(yyscanner,"comment");
2139 yyextra->code->codify(yytext);
2140 yyextra->lastCContext = YY_START ;
2141 BEGIN( SkipCxxComment ) ;
2142 }
2143<*>"("|"[" {
2144 if (yytext[0]=='(') yyextra->bracketCount++;
2145 yyextra->code->codify(yytext);
2146 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2147 }
2148<*>")"|"]" {
2149 if (yytext[0]==')') yyextra->bracketCount--;
2150 yyextra->code->codify(yytext);
2151 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2152 }
2153<*>\n {
2154 codifyLines(yyscanner,yytext);
2155 }
2156<*>[\x80-\xFF]* { // keep utf8 characters together...
2157 yyextra->code->codify(yytext);
2158 }
2159<*>. {
2160 yyextra->code->codify(yytext);
2161 }
2162
2163%%

◆ yyread()

static int yyread ( yyscan_t yyscanner,
char * buf,
int max_size )
static

Definition at line 3974 of file code.l.

3975{
3976 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3977 yy_size_t inputPosition = yyextra->inputPosition;
3978 const char *s = yyextra->inputString + inputPosition;
3979 int c=0;
3980 while( c < max_size && *s )
3981 {
3982 *buf++ = *s++;
3983 c++;
3984 }
3985 yyextra->inputPosition += c;
3986 return c;
3987}