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 "conceptdef.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 DString &s)
static void popScope (yyscan_t yyscanner)
static void setCurrentDoc (yyscan_t yyscanner, const DString &anchor)
static void addToSearchIndex (yyscan_t yyscanner, const DString &text)
static void setClassScope (yyscan_t yyscanner, const DString &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 DString &text)
static void incrementFlowKeyWordCount (yyscan_t yyscanner)
static void writeMultiLineCodeLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const DString &text)
static void addType (yyscan_t yyscanner)
static void addParmType (yyscan_t yyscanner)
static void addUsingDirective (yyscan_t yyscanner, const DString &name)
static void setParameterList (yyscan_t yyscanner, const MemberDef *md)
static const ClassDefstripClassName (yyscan_t yyscanner, const DString &s, const Definition *d)
static const MemberDefsetCallContextForVar (yyscan_t yyscanner, const DString &name)
static void updateCallContextForSmartPointer (yyscan_t yyscanner)
static bool getLinkInScope (yyscan_t yyscanner, const DString &c, const DString &m, const DString &memberText, OutputCodeList &ol, const DString &text, bool varOnly=false)
static bool getLink (yyscan_t yyscanner, const DString &className, const DString &memberName, OutputCodeList &ol, const DString &text=DString(), bool varOnly=false)
static void generateClassOrGlobalLink (yyscan_t yyscanner, OutputCodeList &ol, const DString &clName, bool typeOnly=false, bool varOnly=false)
static bool generateClassMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const MemberDef *xmd, const DString &memName)
static bool generateClassMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *def, const DString &memName)
static void generateMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const DString &varName, const DString &memName)
static void generatePHPVariableLink (yyscan_t yyscanner, OutputCodeList &ol, const char *varName)
static void generateFunctionLink (yyscan_t yyscanner, OutputCodeList &ol, const DString &funcName)
static int countLines (yyscan_t yyscanner)
static void writeObjCMethodCall (yyscan_t yyscanner, ObjCCallCtx *ctx)
static DString escapeName (yyscan_t yyscanner, const DString &s)
static DString escapeObject (yyscan_t yyscanner, const DString &s)
static DString escapeWord (yyscan_t yyscanner, const DString &s)
static DString escapeComment (yyscan_t yyscanner, const DString &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, DString type, DString name)
static bool startsWithKeyword (const DString &str, const DString &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 78 of file code.l.

Referenced by setCallContextForVar().

◆ DBG_CTX

◆ INNERBLOCK

#define INNERBLOCK   3

Definition at line 80 of file code.l.

◆ SCOPEBLOCK

#define SCOPEBLOCK   2

Definition at line 79 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:3985

Definition at line 261 of file code.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 76 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.empty()) yyextra->parmType += ' ' ;
2617 yyextra->parmType += yyextra->parmName ;
2618 yyextra->parmName.clear() ;
2619}

References addParmType().

Referenced by addParmType(), and stateToString().

◆ addToSearchIndex()

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

◆ 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.empty()) yyextra->type += ' ' ;
2605 yyextra->type += yyextra->name ;
2606 yyextra->name.clear() ;
2607 if (!yyextra->type.empty()) yyextra->type += ' ' ;
2608 yyextra->type += yyextra->args ;
2609 yyextra->args.clear() ;
2610}

References addType().

Referenced by addType(), and stateToString().

◆ addUsingDirective()

void addUsingDirective ( yyscan_t yyscanner,
const DString & 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.empty())
2626 {
2628 if (nd)
2629 {
2630 yyextra->theUsingContext.emplace(name.str(),nd);
2631 }
2632 }
bool empty() const
Returns true iff the string is empty (std::string compatible alias for isEmpty()).
Definition dstring.h:152
const std::string & str() const
Definition dstring.h:649
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:108
const T * find(const std::string &key) const
Definition linkedmap.h:47
An abstract interface of a namespace symbol.
2633}

