Doxygen
Loading...
Searching...
No Matches
pycode.l File Reference
#include <stdint.h>
#include <vector>
#include <unordered_map>
#include <string>
#include <stack>
#include <stdio.h>
#include "pycode.h"
#include "message.h"
#include "scanner.h"
#include "entry.h"
#include "doxygen.h"
#include "outputlist.h"
#include "util.h"
#include "membername.h"
#include "searchindex.h"
#include "config.h"
#include "groupdef.h"
#include "classlist.h"
#include "filedef.h"
#include "namespacedef.h"
#include "tooltip.h"
#include "scopedtypevariant.h"
#include "symbolresolver.h"
#include "debug.h"
#include "doxygen_lex.h"
#include "pycode.l.h"
+ Include dependency graph for pycode.l:

Go to the source code of this file.

Classes

struct  pycodeYY_state
 
struct  PythonCodeParser::Private
 

Macros

#define YY_TYPEDEF_YY_SCANNER_T
 
#define DBG_CTX(x)
 
#define YY_NO_INPUT   1
 
#define YY_NO_UNISTD_H   1
 
#define YY_INPUT(buf, result, max_size)
 

Typedefs

typedef yyguts_t * yyscan_t
 

Functions

static const char * stateToString (int state)
 
static void startCodeLine (yyscan_t yyscanner)
 
static int countLines (yyscan_t yyscanner)
 
static void setCurrentDoc (yyscan_t yyscanner, const QCString &anchor)
 
static void addToSearchIndex (yyscan_t yyscanner, const QCString &text)
 
static const ClassDefstripClassName (yyscan_t yyscanner, const QCString &s, Definition *d)
 
static void codify (yyscan_t yyscanner, const QCString &text)
 
static void endCodeLine (yyscan_t yyscanner)
 
static void nextCodeLine (yyscan_t yyscanner)
 
static void writeMultiLineCodeLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const QCString &text)
 
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 bool getLinkInScope (yyscan_t yyscanner, const QCString &c, const QCString &m, const QCString &memberText, OutputCodeList &ol, const QCString &text)
 
static bool getLink (yyscan_t yyscanner, const QCString &className, const QCString &memberName, OutputCodeList &ol, const QCString &text=QCString())
 
static void generateClassOrGlobalLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE)
 
static void generateFunctionLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
 
static bool findMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const Definition *sym, const QCString &symName)
 
static void findMemberLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &symName)
 
static void incrementFlowKeyWordCount (yyscan_t yyscanner)
 
static void adjustScopesAndSuites (yyscan_t yyscanner, unsigned indentLength)
 
static int yyread (yyscan_t yyscanner, char *buf, int max_size)
 
static void pop_state (yyscan_t yyscanner)
 
static const char * getLexerFILE ()
 
int yylex (yyscan_t yyscanner)
 
static void codeFolding (yyscan_t yyscanner, const Definition *d)
 

Macro Definition Documentation

◆ DBG_CTX

#define DBG_CTX ( x)
Value:
do { } while(0)

Definition at line 65 of file pycode.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 pycode.l:771

Definition at line 160 of file pycode.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 67 of file pycode.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 68 of file pycode.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T

Definition at line 30 of file pycode.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 32 of file pycode.l.

Function Documentation

◆ addToSearchIndex()

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

Definition at line 862 of file pycode.l.

863{
864 if (Doxygen::searchIndex.enabled())
865 {
866 Doxygen::searchIndex.addWord(text,FALSE);
867 }
static SearchIndexIntf searchIndex
Definition doxygen.h:124
#define FALSE
Definition qcstring.h:34
868}

References FALSE, and Doxygen::searchIndex.

◆ adjustScopesAndSuites()

static void adjustScopesAndSuites ( yyscan_t yyscanner,
unsigned indentLength )
static

Examines current stack of white-space indentations; re-syncs the parser with the correct scope.

Definition at line 792 of file pycode.l.

793{
794 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
795 // States to pop
796 if (!yyextra->indents.empty() && indentLength < yyextra->indents.top())
797 {
798 while (!yyextra->indents.empty() && indentLength < yyextra->indents.top())
799 {
800 // printf("Exited scope indent of [%d]\n", yyextra->indents.top());
801 yyextra->indents.pop(); // Pop the old suite's indentation
802
803 yyextra->currentMemberDef=nullptr;
804 if (yyextra->currentDefinition)
805 yyextra->currentDefinition=yyextra->currentDefinition->getOuterScope();
806 }
807 }
808
809 // Are there any remaining indentation levels for suites?
810 if (!yyextra->indents.empty())
811 {
812 BEGIN( Suite );
813 }
814 else
815 {
816 BEGIN( Body );
817 }
818}

◆ codeFolding()

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

Definition at line 901 of file pycode.l.

902{
903 if (Config_getBool(HTML_CODE_FOLDING))
904 {
905 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
906 while (!yyextra->foldStack.empty())
907 {
908 const Definition *dd = yyextra->foldStack.back();
909 if (dd->getEndBodyLine()+1==yyextra->yyLineNr) // +1 to close the section after the end of the body
910 {
911 yyextra->code->endFold();
912 //printf("%d: end codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(dd->name()),dd->getStartDefLine(),dd->getEndBodyLine());
913 yyextra->foldStack.pop_back();
914 }
915 else
916 {
917 break;
918 }
919 }
920 if (d)
921 {
922 int startLine = d->getStartDefLine();
923 int endLine = d->getEndBodyLine();
924 if (endLine!=-1 && startLine!=endLine &&
925 // since the end of a section is closed after the last line, we need to avoid starting a
926 // new section if the previous section ends at the same line, i.e. something like
927 // struct X {
928 // ...
929 // }; struct S { <- start of S and end of X at the same line
930 // ...
931 // };
932 (yyextra->foldStack.empty() || yyextra->foldStack.back()->getEndBodyLine()!=startLine))
933 {
934 //printf("%d: start codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->name()),d->getStartDefLine(),d->getEndBodyLine());
935 yyextra->code->startFold(yyextra->yyLineNr,"", "");
936 yyextra->foldStack.push_back(d);
937 }
938 }
939 }
The common base class of all entity definitions found in the sources.
Definition definition.h:76
virtual int getEndBodyLine() const =0
virtual int getStartDefLine() const =0
#define Config_getBool(name)
Definition config.h:33
940}

