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:3995

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()

void addParmType ( yyscan_t yyscanner)
static

Definition at line 2621 of file code.l.

2622{
2623 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2624 if (yyextra->parmName=="const") { yyextra->parmName.clear(); return; }
2625 if (!yyextra->parmType.isEmpty()) yyextra->parmType += ' ' ;
2626 yyextra->parmType += yyextra->parmName ;
2627 yyextra->parmName.clear() ;
2628}

◆ addToSearchIndex() [1/2]

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

Definition at line 2310 of file code.l.

2311{
2312 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:2302
2313}

References addToSearchIndex().

◆ addToSearchIndex() [2/2]

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

◆ addType()

void addType ( 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->name=="const") { yyextra->name.clear(); return; }
2613 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2614 yyextra->type += yyextra->name ;
2615 yyextra->name.clear() ;
2616 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2617 yyextra->type += yyextra->args ;
2618 yyextra->args.clear() ;
2619}

◆ addUsingDirective()

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

Definition at line 2630 of file code.l.

2631{
2632 //printf("AddUsingDirective(%s)\n",qPrint(name));
2633 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2634 if (yyextra->sourceFileDef && !name.isEmpty())
2635 {
2636 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name);
2637 if (nd)
2638 {
2639 yyextra->theUsingContext.emplace(name.str(),nd);
2640 }
2641 }
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:537
2642}

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

◆ addVariable()

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

Definition at line 2187 of file code.l.

2188{
2189 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2190 DBG_CTX((stderr,"VariableContext::addVariable(%s,%s)\n",qPrint(type),qPrint(name)));
2191 QCString ltype = type.simplifyWhiteSpace();
2192 QCString lname = name.simplifyWhiteSpace();
2193 ltype.stripPrefix("struct ");
2194 ltype.stripPrefix("union ");
2195 if (ltype.isEmpty() || lname.isEmpty()) return;
2196 ltype = substitute(ltype,".","::");
2197 DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n",
2198 qPrint(ltype),qPrint(lname),yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>"));
2199 auto it = yyextra->codeClassMap.find(ltype.str());
2200 if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block
2201 {
2202 DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname)));
2203 yyextra->theVarContext.addVariable(lname,std::move(it->second)); // add it to a list
2204 }
2205 else
2206 {
2207 auto findVariableType = [&yyscanner,&yyg,&ltype,&lname,&name](const Definition *d) -> const ClassDef *
2208 {
2209 const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype,true);
2210 int i=0;
2211 if (varDef)
2212 {
2213 DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname)));
2214 yyextra->theVarContext.addVariable(lname,ScopedTypeVariant(varDef)); // add it to a list
2215 }
2216 else if ((i=ltype.find('<'))!=-1)
2217 {
2218 // probably a template class
2219 addVariable(yyscanner,ltype.left(i),name);
2220 }
2221 return varDef;
2222 };
2223 const ClassDef *varDef = findVariableType(yyextra->currentDefinition);
2224 if (varDef==nullptr) // also check via using directive
2225 {
2226 for (const auto &[usingName,namespaceDef] : yyextra->theUsingContext)
2227 {
2228 varDef = findVariableType(namespaceDef);
2229 if (varDef) break;
2230 }
2231 }
2232 if (varDef==nullptr)
2233 {
2234 if (!yyextra->theVarContext.atGlobalScope()) // for local variables add a dummy entry so the name
2235 // is hidden to avoid false links to global variables with the same name
2236 // TODO: make this work for namespaces as well!
2237 {
2238 DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",qPrint(lname)));
2239 yyextra->theVarContext.addVariable(lname,ScopedTypeVariant());
2240 }
2241 else
2242 {
2243 DBG_CTX((stderr,"** addVariable: not adding variable!\n"));
2244 }
2245 }
2246 }
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:2187
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:672
2247}

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

Referenced by addVariable(), and setParameterList().

◆ codeFolding()

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

Definition at line 2366 of file code.l.

