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 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 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 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 int countLines (yyscan_t yyscanner)
static void writeObjCMethodCall (yyscan_t yyscanner, ObjCCallCtx *ctx)
static QCString escapeName (yyscan_t yyscanner, const QCString &s)
static QCString escapeObject (yyscan_t yyscanner, const QCString &s)
static QCString escapeWord (yyscan_t yyscanner, const QCString &s)
static QCString escapeComment (yyscan_t yyscanner, const QCString &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:3963

Definition at line 260 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 2600 of file code.l.

2601{
2602 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2603 if (yyextra->parmName=="const") { yyextra->parmName.clear(); return; }
2604 if (!yyextra->parmType.isEmpty()) yyextra->parmType += ' ' ;
2605 yyextra->parmType += yyextra->parmName ;
2606 yyextra->parmName.clear() ;
2607}

◆ addToSearchIndex()

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

◆ addType()

void addType ( yyscan_t yyscanner)
static

Definition at line 2588 of file code.l.

2589{
2590 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2591 if (yyextra->name=="const") { yyextra->name.clear(); return; }
2592 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2593 yyextra->type += yyextra->name ;
2594 yyextra->name.clear() ;
2595 if (!yyextra->type.isEmpty()) yyextra->type += ' ' ;
2596 yyextra->type += yyextra->args ;
2597 yyextra->args.clear() ;
2598}

◆ addUsingDirective()

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

Definition at line 2609 of file code.l.

2610{
2611 //printf("AddUsingDirective(%s)\n",qPrint(name));
2612 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2613 if (yyextra->sourceFileDef && !name.isEmpty())
2614 {
2615 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name);
2616 if (nd)
2617 {
2618 yyextra->theUsingContext.emplace(name.str(),nd);
2619 }
2620 }
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:163
const std::string & str() const
Definition qcstring.h:552
2621}

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

◆ addVariable()

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

Definition at line 2178 of file code.l.

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

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

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

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

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

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

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

Referenced by 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 3454 of file code.l.

3455{
3456 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3457 const char *p=yyextra->inputString;
3458 char c = 0;
3459 int count=1;
3460 while ((c=*p))
3461 {
3462 p++ ;
3463 if (c=='\n') count++;
3464 }
3465 if (p>yyextra->inputString && *(p-1)!='\n')
3466 { // last line does not end with a \n, so we add an extra
3467 count++;
3468 }
3469 return count;
3470}

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

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

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2478 of file code.l.

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

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

3473{
3474 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3475 if (yyextra->currentFontClass)
3476 {
3477 yyextra->code->endFontClass();
3478 yyextra->currentFontClass=nullptr;
3479 }
3480 if (specialComment && yyextra->insideSpecialComment)
3481 {
3482 yyextra->code->endSpecialComment();
3483 yyextra->insideSpecialComment = false;
3484 }
3485}

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 QCString & s )
static

Definition at line 3903 of file code.l.

3904{
3905 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3906 QCString result;
3907 result.sprintf("$d%d",yyextra->currentCommentId);
3908 yyextra->commentMap.emplace(yyextra->currentCommentId,s);
3909 yyextra->currentCommentId++;
3910 return result;
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
3911}

References QCString::sprintf().

◆ escapeName()

QCString escapeName ( yyscan_t yyscanner,
const QCString & s )
static

Definition at line 3873 of file code.l.

3874{
3875 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3876 QCString result;
3877 result.sprintf("$n%d",yyextra->currentNameId);
3878 yyextra->nameMap.emplace(yyextra->currentNameId,s);
3879 yyextra->currentNameId++;
3880 return result;
3881}

References QCString::sprintf().

◆ escapeObject()

QCString escapeObject ( yyscan_t yyscanner,
const QCString & s )
static

Definition at line 3883 of file code.l.

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

References QCString::sprintf().

◆ escapeWord()

QCString escapeWord ( yyscan_t yyscanner,
const QCString & s )
static

Definition at line 3893 of file code.l.

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

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3195 of file code.l.

