Doxygen
Loading...
Searching...
No Matches
fortrancode.l File Reference
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include "doxygen.h"
#include "message.h"
#include "outputlist.h"
#include "util.h"
#include "membername.h"
#include "defargs.h"
#include "config.h"
#include "groupdef.h"
#include "classlist.h"
#include "filedef.h"
#include "namespacedef.h"
#include "tooltip.h"
#include "fortrancode.h"
#include "fortranscanner.h"
#include "containers.h"
#include "debug.h"
#include "searchindex.h"
#include "doxygen_lex.h"
#include "fortrancode.l.h"
+ Include dependency graph for fortrancode.l:

Go to the source code of this file.

Classes

class  UseEntry
 data of an use-statement More...
 
class  UseMap
 module name -> list of ONLY/remote entries (module name = name of the module, which can be accessed via use-directive) More...
 
class  Scope
 Contains names of used modules and names of local variables. More...
 
struct  fortrancodeYY_state
 
struct  FortranCodeParser::Private
 

Macros

#define YY_TYPEDEF_YY_SCANNER_T
 
#define DBG_CTX(x)
 
#define YY_NO_TOP_STATE   1
 
#define YY_NO_INPUT   1
 
#define YY_NO_UNISTD_H   1
 
#define YY_USER_ACTION   {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += static_cast<int>(yyleng);}
 
#define YY_FTN_RESET   {yy_old_start = 0; yy_my_start = 0; yy_end = 1;}
 
#define YY_FTN_REJECT   {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;}
 
#define YY_INPUT(buf, result, max_size)
 

Typedefs

typedef yyguts_t * yyscan_t
 

Functions

static const char * stateToString (int state)
 
static bool getFortranNamespaceDefs (const QCString &mname, NamespaceDef *&cd)
 searches for definition of a module (Namespace)
 
static bool getFortranTypeDefs (const QCString &tname, const QCString &moduleName, ClassDef *&cd, const UseMap &useMap)
 searches for definition of a type
 
static void startFontClass (yyscan_t yyscanner, const char *s, bool specialComment=false)
 
static void endFontClass (yyscan_t yyscanner, bool specialComment=false)
 
static void setCurrentDoc (yyscan_t yyscanner, const QCString &anchor)
 
static void addToSearchIndex (yyscan_t yyscanner, const QCString &text)
 
static void startCodeLine (yyscan_t yyscanner)
 
static void endCodeLine (yyscan_t yyscanner)
 
static void nextCodeLine (yyscan_t yyscanner)
 
static void codifyLines (yyscan_t yyscanner, const QCString &text)
 
static void writeMultiLineCodeLink (yyscan_t yyscanner, OutputCodeList &ol, Definition *d, const QCString &text)
 
static bool getGenericProcedureLink (yyscan_t,const ClassDef *, const QCString &, OutputCodeList &)
 gets the link to a generic procedure which depends not on the name, but on the parameter list
 
static bool getLink (yyscan_t yyscanner, const UseMap &useMap, const QCString &memberText, OutputCodeList &ol, const QCString &text)
 
static void generateLink (yyscan_t yyscanner, OutputCodeList &ol, const QCString &lname)
 
static void generateLink (yyscan_t yyscanner, OutputCodeList &ol, const char *lname)
 
static int countLines (yyscan_t yyscanner)
 
static void startScope (yyscan_t yyscanner)
 start scope
 
static void endScope (yyscan_t yyscanner)
 end scope
 
static void addUse (yyscan_t yyscanner, const QCString &moduleName)
 
static void addLocalVar (yyscan_t yyscanner, const QCString &varName)
 
static MemberDefgetFortranDefs (yyscan_t yyscanner, const QCString &memberName, const QCString &moduleName, const UseMap &useMap)
 searches for definition of function memberName
 
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)
 
static void checkContLines (yyscan_t yyscanner, const char *s)
 
void parseFortranCode (OutputCodeList &, const char *, const QCString &, bool, const char *, const FileDef *, int, int, bool, const MemberDef *, bool, const Definition *, bool, FortranFormat)
 

Variables

int yy_old_start = 0
 
int yy_my_start = 0
 
int yy_end = 1
 

Macro Definition Documentation

◆ DBG_CTX

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

Definition at line 71 of file fortrancode.l.

◆ YY_FTN_REJECT

#define YY_FTN_REJECT   {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;}

Definition at line 89 of file fortrancode.l.

◆ YY_FTN_RESET

#define YY_FTN_RESET   {yy_old_start = 0; yy_my_start = 0; yy_end = 1;}

Definition at line 88 of file fortrancode.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 220 of file fortrancode.l.

◆ YY_NO_INPUT

#define YY_NO_INPUT   1

Definition at line 74 of file fortrancode.l.

◆ YY_NO_TOP_STATE

#define YY_NO_TOP_STATE   1

Definition at line 73 of file fortrancode.l.

◆ YY_NO_UNISTD_H

#define YY_NO_UNISTD_H   1

Definition at line 75 of file fortrancode.l.

◆ YY_TYPEDEF_YY_SCANNER_T

#define YY_TYPEDEF_YY_SCANNER_T
Todo
  • continuation lines not always recognized
  • merging of use-statements with same module name and different only-names
  • rename part of use-statement
  • links to interface functions
  • references to variables

Definition at line 37 of file fortrancode.l.

◆ YY_USER_ACTION

#define YY_USER_ACTION   {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += static_cast<int>(yyleng);}

Definition at line 87 of file fortrancode.l.

Typedef Documentation

◆ yyscan_t

typedef yyguts_t* yyscan_t

Definition at line 39 of file fortrancode.l.

Function Documentation

◆ addLocalVar()

static void addLocalVar ( yyscan_t yyscanner,
const QCString & varName )
static

Definition at line 1403 of file fortrancode.l.

1404{
1405 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1406 if (!yyextra->scopeStack.empty())
1407 {
1408 std::string lowVarName = varName.lower().str();
1409 yyextra->scopeStack.back().localVars.insert(lowVarName);
1410 if (yyextra->isExternal) yyextra->scopeStack.back().externalVars.insert(lowVarName);
1411 }
QCString lower() const
Definition qcstring.h:234
const std::string & str() const
Definition qcstring.h:537
1412}

References QCString::lower(), and QCString::str().

◆ addToSearchIndex()

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

Definition at line 901 of file fortrancode.l.

902{
903 if (Doxygen::searchIndex.enabled())
904 {
905 Doxygen::searchIndex.addWord(text,FALSE);
906 }
static SearchIndexIntf searchIndex
Definition doxygen.h:124
#define FALSE
Definition qcstring.h:34
907}

References FALSE, and Doxygen::searchIndex.

◆ addUse()

static void addUse ( yyscan_t yyscanner,
const QCString & moduleName )
static

Definition at line 1396 of file fortrancode.l.

1397{
1398 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1399 if (!yyextra->scopeStack.empty())
1400 yyextra->scopeStack.back().useNames.push_back(moduleName);
1401}

