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.

◆ 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:3982

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

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

◆ addToSearchIndex()

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

Definition at line 2304 of file code.l.

2305{
2306 if (Doxygen::searchIndex.enabled())
2307 {
2308 Doxygen::searchIndex.addWord(text,FALSE);
2309 }
static SearchIndexIntf searchIndex
Definition doxygen.h:123
#define FALSE
Definition qcstring.h:34
2310}

References FALSE, and Doxygen::searchIndex.

Referenced by generateClassMemberLink(), generateClassMemberLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFuncLink(), generateMemberLink(), getLink(), getLinkInScope(), and getLinkInScope().

◆ addType()

void addType ( yyscan_t yyscanner)
static

Definition at line 2599 of file code.l.

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

◆ addUsingDirective()

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

Definition at line 2620 of file code.l.

2621{
2622 //printf("AddUsingDirective(%s)\n",qPrint(name));
2623 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2624 if (yyextra->sourceFileDef && !name.isEmpty())
2625 {
2626 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name);
2627 if (nd)
2628 {
2629 yyextra->theUsingContext.emplace(name.str(),nd);
2630 }
2631 }
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:114
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
2632}

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

◆ addVariable()

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

Definition at line 2189 of file code.l.

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

References qPrint().

Referenced by setParameterList().

◆ codeFolding()

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

Definition at line 2362 of file code.l.

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

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

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

References FALSE, and qPrint().

Referenced by codifyMapLines(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateMemberLink(), and generateMemLink().

◆ countLines()

int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3473 of file code.l.

3474{
3475 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3476 const char *p=yyextra->inputString;
3477 char c = 0;
3478 int count=1;
3479 while ((c=*p))
3480 {
3481 p++ ;
3482 if (c=='\n') count++;
3483 }
3484 if (p>yyextra->inputString && *(p-1)!='\n')
3485 { // last line does not end with a \n, so we add an extra
3486 count++;
3487 }
3488 return count;
3489}

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

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

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2489 of file code.l.

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

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

3492{
3493 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3494 if (yyextra->currentFontClass)
3495 {
3496 yyextra->code->endFontClass();
3497 yyextra->currentFontClass=nullptr;
3498 }
3499 if (specialComment && yyextra->insideSpecialComment)
3500 {
3501 yyextra->code->endSpecialComment();
3502 yyextra->insideSpecialComment = false;
3503 }
3504}

Referenced by checkVhdlString().

◆ escapeComment()

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

Definition at line 3922 of file code.l.

3923{
3924 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3925 QCString result;
3926 result.sprintf("$d%d",yyextra->currentCommentId);
3927 yyextra->commentMap.emplace(yyextra->currentCommentId,s);
3928 yyextra->currentCommentId++;
3929 return result;
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
3930}

◆ escapeName()

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

Definition at line 3892 of file code.l.

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

◆ escapeObject()

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

Definition at line 3902 of file code.l.

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

◆ escapeWord()

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

Definition at line 3912 of file code.l.

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

◆ generateClassMemberLink() [1/2]

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

Definition at line 3206 of file code.l.

3210{
3211 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3212 if (def && def->definitionType()==Definition::TypeClass)
3213 {
3214 const ClassDef *cd = toClassDef(def);
3215 const MemberDef *xmd = cd->getMemberByName(memName);
3216 DBG_CTX((stderr,"generateClassMemberLink(class=%s,member=%s)=%p\n",qPrint(def->name()),qPrint(memName),(void*)xmd));
3217 if (xmd)
3218 {
3219 return generateClassMemberLink(yyscanner,ol,xmd,memName);
3220 }
3221 else
3222 {
3223 const Definition *innerDef = cd->findInnerCompound(memName);
3224 if (innerDef)
3225 {
3226 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3227 addToSearchIndex(yyscanner,memName);
3228 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3229 return TRUE;
3230 }
3231 }
3232 }
3233 else if (def && def->definitionType()==Definition::TypeNamespace)
3234 {
3235 const NamespaceDef *nd = toNamespaceDef(def);
3236 DBG_CTX((stderr,"Looking for %s inside namespace %s\n",qPrint(memName),qPrint(nd->name())));
3237 const Definition *innerDef = nd->findInnerCompound(memName);
3238 if (innerDef)
3239 {
3240 yyextra->theCallContext.setScope(ScopedTypeVariant(innerDef));
3241 addToSearchIndex(yyscanner,memName);
3242 writeMultiLineCodeLink(yyscanner,*yyextra->code,innerDef,memName);
3243 return TRUE;
3244 }
3245 }
3246 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:2561
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition code.l:2304
static bool generateClassMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const QCString &memName)
Definition code.l:3144
NamespaceDef * toNamespaceDef(Definition *d)
3247}

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

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

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

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

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