References Config_getBool, Definition::getEndBodyLine(), and Definition::getStartDefLine().

◆ codify()

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

Definition at line 1016 of file pycode.l.

1017{
1018 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1019 yyextra->code->codify(text);
1020}

Referenced by findMemberLink().

◆ codifyLines()

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

Definition at line 1133 of file pycode.l.

1134{
1135 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1136 if (text.isEmpty()) return;
1137 //printf("codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,text);
1138 const char *p=text.data(),*sp=p;
1139 char c=0;
1140 bool done=FALSE;
1141 while (!done)
1142 {
1143 sp=p;
1144 while ((c=*p++) && c!='\n') { }
1145 if (c=='\n')
1146 {
1147 yyextra->yyLineNr++;
1148 size_t l = static_cast<size_t>(p-sp-1);
1149 std::string tmp(sp,l);
1150 yyextra->code->codify(tmp.c_str());
1151 nextCodeLine(yyscanner);
1152 }
1153 else
1154 {
1155 yyextra->code->codify(sp);
1156 done=TRUE;
1157 }
1158 }
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
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 pycode.l:1034
#define TRUE
Definition qcstring.h:37
1159}

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

◆ countLines()

static int countLines ( yyscan_t yyscanner)
static

counts the number of lines in the input

Definition at line 823 of file pycode.l.

824{
825 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
826 const char *p=yyextra->inputString;
827 char c=0;
828 int count=1;
829 while ((c=*p))
830 {
831 p++;
832 if (c=='\n') count++;
833 }
834 if (p>yyextra->inputString && *(p-1)!='\n')
835 { // last line does not end with a \n, so we add an extra
836 // line and explicitly terminate the line after parsing.
837 count++;
838 }
839 return count;
840}

◆ endCodeLine()

static void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 1024 of file pycode.l.

1025{
1026 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1027 endFontClass(yyscanner);
1028 yyextra->code->endCodeLine();
1029 yyextra->insideCodeLine=false;
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
Definition pycode.l:1116
1030}

References endFontClass().

◆ endFontClass()

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

Definition at line 1116 of file pycode.l.

1117{
1118 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1119 if (yyextra->currentFontClass)
1120 {
1121 yyextra->code->endFontClass();
1122 yyextra->currentFontClass=nullptr;
1123 }
1124 if (specialComment && yyextra->insideSpecialComment)
1125 {
1126 yyextra->code->endSpecialComment();
1127 yyextra->insideSpecialComment=false;
1128 }
1129}

◆ findMemberLink() [1/2]

static bool findMemberLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const Definition * sym,
const QCString & symName )
static

Definition at line 1417 of file pycode.l.

1421{
1422 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1423 //printf("sym %s outerScope=%s equal=%d\n",
1424 // qPrint(sym->name()),qPrint(sym->getOuterScope()->name()),
1425 // sym->getOuterScope()==yyextra->currentDefinition);
1426
1427 if (sym->getOuterScope() &&
1429 yyextra->currentDefinition->definitionType()==Definition::TypeClass)
1430 {
1431 const ClassDef *cd = toClassDef(sym->getOuterScope());
1432 const ClassDef *thisCd = toClassDef(yyextra->currentDefinition);
1434 {
1435 if (yyextra->currentMemberDef && yyextra->collectXRefs)
1436 {
1437 addDocCrossReference(yyextra->currentMemberDef,toMemberDef(sym));
1438 }
1439 }
1440 DBG_CTX((stderr,"cd=%s thisCd=%s\n",cd?qPrint(cd->name()):"<none>",thisCd?qPrint(thisCd->name()):"<none>"));
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual DefType definitionType() const =0
virtual Definition * getOuterScope() const =0
virtual const QCString & name() const =0
ClassDef * toClassDef(Definition *d)
void addDocCrossReference(const MemberDef *s, const MemberDef *d)
MemberDef * toMemberDef(Definition *d)
#define DBG_CTX(x)
Definition pycode.l:65
const char * qPrint(const char *s)
Definition qcstring.h:661
1441
1442 // TODO: find the nearest base class in case cd is a base class of
1443 // thisCd
1444 if (cd==thisCd || (thisCd && thisCd->isBaseClass(cd,TRUE)))
1445 {
1446 writeMultiLineCodeLink(yyscanner,ol,sym,symName);
1447 return TRUE;
1448 }
1449 }
1450 return FALSE;
virtual int isBaseClass(const ClassDef *bcd, bool followInstances, const QCString &templSpec=QCString()) const =0
Returns TRUE iff bcd is a direct or indirect base class of this class.
static void writeMultiLineCodeLink(yyscan_t yyscanner, OutputCodeList &ol, const Definition *d, const QCString &text)
Definition pycode.l:1055
1451}

References addDocCrossReference(), DBG_CTX, Definition::definitionType(), FALSE, Definition::getOuterScope(), ClassDef::isBaseClass(), Definition::name(), qPrint(), toClassDef(), toMemberDef(), TRUE, Definition::TypeClass, Definition::TypeMember, and writeMultiLineCodeLink().

Referenced by findMemberLink().

◆ findMemberLink() [2/2]

static void findMemberLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const QCString & symName )
static

Definition at line 1455 of file pycode.l.

1458{
1459 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1460 //printf("Member reference: %s scope=%s member=%s\n",
1461 // yytext,
1462 // yyextra->currentDefinition?qPrint(yyextra->currentDefinition->name()):"<none>",
1463 // yyextra->currentMemberDef?qPrint(yyextra->currentMemberDef->name()):"<none>"
1464 // );
1465 if (yyextra->currentDefinition)
1466 {
1467 const auto &v = Doxygen::symbolMap->find(symName);
1468 for (const auto &p : v)
1469 {
1470 if (findMemberLink(yyscanner,ol,p,symName)) return;
1471 }
1472 }
1473 //printf("sym %s not found\n",&yytext[5]);
1474 codify(yyscanner,symName);
static SymbolMap< Definition > * symbolMap
Definition doxygen.h:125
static void codify(yyscan_t yyscanner, const QCString &text)
Definition pycode.l:1016
static bool findMemberLink(yyscan_t yyscanner, OutputCodeList &ol, const Definition *sym, const QCString &symName)
Definition pycode.l:1417
1475}