References Scope::useNames.

◆ checkContLines()

static void checkContLines ( yyscan_t yyscanner,
const char * s )
static

Definition at line 1417 of file fortrancode.l.

1418{
1419 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1420 int numLines = 0;
1421 int i = 0;
1422 const char *p = s;
1423
1424 numLines = 2; // one for element 0, one in case no \n at end
1425 while (*p)
1426 {
1427 if (*p == '\n') numLines++;
1428 p++;
1429 }
1430
1431 yyextra->hasContLine = (int *) malloc((numLines) * sizeof(int));
1432 for (i = 0; i < numLines; i++)
1433 {
1434 yyextra->hasContLine[i] = 0;
1435 }
1436 p = prepassFixedForm(s, yyextra->hasContLine,yyextra->fixedCommentAfter);
1437 yyextra->hasContLine[0] = 0;
const char * prepassFixedForm(const char *contents, int *hasContLine, int fixedCommentAfter)
1438}

References prepassFixedForm().

Referenced by FortranCodeParser::parseCode().

◆ codeFolding()

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

Definition at line 909 of file fortrancode.l.

910{
911 if (Config_getBool(HTML_CODE_FOLDING))
912 {
913 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
914 while (!yyextra->foldStack.empty())
915 {
916 const Definition *dd = yyextra->foldStack.back();
917 if (dd->getEndBodyLine()+1==yyextra->yyLineNr) // +1 to close the section after the end of the body
918 {
919 yyextra->code->endFold();
920 //printf("%d: end codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(dd->name()),dd->getStartDefLine(),dd->getEndBodyLine());
921 yyextra->foldStack.pop_back();
922 }
923 else
924 {
925 break;
926 }
927 }
928 if (d)
929 {
930 int startLine = d->getStartDefLine();
931 int endLine = d->getEndBodyLine();
932 if (endLine!=-1 && startLine!=endLine &&
933 // since the end of a section is closed after the last line, we need to avoid starting a
934 // new section if the previous section ends at the same line, i.e. something like
935 // struct X {
936 // ...
937 // }; struct S { <- start of S and end of X at the same line
938 // ...
939 // };
940 (yyextra->foldStack.empty() || yyextra->foldStack.back()->getEndBodyLine()!=startLine))
941 {
942 //printf("%d: start codeFolding for %s [%d..%d]\n",yyextra->yyLineNr,qPrint(d->name()),d->getStartDefLine(),d->getEndBodyLine());
943 yyextra->code->startFold(yyextra->yyLineNr,"","");
944 yyextra->foldStack.push_back(d);
945 }
946 }
947 }
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
948}

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

◆ codifyLines()

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 1035 of file fortrancode.l.

1036{
1037 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1038 //printf("codifyLines(%d,\"%s\")\n",yyextra->yyLineNr,text);
1039 if (text.isEmpty()) return;
1040 const char *p=text.data(),*sp=p;
1041 char c = 0;
1042 bool done=FALSE;
1043 while (!done)
1044 {
1045 sp=p;
1046 while ((c=*p++) && c!='\n') { }
1047 if (c=='\n')
1048 {
1049 yyextra->yyLineNr++;
1050 size_t l = static_cast<size_t>(p-sp-1);
1051 std::string tmp(sp,l);
1052 yyextra->code->codify(tmp.c_str());
1053 nextCodeLine(yyscanner);
1054 }
1055 else
1056 {
1057 yyextra->code->codify(QCString(sp));
1058 done=TRUE;
1059 }
1060 }
This is an alternative implementation of QCString.
Definition qcstring.h:101
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)
#define TRUE
Definition qcstring.h:37
1061}

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 1349 of file fortrancode.l.

1350{
1351 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1352 const char *p=yyextra->inputString;
1353 char c = 0;
1354 int count=1;
1355 while ((c=*p))
1356 {
1357 p++ ;
1358 if (c=='\n') count++;
1359 }
1360 if (p>yyextra->inputString && *(p-1)!='\n')
1361 { // last line does not end with a \n, so we add an extra
1362 // line and explicitly terminate the line after parsing.
1363 count++;
1364 }
1365 return count;
1366}

◆ endCodeLine()

static void endCodeLine ( yyscan_t yyscanner)
static

Definition at line 1012 of file fortrancode.l.

1013{
1014 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1015 endFontClass(yyscanner);
1016 yyextra->code->endCodeLine();
1017 yyextra->insideCodeLine=false;
static void endFontClass(yyscan_t yyscanner, bool specialComment=false)
1018}

References endFontClass().

◆ endFontClass()

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

Definition at line 853 of file fortrancode.l.

854{
855 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
856 if (yyextra->currentFontClass)
857 {
858 yyextra->code->endFontClass();
859 yyextra->currentFontClass=nullptr;
860 }
861 if (specialComment && yyextra->insideSpecialComment)
862 {
863 yyextra->code->endSpecialComment();
864 yyextra->insideSpecialComment=false;
865 }
866}

◆ endScope()

static void endScope ( yyscan_t yyscanner)
static

end scope

Definition at line 1378 of file fortrancode.l.

1379{
1380 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1381 DBG_CTX((stderr,"===> endScope %s",yytext));
1382 if (yyextra->scopeStack.empty())
1383 {
1384 DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n"));
1385 return;
1386 }
#define DBG_CTX(x)
Definition fortrancode.l:71
1387
1388 Scope &scope = yyextra->scopeStack.back();
1389 for ( const auto &name : scope.useNames)
1390 {
1391 yyextra->useMembers.erase(name.str());
1392 }
1393 yyextra->scopeStack.pop_back();
Contains names of used modules and names of local variables.
std::vector< QCString > useNames
contains names of used modules
1394}

References DBG_CTX, and Scope::useNames.

◆ generateLink() [1/2]

static void generateLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const char * lname )
static

Definition at line 1343 of file fortrancode.l.

1344{
1345 generateLink(yyscanner,ol,QCString(lname));
static void generateLink(yyscan_t yyscanner, OutputCodeList &ol, const QCString &lname)
1346}

References generateLink().

◆ generateLink() [2/2]

static void generateLink ( yyscan_t yyscanner,
OutputCodeList & ol,
const QCString & lname )
static

Definition at line 1300 of file fortrancode.l.