◆ generateFunctionLink()

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

Definition at line 3355 of file code.l.

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

References generateClassMemberLink().

◆ generateMemberLink()

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

Definition at line 3249 of file code.l.

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

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

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

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

2899{
2900 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2901 DBG_CTX((stderr,"getLink(%s,%s) yyextra->curClassName=%s\n",
2902 qPrint(className),qPrint(memberName),qPrint(yyextra->curClassName)));
2903 QCString m=removeRedundantWhiteSpace(memberName);
2904 QCString c=className;
2905 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2906 {
2907 if (!yyextra->curClassName.isEmpty())
2908 {
2909 if (!c.isEmpty()) c.prepend("::");
2910 c.prepend(yyextra->curClassName);
2911 return getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly);
2912 }
2913 return FALSE;
2914 }
2915 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:2809
2916}

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

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

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

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

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

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

References Doxygen::countFlowKeywordsMutex.

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3973 of file code.l.

3974{
3975 QCString s(keyword);
3976 int i=s.find('<');
3977 if (i==-1) return FALSE;
3978 QCString kw = s.left(i).stripWhiteSpace();
3979 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3980}

References FALSE.

◆ nextCodeLine()

void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2498 of file code.l.

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

References endCodeLine().

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

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

◆ pushScope()

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

add class/namespace name s to the scope

Definition at line 2254 of file code.l.

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

References leftScopeMatch().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4029 of file code.l.

4030{
4031 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
4032 DBG_CTX((stderr,"restore state=%d->%d\n",YY_START,yyextra->currentCtx->lexState));
4033 BEGIN(yyextra->currentCtx->lexState);
4034 yyextra->braceCount = yyextra->currentCtx->braceCount;
4035 if (!yyextra->contextStack.empty())
4036 {
4037 yyextra->currentCtx = yyextra->contextStack.top();
4038 yyextra->contextStack.pop();
4039 }
4040 else
4041 {
4042 yyextra->currentCtx = nullptr;
4043 DBG_CTX((stderr,"Trying to pop context while yyextra->contextStack is empty!\n"));
4044 }
4045}

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 3998 of file code.l.

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

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

◆ setCallContextForVar()

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

Definition at line 2682 of file code.l.

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

Referenced by generateClassOrGlobalLink().

◆ setClassScope()

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

Definition at line 2312 of file code.l.

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

◆ setCurrentDoc()

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

Definition at line 2288 of file code.l.

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

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

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

References addVariable().

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3932 of file code.l.

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

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

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

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

3507{
3508 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3509 endFontClass(yyscanner);
3510 if (specialComment)
3511 {
3512 yyextra->code->startSpecialComment();
3513 yyextra->insideSpecialComment = true;
3514 }
3515 yyextra->code->startFontClass(s);
3516 yyextra->currentFontClass=s;
3517}

Referenced by checkVhdlString().

◆ startsWithKeyword()

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

Definition at line 2182 of file code.l.