3199{
3200 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3201 if (def && def->definitionType()==Definition::TypeClass)
3202 {
3203 const ClassDef *cd = toClassDef(def);
3204 const MemberDef *xmd = cd->getMemberByName(memName);
3205 DBG_CTX((stderr,"generateClassMemberLink(class=%s,member=%s)=%p\n",qPrint(def->name()),qPrint(memName),(void*)xmd));
3206 if (xmd)
3207 {
3208 return generateClassMemberLink(yyscanner,ol,xmd,memName);
3209 }
3210 else
3211 {
3212 const Definition *innerDef = cd->findInnerCompound(memName);
3213 if (innerDef)
3214 {
3215 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3216 addToSearchIndex(yyscanner,memName);
3217 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3218 return TRUE;
3219 }
3220 }
3221 }
3222 else if (def && def->definitionType()==Definition::TypeNamespace)
3223 {
3224 const NamespaceDef *nd = toNamespaceDef(def);
3225 DBG_CTX((stderr,"Looking for %s inside namespace %s\n",qPrint(memName),qPrint(nd->name())));
3226 const Definition *innerDef = nd->findInnerCompound(memName);
3227 if (innerDef)
3228 {
3229 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3230 addToSearchIndex(yyscanner,memName);
3231 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3232 return TRUE;
3233 }
3234 }
3235 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:2550
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition code.l:2293
static bool generateClassMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const QCString &memName)
Definition code.l:3133
NamespaceDef * toNamespaceDef(Definition *d)
3236}

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

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

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

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

Definition at line 2907 of file code.l.

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

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(), generateFunctionLink(), generateFunctionLink(), and writeWord().

◆ generateFunctionLink()

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

Definition at line 3344 of file code.l.

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

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

◆ generateMemberLink()

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

Definition at line 3238 of file code.l.

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

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

3333{
3334 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3335 QCString name(varName+7); // strip $this->
3336 name.prepend("$");
3337 DBG_CTX((stderr,"generatePHPVariableLink(%s) name=%s scope=%s\n",varName,qPrint(name),qPrint(yyextra->scopeName)));
3338 if (!getLink(yyscanner,yyextra->scopeName,name,ol,varName))
3339 {
3340 codifyLines(yyscanner,varName);
3341 }
3342}

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

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 263 of file code.l.

263{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 2882 of file code.l.

2888{
2889 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2890 DBG_CTX((stderr,"getLink(%s,%s) yyextra->curClassName=%s\n",
2891 qPrint(className),qPrint(memberName),qPrint(yyextra->curClassName)));
2892 QCString m=removeRedundantWhiteSpace(memberName);
2893 QCString c=className;
2894 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2895 {
2896 if (!yyextra->curClassName.isEmpty())
2897 {
2898 if (!c.isEmpty()) c.prepend("::");
2899 c.prepend(yyextra->curClassName);
2900 return getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly);
2901 }
2902 return FALSE;
2903 }
2904 return TRUE;
QCString & prepend(const char *s)
Definition qcstring.h:422
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:2798
2905}

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

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

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

2533{
2534 std::lock_guard<std::mutex> lock(Doxygen::countFlowKeywordsMutex);
2535 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2536 if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction())
2537 {
2538 MemberDefMutable *md = toMemberDefMutable(const_cast<MemberDef*>(yyextra->currentMemberDef));
2539 if (md)
2540 {
2542 }
2543 }
static std::mutex countFlowKeywordsMutex
Definition doxygen.h:141
virtual void incrementFlowKeyWordCount()=0
2544}

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

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3954 of file code.l.

3955{
3956 QCString s(keyword);
3957 int i=s.find('<');
3958 if (i==-1) return FALSE;
3959 QCString kw = s.left(i).stripWhiteSpace();
3960 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3961}

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

◆ nextCodeLine()

void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2487 of file code.l.

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

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

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

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

2244{
2245 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2246 yyextra->scopeNameLengthStack.push_back(int(yyextra->scopeName.length()));
2247 if (yyextra->scopeName.isEmpty() || leftScopeMatch(s,yyextra->scopeName))
2248 {
2249 yyextra->scopeName = s;
2250 }
2251 else
2252 {
2253 yyextra->scopeName += "::";
2254 yyextra->scopeName += s;
2255 }
2256 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
2257}

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

Referenced by setClassScope().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4010 of file code.l.