References addUsingDirective(), DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), Doxygen::namespaceLinkedMap, and DString::str().

Referenced by addUsingDirective(), and stateToString().

◆ addVariable()

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

Definition at line 2191 of file code.l.

2192{
2193 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2194 DBG_CTX((stderr,"VariableContext::addVariable(%s,%s)\n",qPrint(type),qPrint(name)));
2195 DString ltype = type.simplifyWhiteSpace();
2196 DString lname = name.simplifyWhiteSpace();
2197 ltype.stripPrefix("struct ");
2198 ltype.stripPrefix("union ");
2199 if (ltype.empty() || lname.empty()) return;
2200 ltype = substitute(ltype,".","::");
2201 DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' currentDefinition=%s\n",
2202 qPrint(ltype),qPrint(lname),yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>"));
2203 auto it = yyextra->codeClassMap.find(ltype.str());
2204 if (it!=yyextra->codeClassMap.end()) // look for class definitions inside the code block
2205 {
2206 DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",qPrint(ltype),qPrint(lname)));
2207 yyextra->theVarContext.addVariable(lname,std::move(it->second)); // add it to a list
2208 }
2209 else
2210 {
2211 auto findVariableType = [&yyscanner,&yyg,&ltype,&lname,&name](const Definition *d) -> const ClassDef *
2212 {
2213 const ClassDef *varDef = yyextra->symbolResolver.resolveClass(d,ltype,true);
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 (size_t i=ltype.find('<') ; i!=DString::npos)
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:100
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:88
DString simplifyWhiteSpace() const
return a copy of this string with leading and trailing whitespace removed and multiple internal white...
Definition dstring.cpp:123
static constexpr size_t npos
value used to indicate 'not found' or 'to the end of the string', matching std::string::npos
Definition dstring.h:182
bool stripPrefix(const DString &prefix)
Definition dstring.h:294
The common base class of all entity definitions found in the sources.
Definition definition.h:77
ScopedTypeVariant(GlobalDef d=nullptr)
#define DBG_CTX(x)
Definition code.l:74
static void addVariable(yyscan_t yyscanner, DString type, DString name)
Definition code.l:2191
DString substitute(const DString &s, const DString &src, const DString &dst)
substitute all occurrences of src in s by dst
Definition dstring.cpp:481
const char * qPrint(const char *s)
Definition dstring.h:787
2250}

References addVariable(), DBG_CTX, DString::empty(), DString::npos, qPrint(), ScopedTypeVariant::ScopedTypeVariant(), DString::simplifyWhiteSpace(), DString::str(), DString::stripPrefix(), and substitute().

Referenced by addVariable(), setParameterList(), stateToString(), and stateToString().

◆ 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:45
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 codeFolding(), Config_getBool, Definition::definitionType(), endCodeFold(), Definition::getEndBodyLine(), Definition::getStartDefLine(), MemberDef::isCallable(), MemberDef::isDefine(), toMemberDef(), Definition::TypeClass, and Definition::TypeMember.

Referenced by codeFolding(), codeFolding(), startCodeLine(), startCodeLine(), and substituteHtmlKeywords().

◆ codifyLines()

void codifyLines ( yyscan_t yyscanner,
const DString & 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.empty()) 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(DString(sp,l));
2534 nextCodeLine(yyscanner);
2535 }
2536 else
2537 {
2538 yyextra->code->codify(sp);
2539 done=true;
2540 }
2541 }
DString()=default
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition dstring.h:161
static void nextCodeLine(yyscan_t yyscanner)
Definition code.l:2499
2542}

References codifyLines(), DString::data(), DBG_CTX, DString::DString(), DString::empty(), nextCodeLine(), and qPrint().