2367{
2368 if (Config_getBool(HTML_CODE_FOLDING))
2369 {
2370 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2371 //fprintf(stderr,"codeFolding at %d\n",yyextra->yyLineNr);
2372 //if (d)
2373 // fprintf(stderr,"%d: codeFolding: candidate=%s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->qualifiedName()),d->getStartDefLine(),d->getEndBodyLine());
2374 endCodeFold(yyscanner);
2375 if (d)
2376 {
2377 int startLine = d->getStartDefLine();
2378 int endLine = d->getEndBodyLine();
2379 if (endLine!=-1 && startLine!=endLine &&
2380 // since the end of a section is closed after the last line, we need to avoid starting a
2381 // new section if the previous section ends at the same line, i.e. something like
2382 // struct X {
2383 // ...
2384 // }; struct S { <- start of S and end of X at the same line
2385 // ...
2386 // };
2387 (yyextra->foldStack.empty() || yyextra->foldStack.back()->getEndBodyLine()!=startLine))
2388 {
2389 //printf("%d: start codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->name()),d->getStartDefLine(),d->getEndBodyLine());
2391 {
2392 const MemberDef *md = toMemberDef(d);
2393 if (md && md->isDefine())
2394 {
2395 yyextra->code->startFold(yyextra->yyLineNr,"",""); // #define X ...
2396 }
2397 else if (md && md->isCallable())
2398 {
2399 yyextra->code->startFold(yyextra->yyLineNr,"{","}"); // func() { ... }
2400 }
2401 else
2402 {
2403 yyextra->code->startFold(yyextra->yyLineNr,"{","};"); // enum X { ... }
2404 }
2405 }
2407 {
2408 yyextra->code->startFold(yyextra->yyLineNr,"{","};"); // class X { ... };
2409 }
2410 else
2411 {
2412 yyextra->code->startFold(yyextra->yyLineNr,"{","}"); // namespace X {...}
2413 }
2414 yyextra->foldStack.push_back(d);
2415 }
2416 }
2417 }
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:2345
#define Config_getBool(name)
Definition config.h:33
MemberDef * toMemberDef(Definition *d)
2418}

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]

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

Definition at line 2548 of file code.l.

2549{
2550 codifyLines(yyscanner,QCString(text));
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2520
2551}

References codifyLines().

◆ codifyLines() [2/2]

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 2520 of file code.l.