1301{
1302 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1303 ClassDef *cd=nullptr;
1304 NamespaceDef *nsd=nullptr;
1305 QCString name = lname;
1306 name = removeRedundantWhiteSpace(name.lower());
A abstract class representing of a compound symbol.
Definition classdef.h:104
An abstract interface of a namespace symbol.
QCString removeRedundantWhiteSpace(const QCString &s)
Definition util.cpp:578
1307
1308 // check if lowercase lname is a linkable type or interface
1309 if ( (getFortranTypeDefs(name, yyextra->currentModule, cd, yyextra->useMembers)) && cd->isLinkable() )
1310 {
1311 if ( (cd->compoundType() == ClassDef::Class) && // was Entry::INTERFACE_SEC) &&
1312 (getGenericProcedureLink(yyscanner, cd, name, ol)) )
1313 {
1314 //cout << "=== generic procedure resolved" << endl;
1315 }
1316 else
1317 { // write type or interface link
1318 writeMultiLineCodeLink(yyscanner, ol,cd,name);
1319 addToSearchIndex(yyscanner, name);
1320 }
1321 }
1322 // check for module
1323 else if ( (getFortranNamespaceDefs(name, nsd)) && nsd->isLinkable() )
1324 { // write module link
1325 writeMultiLineCodeLink(yyscanner,ol,nsd,name);
1326 addToSearchIndex(yyscanner,name);
1327 }
1328 // check for function/variable
1329 else if (getLink(yyscanner,yyextra->useMembers, name, ol, name))
1330 {
1331 //cout << "=== found link for lowercase " << lname << endl;
1332 }
1333 else
1334 {
1335 // nothing found, just write out the word
1336 //startFontClass("charliteral"); //test
1337 codifyLines(yyscanner,name);
1338 //endFontClass(yyscanner); //test
1339 addToSearchIndex(yyscanner,name);
1340 }
virtual CompoundType compoundType() const =0
Returns the type of compound this is, i.e.
virtual bool isLinkable() const =0
static bool getGenericProcedureLink(yyscan_t yyscanner, const ClassDef *cd, const QCString &memberText, OutputCodeList &ol)
gets the link to a generic procedure which depends not on the name, but on the parameter list
static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, ClassDef *&cd, const UseMap &useMap)
searches for definition of a type
static void codifyLines(yyscan_t yyscanner, const QCString &text)
static bool getFortranNamespaceDefs(const QCString &mname, NamespaceDef *&cd)
searches for definition of a module (Namespace)
static void addToSearchIndex(yyscan_t yyscanner, const QCString &text)
static bool getLink(yyscan_t yyscanner, const UseMap &useMap, const QCString &memberText, OutputCodeList &ol, const QCString &text)
static void writeMultiLineCodeLink(yyscan_t yyscanner, OutputCodeList &ol, Definition *d, const QCString &text)
1341}

References addToSearchIndex(), ClassDef::Class, codifyLines(), ClassDef::compoundType(), getFortranNamespaceDefs(), getFortranTypeDefs(), getGenericProcedureLink(), getLink(), Definition::isLinkable(), QCString::lower(), removeRedundantWhiteSpace(), and writeMultiLineCodeLink().

Referenced by generateLink(), and FTVHelp::Private::generateTree().

◆ getFortranDefs()

static MemberDef * getFortranDefs ( yyscan_t yyscanner,
const QCString & memberName,
const QCString & moduleName,
const UseMap & useMap )
static

searches for definition of function memberName

Parameters
yyscannerthe scanner data to be used
memberNamethe name of the function/variable
moduleNamename of enclosing module or null, if global entry
useMapmap of data of USE-statement
Returns
MemberDef pointer, if found, or nullptr otherwise

Definition at line 1170 of file fortrancode.l.

1172{
1173 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1174 MemberDef *potentialMd = nullptr;
1175 if (memberName.isEmpty()) return nullptr; /* empty name => nothing to link */
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
1176
1177 // look in local variables
1178 for (auto it = yyextra->scopeStack.rbegin(); it!=yyextra->scopeStack.rend(); ++it)
1179 {
1180 const Scope &scope = *it;
1181 std::string lowMemName = memberName.lower().str();
1182 if (scope.localVars .find(lowMemName)!=std::end(scope.localVars) && // local var
1183 scope.externalVars.find(lowMemName)==std::end(scope.externalVars)) // and not external
1184 {
1185 return nullptr;
1186 }
1187 }
StringUnorderedSet externalVars
contains names of external entities
StringUnorderedSet localVars
contains names of local variables
1188
1189 // search for function
1190 MemberName *mn = Doxygen::functionNameLinkedMap->find(memberName);
1191 if (!mn)
1192 {
1193 mn = Doxygen::memberNameLinkedMap->find(memberName);
1194 }
static MemberNameLinkedMap * functionNameLinkedMap
Definition doxygen.h:112
static MemberNameLinkedMap * memberNameLinkedMap
Definition doxygen.h:111
1195
1196 if (mn) // name is known
1197 {
1198 // all found functions with given name
1199 for (const auto &md : *mn)
1200 {
1201 const FileDef *fd=md->getFileDef();
1202 const GroupDef *gd=md->getGroupDef();
1203 const ClassDef *cd=md->getClassDef();
A model of a file symbol.
Definition filedef.h:99
A model of a group of symbols.
Definition groupdef.h:52
1204
1205 //cout << "found link with same name: " << fd->fileName() << " " << memberName;
1206 //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl;
1207
1208 if ((gd && gd->isLinkable()) || (fd && fd->isLinkable()))
1209 {
1210 const NamespaceDef *nspace= md->getNamespaceDef();
1211
1212 if (nspace == nullptr)
1213 { // found function in global scope
1214 if (cd == nullptr)
1215 { // Skip if bound to type
1216 if (md.get()->getFileDef() == yyextra->sourceFileDef) return md.get();
1217 else if (!potentialMd) potentialMd = md.get();
1218 }
1219 }
1220 else if (moduleName == nspace->name())
1221 { // found in local scope
1222 return md.get();
1223 }
1224 else
1225 { // else search in used modules
1226 QCString usedModuleName= nspace->name();
1227 auto use_it = useMap.find(usedModuleName.str());
1228 if (use_it!=useMap.end())
1229 {
1230 const UseEntry &ue = use_it->second;
1231 // check if only-list exists and if current entry exists is this list
1232 if (ue.onlyNames.empty())
1233 {
1234 //cout << " found in module " << usedModuleName << " entry " << memberName << endl;
1235 return md.get(); // whole module used
1236 }
1237 else
1238 {
1239 for ( const auto &name : ue.onlyNames)
1240 {
1241 //cout << " search in only: " << usedModuleName << ":: " << memberName << "==" << (*it)<< endl;
1242 if (memberName == name)
1243 {
1244 return md.get(); // found in ONLY-part of use list
1245 }
1246 }
1247 }
1248 }
1249 }
1250 } // if linkable
1251 } // for
1252 }
1253 return potentialMd;
virtual const QCString & name() const =0
data of an use-statement
Definition fortrancode.l:97
std::vector< QCString > onlyNames
1254}

References Scope::externalVars, Doxygen::functionNameLinkedMap, QCString::isEmpty(), Definition::isLinkable(), Scope::localVars, QCString::lower(), Doxygen::memberNameLinkedMap, Definition::name(), UseEntry::onlyNames, and QCString::str().

Referenced by getLink().

◆ getFortranNamespaceDefs()

static bool getFortranNamespaceDefs ( const QCString & mname,
NamespaceDef *& cd )
static

searches for definition of a module (Namespace)