Referenced by codifyLines(), codifyLines(), codifyLines(), codifyLines(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateMemberLink(), generatePHPVariableLink(), stateToString(), stateToString(), stateToString(), stateToString(), and writeObjCMethodCall().

◆ countLines()

int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3476 of file code.l.

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

References countLines().

Referenced by countLines(), countLines(), countLines(), countLines(), CCodeParser::parseCode(), stateToString(), stateToString(), stateToString(), and stateToString().

◆ 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 endCodeFold(), and Definition::getEndBodyLine().

Referenced by codeFolding(), endCodeFold(), and stateToString().

◆ 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:3494
2497}

References DBG_CTX, endCodeLine(), and endFontClass().

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

◆ endFontClass()

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

Definition at line 3494 of file code.l.

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

References endFontClass().

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

◆ escapeComment()

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

Definition at line 3925 of file code.l.

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

References escapeComment(), and DString::sprintf().

Referenced by escapeComment(), and stateToString().

◆ escapeName()

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

Definition at line 3895 of file code.l.

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

References escapeName(), and DString::sprintf().

Referenced by escapeName(), and stateToString().

◆ escapeObject()

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

Definition at line 3905 of file code.l.

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

References escapeObject(), and DString::sprintf().

Referenced by escapeObject(), and stateToString().

◆ escapeWord()

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

Definition at line 3915 of file code.l.

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

References escapeWord(), and DString::sprintf().

Referenced by escapeWord(), and stateToString().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3210 of file code.l.

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

References addToSearchIndex(), DBG_CTX, Definition::definitionType(), Definition::findInnerCompound(), generateClassMemberLink(), ClassDef::getMemberByName(), Definition::name(), qPrint(), ScopedTypeVariant::ScopedTypeVariant(), toClassDef(), toNamespaceDef(), Definition::TypeClass, Definition::TypeNamespace, and writeMultiLineCodeLink().

◆ generateClassMemberLink() [2/2]

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

Definition at line 3148 of file code.l.

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

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), MemberDef::argsString(), DBG_CTX, generateClassMemberLink(), MemberDef::getClassDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), Definition::getOuterScope(), Doxygen::globalScope, Definition::isLinkable(), Definition::name(), qPrint(), removeAnonymousScopes(), ScopedTypeVariant::ScopedTypeVariant(), DString::sprintf(), stripClassName(), toMemberDefMutable(), MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by generateClassMemberLink(), generateClassMemberLink(), generateFunctionLink(), generateMemberLink(), and stateToString().

◆ generateClassOrGlobalLink()

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

References addDocCrossReference(), ClassDefMutable::addExample(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), codifyLines(), DBG_CTX, Definition::definitionType(), DString::DString(), DString::empty(), DString::find(), generateClassOrGlobalLink(), ClassDef::getFileDef(), MemberDef::getFileDef(), MemberDef::getGroupDef(), getLink(), Definition::getOuterScope(), getResolvedConcept(), getResolvedNamespace(), FileDef::getUsedNamespaces(), Doxygen::globalScope, ScopedTypeVariant::isDummy(), Definition::isLinkable(), MemberDef::isVariable(), DString::left(), DString::mid(), Definition::name(), ScopedTypeVariant::name(), DString::npos, parent(), qPrint(), ScopedTypeVariant::ScopedTypeVariant(), setCallContextForVar(), DString::sprintf(), substitute(), toClassDef(), toClassDefMutable(), toMemberDef(), toMemberDefMutable(), Definition::TypeClass, Definition::TypeMember, OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

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

◆ generateFunctionLink()

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

Definition at line 3358 of file code.l.

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

References LocalDef::baseClasses(), DBG_CTX, DString::empty(), DString::find(), generateClassMemberLink(), generateClassOrGlobalLink(), generateFunctionLink(), getLink(), DString::left(), ScopedTypeVariant::localDef(), DString::mid(), DString::npos, qPrint(), removeRedundantWhiteSpace(), DString::rfind(), DString::startsWith(), DString::str(), and DString::stripWhiteSpace().

Referenced by generateFunctionLink(), generateFunctionLink(), stateToString(), and stateToString().

◆ generateMemberLink()

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

Definition at line 3253 of file code.l.

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