References codify(), findMemberLink(), and Doxygen::symbolMap.

◆ generateClassOrGlobalLink()

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

Definition at line 1233 of file pycode.l.

1237{
1238 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1239 QCString className=clName;
This is an alternative implementation of QCString.
Definition qcstring.h:101
1240
1241 // Don't do anything for empty text
1242 if (className.isEmpty()) return;
1243
1244 DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",qPrint(className)));
1245
1246 const ScopedTypeVariant *lcd = nullptr;
1247 const ClassDef *cd=nullptr; // Class def that we may find
1248 const MemberDef *md=nullptr; // Member def that we may find
1249 //bool isLocal=FALSE;
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
1250
1251 if ((lcd=yyextra->theVarContext.findVariable(className))==nullptr) // not a local variable
1252 {
1253 const Definition *d = yyextra->currentDefinition;
1254 QCString scope = substitute(className,".","::");
QCString substitute(const QCString &s, const QCString &src, const QCString &dst)
substitute all occurrences of src in s by dst
Definition qcstring.cpp:477
1255
1256 cd = yyextra->symbolResolver.resolveClass(d,substitute(className,".","::"),true);
1257 md = yyextra->symbolResolver.getTypedef();
1258
1259 DBG_CTX((stderr,"d=%s yyextra->sourceFileDef=%s\n",
1260 d?qPrint(d->displayName()):"<null>",
1261 yyextra->currentDefinition?qPrint(yyextra->currentDefinition->displayName()):"<null>"));
1262 DBG_CTX((stderr,"is found as a type %s\n",cd?qPrint(cd->name()):"<null>"));
virtual QCString displayName(bool includeScope=TRUE) const =0
1263
1264 if (cd==nullptr && md==nullptr) // also see if it is variable or enum or enum value
1265 {
1266 const NamespaceDef *nd = getResolvedNamespace(scope);
1267 if (nd)
1268 {
1269 writeMultiLineCodeLink(yyscanner,ol,nd,clName);
1270 addToSearchIndex(yyscanner,className);
1271 return;
1272 }
1273 else if (getLink(yyscanner,yyextra->classScope,clName,ol,clName))
1274 {
1275 return;
1276 }
1277 }
1278 }
1279 else
1280 {
1281 if (!lcd->isDummy())
1282 {
1283 yyextra->theCallContext.setScope(*lcd);
1284 }
1285 //isLocal=TRUE;
1286 DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
1287 }
An abstract interface of a namespace symbol.
NamespaceDef * getResolvedNamespace(const QCString &name)
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
Definition pycode.l:862
static bool getLink(yyscan_t yyscanner, const QCString &className, const QCString &memberName, OutputCodeList &ol, const QCString &text=QCString())
Definition pycode.l:1205
1288
1289 if (cd && cd->isLinkable()) // is it a linkable class
1290 {
1291 writeMultiLineCodeLink(yyscanner,ol,cd,clName);
1292 addToSearchIndex(yyscanner,className);
1293 if (md)
1294 {
1296 md->getBodyDef() : md->getOuterScope();
1297 if (md->getGroupDef()) d = md->getGroupDef();
1298 if (d && d->isLinkable() && md->isLinkable() &&
1299 yyextra->currentMemberDef && yyextra->collectXRefs && yyextra->insideBody)
1300 {
1301 addDocCrossReference(yyextra->currentMemberDef,md);
1302 }
1303 }
1304 }
1305 else // not a class, maybe a global member
1306 {
1307 int scopeEnd = className.findRev(".");
1308 if (scopeEnd!=-1 && !typeOnly) // name with explicit scope
1309 {
1310 QCString scope = substitute(className.left(scopeEnd),".","::");
1311 QCString locName = className.right(className.length()-scopeEnd-1);
1312 ClassDef *mcd = getClass(scope);
1313 DBG_CTX((stderr,"scope=%s locName=%s mcd=%p\n",qPrint(scope),qPrint(locName),mcd));
1314 if (mcd)
1315 {
1316 const MemberDef *mmd = mcd->getMemberByName(locName);
1317 if (mmd)
1318 {
1319 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())));
1320 writeMultiLineCodeLink(yyscanner,ol,mmd,clName);
1321 addToSearchIndex(yyscanner,className);
1322 const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ?
1323 mmd->getBodyDef() : mmd->getOuterScope();
1324 if (mmd->getGroupDef()) d = mmd->getGroupDef();
1325 if (d && d->isLinkable() && mmd->isLinkable() &&
1326 yyextra->currentMemberDef && yyextra->collectXRefs && yyextra->insideBody)
1327 {
1328 addDocCrossReference(yyextra->currentMemberDef,mmd);
1329 }
1330 return;
1331 }
1332 }
1333 else // check namespace as well
1334 {
1335 const NamespaceDef *mnd = getResolvedNamespace(scope);
1336 if (mnd)
1337 {
1338 const MemberDef *mmd=mnd->getMemberByName(locName);
1339 if (mmd)
1340 {
1341 //printf("name=%s scope=%s\n",qPrint(locName),qPrint(scope));
1342 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,mmd->typeString(),mmd->getOuterScope())));
1343 writeMultiLineCodeLink(yyscanner,ol,mmd,clName);
1344 addToSearchIndex(yyscanner,className);
1345 const Definition *d = mmd->getOuterScope()==Doxygen::globalScope ?
1346 mmd->getBodyDef() : mmd->getOuterScope();
1347 if (mmd->getGroupDef()) d = mmd->getGroupDef();
1348 if (d && d->isLinkable() && mmd->isLinkable() &&
1349 yyextra->currentMemberDef && yyextra->collectXRefs && yyextra->insideBody)
1350 {
1351 addDocCrossReference(yyextra->currentMemberDef,mmd);
1352 }
1353 return;
1354 }
1355 }
1356 }
1357 }
virtual const MemberDef * getMemberByName(const QCString &) const =0
Returns the member with the given name.
virtual bool isLinkable() const =0
virtual const FileDef * getBodyDef() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual QCString typeString() const =0
virtual GroupDef * getGroupDef()=0
virtual const MemberDef * getMemberByName(const QCString &) const =0
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
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 left(size_t len) const
Definition qcstring.h:214
ClassDef * getClass(const QCString &n)
static const ClassDef * stripClassName(yyscan_t yyscanner, const QCString &s, Definition *d)
Definition pycode.l:872
1358
1359 // nothing found, just write out the word
1360 codifyLines(yyscanner,clName);
1361 addToSearchIndex(yyscanner,clName);
1362 }
static void codifyLines(yyscan_t yyscanner, const QCString &text)
Definition pycode.l:1133
1363}

