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

Go to the source code of this file.

Classes

struct  ObjCCallCtx
 
struct  codeYY_state
 
struct  CCodeParser::Private
 

Macros

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

Typedefs

typedef yyguts_t * yyscan_t
 

Functions

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

Macro Definition Documentation

◆ CLASSBLOCK

#define CLASSBLOCK   1

Definition at line 77 of file code.l.

Referenced by setCallContextForVar().

◆ DBG_CTX

◆ INNERBLOCK

#define INNERBLOCK   3

Definition at line 79 of file code.l.

◆ SCOPEBLOCK

#define SCOPEBLOCK   2

Definition at line 78 of file code.l.

◆ YY_INPUT

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

Definition at line 265 of file code.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 75 of file code.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 22 of file code.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 24 of file code.l.

Function Documentation

◆ addParmType()

static void addParmType ( yyscan_t yyscanner)
static

Definition at line 2615 of file code.l.

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

◆ addToSearchIndex() [1/2]

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

Definition at line 2304 of file code.l.

2305{
2306 addToSearchIndex(yyscanner,QCString(text));
This is an alternative implementation of QCString.
Definition qcstring.h:101
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition code.l:2296
2307}

References addToSearchIndex().

◆ addToSearchIndex() [2/2]

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

◆ addType()

static void addType ( yyscan_t yyscanner)
static

Definition at line 2603 of file code.l.

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

◆ addUsingDirective()

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

Definition at line 2624 of file code.l.

2625{
2626 //printf("AddUsingDirective(%s)\n",qPrint(name));
2627 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2628 if (yyextra->sourceFileDef && !name.isEmpty())
2629 {
2630 const NamespaceDef *nd = Doxygen::namespaceLinkedMap->find(name);
2631 if (nd)
2632 {
2633 yyextra->theUsingContext.emplace(name.str(),nd);
2634 }
2635 }
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
An abstract interface of a namespace symbol.
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
2636}

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

◆ addVariable()

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

Definition at line 2181 of file code.l.

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

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

Referenced by addVariable(), and setParameterList().

◆ codeFolding()

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

Definition at line 2360 of file code.l.

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

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

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

◆ codifyLines() [1/2]

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

Definition at line 2542 of file code.l.

2543{
2544 codifyLines(yyscanner,QCString(text));
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition code.l:2514
2545}

References codifyLines().

◆ codifyLines() [2/2]

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

write a code fragment 'text' that may span multiple lines, inserting line numbers for each line.

Definition at line 2514 of file code.l.