Parameters
mnamethe name of the module
cdthe entry, if found or null
Returns
true, if module is found

Definition at line 1110 of file fortrancode.l.

1112{
1113 if (mname.isEmpty()) return FALSE; /* empty name => nothing to link */
1114
1115 // search for module
1116 if ((cd=Doxygen::namespaceLinkedMap->find(mname))) return TRUE;
static NamespaceLinkedMap * namespaceLinkedMap
Definition doxygen.h:115
1117
1118 return FALSE;
1119}

References FALSE, QCString::isEmpty(), Doxygen::namespaceLinkedMap, and TRUE.

Referenced by generateLink().

◆ getFortranTypeDefs()

static bool getFortranTypeDefs ( const QCString & tname,
const QCString & moduleName,
ClassDef *& cd,
const UseMap & useMap )
static

searches for definition of a type

Parameters
tnamethe name of the type
moduleNamename of enclosing module or null, if global entry
cdthe entry, if found or null
useMapmap of data of USE-statement
Returns
true, if type is found

Definition at line 1129 of file fortrancode.l.

1131{
1132 if (tname.isEmpty()) return FALSE; /* empty name => nothing to link */
1133
1134 //cout << "=== search for type: " << tname << endl;
1135
1136 // search for type
1137 if ((cd=Doxygen::classLinkedMap->find(tname)))
1138 {
1139 //cout << "=== type found in global module" << endl;
1140 return TRUE;
1141 }
1142 else if (!moduleName.isEmpty() && (cd=Doxygen::classLinkedMap->find(moduleName+"::"+tname)))
1143 {
1144 //cout << "=== type found in local module" << endl;
1145 return TRUE;
1146 }
1147 else
1148 {
1149 for (const auto &[name,useEntry] : useMap)
1150 {
1151 if ((cd=Doxygen::classLinkedMap->find(useEntry.module+"::"+tname)))
1152 {
1153 //cout << "=== type found in used module" << endl;
1154 return TRUE;
1155 }
1156 }
1157 }
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
1158
1159 return FALSE;
1160}

References Doxygen::classLinkedMap, FALSE, QCString::isEmpty(), and TRUE.

Referenced by generateLink().

◆ getGenericProcedureLink()

static bool getGenericProcedureLink ( yyscan_t ,
const ClassDef * ,
const QCString & ,
OutputCodeList &  )
static

gets the link to a generic procedure which depends not on the name, but on the parameter list

Todo
implementation

Definition at line 1260 of file fortrancode.l.

1263{
1264 return FALSE;
1265}

References FALSE.

Referenced by generateLink().

◆ getLexerFILE()

static const char * getLexerFILE ( )
inlinestatic

Definition at line 223 of file fortrancode.l.

223{return __FILE__;}

◆ getLink()

static bool getLink ( yyscan_t yyscanner,
const UseMap & useMap,
const QCString & memberText,
OutputCodeList & ol,
const QCString & text )
static

Definition at line 1267 of file fortrancode.l.

1271{
1272 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1273 MemberDef *md=nullptr;
1274 QCString memberName= removeRedundantWhiteSpace(memberText);
1275
1276 if ((md=getFortranDefs(yyscanner,memberName, yyextra->currentModule, useMap)) && md->isLinkable())
1277 {
1278 if (md->isVariable() && (md->getLanguage()!=SrcLangExt::Fortran)) return FALSE; // Non Fortran variables aren't handled yet,
1279 // see also linkifyText in util.cpp
virtual SrcLangExt getLanguage() const =0
Returns the programming language this definition was written in.
virtual bool isVariable() const =0
static MemberDef * getFortranDefs(yyscan_t yyscanner, const QCString &memberName, const QCString &moduleName, const UseMap &useMap)
searches for definition of function memberName
@ Fortran
Definition types.h:53
1280
1282 md->getBodyDef() : md->getOuterScope();
1283 if (md->getGroupDef()) d = md->getGroupDef();
1284 if (d && d->isLinkable())
1285 {
1286 if (yyextra->currentDefinition && yyextra->currentMemberDef &&
1287 yyextra->insideBody && yyextra->collectXRefs)
1288 {
1289 addDocCrossReference(yyextra->currentMemberDef,md);
1290 }
1291 writeMultiLineCodeLink(yyscanner,ol,md,!text.isEmpty() ? text : memberText);
1292 addToSearchIndex(yyscanner, !text.isEmpty() ? text : memberText);
1293 return TRUE;
1294 }
1295 }
1296 return FALSE;
virtual const FileDef * getBodyDef() const =0
virtual Definition * getOuterScope() const =0
static NamespaceDefMutable * globalScope
Definition doxygen.h:121
virtual GroupDef * getGroupDef()=0
void addDocCrossReference(const MemberDef *s, const MemberDef *d)
1297}

References addDocCrossReference(), addToSearchIndex(), FALSE, Fortran, Definition::getBodyDef(), getFortranDefs(), MemberDef::getGroupDef(), Definition::getLanguage(), Definition::getOuterScope(), Doxygen::globalScope, QCString::isEmpty(), Definition::isLinkable(), MemberDef::isVariable(), removeRedundantWhiteSpace(), TRUE, and writeMultiLineCodeLink().

◆ nextCodeLine()

static void nextCodeLine ( yyscan_t yyscanner)
static

Definition at line 1020 of file fortrancode.l.

1021{
1022 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1023 const char * fc = yyextra->currentFontClass;
1024 endCodeLine(yyscanner);
1025 if (yyextra->yyLineNr<yyextra->inputLines)
1026 {
1027 yyextra->currentFontClass = fc;
1028 startCodeLine(yyscanner);
1029 }
static void endCodeLine(yyscan_t yyscanner)
static void startCodeLine(yyscan_t yyscanner)
1030}

References endCodeLine(), and startCodeLine().

◆ parseFortranCode()

void parseFortranCode ( OutputCodeList & ,
const char * ,
const QCString & ,
bool ,
const char * ,
const FileDef * ,
int ,
int ,
bool ,
const MemberDef * ,
bool ,
const Definition * ,
bool ,
FortranFormat  )

Definition at line 1440 of file fortrancode.l.

1445{
1446 //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1447
1448 return;
1449}

◆ pop_state()

static void pop_state ( yyscan_t yyscanner)
inlinestatic

Definition at line 1592 of file fortrancode.l.

1593{
1594 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1595 if ( yyg->yy_start_stack_ptr <= 0 )
1596 warn(yyextra->fileName,yyextra->yyLineNr,"Unexpected statement '{}'",yytext );
1597 else
1598 yy_pop_state(yyscanner);
#define warn(file, line, fmt,...)
Definition message.h:97
1599}

References warn.

◆ setCurrentDoc()

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

Definition at line 885 of file fortrancode.l.

886{
887 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
888 if (Doxygen::searchIndex.enabled())
889 {
890 if (yyextra->searchCtx)
891 {
892 Doxygen::searchIndex.setCurrentDoc(yyextra->searchCtx,yyextra->searchCtx->anchor(),FALSE);
893 }
894 else
895 {
896 Doxygen::searchIndex.setCurrentDoc(yyextra->sourceFileDef,anchor,TRUE);
897 }
898 }
899}

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 954 of file fortrancode.l.