References addDocCrossReference(), addToSearchIndex(), codifyLines(), DBG_CTX, Definition::displayName(), QCString::findRev(), Definition::getBodyDef(), getClass(), MemberDef::getGroupDef(), getLink(), ClassDef::getMemberByName(), NamespaceDef::getMemberByName(), Definition::getOuterScope(), getResolvedNamespace(), Doxygen::globalScope, ScopedTypeVariant::isDummy(), QCString::isEmpty(), Definition::isLinkable(), QCString::left(), QCString::length(), Definition::name(), qPrint(), QCString::right(), stripClassName(), substitute(), MemberDef::typeString(), and writeMultiLineCodeLink().

◆ generateFunctionLink()

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

Definition at line 1374 of file pycode.l.

1377{
1378 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1379 QCString locScope=yyextra->classScope;
1380 QCString locFunc=removeRedundantWhiteSpace(funcName);
1381 DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",qPrint(locScope),qPrint(locFunc)));
1382 int i=locFunc.findRev("::");
1383 if (i>0)
1384 {
1385 locScope=locFunc.left(i);
1386 locFunc=locFunc.right(locFunc.length()-i-2).stripWhiteSpace();
1387 }
1388 //printf("generateFunctionLink(%s) classScope='%s'\n",qPrint(locFunc),qPrint(locScope));
1389 if (!locScope.isEmpty())
1390 {
1391 auto it = yyextra->codeClassMap.find(locScope.str());
1392 if (it!=yyextra->codeClassMap.end())
1393 {
1394 ScopedTypeVariant ccd = it->second;
1395 //printf("using classScope %s\n",qPrint(yyextra->classScope));
1396 if (ccd.localDef() && !ccd.localDef()->baseClasses().empty())
1397 {
1398 for (const auto &bcName : ccd.localDef()->baseClasses())
1399 {
1400 if (getLink(yyscanner,bcName,locFunc,ol,funcName))
1401 {
1402 return;
1403 }
1404 }
1405 }
1406 }
1407 }
1408 if (!getLink(yyscanner,locScope,locFunc,ol,funcName))
1409 {
1410 generateClassOrGlobalLink(yyscanner,ol,funcName);
1411 }
1412 return;
std::vector< QCString > baseClasses() const
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
const std::string & str() const
Definition qcstring.h:526
static void generateClassOrGlobalLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &clName, bool typeOnly=FALSE)
Definition pycode.l:1233
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
1413}

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

◆ getLexerFILE()

static const char * getLexerFILE ( )
inlinestatic

Definition at line 163 of file pycode.l.

163{return __FILE__;}

◆ getLink()

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

Definition at line 1205 of file pycode.l.

1210{
1211 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1212 QCString m=removeRedundantWhiteSpace(memberName);
1213 QCString c=className;
1214 if (!getLinkInScope(yyscanner,c,m,memberName,ol,text))
1215 {
1216 if (!yyextra->curClassName.isEmpty())
1217 {
1218 if (!c.isEmpty()) c.prepend("::");
1219 c.prepend(yyextra->curClassName);
1220 return getLinkInScope(yyscanner,c,m,memberName,ol,text);
1221 }
1222 return FALSE;
1223 }
1224 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)
Definition pycode.l:1163
1225}

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

◆ getLinkInScope()

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

Definition at line 1163 of file pycode.l.

1170{
1171 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1172 GetDefInput input(c,m,"()");
1173 input.currentFile = yyextra->sourceFileDef;
1174 input.insideCode = true;
1175 GetDefResult result = getDefs(input);
1176 //printf("Trying '%s'::'%s'\n",qPrint(c),qPrint(m));
1177 if (result.found && result.md->isLinkable())
1178 {
1179 const Definition *d = result.md->getOuterScope()==Doxygen::globalScope ?
1180 result.md->getBodyDef() : result.md->getOuterScope();
1181 //printf("Found! d=%s\n",d?qPrint(d->name()):"<none>");
1182 if (result.md->getGroupDef()) d = result.md->getGroupDef();
1183 if (d && d->isLinkable())
1184 {
1185 yyextra->theCallContext.setScope(ScopedTypeVariant(stripClassName(yyscanner,result.md->typeString(),result.md->getOuterScope())));
1186 //printf("yyextra->currentDefinition=%p yyextra->currentMemberDef=%p\n",
1187 // yyextra->currentDefinition,yyextra->currentMemberDef);
const MemberDef * md
Definition util.h:125
bool found
Definition util.h:124
GetDefResult getDefs(const GetDefInput &input)
Definition util.cpp:2742
1188
1189 if (yyextra->currentDefinition && yyextra->currentMemberDef && yyextra->collectXRefs && yyextra->insideBody)
1190 {
1191 addDocCrossReference(yyextra->currentMemberDef,result.md);
1192 }
1193 //printf("d->getReference()='%s' d->getOutputBase()='%s' name='%s' member name='%s'\n",qPrint(d->getReference()),qPrint(d->getOutputFileBase()),qPrint(d->name()),qPrint(md->name()));
1194
1195 writeMultiLineCodeLink(yyscanner,ol,result.md, !text.isEmpty() ? text : memberText);
1196 addToSearchIndex(yyscanner,!text.isEmpty() ? text : memberText);
1197 return TRUE;
1198 }
1199 }
1200 return FALSE;
1201}

References addDocCrossReference(), addToSearchIndex(), GetDefInput::currentFile, FALSE, GetDefResult::found, Definition::getBodyDef(), getDefs(), MemberDef::getGroupDef(), Definition::getOuterScope(), Doxygen::globalScope, GetDefInput::insideCode, QCString::isEmpty(), Definition::isLinkable(), GetDefResult::md, stripClassName(), TRUE, MemberDef::typeString(), and writeMultiLineCodeLink().

◆ incrementFlowKeyWordCount()