References addToSearchIndex(), LocalDef::baseClasses(), codifyLines(), DBG_CTX, DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), generateClassMemberLink(), generateMemberLink(), getClass(), getLink(), ScopedTypeVariant::isDummy(), Definition::isLinkable(), DString::left(), ScopedTypeVariant::localDef(), Doxygen::memberNameLinkedMap, DString::mid(), ScopedTypeVariant::name(), DString::npos, qPrint(), DString::rfind(), and stripClassName().

Referenced by generateMemberLink(), and stateToString().

◆ generatePHPVariableLink()

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

Definition at line 3346 of file code.l.

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

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

Referenced by generatePHPVariableLink(), and stateToString().

◆ getLexerFILE()

const char * getLexerFILE ( )
inlinestatic

Definition at line 264 of file code.l.

264{return __FILE__;}

References getLexerFILE().

Referenced by getLexerFILE(), getLexerFILE(), getLexerFILE(), getLexerFILE(), getLexerFILE(), getLexerFILE(), and getLexerFILE().

◆ getLink()

bool getLink ( yyscan_t yyscanner,
const DString & className,
const DString & memberName,
OutputCodeList & ol,
const DString & text = DString(),
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 DString m=removeRedundantWhiteSpace(memberName);
2905 DString c=className;
2906 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2907 {
2908 if (!yyextra->curClassName.empty())
2909 {
2910 if (!c.empty()) 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;
DString & prepend(const char *s)
Definition dstring.h:519
static bool getLinkInScope(yyscan_t yyscanner, const DString &c, const DString &m, const DString &memberText, OutputCodeList &ol, const DString &text, bool varOnly=false)
Definition code.l:2810
2917}

References DBG_CTX, DString::empty(), getLink(), getLinkInScope(), DString::prepend(), qPrint(), and removeRedundantWhiteSpace().

Referenced by generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFunctionLink(), generateFunctionLink(), generateMemberLink(), generatePHPVariableLink(), getLink(), getLink(), stateToString(), and stateToString().

◆ getLinkInScope()

bool getLinkInScope ( yyscan_t yyscanner,
const DString & c,
const DString & m,
const DString & memberText,
OutputCodeList & ol,
const DString & 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 DString 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 DString 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 DString qualifiedName() const =0
virtual bool isVariable() const =0
const MemberDef * md
Definition util.h:95
bool found
Definition util.h:94
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:1868
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 DString getReference() const =0
virtual DString getOutputFileBase() const =0
2884
2885 writeMultiLineCodeLink(yyscanner,ol,result.md, !text.empty() ? text : memberText);
2886 addToSearchIndex(yyscanner,!text.empty() ? 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, DString::empty(), DString::find(), GetDefResult::found, getDefs(), MemberDef::getFileDef(), MemberDef::getGroupDef(), getLinkInScope(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), Doxygen::globalScope, GetDefInput::insideCode, Definition::isLinkable(), MemberDef::isVariable(), ScopedTypeVariant::localDef(), GetDefResult::md, DString::mid(), Definition::name(), qPrint(), Definition::qualifiedName(), MemberDef::resolveAlias(), ScopedTypeVariant::ScopedTypeVariant(), GetDefInput::scopeName, DString::sprintf(), DString::str(), stripClassName(), toMemberDefMutable(), MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by getLink(), getLink(), getLinkInScope(), getLinkInScope(), stateToString(), and stateToString().

◆ 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:132
virtual void incrementFlowKeyWordCount()=0
2556}

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

Referenced by incrementFlowKeyWordCount(), incrementFlowKeyWordCount(), stateToString(), and stateToString().

◆ isCastKeyword()

bool isCastKeyword ( const char * s)
static

Definition at line 3976 of file code.l.

3977{
3978 DString s(keyword);
3979 size_t i=s.find('<');
3980 if (i==DString::npos) return false;
3981 DString kw = s.left(i).stripWhiteSpace();
3982 return kw=="const_cast" || kw=="static_cast" || kw=="dynamic_cast" || kw=="reinterpret_cast";
3983}

References DString::find(), isCastKeyword(), DString::left(), DString::npos, and DString::stripWhiteSpace().

Referenced by isCastKeyword().

◆ 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(), nextCodeLine(), and startCodeLine().

Referenced by codifyLines(), codifyLines(), codifyLines(), codifyLines(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), stateToString(), stateToString(), stateToString(), stateToString(), 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, popScope(), and qPrint().

Referenced by popScope(), setClassScope(), and stateToString().

◆ pushScope()

void pushScope ( yyscan_t yyscanner,
const DString & 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.empty() || 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 DString &scope, const DString &name)
Definition util.cpp:742
2269}

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

Referenced by pushScope(), setClassScope(), and stateToString().

◆ restoreObjCContext()

void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4032 of file code.l.

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

References DBG_CTX, and restoreObjCContext().

Referenced by restoreObjCContext(), and stateToString().

◆ saveObjCContext()

void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 4001 of file code.l.

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

References DBG_CTX, DString::DString(), qPrint(), and saveObjCContext().

Referenced by saveObjCContext(), and stateToString().

◆ setCallContextForVar()

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

Definition at line 2683 of file code.l.

2684{
2685 if (name.empty()) 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 size_t scopeEnd = name.rfind("::");
2690 if (scopeEnd!=DString::npos) // name with explicit scope
2691 {
2692 DString scope = name.left(scopeEnd);
2693 DString locName = name.mid(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.empty())
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.empty())
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 DString &) 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:78
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:105
Ptr & front()
Definition membername.h:49
size_t size() const
Definition membername.h:46
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, DString::empty(), LinkedMap< T, Hash, KeyEqual, Map >::find(), MemberName::front(), Doxygen::functionNameLinkedMap, getClass(), ClassDef::getMemberByName(), NamespaceDef::getMemberByName(), Definition::getOuterScope(), getResolvedNamespace(), ScopedTypeVariant::isDummy(), DString::left(), DString::mid(), Definition::name(), ScopedTypeVariant::name(), DString::npos, qPrint(), DString::rfind(), ScopedTypeVariant::ScopedTypeVariant(), setCallContextForVar(), MemberName::size(), stripClassName(), and MemberDef::typeString().

Referenced by generateClassOrGlobalLink(), setCallContextForVar(), and stateToString().

◆ setClassScope()

void setClassScope ( yyscan_t yyscanner,
const DString & 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 DString n=name;
2318 n=n.simplifyWhiteSpace();
2319 size_t ts=n.find('<'); // start of template
2320 size_t te=n.rfind('>'); // end of template
2321 DBG_CTX((stderr,"ts=%zu te=%zu\n",ts,te));
2322 if (ts!=DString::npos && te!=DString::npos && te>ts)
2323 {
2324 // remove template from scope
2325 n=n.left(ts)+n.mid(te+1);
2326 }
2327 while (!yyextra->scopeNameLengthStack.empty())
2328 {
2329 popScope(yyscanner);
2330 }
2331 yyextra->scopeName.clear();
2332 size_t i;
2333 while ((i=n.find("::"))!=DString::npos)
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 DString &s)
Definition code.l:2255
static void popScope(yyscan_t yyscanner)
Definition code.l:2273
2340}

References DBG_CTX, DString::find(), DString::left(), DString::mid(), DString::npos, popScope(), pushScope(), qPrint(), DString::rfind(), setClassScope(), and DString::simplifyWhiteSpace().

Referenced by setClassScope(), and stateToString().

◆ setCurrentDoc()

void setCurrentDoc ( yyscan_t yyscanner,
const DString & 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 DString &anchor, bool isSourceFile)
2303}

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

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