2515{
2516 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2517 DBG_CTX((stderr,"codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,qPrint(text)));
2518 if (text.isEmpty()) return;
2519 const char *p=text.data(),*sp=p;
2520 char c;
2521 bool done=FALSE;
2522 while (!done)
2523 {
2524 sp=p;
2525 while ((c=*p++) && c!='\n');
2526 if (c=='\n')
2527 {
2528 yyextra->yyLineNr++;
2529 size_t l = static_cast<size_t>(p-sp-1);
2530 std::string tmp(sp,l);
2531 yyextra->code->codify(tmp.c_str());
2532 nextCodeLine(yyscanner);
2533 }
2534 else
2535 {
2536 yyextra->code->codify(QCString(sp));
2537 done=TRUE;
2538 }
2539 }
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
static void nextCodeLine(yyscan_t yyscanner)
Definition code.l:2496
#define TRUE
Definition qcstring.h:37
2540}

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

Referenced by codifyLines(), codifyMapLines(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateClassOrGlobalLink(), generateFuncLink(), generateLink(), generateMemberLink(), generateMemLink(), generatePHPVariableLink(), handleCCode(), writeFuncProto(), writeObjCMethodCall(), and writeProcessProto().

◆ countLines()

static int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 3480 of file code.l.

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

Referenced by CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ endCodeFold()

static void endCodeFold ( yyscan_t yyscanner)
static

Definition at line 2339 of file code.l.

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

References Definition::getEndBodyLine().

Referenced by codeFolding().

◆ endCodeLine()

static void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 2487 of file code.l.

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

References DBG_CTX, and endFontClass().

Referenced by nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ endFontClass()

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

Definition at line 3498 of file code.l.

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

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

◆ escapeComment()

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

Definition at line 3929 of file code.l.

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

References QCString::sprintf().

◆ escapeName()

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

Definition at line 3899 of file code.l.

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

References QCString::sprintf().

◆ escapeObject()

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

Definition at line 3909 of file code.l.

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

References QCString::sprintf().

◆ escapeWord()

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

Definition at line 3919 of file code.l.

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

References QCString::sprintf().

◆ generateClassMemberLink() [1/2]

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

Definition at line 3216 of file code.l.

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

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

◆ generateClassMemberLink() [2/2]

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

Definition at line 3154 of file code.l.

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

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

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

◆ generateClassOrGlobalLink() [1/2]

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

Definition at line 3148 of file code.l.

3150{
3151 generateClassOrGlobalLink(yyscanner,ol,QCString(clName),typeOnly,varOnly);
static void generateClassOrGlobalLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE, bool varOnly=FALSE)
Definition code.l:2922
3152}

References generateClassOrGlobalLink().

◆ generateClassOrGlobalLink() [2/2]

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

Definition at line 2922 of file code.l.

2927{
2928 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2929 QCString scopeName=scName;
2930 if (!scopeName.isEmpty() && scopeName[0]=='~') // correct for matching negated values i.s.o. destructors.
2931 {
2932 scopeName=scopeName.mid(1);
2933 }
2934 if (scopeName.isEmpty())
2935 {
2936 yyextra->code->codify("~");
2937 return;
2938 }
2939 if (yyextra->insideProtocolList) // for Obj-C
2940 {
2941 scopeName+="-p";
2942 }
2943 if (yyextra->lang==SrcLangExt::PHP)
2944 {
2945 scopeName = substitute(scopeName,"\\","::"); // for PHP namespaces
2946 }
2947 else if (yyextra->lang==SrcLangExt::CSharp || yyextra->lang==SrcLangExt::Java)
2948 {
2949 scopeName = substitute(scopeName,".","::"); // for C#/Java namespaces
2950 }
2951 if (yyextra->currentDefinition==nullptr && !yyextra->scopeName.isEmpty())
2952 {
2953 scopeName = yyextra->scopeName+"::"+scopeName;
2954 }
2955 const ScopedTypeVariant *lcd=nullptr;
2956 const Definition *sym=nullptr;
2957 bool isLocal=FALSE;
QCString mid(size_t index, size_t len=static_cast< size_t >(-1)) const
Definition qcstring.h:226
@ CSharp
Definition types.h:46
2958
2959 DBG_CTX((stderr,"generateClassOrGlobalLink(name=%s) yyextra->scopeName=%s scopeName=%s\n",qPrint(scName),qPrint(yyextra->scopeName),qPrint(scopeName)));
2960 if (!yyextra->isPrefixedWithThis || (lcd=yyextra->theVarContext.findVariable(scopeName))==nullptr) // not a local variable
2961 {
2962 int i=scopeName.find('<');
2963 QCString bareName = scopeName;
2964 if (i!=-1) bareName = bareName.left(i);
int find(char c, int index=0, bool cs=TRUE) const
Definition qcstring.cpp:43
QCString left(size_t len) const
Definition qcstring.h:214
2965
2966 auto checkForSymbol = [&yyg,&bareName,&scopeName](const Definition *parent,
2967 const Definition *&sym_)
2968 {
2969 sym_ = yyextra->symbolResolver.resolveSymbol(parent,scopeName,QCString(),false,true);
2970 DBG_CTX((stderr,"non-local variable name=%s sym=%s!\n",
2971 qPrint(scopeName),sym_?qPrint(sym_->name()):"<none>"));
2972 if (sym_==nullptr && !bareName.isEmpty())
2973 {
2974 DBG_CTX((stderr,"bareName=%s\n",qPrint(bareName)));
2975 if (bareName!=scopeName)
2976 {
2977 sym_ = yyextra->symbolResolver.resolveSymbol(parent,bareName,QCString(),false,true); // try unspecialized version
2978 }
2979 }
2980 };
2981 const Definition *d = yyextra->currentDefinition;
2982 DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",d?qPrint(d->name()):"<none>",yyextra->sourceFileDef?qPrint(yyextra->sourceFileDef->name()):"<none>"));
2983 checkForSymbol(d,sym);
2984 if (sym==nullptr && d && d->definitionType()==Definition::TypeClass)
2985 {
2986 const FileDef *fd = toClassDef(d)->getFileDef();
2987 if (fd)
2988 {
2989 // also check for using directive in the file that defines this class
2990 for (const auto &nd : fd->getUsedNamespaces())
2991 {
2992 checkForSymbol(nd,sym);
2993 if (sym) break;
2994 }
2995 }
2996 }
2997 if (sym==nullptr)
2998 {
2999 // also check via using directive
3000 for (const auto &[usingName,namespaceDef] : yyextra->theUsingContext)
3001 {
3002 checkForSymbol(namespaceDef,sym);
3003 if (sym) break;
3004 }
3005 }
virtual FileDef * getFileDef() const =0
Returns the namespace this compound is in, or 0 if it has a global scope.
A model of a file symbol.
Definition filedef.h:99
virtual const LinkedRefMap< NamespaceDef > & getUsedNamespaces() const =0
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
Definition docnode.h:1324
3006
3007 const NamespaceDef *nd = getResolvedNamespace(scopeName);
3008 if (nd && nd->isLinkable())
3009 {
3010 yyextra->theCallContext.setScope(ScopedTypeVariant(nd));
3011 addToSearchIndex(yyscanner,scopeName);
3012 writeMultiLineCodeLink(yyscanner,*yyextra->code,nd,scName);
3013 return;
3014 }
3015 const ConceptDef *conceptDef = getResolvedConcept(d,bareName);
3016 if (conceptDef && conceptDef->isLinkable())
3017 {
3018 yyextra->theCallContext.setScope(ScopedTypeVariant(conceptDef));
3019 addToSearchIndex(yyscanner,scopeName);
3020 writeMultiLineCodeLink(yyscanner,*yyextra->code,conceptDef,scName);
3021 return;
3022 }
3023 DBG_CTX((stderr,"sym=%s\n",sym?qPrint(sym->name()):"<none>"));
3024 DBG_CTX((stderr,"is found as a type sym=%s nd=%s\n",
3025 sym?qPrint(sym->name()):"<null>",
3026 nd?qPrint(nd->name()):"<null>"));
3027 if (sym==nullptr) // also see if it is variable or enum or enum value
3028 {
3029 if (getLink(yyscanner,yyextra->scopeName,scName,ol,scName,varOnly))
3030 {
3031 return;
3032 }
3033 }
3034 }
3035 else
3036 {
3037 DBG_CTX((stderr,"local variable!\n"));
3038 if (!lcd->isDummy())
3039 {
3040 DBG_CTX((stderr,"non-dummy context lcd=%s!\n",qPrint(lcd->name())));
3041 yyextra->theCallContext.setScope(*lcd);
QCString name() const
static bool getLink(yyscan_t yyscanner, const QCString &className, const QCString &memberName, OutputCodeList &ol, const QCString &text=QCString(), bool varOnly=FALSE)
Definition code.l:2897
ConceptDef * getResolvedConcept(const Definition *d, const QCString &name)
NamespaceDef * getResolvedNamespace(const QCString &name)
3042
3043 // to following is needed for links to a global variable, but is
3044 // no good for a link to a local variable that is also a global symbol.
3045
3046 //if (getLink(yyscanner,yyextra->scopeName,scName,ol,scName))
3047 //{
3048 //return;
3049 //}
3050 }
3051 isLocal=TRUE;
3052 DBG_CTX((stderr,"is a local variable sym=%p!\n",(void*)sym));
3053 }
3054 yyextra->isPrefixedWithThis = FALSE; // discard the "this" prefix for the next calls
3055
3056 if (sym && sym->isLinkable()) // is it a linkable class
3057 {
3058 DBG_CTX((stderr,"is linkable class %s\n",qPrint(scName)));
3059 if (yyextra->exampleBlock)
3060 {
3061 std::lock_guard<std::mutex> lock(Doxygen::addExampleMutex);
3062 QCString anchor;
3063 anchor.sprintf("_a%d",yyextra->anchorCount);
3064 DBG_CTX((stderr,"addExampleClass(%s,%s,%s)\n",qPrint(anchor),qPrint(yyextra->exampleName),
3065 qPrint(yyextra->exampleFile)));
3067 {
3068 ClassDefMutable *cdm = toClassDefMutable(const_cast<Definition*>(sym));
3069 if (cdm && cdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
3070 {
3071 ol.writeCodeAnchor(anchor);
3072 yyextra->anchorCount++;
3073 }
3074 }
3075 else if (sym->definitionType()==Definition::TypeMember)
3076 {
3077 MemberDefMutable *mdm = toMemberDefMutable(const_cast<Definition*>(sym));
3078 if (mdm && mdm->addExample(anchor,yyextra->exampleName,yyextra->exampleFile))
3079 {
3080 ol.writeCodeAnchor(anchor);
3081 yyextra->anchorCount++;
3082 }
3083 }
3084 }
3085 writeMultiLineCodeLink(yyscanner,ol,sym,scName);
3086 addToSearchIndex(yyscanner,scopeName);
3087 yyextra->theCallContext.setScope(ScopedTypeVariant(sym));
3088 if (sym && sym->definitionType()==Definition::TypeMember)
3089 {
3090 const MemberDef *md = toMemberDef(sym);
3091 const Definition *d = sym->getOuterScope()==Doxygen::globalScope ?
3092 md->getFileDef() : md->getOuterScope();
3093 if (md->getGroupDef()) d = md->getGroupDef();
3094 if (d && d->isLinkable() && md->isLinkable() &&
3095 yyextra->currentMemberDef && yyextra->collectXRefs)
3096 {
3097 addDocCrossReference(yyextra->currentMemberDef,md);
3098 }
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 QCString &anchor, const QCString &name, const QCString &file)=0
ClassDefMutable * toClassDefMutable(Definition *d)
static const MemberDef * setCallContextForVar(yyscan_t yyscanner, const QCString &name)
Definition code.l:2686
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 }
3146}

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

Referenced by codifyMapLines(), generateClassOrGlobalLink(), generateFunctionLink(), generateFunctionLink(), and writeWord().

◆ generateFunctionLink() [1/2]

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

Definition at line 3474 of file code.l.

3475{
3476 generateFunctionLink(yyscanner,ol,QCString(funcName));
static void generateFunctionLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
Definition code.l:3365
3477}

References generateFunctionLink().

◆ generateFunctionLink() [2/2]

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

Definition at line 3365 of file code.l.

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

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

Referenced by generateFunctionLink().

◆ generateMemberLink()

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

Definition at line 3259 of file code.l.

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

References addToSearchIndex(), LocalDef::baseClasses(), codifyLines(), DBG_CTX, QCString::findRev(), generateClassMemberLink(), getClass(), getLink(), ScopedTypeVariant::isDummy(), QCString::isEmpty(), Definition::isLinkable(), QCString::left(), QCString::length(), ScopedTypeVariant::localDef(), Doxygen::memberNameLinkedMap, ScopedTypeVariant::name(), qPrint(), QCString::right(), and stripClassName().

◆ generatePHPVariableLink()

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

Definition at line 3353 of file code.l.

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

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

◆ getLexerFILE()

static const char * getLexerFILE ( )
inlinestatic

Definition at line 268 of file code.l.

268{return __FILE__;}

◆ getLink()

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

Definition at line 2897 of file code.l.

2903{
2904 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2905 DBG_CTX((stderr,"getLink(%s,%s) yyextra->curClassName=%s\n",
2906 qPrint(className),qPrint(memberName),qPrint(yyextra->curClassName)));
2907 QCString m=removeRedundantWhiteSpace(memberName);
2908 QCString c=className;
2909 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly))
2910 {
2911 if (!yyextra->curClassName.isEmpty())
2912 {
2913 if (!c.isEmpty()) c.prepend("::");
2914 c.prepend(yyextra->curClassName);
2915 return getLinkInScope(yyscanner,c,m,memberName,ol,text,varOnly);
2916 }
2917 return FALSE;
2918 }
2919 return TRUE;
QCString & prepend(const char *s)
Definition qcstring.h:407
static bool getLinkInScope(yyscan_t yyscanner, const QCString &c, const QCString &m, const QCString &memberText, OutputCodeList &ol, const QCString &text, bool varOnly=FALSE)
Definition code.l:2813
2920}

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

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

◆ getLinkInScope()

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

Definition at line 2813 of file code.l.

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

References addDocCrossReference(), MemberDefMutable::addExample(), Doxygen::addExampleMutex, addToSearchIndex(), LocalDef::baseClasses(), GetDefInput::currentFile, DBG_CTX, FALSE, QCString::find(), GetDefResult::found, getDefs(), MemberDef::getFileDef(), MemberDef::getGroupDef(), Definition::getOuterScope(), Definition::getOutputFileBase(), Definition::getReference(), Doxygen::globalScope, GetDefInput::insideCode, QCString::isEmpty(), Definition::isLinkable(), MemberDef::isVariable(), ScopedTypeVariant::localDef(), GetDefResult::md, QCString::mid(), Definition::name(), qPrint(), Definition::qualifiedName(), MemberDef::resolveAlias(), GetDefInput::scopeName, QCString::sprintf(), QCString::str(), stripClassName(), toMemberDefMutable(), TRUE, MemberDef::typeString(), OutputCodeList::writeCodeAnchor(), and writeMultiLineCodeLink().

Referenced by getLink(), and getLink().

◆ incrementFlowKeyWordCount()

static void incrementFlowKeyWordCount ( yyscan_t yyscanner)
static

Definition at line 2547 of file code.l.

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

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

◆ isCastKeyword()

static bool isCastKeyword ( const char * s)
static

Definition at line 3980 of file code.l.

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

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

◆ nextCodeLine()

static void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 2496 of file code.l.

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

References endCodeLine(), and startCodeLine().

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

◆ popScope()

static void popScope ( yyscan_t yyscanner)
static

remove the top class/namespace name from the scope

Definition at line 2264 of file code.l.

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

References DBG_CTX, and qPrint().

Referenced by setClassScope().

◆ pushScope()

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

add class/namespace name s to the scope

Definition at line 2246 of file code.l.

2247{
2248 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
2249 yyextra->scopeNameLengthStack.push_back(int(yyextra->scopeName.length()));
2250 if (yyextra->scopeName.isEmpty() || leftScopeMatch(s,yyextra->scopeName))
2251 {
2252 yyextra->scopeName = s;
2253 }
2254 else
2255 {
2256 yyextra->scopeName += "::";
2257 yyextra->scopeName += s;
2258 }
2259 DBG_CTX((stderr,"pushScope(%s) result: '%s'\n",qPrint(s),qPrint(yyextra->scopeName)));
bool leftScopeMatch(const QCString &scope, const QCString &name)
Definition util.cpp:892
2260}

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

Referenced by setClassScope().

◆ restoreObjCContext()

static void restoreObjCContext ( yyscan_t yyscanner)
static

Definition at line 4036 of file code.l.

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

References DBG_CTX.

◆ saveObjCContext()

static void saveObjCContext ( yyscan_t yyscanner)
static

Definition at line 4005 of file code.l.

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

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

◆ setCallContextForVar()

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

Definition at line 2686 of file code.l.

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

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

Referenced by generateClassOrGlobalLink().

◆ setClassScope()

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

Definition at line 2310 of file code.l.

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

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

◆ setCurrentDoc()

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

Definition at line 2280 of file code.l.

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

References FALSE, Doxygen::searchIndex, and TRUE.

Referenced by CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), XMLCodeParser::parseCode(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), startCodeLine(), and startCodeLine().

