Permalink
Browse files

Bug 625601 - FORTRAN: recognition free versus fixed formatted code

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 2dec1060623165057628ee678eb3580351922408
Showing with 81 additions and 42 deletions.
  1. +13 −4 doc/docblocks.doc
  2. +4 −1 src/config.xml
  3. +9 −7 src/doxygen.cpp
  4. +1 −1 src/fortrancode.h
  5. +5 −3 src/fortrancode.l
  6. +19 −3 src/fortranscanner.h
  7. +9 −6 src/fortranscanner.l
  8. +19 −17 src/util.cpp
  9. +2 −0 src/util.h
@@ -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.

@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
@@ -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
@@ -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),
@@ -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...
@@ -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();
@@ -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++;
@@ -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);
@@ -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;
@@ -19,6 +19,7 @@
#define SCANNER_FORTRAN_H
#include "parserintf.h"
#include "util.h"
/** \brief Fortran language parser using state-based lexical scanning.
*
@@ -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,
@@ -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
@@ -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;
@@ -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++;
@@ -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();
@@ -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)
{
@@ -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);
}
@@ -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)
@@ -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)
@@ -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
{

0 comments on commit 2dec106

Please sign in to comment.