◆ 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 size_t i = yyextra->parmType.find('*');
2643 if (i!=DString::npos) yyextra->parmType = yyextra->parmType.left(i);
2644 i = yyextra->parmType.find('&');
2645 if (i!=DString::npos) 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 }
This class contains the information about the argument of a function or template.
Definition arguments.h:27
virtual const ArgumentList & argumentList() const =0
2650}

References addVariable(), MemberDef::argumentList(), DString::npos, and setParameterList().

Referenced by CCodeParser::parseCode(), setParameterList(), and stateToString().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3935 of file code.l.

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

References skipLanguageSpecificKeyword().

Referenced by skipLanguageSpecificKeyword(), and stateToString().

◆ 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 //DString 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 DString 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 DString(),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(DString(),DString(),DString(),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 }
void clear()
Definition dstring.h:218
virtual bool isLinkableInProject() const =0
static void setCurrentDoc(yyscan_t yyscanner, const DString &anchor)
Definition code.l:2289
static void codeFolding(yyscan_t yyscanner, const Definition *d)
Definition code.l:2363
2486}

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

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

◆ startFontClass()

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

Definition at line 3509 of file code.l.

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

References endFontClass(), and startFontClass().

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

◆ startsWithKeyword()

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

Definition at line 2184 of file code.l.