2521{
2522 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2523 DBG_CTX((stderr,"codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,qPrint(text)));
2524 if (text.isEmpty()) return;
2525 const char *p=text.data(),*sp=p;
2526 char c;
2527 bool done=FALSE;
2528 while (!done)
2529 {
2530 sp=p;
2531 while ((c=*p++) && c!='\n');
2532 if (c=='\n')
2533 {
2534 yyextra->yyLineNr++;
2535 size_t l = static_cast<size_t>(p-sp-1);
2536 std::string tmp(sp,l);
2537 yyextra->code->codify(tmp.c_str());
2538 nextCodeLine(yyscanner);
2539 }
2540 else
2541 {
2542 yyextra->code->codify(QCString(sp));
2543 done=TRUE;
2544 }
2545 }
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:2502
#define TRUE
Definition qcstring.h:37
2546}

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()

int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3486 of file code.l.

3487{
3488 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3489 const char *p=yyextra->inputString;
3490 char c = 0;
3491 int count=1;
3492 while ((c=*p))
3493 {
3494 p++ ;
3495 if (c=='\n') count++;
3496 }
3497 if (p>yyextra->inputString && *(p-1)!='\n')
3498 { // last line does not end with a \n, so we add an extra
3499 count++;
3500 }
3501 return count;
3502}

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

◆ endCodeFold()

void endCodeFold ( yyscan_t yyscanner)
static

Definition at line 2345 of file code.l.

2346{
2347 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2348 while (!yyextra->foldStack.empty())
2349 {
2350 const Definition *dd = yyextra->foldStack.back();
2351 if (dd->getEndBodyLine()+1==yyextra->yyLineNr) // +1 to close the section after the end of the body
2352 {
2353 yyextra->code->endFold();
2354 //fprintf(stderr,"%d: end codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(dd->name()),dd->getStartDefLine(),dd->getEndBodyLine());
2355 yyextra->foldStack.pop_back();
2356 }
2357 else
2358 {
2359 //fprintf(stderr,"no end of block dd=%s end=%d\n",qPrint(dd->qualifiedName()),dd->getEndBodyLine());
2360 break;
2361 }
2362 }
2363}

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2493 of file code.l.

2494{
2495 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2496 DBG_CTX((stderr,"endCodeLine(%d)\n",yyextra->yyLineNr));
2497 endFontClass(yyscanner);
2498 yyextra->code->endCodeLine();
2499 yyextra->insideCodeLine = false;
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
Definition code.l:3504
2500}

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()

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

Definition at line 3504 of file code.l.

3505{
3506 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3507 if (yyextra->currentFontClass)
3508 {
3509 yyextra->code->endFontClass();
3510 yyextra->currentFontClass=nullptr;
3511 }
3512 if (specialComment && yyextra->insideSpecialComment)
3513 {
3514 yyextra->code->endSpecialComment();
3515 yyextra->insideSpecialComment = false;
3516 }
3517}

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

◆ escapeComment()

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

Definition at line 3935 of file code.l.

3936{
3937 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3938 QCString result;
3939 result.sprintf("$d%d",yyextra->currentCommentId);
3940 yyextra->commentMap.emplace(yyextra->currentCommentId,s);
3941 yyextra->currentCommentId++;
3942 return result;
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
3943}

References QCString::sprintf().

◆ escapeName()

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

Definition at line 3905 of file code.l.

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

References QCString::sprintf().

◆ escapeObject()

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

Definition at line 3915 of file code.l.

3916{
3917 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3918 QCString result;
3919 result.sprintf("$o%d",yyextra->currentObjId);
3920 yyextra->objectMap.emplace(yyextra->currentObjId,s);
3921 yyextra->currentObjId++;
3922 return result;
3923}

References QCString::sprintf().

◆ escapeWord()

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

Definition at line 3925 of file code.l.

3926{
3927 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3928 QCString result;
3929 result.sprintf("$w%d",yyextra->currentWordId);
3930 yyextra->wordMap.emplace(yyextra->currentWordId,s);
3931 yyextra->currentWordId++;
3932 return result;
3933}

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3222 of file code.l.

3226{
3227 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3228 if (def && def->definitionType()==Definition::TypeClass)
3229 {
3230 const ClassDef *cd = toClassDef(def);
3231 const MemberDef *xmd = cd->getMemberByName(memName);
3232 DBG_CTX((stderr,"generateClassMemberLink(class=%s,member=%s)=%p\n",qPrint(def->name()),qPrint(memName),(void*)xmd));
3233 if (xmd)
3234 {
3235 return generateClassMemberLink(yyscanner,ol,xmd,memName);
3236 }
3237 else
3238 {
3239 const Definition *innerDef = cd->findInnerCompound(memName);
3240 if (innerDef)
3241 {
3242 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3243 addToSearchIndex(yyscanner,memName);
3244 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3245 return TRUE;
3246 }
3247 }
3248 }
3249 else if (def && def->definitionType()==Definition::TypeNamespace)
3250 {
3251 const NamespaceDef *nd = toNamespaceDef(def);
3252 DBG_CTX((stderr,"Looking for %s inside namespace %s\n",qPrint(memName),qPrint(nd->name())));
3253 const Definition *innerDef = nd->findInnerCompound(memName);
3254 if (innerDef)
3255 {
3256 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3257 addToSearchIndex(yyscanner,memName);
3258 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3259 return TRUE;
3260 }
3261 }
3262 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:2571
static bool generateClassMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const QCString &memName)
Definition code.l:3160
NamespaceDef * toNamespaceDef(Definition *d)
3263}

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]

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

Definition at line 3160 of file code.l.

