Skip to content

Commit

Permalink
Bug 625601 - FORTRAN: recognition free versus fixed formatted code
Browse files Browse the repository at this point in the history
The recognition of the type (free or fixed) of Fortran code is not reliable possible. A well known possibility as used with compilers as well is to specify the type of code by means of the extension.
With EXTENSION_MAPPING it is possible to select the type of Fortran code, when not explicitly set doxygen tries to guess the type of Fortran code.
  • Loading branch information
albert-github committed Mar 9, 2014
1 parent 8eeaae0 commit 2dec106
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 42 deletions.
17 changes: 13 additions & 4 deletions doc/docblocks.doc
Expand Up @@ -460,11 +460,18 @@ settings where overruled.
When using doxygen for Fortran code you should
set \ref cfg_optimize_for_fortran "OPTIMIZE_FOR_FORTRAN" to \c YES.

The parser tries to guess wheter the source code is fixed format Fortran or
free format Fortran code. This is not always correct, in the later case
one should use \ref cfg_extension_mapping "EXTENSION_MAPPING" to correct this.
By setteing `EXTENSION_MAPPING = f=FortranFixed f90=FortranFree` files with
extension \c f90 are interpreted as fixed format Fortran code and files with

This comment has been minimized.

Copy link
@dnm

dnm Jun 19, 2014

This line seems to be a typo, as a f90 extension should denote free format Fortran code -- not fixed format -- both by convention and in keeping with the line above (466) (f=FortranFixed f90=FortranFree).

extension \c f are interpreted as free format Fortran code.

For Fortran "!>" or "!<" starts a comment and "!!" or "!>" can be used to
continue an one line comment into a multi-line comment.

Here is an example of a documented Fortran subroutine:
\verbatim
\code{.f}
!> Build the restriction matrix for the aggregation
!! method.
!! @param aggr information about the aggregates
Expand All @@ -474,18 +481,20 @@ Here is an example of a documented Fortran subroutine:
Type(SpMtx), intent(in) :: A !< our fine level matrix
Type(Aggrs), intent(in) :: aggr
Type(SpMtx), intent(out) :: Restrict !< Our restriction matrix
\endverbatim
!...
end subroutine
\endcode

As an alternative you can also use comments in fixed format code:

\verbatim
\code{.f}
C> Function comment
C> another line of comment
function A(i)
C> input parameter
integer i
end function A
\endverbatim
\endcode

\subsection tclblocks Comment blocks in Tcl

Expand Down
5 changes: 4 additions & 1 deletion src/config.xml
Expand Up @@ -588,7 +588,10 @@ Go to the <a href="commands.html">next</a> section or return to the
Doxygen has a built-in mapping, but you can override or extend it using this tag.
The format is <code>ext=language</code>, where \c ext is a file extension, and language is one of
the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
Objective-C, Python, Fortran, VHDL.
Objective-C, Python, Fortran (fixed format Fortran: FortranFixed,
free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In
the later case the parser tries to guess whether the code is fixed or free
formatted code, this is the default for Fortran type files), VHDL.
For instance to make doxygen treat
<code>.inc</code> files as Fortran files (default is PHP), and <code>.f</code> files as C (default is Fortran),
Expand Down
16 changes: 9 additions & 7 deletions src/doxygen.cpp
Expand Up @@ -9877,13 +9877,15 @@ void initDoxygen()
initPreprocessor();

Doxygen::parserManager = new ParserManager;
Doxygen::parserManager->registerParser("c", new CLanguageScanner, TRUE);
Doxygen::parserManager->registerParser("python", new PythonLanguageScanner);
Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner);
Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner);
Doxygen::parserManager->registerParser("dbusxml", new DBusXMLScanner);
Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner);
Doxygen::parserManager->registerParser("md", new MarkdownFileParser);
Doxygen::parserManager->registerParser("c", new CLanguageScanner, TRUE);
Doxygen::parserManager->registerParser("python", new PythonLanguageScanner);
Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner);
Doxygen::parserManager->registerParser("fortranfree", new FortranLanguageScannerFree);
Doxygen::parserManager->registerParser("fortranfixed", new FortranLanguageScannerFixed);
Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner);
Doxygen::parserManager->registerParser("dbusxml", new DBusXMLScanner);
Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner);
Doxygen::parserManager->registerParser("md", new MarkdownFileParser);