955{
956 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
957 if (yyextra->sourceFileDef)
958 {
959 //QCString lineNumber,lineAnchor;
960 //lineNumber.sprintf("%05d",yyextra->yyLineNr);
961 //lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
962
963 const Definition *d = yyextra->sourceFileDef->getSourceDefinition(yyextra->yyLineNr);
964 //printf("startCodeLine %d d=%s\n", yyextra->yyLineNr,d ? qPrint(d->name()) : "<null>");
965 if (!yyextra->includeCodeFragment && d)
966 {
967 yyextra->currentDefinition = d;
968 yyextra->currentMemberDef = yyextra->sourceFileDef->getSourceMember(yyextra->yyLineNr);
969 yyextra->insideBody = FALSE;
970 yyextra->endComment = FALSE;
971 QCString lineAnchor;
972 lineAnchor.sprintf("l%05d",yyextra->yyLineNr);
973 if (yyextra->currentMemberDef)
974 {
975 codeFolding(yyscanner,yyextra->currentMemberDef);
976 yyextra->code->writeLineNumber(yyextra->currentMemberDef->getReference(),
977 yyextra->currentMemberDef->getOutputFileBase(),
978 yyextra->currentMemberDef->anchor(),yyextra->yyLineNr,
979 !yyextra->includeCodeFragment);
980 setCurrentDoc(yyscanner,lineAnchor);
981 }
982 else if (d->isLinkableInProject())
983 {
984 codeFolding(yyscanner,d);
985 yyextra->code->writeLineNumber(d->getReference(),
987 QCString(),yyextra->yyLineNr,
988 !yyextra->includeCodeFragment);
989 setCurrentDoc(yyscanner,lineAnchor);
990 }
991 else
992 {
993 codeFolding(yyscanner,nullptr);
994 }
995 }
996 else
997 {
998 codeFolding(yyscanner,nullptr);
999 yyextra->code->writeLineNumber(QCString(),QCString(),QCString(),yyextra->yyLineNr,
1000 !yyextra->includeCodeFragment);
1001 }
1002 }
1003 yyextra->code->startCodeLine(yyextra->yyLineNr);
1004 yyextra->insideCodeLine=true;
1005 if (yyextra->currentFontClass)
1006 {
1007 yyextra->code->startFontClass(QCString(yyextra->currentFontClass));
1008 }
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)
static void codeFolding(yyscan_t yyscanner, const Definition *d)
1009}

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

◆ startFontClass()

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

Definition at line 868 of file fortrancode.l.

869{
870 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
871 if (specialComment)
872 {
873 yyextra->code->startSpecialComment();
874 yyextra->insideSpecialComment = true;
875 }
876 // if font class is already set don't stop and start it.
877 if (qstrcmp(yyextra->currentFontClass,s)!=0)
878 {
879 endFontClass(yyscanner);
880 yyextra->code->startFontClass(QCString(s));
881 yyextra->currentFontClass=s;
882 }
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
883}

References endFontClass(), and qstrcmp().

◆ startScope()

static void startScope ( yyscan_t yyscanner)
static

start scope

Definition at line 1370 of file fortrancode.l.

1371{
1372 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1373 DBG_CTX((stderr, "===> startScope %s",yytext));
1374 yyextra->scopeStack.emplace_back();
1375}

References DBG_CTX.

Referenced by findScopeFromQualifiedName().

◆ stateToString()

static const char * stateToString ( int state)
static

◆ writeMultiLineCodeLink()