2183{
2184 if (str.length()<kw.length()) return false; // string too short to match
2185 return str==kw || // exact match
2186 (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:207
2187}

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

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

References qPrint().

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

◆ updateCallContextForSmartPointer()

void updateCallContextForSmartPointer ( yyscan_t yyscanner)
static

Definition at line 2792 of file code.l.

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

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

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

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(), getLink(), getLinkInScope(), and getLinkInScope().

◆ writeObjCMethodCall()

void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3522 of file code.l.

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

References QCString::at(), DBG_CTX, ObjCCallCtx::format, ClassDef::getMemberByName(), ScopedTypeVariant::globalDef(), QCString::isEmpty(), ObjCCallCtx::method, ObjCCallCtx::methodName, ObjCCallCtx::objectTypeOrName, qPrint(), and toClassDef().

◆ 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:104
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:3581
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2871
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:2599
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:3355
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:2620
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:3932
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:2543
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:3343
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:3973
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:2182
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:6934
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:6942
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:2792
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:3998
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:4029
1519<ObjCCall,ObjCMName>{CPPC}.* {
1520 yyextra->currentCtx->format+=escapeComment(yyscanner,yytext);
1521 }
static QCString escapeComment(yyscan_t yyscanner, const QCString &s)
Definition code.l:3922
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:3902
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:3912
static QCString escapeName(yyscan_t yyscanner, const QCString &s)
Definition code.l:3892
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:2611
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>"=>" { // C# Expression Body
1784 if (yyextra->lang!=SrcLangExt::CSharp || yyextra->insideBody)
1785 {
1786 REJECT;
1787 }
1788 else
1789 {
1790 yyextra->code->codify("=>");
1791 BEGIN( Body );
1792 }
1793 }
1794<CallEnd>{ENDQopt}/{BN}*(";"|"="|"throw"{BN}*"(") {
1795 startFontClass(yyscanner,"keyword");
1796 codifyLines(yyscanner,yytext);
1797 endFontClass(yyscanner);
1798 }
1799<CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
1800 if (yyextra->insideBody)
1801 {
1802 yyextra->theVarContext.pushScope();
1803 }
1804 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1805 //yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
1806 yyextra->parmType.clear();yyextra->parmName.clear();
1807 int index = yyextra->name.findRev("::");
1808 DBG_CTX((stderr,"yyextra->name=%s\n",qPrint(yyextra->name)));
1809 if (index!=-1)
1810 {
1811 QCString scope = yyextra->name.left((uint32_t)index);
1812 if (!yyextra->scopeName.isEmpty()) scope.prepend((yyextra->scopeName+"::"));
1813 const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope,true);
1814 if (cd)
1815 {
1816 setClassScope(yyscanner,cd->name());
1817 yyextra->scopeStack.push(SCOPEBLOCK);
1818 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1819 }
1820 else
1821 {
1822 //setClassScope(yyscanner,yyextra->realScope);
1823 yyextra->scopeStack.push(INNERBLOCK);
1824 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1825 }
1826 }
1827 else
1828 {
1829 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1830 yyextra->scopeStack.push(INNERBLOCK);
1831 }
1832 yytext[yyleng-1]='\0';
1833 QCString cv(yytext);
1834 if (!cv.stripWhiteSpace().isEmpty())
1835 {
1836 startFontClass(yyscanner,"keyword");
1837 codifyLines(yyscanner,yytext);
1838 endFontClass(yyscanner);
1839 }
1840 else // just whitespace
1841 {
1842 codifyLines(yyscanner,yytext);
1843 }
1844 yyextra->code->codify("{");
1845 if (yyextra->searchingForBody)
1846 {
1847 yyextra->searchingForBody=FALSE;
1848 yyextra->insideBody=TRUE;
1849 }
1850 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1851 yyextra->type.clear(); yyextra->name.clear();
1852 BEGIN( Body );
1853 }
static void setClassScope(yyscan_t yyscanner, const QCString &name)
Definition code.l:2312
1854<CallEnd>"try" { // function-try-block
1855 startFontClass(yyscanner,"keyword");
1856 yyextra->code->codify(yytext);
1857 endFontClass(yyscanner);
1858 yyextra->inFunctionTryBlock=TRUE;
1859 }
1860<CallEnd>"requires" { // function-try-block
1861 startFontClass(yyscanner,"keyword");
1862 yyextra->code->codify(yytext);
1863 endFontClass(yyscanner);
1864 }
1865<CallEnd>{ID} {
1866 if (yyextra->insideBody || !yyextra->parmType.isEmpty())
1867 {
1868 REJECT;
1869 }
1870 // could be K&R style definition
1871 addParmType(yyscanner);
1872 yyextra->parmName=yytext;
1873 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1874 BEGIN(OldStyleArgs);
1875 }
1876<OldStyleArgs>{ID} {
1877 addParmType(yyscanner);
1878 yyextra->parmName=yytext;
1879 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1880 }
1881<OldStyleArgs>[,;] {
1882 yyextra->code->codify(yytext);
1883 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1884 if (*yytext==';') yyextra->parmType.clear();
1885 yyextra->parmName.clear();
1886 }
1887<CallEnd,OldStyleArgs>"#" {
1888 startFontClass(yyscanner,"preprocessor");
1889 yyextra->lastSkipCppContext = Body;
1890 yyextra->code->codify(yytext);
1891 BEGIN( SkipCPP );
1892 }
1893<CallEnd>. {
1894 unput(*yytext);
1895 if (!yyextra->insideBody)
1896 {
1897 yyextra->theVarContext.popScope();
1898 }
1899 yyextra->name.clear();yyextra->args.clear();
1900 yyextra->parmType.clear();yyextra->parmName.clear();
1901 BEGIN( Body );
1902 }
1903<SkipInits>";" {
1904 yyextra->code->codify(yytext);
1905 yyextra->type.clear(); yyextra->name.clear();
1906 BEGIN( Body );
1907 }
1908<SkipInits>"{" {
1909 yyextra->code->codify(yytext);
1910 if (yyextra->searchingForBody)
1911 {
1912 yyextra->searchingForBody=FALSE;
1913 yyextra->insideBody=TRUE;
1914 }
1915 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1916 if (yyextra->name.find("::")!=-1)
1917 {
1918 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1919 yyextra->scopeStack.push(SCOPEBLOCK);
1920 setClassScope(yyscanner,yyextra->realScope);
1921 }
1922 else
1923 {
1924 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1925 yyextra->scopeStack.push(INNERBLOCK);
1926 }
1927 yyextra->type.clear(); yyextra->name.clear();
1928 BEGIN( Body );
1929 }
1930<SkipInits>{ID}{B}*"{" {
1931 QCString text(yytext);
1932 int bracketPos = text.find('{');
1933 int spacePos = text.find(' ');
1934 int len = spacePos==-1 ? bracketPos : spacePos;
1935 generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len));
1936 yyextra->code->codify(yytext+len);
1937 }
1938<SkipInits>{ID} {
1939 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1940 }
1941<FuncCall>{ID}/"(" {
1942 generateFunctionLink(yyscanner,*yyextra->code,yytext);
1943 }
1944<FuncCall>{ID}/("."|"->") {
1945 yyextra->name=yytext;
1946 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1947 BEGIN( MemberCall2 );
1948 }
1949<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") {
1950 yyextra->code->codify(yytext);
1951 uint32_t s=0;while (!isId(yytext[s])) s++;
1952 uint32_t e=(uint32_t)yyleng-1;while (e>1 && !isId(yytext[e])) e--;
1953 yyextra->name=((QCString)yytext).mid(s,e-s+1);
1954 BEGIN( MemberCall2 );
1955 }
1956<MemberCall2>{ID}/([ \t\n]*"(") {
1957 if (!yyextra->args.isEmpty())
1958 generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext);
1959 else
1960 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1961 yyextra->args.clear();
1962 BEGIN( FuncCall );
1963 }
static void generateMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &varName, const QCString &memName)
Definition code.l:3249
1964<MemberCall2>{ID}/([ \t\n]*("."|"->")) {
1965 //yyextra->code->codify(yytext);
1966 yyextra->name=yytext;
1967 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1968 BEGIN( MemberCall2 );
1969 }
1970<MemberCall2>"->"|"." {
1971 if (yytext[0]=='-') // -> could be overloaded
1972 {
1974 }
1975 yyextra->code->codify(yytext);
1976 yyextra->memCallContext = YY_START;
1977 BEGIN( MemberCall );
1978 }
1979<SkipComment>{CCS}("!"?){CCE} {
1980 yyextra->code->codify(yytext);
1981 endFontClass(yyscanner,true);
1982 BEGIN( yyextra->lastCContext ) ;
1983 }
1984<SkipComment>{CPPC}|{CCS} {
1985 yyextra->code->codify(yytext);
1986 }
1987<SkipComment>[^*\/\n]+ {
1988 yyextra->code->codify(yytext);
1989 }
1990<SkipComment>[ \t]*{CCE} {
1991 yyextra->code->codify(yytext);
1992 endFontClass(yyscanner,true);
1993 if (yyextra->lastCContext==SkipCPP)
1994 {
1995 startFontClass(yyscanner,"preprocessor");
1996 }
1997 BEGIN( yyextra->lastCContext ) ;
1998 }
1999<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation
2000 codifyLines(yyscanner,yytext);
2001 }
2002<SkipCxxComment>[^\r\n]+ {
2003 yyextra->code->codify(yytext);
2004 }
2005<SkipCxxComment>\r
2006<SkipCxxComment>\n {
2007 unput('\n');
2008 endFontClass(yyscanner);
2009 BEGIN( yyextra->lastCContext ) ;
2010 }
2011<SkipCxxComment>. {
2012 yyextra->code->codify(yytext);
2013 }
2014<MemberCall>[^a-z_A-Z0-9(\n] {
2015 yyextra->code->codify(yytext);
2016 yyextra->type.clear();
2017 yyextra->name.clear();
2018 BEGIN(yyextra->memCallContext);
2019 }
2020<*>\n({B}*{CPPC}[!/][^\n]*\n)+ { // remove special one-line comment
2021 if (YY_START==SkipCPP) REJECT;
2022 startFontClass(yyscanner,"comment",true);
2023 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2024 endFontClass(yyscanner,true);
2025 codifyLines(yyscanner,"\n");
2026 if (YY_START==SkipCxxComment)
2027 {
2028 BEGIN( yyextra->lastCContext ) ;
2029 }
2030 }
2031<SkipCPP>\n/(.|\n) {
2032 endFontClass(yyscanner);
2033 BEGIN( yyextra->lastSkipCppContext ) ;
2034 unput('\n');
2035 }
2036<*>\n{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2037 startFontClass(yyscanner,"comment",true);
2038 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2039 endFontClass(yyscanner,true);
2040 codifyLines(yyscanner,"\n");
2041 if (YY_START==SkipCxxComment)
2042 {
2043 BEGIN( yyextra->lastCContext ) ;
2044 }
2045 }
2046<*>\n{B}*{CCS}"@"[{}] { // remove one-line group marker
2047 // check is to prevent getting stuck in skipping C++ comments
2048 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2049 {
2050 yyextra->lastCContext = YY_START ;
2051 }
2052 startFontClass(yyscanner,"comment",true);
2053 codifyLines(yyscanner,yytext);
2054 BEGIN(SkipComment);
2055 }
2056<*>^{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2057 startFontClass(yyscanner,"comment",true);
2058 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2059 endFontClass(yyscanner,true);
2060 codifyLines(yyscanner,"\n");
2061 }
2062<*>^{B}*{CCS}"@"[{}] { // remove multi-line group marker
2063 // check is to prevent getting stuck in skipping C++ comments
2064 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2065 {
2066 yyextra->lastCContext = YY_START ;
2067 }
2068 startFontClass(yyscanner,"comment",true);
2069 yyextra->code->codify(yytext);
2070 BEGIN(SkipComment);
2071 }
2072<*>^{B}*{CPPC}[!/][^\n]* { // remove special one-line comment
2073 startFontClass(yyscanner,"comment",true);
2074 codifyLines(yyscanner,yytext);
2075 endFontClass(yyscanner,true);
2076 }
2077<*>{CPPC}[!/][^\n]* { // strip special one-line comment
2078 if (YY_START==SkipComment || YY_START==SkipString) REJECT;
2079 startFontClass(yyscanner,"comment",true);
2080 codifyLines(yyscanner,yytext);
2081 endFontClass(yyscanner,true);
2082 }
2083<*>\n{B}*{CCS}[!*]/{NCOMM} {
2084 // check is to prevent getting stuck in skipping C++ comments
2085 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2086 {
2087 yyextra->lastCContext = YY_START ;
2088 }
2089 startFontClass(yyscanner,"comment",true);
2090 codifyLines(yyscanner,yytext);
2091 BEGIN(SkipComment);
2092 }
2093<*>^{B}*{CCS}"*"[*]+/[^/] {
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 // special C "banner" comment block at a new line
2100 startFontClass(yyscanner,"comment",Config_getBool(JAVADOC_BANNER));
2101 yyextra->code->codify(yytext);
2102 BEGIN(SkipComment);
2103 }
2104<*>^{B}*{CCS}[!*]/{NCOMM} { // special C comment block at a new line
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}[!*]/{NCOMM} { // special C comment block half way a line
2115 if (YY_START==SkipString) REJECT;
2116 // check is to prevent getting stuck in skipping C++ comments
2117 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2118 {
2119 yyextra->lastCContext = YY_START ;
2120 }
2121 startFontClass(yyscanner,"comment",true);
2122 yyextra->code->codify(yytext);
2123 BEGIN(SkipComment);
2124 }
2125<*>{CCS}("!"?){CCE} {
2126 if (YY_START==SkipString) REJECT;
2127 bool specialComment = QCString(yytext).find('!')!=-1;
2128 startFontClass(yyscanner,"comment",specialComment);
2129 yyextra->code->codify(yytext);
2130 endFontClass(yyscanner,specialComment);
2131 }
2132<SkipComment>[^\*\n]+ {
2133 yyextra->code->codify(yytext);
2134 }
2135<*>{CCS} {
2136 startFontClass(yyscanner,"comment");
2137 yyextra->code->codify(yytext);
2138 // check is to prevent getting stuck in skipping C++ comments
2139 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2140 {
2141 yyextra->lastCContext = YY_START ;
2142 }
2143 BEGIN( SkipComment ) ;
2144 }
2145<*>[$]?@\" { // C# (interpolated) verbatim string
2146 startFontClass(yyscanner,"stringliteral");
2147 yyextra->code->codify(yytext);
2148 yyextra->lastVerbStringContext=YY_START;
2149 BEGIN(SkipVerbString);
2150 }
2151<*>{CPPC} {
2152 startFontClass(yyscanner,"comment");
2153 yyextra->code->codify(yytext);
2154 yyextra->lastCContext = YY_START ;
2155 BEGIN( SkipCxxComment ) ;
2156 }
2157<*>"("|"[" {
2158 if (yytext[0]=='(') yyextra->bracketCount++;
2159 yyextra->code->codify(yytext);
2160 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2161 }
2162<*>")"|"]" {
2163 if (yytext[0]==')') yyextra->bracketCount--;
2164 yyextra->code->codify(yytext);
2165 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2166 }
2167<*>\n {
2168 codifyLines(yyscanner,yytext);
2169 }
2170<*>[\x80-\xFF]* { // keep utf8 characters together...
2171 yyextra->code->codify(yytext);
2172 }
2173<*>. {
2174 yyextra->code->codify(yytext);
2175 }
2176
2177%%

◆ yyread()

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

Definition at line 3982 of file code.l.

3983{
3984 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3985 yy_size_t inputPosition = yyextra->inputPosition;
3986 const char *s = yyextra->inputString + inputPosition;
3987 int c=0;
3988 while( c < max_size && *s )
3989 {
3990 *buf++ = *s++;
3991 c++;
3992 }
3993 yyextra->inputPosition += c;
3994 return c;
3995}