static void incrementFlowKeyWordCount ( yyscan_t yyscanner)
static

Definition at line 1477 of file pycode.l.

1478{
1479 std::lock_guard<std::mutex> lock(Doxygen::countFlowKeywordsMutex);
1480 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1481 if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction())
1482 {
1483 MemberDefMutable *md = toMemberDefMutable(const_cast<MemberDef*>(yyextra->currentMemberDef));
1484 if (md)
1485 {
1487 }
1488 }
static std::mutex countFlowKeywordsMutex
Definition doxygen.h:141
virtual void incrementFlowKeyWordCount()=0
MemberDefMutable * toMemberDefMutable(Definition *d)
1489}

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

◆ nextCodeLine()

static void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 1034 of file pycode.l.

1035{
1036 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1037 const char *fc = yyextra->currentFontClass;
1038 if (yyextra->insideCodeLine)
1039 {
1040 endCodeLine(yyscanner);
1041 }
1042 if (yyextra->yyLineNr<yyextra->inputLines)
1043 {
1044 yyextra->currentFontClass = fc;
1045 startCodeLine(yyscanner);
1046 }
static void endCodeLine(yyscan_t yyscanner)
Definition pycode.l:1024
static void startCodeLine(yyscan_t yyscanner)
Definition pycode.l:948
1047}

References endCodeLine(), and startCodeLine().

◆ pop_state()

static void pop_state ( yyscan_t yyscanner)
inlinestatic

Definition at line 1622 of file pycode.l.

1623{
1624 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1625 if ( yyg->yy_start_stack_ptr <= 0 )
1626 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected statement '%s'",yytext );
1627 else
1628 yy_pop_state(yyscanner);
#define warn(file, line, fmt,...)
Definition message.h:59
1629}

References warn.

◆ setCurrentDoc()

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

Definition at line 844 of file pycode.l.

845{
846 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
847 if (Doxygen::searchIndex.enabled())
848 {
849 if (yyextra->searchCtx)
850 {
851 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
852 }
853 else
854 {
855 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,TRUE);
856 }
857 }
858}

References FALSE, Doxygen::searchIndex, and TRUE.

◆ 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 948 of file pycode.l.

949{
950 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
951 //if (yyextra->currentFontClass) { yyextra->code->endFontClass(yyscanner); }
952 if (yyextra->sourceFileDef)
953 {
954 //QCString lineNumber,lineAnchor;
955 //lineNumber.sprintf("%05d",yyextra->yyLineNr);
956 //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
957
958 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
959 //printf("startCodeLine %d d=%p\n",yyextra->yyLineNr,d);
960 //yyextra->code->startLineNumber();
961
962 if (!yyextra->includeCodeFragment && d && d->isLinkableInProject())
963 {
964 yyextra->currentDefinition = d;
965 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
966 yyextra->insideBody = false;
967 yyextra->endComment = FALSE;
968 yyextra->searchingForBody = TRUE;
969 yyextra->realScope = d->name();
970 yyextra->classScope = d->name();
971 //printf("Real scope: '%s'\n",qPrint(yyextra->realScope));
972 yyextra->bodyCurlyCount = 0;
973 QCString lineAnchor;
974 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
975 if (yyextra->currentMemberDef)
976 {
977 codeFolding(yyscanner,yyextra->currentMemberDef);
978 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
979 yyextra->currentMemberDef->getOutputFileBase(),
980 yyextra->currentMemberDef->anchor(),yyextra->yyLineNr,
981 !yyextra->includeCodeFragment);
982 setCurrentDoc(yyscanner,lineAnchor);
983 }
984 else if (d->isLinkableInProject())
985 {
986 codeFolding(yyscanner,d);
987 yyextra->code->writeLineNumber(d->getReference(),
989 QCString(),yyextra->yyLineNr,
990 !yyextra->includeCodeFragment);
991 setCurrentDoc(yyscanner,lineAnchor);
992 }
993 else
994 {
995 codeFolding(yyscanner,nullptr);
996 }
997 }
998 else
999 {
1000 codeFolding(yyscanner,nullptr);
1001 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
1002 !yyextra->includeCodeFragment);
1003 }
1004 }
1005 yyextra->code->startCodeLine(yyextra->yyLineNr);
1006 yyextra->insideCodeLine=true;
virtual bool isLinkableInProject() const =0
virtual QCString getReference() const =0
virtual QCString getOutputFileBase() const =0
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
static void setCurrentDoc(yyscan_t yyscanner, const QCString &anchor)
Definition pycode.l:844
static void codeFolding(yyscan_t yyscanner, const Definition *d)
Definition pycode.l:901
1007
1008 if (yyextra->currentFontClass)
1009 {
1010 yyextra->code->startFontClass(yyextra->currentFontClass);
1011 }
1012}

References codeFolding(), FALSE, Definition::getOutputFileBase(), Definition::getReference(), Definition::isLinkableInProject(), Definition::name(), setCurrentDoc(), QCString::sprintf(), and TRUE.

◆ startFontClass()

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

Definition at line 1097 of file pycode.l.

1098{
1099 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1100 if (specialComment)
1101 {
1102 yyextra->code->startSpecialComment();
1103 yyextra->insideSpecialComment = true;
1104 }
1105 // if font class is already set don't stop and start it.
1106 if (qstrcmp(yyextra->currentFontClass,s)!=0)
1107 {
1108 endFontClass(yyscanner);
1109 yyextra->code->startFontClass(s);
1110 yyextra->currentFontClass=s;
1111 }
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
1112}

References endFontClass(), and qstrcmp().

◆ stateToString()

static const char * stateToString ( int state)
static

References FALSE.

◆ stripClassName()

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

Definition at line 872 of file pycode.l.

873{
874 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
875 int pos=0;
876 QCString type = s;
877 QCString className;
878 QCString templSpec;
879 while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
880 {
881 QCString clName=className+templSpec;
882 const ClassDef *cd=nullptr;
883 if (!yyextra->classScope.isEmpty())
884 {
885 cd=yyextra->symbolResolver.resolveClass(d,yyextra->classScope+"::"+clName,true);
886 }
887 if (cd==nullptr)
888 {
889 cd=yyextra->symbolResolver.resolveClass(d,clName,true);
890 }
891 if (cd)
892 {
893 return cd;
894 }
895 }
int extractClassNameFromType(const QCString &type, int &pos, QCString &name, QCString &templSpec, SrcLangExt lang)
Definition util.cpp:4566
896
897 return nullptr;
898}

