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

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

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

◆ addToSearchIndex() [1/2]

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

Definition at line 2307 of file code.l.

2308{
2309 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:2299
2310}

References addToSearchIndex().

◆ addToSearchIndex() [2/2]

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

◆ addType()

void addType ( yyscan_t yyscanner)
static

Definition at line 2606 of file code.l.

2607{
2608 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2609 if (yyextra->name=="const") { yyextra->name.clear(); return; }
2610 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2611 yyextra->type += yyextra->name ;
2612 yyextra->name.clear() ;
2613 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2614 yyextra->type += yyextra->args ;
2615 yyextra->args.clear() ;
2616}

◆ addUsingDirective()

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

Definition at line 2627 of file code.l.

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

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

◆ addVariable()

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

Definition at line 2184 of file code.l.

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

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

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

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

2546{
2547 codifyLines(yyscanner,QCString(text));
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2517
2548}

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

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

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

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

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

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

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2490 of file code.l.

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

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

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

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

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

References QCString::sprintf().

◆ escapeName()

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

Definition at line 3902 of file code.l.

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

References QCString::sprintf().

◆ escapeObject()

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

Definition at line 3912 of file code.l.

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

References QCString::sprintf().

◆ escapeWord()

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

Definition at line 3922 of file code.l.

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

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3219 of file code.l.

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

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

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

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

3153{
3154 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:2925
3155}

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

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

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

3478{
3479 generateFunctionLink(yyscanner,ol,QCString(funcName));
static void generateFunctionLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
Definition code.l:3368
3480}

References generateFunctionLink().

◆ generateFunctionLink() [2/2]

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

Definition at line 3368 of file code.l.

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

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

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

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

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

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

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

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

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

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

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

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

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3983 of file code.l.

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

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

◆ nextCodeLine()

void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2499 of file code.l.

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

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

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

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

2250{
2251 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2252 yyextra->scopeNameLengthStack.push_back(int(yyextra->scopeName.length()));
2253 if (yyextra->scopeName.isEmpty() || leftScopeMatch(s,yyextra->scopeName))
2254 {
2255 yyextra->scopeName = s;
2256 }
2257 else
2258 {
2259 yyextra->scopeName += "::";
2260 yyextra->scopeName += s;
2261 }
2262 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
2263}

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

Referenced by setClassScope().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4039 of file code.l.

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

References DBG_CTX.

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 4008 of file code.l.

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

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

◆ setCallContextForVar()

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

Definition at line 2689 of file code.l.

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

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

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

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

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

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

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

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

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3942 of file code.l.

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

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

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

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

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

References endFontClass().

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

◆ startsWithKeyword()

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

Definition at line 2177 of file code.l.