4011{
4012 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4013 DBG_CTX((stderr,"restore state=%d->%d\n",YY_START,yyextra->currentCtx->lexState));
4014 BEGIN(yyextra->currentCtx->lexState);
4015 yyextra->braceCount = yyextra->currentCtx->braceCount;
4016 if (!yyextra->contextStack.empty())
4017 {
4018 yyextra->currentCtx = yyextra->contextStack.top();
4019 yyextra->contextStack.pop();
4020 }
4021 else
4022 {
4023 yyextra->currentCtx = nullptr;
4024 DBG_CTX((stderr,"Trying to pop context while yyextra->contextStack is empty!\n"));
4025 }
4026}

References DBG_CTX.

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 3979 of file code.l.

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

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

◆ setCallContextForVar()

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

Definition at line 2671 of file code.l.

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

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

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

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

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

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

2624{
2625 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2626 for (const Argument &a : md->argumentList())
2627 {
2628 yyextra->parmName = a.name;
2629 yyextra->parmType = a.type;
2630 int i = yyextra->parmType.find('*');
2631 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2632 i = yyextra->parmType.find('&');
2633 if (i!=-1) yyextra->parmType = yyextra->parmType.left(i);
2634 yyextra->parmType.stripPrefix("const ");
2635 yyextra->parmType=yyextra->parmType.stripWhiteSpace();
2636 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
2637 }
virtual const ArgumentList & argumentList() const =0
This class contains the information about the argument of a function or template.
Definition arguments.h:27
2638}

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

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3913 of file code.l.

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

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

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

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

3488{
3489 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3490 endFontClass(yyscanner);
3491 if (specialComment)
3492 {
3493 yyextra->code->startSpecialComment();
3494 yyextra->insideSpecialComment = true;
3495 }
3496 yyextra->code->startFontClass(s);
3497 yyextra->currentFontClass=s;
3498}

References endFontClass().

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

◆ startsWithKeyword()

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

Definition at line 2171 of file code.l.

2172{
2173 if (str.length()<kw.length()) return false; // string too short to match
2174 return str==kw || // exact match
2175 (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:593
bool isId(int c)
Definition util.h:208
2176}

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

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

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

2782{
2783 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2784 const Definition *d = yyextra->theCallContext.getScope().globalDef();
2785 //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? qPrint(d->name()) : "<none>");
2786 const MemberDef *md = nullptr;
2787 if (d && d->definitionType()==Definition::TypeClass && (md=(toClassDef(d))->isSmartPointer()))
2788 {
2789 const ClassDef *ncd = stripClassName(yyscanner,md->typeString(),md->getOuterScope());
2790 if (ncd)
2791 {
2792 yyextra->theCallContext.setScope(ScopedTypeVariant(ncd));
2793 //printf("Found smart pointer call %s->%s!\n",qPrint(cd->name()),qPrint(ncd->name()));
2794 }
2795 }
2796}

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

2553{
2554 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2555 bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
2556 yyextra->tooltipManager.addTooltip(d);
2557 QCString ref = d->getReference();
2558 QCString file = d->getOutputFileBase();
2559 QCString anchor = d->anchor();
2560 QCString tooltip;
2561 if (!sourceTooltips) // fall back to simple "title" tooltips
2562 {
2563 tooltip = d->briefDescriptionAsTooltip();
2564 }
2565 bool done=FALSE;
2566 const char *p=text.data();
2567 while (!done)
2568 {
2569 const char *sp=p;
2570 char c = 0;
2571 while ((c=*p++) && c!='\n') { }
2572 if (c=='\n')
2573 {
2574 yyextra->yyLineNr++;
2575 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),qPrint(QCString(sp,p-sp-1))));
2576 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip);
2577 nextCodeLine(yyscanner);
2578 }
2579 else
2580 {
2581 DBG_CTX((stderr,"writeCodeLink(%s,%s,%s,%s)\n",qPrint(ref),qPrint(file),qPrint(anchor),sp));
2582 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,sp,tooltip);
2583 done=TRUE;
2584 }
2585 }
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
2586}

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

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

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

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

◆ yyread()

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

Definition at line 3963 of file code.l.

3964{
3965 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3966 yy_size_t inputPosition = yyextra->inputPosition;
3967 const char *s = yyextra->inputString + inputPosition;
3968 int c=0;
3969 while( c < max_size && *s )
3970 {
3971 *buf++ = *s++;
3972 c++;
3973 }
3974 yyextra->inputPosition += c;
3975 return c;
3976}