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

Go to the source code of this file.

Classes

struct  ObjCCallCtx
struct  codeYY_state
struct  CCodeParser::Private

Macros

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

Typedefs

typedef yyguts_t * yyscan_t

Functions

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

Macro Definition Documentation

◆ CLASSBLOCK

#define CLASSBLOCK   1

Definition at line 77 of file code.l.

Referenced by setCallContextForVar().

◆ DBG_CTX

◆ INNERBLOCK

#define INNERBLOCK   3

Definition at line 79 of file code.l.

◆ SCOPEBLOCK

#define SCOPEBLOCK   2

Definition at line 78 of file code.l.

◆ YY_INPUT

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

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

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

◆ addToSearchIndex()

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

Definition at line 2305 of file code.l.

2306{
2307 if (Doxygen::searchIndex.enabled())
2308 {
2309 Doxygen::searchIndex.addWord(text,false);
2310 }
static SearchIndexIntf searchIndex
Definition doxygen.h:124
void addWord(const QCString &word, bool hiPriority)
2311}

References SearchIndexIntf::addWord(), and Doxygen::searchIndex.

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

◆ addType()

void addType ( yyscan_t yyscanner)
static

Definition at line 2600 of file code.l.

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

◆ addUsingDirective()

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

Definition at line 2621 of file code.l.

2622{
2623 //printf("AddUsingDirective(%s)\n",qPrint(name));
2624 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2625 if (yyextra->sourceFileDef && !name.isEmpty())
2626 {
2628 if (nd)
2629 {
2630 yyextra->theUsingContext.emplace(name.str(),nd);
2631 }
2632 }
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
const T * find(const std::string &key) const
Definition linkedmap.h:47
An abstract interface of a namespace symbol.
bool isEmpty() const
Returns true iff the string is empty.
Definition qcstring.h:161
const std::string & str() const
Definition qcstring.h:550
2633}

References LinkedMap< T, Hash, KeyEqual, Map >::find(), QCString::isEmpty(), Doxygen::namespaceLinkedMap, and QCString::str().

◆ addVariable()

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

Definition at line 2190 of file code.l.

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

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

Referenced by addVariable(), and setParameterList().

◆ codeFolding()

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

Definition at line 2363 of file code.l.

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

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

Referenced by startCodeLine(), 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 2517 of file code.l.

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

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

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

◆ countLines()

int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3478 of file code.l.

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

Referenced by CCodeParser::parseCode().

◆ endCodeFold()

void endCodeFold ( yyscan_t yyscanner)
static

Definition at line 2342 of file code.l.

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

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2490 of file code.l.

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

References DBG_CTX, and endFontClass().

Referenced by nextCodeLine(), nextCodeLine(), and CCodeParser::parseCode().

◆ endFontClass()

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

Definition at line 3496 of file code.l.

3497{
3498 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3499 if (yyextra->currentFontClass)
3500 {
3501 yyextra->code->endFontClass();
3502 yyextra->currentFontClass=nullptr;
3503 }
3504 if (specialComment && yyextra->insideSpecialComment)
3505 {
3506 yyextra->code->endSpecialComment();
3507 yyextra->insideSpecialComment = false;
3508 }
3509}

Referenced by endCodeLine(), endCodeLine(), startFontClass(), startFontClass(), and writeObjCMethodCall().

◆ escapeComment()

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

Definition at line 3927 of file code.l.

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

References QCString::sprintf().

◆ escapeName()

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

Definition at line 3897 of file code.l.

3898{
3899 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3900 QCString result;
3901 result.sprintf("$n%d",yyextra->currentNameId);
3902 yyextra->nameMap.emplace(yyextra->currentNameId,s);
3903 yyextra->currentNameId++;
3904 return result;
3905}

References QCString::sprintf().

◆ escapeObject()

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

Definition at line 3907 of file code.l.

3908{
3909 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3910 QCString result;
3911 result.sprintf("$o%d",yyextra->currentObjId);
3912 yyextra->objectMap.emplace(yyextra->currentObjId,s);
3913 yyextra->currentObjId++;
3914 return result;
3915}

References QCString::sprintf().

◆ escapeWord()

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

Definition at line 3917 of file code.l.

3918{
3919 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3920 QCString result;
3921 result.sprintf("$w%d",yyextra->currentWordId);
3922 yyextra->wordMap.emplace(yyextra->currentWordId,s);
3923 yyextra->currentWordId++;
3924 return result;
3925}

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3211 of file code.l.

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

References addToSearchIndex(), DBG_CTX, Definition::definitionType(), Definition::findInnerCompound(), generateClassMemberLink(), ClassDef::getMemberByName(), Definition::name(), qPrint(), toClassDef(), toNamespaceDef(), 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 3149 of file code.l.

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

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), MemberDef::argsString(), DBG_CTX, MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), Definition::getOuterScope(), Doxygen::globalScope, Definition::isLinkable(), Definition::name(), qPrint(), removeAnonymousScopes(), QCString::sprintf(), stripClassName(), toMemberDefMutable(), 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 2919 of file code.l.

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

References addDocCrossReference(), ClassDefMutable::addExample(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), codifyLines(), DBG_CTX, Definition::definitionType(), 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(), Definition::TypeClass, Definition::TypeMember, OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by generateFunctionLink().

◆ generateFunctionLink()

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

Definition at line 3360 of file code.l.

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

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

◆ generateMemberLink()

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

Definition at line 3254 of file code.l.

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

References addToSearchIndex(), LocalDef::baseClasses(), codifyLines(), DBG_CTX, LinkedMap< T, Hash, KeyEqual, Map >::find(), 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 3348 of file code.l.

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

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

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 263 of file code.l.

263{return __FILE__;}

◆ getLink()

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

Definition at line 2894 of file code.l.

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

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

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

◆ getLinkInScope()

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

Definition at line 2810 of file code.l.

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

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), LocalDef::baseClasses(), GetDefInput::currentFile, DBG_CTX, 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(), MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by getLink().

◆ incrementFlowKeyWordCount()

void incrementFlowKeyWordCount ( yyscan_t yyscanner)
static

Definition at line 2544 of file code.l.

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

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

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3978 of file code.l.

3979{
3980 QCString s(keyword);
3981 int i=s.find('<');
3982 if (i==-1) return false;
3983 QCString kw = s.left(i).stripWhiteSpace();
3984 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3985}

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