3164{
3165 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3166 // extract class definition of the return type in order to resolve
3167 // a->b()->c() like call chains
3168
3169 DBG_CTX((stderr,"type='%s' args='%s' class=%s\n",
3170 qPrint(xmd->typeString()),qPrint(xmd->argsString()),
3171 qPrint(xmd->getClassDef()->name())));
virtual QCString typeString() const =0
virtual const ClassDef * getClassDef() const =0
virtual QCString argsString() const =0
3172
3173 if (yyextra->exampleBlock)
3174 {
3175 std::lock_guard<std::mutex> lock(Doxygen::addExampleMutex);
3176 QCString anchor;
3177 anchor.sprintf("a%d",yyextra->anchorCount);
3178 DBG_CTX((stderr,"addExampleFile(%s,%s,%s)\n",qPrint(anchor),qPrint(yyextra->exampleName),
3179 qPrint(yyextra->exampleFile)));
3180 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(xmd));
3181 if (mdm && mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
3182 {
3183 ol.writeCodeAnchor(anchor);
3184 yyextra->anchorCount++;
3185 }
3186 }
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)
3187
3188 const ClassDef *typeClass = stripClassName(yyscanner,removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope());
3189 DBG_CTX((stderr,"%s -> typeName=%p\n",qPrint(xmd->typeString()),(void*)typeClass));
3190 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:2661
QCString removeAnonymousScopes(const QCString &str)
Definition util.cpp:173
3191
3192 const Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
3193 xmd->getFileDef() : xmd->getOuterScope();
3194 if (xmd->getGroupDef()) xd = xmd->getGroupDef();
3195 if (xd && xd->isLinkable())
3196 {
virtual bool isLinkable() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual GroupDef * getGroupDef()=0
virtual const FileDef * getFileDef() const =0
3197
3198 DBG_CTX((stderr,"yyextra->currentDefinition=%p yyextra->currentMemberDef=%p xmd=%p yyextra->insideBody=%d\n",
3199 (void*)yyextra->currentDefinition,(void*)yyextra->currentMemberDef,(void*)xmd,yyextra->insideBody));
3200
3201 if (xmd->templateMaster()) xmd = xmd->templateMaster();
virtual const MemberDef * templateMaster() const =0
3202
3203 if (xmd->isLinkable())
3204 {
3205 // add usage reference
3206 if (yyextra->currentDefinition && yyextra->currentMemberDef &&
3207 yyextra->insideBody && yyextra->collectXRefs)
3208 {
3209 addDocCrossReference(yyextra->currentMemberDef,xmd);
3210 }
void addDocCrossReference(const MemberDef *s, const MemberDef *d)
3211
3212 // write the actual link
3213 writeMultiLineCodeLink(yyscanner,ol,xmd,memName);
3214 addToSearchIndex(yyscanner,memName);
3215 return TRUE;
3216 }
3217 }
3218
3219 return FALSE;
3220}

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]

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

Definition at line 3154 of file code.l.

3156{
3157 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:2928
3158}

References generateClassOrGlobalLink().

◆ generateClassOrGlobalLink() [2/2]

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

Definition at line 2928 of file code.l.

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

References addDocCrossReference(), ClassDefMutable::addExample(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), codifyLines(), 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(), QCString::left(), QCString::mid(), Definition::name(), ScopedTypeVariant::name(), parent(), qPrint(), setCallContextForVar(), QCString::sprintf(), substitute(), toClassDef(), toClassDefMutable(), toMemberDef(), toMemberDefMutable(), TRUE, Definition::TypeClass, Definition::TypeMember, OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

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

◆ generateFunctionLink() [1/2]

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

Definition at line 3480 of file code.l.

3481{
3482 generateFunctionLink(yyscanner,ol,QCString(funcName));
static void generateFunctionLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
Definition code.l:3371
3483}

References generateFunctionLink().

◆ generateFunctionLink() [2/2]

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

Definition at line 3371 of file code.l.