// register any additional parsers here...

Expand Down
2 changes: 1 addition & 1 deletion src/fortrancode.h
Expand Up @@ -28,7 +28,7 @@ void parseFortranCode(CodeOutputInterface &,const char *,const QCString &,
bool ,const char *,FileDef *fd,
int startLine,int endLine,bool inlineFragment,
MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx,
bool collectRefs);
bool collectRefs, FortranKind codeType);
void resetFortranCodeParserState();
void codeFreeScanner();

Expand Down
8 changes: 5 additions & 3 deletions src/fortrancode.l
Expand Up @@ -154,11 +154,13 @@ static int bracketCount = 0;

// simplified way to know if this is fixed form
// duplicate in fortranscanner.l
static bool recognizeFixedForm(const char* contents)
static bool recognizeFixedForm(const char* contents, FortranKind codeType)
{
int column=0;
bool skipLine=FALSE;

if (codeType == FORTRAN_FIXED) return TRUE;
if (codeType == FORTRAN_FREE) return FALSE;
for (int i=0;;i++)
{
column++;
Expand Down Expand Up @@ -1108,7 +1110,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *className,const QCStri
bool exBlock, const char *exName,FileDef *fd,
int startLine,int endLine,bool inlineFragment,
MemberDef *memberDef,bool,Definition *searchCtx,
bool collectXRefs)
bool collectXRefs, FortranKind codeType)
{
//printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);

Expand All @@ -1122,7 +1124,7 @@ void parseFortranCode(CodeOutputInterface &od,const char *className,const QCStri
g_code = &od;
g_inputString = s;
g_inputPosition = 0;
g_isFixedForm = recognizeFixedForm((const char*)s);
g_isFixedForm = recognizeFixedForm((const char*)s,codeType);
g_currentFontClass = 0;
g_needsTermination = FALSE;
g_searchCtx = searchCtx;
Expand Down
22 changes: 19 additions & 3 deletions src/fortranscanner.h
Expand Up @@ -19,6 +19,7 @@
#define SCANNER_FORTRAN_H

#include "parserintf.h"
#include "util.h"

/** \brief Fortran language parser using state-based lexical scanning.
*
Expand All @@ -27,9 +28,10 @@
class FortranLanguageScanner : public ParserInterface
{
public:
virtual ~FortranLanguageScanner() {}
FortranLanguageScanner(void) { codeType = FORTRAN_UNKNOWN;}
virtual ~FortranLanguageScanner(void) {}
void startTranslationUnit(const char *) {}
void finishTranslationUnit() {}
void finishTranslationUnit(void) {}
void parseInput(const char *fileName,
const char *fileBuf,
Entry *root,
Expand All @@ -51,8 +53,22 @@ class FortranLanguageScanner : public ParserInterface
Definition *searchCtx=0,
bool collectXRefs=TRUE
);
void resetCodeParserState();
void resetCodeParserState(void);
void parsePrototype(const char *text);

FortranKind codeType;
};

class FortranLanguageScannerFree : public FortranLanguageScanner
{
public:
FortranLanguageScannerFree(void) { codeType = FORTRAN_FREE; }
};

class FortranLanguageScannerFixed : public FortranLanguageScanner
{
public:
FortranLanguageScannerFixed(void) { codeType = FORTRAN_FIXED; }
};

#endif
15 changes: 9 additions & 6 deletions src/fortranscanner.l
Expand Up @@ -187,7 +187,7 @@ static InterfaceType ifType = IF_NONE;
static bool functionLine = FALSE;

static char stringStartSymbol; // single or double quote
static bool parsingPrototype = FALSE; // see parsePrototype()
static bool parsingPrototype = FALSE; // see parsePrototype()

//! Accumulated modifiers of current statement, eg variable declaration.
static SymbolModifiers currentModifiers;
Expand Down Expand Up @@ -1313,11 +1313,14 @@ void truncatePrepass(int index)

// simplified way to know if this is fixed form
// duplicate in fortrancode.l
static bool recognizeFixedForm(const char* contents)
static bool recognizeFixedForm(const char* contents, FortranKind codeType)
{
int column=0;
bool skipLine=FALSE;

if (codeType == FORTRAN_FIXED) return TRUE;
if (codeType == FORTRAN_FREE) return FALSE;

for(int i=0;;i++) {
column++;

Expand Down Expand Up @@ -2243,7 +2246,7 @@ level--;
#endif


static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
static void parseMain(const char *fileName,const char *fileBuf,Entry *rt, FortranKind codeType)
{
char *tmpBuf = NULL;
initParser();
Expand All @@ -2263,7 +2266,7 @@ static void parseMain(const char *fileName,const char *fileBuf,Entry *rt)
inputFile.setName(fileName);
if (inputFile.open(IO_ReadOnly))
{
isFixedForm = recognizeFixedForm(fileBuf);
isFixedForm = recognizeFixedForm(fileBuf,codeType);

if (isFixedForm)
{
Expand Down Expand Up @@ -2342,7 +2345,7 @@ void FortranLanguageScanner::parseInput(const char *fileName,

printlex(yy_flex_debug, TRUE, __FILE__, fileName);

::parseMain(fileName,fileBuf,root);
::parseMain(fileName,fileBuf,root,this->codeType);

printlex(yy_flex_debug, FALSE, __FILE__, fileName);
}
Expand All @@ -2365,7 +2368,7 @@ void FortranLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf,
{
::parseFortranCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName,
fileDef,startLine,endLine,inlineFragment,memberDef,
showLineNumbers,searchCtx,collectXRefs);
showLineNumbers,searchCtx,collectXRefs,this->codeType);
}

bool FortranLanguageScanner::needsPreprocessing(const QCString &extension)
Expand Down
36 changes: 19 additions & 17 deletions src/util.cpp
Expand Up @@ -6624,23 +6624,25 @@ static struct Lang2ExtMap
}
g_lang2extMap[] =
{
// language parser parser option
{ "idl", "c", SrcLangExt_IDL },
{ "java", "c", SrcLangExt_Java },
{ "javascript", "c", SrcLangExt_JS },
{ "csharp", "c", SrcLangExt_CSharp },
{ "d", "c", SrcLangExt_D },
{ "php", "c", SrcLangExt_PHP },
{ "objective-c", "c", SrcLangExt_ObjC },
{ "c", "c", SrcLangExt_Cpp },
{ "c++", "c", SrcLangExt_Cpp },
{ "python", "python", SrcLangExt_Python },
{ "fortran", "fortran", SrcLangExt_Fortran },
{ "vhdl", "vhdl", SrcLangExt_VHDL },
{ "dbusxml", "dbusxml", SrcLangExt_XML },
{ "tcl", "tcl", SrcLangExt_Tcl },
{ "md", "md", SrcLangExt_Markdown },
{ 0, 0, (SrcLangExt)0 }
// language parser parser option
{ "idl", "c", SrcLangExt_IDL },
{ "java", "c", SrcLangExt_Java },
{ "javascript", "c", SrcLangExt_JS },
{ "csharp", "c", SrcLangExt_CSharp },
{ "d", "c", SrcLangExt_D },
{ "php", "c", SrcLangExt_PHP },
{ "objective-c", "c", SrcLangExt_ObjC },
{ "c", "c", SrcLangExt_Cpp },
{ "c++", "c", SrcLangExt_Cpp },
{ "python", "python", SrcLangExt_Python },
{ "fortran", "fortran", SrcLangExt_Fortran },
{ "fortranfree", "fortranfree", SrcLangExt_Fortran },
{ "fortranfixed", "fortranfixed", SrcLangExt_Fortran },
{ "vhdl", "vhdl", SrcLangExt_VHDL },
{ "dbusxml", "dbusxml", SrcLangExt_XML },
{ "tcl", "tcl", SrcLangExt_Tcl },
{ "md", "md", SrcLangExt_Markdown },
{ 0, 0, (SrcLangExt)0 }
};

bool updateLanguageMapping(const QCString &extension,const QCString &language)
Expand Down
2 changes: 2 additions & 0 deletions src/util.h
Expand Up @@ -414,6 +414,8 @@ QCString externalRef(const QCString &relPath,const QCString &ref,bool href);
int nextUtf8CharPosition(const QCString &utf8Str,int len,int startPos);
const char *writeUtf8Char(FTextStream &t,const char *s);

enum FortranKind { FORTRAN_UNKNOWN = 0, FORTRAN_FREE, FORTRAN_FIXED};

/** Data associated with a HSV colored image. */
struct ColoredImgDataItem
{
Expand Down

0 comments on commit 2dec106

Please sign in to comment.