◆ nextCodeLine()

void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2499 of file code.l.

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

References endCodeLine(), and startCodeLine().

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

◆ popScope()

void popScope ( yyscan_t yyscanner)
static

remove the top class/namespace name from the scope

Definition at line 2273 of file code.l.

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

References DBG_CTX, and qPrint().

Referenced by setClassScope().

◆ pushScope()

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

add class/namespace name s to the scope

Definition at line 2255 of file code.l.

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

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

Referenced by setClassScope().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4034 of file code.l.

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

References DBG_CTX.

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 4003 of file code.l.

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

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

◆ setCallContextForVar()

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

Definition at line 2683 of file code.l.

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

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

Referenced by generateClassOrGlobalLink().

◆ setClassScope()

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

Definition at line 2313 of file code.l.

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

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

◆ setCurrentDoc()

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

Definition at line 2289 of file code.l.

2290{
2291 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2292 if (Doxygen::searchIndex.enabled())
2293 {
2294 if (yyextra->searchCtx)
2295 {
2296 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),false);
2297 }
2298 else
2299 {
2300 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,true);
2301 }
2302 }
void setCurrentDoc(const Definition *ctx, const QCString &anchor, bool isSourceFile)
2303}

References Doxygen::searchIndex, and SearchIndexIntf::setCurrentDoc().

Referenced by CCodeParser::parseCode(), startCodeLine(), and startCodeLine().

◆ setParameterList()

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

Definition at line 2635 of file code.l.

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

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

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3937 of file code.l.

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

◆ startCodeLine()

void startCodeLine ( yyscan_t yyscanner)
static

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

Definition at line 2421 of file code.l.

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

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

Referenced by nextCodeLine(), nextCodeLine(), and CCodeParser::parseCode().

◆ startFontClass()

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

Definition at line 3511 of file code.l.

3512{
3513 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3514 endFontClass(yyscanner);
3515 if (specialComment)
3516 {
3517 yyextra->code->startSpecialComment();
3518 yyextra->insideSpecialComment = true;
3519 }
3520 yyextra->code->startFontClass(s);
3521 yyextra->currentFontClass=s;
3522}

References endFontClass().

Referenced by writeObjCMethodCall().

◆ startsWithKeyword()

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

Definition at line 2183 of file code.l.