3372{
3373 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3374 //CodeClassDef *ccd=nullptr;
3375 QCString locScope=yyextra->scopeName;
3376 QCString locFunc=removeRedundantWhiteSpace(funcName);
3377 if (yyextra->lang==SrcLangExt::PHP && locFunc.startsWith("self::")) locFunc=locFunc.mid(4);
3378 QCString funcScope;
3379 QCString funcWithScope=locFunc;
3380 QCString funcWithFullScope=locFunc;
3381 QCString fullScope=locScope;
3382 DBG_CTX((stderr,"*** locScope=%s locFunc=%s\n",qPrint(locScope),qPrint(locFunc)));
3383 int len=2;
3384 int i=locFunc.findRev("::");
3385 if (yyextra->currentMemberDef && yyextra->currentMemberDef->resolveAlias()->getClassDef() &&
3386 funcName==yyextra->currentMemberDef->localName() &&
3387 yyextra->currentMemberDef->getDefLine()==yyextra->yyLineNr &&
3388 generateClassMemberLink(yyscanner,ol,yyextra->currentMemberDef,funcName)
3389 )
3390 {
3391 // special case where funcName is the name of a method that is also
3392 // defined on this line. In this case we can directly link to
3393 // yyextra->currentMemberDef, which is not only faster, but
3394 // in case of overloaded methods, this will make sure that we link to
3395 // the correct method, and thereby get the correct reimplemented relations.
3396 // See also bug 549022.
3397 goto exit;
3398 }
3399 if (i==-1) i=locFunc.findRev("."),len=1;
3400 if (i==-1) i=locFunc.findRev("\\"),len=1; // for PHP
3401 if (i>0)
3402 {
3403 funcScope=locFunc.left(i);
3404 locFunc=locFunc.right(locFunc.length()-i-len).stripWhiteSpace();
3405 int ts=locScope.find('<'); // start of template
3406 int te=locScope.findRev('>'); // end of template
3407 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
3408 if (ts!=-1 && te!=-1 && te>ts)
3409 {
3410 // remove template from scope
3411 locScope=locScope.left(ts)+locScope.right(locScope.length()-te-1);
3412 }
3413 ts=funcScope.find('<'); // start of template
3414 te=funcScope.findRev('>'); // end of template
3415 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
3416 if (ts!=-1 && te!=-1 && te>ts)
3417 {
3418 // remove template from scope
3419 funcScope=funcScope.left(ts)+funcScope.right(funcScope.length()-te-1);
3420 }
3421 if (!funcScope.isEmpty())
3422 {
3423 funcWithScope = funcScope+"::"+locFunc;
3424 if (!locScope.isEmpty())
3425 {
3426 fullScope=locScope+"::"+funcScope;
3427 }
3428 }
3429 if (!locScope.isEmpty())
3430 {
3431 funcWithFullScope = locScope+"::"+funcWithScope;
3432 }
3433 }
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:579
3434
3435 if (!fullScope.isEmpty())
3436 {
3437 auto it = yyextra->codeClassMap.find(fullScope.str());
3438 if (it!=yyextra->codeClassMap.end())
3439 {
3440 ScopedTypeVariant ccd = it->second;
3441 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
3442 {
3443 for (const auto &bcName : ccd.localDef()->baseClasses())
3444 {
3445 if (getLink(yyscanner,bcName,locFunc,ol,funcName))
3446 {
3447 goto exit;
3448 }
3449 }
3450 }
3451 }
3452 }
std::vector< QCString > baseClasses() const
3453
3454 if (!locScope.isEmpty() && fullScope!=locScope)
3455 {
3456 auto it = yyextra->codeClassMap.find(locScope.str());
3457 if (it!=yyextra->codeClassMap.end())
3458 {
3459 ScopedTypeVariant ccd = it->second;
3460 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
3461 {
3462 for (const auto &bcName : ccd.localDef()->baseClasses())
3463 {
3464 if (getLink(yyscanner,bcName,funcWithScope,ol,funcName))
3465 {
3466 goto exit;
3467 }
3468 }
3469 }
3470 }
3471 }
3472 if (!getLink(yyscanner,locScope,funcWithScope,ol,funcName))
3473 {
3474 generateClassOrGlobalLink(yyscanner,ol,funcName);
3475 }
3476exit:
3477 return;
3478}

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

Referenced by generateFunctionLink().

◆ generateMemberLink()

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

Definition at line 3265 of file code.l.

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

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()

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

Definition at line 3359 of file code.l.

3360{
3361 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3362 QCString name(varName+7); // strip $this->
3363 name.prepend("$");
3364 DBG_CTX((stderr,"generatePHPVariableLink(%s) name=%s scope=%s\n",varName,qPrint(name),qPrint(yyextra->scopeName)));
3365 if (!getLink(yyscanner,yyextra->scopeName,name,ol,QCString(varName)))
3366 {
3367 codifyLines(yyscanner,varName);
3368 }
3369}

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

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 268 of file code.l.

268{return __FILE__;}

◆ getLink()

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

Definition at line 2903 of file code.l.

2909{
2910 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2911 DBG_CTX((stderr,"getLink(%s,%s) yyextra->curClassName=%s\n",
2912 qPrint(className),qPrint(memberName),qPrint(yyextra->curClassName)));
2913 QCString m=removeRedundantWhiteSpace(memberName);
2914 QCString c=className;
2915 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2916 {
2917 if (!yyextra->curClassName.isEmpty())
2918 {
2919 if (!c.isEmpty()) c.prepend("::");
2920 c.prepend(yyextra->curClassName);
2921 return getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly);
2922 }
2923 return FALSE;
2924 }
2925 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:2819
2926}

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

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

◆ getLinkInScope()

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 2819 of file code.l.

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

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()

void incrementFlowKeyWordCount ( yyscan_t yyscanner)
static

Definition at line 2553 of file code.l.

2554{
2555 std::lock_guard<std::mutex> lock(Doxygen::countFlowKeywordsMutex);
2556 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2557 if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction())
2558 {
2559 MemberDefMutable *md = toMemberDefMutable(const_cast<MemberDef*>(yyextra->currentMemberDef));
2560 if (md)
2561 {
2563 }
2564 }
static std::mutex countFlowKeywordsMutex
Definition doxygen.h:141
virtual void incrementFlowKeyWordCount()=0
2565}

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

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3986 of file code.l.