2178{
2179 if (str.length()<kw.length()) return false; // string too short to match
2180 return str==kw || // exact match
2181 (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
2182}

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

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

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

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

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

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

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

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

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:4116
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:3417
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:2606
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:2627
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:3942
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:2550
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:3356
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:3983
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:2177
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 = extractBeginRawStringDelimiter(yytext);
1261 BEGIN( RawString );
1262 }
QCString extractBeginRawStringDelimiter(const char *rawStart)
Definition util.cpp:7451
1263<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit,ClassVar,OldStyleArgs>\" {
1264 startFontClass(yyscanner,"stringliteral");
1265 yyextra->code->codify(yytext);
1266 yyextra->lastStringContext=YY_START;
1267 yyextra->inForEachExpression = FALSE;
1268 BEGIN( SkipString );
1269 }
1270<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>{NUMBER} { //Note similar code in commentcnv.l
1271 if (yyextra->lang!=SrcLangExt::Cpp) REJECT;
1272 yyextra->code->codify(yytext);
1273 }
1274<FuncCall,Body,MemberCall,MemberCall2,SkipInits,InlineInit>\' {
1275 startFontClass(yyscanner,"stringliteral");
1276 yyextra->code->codify(yytext);
1277 yyextra->lastStringContext=YY_START;
1278 yyextra->inForEachExpression = FALSE;
1279 BEGIN( SkipStringS );
1280 }
1281<SkipString>[^\"\\\r\n]{1,100} {
1282 yyextra->code->codify(yytext);
1283 }
1284<SkipStringS>[^\'\\\r\n]{1,100} {
1285 yyextra->code->codify(yytext);
1286 }
1287<SkipString,SkipStringS>{CPPC}|{CCS} {
1288 yyextra->code->codify(yytext);
1289 }
1290<SkipString>@?\" {
1291 yyextra->code->codify(yytext);
1292 if (yyextra->lastStringContext!=SkipCPP)
1293 {
1294 endFontClass(yyscanner);
1295 }
1296 BEGIN( yyextra->lastStringContext );
1297 }
1298<SkipStringS>\' {
1299 yyextra->code->codify(yytext);
1300 endFontClass(yyscanner);
1301 BEGIN( yyextra->lastStringContext );
1302 }
1303<SkipString,SkipStringS>\\. {
1304 yyextra->code->codify(yytext);
1305 }
1306<RawString>{RAWEND} {
1307 yyextra->code->codify(yytext);
1308 if (extractEndRawStringDelimiter(yytext)==yyextra->delimiter)
1309 {
1310 BEGIN( yyextra->lastStringContext );
1311 }
1312 }
QCString extractEndRawStringDelimiter(const char *rawEnd)
Definition util.cpp:7459
1313<RawString>[^)\n]+ { yyextra->code->codify(yytext); }
1314<RawString>. { yyextra->code->codify(yytext); }
1315<RawString>\n { codifyLines(yyscanner,yytext); }
1316<SkipVerbString>[^"\n]+ {
1317 yyextra->code->codify(yytext);
1318 }
1319<SkipVerbString>\"\" { // escaped quote
1320 yyextra->code->codify(yytext);
1321 }
1322<SkipVerbString>\" { // end of string
1323 yyextra->code->codify(yytext);
1324 endFontClass(yyscanner);
1325 BEGIN( yyextra->lastVerbStringContext );
1326 }
1327<SkipVerbString>. {
1328 yyextra->code->codify(yytext);
1329 }
1330<SkipVerbString>\n {
1331 codifyLines(yyscanner,yytext);
1332 }
1333<Body>":" {
1334 yyextra->code->codify(yytext);
1335 yyextra->name.clear();yyextra->type.clear();
1336 }
1337<Body>"<" {
1338 if (yyextra->insideTemplate)
1339 {
1340 yyextra->sharpCount++;
1341 }
1342 yyextra->code->codify(yytext);
1343 }
1344<Body>">" {
1345 if (yyextra->insideTemplate)
1346 {
1347 if (--yyextra->sharpCount<=0)
1348 {
1349 yyextra->insideTemplate=FALSE;
1350 }
1351 }
1352 yyextra->code->codify(yytext);
1353 }
1354<Body,MemberCall,MemberCall2,FuncCall,OldStyleArgs>"'"((\\0[Xx0-9]+)|(\\.)|(.))"'" {
1355 startFontClass(yyscanner,"charliteral");
1356 yyextra->code->codify(yytext);
1357 endFontClass(yyscanner);
1358 }
1359<Body>"."|"->" {
1360 if (yytext[0]=='-') // -> could be overloaded
1361 {
1363 }
1364 yyextra->code->codify(yytext);
1365 yyextra->memCallContext = YY_START;
1366 BEGIN( MemberCall );
1367 }
static void updateCallContextForSmartPointer(yyscan_t yyscanner)
Definition code.l:2799
1368<MemberCall>{SCOPETNAME}/{BN}*"(" {
1369 if (yyextra->theCallContext.getScope().globalDef())
1370 {
1371 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1372 {
1373 codifyLines(yyscanner,yytext);
1374 addToSearchIndex(yyscanner,yytext);
1375 }
1376 yyextra->name.clear();
1377 }
1378 else
1379 {
1380 codifyLines(yyscanner,yytext);
1381 addToSearchIndex(yyscanner,yytext);
1382 yyextra->name.clear();
1383 }
1384 yyextra->type.clear();
1385 if (yyextra->memCallContext==Body)
1386 {
1387 BEGIN(FuncCall);
1388 }
1389 else
1390 {
1391 BEGIN(yyextra->memCallContext);
1392 }
1393 }
1394<MemberCall>{SCOPENAME}/{B}* {
1395 if (yyextra->theCallContext.getScope().globalDef())
1396 {
1397 DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",(void*)yyextra->theCallContext.getScope().globalDef()));
1398 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1399 {
1400 codifyLines(yyscanner,yytext);
1401 addToSearchIndex(yyscanner,yytext);
1402 }
1403 yyextra->name.clear();
1404 }
1405 else
1406 {
1407 DBG_CTX((stderr,"no class context!\n"));
1408 codifyLines(yyscanner,yytext);
1409 addToSearchIndex(yyscanner,yytext);
1410 yyextra->name.clear();
1411 }
1412 yyextra->type.clear();
1413 BEGIN(yyextra->memCallContext);
1414 }
1415<Body>[,=;\[{] {
1416 if (yyextra->insideObjC && *yytext=='[')
1417 {
1418 DBG_CTX((stderr,"Found start of ObjC call!\n"));
1419 // start of a method call
1420 yyextra->contextMap.clear();
1421 yyextra->nameMap.clear();
1422 yyextra->objectMap.clear();
1423 yyextra->wordMap.clear();
1424 yyextra->commentMap.clear();
1425 yyextra->currentCtxId = 0;
1426 yyextra->currentNameId = 0;
1427 yyextra->currentObjId = 0;
1428 yyextra->currentCtx = nullptr;
1429 yyextra->braceCount = 0;
1430 unput('[');
1431 BEGIN(ObjCCall);
1432 }
1433 else
1434 {
1435 if (*yytext!='{') yyextra->code->codify(yytext);
1436 yyextra->saveName = yyextra->name;
1437 yyextra->saveType = yyextra->type;
1438 if (*yytext!='[' && !yyextra->type.isEmpty())
1439 {
1440 //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom());
1441 //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363
1442 {
1443 //printf("AddVariable: '%s' '%s' context=%d\n",
1444 // qPrint(yyextra->type),qPrint(yyextra->name),yyextra->theVarContext.count());
1445 addVariable(yyscanner,yyextra->type,yyextra->name);
1446 }
1447 yyextra->name.clear();
1448 }
1449 if (*yytext==';' || *yytext=='=' || *yytext=='{')
1450 {
1451 yyextra->type.clear();
1452 yyextra->name.clear();
1453 }
1454 else if (*yytext=='[')
1455 {
1456 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1457 }
1458 yyextra->args.clear();
1459 yyextra->parmType.clear();
1460 yyextra->parmName.clear();
1461 if (*yytext=='{')
1462 {
1463 BEGIN( BodyVar );
1464 unput('{');
1465 }
1466 }
1467 }
1468<Body,FuncCall,BodyVar>"{" {
1469 yyextra->theVarContext.pushScope();
1470 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1471 yyextra->bracketCount = 0;
1472
1473 DBG_CTX((stderr,"** type='%s' name='%s'\n",qPrint(yyextra->type),qPrint(yyextra->name)));
1474 if (yyextra->type.find("enum ")!=-1)
1475 { // for strong enums we need to start a scope
1476 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1477 pushScope(yyscanner,yyextra->name);
1478 yyextra->scopeStack.push(SCOPEBLOCK);
1479 }
1480 else
1481 {
1482 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1483 yyextra->scopeStack.push(INNERBLOCK);
1484 }
1485
1486 if (yyextra->searchingForBody)
1487 {
1488 yyextra->searchingForBody=FALSE;
1489 yyextra->insideBody=TRUE;
1490 }
1491 yyextra->code->codify(yytext);
1492 if (yyextra->insideBody)
1493 {
1494 yyextra->bodyCurlyCount++;
1495 }
1496 yyextra->type.clear();
1497 yyextra->name.clear();
1498 BEGIN( Body );
1499 }
1500<ObjCCall,ObjCMName>"["|"{" {
1501 saveObjCContext(yyscanner);
1502 yyextra->currentCtx->format+=*yytext;
1503 BEGIN(ObjCCall);
1504 DBG_CTX((stderr,"open\n"));
1505 }
static void saveObjCContext(yyscan_t yyscanner)
Definition code.l:4008
1506<ObjCCall,ObjCMName>"]"|"}" {
1507 yyextra->currentCtx->format+=*yytext;
1508 restoreObjCContext(yyscanner);
1509 BEGIN(ObjCMName);
1510 if (yyextra->currentCtx==nullptr)
1511 {
1512 // end of call
1513 ObjCCallCtx *ctx = nullptr;
1514 auto it = yyextra->contextMap.find(0);
1515 if (it!=yyextra->contextMap.end())
1516 {
1517 ctx = it->second.get();
1518 }
1519 writeObjCMethodCall(yyscanner,ctx);
1520 BEGIN(Body);
1521 }
1522 DBG_CTX((stderr,"close\n"));
1523 }
static void restoreObjCContext(yyscan_t yyscanner)
Definition code.l:4039
1524<ObjCCall,ObjCMName>{CPPC}.* {
1525 yyextra->currentCtx->format+=escapeComment(yyscanner,yytext);
1526 }
static QCString escapeComment(yyscan_t yyscanner, const char *s)
Definition code.l:3932
1527<ObjCCall,ObjCMName>{CCS} {
1528 yyextra->lastObjCCallContext = YY_START;
1529 yyextra->currentCtx->comment.str(yytext);
1530 BEGIN(ObjCCallComment);
1531 }
1532<ObjCCallComment>{CCE} {
1533 yyextra->currentCtx->comment << yytext;
1534 std::string commentStr = yyextra->currentCtx->comment.str();
1535 yyextra->currentCtx->format+=escapeComment(yyscanner,commentStr.c_str());
1536 BEGIN(yyextra->lastObjCCallContext);
1537 }
1538<ObjCCallComment>[^*\n]+ { yyextra->currentCtx->comment << yytext; }
1539<ObjCCallComment>{CPPC}|{CCS} { yyextra->currentCtx->comment << yytext; }
1540<ObjCCallComment>\n { yyextra->currentCtx->comment << *yytext; }
1541<ObjCCallComment>. { yyextra->currentCtx->comment << *yytext; }
1542<ObjCCall>{ID}({B}*"."{B}*{ID})* {
1543 yyextra->currentCtx->format+=escapeObject(yyscanner,QCString(yytext).data());
1544 if (yyextra->braceCount==0)
1545 {
1546 yyextra->currentCtx->objectTypeOrName=yytext;
1547 DBG_CTX((stderr,"new type=%s\n",qPrint(yyextra->currentCtx->objectTypeOrName)));
1548 BEGIN(ObjCMName);
1549 }
1550 }
static QCString escapeObject(yyscan_t yyscanner, const char *s)
Definition code.l:3912
1551<ObjCMName>{ID}/{BN}*"]" {
1552 if (yyextra->braceCount==0 &&
1553 yyextra->currentCtx->methodName.isEmpty())
1554 {
1555 yyextra->currentCtx->methodName=yytext;
1556 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1557 }
1558 else
1559 {
1560 yyextra->currentCtx->format+=escapeWord(yyscanner,yytext);
1561 }
1562 }
static QCString escapeName(yyscan_t yyscanner, const char *s)
Definition code.l:3902
static QCString escapeWord(yyscan_t yyscanner, const char *s)
Definition code.l:3922
1563<ObjCMName>{ID}/{BN}*":" {
1564 if (yyextra->braceCount==0)
1565 {
1566 yyextra->currentCtx->methodName+=yytext;
1567 yyextra->currentCtx->methodName+=":";
1568 }
1569 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1570 }
1571<ObjCSkipStr>[^\n\"$\\]* { yyextra->currentCtx->format+=yytext; }
1572<ObjCSkipStr>\\. { yyextra->currentCtx->format+=yytext; }
1573<ObjCSkipStr>"\"" { yyextra->currentCtx->format+=yytext;
1574 BEGIN(yyextra->lastStringContext);
1575 }
1576<ObjCCall,ObjCMName>{CHARLIT} { yyextra->currentCtx->format+=yytext; }
1577<ObjCCall,ObjCMName>"@"?"\"" { yyextra->currentCtx->format+=yytext;
1578 yyextra->lastStringContext=YY_START;
1579 BEGIN(ObjCSkipStr);
1580 }
1581<ObjCCall,ObjCMName,ObjCSkipStr>"$" { yyextra->currentCtx->format+="$$"; }
1582<ObjCCall,ObjCMName>"(" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount++; }
1583<ObjCCall,ObjCMName>")" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount--; }
1584<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#)
1585 yyextra->currentCtx->format+=yytext;
1586 }
1587<ObjCCall,ObjCMName,ObjCSkipStr>{ID} { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); }
1588<ObjCCall,ObjCMName,ObjCSkipStr>. { yyextra->currentCtx->format+=*yytext; }
1589<ObjCCall,ObjCMName,ObjCSkipStr>\n { yyextra->currentCtx->format+=*yytext; }
1590
1591<Body>"]" {
1592 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1593 yyextra->code->codify(yytext);
1594 // TODO: nested arrays like: a[b[0]->func()]->func()
1595 yyextra->name = yyextra->saveName;
1596 yyextra->type = yyextra->saveType;
1597 }
1598<Body>[0-9]+ {
1599 yyextra->code->codify(yytext);
1600 }
1601<Body>[0-9]+[xX][0-9A-Fa-f]+ {
1602 yyextra->code->codify(yytext);
1603 }
1604<MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
1605 //addParmType(yyscanner);
1606 //yyextra->parmName=yytext;
1607 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
1608 startFontClass(yyscanner,"keyword");
1609 yyextra->code->codify(yytext);
1610 endFontClass(yyscanner);
1611 }
1612<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) {
1613 addParmType(yyscanner);
1614 yyextra->parmName=yytext;
1615 startFontClass(yyscanner,"keywordtype");
1616 yyextra->code->codify(yytext);
1617 endFontClass(yyscanner);
1618 }
static void addParmType(yyscan_t yyscanner)
Definition code.l:2618
1619<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKWSL}/([^a-z_A-Z0-9]) {
1620 if (yyextra->lang!=SrcLangExt::Slice)
1621 {
1622 REJECT;
1623 }
1624 else
1625 {
1626 addParmType(yyscanner);
1627 yyextra->parmName=yytext;
1628 startFontClass(yyscanner,"keywordtype");
1629 yyextra->code->codify(yytext);
1630 endFontClass(yyscanner);
1631 }
1632 }
1633<MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) {
1634 addParmType(yyscanner);
1635 yyextra->parmName=yytext;
1636 startFontClass(yyscanner,"keywordflow");
1637 yyextra->code->codify(yytext);
1638 endFontClass(yyscanner);
1639 }
1640<MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) {
1641 incrementFlowKeyWordCount(yyscanner);
1642 addParmType(yyscanner);
1643 yyextra->parmName=yytext;
1644 startFontClass(yyscanner,"keywordflow");
1645 yyextra->code->codify(yytext);
1646 endFontClass(yyscanner);
1647 }
1648<MemberCall2,FuncCall>("::")?{ID}(({B}*"<"[^\n\[\](){}<>']*">")?({B}*"::"{B}*{ID})?)* {
1649 if (isCastKeyword(yytext))
1650 {
1651 REJECT;
1652 }
1653 addParmType(yyscanner);
1654 yyextra->parmName=yytext;
1655 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1656 }
1657<FuncCall>";" { // probably a cast, not a function call
1658 yyextra->code->codify(yytext);
1659 yyextra->inForEachExpression = FALSE;
1660 BEGIN( Body );
1661 }
1662<MemberCall2,FuncCall>, {
1663 yyextra->code->codify(yytext);
1664 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1665 yyextra->parmType.clear();yyextra->parmName.clear();
1666 }
1667<MemberCall2,FuncCall>"{" {
1668 if (yyextra->bracketCount>0)
1669 {
1670 yyextra->code->codify(yytext);
1671 yyextra->skipInlineInitContext=YY_START;
1672 yyextra->curlyCount=0;
1673 BEGIN(InlineInit);
1674 }
1675 else
1676 {
1677 REJECT;
1678 }
1679 }
1680<InlineInit>"{" { yyextra->curlyCount++;
1681 yyextra->code->codify(yytext);
1682 }
1683<InlineInit>"}" {
1684 yyextra->code->codify(yytext);
1685 if (--yyextra->curlyCount<=0)
1686 {
1687 BEGIN(yyextra->skipInlineInitContext);
1688 }
1689 }
1690<InlineInit>\n {
1691 codifyLines(yyscanner,yytext);
1692 }
1693<InlineInit>. {
1694 yyextra->code->codify(yytext);
1695 }
1696<MemberCall2,FuncCall>"(" {
1697 yyextra->parmType.clear();yyextra->parmName.clear();
1698 yyextra->code->codify(yytext);
1699 yyextra->bracketCount++;
1700 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1701 if (YY_START==FuncCall && !yyextra->insideBody)
1702 {
1703 yyextra->theVarContext.pushScope();
1704 }
1705 }
1706<MemberCall2,FuncCall>{OPERATOR} { // operator
1707 if (qstrcmp(yytext,"*") &&
1708 qstrcmp(yytext,"&") &&
1709 qstrcmp(yytext,"^") &&
1710 qstrcmp(yytext,"%")) // typically a pointer or reference
1711 {
1712 // not a * or &, or C++/CLI's ^ or %
1713 yyextra->parmType.clear();yyextra->parmName.clear();
1714 }
1715 yyextra->code->codify(yytext);
1716 }
1717<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" {
1718 if (yytext[0]==')') // no a pointer cast
1719 {
1720 DBG_CTX((stderr,"addVariable(%s,%s)\n",qPrint(yyextra->parmType),qPrint(yyextra->parmName)));
1721 if (yyextra->parmType.isEmpty())
1722 {
1723 yyextra->parmType=yyextra->parmName;
1724 yyextra->parmName.clear();
1725 }
1726 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1727 }
1728 else
1729 {
1730 yyextra->parmType = yyextra->parmName;
1731 yyextra->parmName.clear();
1732 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1733 }
1734 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1735 yyextra->inForEachExpression = FALSE;
1736 //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b().
1737 yyextra->code->codify(yytext);
1738 if (--yyextra->bracketCount<=0)
1739 {
1740 if (yyextra->name.isEmpty())
1741 {
1742 BEGIN( Body );
1743 }
1744 else
1745 {
1746 BEGIN( CallEnd );
1747 }
1748 }
1749 }
1750<MemberCall,MemberCall2,FuncCall>[;:] { // recover from unexpected end of call
1751 //if (yytext[0]==';' || yyextra->bracketCount<=0)
1752 if (yyextra->bracketCount<=0)
1753 {
1754 unput(*yytext);
1755 BEGIN(CallEnd);
1756 }
1757 else
1758 {
1759 yyextra->code->codify(yytext);
1760 }
1761 }
1762<CallEnd>[ \t\n]* { codifyLines(yyscanner,yytext); }
1763<CallEnd>[;:] {
1764 codifyLines(yyscanner,yytext);
1765 yyextra->bracketCount=0;
1766 if (*yytext==';') yyextra->searchingForBody=FALSE;
1767 if (!yyextra->type.isEmpty())
1768 {
1769 DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",qPrint(yyextra->type),qPrint(yyextra->name)));
1770 addVariable(yyscanner,yyextra->type,yyextra->name);
1771 }
1772 yyextra->parmType.clear();yyextra->parmName.clear();
1773 yyextra->theCallContext.setScope(ScopedTypeVariant());
1774 if (*yytext==';' || yyextra->insideBody)
1775 {
1776 if (!yyextra->insideBody)
1777 {
1778 yyextra->theVarContext.popScope();
1779 }
1780 yyextra->name.clear();yyextra->type.clear();
1781 BEGIN( Body );
1782 }
1783 else
1784 {
1785 yyextra->bracketCount=0;
1786 BEGIN( SkipInits );
1787 }
1788 }
1789<CallEnd>{ENDQopt}/{BN}*(";"|"="|"throw"{BN}*"(") {
1790 startFontClass(yyscanner,"keyword");
1791 codifyLines(yyscanner,yytext);
1792 endFontClass(yyscanner);
1793 }
1794<CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
1795 if (yyextra->insideBody)
1796 {
1797 yyextra->theVarContext.pushScope();
1798 }
1799 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1800 //yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
1801 yyextra->parmType.clear();yyextra->parmName.clear();
1802 int index = yyextra->name.findRev("::");
1803 DBG_CTX((stderr,"yyextra->name=%s\n",qPrint(yyextra->name)));
1804 if (index!=-1)
1805 {
1806 QCString scope = yyextra->name.left((uint32_t)index);
1807 if (!yyextra->scopeName.isEmpty()) scope.prepend((yyextra->scopeName+"::"));
1808 const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope,true);
1809 if (cd)
1810 {
1811 setClassScope(yyscanner,cd->name());
1812 yyextra->scopeStack.push(SCOPEBLOCK);
1813 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1814 }
1815 else
1816 {
1817 //setClassScope(yyscanner,yyextra->realScope);
1818 yyextra->scopeStack.push(INNERBLOCK);
1819 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1820 }
1821 }
1822 else
1823 {
1824 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1825 yyextra->scopeStack.push(INNERBLOCK);
1826 }
1827 yytext[yyleng-1]='\0';
1828 QCString cv(yytext);
1829 if (!cv.stripWhiteSpace().isEmpty())
1830 {
1831 startFontClass(yyscanner,"keyword");
1832 codifyLines(yyscanner,yytext);
1833 endFontClass(yyscanner);
1834 }
1835 else // just whitespace
1836 {
1837 codifyLines(yyscanner,yytext);
1838 }
1839 yyextra->code->codify("{");
1840 if (yyextra->searchingForBody)
1841 {
1842 yyextra->searchingForBody=FALSE;
1843 yyextra->insideBody=TRUE;
1844 }
1845 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1846 yyextra->type.clear(); yyextra->name.clear();
1847 BEGIN( Body );
1848 }
static void setClassScope(yyscan_t yyscanner, const QCString &name)
Definition code.l:2313
1849<CallEnd>"try" { // function-try-block
1850 startFontClass(yyscanner,"keyword");
1851 yyextra->code->codify(yytext);
1852 endFontClass(yyscanner);
1853 yyextra->inFunctionTryBlock=TRUE;
1854 }
1855<CallEnd>"requires" { // function-try-block
1856 startFontClass(yyscanner,"keyword");
1857 yyextra->code->codify(yytext);
1858 endFontClass(yyscanner);
1859 }
1860<CallEnd>{ID} {
1861 if (yyextra->insideBody || !yyextra->parmType.isEmpty())
1862 {
1863 REJECT;
1864 }
1865 // could be K&R style definition
1866 addParmType(yyscanner);
1867 yyextra->parmName=yytext;
1868 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1869 BEGIN(OldStyleArgs);
1870 }
1871<OldStyleArgs>{ID} {
1872 addParmType(yyscanner);
1873 yyextra->parmName=yytext;
1874 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1875 }
1876<OldStyleArgs>[,;] {
1877 yyextra->code->codify(yytext);
1878 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1879 if (*yytext==';') yyextra->parmType.clear();
1880 yyextra->parmName.clear();
1881 }
1882<CallEnd,OldStyleArgs>"#" {
1883 startFontClass(yyscanner,"preprocessor");
1884 yyextra->lastSkipCppContext = Body;
1885 yyextra->code->codify(yytext);
1886 BEGIN( SkipCPP );
1887 }
1888<CallEnd>. {
1889 unput(*yytext);
1890 if (!yyextra->insideBody)
1891 {
1892 yyextra->theVarContext.popScope();
1893 }
1894 yyextra->name.clear();yyextra->args.clear();
1895 yyextra->parmType.clear();yyextra->parmName.clear();
1896 BEGIN( Body );
1897 }
1898<SkipInits>";" {
1899 yyextra->code->codify(yytext);
1900 yyextra->type.clear(); yyextra->name.clear();
1901 BEGIN( Body );
1902 }
1903<SkipInits>"{" {
1904 yyextra->code->codify(yytext);
1905 if (yyextra->searchingForBody)
1906 {
1907 yyextra->searchingForBody=FALSE;
1908 yyextra->insideBody=TRUE;
1909 }
1910 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1911 if (yyextra->name.find("::")!=-1)
1912 {
1913 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1914 yyextra->scopeStack.push(SCOPEBLOCK);
1915 setClassScope(yyscanner,yyextra->realScope);
1916 }
1917 else
1918 {
1919 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1920 yyextra->scopeStack.push(INNERBLOCK);
1921 }
1922 yyextra->type.clear(); yyextra->name.clear();
1923 BEGIN( Body );
1924 }
1925<SkipInits>{ID}{B}*"{" {
1926 QCString text(yytext);
1927 int bracketPos = text.find('{');
1928 int spacePos = text.find(' ');
1929 int len = spacePos==-1 ? bracketPos : spacePos;
1930 generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len));
1931 yyextra->code->codify(QCString(yytext+len));
1932 }
1933<SkipInits>{ID} {
1934 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1935 }
1936<FuncCall>{ID}/"(" {
1937 generateFunctionLink(yyscanner,*yyextra->code,yytext);
1938 }
1939<FuncCall>{ID}/("."|"->") {
1940 yyextra->name=yytext;
1941 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1942 BEGIN( MemberCall2 );
1943 }
1944<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") {
1945 yyextra->code->codify(yytext);
1946 uint32_t s=0;while (!isId(yytext[s])) s++;
1947 uint32_t e=(uint32_t)yyleng-1;while (e>1 && !isId(yytext[e])) e--;
1948 yyextra->name=((QCString)yytext).mid(s,e-s+1);
1949 BEGIN( MemberCall2 );
1950 }
1951<MemberCall2>{ID}/([ \t\n]*"(") {
1952 if (!yyextra->args.isEmpty())
1953 generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext);
1954 else
1955 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1956 yyextra->args.clear();
1957 BEGIN( FuncCall );
1958 }
static void generateMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &varName, const QCString &memName)
Definition code.l:3262
1959<MemberCall2>{ID}/([ \t\n]*("."|"->")) {
1960 //yyextra->code->codify(yytext);
1961 yyextra->name=yytext;
1962 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1963 BEGIN( MemberCall2 );
1964 }
1965<MemberCall2>"->"|"." {
1966 if (yytext[0]=='-') // -> could be overloaded
1967 {
1969 }
1970 yyextra->code->codify(yytext);
1971 yyextra->memCallContext = YY_START;
1972 BEGIN( MemberCall );
1973 }
1974<SkipComment>{CCS}("!"?){CCE} {
1975 yyextra->code->codify(yytext);
1976 endFontClass(yyscanner,true);
1977 BEGIN( yyextra->lastCContext ) ;
1978 }
1979<SkipComment>{CPPC}|{CCS} {
1980 yyextra->code->codify(yytext);
1981 }
1982<SkipComment>[^*\/\n]+ {
1983 yyextra->code->codify(yytext);
1984 }
1985<SkipComment>[ \t]*{CCE} {
1986 yyextra->code->codify(yytext);
1987 endFontClass(yyscanner,true);
1988 if (yyextra->lastCContext==SkipCPP)
1989 {
1990 startFontClass(yyscanner,"preprocessor");
1991 }
1992 BEGIN( yyextra->lastCContext ) ;
1993 }
1994<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation
1995 codifyLines(yyscanner,yytext);
1996 }
1997<SkipCxxComment>[^\r\n]+ {
1998 yyextra->code->codify(yytext);
1999 }
2000<SkipCxxComment>\r
2001<SkipCxxComment>\n {
2002 unput('\n');
2003 endFontClass(yyscanner);
2004 BEGIN( yyextra->lastCContext ) ;
2005 }
2006<SkipCxxComment>. {
2007 yyextra->code->codify(yytext);
2008 }
2009<MemberCall>[^a-z_A-Z0-9(\n] {
2010 yyextra->code->codify(yytext);
2011 yyextra->type.clear();
2012 yyextra->name.clear();
2013 BEGIN(yyextra->memCallContext);
2014 }
2015<*>\n({B}*{CPPC}[!/][^\n]*\n)+ { // remove special one-line comment
2016 if (YY_START==SkipCPP) REJECT;
2017 startFontClass(yyscanner,"comment",true);
2018 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2019 endFontClass(yyscanner,true);
2020 codifyLines(yyscanner,"\n");
2021 if (YY_START==SkipCxxComment)
2022 {
2023 BEGIN( yyextra->lastCContext ) ;
2024 }
2025 }
2026<SkipCPP>\n/(.|\n) {
2027 endFontClass(yyscanner);
2028 BEGIN( yyextra->lastSkipCppContext ) ;
2029 unput('\n');
2030 }
2031<*>\n{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2032 startFontClass(yyscanner,"comment",true);
2033 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2034 endFontClass(yyscanner,true);
2035 codifyLines(yyscanner,"\n");
2036 if (YY_START==SkipCxxComment)
2037 {
2038 BEGIN( yyextra->lastCContext ) ;
2039 }
2040 }
2041<*>\n{B}*{CCS}"@"[{}] { // remove one-line group marker
2042 // check is to prevent getting stuck in skipping C++ comments
2043 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2044 {
2045 yyextra->lastCContext = YY_START ;
2046 }
2047 startFontClass(yyscanner,"comment",true);
2048 codifyLines(yyscanner,yytext);
2049 BEGIN(SkipComment);
2050 }
2051<*>^{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2052 startFontClass(yyscanner,"comment",true);
2053 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2054 endFontClass(yyscanner,true);
2055 codifyLines(yyscanner,"\n");
2056 }
2057<*>^{B}*{CCS}"@"[{}] { // remove multi-line group marker
2058 // check is to prevent getting stuck in skipping C++ comments
2059 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2060 {
2061 yyextra->lastCContext = YY_START ;
2062 }
2063 startFontClass(yyscanner,"comment",true);
2064 yyextra->code->codify(yytext);
2065 BEGIN(SkipComment);
2066 }
2067<*>^{B}*{CPPC}[!/][^\n]* { // remove special one-line comment
2068 startFontClass(yyscanner,"comment",true);
2069 codifyLines(yyscanner,yytext);
2070 endFontClass(yyscanner,true);
2071 }
2072<*>{CPPC}[!/][^\n]* { // strip special one-line comment
2073 if (YY_START==SkipComment || YY_START==SkipString) REJECT;
2074 startFontClass(yyscanner,"comment",true);
2075 codifyLines(yyscanner,yytext);
2076 endFontClass(yyscanner,true);
2077 }
2078<*>\n{B}*{CCS}[!*]/{NCOMM} {
2079 // check is to prevent getting stuck in skipping C++ comments
2080 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2081 {
2082 yyextra->lastCContext = YY_START ;
2083 }
2084 startFontClass(yyscanner,"comment",true);
2085 codifyLines(yyscanner,yytext);
2086 BEGIN(SkipComment);
2087 }
2088<*>^{B}*{CCS}"*"[*]+/[^/] {
2089 // check is to prevent getting stuck in skipping C++ comments
2090 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2091 {
2092 yyextra->lastCContext = YY_START ;
2093 }
2094 // special C "banner" comment block at a new line
2095 startFontClass(yyscanner,"comment",Config_getBool(JAVADOC_BANNER));
2096 yyextra->code->codify(yytext);
2097 BEGIN(SkipComment);
2098 }
2099<*>^{B}*{CCS}[!*]/{NCOMM} { // special C comment block at a new line
2100 // check is to prevent getting stuck in skipping C++ comments
2101 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2102 {
2103 yyextra->lastCContext = YY_START ;
2104 }
2105 startFontClass(yyscanner,"comment",true);
2106 yyextra->code->codify(yytext);
2107 BEGIN(SkipComment);
2108 }
2109<*>{CCS}[!*]/{NCOMM} { // special C comment block half way a line
2110 if (YY_START==SkipString) REJECT;
2111 // check is to prevent getting stuck in skipping C++ comments
2112 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2113 {
2114 yyextra->lastCContext = YY_START ;
2115 }
2116 startFontClass(yyscanner,"comment",true);
2117 yyextra->code->codify(yytext);
2118 BEGIN(SkipComment);
2119 }
2120<*>{CCS}("!"?){CCE} {
2121 if (YY_START==SkipString) REJECT;
2122 bool specialComment = QCString(yytext).find('!')!=-1;
2123 startFontClass(yyscanner,"comment",specialComment);
2124 yyextra->code->codify(yytext);
2125 endFontClass(yyscanner,specialComment);
2126 }
2127<SkipComment>[^\*\n]+ {
2128 yyextra->code->codify(yytext);
2129 }
2130<*>{CCS} {
2131 startFontClass(yyscanner,"comment");
2132 yyextra->code->codify(yytext);
2133 // check is to prevent getting stuck in skipping C++ comments
2134 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2135 {
2136 yyextra->lastCContext = YY_START ;
2137 }
2138 BEGIN( SkipComment ) ;
2139 }
2140<*>[$]?@\" { // C# (interpolated) verbatim string
2141 startFontClass(yyscanner,"stringliteral");
2142 yyextra->code->codify(yytext);
2143 yyextra->lastVerbStringContext=YY_START;
2144 BEGIN(SkipVerbString);
2145 }
2146<*>{CPPC} {
2147 startFontClass(yyscanner,"comment");
2148 yyextra->code->codify(yytext);
2149 yyextra->lastCContext = YY_START ;
2150 BEGIN( SkipCxxComment ) ;
2151 }
2152<*>"("|"[" {
2153 if (yytext[0]=='(') yyextra->bracketCount++;
2154 yyextra->code->codify(yytext);
2155 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2156 }
2157<*>")"|"]" {
2158 if (yytext[0]==')') yyextra->bracketCount--;
2159 yyextra->code->codify(yytext);
2160 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2161 }
2162<*>\n {
2163 codifyLines(yyscanner,yytext);
2164 }
2165<*>[\x80-\xFF]* { // keep utf8 characters together...
2166 yyextra->code->codify(yytext);
2167 }
2168<*>. {
2169 yyextra->code->codify(yytext);
2170 }
2171
2172%%

◆ yyread()

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

Definition at line 3992 of file code.l.

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