static void writeMultiLineCodeLink ( yyscan_t yyscanner,
OutputCodeList & ol,
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 1067 of file fortrancode.l.

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

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

◆ yylex()

int yylex ( yyscan_t yyscanner)

Definition at line 277 of file fortrancode.l.

282 {IGNORE}/{BS}"(" { // do not search keywords, intrinsics... TODO: complete list
283 codifyLines(yyscanner,yytext);
284 }
285 /*-------- inner construct ---------------------------------------------------*/
286
287<Start>{COMMANDS}/{BS}[,( \t\n] { // highlight
288 /* font class is defined e.g. in doxygen.css */
289 startFontClass(yyscanner,"keyword");
290 codifyLines(yyscanner,yytext);
291 endFontClass(yyscanner);
292 }
static void startFontClass(yyscan_t yyscanner, const char *s, bool specialComment=false)
293<Start>{FLOW}/{BS}[,( \t\n] {
294 if (yyextra->isFixedForm)
295 {
296 if ((yy_my_start == 1) && ((yytext[0] == 'c') || (yytext[0] == 'C'))) YY_FTN_REJECT;
297 }
298 if (yyextra->currentMemberDef && yyextra->currentMemberDef->isFunction())
299 {
300 std::lock_guard<std::mutex> lock(Doxygen::countFlowKeywordsMutex);
301 MemberDefMutable *mdm = toMemberDefMutable(const_cast<MemberDef*>(yyextra->currentMemberDef));
302 if (mdm)
303 {
305 }
306 }
307 /* font class is defined e.g. in doxygen.css */
308 startFontClass(yyscanner,"keywordflow");
309 codifyLines(yyscanner,yytext);
310 endFontClass(yyscanner);
311 }
static std::mutex countFlowKeywordsMutex
Definition doxygen.h:141
virtual void incrementFlowKeyWordCount()=0
#define YY_FTN_REJECT
Definition fortrancode.l:89
int yy_my_start
Definition fortrancode.l:85
MemberDefMutable * toMemberDefMutable(Definition *d)
312<Start>{BS}(RANK){BS_}(DEFAULT) |
313<Start>{BS}(RANK)/{BS}"("{BS}([0-9]+|"*"){BS}")" |
314<Start>{BS}(CASE|CLASS|TYPE){BS_}(IS|DEFAULT) {
315 startFontClass(yyscanner,"keywordflow");
316 codifyLines(yyscanner,yytext);
317 endFontClass(yyscanner);
318 }
319<Start>{BS}"end"({BS}{FLOW})/[ \t\n] { // list is a bit long as not all have possible end
320 startFontClass(yyscanner,"keywordflow");
321 codifyLines(yyscanner,yytext);
322 endFontClass(yyscanner);
323 }
324<Start>"implicit"{BS}("none"|{TYPE_SPEC}) {
325 startFontClass(yyscanner,"keywordtype");
326 codifyLines(yyscanner,yytext);
327 endFontClass(yyscanner);
328 }
329<Start>^{BS}"namelist"/[/] { // Namelist specification
330 startFontClass(yyscanner,"keywordtype");
331 codifyLines(yyscanner,yytext);
332 endFontClass(yyscanner);
333 }
334 /*-------- use statement -------------------------------------------*/
335<Start>"use"{BS_} {
336 startFontClass(yyscanner,"keywordtype");
337 codifyLines(yyscanner,yytext);
338 endFontClass(yyscanner);
339 yy_push_state(YY_START,yyscanner);
340 BEGIN(Use);
341 }
342<Use>"ONLY" { // TODO: rename
343 startFontClass(yyscanner,"keywordtype");
344 codifyLines(yyscanner,yytext);
345 endFontClass(yyscanner);
346 yy_push_state(YY_START,yyscanner);
347 BEGIN(UseOnly);
348 }
349<Use>{ID} {
350 QCString tmp(yytext);
351 tmp = tmp.lower();
352 yyextra->insideBody=TRUE;
353 generateLink(yyscanner,*yyextra->code, yytext);
354 yyextra->insideBody=FALSE;
355
356 /* append module name to use dict */
357 yyextra->useEntry = UseEntry();
358 yyextra->useEntry.module = tmp;
359 yyextra->useMembers.emplace(tmp.str(), yyextra->useEntry);
360 addUse(yyscanner,tmp);
361 }
static void addUse(yyscan_t yyscanner, const QCString &moduleName)
362<Use,UseOnly,Import>{BS},{BS} { codifyLines(yyscanner,yytext); }
363<UseOnly,Import>{BS}&{BS}"\n" { codifyLines(yyscanner,yytext);
364 yyextra->contLineNr++;
#define YY_FTN_RESET
Definition fortrancode.l:88
366<UseOnly>{ID} {
367 QCString tmp(yytext);
368 tmp = tmp.lower();
369 yyextra->useEntry.onlyNames.push_back(tmp);
370 yyextra->insideBody=TRUE;
371 generateLink(yyscanner,*yyextra->code, yytext);
372 yyextra->insideBody=FALSE;
373 }
374<Use,UseOnly,Import>"\n" {
375 unput(*yytext);
376 pop_state(yyscanner);
378 }
static void pop_state(yyscan_t yyscanner)
379<*>"import"{BS}/"\n" |
380<*>"import"{BS_} {
381 if(YY_START == String) YY_FTN_REJECT; // ignore in strings
382 startFontClass(yyscanner,"keywordtype");
383 codifyLines(yyscanner,yytext);
384 endFontClass(yyscanner);
385 yy_push_state(YY_START,yyscanner);
386 BEGIN(Import);
387 }
388<Import>{ID} {
389 yyextra->insideBody=TRUE;
390 generateLink(yyscanner,*yyextra->code, yytext);
391 yyextra->insideBody=FALSE;
392 }
393<Import>("ONLY"|"NONE"|"ALL") {
394 startFontClass(yyscanner,"keywordtype");
395 codifyLines(yyscanner,yytext);
396 endFontClass(yyscanner);
397 }
398 /*-------- fortran module -----------------------------------------*/
399<Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n { //
400 startScope(yyscanner);
401 startFontClass(yyscanner,"keyword");
402 codifyLines(yyscanner,yytext);
403 endFontClass(yyscanner);
404 yy_push_state(YY_START,yyscanner);
405 BEGIN(ClassName);
406 if (!qstricmp(yytext,"module")) yyextra->currentModule="module";
407 }
static void startScope(yyscan_t yyscanner)
start scope
int qstricmp(const char *s1, const char *s2)
Definition qcstring.cpp:442
408<Start>("enum")/{BS_}|{BS}{COMMA}{BS}{LANGUAGE_BIND_SPEC}|\n { //
409 startScope(yyscanner);
410 startFontClass(yyscanner,"keyword");
411 codifyLines(yyscanner,yytext);
412 endFontClass(yyscanner);
413 yy_push_state(YY_START,yyscanner);
414 BEGIN(ClassName);
415 }
416<*>{LANGUAGE_BIND_SPEC} { //
417 if(YY_START == String) YY_FTN_REJECT; // ignore in strings
418 startFontClass(yyscanner,"keyword");
419 codifyLines(yyscanner,yytext);
420 endFontClass(yyscanner);
421 }
422<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n { //
423 startScope(yyscanner);
424 startFontClass(yyscanner,"keyword");
425 codifyLines(yyscanner,yytext);
426 endFontClass(yyscanner);
427 yy_push_state(YY_START,yyscanner);
428 BEGIN(ClassName);
429 }
430<ClassName>{ID} {
431 if (yyextra->currentModule == "module")
432 {
433 yyextra->currentModule=yytext;
434 yyextra->currentModule = yyextra->currentModule.lower();
435 }
436 generateLink(yyscanner,*yyextra->code,yytext);
437 pop_state(yyscanner);
438 }
439<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable declaration
440 startFontClass(yyscanner,"keyword");
441 yyextra->code->codify(QCString(yytext));
442 endFontClass(yyscanner);
443 }
444<ClassName>\n { // interface may be without name
445 pop_state(yyscanner);
447 }
448<Start>^{BS}"end"({BS_}"enum").* {
450 }
451<Start>^{BS}"end"({BS_}"type").* {
453 }
454<Start>^{BS}"end"({BS_}"module").* { // just reset yyextra->currentModule, rest is done in following rule
455 yyextra->currentModule=nullptr;
457 }
458 /*-------- subprog definition -------------------------------------*/
459<Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_} { // TYPE_SPEC is for old function style function result
460 startFontClass(yyscanner,"keyword");
461 codifyLines(yyscanner,yytext);
462 endFontClass(yyscanner);
463 }
464<Start>({PREFIX}{BS_})?{SUBPROG}{BS_} { // Fortran subroutine or function found
465 startFontClass(yyscanner,"keyword");
466 codifyLines(yyscanner,yytext);
467 endFontClass(yyscanner);
468 yy_push_state(YY_START,yyscanner);
469 BEGIN(Subprog);
470 }
471<Subprog>{ID} { // subroutine/function name
472 DBG_CTX((stderr, "===> start subprogram %s\n", yytext));
473 startScope(yyscanner);
474 generateLink(yyscanner,*yyextra->code,yytext);
475 }
476<Subprog>"result"/{BS}"("[^)]*")" {
477 startFontClass(yyscanner,"keyword");
478 codifyLines(yyscanner,yytext);
479 endFontClass(yyscanner);
480 }
481<Subprog>"("[^)]*")" { // ignore rest of line
482 codifyLines(yyscanner,yytext);
483 }
484<Subprog,Subprogend>"\n" { codifyLines(yyscanner,yytext);
485 yyextra->contLineNr++;
486 pop_state(yyscanner);
488 }
489<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface")?{BS} { // Fortran subroutine or function ends
490 //cout << "===> end function " << yytext << endl;
491 endScope(yyscanner);
492 startFontClass(yyscanner,"keyword");
493 codifyLines(yyscanner,yytext);
494 endFontClass(yyscanner);
495 yy_push_state(YY_START,yyscanner);
496 BEGIN(Subprogend);
497 }
static void endScope(yyscan_t yyscanner)
end scope
498<Subprogend>{ID}/{BS}(\n|!|;) {
499 generateLink(yyscanner,*yyextra->code,yytext);
500 pop_state(yyscanner);
501 }
502<Start>"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"enum"|"type"|"interface"){BS}/(\n|!|;) { // Fortran subroutine or function ends
503 //cout << "===> end function " << yytext << endl;
504 endScope(yyscanner);
505 startFontClass(yyscanner,"keyword");
506 codifyLines(yyscanner,yytext);
507 endFontClass(yyscanner);
508 }
509 /*-------- variable declaration ----------------------------------*/
510<Start>^{BS}"real"/[,:( ] { // real is a bit tricky as it is a data type but also a function.
511 yy_push_state(YY_START,yyscanner);
512 BEGIN(Declaration);
513 startFontClass(yyscanner,"keywordtype");
514 yyextra->code->codify(QCString(yytext));
515 endFontClass(yyscanner);
516 }
517<Start>{TYPE_SPEC}/[,:( ] {
518 QCString typ(yytext);
519 typ = removeRedundantWhiteSpace(typ.lower());
520 if (typ.startsWith("real")) YY_FTN_REJECT;
521 if (typ == "type" || typ == "class" || typ == "procedure") yyextra->inTypeDecl = 1;
522 yy_push_state(YY_START,yyscanner);
523 BEGIN(Declaration);
524 startFontClass(yyscanner,"keywordtype");
525 yyextra->code->codify(QCString(yytext));
526 endFontClass(yyscanner);
527 }
528<Start>{ATTR_SPEC} {
529 if (QCString(yytext) == "external")
530 {
531 yy_push_state(YY_START,yyscanner);
532 BEGIN(Declaration);
533 yyextra->isExternal = true;
534 }
535 startFontClass(yyscanner,"keywordtype");
536 yyextra->code->codify(QCString(yytext));
537 endFontClass(yyscanner);
538 }
539<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable declaration
540 if (QCString(yytext) == "external") yyextra->isExternal = true;
541 startFontClass(yyscanner,"keywordtype");
542 yyextra->code->codify(QCString(yytext));
543 endFontClass(yyscanner);
544 }
545<Declaration>{ID} { // local var
546 if (yyextra->isFixedForm && yy_my_start == 1)
547 {
548 startFontClass(yyscanner,"comment");
549 yyextra->code->codify(QCString(yytext));
550 endFontClass(yyscanner);
551 }
552 else if (yyextra->currentMemberDef &&
553 ((yyextra->currentMemberDef->isFunction() && (yyextra->currentMemberDef->typeString()!=QCString("subroutine") || yyextra->inTypeDecl)) ||
554 yyextra->currentMemberDef->isVariable() || yyextra->currentMemberDef->isEnumValue()
555 )
556 )
557 {
558 generateLink(yyscanner,*yyextra->code, yytext);
559 }
560 else
561 {
562 yyextra->code->codify(QCString(yytext));
563 addLocalVar(yyscanner,QCString(yytext));
564 }
565 }
static void addLocalVar(yyscan_t yyscanner, const QCString &varName)
566<Declaration>{BS}("=>"|"="){BS} { // Procedure binding
567 BEGIN(DeclarationBinding);
568 yyextra->code->codify(QCString(yytext));
569 }
570<DeclarationBinding>{ID} { // Type bound procedure link
571 generateLink(yyscanner,*yyextra->code, yytext);
572 pop_state(yyscanner);
573 }
574<Declaration>[(] { // start of array or type / class specification
575 yyextra->bracketCount++;
576 yyextra->code->codify(QCString(yytext));
577 }
578
579<Declaration>[)] { // end array specification
580 yyextra->bracketCount--;
581 if (!yyextra->bracketCount) yyextra->inTypeDecl = 0;
582 yyextra->code->codify(QCString(yytext));
583 }
584
585<Declaration,DeclarationBinding>"&" { // continuation line
586 yyextra->code->codify(QCString(yytext));
587 if (!yyextra->isFixedForm)
588 {
589 yy_push_state(YY_START,yyscanner);
590 BEGIN(DeclContLine);
591 }
592 }
593<DeclContLine>"\n" { // declaration not yet finished
594 yyextra->contLineNr++;
595 codifyLines(yyscanner,yytext);
596 yyextra->bracketCount = 0;
597 pop_state(yyscanner);
599 }
600<Declaration,DeclarationBinding>"\n" { // end declaration line (?)
601 if (yyextra->endComment)
602 {
603 yyextra->endComment=FALSE;
604 }
605 else
606 {
607 codifyLines(yyscanner,yytext);
608 }
609 yyextra->bracketCount = 0;
610 yyextra->contLineNr++;
611 if (!(yyextra->hasContLine && yyextra->hasContLine[yyextra->contLineNr - 1]))
612 {
613 yyextra->isExternal = false;
614 pop_state(yyscanner);
615 }
617 }
618
619 /*-------- subprog calls -----------------------------------------*/
620
621<Start>"call"{BS_} {
622 startFontClass(yyscanner,"keyword");
623 codifyLines(yyscanner,yytext);
624 endFontClass(yyscanner);
625 yy_push_state(YY_START,yyscanner);
626 BEGIN(SubCall);
627 }
628<SubCall>{ID} { // subroutine call
629 yyextra->insideBody=TRUE;
630 generateLink(yyscanner,*yyextra->code, yytext);
631 yyextra->insideBody=FALSE;
632 pop_state(yyscanner);
633 }
634<Start>{ID}{BS}/"(" { // function call
635 if (yyextra->isFixedForm && yy_my_start == 6)
636 {
637 // fixed form continuation line
639 }
640 else if (QCString(yytext).stripWhiteSpace().lower() == "type")
641 {
642 yy_push_state(YY_START,yyscanner);
643 BEGIN(Declaration);
644 startFontClass(yyscanner,"keywordtype");
645 yyextra->code->codify(QCString(yytext).stripWhiteSpace());
646 endFontClass(yyscanner);
647 yyextra->code->codify(QCString(yytext + 4));
648 }
649 else
650 {
651 yyextra->insideBody=TRUE;
652 generateLink(yyscanner,*yyextra->code,yytext);
653 yyextra->insideBody=FALSE;
654 }
655 }
std::string_view stripWhiteSpace(std::string_view s)
Given a string view s, returns a new, narrower view on that string, skipping over any leading or trai...
Definition stringutil.h:72
656
657 /*-------- comments ---------------------------------------------------*/
658<Start,Declaration,DeclarationBinding>\n?{BS}"!>"|"!<" { // start comment line or comment block
659 if (yytext[0] == '\n')
660 {
661 yyextra->contLineNr++;
662 yy_old_start = 0;
663 yy_my_start = 1;
664 yy_end = static_cast<int>(yyleng);
665 }
666 // Actually we should see if ! on position 6, can be continuation
667 // but the chance is very unlikely, so no effort to solve it here
668 yy_push_state(YY_START,yyscanner);
669 BEGIN(DocBlock);
670 yyextra->docBlock=yytext;
671 }
int yy_old_start
Definition fortrancode.l:84
int yy_end
Definition fortrancode.l:86
672<Declaration,DeclarationBinding>{BS}"!<" { // start comment line or comment block
673 yy_push_state(YY_START,yyscanner);
674 BEGIN(DocBlock);
675 yyextra->docBlock=yytext;
676 }
677
678<DocBlock>.* { // contents of current comment line
679 yyextra->docBlock+=yytext;
680 }
681<DocBlock>"\n"{BS}("!>"|"!<"|"!!") { // comment block (next line is also comment line)
682 yyextra->contLineNr++;
683 yy_old_start = 0;
684 yy_my_start = 1;
685 yy_end = static_cast<int>(yyleng);
686 // Actually we should see if ! on position 6, can be continuation
687 // but the chance is very unlikely, so no effort to solve it here
688 yyextra->docBlock+=yytext;
689 }
690<DocBlock>"\n" { // comment block ends at the end of this line
691 // remove special comment (default config)
692 yyextra->contLineNr++;
693 startFontClass(yyscanner,"comment");
694 codifyLines(yyscanner,yyextra->docBlock);
695 endFontClass(yyscanner);
696 unput(*yytext);
697 yyextra->contLineNr--;
698 pop_state(yyscanner);
700 }
701
702<*>"!"[^><\n].*|"!"$ { // normal comment
703 if(YY_START == String) YY_FTN_REJECT; // ignore in strings
704 if (yyextra->isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
705 startFontClass(yyscanner,"comment");
706 codifyLines(yyscanner,yytext);
707 endFontClass(yyscanner);
708 }
709
710<*>^[Cc*].* { // normal comment
711 if(! yyextra->isFixedForm) YY_FTN_REJECT;
712
713 startFontClass(yyscanner,"comment");
714 codifyLines(yyscanner,yytext);
715 endFontClass(yyscanner);
716 }
717<*>"assignment"/{BS}"("{BS}"="{BS}")" {
718 if(YY_START == String) YY_FTN_REJECT; // ignore in strings
719 startFontClass(yyscanner,"keyword");
720 codifyLines(yyscanner,yytext);
721 endFontClass(yyscanner);
722 }
723<*>"operator"/{BS}"("[^)]*")" {
724 if(YY_START == String) YY_FTN_REJECT; // ignore in strings
725 startFontClass(yyscanner,"keyword");
726 codifyLines(yyscanner,yytext);
727 endFontClass(yyscanner);
728 }
729
730 /*------ preprocessor --------------------------------------------*/
731<Start>"#".*\n {
732 if (yyextra->isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
733 yyextra->contLineNr++;
734 startFontClass(yyscanner,"preprocessor");
735 codifyLines(yyscanner,yytext);
736 endFontClass(yyscanner);
738 }
739 /*------ variable references? -------------------------------------*/
740
741<Start>"%"{BS}{ID} { // ignore references to elements
742 yyextra->code->codify(QCString(yytext));
743 }
744<Start>{ID} {
745 yyextra->insideBody=TRUE;
746 generateLink(yyscanner,*yyextra->code, yytext);
747 yyextra->insideBody=FALSE;
748 }
749 /*------ strings --------------------------------------------------*/
750<String>\n { // string with \n inside
751 yyextra->contLineNr++;
752 yyextra->str+=yytext;
753 startFontClass(yyscanner,"stringliteral");
754 codifyLines(yyscanner,yyextra->str);
755 endFontClass(yyscanner);
756 yyextra->str = "";
758 }
759<String>\"|\' { // string ends with next quote without previous backspace
760 if(yytext[0]!=yyextra->stringStartSymbol) YY_FTN_REJECT; // single vs double quote
761 yyextra->str+=yytext;
762 startFontClass(yyscanner,"stringliteral");
763 codifyLines(yyscanner,yyextra->str);
764 endFontClass(yyscanner);
765 pop_state(yyscanner);
766 }
767<String>[\x80-\xFF]* |
768<String>. {yyextra->str+=yytext;}
769
770<*>\"|\' { /* string starts */
771 /* if(YY_START == StrIgnore) YY_FTN_REJECT; // ignore in simple comments */
772 if (yyextra->isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
773 yy_push_state(YY_START,yyscanner);
774 yyextra->stringStartSymbol=yytext[0]; // single or double quote
775 BEGIN(String);
776 yyextra->str=yytext;
777 }
778 /*-----------------------------------------------------------------------------*/
779
780<*>\n {
781 if (yyextra->endComment)
782 {
783 yyextra->endComment=FALSE;
784 }
785 else
786 {
787 codifyLines(yyscanner,yytext);
788 // comment cannot extend over the end of a line so should always be terminated at the end of the line.
789 if (yyextra->currentFontClass && !strcmp(yyextra->currentFontClass,"comment")) endFontClass(yyscanner);
790 }
791 yyextra->contLineNr++;
793 }
794<*>^{BS}"type"{BS}"=" { yyextra->code->codify(QCString(yytext)); }
795
796<*>[\x80-\xFF]* { // keep utf8 characters together...
797 if (yyextra->isFixedForm && yy_my_start > yyextra->fixedCommentAfter)
798 {
799 startFontClass(yyscanner,"comment");
800 codifyLines(yyscanner,yytext);
801 }
802 else
803 {
804 yyextra->code->codify(QCString(yytext));
805 }
806 }
807<*>. {
808 if (yyextra->isFixedForm && yy_my_start > yyextra->fixedCommentAfter)
809 {
810 //yy_push_state(YY_START,yyscanner);
811 //BEGIN(DocBlock);
812 //yyextra->docBlock=yytext;
813 startFontClass(yyscanner,"comment");
814 codifyLines(yyscanner,yytext);
815 }
816 else
817 {
818 yyextra->code->codify(QCString(yytext));
819 }
820 }
821<*>{LOG_OPER} { // Fortran logical comparison keywords
822 yyextra->code->codify(QCString(yytext));
823 }
824<*><<EOF>> {
825 if (YY_START == DocBlock)
826 {
827 startFontClass(yyscanner,"comment");
828 codifyLines(yyscanner,yyextra->docBlock);
829 endFontClass(yyscanner);
830 }
831 yyterminate();
832 }
#define yyterminate()
833%%

◆ yyread()

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

Definition at line 838 of file fortrancode.l.

839{
840 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
841 int inputPosition = yyextra->inputPosition;
842 const char *s = yyextra->inputString + inputPosition;
843 int c=0;
844 while( c < max_size && *s)
845 {
846 *buf++ = *s++;
847 c++;
848 }
849 yyextra->inputPosition += c;
850 return c;
851}

Variable Documentation

◆ yy_end

int yy_end = 1

Definition at line 86 of file fortrancode.l.

◆ yy_my_start

int yy_my_start = 0

Definition at line 85 of file fortrancode.l.

◆ yy_old_start

int yy_old_start = 0

Definition at line 84 of file fortrancode.l.