3987{
3988 QCString s(keyword);
3989 int i=s.find('<');
3990 if (i==-1) return FALSE;
3991 QCString kw = s.left(i).stripWhiteSpace();
3992 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3993}

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

◆ nextCodeLine()

void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2502 of file code.l.

2503{
2504 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2505 const char * fc = yyextra->currentFontClass;
2506 if (yyextra->insideCodeLine)
2507 {
2508 endCodeLine(yyscanner);
2509 }
2510 if (yyextra->yyLineNr<yyextra->inputLines)
2511 {
2512 yyextra->currentFontClass = fc;
2513 startCodeLine(yyscanner);
2514 }
static void endCodeLine(yyscan_t yyscanner)
Definition code.l:2493
static void startCodeLine(yyscan_t yyscanner)
Definition code.l:2424
2515}

References endCodeLine(), and startCodeLine().

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

◆ popScope()

void popScope ( yyscan_t yyscanner)
static

remove the top class/namespace name from the scope

Definition at line 2270 of file code.l.

2271{
2272 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2273 if (!yyextra->scopeNameLengthStack.empty())
2274 {
2275 int length = yyextra->scopeNameLengthStack.back();
2276 yyextra->scopeNameLengthStack.pop_back();
2277 yyextra->scopeName.resize(length);
2278 }
2279 else
2280 {
2281 //err("Too many end of scopes found!\n");
2282 }
2283 DBG_CTX((stderr,"popScope() result: '%s'\n",qPrint(yyextra->scopeName)));
2284}

References DBG_CTX, and qPrint().

Referenced by setClassScope().

◆ pushScope()

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

add class/namespace name s to the scope

Definition at line 2252 of file code.l.

2253{
2254 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2255 yyextra->scopeNameLengthStack.push_back(int(yyextra->scopeName.length()));
2256 if (yyextra->scopeName.isEmpty() || leftScopeMatch(s,yyextra->scopeName))
2257 {
2258 yyextra->scopeName = s;
2259 }
2260 else
2261 {
2262 yyextra->scopeName += "::";
2263 yyextra->scopeName += s;
2264 }
2265 DBG_CTX((stderr,"pushScope(%s) result: '%s'\n",qPrint(s),qPrint(yyextra->scopeName)));
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:893
2266}

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

Referenced by setClassScope().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4042 of file code.l.

4043{
4044 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4045 DBG_CTX((stderr,"restore state=%d->%d\n",YY_START,yyextra->currentCtx->lexState));
4046 BEGIN(yyextra->currentCtx->lexState);
4047 yyextra->braceCount = yyextra->currentCtx->braceCount;
4048 if (!yyextra->contextStack.empty())
4049 {
4050 yyextra->currentCtx = yyextra->contextStack.top();
4051 yyextra->contextStack.pop();
4052 }
4053 else
4054 {
4055 yyextra->currentCtx = nullptr;
4056 DBG_CTX((stderr,"Trying to pop context while yyextra->contextStack is empty!\n"));
4057 }
4058}

References DBG_CTX.

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 4011 of file code.l.

4012{
4013 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4014 if (yyextra->currentCtx)
4015 {
4016 yyextra->currentCtx->format+=QCString().sprintf("$c%d",yyextra->currentCtxId);
4017 if (yyextra->braceCount==0 && YY_START==ObjCCall)
4018 {
4019 yyextra->currentCtx->objectTypeOrName=yyextra->currentCtx->format.mid(1);
4020 DBG_CTX((stderr,"new type=%s\n",qPrint(yyextra->currentCtx->objectTypeOrName)));
4021 }
4022 yyextra->contextStack.push(yyextra->currentCtx);
4023 }
4024 else
4025 {
4026 DBG_CTX((stderr,"Trying to save NULL context!\n"));
4027 }
4028 auto newCtx = std::make_unique<ObjCCallCtx>();
4029 newCtx->id = yyextra->currentCtxId;
4030 newCtx->lexState = YY_START;
4031 newCtx->braceCount = yyextra->braceCount;
4032 newCtx->objectType = nullptr;
4033 newCtx->objectVar = nullptr;
4034 newCtx->method = nullptr;
4035 DBG_CTX((stderr,"save state=%d\n",YY_START));
4036 yyextra->currentCtx = newCtx.get();
4037 yyextra->contextMap.emplace(yyextra->currentCtxId,std::move(newCtx));
4038 yyextra->braceCount = 0;
4039 yyextra->currentCtxId++;
4040}

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