◆ setParameterList()

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

Definition at line 2638 of file code.l.

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

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

Referenced by CCodeParser::parseCode().

◆ skipLanguageSpecificKeyword()

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

Definition at line 3939 of file code.l.

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

References Cpp, and Java.

◆ startCodeLine()

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

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

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

Referenced by nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), nextCodeLine(), CCodeParser::parseCode(), FortranCodeParser::parseCode(), LexCodeParser::parseCode(), PythonCodeParser::parseCode(), SQLCodeParser::parseCode(), VHDLCodeParser::parseCode(), and XMLCodeParser::parseCode().

◆ startFontClass()

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

Definition at line 3513 of file code.l.

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

References endFontClass().

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

◆ startsWithKeyword()

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

Definition at line 2174 of file code.l.

2175{
2176 if (str.length()<kw.length()) return false; // string too short to match
2177 return str==kw || // exact match
2178 (str.startsWith(kw) && !isId(str.at(kw.length()))); // match that is not a substring
char & at(size_t i)
Returns a reference to the character at index i.
Definition qcstring.h:578
bool isId(int c)
Definition util.h:206
2179}

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

◆ stateToString()

static const char * stateToString ( int state)
static

References FALSE.

Referenced by scanner_abort().

◆ stripClassName()

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

Definition at line 2655 of file code.l.

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

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

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

◆ updateCallContextForSmartPointer()

static void updateCallContextForSmartPointer ( yyscan_t yyscanner)
static

Definition at line 2796 of file code.l.

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

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

◆ writeMultiLineCodeLink()

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

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

Definition at line 2565 of file code.l.

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

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

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

◆ writeObjCMethodCall()

static void writeObjCMethodCall ( yyscan_t yyscanner,
ObjCCallCtx * ctx )
static

Definition at line 3529 of file code.l.

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

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

Referenced by writeObjCMethodCall().

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 382 of file code.l.

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

◆ yyread()

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

Definition at line 3989 of file code.l.

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