2184{
2185 if (str.length()<kw.length()) return false; // string too short to match
2186 return str==kw || // exact match
2187 (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:591
bool isId(int c)
Definition util.h:257
2188}

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

◆ stateToString()

const char * stateToString ( int state)
static

◆ stripClassName()

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

Definition at line 2652 of file code.l.

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

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

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

◆ updateCallContextForSmartPointer()

void updateCallContextForSmartPointer ( yyscan_t yyscanner)
static

Definition at line 2793 of file code.l.

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

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

◆ writeMultiLineCodeLink()

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

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

Definition at line 2562 of file code.l.

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

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

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

◆ writeObjCMethodCall()

void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3527 of file code.l.

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

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

Referenced by writeObjCMethodCall().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 378 of file code.l.

381 {
382 startFontClass(yyscanner,"preprocessor");
383 yyextra->code->codify(yytext);
384 BEGIN( ReadInclude );
385 }
386<Body>("@interface"|"@implementation"|"@protocol")[ \t\n]+ {
387 yyextra->insideObjC=true;
388 startFontClass(yyscanner,"keyword");
389 codifyLines(yyscanner,yytext);
390 endFontClass(yyscanner);
391 if (!yyextra->insideTemplate)
392 BEGIN( ClassName );
393 }
394<Body>(("public"|"private"){B}+)?("ref"|"value"|"interface"|"enum"){B}+("class"|"struct") {
395 if (yyextra->insideTemplate) REJECT;
396 startFontClass(yyscanner,"keyword");
397 codifyLines(yyscanner,yytext);
398 endFontClass(yyscanner);
399 BEGIN( ClassName );
400 }
401<Body>"property"|"event"/{BN}* {
402 if (yyextra->insideTemplate) REJECT;
403 startFontClass(yyscanner,"keyword");
404 codifyLines(yyscanner,yytext);
405 endFontClass(yyscanner);
406 }
407<Body>("partial"{B}+)?("class"|"struct"|"union"|"namespace"|"interface"){B}+ {
408 startFontClass(yyscanner,"keyword");
409 codifyLines(yyscanner,yytext);
410 endFontClass(yyscanner);
411 if (!yyextra->insideTemplate)
412 BEGIN( ClassName );
413 }
414<Body>("package")[ \t\n]+ {
415 startFontClass(yyscanner,"keyword");
416 codifyLines(yyscanner,yytext);
417 endFontClass(yyscanner);
418 BEGIN( PackageName );
419 }
420<ClassVar>\n {
421 if (!yyextra->insideObjC) REJECT;
422 codifyLines(yyscanner,yytext);
423 BEGIN(Body);
424 }
425<Body,ClassVar,Bases>"-"|"+" {
426 if (!yyextra->insideObjC || yyextra->insideBody)
427 {
428 yyextra->code->codify(yytext);
429 }
430 else // Start of Objective-C method
431 {
432 DBG_CTX((stderr,"Start of Objective-C method!\n"));
433 yyextra->code->codify(yytext);
434 BEGIN(ObjCMethod);
435 }
436 }
437<ObjCMethod>":" {
438 yyextra->code->codify(yytext);
439 BEGIN(ObjCParams);
440 }
441<ObjCParams>"(" {
442 yyextra->code->codify(yytext);
443 BEGIN(ObjCParamType);
444 }
445<ObjCParams,ObjCMethod>";"|"{" {
446 yyextra->code->codify(yytext);
447 if (*yytext=='{')
448 {
449 if (yyextra->searchingForBody)
450 {
451 yyextra->searchingForBody=false;
452 yyextra->insideBody=true;
453 }
454 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
455 if (!yyextra->curClassName.isEmpty()) // valid class name
456 {
457 pushScope(yyscanner,yyextra->curClassName);
458 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
459 yyextra->scopeStack.push(SCOPEBLOCK);
460 }
461 }
462 yyextra->type.clear();
463 yyextra->name.clear();
464 BEGIN(Body);
465 }
#define SCOPEBLOCK
Definition code.l:78
466<ObjCParams>{ID}{B}*":" {
467 yyextra->code->codify(yytext);
468 }
469<ObjCParamType>{TYPEKW} {
470 startFontClass(yyscanner,"keywordtype");
471 yyextra->code->codify(yytext);
472 endFontClass(yyscanner);
473 yyextra->parmType=yytext;
474 }
475<ObjCParamType>{ID} {
476 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
477 yyextra->parmType=yytext;
478 }
479<ObjCParamType>")" {
480 yyextra->code->codify(yytext);
481 BEGIN(ObjCParams);
482 }
483<ObjCParams>{ID} {
484 yyextra->code->codify(yytext);
485 yyextra->parmName=yytext;
486 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
487 yyextra->parmType.clear();yyextra->parmName.clear();
488 }
489<ObjCMethod,ObjCParams,ObjCParamType>{ID} {
490 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
491 }
492<ObjCMethod,ObjCParams,ObjCParamType>. {
493 yyextra->code->codify(yytext);
494 }
495<ObjCMethod,ObjCParams,ObjCParamType>\n {
496 codifyLines(yyscanner,yytext);
497 }
498<ReadInclude>[^\n\">]+/(">"|"\"") {
499 //FileInfo *f;
500 bool found = false;
501 bool ambig = false;
502 QCString absIncFileName = determineAbsoluteIncludeName(yyextra->absFileName,yytext);
503 const FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
504 //printf("looking for include %s -> %s fd=%p\n",yytext,qPrint(absPath),fd);
505 if (fd && fd->isLinkable())
506 {
507 if (ambig) // multiple input files match the name
508 {
509 DBG_CTX((stderr,"===== yes %s is ambiguous\n",yytext));
510 QCString name(Dir::cleanDirPath(yytext));
511 if (!name.isEmpty() && yyextra->sourceFileDef)
512 {
513 const FileName *fn = Doxygen::inputNameLinkedMap->find(name);
514 if (fn)
515 {
516 // see if this source file actually includes the file
517 auto it = std::find_if(fn->begin(),
518 fn->end(),
519 [&sfd=yyextra->sourceFileDef]
520 (const auto &lfd)
521 { return sfd->isIncluded(lfd->absFilePath()); });
522 found = it!=fn->end();
523 }
524 }
525 }
526 else // not ambiguous
527 {
528 found = true;
529 }
530 }
531 DBG_CTX((stderr," include file %s found=%d\n",fd ? qPrint(fd->absFilePath()) : "<none>",found));
532 if (found)
533 {
534 writeMultiLineCodeLink(yyscanner,*yyextra->code,fd,yytext);
535 }
536 else
537 {
538 yyextra->code->codify(yytext);
539 }
540 char c=(char)yyinput(yyscanner);
541 QCString text;
542 text+=c;
543 yyextra->code->codify(text);
544 endFontClass(yyscanner);
545 BEGIN( Body );
546 }
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:357
static FileNameLinkedMap * inputNameLinkedMap
Definition doxygen.h: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:3639
FileDef * findFileDef(const FileNameLinkedMap *fnMap, const QCString &n, bool &ambig)
Definition util.cpp:2919
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:247
bool endsWith(const char *s) const
Definition qcstring.h:522
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:2600
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:3360
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:2621
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:3937
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:63
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:2544
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:3348
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:3978
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:2183
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:6974
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:6982
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:2793
1363<MemberCall>{SCOPETNAME}/{BN}*"(" {
1364 DBG_CTX((stderr,"MemberCall: '%s'\n",qPrint(yytext)));
1365 if (yyextra->theCallContext.getScope().globalDef())
1366 {
1367 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1368 {
1369 codifyLines(yyscanner,yytext);
1370 addToSearchIndex(yyscanner,yytext);
1371 }
1372 yyextra->name.clear();
1373 }
1374 else
1375 {
1376 codifyLines(yyscanner,yytext);
1377 addToSearchIndex(yyscanner,yytext);
1378 yyextra->name.clear();
1379 }
1380 yyextra->type.clear();
1381 if (yyextra->memCallContext==Body)
1382 {
1383 BEGIN(FuncCall);
1384 }
1385 else
1386 {
1387 BEGIN(yyextra->memCallContext);
1388 }
1389 }
1390<MemberCall>{SCOPENAME}/{B}* {
1391 if (yyextra->theCallContext.getScope().globalDef())
1392 {
1393 DBG_CTX((stderr,"yyextra->theCallContext.getClass()=%p\n",(void*)yyextra->theCallContext.getScope().globalDef()));
1394 if (!generateClassMemberLink(yyscanner,*yyextra->code,yyextra->theCallContext.getScope().globalDef(),yytext))
1395 {
1396 codifyLines(yyscanner,yytext);
1397 addToSearchIndex(yyscanner,yytext);
1398 }
1399 yyextra->name.clear();
1400 }
1401 else
1402 {
1403 DBG_CTX((stderr,"no class context!\n"));
1404 codifyLines(yyscanner,yytext);
1405 addToSearchIndex(yyscanner,yytext);
1406 yyextra->name.clear();
1407 }
1408 yyextra->type.clear();
1409 BEGIN(yyextra->memCallContext);
1410 }
1411<Body>[,=;\‍[{] {
1412 if (yyextra->insideObjC && *yytext=='[')
1413 {
1414 DBG_CTX((stderr,"Found start of ObjC call!\n"));
1415 // start of a method call
1416 yyextra->contextMap.clear();
1417 yyextra->nameMap.clear();
1418 yyextra->objectMap.clear();
1419 yyextra->wordMap.clear();
1420 yyextra->commentMap.clear();
1421 yyextra->currentCtxId = 0;
1422 yyextra->currentNameId = 0;
1423 yyextra->currentObjId = 0;
1424 yyextra->currentCtx = nullptr;
1425 yyextra->braceCount = 0;
1426 unput('[');
1427 BEGIN(ObjCCall);
1428 }
1429 else
1430 {
1431 if (*yytext!='{') yyextra->code->codify(yytext);
1432 yyextra->saveName = yyextra->name;
1433 yyextra->saveType = yyextra->type;
1434 if (*yytext!='[' && !yyextra->type.isEmpty())
1435 {
1436 //printf("yyextra->scopeStack.bottom()=%p\n",yyextra->scopeStack.bottom());
1437 //if (yyextra->scopeStack.top()!=CLASSBLOCK) // commented out for bug731363
1438 {
1439 //printf("AddVariable: '%s' '%s' context=%d\n",
1440 // qPrint(yyextra->type),qPrint(yyextra->name),yyextra->theVarContext.count());
1441 addVariable(yyscanner,yyextra->type,yyextra->name);
1442 }
1443 yyextra->name.clear();
1444 }
1445 if (*yytext==';' || *yytext=='=' || *yytext=='{')
1446 {
1447 yyextra->type.clear();
1448 yyextra->name.clear();
1449 }
1450 else if (*yytext=='[')
1451 {
1452 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1453 }
1454 yyextra->args.clear();
1455 yyextra->parmType.clear();
1456 yyextra->parmName.clear();
1457 if (*yytext=='{')
1458 {
1459 BEGIN( BodyVar );
1460 unput('{');
1461 }
1462 }
1463 }
1464<Body,FuncCall,BodyVar>"{" {
1465 yyextra->theVarContext.pushScope();
1466 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1467 yyextra->bracketCount = 0;
1468
1469 DBG_CTX((stderr,"** type='%s' name='%s'\n",qPrint(yyextra->type),qPrint(yyextra->name)));
1470 if (yyextra->type.find("enum ")!=-1)
1471 { // for strong enums we need to start a scope
1472 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1473 pushScope(yyscanner,yyextra->name);
1474 yyextra->scopeStack.push(SCOPEBLOCK);
1475 }
1476 else
1477 {
1478 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1479 yyextra->scopeStack.push(INNERBLOCK);
1480 }
1481
1482 if (yyextra->searchingForBody)
1483 {
1484 yyextra->searchingForBody=false;
1485 yyextra->insideBody=true;
1486 }
1487 yyextra->code->codify(yytext);
1488 if (yyextra->insideBody)
1489 {
1490 yyextra->bodyCurlyCount++;
1491 }
1492 yyextra->type.clear();
1493 yyextra->name.clear();
1494 BEGIN( Body );
1495 }
1496<ObjCCall,ObjCMName>"["|"{" {
1497 saveObjCContext(yyscanner);
1498 yyextra->currentCtx->format+=*yytext;
1499 BEGIN(ObjCCall);
1500 DBG_CTX((stderr,"open\n"));
1501 }
static void saveObjCContext(yyscan_t yyscanner)
Definition code.l:4003
1502<ObjCCall,ObjCMName>"]"|"}" {
1503 yyextra->currentCtx->format+=*yytext;
1504 restoreObjCContext(yyscanner);
1505 BEGIN(ObjCMName);
1506 if (yyextra->currentCtx==nullptr)
1507 {
1508 // end of call
1509 ObjCCallCtx *ctx = nullptr;
1510 auto it = yyextra->contextMap.find(0);
1511 if (it!=yyextra->contextMap.end())
1512 {
1513 ctx = it->second.get();
1514 }
1515 writeObjCMethodCall(yyscanner,ctx);
1516 BEGIN(Body);
1517 }
1518 DBG_CTX((stderr,"close\n"));
1519 }
static void restoreObjCContext(yyscan_t yyscanner)
Definition code.l:4034
1520<ObjCCall,ObjCMName>{CPPC}.* {
1521 yyextra->currentCtx->format+=escapeComment(yyscanner,yytext);
1522 }
static QCString escapeComment(yyscan_t yyscanner, const QCString &s)
Definition code.l:3927
1523<ObjCCall,ObjCMName>{CCS} {
1524 yyextra->lastObjCCallContext = YY_START;
1525 yyextra->currentCtx->comment.str(yytext);
1526 BEGIN(ObjCCallComment);
1527 }
1528<ObjCCallComment>{CCE} {
1529 yyextra->currentCtx->comment << yytext;
1530 yyextra->currentCtx->format+=escapeComment(yyscanner,yyextra->currentCtx->comment.str());
1531 BEGIN(yyextra->lastObjCCallContext);
1532 }
1533<ObjCCallComment>[^*\n]+ { yyextra->currentCtx->comment << yytext; }
1534<ObjCCallComment>{CPPC}|{CCS} { yyextra->currentCtx->comment << yytext; }
1535<ObjCCallComment>\n { yyextra->currentCtx->comment << *yytext; }
1536<ObjCCallComment>. { yyextra->currentCtx->comment << *yytext; }
1537<ObjCCall>{ID}({B}*"."{B}*{ID})* {
1538 yyextra->currentCtx->format+=escapeObject(yyscanner,yytext);
1539 if (yyextra->braceCount==0)
1540 {
1541 yyextra->currentCtx->objectTypeOrName=yytext;
1542 DBG_CTX((stderr,"new type=%s\n",qPrint(yyextra->currentCtx->objectTypeOrName)));
1543 BEGIN(ObjCMName);
1544 }
1545 }
static QCString escapeObject(yyscan_t yyscanner, const QCString &s)
Definition code.l:3907
1546<ObjCMName>{ID}/{BN}*"]" {
1547 if (yyextra->braceCount==0 &&
1548 yyextra->currentCtx->methodName.isEmpty())
1549 {
1550 yyextra->currentCtx->methodName=yytext;
1551 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1552 }
1553 else
1554 {
1555 yyextra->currentCtx->format+=escapeWord(yyscanner,yytext);
1556 }
1557 }
static QCString escapeWord(yyscan_t yyscanner, const QCString &s)
Definition code.l:3917
static QCString escapeName(yyscan_t yyscanner, const QCString &s)
Definition code.l:3897
1558<ObjCMName>{ID}/{BN}*":" {
1559 if (yyextra->braceCount==0)
1560 {
1561 yyextra->currentCtx->methodName+=yytext;
1562 yyextra->currentCtx->methodName+=":";
1563 }
1564 yyextra->currentCtx->format+=escapeName(yyscanner,yytext);
1565 }
1566<ObjCSkipStr>[^\n\"$\\‍]* { yyextra->currentCtx->format+=yytext; }
1567<ObjCSkipStr>\\. { yyextra->currentCtx->format+=yytext; }
1568<ObjCSkipStr>"\"" { yyextra->currentCtx->format+=yytext;
1569 BEGIN(yyextra->lastStringContext);
1570 }
1571<ObjCCall,ObjCMName>{CHARLIT} { yyextra->currentCtx->format+=yytext; }
1572<ObjCCall,ObjCMName>"@"?"\"" { yyextra->currentCtx->format+=yytext;
1573 yyextra->lastStringContext=YY_START;
1574 BEGIN(ObjCSkipStr);
1575 }
1576<ObjCCall,ObjCMName,ObjCSkipStr>"$" { yyextra->currentCtx->format+="$$"; }
1577<ObjCCall,ObjCMName>"(" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount++; }
1578<ObjCCall,ObjCMName>")" { yyextra->currentCtx->format+=*yytext; yyextra->braceCount--; }
1579<ObjCSkipStr>"@"/"\"" { // needed to prevent matching the global rule (for C#)
1580 yyextra->currentCtx->format+=yytext;
1581 }
1582<ObjCCall,ObjCMName,ObjCSkipStr>{ID} { yyextra->currentCtx->format+=escapeWord(yyscanner,yytext); }
1583<ObjCCall,ObjCMName,ObjCSkipStr>. { yyextra->currentCtx->format+=*yytext; }
1584<ObjCCall,ObjCMName,ObjCSkipStr>\n { yyextra->currentCtx->format+=*yytext; }
1585
1586<Body>"]" {
1587 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1588 yyextra->code->codify(yytext);
1589 // TODO: nested arrays like: a[b[0]->func()]->func()
1590 yyextra->name = yyextra->saveName;
1591 yyextra->type = yyextra->saveType;
1592 }
1593<Body>[0-9]+ {
1594 yyextra->code->codify(yytext);
1595 }
1596<Body>[0-9]+[xX][0-9A-Fa-f]+ {
1597 yyextra->code->codify(yytext);
1598 }
1599<MemberCall2,FuncCall>{KEYWORD}/([^a-z_A-Z0-9]) {
1600 //addParmType(yyscanner);
1601 //yyextra->parmName=yytext;
1602 if (skipLanguageSpecificKeyword(yyscanner,yytext)) REJECT;
1603 startFontClass(yyscanner,"keyword");
1604 yyextra->code->codify(yytext);
1605 endFontClass(yyscanner);
1606 }
1607<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKW}/([^a-z_A-Z0-9]) {
1608 addParmType(yyscanner);
1609 yyextra->parmName=yytext;
1610 startFontClass(yyscanner,"keywordtype");
1611 yyextra->code->codify(yytext);
1612 endFontClass(yyscanner);
1613 }
static void addParmType(yyscan_t yyscanner)
Definition code.l:2612
1614<MemberCall2,FuncCall,OldStyleArgs,TemplCast>{TYPEKWSL}/([^a-z_A-Z0-9]) {
1615 if (yyextra->lang!=SrcLangExt::Slice)
1616 {
1617 REJECT;
1618 }
1619 else
1620 {
1621 addParmType(yyscanner);
1622 yyextra->parmName=yytext;
1623 startFontClass(yyscanner,"keywordtype");
1624 yyextra->code->codify(yytext);
1625 endFontClass(yyscanner);
1626 }
1627 }
1628<MemberCall2,FuncCall>{FLOWKW}/([^a-z_A-Z0-9]) {
1629 addParmType(yyscanner);
1630 yyextra->parmName=yytext;
1631 startFontClass(yyscanner,"keywordflow");
1632 yyextra->code->codify(yytext);
1633 endFontClass(yyscanner);
1634 }
1635<MemberCall2,FuncCall>{FLOWCONDITION}/([^a-z_A-Z0-9]) {
1636 incrementFlowKeyWordCount(yyscanner);
1637 addParmType(yyscanner);
1638 yyextra->parmName=yytext;
1639 startFontClass(yyscanner,"keywordflow");
1640 yyextra->code->codify(yytext);
1641 endFontClass(yyscanner);
1642 }
1643<MemberCall2,FuncCall>("::")?{ID}(({B}*"<"[^\n\‍[\‍](){}<>']*">")?({B}*"::"{B}*{ID})?)* {
1644 if (isCastKeyword(yytext))
1645 {
1646 REJECT;
1647 }
1648 addParmType(yyscanner);
1649 yyextra->parmName=yytext;
1650 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1651 }
1652<FuncCall>";" { // probably a cast, not a function call
1653 yyextra->code->codify(yytext);
1654 yyextra->inForEachExpression = false;
1655 BEGIN( Body );
1656 }
1657<MemberCall2,FuncCall>, {
1658 yyextra->code->codify(yytext);
1659 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1660 yyextra->parmType.clear();yyextra->parmName.clear();
1661 }
1662<MemberCall2,FuncCall>"{" {
1663 if (yyextra->bracketCount>0)
1664 {
1665 yyextra->code->codify(yytext);
1666 yyextra->skipInlineInitContext=YY_START;
1667 yyextra->curlyCount=0;
1668 BEGIN(InlineInit);
1669 }
1670 else
1671 {
1672 REJECT;
1673 }
1674 }
1675<InlineInit>"{" { yyextra->curlyCount++;
1676 yyextra->code->codify(yytext);
1677 }
1678<InlineInit>"}" {
1679 yyextra->code->codify(yytext);
1680 if (--yyextra->curlyCount<=0)
1681 {
1682 BEGIN(yyextra->skipInlineInitContext);
1683 }
1684 }
1685<InlineInit>\n {
1686 codifyLines(yyscanner,yytext);
1687 }
1688<InlineInit>. {
1689 yyextra->code->codify(yytext);
1690 }
1691<MemberCall2,FuncCall>"(" {
1692 yyextra->parmType.clear();yyextra->parmName.clear();
1693 yyextra->code->codify(yytext);
1694 yyextra->bracketCount++;
1695 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1696 if (YY_START==FuncCall && !yyextra->insideBody)
1697 {
1698 yyextra->theVarContext.pushScope();
1699 }
1700 }
1701<MemberCall2,FuncCall>{OPERATOR} { // operator
1702 if (qstrcmp(yytext,"*") &&
1703 qstrcmp(yytext,"&") &&
1704 qstrcmp(yytext,"^") &&
1705 qstrcmp(yytext,"%")) // typically a pointer or reference
1706 {
1707 // not a * or &, or C++/CLI's ^ or %
1708 yyextra->parmType.clear();yyextra->parmName.clear();
1709 }
1710 yyextra->code->codify(yytext);
1711 }
1712<MemberCall,MemberCall2,FuncCall>("*"{B}*)?")" {
1713 if (yytext[0]==')') // no a pointer cast
1714 {
1715 DBG_CTX((stderr,"addVariable(%s,%s)\n",qPrint(yyextra->parmType),qPrint(yyextra->parmName)));
1716 if (yyextra->parmType.isEmpty())
1717 {
1718 yyextra->parmType=yyextra->parmName;
1719 yyextra->parmName.clear();
1720 }
1721 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1722 }
1723 else
1724 {
1725 yyextra->parmType = yyextra->parmName;
1726 yyextra->parmName.clear();
1727 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1728 }
1729 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
1730 yyextra->inForEachExpression = false;
1731 //yyextra->theCallContext.setClass(0); // commented out, otherwise a()->b() does not work for b().
1732 yyextra->code->codify(yytext);
1733 if (--yyextra->bracketCount<=0)
1734 {
1735 if (yyextra->name.isEmpty())
1736 {
1737 BEGIN( Body );
1738 }
1739 else
1740 {
1741 BEGIN( CallEnd );
1742 }
1743 }
1744 }
1745<MemberCall,MemberCall2,FuncCall>[;:] { // recover from unexpected end of call
1746 //if (yytext[0]==';' || yyextra->bracketCount<=0)
1747 if (yyextra->bracketCount<=0)
1748 {
1749 unput(*yytext);
1750 BEGIN(CallEnd);
1751 }
1752 else
1753 {
1754 yyextra->code->codify(yytext);
1755 }
1756 }
1757<CallEnd>[ \t\n]* { codifyLines(yyscanner,yytext); }
1758<CallEnd>[;:] {
1759 codifyLines(yyscanner,yytext);
1760 yyextra->bracketCount=0;
1761 if (*yytext==';') yyextra->searchingForBody=false;
1762 if (!yyextra->type.isEmpty())
1763 {
1764 DBG_CTX((stderr,"add variable yyextra->type=%s yyextra->name=%s)\n",qPrint(yyextra->type),qPrint(yyextra->name)));
1765 addVariable(yyscanner,yyextra->type,yyextra->name);
1766 }
1767 yyextra->parmType.clear();yyextra->parmName.clear();
1768 yyextra->theCallContext.setScope(ScopedTypeVariant());
1769 if (*yytext==';' || yyextra->insideBody)
1770 {
1771 if (!yyextra->insideBody)
1772 {
1773 yyextra->theVarContext.popScope();
1774 }
1775 yyextra->name.clear();yyextra->type.clear();
1776 BEGIN( Body );
1777 }
1778 else
1779 {
1780 yyextra->bracketCount=0;
1781 BEGIN( SkipInits );
1782 }
1783 }
1784<CallEnd>"=>" { // C# Expression Body
1785 if (yyextra->lang!=SrcLangExt::CSharp || yyextra->insideBody)
1786 {
1787 REJECT;
1788 }
1789 else
1790 {
1791 yyextra->code->codify("=>");
1792 BEGIN( Body );
1793 }
1794 }
1795<CallEnd>{ENDQopt}/{BN}*(";"|"="|"throw"{BN}*"(") {
1796 startFontClass(yyscanner,"keyword");
1797 codifyLines(yyscanner,yytext);
1798 endFontClass(yyscanner);
1799 }
1800<CallEnd,OldStyleArgs>("const"|"volatile"|"sealed"|"override")*({BN}+("const"|"volatile"|"sealed"|"override"))*{BN}*"{" {
1801 if (yyextra->insideBody)
1802 {
1803 yyextra->theVarContext.pushScope();
1804 }
1805 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1806 //yyextra->theCallContext.popScope(yyextra->name, yyextra->type);
1807 yyextra->parmType.clear();yyextra->parmName.clear();
1808 int index = yyextra->name.findRev("::");
1809 DBG_CTX((stderr,"yyextra->name=%s\n",qPrint(yyextra->name)));
1810 if (index!=-1)
1811 {
1812 QCString scope = yyextra->name.left((uint32_t)index);
1813 if (!yyextra->scopeName.isEmpty()) scope.prepend((yyextra->scopeName+"::"));
1814 const ClassDef *cd=yyextra->symbolResolver.resolveClass(Doxygen::globalScope,scope,true);
1815 if (cd)
1816 {
1817 setClassScope(yyscanner,cd->name());
1818 yyextra->scopeStack.push(SCOPEBLOCK);
1819 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1820 }
1821 else
1822 {
1823 //setClassScope(yyscanner,yyextra->realScope);
1824 yyextra->scopeStack.push(INNERBLOCK);
1825 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1826 }
1827 }
1828 else
1829 {
1830 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1831 yyextra->scopeStack.push(INNERBLOCK);
1832 }
1833 yytext[yyleng-1]='\0';
1834 QCString cv(yytext);
1835 if (!cv.stripWhiteSpace().isEmpty())
1836 {
1837 startFontClass(yyscanner,"keyword");
1838 codifyLines(yyscanner,yytext);
1839 endFontClass(yyscanner);
1840 }
1841 else // just whitespace
1842 {
1843 codifyLines(yyscanner,yytext);
1844 }
1845 yyextra->code->codify("{");
1846 if (yyextra->searchingForBody)
1847 {
1848 yyextra->searchingForBody=false;
1849 yyextra->insideBody=true;
1850 }
1851 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1852 yyextra->type.clear(); yyextra->name.clear();
1853 BEGIN( Body );
1854 }
static void setClassScope(yyscan_t yyscanner, const QCString &name)
Definition code.l:2313
1855<CallEnd>"try" { // function-try-block
1856 startFontClass(yyscanner,"keyword");
1857 yyextra->code->codify(yytext);
1858 endFontClass(yyscanner);
1859 yyextra->inFunctionTryBlock=true;
1860 }
1861<CallEnd>"requires" { // function-try-block
1862 startFontClass(yyscanner,"keyword");
1863 yyextra->code->codify(yytext);
1864 endFontClass(yyscanner);
1865 }
1866<CallEnd>{ID} {
1867 if (yyextra->insideBody || !yyextra->parmType.isEmpty())
1868 {
1869 REJECT;
1870 }
1871 // could be K&R style definition
1872 addParmType(yyscanner);
1873 yyextra->parmName=yytext;
1874 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1875 BEGIN(OldStyleArgs);
1876 }
1877<OldStyleArgs>{ID} {
1878 addParmType(yyscanner);
1879 yyextra->parmName=yytext;
1880 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,!yyextra->insideBody);
1881 }
1882<OldStyleArgs>[,;] {
1883 yyextra->code->codify(yytext);
1884 addVariable(yyscanner,yyextra->parmType,yyextra->parmName);
1885 if (*yytext==';') yyextra->parmType.clear();
1886 yyextra->parmName.clear();
1887 }
1888<CallEnd,OldStyleArgs>"#" {
1889 startFontClass(yyscanner,"preprocessor");
1890 yyextra->lastSkipCppContext = Body;
1891 yyextra->code->codify(yytext);
1892 BEGIN( SkipCPP );
1893 }
1894<CallEnd>. {
1895 unput(*yytext);
1896 if (!yyextra->insideBody)
1897 {
1898 yyextra->theVarContext.popScope();
1899 }
1900 yyextra->name.clear();yyextra->args.clear();
1901 yyextra->parmType.clear();yyextra->parmName.clear();
1902 BEGIN( Body );
1903 }
1904<SkipInits>";" {
1905 yyextra->code->codify(yytext);
1906 yyextra->type.clear(); yyextra->name.clear();
1907 BEGIN( Body );
1908 }
1909<SkipInits>"{" {
1910 yyextra->code->codify(yytext);
1911 if (yyextra->searchingForBody)
1912 {
1913 yyextra->searchingForBody=false;
1914 yyextra->insideBody=true;
1915 }
1916 if (yyextra->insideBody) yyextra->bodyCurlyCount++;
1917 if (yyextra->name.find("::")!=-1)
1918 {
1919 DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
1920 yyextra->scopeStack.push(SCOPEBLOCK);
1921 setClassScope(yyscanner,yyextra->realScope);
1922 }
1923 else
1924 {
1925 DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
1926 yyextra->scopeStack.push(INNERBLOCK);
1927 }
1928 yyextra->type.clear(); yyextra->name.clear();
1929 BEGIN( Body );
1930 }
1931<SkipInits>{ID}{B}*"{" {
1932 QCString text(yytext);
1933 int bracketPos = text.find('{');
1934 int spacePos = text.find(' ');
1935 int len = spacePos==-1 ? bracketPos : spacePos;
1936 generateClassOrGlobalLink(yyscanner,*yyextra->code,text.left(len));
1937 yyextra->code->codify(yytext+len);
1938 }
1939<SkipInits>{ID} {
1940 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1941 }
1942<FuncCall>{ID}/"(" {
1943 generateFunctionLink(yyscanner,*yyextra->code,yytext);
1944 }
1945<FuncCall>{ID}/("."|"->") {
1946 yyextra->name=yytext;
1947 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1948 BEGIN( MemberCall2 );
1949 }
1950<FuncCall,MemberCall2>("("{B}*("*"{B}*)+{ID}+{B}*")"{B}*)/("."|"->") {
1951 yyextra->code->codify(yytext);
1952 uint32_t s=0;while (!isId(yytext[s])) s++;
1953 uint32_t e=(uint32_t)yyleng-1;while (e>1 && !isId(yytext[e])) e--;
1954 yyextra->name=((QCString)yytext).mid(s,e-s+1);
1955 BEGIN( MemberCall2 );
1956 }
1957<MemberCall2>{ID}/([ \t\n]*"(") {
1958 if (!yyextra->args.isEmpty())
1959 generateMemberLink(yyscanner,*yyextra->code,yyextra->args,yytext);
1960 else
1961 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1962 yyextra->args.clear();
1963 BEGIN( FuncCall );
1964 }
static void generateMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &varName, const QCString &memName)
Definition code.l:3254
1965<MemberCall2>{ID}/([ \t\n]*("."|"->")) {
1966 //yyextra->code->codify(yytext);
1967 yyextra->name=yytext;
1968 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
1969 BEGIN( MemberCall2 );
1970 }
1971<MemberCall2>"->"|"." {
1972 if (yytext[0]=='-') // -> could be overloaded
1973 {
1975 }
1976 yyextra->code->codify(yytext);
1977 yyextra->memCallContext = YY_START;
1978 BEGIN( MemberCall );
1979 }
1980<SkipComment>{CCS}("!"?){CCE} {
1981 yyextra->code->codify(yytext);
1982 endFontClass(yyscanner,true);
1983 BEGIN( yyextra->lastCContext ) ;
1984 }
1985<SkipComment>{CPPC}|{CCS} {
1986 yyextra->code->codify(yytext);
1987 }
1988<SkipComment>[^*\/\n]+ {
1989 yyextra->code->codify(yytext);
1990 }
1991<SkipComment>[ \t]*{CCE} {
1992 yyextra->code->codify(yytext);
1993 endFontClass(yyscanner,true);
1994 if (yyextra->lastCContext==SkipCPP)
1995 {
1996 startFontClass(yyscanner,"preprocessor");
1997 }
1998 BEGIN( yyextra->lastCContext ) ;
1999 }
2000<SkipCxxComment>[^\r\n]*"\\"[\r]?\n { // line continuation
2001 codifyLines(yyscanner,yytext);
2002 }
2003<SkipCxxComment>[^\r\n]+ {
2004 yyextra->code->codify(yytext);
2005 }
2006<SkipCxxComment>\r
2007<SkipCxxComment>\n {
2008 unput('\n');
2009 endFontClass(yyscanner);
2010 BEGIN( yyextra->lastCContext ) ;
2011 }
2012<SkipCxxComment>. {
2013 yyextra->code->codify(yytext);
2014 }
2015<MemberCall>[^a-z_A-Z0-9(\n] {
2016 yyextra->code->codify(yytext);
2017 yyextra->type.clear();
2018 yyextra->name.clear();
2019 BEGIN(yyextra->memCallContext);
2020 }
2021<*>\n({B}*{CPPC}[!/][^\n]*\n)+ { // remove special one-line comment
2022 if (YY_START==SkipCPP) REJECT;
2023 startFontClass(yyscanner,"comment",true);
2024 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2025 endFontClass(yyscanner,true);
2026 codifyLines(yyscanner,"\n");
2027 if (YY_START==SkipCxxComment)
2028 {
2029 BEGIN( yyextra->lastCContext ) ;
2030 }
2031 }
2032<SkipCPP>\n/(.|\n) {
2033 endFontClass(yyscanner);
2034 BEGIN( yyextra->lastSkipCppContext ) ;
2035 unput('\n');
2036 }
2037<*>\n{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2038 startFontClass(yyscanner,"comment",true);
2039 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2040 endFontClass(yyscanner,true);
2041 codifyLines(yyscanner,"\n");
2042 if (YY_START==SkipCxxComment)
2043 {
2044 BEGIN( yyextra->lastCContext ) ;
2045 }
2046 }
2047<*>\n{B}*{CCS}"@"[{}] { // remove one-line group marker
2048 // check is to prevent getting stuck in skipping C++ comments
2049 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2050 {
2051 yyextra->lastCContext = YY_START ;
2052 }
2053 startFontClass(yyscanner,"comment",true);
2054 codifyLines(yyscanner,yytext);
2055 BEGIN(SkipComment);
2056 }
2057<*>^{B}*{CPPC}"@"[{}].*\n { // remove one-line group marker
2058 startFontClass(yyscanner,"comment",true);
2059 codifyLines(yyscanner,QCString(yytext).left(yyleng-1));
2060 endFontClass(yyscanner,true);
2061 codifyLines(yyscanner,"\n");
2062 }
2063<*>^{B}*{CCS}"@"[{}] { // remove multi-line group marker
2064 // check is to prevent getting stuck in skipping C++ comments
2065 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2066 {
2067 yyextra->lastCContext = YY_START ;
2068 }
2069 startFontClass(yyscanner,"comment",true);
2070 yyextra->code->codify(yytext);
2071 BEGIN(SkipComment);
2072 }
2073<*>^{B}*{CPPC}[!/][^\n]* { // remove special one-line comment
2074 startFontClass(yyscanner,"comment",true);
2075 codifyLines(yyscanner,yytext);
2076 endFontClass(yyscanner,true);
2077 }
2078<*>{CPPC}[!/][^\n]* { // strip special one-line comment
2079 if (YY_START==SkipComment || YY_START==SkipString) REJECT;
2080 startFontClass(yyscanner,"comment",true);
2081 codifyLines(yyscanner,yytext);
2082 endFontClass(yyscanner,true);
2083 }
2084<*>\n{B}*{CCS}[!*]/{NCOMM} {
2085 // check is to prevent getting stuck in skipping C++ comments
2086 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2087 {
2088 yyextra->lastCContext = YY_START ;
2089 }
2090 startFontClass(yyscanner,"comment",true);
2091 codifyLines(yyscanner,yytext);
2092 BEGIN(SkipComment);
2093 }
2094<*>^{B}*{CCS}"*"[*]+/[^/] {
2095 // check is to prevent getting stuck in skipping C++ comments
2096 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2097 {
2098 yyextra->lastCContext = YY_START ;
2099 }
2100 // special C "banner" comment block at a new line
2101 startFontClass(yyscanner,"comment",Config_getBool(JAVADOC_BANNER));
2102 yyextra->code->codify(yytext);
2103 BEGIN(SkipComment);
2104 }
2105<*>^{B}*{CCS}[!*]/{NCOMM} { // special C comment block at a new line
2106 // check is to prevent getting stuck in skipping C++ comments
2107 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2108 {
2109 yyextra->lastCContext = YY_START ;
2110 }
2111 startFontClass(yyscanner,"comment",true);
2112 yyextra->code->codify(yytext);
2113 BEGIN(SkipComment);
2114 }
2115<*>{CCS}[!*]/{NCOMM} { // special C comment block half way a line
2116 if (YY_START==SkipString) REJECT;
2117 // check is to prevent getting stuck in skipping C++ comments
2118 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2119 {
2120 yyextra->lastCContext = YY_START ;
2121 }
2122 startFontClass(yyscanner,"comment",true);
2123 yyextra->code->codify(yytext);
2124 BEGIN(SkipComment);
2125 }
2126<*>{CCS}("!"?){CCE} {
2127 if (YY_START==SkipString) REJECT;
2128 bool specialComment = QCString(yytext).find('!')!=-1;
2129 startFontClass(yyscanner,"comment",specialComment);
2130 yyextra->code->codify(yytext);
2131 endFontClass(yyscanner,specialComment);
2132 }
2133<SkipComment>[^\*\n]+ {
2134 yyextra->code->codify(yytext);
2135 }
2136<*>{CCS} {
2137 startFontClass(yyscanner,"comment");
2138 yyextra->code->codify(yytext);
2139 // check is to prevent getting stuck in skipping C++ comments
2140 if (YY_START != SkipComment && YY_START != SkipCxxComment)
2141 {
2142 yyextra->lastCContext = YY_START ;
2143 }
2144 BEGIN( SkipComment ) ;
2145 }
2146<*>[$]?@\" { // C# (interpolated) verbatim string
2147 startFontClass(yyscanner,"stringliteral");
2148 yyextra->code->codify(yytext);
2149 yyextra->lastVerbStringContext=YY_START;
2150 BEGIN(SkipVerbString);
2151 }
2152<*>{CPPC} {
2153 startFontClass(yyscanner,"comment");
2154 yyextra->code->codify(yytext);
2155 yyextra->lastCContext = YY_START ;
2156 BEGIN( SkipCxxComment ) ;
2157 }
2158<*>"("|"[" {
2159 if (yytext[0]=='(') yyextra->bracketCount++;
2160 yyextra->code->codify(yytext);
2161 yyextra->theCallContext.pushScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2162 }
2163<*>")"|"]" {
2164 if (yytext[0]==')') yyextra->bracketCount--;
2165 yyextra->code->codify(yytext);
2166 yyextra->theCallContext.popScope(yyextra->name, yyextra->type, yyextra->bracketCount);
2167 }
2168<*>\n {
2169 codifyLines(yyscanner,yytext);
2170 }
2171<*>[\x80-\xFF]* { // keep utf8 characters together...
2172 yyextra->code->codify(yytext);
2173 }
2174<*>. {
2175 yyextra->code->codify(yytext);
2176 }
2177
2178%%

◆ yyread()

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

Definition at line 3987 of file code.l.

3988{
3989 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
3990 yy_size_t inputPosition = yyextra->inputPosition;
3991 const char *s = yyextra->inputString + inputPosition;
3992 int c=0;
3993 while( c < max_size && *s )
3994 {
3995 *buf++ = *s++;
3996 c++;
3997 }
3998 yyextra->inputPosition += c;
3999 return c;
4000}