◆ setCallContextForVar()

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

Definition at line 2692 of file code.l.

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

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()

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

Definition at line 2316 of file code.l.

2317{
2318 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2319 DBG_CTX((stderr,"setClassScope(%s)\n",qPrint(name)));
2320 QCString n=name;
2321 n=n.simplifyWhiteSpace();
2322 int ts=n.find('<'); // start of template
2323 int te=n.findRev('>'); // end of template
2324 DBG_CTX((stderr,"ts=%d te=%d\n",ts,te));
2325 if (ts!=-1 && te!=-1 && te>ts)
2326 {
2327 // remove template from scope
2328 n=n.left(ts)+n.right(n.length()-te-1);
2329 }
2330 while (!yyextra->scopeNameLengthStack.empty())
2331 {
2332 popScope(yyscanner);
2333 }
2334 yyextra->scopeName.clear();
2335 int i;
2336 while ((i=n.find("::"))!=-1)
2337 {
2338 pushScope(yyscanner,n.left(i));
2339 n = n.mid(i+2);
2340 }
2341 pushScope(yyscanner,n);
2342 DBG_CTX((stderr,"--->New class scope '%s'\n",qPrint(yyextra->scopeName)));
static void pushScope(yyscan_t yyscanner, const QCString &s)
Definition code.l:2252
static void popScope(yyscan_t yyscanner)
Definition code.l:2270
2343}

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

◆ setCurrentDoc()

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

Definition at line 2286 of file code.l.

2287{
2288 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2289 if (Doxygen::searchIndex.enabled())
2290 {
2291 if (yyextra->searchCtx)
2292 {
2293 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
2294 }
2295 else
2296 {
2297 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,TRUE);
2298 }
2299 }
2300}

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()

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

Definition at line 2644 of file code.l.

2645{
2646 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2647 for (const Argument &a : md->argumentList())
2648 {
2649 yyextra->parmName = a.name;
2650 yyextra->parmType = a.type;
2651 int i = yyextra->parmType.find('*');
2652 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2653 i = yyextra->parmType.find('&');
2654 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2655 yyextra->parmType.stripPrefix("const ");
2656 yyextra->parmType=yyextra->parmType.stripWhiteSpace();
2657 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
2658 }
virtual const ArgumentList & argumentList() const =0
This class contains the information about the argument of a function or template.
Definition arguments.h:27
2659}

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

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3945 of file code.l.

3946{
3947 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3948 static const std::unordered_set<std::string> non_cpp_keywords = {
3949 "__assume", "__super", "abstract", "function",
3950 "gcnew", "gcroot", "generic", "get",
3951 "internal", "null", "pin_ptr", "raise",
3952 "remove", "self", "set", "transient",
3953 "sealed"
3954 };
3955 static const std::unordered_set<std::string> non_java_keywords = {
3956 "alignas", "alignof", "and", "and_eq", "asm",
3957 "atomic_cancel", "atomic_commit", "atomic_noexcept", "auto", "bitand",
3958 "bitor", "bool", "char8_t", "char16_t", "char32_t",
3959 "compl", "concept", "consteval", "constexpr", "constinit",
3960 "const_cast", "co_await", "co_return", "co_yield", "decltype",
3961 "delete", "dynamic_cast", "explicit", "export", "extern",
3962 "friend", "inline", "mutable", "namespace", "noexcept",
3963 "not", "not_eq", "nullptr", "operator", "or",
3964 "or_eq", "reflexpr", "register", "reinterpret_cast", "requires",
3965 "signed", "sizeof", "static_assert", "_Static_assert", "static_cast", "struct",
3966 "template", "thread_local", "typedef", "typeid", "typename",
3967 "union", "unsigned", "using", "virtual", "wchar_t",
3968 "xor", "xor_eq", "override", "sealed"
3969 };
3970 bool retval = false;
3971 switch (yyextra->lang)
3972 {
3973 case SrcLangExt::Cpp:
3974 retval = (non_cpp_keywords.find(keyword) != non_cpp_keywords.end());
3975 break;
3976 case SrcLangExt::Java:
3977 retval = (non_java_keywords.find(keyword) != non_java_keywords.end());
3978 break;
3979 default:
3980 retval = false;
3981 break;
3982 }
3983 return retval;
3984}

