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

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

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

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

References Scope::useNames.

◆ checkContLines()

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

Definition at line 1415 of file fortrancode.l.

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

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

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

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

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

References DBG_CTX, and Scope::useNames.

◆ generateLink() [1/2]

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

Definition at line 1341 of file fortrancode.l.

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

References generateLink().

◆ generateLink() [2/2]

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

Definition at line 1298 of file fortrancode.l.

1299{
1300 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1301 ClassDef *cd=nullptr;
1302 NamespaceDef *nsd=nullptr;
1303 QCString name = lname;
1304 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
1305
1306 // check if lowercase lname is a linkable type or interface
1307 if ( (getFortranTypeDefs(name, yyextra->currentModule, cd, yyextra->useMembers)) && cd->isLinkable() )
1308 {
1309 if ( (cd->compoundType() == ClassDef::Class) && // was Entry::INTERFACE_SEC) &&
1310 (getGenericProcedureLink(yyscanner, cd, name, ol)) )
1311 {
1312 //cout << "=== generic procedure resolved" << endl;
1313 }
1314 else
1315 { // write type or interface link
1316 writeMultiLineCodeLink(yyscanner, ol,cd,name);
1317 addToSearchIndex(yyscanner, name);
1318 }
1319 }
1320 // check for module
1321 else if ( (getFortranNamespaceDefs(name, nsd)) && nsd->isLinkable() )
1322 { // write module link
1323 writeMultiLineCodeLink(yyscanner,ol,nsd,name);
1324 addToSearchIndex(yyscanner,name);
1325 }
1326 // check for function/variable
1327 else if (getLink(yyscanner,yyextra->useMembers, name, ol, name))
1328 {
1329 //cout << "=== found link for lowercase " << lname << endl;
1330 }
1331 else
1332 {
1333 // nothing found, just write out the word
1334 //startFontClass("charliteral"); //test
1335 codifyLines(yyscanner,name);
1336 //endFontClass(yyscanner); //test
1337 addToSearchIndex(yyscanner,name);
1338 }
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)
1339}

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

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

1261{
1262 return FALSE;
1263}

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

1269{
1270 struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
1271 MemberDef *md=nullptr;
1272 QCString memberName= removeRedundantWhiteSpace(memberText);
A model of a class/file/namespace member symbol.
Definition memberdef.h:48
1273
1274 if ((md=getFortranDefs(yyscanner,memberName, yyextra->currentModule, useMap)) && md->isLinkable())
1275 {
1276 if (md->isVariable() && (md->getLanguage()!=SrcLangExt::Fortran)) return FALSE; // Non Fortran variables aren't handled yet,
1277 // 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
1278
1280 md->getBodyDef() : md->getOuterScope();
1281 if (md->getGroupDef()) d = md->getGroupDef();
1282 if (d && d->isLinkable())
1283 {
1284 if (yyextra->currentDefinition && yyextra->currentMemberDef &&
1285 yyextra->insideBody && yyextra->collectXRefs)
1286 {
1287 addDocCrossReference(yyextra->currentMemberDef,md);
1288 }
1289 writeMultiLineCodeLink(yyscanner,ol,md,!text.isEmpty() ? text : memberText);
1290 addToSearchIndex(yyscanner, !text.isEmpty() ? text : memberText);
1291 return TRUE;
1292 }
1293 }
1294 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)
1295}

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

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

◆ pop_state()

static void pop_state ( yyscan_t yyscanner)
inlinestatic

Definition at line 1590 of file fortrancode.l.

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

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

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

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.