References extractClassNameFromType().

◆ 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 1055 of file pycode.l.

1059{
1060 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1061 if (text.isEmpty()) return;
1062 bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
1063 yyextra->tooltipManager.addTooltip(d);
1064 QCString ref = d->getReference();
1065 QCString file = d->getOutputFileBase();
1066 QCString anchor = d->anchor();
1067 QCString tooltip;
1068 if (!sourceTooltips) // fall back to simple "title" tooltips
1069 {
1070 tooltip = d->briefDescriptionAsTooltip();
1071 }
1072 bool done=FALSE;
1073 const char *p=text.data();
1074 while (!done)
1075 {
1076 const char *sp=p;
1077 char c=0;
1078 while ((c=*p++) && c!='\n') { }
1079 if (c=='\n')
1080 {
1081 yyextra->yyLineNr++;
1082 //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
1083 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,QCString(sp,p-sp-1),tooltip);
1084 nextCodeLine(yyscanner);
1085 }
1086 else
1087 {
1088 //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
1089 ol.writeCodeLink(d->codeSymbolType(),ref,file,anchor,sp,tooltip);
1090 done=TRUE;
1091 }
1092 }
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
1093}

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

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 217 of file pycode.l.

219 {
220 "def"{BB} {
221 startFontClass(yyscanner,"keyword");
222 codify(yyscanner,yytext);
223 endFontClass(yyscanner);
224 BEGIN( FunctionDec );
225 }
226 "async"{BB}"def"{BB} {
227 startFontClass(yyscanner,"keyword");
228 codify(yyscanner,yytext);
229 endFontClass(yyscanner);
230 BEGIN( FunctionDec );
231 }
static void startFontClass(yyscan_t yyscanner, const char *s, bool specialComment=false)
Definition pycode.l:1097
232
233 "class"{BB} {
234 startFontClass(yyscanner,"keyword");
235 codify(yyscanner,yytext);
236 endFontClass(yyscanner);
237 BEGIN( ClassDec );
238 }
239 "None" {
240 startFontClass(yyscanner,"keywordtype");
241 codify(yyscanner,yytext);
242 endFontClass(yyscanner);
243 }
244 "self."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER}"(" {
245 codify(yyscanner,"self.");
246 findMemberLink(yyscanner,*yyextra->code,&yytext[5]);
247 }
248 "self."{IDENTIFIER}/"(" {
249 codify(yyscanner,"self.");
250 findMemberLink(yyscanner,*yyextra->code,&yytext[5]);
251 }
252 "self."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER} {
253 codify(yyscanner,"self.");
254 findMemberLink(yyscanner,*yyextra->code,&yytext[5]);
255 }
256 "self."{IDENTIFIER} {
257 codify(yyscanner,"self.");
258 findMemberLink(yyscanner,*yyextra->code,&yytext[5]);
259 }
260 "cls."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER}"(" {
261 codify(yyscanner,"cls.");
262 findMemberLink(yyscanner,*yyextra->code,&yytext[4]);
263 }
264 "cls."{IDENTIFIER}/"(" {
265 codify(yyscanner,"cls.");
266 findMemberLink(yyscanner,*yyextra->code,&yytext[4]);
267 }
268 "cls."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER} {
269 codify(yyscanner,"cls.");
270 findMemberLink(yyscanner,*yyextra->code,&yytext[4]);
271 }
272 "cls."{IDENTIFIER} {
273 codify(yyscanner,"cls.");
274 findMemberLink(yyscanner,*yyextra->code,&yytext[4]);
275 }
276 "@"{SCOPE}{CALLANY}? { // decorator
277 startFontClass(yyscanner,"preprocessor");
278 codify(yyscanner,yytext);
279 endFontClass(yyscanner);
280 }
281}
282
283<ClassDec>{IDENTIFIER} {
284 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
285 // codify(yyscanner,yytext);
286 yyextra->curClassName = yytext;
287 yyextra->curClassBases.clear();
288 BEGIN( ClassInheritance );
289 }
290
291<ClassInheritance>{
292 ({BB}|[(,)]) {
293 codify(yyscanner,yytext);
294 }
295
296 ({IDENTIFIER}".")*{IDENTIFIER} {
297 // The parser
298 // is assuming
299 // that ALL identifiers
300 // in this state
301 // are base classes;
302 // it doesn't check to see
303 // that the first parenthesis
304 // has been seen.
305
306 // This is bad - it should
307 // probably be more strict
308 // about what to accept.
309
310 yyextra->curClassBases.emplace_back(yytext);
311 yyextra->insideBody = true;
312 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
313 yyextra->insideBody = false;
314 // codify(yyscanner,yytext);
315 }
316
317 ":" {
318 codify(yyscanner,yytext);
319
320 // Assume this will
321 // be a one-line suite;
322 // found counter-example
323 // in SuiteStart.
324
325 // Push a class scope
326 ScopedTypeVariant var(yyextra->curClassName);
327 for (const auto &s : yyextra->curClassBases)
328 {
329 const ClassDef *baseDefToAdd = nullptr;
330 // find class in the local scope
331 auto it = yyextra->codeClassMap.find(s);
332 if (it != yyextra->codeClassMap.end())
333 {
334 baseDefToAdd = toClassDef(it->second.globalDef());
335 }
336 // Try to find class in global scope
337 if (baseDefToAdd==nullptr)
338 {
339 baseDefToAdd=yyextra->symbolResolver.resolveClass(yyextra->currentDefinition,s.c_str(),true);
340 }
341
342 if (baseDefToAdd && baseDefToAdd->name()!=yyextra->curClassName)
343 {
344 var.localDef()->insertBaseClass(baseDefToAdd->name());
345 }
346 }
347 yyextra->codeClassMap.emplace(yyextra->curClassName.str(),std::move(var));
348
349 // Reset class-parsing variables.
350 yyextra->curClassName.clear();
351 yyextra->curClassBases.clear();
352
353 yyextra->noSuiteFound = TRUE;
354 BEGIN( SuiteStart );
355 }
356}
357
358
359<FunctionDec>{
360 {IDENTIFIER} {
361 generateFunctionLink(yyscanner,*yyextra->code,yytext);
362 }
static void generateFunctionLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &funcName)
Definition pycode.l:1374
363
364 {B}"(" {
365 codify(yyscanner,yytext);
366 BEGIN( FunctionParams );
367 }
368}
369
370<FunctionParams>{
371 ({BB}|",") {
372 // Parses delimiters
373 codify(yyscanner,yytext);
374 }
375
376 ({IDENTIFIER}|{PARAMNONEMPTY}+) {
377 codify(yyscanner,yytext);
378 }
379
380 ")" {
381 codify(yyscanner,yytext);
382 }
383
384 "\n" {
385 codifyLines(yyscanner,yytext);
386 }
387
388 ":" {
389 codify(yyscanner,yytext);
390
391 // Assume this will
392 // be a one-line suite;
393 // found counter-example
394 // in SuiteStart.
395 yyextra->noSuiteFound = TRUE;
396 BEGIN( SuiteStart );
397 }
398}
399
400<Body,Suite>{
401
402 {KEYWORD} {
403 // Position-sensitive rules!
404 // Must come AFTER keyword-triggered rules
405 // Must come BEFORE identifier NONEMPTY-like rules
406 // to syntax highlight.
407
408 startFontClass(yyscanner,"keyword");
409 codify(yyscanner,yytext);
410 endFontClass(yyscanner);
411 }
412
413 {FLOWKW} {
414 incrementFlowKeyWordCount(yyscanner);
415 startFontClass(yyscanner,"keywordflow");
416 codify(yyscanner,yytext);
417 endFontClass(yyscanner);
418 }
419 ({IDENTIFIER}".")*{IDENTIFIER}/"(" {
420 yyextra->insideBody = true;
421 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext);
422 yyextra->insideBody = false;
423 }
424 ({IDENTIFIER}".")+{IDENTIFIER} {
425 yyextra->insideBody = true;
426 generateClassOrGlobalLink(yyscanner,*yyextra->code,yytext,TRUE);
427 yyextra->insideBody = false;
428 }
429 {IDENTIFIER} { codify(yyscanner,yytext); }
static void incrementFlowKeyWordCount(yyscan_t yyscanner)
Definition pycode.l:1477
430
431}
432
433
434
435<SuiteStart>{
436
437 {BB} {
438 codify(yyscanner,yytext);
439 }
440 "pass" {
441 startFontClass(yyscanner,"keyword");
442 codifyLines(yyscanner,yytext);
443 endFontClass(yyscanner);
444 BEGIN(Body);
445 }
446 {KEYWORD} {
447 startFontClass(yyscanner,"keyword");
448 codifyLines(yyscanner,yytext);
449 endFontClass(yyscanner);
450
451 // No indentation necessary
452 yyextra->noSuiteFound = FALSE;
453 }
454
455 {FLOWKW} {
456 incrementFlowKeyWordCount(yyscanner);
457 startFontClass(yyscanner,"keywordflow");
458 codifyLines(yyscanner,yytext);
459 endFontClass(yyscanner);
460
461 // No indentation necessary
462 yyextra->noSuiteFound = FALSE;
463 }
464 {IDENTIFIER} {
465 codify(yyscanner,yytext);
466 }
467
468
469 {POUNDCOMMENT} {
470 if (YY_START==SingleQuoteString ||
471 YY_START==DoubleQuoteString ||
472 YY_START==TripleString
473 )
474 {
475 REJECT;
476 }
477 yy_push_state(YY_START,yyscanner);
478 BEGIN(DocBlock);
479 yyextra->docBlock=yytext;
480 }
481
482 {NEWLINE} {
483 codifyLines(yyscanner,yytext);
484 if ( yyextra->noSuiteFound )
485 {
486 // printf("New suite to capture! [%d]\n", yyextra->yyLineNr);
487 BEGIN ( SuiteCaptureIndent );
488 }
489 }
490}
491
492<SuiteCaptureIndent>{
493 "\n"|({BB}"\n") {
494 // Blankline - ignore, keep looking for indentation.
495 codifyLines(yyscanner,yytext);
496 }
497
498 {BB} {
499 // This state lasts momentarily,
500 // to check the indentation
501 // level that is about to be
502 // used.
503 codifyLines(yyscanner,yytext);
504 yyextra->indents.push(yyleng);
505 // printf("Captured indent of %d [line %d]\n", yyleng, yyextra->yyLineNr);
506 BEGIN( Suite );
507 }
508}
509
510<SuiteMaintain>{
511
512 {BB}/({NONEMPTY}|{EXPCHAR}) {
513 // This implements poor
514 // indentation-tracking;
515 // should be improved.
516 // (translate tabs to space, etc)
517 codifyLines(yyscanner,yytext);
518 adjustScopesAndSuites(yyscanner,static_cast<int>(yyleng));
519 }
static void adjustScopesAndSuites(yyscan_t yyscanner, unsigned indentLength)
Definition pycode.l:792
520
521 "\n"|({BB}"\n") {
522 // If this ever succeeds,
523 // it means that this is
524 // a blank line, and
525 // can be ignored.
526 codifyLines(yyscanner,yytext);
527 }
528
529 ""/({NONEMPTY}|{EXPCHAR}) {
530 // Default rule; matches
531 // the empty string, assuming
532 // real text starts here.
533 // Just go straight to Body.
534 adjustScopesAndSuites(yyscanner,0);
535 }
536}
537
538
539<Suite>{NEWLINE} {
540 codifyLines(yyscanner,yytext);
541 BEGIN( SuiteMaintain );
542 }
543<Body>{IDENTIFIER} {
544 codify(yyscanner,yytext);
545 }
546<Body>{NEWLINE} {
547 codifyLines(yyscanner,yytext);
548 }
549
550<SingleQuoteString>{ // Single quoted string like 'That\'s a """nice""" string!'
551 \\{B}\n { // line continuation
552 codifyLines(yyscanner,yytext);
553 }
554 \\. { // escaped char
555 codify(yyscanner,yytext);
556 }
557 {STRINGPREFIX}?{TRIDOUBLEQUOTE} { // triple double quotes
558 codify(yyscanner,yytext);
559 }
560 "'" { // end of the string
561 codify(yyscanner,yytext);
562 endFontClass(yyscanner);
563 BEGIN(yyextra->stringContext);
564 }
565 [^"'\n\\]+ { // normal chars
566 codify(yyscanner,yytext);
567 }
568 . { // normal char
569 codify(yyscanner,yytext);
570 }
571}
572
573<DoubleQuoteString>{ // Double quoted string like "That's \"a '''nice'''\" string!"
574 \\{B}\n { // line continuation
575 codifyLines(yyscanner,yytext);
576 }
577 \\. { // escaped char
578 codify(yyscanner,yytext);
579 }
580 {STRINGPREFIX}?{TRISINGLEQUOTE} { // triple single quotes
581 codify(yyscanner,yytext);
582 }
583 "\"" { // end of the string
584 codify(yyscanner,yytext);
585 endFontClass(yyscanner);
586 BEGIN(yyextra->stringContext);
587 }
588 [^"'\n\\]+ { // normal chars
589 codify(yyscanner,yytext);
590 }
591 . { // normal char
592 codify(yyscanner,yytext);
593 }
594}
595
596<TripleString>{
597 {TRIDOUBLEQUOTE} |
598 {TRISINGLEQUOTE} {
599 codify(yyscanner,yytext);
600 if (yyextra->doubleQuote==(yytext[0]=='"'))
601 {
602 endFontClass(yyscanner);
603 BEGIN(yyextra->stringContext);
604 }
605 }
606 {LONGSTRINGBLOCK} {
607 codifyLines(yyscanner,yytext);
608 }
609 \n {
610 codifyLines(yyscanner,yytext);
611 }
612 [ \t]+ {
613 codify(yyscanner,yytext);
614 }
615 . {
616 codify(yyscanner,yytext);
617 }
618}
619
620
621<*>{STRINGPREFIX}?{TRISINGLEQUOTE} {
622 if (YY_START==SingleQuoteString) REJECT;
623 startFontClass(yyscanner,"stringliteral");
624 yyextra->stringContext=YY_START;
625 yyextra->doubleQuote=yytext[yyleng-1]=='"';
626 codify(yyscanner,yytext);
627 BEGIN(TripleString);
628 }
629<*>{STRINGPREFIX}?{TRIDOUBLEQUOTE} {
630 if (YY_START==DoubleQuoteString) REJECT;
631 startFontClass(yyscanner,"stringliteral");
632 yyextra->stringContext=YY_START;
633 yyextra->doubleQuote=yytext[yyleng-1]=='"';
634 codify(yyscanner,yytext);
635 BEGIN(TripleString);
636 }
637<*>{STRINGPREFIX}?"'" { // single quoted string
638 if (YY_START==SingleQuoteString ||
639 YY_START==DoubleQuoteString ||
640 YY_START==TripleString)
641 {
642 REJECT;
643 }
644 startFontClass(yyscanner,"stringliteral");
645 yyextra->stringContext=YY_START;
646 codify(yyscanner,yytext);
647 BEGIN(SingleQuoteString);
648 }
649<*>{STRINGPREFIX}?"\"" { // double quoted string
650 if (YY_START==SingleQuoteString ||
651 YY_START==DoubleQuoteString ||
652 YY_START==TripleString)
653 {
654 REJECT;
655 }
656 startFontClass(yyscanner,"stringliteral");
657 yyextra->stringContext=YY_START;
658 codify(yyscanner,yytext);
659 BEGIN(DoubleQuoteString);
660 }
661<DocBlock>.* { // contents of current comment line
662 yyextra->docBlock+=yytext;
663 }
664<DocBlock>"\n"{B}("#") { // comment block (next line is also comment line)
665 yyextra->docBlock+=yytext;
666 }
667<DocBlock>{NEWLINE} { // comment block ends at the end of this line
668 // remove special comment (default config)
669 startFontClass(yyscanner,"comment",true);
670 codifyLines(yyscanner,yyextra->docBlock);
671 endFontClass(yyscanner,true);
672 unput(*yytext);
673 pop_state(yyscanner);
674 }
static void pop_state(yyscan_t yyscanner)
Definition pycode.l:1622
675<*>{POUNDCOMMENT}.* {
676 if (YY_START==SingleQuoteString ||
677 YY_START==DoubleQuoteString ||
678 YY_START==TripleString)
679 {
680 REJECT;
681 }
682 yy_push_state(YY_START,yyscanner);
683 BEGIN(DocBlock);
684 yyextra->docBlock=yytext;
685 }
686<*>"#".* { // normal comment
687 if (YY_START==SingleQuoteString ||
688 YY_START==DoubleQuoteString ||
689 YY_START==TripleString)
690 {
691 REJECT;
692 }
693 startFontClass(yyscanner,"comment");
694 codifyLines(yyscanner,yytext);
695 endFontClass(yyscanner);
696 }
697<*>{NEWLINE} {
698 if (yyextra->endComment)
699 {
700 yyextra->endComment=FALSE;
701 }
702 else
703 {
704 codifyLines(yyscanner,yytext);
705 }
706 //printf("[pycode] %d NEWLINE [line %d] no match\n",
707 // YY_START, yyextra->yyLineNr);
708
709 BEGIN(Body);
710 }
711
712<*>[ \t]+ {
713 codify(yyscanner,yytext);
714 BEGIN(Body);
715 }
716<*>. {
717 codify(yyscanner,yytext);
718 // printf("[pycode] '%s' [ state %d ] [line %d] no match\n",
719 // yytext, YY_START, yyextra->yyLineNr);
720
721 BEGIN(Body);
722 }
723
724<*><<EOF>> {
725 if (YY_START==DocBlock)
726 {
727 startFontClass(yyscanner,"comment",true);
728 codifyLines(yyscanner,yyextra->docBlock);
729 endFontClass(yyscanner,true);
730 }
731 yyterminate();
732 }
#define yyterminate()
733%%

◆ yyread()

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

Definition at line 771 of file pycode.l.

772{
773 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
774 int inputPosition = yyextra->inputPosition;
775 const char *s = yyextra->inputString + inputPosition;
776 int c=0;
777 while( c < max_size && *s )
778 {
779 *buf++ = *s++;
780 c++;
781 }
782 yyextra->inputPosition += c;
783 return c;
784}