◆ startCodeLine()

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 2424 of file code.l.

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

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()

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

Definition at line 3519 of file code.l.

3520{
3521 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3522 endFontClass(yyscanner);
3523 if (specialComment)
3524 {
3525 yyextra->code->startSpecialComment();
3526 yyextra->insideSpecialComment = true;
3527 }
3528 yyextra->code->startFontClass(QCString(s));
3529 yyextra->currentFontClass=s;
3530}

References endFontClass().

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

◆ startsWithKeyword()

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

Definition at line 2180 of file code.l.

2181{
2182 if (str.length()<kw.length()) return false; // string too short to match
2183 return str==kw || // exact match
2184 (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:578
bool isId(int c)
Definition util.h:208
2185}

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

◆ stateToString()

const char * stateToString ( int state)
static

References FALSE.

Referenced by scanner_abort().

◆ stripClassName()

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

Definition at line 2661 of file code.l.

2662{
2663 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2664 DBG_CTX((stderr,"stripClassName(scope=%s,type=%s) scopeName=%s\n",
2665 qPrint(d?d->name():""),qPrint(s),qPrint(yyextra->scopeName)));
2666 int pos=0;
2667 QCString type = s;
2668 QCString className;
2669 QCString templSpec;
2670 while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
2671 {
2672 QCString clName=className+templSpec;
2673 const ClassDef *cd=nullptr;
2674 if (!yyextra->scopeName.isEmpty())
2675 {
2676 cd=yyextra->symbolResolver.resolveClass(d,yyextra->scopeName+"::"+clName,true);
2677 }
2678 if (cd==nullptr)
2679 {
2680 cd=yyextra->symbolResolver.resolveClass(d,clName,true);
2681 }
2682 DBG_CTX((stderr,"stripClass trying '%s' = %p\n",qPrint(clName),(void*)cd));
2683 if (cd)
2684 {
2685 return cd;
2686 }
2687 }
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4725
2688
2689 return nullptr;
2690}

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

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

◆ updateCallContextForSmartPointer()

void updateCallContextForSmartPointer ( yyscan_t yyscanner)
static

Definition at line 2802 of file code.l.

2803{
2804 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2805 const Definition *d = yyextra->theCallContext.getScope().globalDef();
2806 //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? qPrint(d->name()) : "<none>");
2807 const MemberDef *md = nullptr;
2808 if (d && d->definitionType()==Definition::TypeClass && (md=(toClassDef(d))->isSmartPointer()))
2809 {
2810 const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope());
2811 if (ncd)
2812 {
2813 yyextra->theCallContext.setScope(ScopedTypeVariant(ncd));
2814 //printf("Found smart pointer call %s->%s!\n",qPrint(cd->name()),qPrint(ncd->name()));
2815 }
2816 }
2817}

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

◆ writeMultiLineCodeLink()

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 2571 of file code.l.

2574{
2575 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2576 bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
2577 yyextra->tooltipManager.addTooltip(d);
2578 QCString ref = d->getReference();
2579 QCString file = d->getOutputFileBase();
2580 QCString anchor = d->anchor();
2581 QCString tooltip;
2582 if (!sourceTooltips) // fall back to simple "title" tooltips
2583 {
2584 tooltip = d->briefDescriptionAsTooltip();
2585 }
2586 bool done=FALSE;
2587 const char *p=text.data();
2588 while (!done)
2589 {
2590 const char *sp=p;
2591 char c = 0;
2592 while ((c=*p++) && c!='\n') { }
2593 if (c=='\n')
2594 {
2595 yyextra->yyLineNr++;
2596 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),qPrint(QCString(sp,p-sp-1))));
2597 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip);
2598 nextCodeLine(yyscanner);
2599 }
2600 else
2601 {
2602 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),sp));
2603 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp),tooltip);
2604 done=TRUE;
2605 }
2606 }
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
2607}

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()

void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3535 of file code.l.

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

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(), writeMultiLineCodeLink(), and writeObjCMethodCall().

Referenced by writeObjCMethodCall().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 383 of file code.l.

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

◆ yyread()

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

Definition at line 3995 of file code.l.

3996{
3997 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3998 yy_size_t inputPosition = yyextra->inputPosition;
3999 const char *s = yyextra->inputString + inputPosition;
4000 int c=0;
4001 while( c < max_size && *s )
4002 {
4003 *buf++ = *s++;
4004 c++;
4005 }
4006 yyextra->inputPosition += c;
4007 return c;
4008}