2185{
2186 if (str.length()<kw.length()) return false; // string too short to match
2187 return str==kw || // exact match
2188 (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 dstring.h:690
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition dstring.h:155
bool isId(int c)
Returns true if c is a valid character for an identifier.
Definition dstring.h:899
2189}

References DString::at(), isId(), DString::length(), DString::startsWith(), and startsWithKeyword().

Referenced by startsWithKeyword(), and stateToString().

◆ stateToString()

◆ stripClassName()

const ClassDef * stripClassName ( yyscan_t yyscanner,
const DString & 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 DString type = s;
2659 DString className;
2660 DString templSpec;
2661 while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
2662 {
2663 DString clName=className+templSpec;
2664 const ClassDef *cd=nullptr;
2665 if (!yyextra->scopeName.empty())
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 DString &type, int &pos, DString &name, DString &templSpec, SrcLangExt lang)
Definition util.cpp:3382
2679
2680 return nullptr;
2681}

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

Referenced by generateClassMemberLink(), generateClassOrGlobalLink(), generateMemberLink(), getLinkInScope(), getLinkInScope(), setCallContextForVar(), stateToString(), stateToString(), stripClassName(), stripClassName(), 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(), ScopedTypeVariant::ScopedTypeVariant(), stripClassName(), toClassDef(), Definition::TypeClass, MemberDef::typeString(), and updateCallContextForSmartPointer().

Referenced by stateToString(), and updateCallContextForSmartPointer().

◆ writeMultiLineCodeLink()

void writeMultiLineCodeLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const Definition * d,
const DString & 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 DString ref = d->getReference();
2570 DString file = d->getOutputFileBase();
2571 DString anchor = d->anchor();
2572 DString 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(DString(sp,p-sp-1))));
2588 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,DString(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 DString briefDescriptionAsTooltip() const =0
virtual DString anchor() const =0
virtual CodeSymbolType codeSymbolType() const =0
void writeCodeLink(CodeSymbolType type, const DString &ref, const DString &file, const DString &anchor, const DString &name, const DString &tooltip)
Definition outputlist.h:247
2598}

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

Referenced by findMemberLink(), generateClassMemberLink(), generateClassMemberLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), getLinkInScope(), getLinkInScope(), stateToString(), stateToString(), writeMultiLineCodeLink(), writeMultiLineCodeLink(), and writeObjCMethodCall().

◆ writeObjCMethodCall()

void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3525 of file code.l.

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

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

Referenced by stateToString(), and writeObjCMethodCall().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 379 of file code.l.

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

Referenced by convertCppComments().

◆ yyread()

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

Definition at line 3985 of file code.l.

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

References yyread().

Referenced by stateToString(), stateToString(), stateToString(), stateToString(), stateToString(), stateToString(), stateToString(), yyread(), yyread(), yyread(), yyread(), yyread(), yyread(), and yyread().