Blame src/fortrancode.l

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * Parser for syntax highlighting and references for Fortran90 F subset
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright (C) by Anke Visser
Packit 1c1d7e
 * based on the work of Dimitri van Heesch.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Permission to use, copy, modify, and distribute this software and its
Packit 1c1d7e
 * documentation under the terms of the GNU General Public License is hereby 
Packit 1c1d7e
 * granted. No representations are made about the suitability of this software 
Packit 1c1d7e
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit 1c1d7e
 * See the GNU General Public License for more details.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Documents produced by Doxygen are derivative works derived from the
Packit 1c1d7e
 * input used in their production; they are not affected by this license.
Packit 1c1d7e
 *
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 @todo - continutation lines not always recognized
Packit 1c1d7e
       - merging of use-statements with same module name and different only-names
Packit 1c1d7e
       - rename part of use-statement
Packit 1c1d7e
       - links to interface functions 
Packit 1c1d7e
       - references to variables
Packit 1c1d7e
**/
Packit 1c1d7e
%option never-interactive
Packit 1c1d7e
%option case-insensitive
Packit 1c1d7e
%option prefix="fortrancodeYY"
Packit 1c1d7e
Packit 1c1d7e
%{
Packit 1c1d7e
Packit 1c1d7e
/*
Packit 1c1d7e
 *	includes
Packit 1c1d7e
 */
Packit 1c1d7e
#include <stdio.h>
Packit 1c1d7e
#include <assert.h>
Packit 1c1d7e
#include <ctype.h>
Packit 1c1d7e
#include <qregexp.h>
Packit 1c1d7e
#include <qdir.h>
Packit 1c1d7e
#include <qstringlist.h>
Packit 1c1d7e
#include "entry.h"
Packit 1c1d7e
#include "doxygen.h"
Packit 1c1d7e
#include "message.h"
Packit 1c1d7e
#include "outputlist.h"
Packit 1c1d7e
#include "util.h"
Packit 1c1d7e
#include "membername.h"
Packit 1c1d7e
#include "searchindex.h"
Packit 1c1d7e
#include "defargs.h"
Packit 1c1d7e
#include "memberlist.h"
Packit 1c1d7e
#include "config.h"
Packit 1c1d7e
#include "groupdef.h"
Packit 1c1d7e
#include "classlist.h"
Packit 1c1d7e
#include "filedef.h"
Packit 1c1d7e
#include "namespacedef.h"
Packit 1c1d7e
#include "tooltip.h"
Packit 1c1d7e
#include "fortrancode.h"
Packit 1c1d7e
Packit 1c1d7e
// Toggle for some debugging info
Packit 1c1d7e
//#define DBG_CTX(x) fprintf x
Packit 1c1d7e
#define DBG_CTX(x) do { } while(0)
Packit 1c1d7e
Packit 1c1d7e
#define YY_NO_TOP_STATE 1
Packit 1c1d7e
#define YY_NO_INPUT 1
Packit 1c1d7e
#define YY_NO_UNISTD_H 1
Packit 1c1d7e
Packit 1c1d7e
/*
Packit 1c1d7e
 * For fixed formatted code position 6 is of importance (continuation character).
Packit 1c1d7e
 * The following variables and macros keep track of the column number
Packit 1c1d7e
 * YY_USER_ACTION is always called for each scan action
Packit 1c1d7e
 * YY_FTN_RESET   is used to handle end of lines and reset the column counter
Packit 1c1d7e
 * YY_FTN_REJECT  resets the column counters when a pattern is rejected and thus rescanned.
Packit 1c1d7e
 */
Packit 1c1d7e
int yy_old_start = 0;
Packit 1c1d7e
int yy_my_start  = 0;
Packit 1c1d7e
int yy_end       = 1;
Packit 1c1d7e
#define YY_USER_ACTION {yy_old_start = yy_my_start; yy_my_start = yy_end; yy_end += yyleng;}
Packit 1c1d7e
#define YY_FTN_RESET   {yy_old_start = 0; yy_my_start = 0; yy_end = 1;}
Packit 1c1d7e
#define YY_FTN_REJECT  {yy_end = yy_my_start; yy_my_start = yy_old_start; REJECT;}
Packit 1c1d7e
   
Packit 1c1d7e
//--------------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
  data of an use-statement
Packit 1c1d7e
*/
Packit 1c1d7e
class UseEntry 
Packit 1c1d7e
{
Packit 1c1d7e
 public: 
Packit 1c1d7e
   QCString module; // just for debug
Packit 1c1d7e
   QStringList onlyNames;   /* entries of the ONLY-part */
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
  module name -> list of ONLY/remote entries
Packit 1c1d7e
  (module name = name of the module, which can be accessed via use-directive)
Packit 1c1d7e
*/
Packit 1c1d7e
class UseSDict : public SDict<UseEntry> 
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    UseSDict() : SDict<UseEntry>(17) {}
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
  Contains names of used modules and names of local variables.
Packit 1c1d7e
*/
Packit 1c1d7e
class Scope 
Packit 1c1d7e
{
Packit 1c1d7e
  public:
Packit 1c1d7e
    QStringList useNames; //!< contains names of used modules
Packit 1c1d7e
    QDict<void> localVars; //!< contains names of local variables
Packit 1c1d7e
Packit 1c1d7e
    Scope() : localVars(7, FALSE /*caseSensitive*/) {}
Packit 1c1d7e
};
Packit 1c1d7e
Packit 1c1d7e
/*===================================================================*/
Packit 1c1d7e
/* 
Packit 1c1d7e
 *	statics
Packit 1c1d7e
 */
Packit 1c1d7e
  
Packit 1c1d7e
static QCString  docBlock;                   //!< contents of all lines of a documentation block
Packit 1c1d7e
static QCString  currentModule=0;            //!< name of the current enclosing module
Packit 1c1d7e
static QCString  currentClass=0;             //!< name of the current enclosing class
Packit 1c1d7e
static UseSDict  *useMembers= new UseSDict;  //!< info about used modules
Packit 1c1d7e
static UseEntry  *useEntry = 0;              //!< current use statement info
Packit 1c1d7e
static QList<Scope> scopeStack;
Packit 1c1d7e
// static QStringList *currentUseNames= new QStringList; //! contains names of used modules of current program unit
Packit 1c1d7e
static QCString str="";         //!> contents of fortran string
Packit 1c1d7e
Packit 1c1d7e
static CodeOutputInterface * g_code;
Packit 1c1d7e
Packit 1c1d7e
// TODO: is this still needed? if so, make it work
Packit 1c1d7e
static QCString      g_parmType;
Packit 1c1d7e
static QCString      g_parmName;
Packit 1c1d7e
Packit 1c1d7e
static const char *  g_inputString;     //!< the code fragment as text
Packit 1c1d7e
static int	     g_inputPosition;   //!< read offset during parsing 
Packit 1c1d7e
static int           g_inputLines;      //!< number of line in the code fragment
Packit 1c1d7e
static int	     g_yyLineNr;        //!< current line number
Packit 1c1d7e
static int	     g_contLineNr;      //!< current, local, line number for continuation determination
Packit 1c1d7e
static int	    *g_hasContLine = NULL;     //!< signals whether or not a line has a continuation line (fixed source form)
Packit 1c1d7e
static bool          g_needsTermination;
Packit 1c1d7e
static Definition   *g_searchCtx;
Packit 1c1d7e
static bool          g_collectXRefs;
Packit 1c1d7e
static bool          g_isFixedForm;
Packit 1c1d7e
Packit 1c1d7e
static bool          g_insideBody;      //!< inside subprog/program body? => create links
Packit 1c1d7e
static const char *  g_currentFontClass;
Packit 1c1d7e
Packit 1c1d7e
static bool          g_exampleBlock;
Packit 1c1d7e
static QCString      g_exampleName;
Packit 1c1d7e
static QCString      g_exampleFile;
Packit 1c1d7e
Packit 1c1d7e
static FileDef *     g_sourceFileDef;
Packit 1c1d7e
static Definition *  g_currentDefinition;
Packit 1c1d7e
static MemberDef *   g_currentMemberDef;
Packit 1c1d7e
static bool          g_includeCodeFragment;
Packit 1c1d7e
Packit 1c1d7e
static char          stringStartSymbol; // single or double quote
Packit 1c1d7e
// count in variable declaration to filter out
Packit 1c1d7e
//  declared from referenced names
Packit 1c1d7e
static int 	     bracketCount = 0;
Packit 1c1d7e
Packit 1c1d7e
static bool      g_endComment;
Packit 1c1d7e
Packit 1c1d7e
static void endFontClass()
Packit 1c1d7e
{
Packit 1c1d7e
  if (g_currentFontClass)
Packit 1c1d7e
  {
Packit 1c1d7e
    g_code->endFontClass();
Packit 1c1d7e
    g_currentFontClass=0;
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void startFontClass(const char *s)
Packit 1c1d7e
{
Packit 1c1d7e
  // if font class is already set don't stop and start it.
Packit 1c1d7e
  // strcmp does not like null pointers as input.
Packit 1c1d7e
  if (!g_currentFontClass || !s || strcmp(g_currentFontClass,s))
Packit 1c1d7e
  {
Packit 1c1d7e
    endFontClass();
Packit 1c1d7e
    g_code->startFontClass(s);
Packit 1c1d7e
    g_currentFontClass=s;
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void setCurrentDoc(const QCString &anchor)
Packit 1c1d7e
{
Packit 1c1d7e
  if (Doxygen::searchIndex)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (g_searchCtx)
Packit 1c1d7e
    {
Packit 1c1d7e
      Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void addToSearchIndex(const char *text)
Packit 1c1d7e
{
Packit 1c1d7e
  if (Doxygen::searchIndex)
Packit 1c1d7e
  {
Packit 1c1d7e
    Doxygen::searchIndex->addWord(text,FALSE);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/*! start a new line of code, inserting a line number if g_sourceFileDef
Packit 1c1d7e
 * is TRUE. If a definition starts at the current line, then the line
Packit 1c1d7e
 * number is linked to the documentation of that definition.
Packit 1c1d7e
 */
Packit 1c1d7e
static void startCodeLine()
Packit 1c1d7e
{
Packit 1c1d7e
  if (g_sourceFileDef)
Packit 1c1d7e
  {
Packit 1c1d7e
    //QCString lineNumber,lineAnchor;
Packit 1c1d7e
    //lineNumber.sprintf("%05d",g_yyLineNr);
Packit 1c1d7e
    //lineAnchor.sprintf("l%05d",g_yyLineNr);
Packit 1c1d7e
   
Packit 1c1d7e
    Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
Packit 1c1d7e
    //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
Packit 1c1d7e
    if (!g_includeCodeFragment && d)
Packit 1c1d7e
    {
Packit 1c1d7e
      g_currentDefinition = d;
Packit 1c1d7e
      g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
Packit 1c1d7e
      g_insideBody = FALSE;
Packit 1c1d7e
      g_endComment = FALSE;
Packit 1c1d7e
      g_parmType.resize(0);
Packit 1c1d7e
      g_parmName.resize(0);
Packit 1c1d7e
      QCString lineAnchor;
Packit 1c1d7e
      lineAnchor.sprintf("l%05d",g_yyLineNr);
Packit 1c1d7e
      if (g_currentMemberDef)
Packit 1c1d7e
      {
Packit 1c1d7e
        g_code->writeLineNumber(g_currentMemberDef->getReference(),
Packit 1c1d7e
	                        g_currentMemberDef->getOutputFileBase(),
Packit 1c1d7e
	                        g_currentMemberDef->anchor(),g_yyLineNr);
Packit 1c1d7e
        setCurrentDoc(lineAnchor);
Packit 1c1d7e
      }
Packit 1c1d7e
      else if (d->isLinkableInProject())
Packit 1c1d7e
      {
Packit 1c1d7e
        g_code->writeLineNumber(d->getReference(),
Packit 1c1d7e
	                        d->getOutputFileBase(),
Packit 1c1d7e
	                        0,g_yyLineNr);
Packit 1c1d7e
        setCurrentDoc(lineAnchor);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      g_code->writeLineNumber(0,0,0,g_yyLineNr);
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  g_code->startCodeLine(g_sourceFileDef); 
Packit 1c1d7e
  if (g_currentFontClass)
Packit 1c1d7e
  {
Packit 1c1d7e
    g_code->startFontClass(g_currentFontClass);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
static void endFontClass();
Packit 1c1d7e
static void endCodeLine()
Packit 1c1d7e
{
Packit 1c1d7e
  endFontClass();
Packit 1c1d7e
  g_code->endCodeLine();
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/*! write a code fragment `text' that may span multiple lines, inserting
Packit 1c1d7e
 * line numbers for each line.
Packit 1c1d7e
 */
Packit 1c1d7e
static void codifyLines(char *text)
Packit 1c1d7e
{
Packit 1c1d7e
  //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
Packit 1c1d7e
  char *p=text,*sp=p;
Packit 1c1d7e
  char c;
Packit 1c1d7e
  bool done=FALSE;
Packit 1c1d7e
  const char *  tmp_currentFontClass = g_currentFontClass;
Packit 1c1d7e
  while (!done)
Packit 1c1d7e
  {
Packit 1c1d7e
    sp=p;
Packit 1c1d7e
    while ((c=*p++) && c!='\n') { }
Packit 1c1d7e
    if (c=='\n')
Packit 1c1d7e
    {
Packit 1c1d7e
      g_yyLineNr++;
Packit 1c1d7e
      *(p-1)='\0';
Packit 1c1d7e
      g_code->codify(sp);
Packit 1c1d7e
      endCodeLine();
Packit 1c1d7e
      if (g_yyLineNr
Packit 1c1d7e
      {
Packit 1c1d7e
	startCodeLine();
Packit 1c1d7e
      }
Packit 1c1d7e
      if (tmp_currentFontClass)
Packit 1c1d7e
      {
Packit 1c1d7e
        startFontClass(tmp_currentFontClass);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      g_code->codify(sp);
Packit 1c1d7e
      done=TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void codifyLines(QCString str)
Packit 1c1d7e
{
Packit 1c1d7e
  char *tmp= (char *) malloc(str.length()+1);
Packit 1c1d7e
  strcpy(tmp, str);
Packit 1c1d7e
  codifyLines(tmp);
Packit 1c1d7e
  free(tmp);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/*! writes a link to a fragment \a text that may span multiple lines, inserting
Packit 1c1d7e
 * line numbers for each line. If \a text contains newlines, the link will be 
Packit 1c1d7e
 * split into multiple links with the same destination, one for each line.
Packit 1c1d7e
 */
Packit 1c1d7e
static void writeMultiLineCodeLink(CodeOutputInterface &ol,
Packit 1c1d7e
                  Definition *d,const char *text)
Packit 1c1d7e
{
Packit 1c1d7e
  static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
Packit 1c1d7e
  TooltipManager::instance()->addTooltip(d);
Packit 1c1d7e
  QCString ref  = d->getReference();
Packit 1c1d7e
  QCString file = d->getOutputFileBase();
Packit 1c1d7e
  QCString anchor = d->anchor();
Packit 1c1d7e
  QCString tooltip; 
Packit 1c1d7e
  if (!sourceTooltips) // fall back to simple "title" tooltips
Packit 1c1d7e
  {
Packit 1c1d7e
    tooltip = d->briefDescriptionAsTooltip();
Packit 1c1d7e
  }
Packit 1c1d7e
  bool done=FALSE;
Packit 1c1d7e
  char *p=(char *)text;
Packit 1c1d7e
  while (!done)
Packit 1c1d7e
  {
Packit 1c1d7e
    char *sp=p;
Packit 1c1d7e
    char c;
Packit 1c1d7e
    while ((c=*p++) && c!='\n') { }
Packit 1c1d7e
    if (c=='\n')
Packit 1c1d7e
    {
Packit 1c1d7e
      g_yyLineNr++;
Packit 1c1d7e
      *(p-1)='\0';
Packit 1c1d7e
      //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
Packit 1c1d7e
      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
Packit 1c1d7e
      endCodeLine();
Packit 1c1d7e
      if (g_yyLineNr
Packit 1c1d7e
      {
Packit 1c1d7e
	startCodeLine();
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
Packit 1c1d7e
      ol.writeCodeLink(ref,file,anchor,sp,tooltip);
Packit 1c1d7e
      done=TRUE;
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
//-------------------------------------------------------------------------------
Packit 1c1d7e
/**
Packit 1c1d7e
  searches for definition of a module (Namespace)
Packit 1c1d7e
  @param mname the name of the module
Packit 1c1d7e
  @param cd the entry, if found or null
Packit 1c1d7e
  @returns true, if module is found
Packit 1c1d7e
*/
Packit 1c1d7e
static bool getFortranNamespaceDefs(const QCString &mname,
Packit 1c1d7e
                               NamespaceDef *&cd)
Packit 1c1d7e
{
Packit 1c1d7e
  if (mname.isEmpty()) return FALSE; /* empty name => nothing to link */
Packit 1c1d7e
Packit 1c1d7e
  // search for module
Packit 1c1d7e
  if ((cd=Doxygen::namespaceSDict->find(mname))) return TRUE;
Packit 1c1d7e
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
//-------------------------------------------------------------------------------
Packit 1c1d7e
/**
Packit 1c1d7e
  searches for definition of a type
Packit 1c1d7e
  @param tname the name of the type
Packit 1c1d7e
  @param moduleName name of enclosing module or null, if global entry
Packit 1c1d7e
  @param cd the entry, if found or null
Packit 1c1d7e
  @param useDict dictionary of data of USE-statement
Packit 1c1d7e
  @returns true, if type is found 
Packit 1c1d7e
*/
Packit 1c1d7e
static bool getFortranTypeDefs(const QCString &tname, const QCString &moduleName, 
Packit 1c1d7e
                               ClassDef *&cd, UseSDict *usedict=0)
Packit 1c1d7e
{
Packit 1c1d7e
  if (tname.isEmpty()) return FALSE; /* empty name => nothing to link */
Packit 1c1d7e
Packit 1c1d7e
  //cout << "=== search for type: " << tname << endl;
Packit 1c1d7e
Packit 1c1d7e
  // search for type  
Packit 1c1d7e
  if ((cd=Doxygen::classSDict->find(tname))) 
Packit 1c1d7e
  {
Packit 1c1d7e
    //cout << "=== type found in global module" << endl;
Packit 1c1d7e
    return TRUE;
Packit 1c1d7e
  }
Packit 1c1d7e
  else if (moduleName && (cd= Doxygen::classSDict->find(moduleName+"::"+tname))) 
Packit 1c1d7e
  {
Packit 1c1d7e
    //cout << "=== type found in local module" << endl;
Packit 1c1d7e
    return TRUE;
Packit 1c1d7e
  }
Packit 1c1d7e
  else 
Packit 1c1d7e
  {
Packit 1c1d7e
    UseEntry *use;
Packit 1c1d7e
    for (UseSDict::Iterator di(*usedict); (use=di.current()); ++di)
Packit 1c1d7e
    {
Packit 1c1d7e
      if ((cd= Doxygen::classSDict->find(use->module+"::"+tname)))
Packit 1c1d7e
      {
Packit 1c1d7e
 	//cout << "===  type found in used module" << endl;
Packit 1c1d7e
        return TRUE;
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
  searches for definition of function memberName
Packit 1c1d7e
  @param memberName the name of the function/variable
Packit 1c1d7e
  @param moduleName name of enclosing module or null, if global entry
Packit 1c1d7e
  @param md the entry, if found or null
Packit 1c1d7e
  @param usedict array of data of USE-statement
Packit 1c1d7e
  @returns true, if found 
Packit 1c1d7e
*/
Packit 1c1d7e
static bool getFortranDefs(const QCString &memberName, const QCString &moduleName, 
Packit 1c1d7e
                           MemberDef *&md, UseSDict *usedict=0)
Packit 1c1d7e
{
Packit 1c1d7e
  if (memberName.isEmpty()) return FALSE; /* empty name => nothing to link */
Packit 1c1d7e
Packit 1c1d7e
  // look in local variables
Packit 1c1d7e
  QListIterator<Scope> it(scopeStack);
Packit 1c1d7e
  Scope *scope;
Packit 1c1d7e
  for (it.toLast();(scope=it.current());--it)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (scope->localVars.find(memberName))
Packit 1c1d7e
      return FALSE;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  // search for function
Packit 1c1d7e
  MemberName *mn = Doxygen::functionNameSDict->find(memberName);
Packit 1c1d7e
  if (!mn)
Packit 1c1d7e
  {
Packit 1c1d7e
    mn = Doxygen::memberNameSDict->find(memberName);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (mn) // name is known
Packit 1c1d7e
  {
Packit 1c1d7e
      MemberNameIterator mli(*mn);
Packit 1c1d7e
      for (mli.toFirst();(md=mli.current());++mli) // all found functions with given name
Packit 1c1d7e
      {
Packit 1c1d7e
        FileDef  *fd=md->getFileDef();
Packit 1c1d7e
        GroupDef *gd=md->getGroupDef();
Packit 1c1d7e
        ClassDef *cd=md->getClassDef();
Packit 1c1d7e
Packit 1c1d7e
 //cout << "found link with same name: " << fd->fileName() << "  " <<  memberName;
Packit 1c1d7e
 //if (md->getNamespaceDef() != 0) cout << " in namespace " << md->getNamespaceDef()->name();cout << endl;
Packit 1c1d7e
Packit 1c1d7e
        if ((gd && gd->isLinkable()) || (fd && fd->isLinkable()))
Packit 1c1d7e
        {
Packit 1c1d7e
           NamespaceDef *nspace= md->getNamespaceDef();
Packit 1c1d7e
Packit 1c1d7e
           if (nspace == 0) 
Packit 1c1d7e
	   { // found function in global scope
Packit 1c1d7e
             if(cd == 0) { // Skip if bound to type
Packit 1c1d7e
                return TRUE;
Packit 1c1d7e
              }
Packit 1c1d7e
           }
Packit 1c1d7e
           else if (moduleName == nspace->name()) 
Packit 1c1d7e
	   { // found in local scope
Packit 1c1d7e
             return TRUE;
Packit 1c1d7e
           }
Packit 1c1d7e
           else 
Packit 1c1d7e
	   { // else search in used modules
Packit 1c1d7e
	     QCString moduleName= nspace->name();
Packit 1c1d7e
	     UseEntry *ue= usedict->find(moduleName);
Packit 1c1d7e
	     if (ue) 
Packit 1c1d7e
	     {
Packit 1c1d7e
               // check if only-list exists and if current entry exists is this list
Packit 1c1d7e
	       QStringList &only= ue->onlyNames;
Packit 1c1d7e
	       if (only.isEmpty()) 
Packit 1c1d7e
	       {
Packit 1c1d7e
               //cout << " found in module " << moduleName << " entry " << memberName <<  endl;
Packit 1c1d7e
                 return TRUE; // whole module used
Packit 1c1d7e
               }
Packit 1c1d7e
               else
Packit 1c1d7e
	       {
Packit 1c1d7e
	         for ( QStringList::Iterator it = only.begin(); it != only.end(); ++it)
Packit 1c1d7e
                 {
Packit 1c1d7e
                   //cout << " search in only: " << moduleName << ":: " << memberName << "==" << (*it)<<  endl;
Packit 1c1d7e
		   if (memberName == (*it).utf8())
Packit 1c1d7e
	           {
Packit 1c1d7e
                     return TRUE; // found in ONLY-part of use list
Packit 1c1d7e
	           }
Packit 1c1d7e
	         }
Packit 1c1d7e
	       }
Packit 1c1d7e
             }
Packit 1c1d7e
           }
Packit 1c1d7e
        } // if linkable
Packit 1c1d7e
      } // for
Packit 1c1d7e
  }
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 gets the link to a generic procedure which depends not on the name, but on the parameter list
Packit 1c1d7e
 @todo implementation
Packit 1c1d7e
*/
Packit 1c1d7e
static bool getGenericProcedureLink(const ClassDef *cd, 
Packit 1c1d7e
                                    const char *memberText, 
Packit 1c1d7e
				    CodeOutputInterface &ol) 
Packit 1c1d7e
{
Packit 1c1d7e
  (void)cd;
Packit 1c1d7e
  (void)memberText;
Packit 1c1d7e
  (void)ol;
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static bool getLink(UseSDict *usedict, // dictonary with used modules
Packit 1c1d7e
                    const char *memberText,  // exact member text
Packit 1c1d7e
		    CodeOutputInterface &ol,
Packit 1c1d7e
		    const char *text)
Packit 1c1d7e
{
Packit 1c1d7e
  MemberDef *md=0;
Packit 1c1d7e
  QCString memberName= removeRedundantWhiteSpace(memberText);
Packit 1c1d7e
Packit 1c1d7e
  if (getFortranDefs(memberName, currentModule, md, usedict) && md->isLinkable())
Packit 1c1d7e
  { 
Packit 1c1d7e
    if (md->isVariable() && (md->getLanguage()!=SrcLangExt_Fortran)) return FALSE; // Non Fortran variables aren't handled yet,
Packit 1c1d7e
                                                                                   // see also linkifyText in util.cpp
Packit 1c1d7e
Packit 1c1d7e
    Definition *d = md->getOuterScope()==Doxygen::globalScope ?
Packit 1c1d7e
	            md->getBodyDef() : md->getOuterScope();
Packit 1c1d7e
    if (md->getGroupDef()) d = md->getGroupDef();
Packit 1c1d7e
    if (d && d->isLinkable())
Packit 1c1d7e
    {
Packit 1c1d7e
      if (g_currentDefinition && g_currentMemberDef && 
Packit 1c1d7e
          md!=g_currentMemberDef && g_insideBody && g_collectXRefs)
Packit 1c1d7e
      { 
Packit 1c1d7e
	addDocCrossReference(g_currentMemberDef,md); 
Packit 1c1d7e
      }     
Packit 1c1d7e
      writeMultiLineCodeLink(ol,md,text ? text : memberText);
Packit 1c1d7e
      addToSearchIndex(text ? text : memberText);
Packit 1c1d7e
      return TRUE;
Packit 1c1d7e
    } 
Packit 1c1d7e
  }
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
static void generateLink(CodeOutputInterface &ol, char *lname)
Packit 1c1d7e
{
Packit 1c1d7e
  ClassDef *cd=0;
Packit 1c1d7e
  NamespaceDef *nsd=0;
Packit 1c1d7e
  QCString tmp = lname;
Packit 1c1d7e
  tmp = removeRedundantWhiteSpace(tmp.lower());
Packit 1c1d7e
 
Packit 1c1d7e
  // check if lowercase lname is a linkable type or interface
Packit 1c1d7e
  if ( (getFortranTypeDefs(tmp, currentModule, cd, useMembers)) && cd->isLinkable() )
Packit 1c1d7e
  {
Packit 1c1d7e
    if ( (cd->compoundType() == ClassDef::Class) && // was  Entry::INTERFACE_SEC) &&
Packit 1c1d7e
         (getGenericProcedureLink(cd, tmp, ol)) ) 
Packit 1c1d7e
    {
Packit 1c1d7e
      //cout << "=== generic procedure resolved" << endl; 
Packit 1c1d7e
    } 
Packit 1c1d7e
    else 
Packit 1c1d7e
    { // write type or interface link
Packit 1c1d7e
      writeMultiLineCodeLink(ol,cd,tmp);
Packit 1c1d7e
      addToSearchIndex(tmp.data());
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  // check for module
Packit 1c1d7e
  else if ( (getFortranNamespaceDefs(tmp, nsd)) && nsd->isLinkable() )
Packit 1c1d7e
  { // write module link
Packit 1c1d7e
    writeMultiLineCodeLink(ol,nsd,tmp);
Packit 1c1d7e
    addToSearchIndex(tmp.data());
Packit 1c1d7e
  }
Packit 1c1d7e
  // check for function/variable
Packit 1c1d7e
  else if (getLink(useMembers, tmp, ol, tmp)) 
Packit 1c1d7e
  {
Packit 1c1d7e
    //cout << "=== found link for lowercase " << lname << endl;
Packit 1c1d7e
  }
Packit 1c1d7e
  else 
Packit 1c1d7e
  {
Packit 1c1d7e
    // nothing found, just write out the word
Packit 1c1d7e
    //startFontClass("charliteral"); //test
Packit 1c1d7e
    codifyLines(tmp);
Packit 1c1d7e
    //endFontClass(); //test
Packit 1c1d7e
    addToSearchIndex(tmp.data());
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/*! counts the number of lines in the input */
Packit 1c1d7e
static int countLines()
Packit 1c1d7e
{
Packit 1c1d7e
  const char *p=g_inputString;
Packit 1c1d7e
  char c;
Packit 1c1d7e
  int count=1;
Packit 1c1d7e
  while ((c=*p)) 
Packit 1c1d7e
  { 
Packit 1c1d7e
    p++ ; 
Packit 1c1d7e
    if (c=='\n') count++;  
Packit 1c1d7e
  }
Packit 1c1d7e
  if (p>g_inputString && *(p-1)!='\n') 
Packit 1c1d7e
  { // last line does not end with a \n, so we add an extra
Packit 1c1d7e
    // line and explicitly terminate the line after parsing.
Packit 1c1d7e
    count++, 
Packit 1c1d7e
    g_needsTermination=TRUE; 
Packit 1c1d7e
  } 
Packit 1c1d7e
  return count;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
//----------------------------------------------------------------------------
Packit 1c1d7e
/** start scope */
Packit 1c1d7e
static void startScope() 
Packit 1c1d7e
{
Packit 1c1d7e
  DBG_CTX((stderr, "===> startScope %s",yytext));
Packit 1c1d7e
  Scope *scope = new Scope;
Packit 1c1d7e
  scopeStack.append(scope);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/** end scope */
Packit 1c1d7e
static void endScope() 
Packit 1c1d7e
{
Packit 1c1d7e
  DBG_CTX((stderr,"===> endScope %s",yytext));
Packit 1c1d7e
  if (scopeStack.isEmpty()) 
Packit 1c1d7e
  {
Packit 1c1d7e
    DBG_CTX((stderr,"WARNING: fortrancode.l: stack empty!\n")); 
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  Scope *scope = scopeStack.getLast();
Packit 1c1d7e
  scopeStack.removeLast();
Packit 1c1d7e
  for ( QStringList::Iterator it = scope->useNames.begin(); it != scope->useNames.end(); ++it) 
Packit 1c1d7e
  {
Packit 1c1d7e
    useMembers->remove((*it).utf8());
Packit 1c1d7e
  }
Packit 1c1d7e
  delete scope;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void addUse(const QCString &moduleName) 
Packit 1c1d7e
{
Packit 1c1d7e
  if (!scopeStack.isEmpty())
Packit 1c1d7e
    scopeStack.getLast()->useNames.append(moduleName);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
static void addLocalVar(const QCString &varName) 
Packit 1c1d7e
{
Packit 1c1d7e
  if (!scopeStack.isEmpty())
Packit 1c1d7e
    scopeStack.getLast()->localVars.insert(varName, (void*)1);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
//----------------------------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
/* -----------------------------------------------------------------*/
Packit 1c1d7e
#undef	YY_INPUT
Packit 1c1d7e
#define	YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
Packit 1c1d7e
Packit 1c1d7e
static int yyread(char *buf,int max_size)
Packit 1c1d7e
{
Packit 1c1d7e
    int c=0;
Packit 1c1d7e
    while( c < max_size && g_inputString[g_inputPosition] )
Packit 1c1d7e
    {
Packit 1c1d7e
	*buf = g_inputString[g_inputPosition++] ;
Packit 1c1d7e
	c++; buf++;
Packit 1c1d7e
    }
Packit 1c1d7e
    return c;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
%}
Packit 1c1d7e
Packit 1c1d7e
IDSYM	  [a-z_A-Z0-9]
Packit 1c1d7e
ID        [a-z_A-Z]+{IDSYM}*
Packit 1c1d7e
SUBPROG   (subroutine|function)
Packit 1c1d7e
B         [ \t]
Packit 1c1d7e
BS        [ \t]*
Packit 1c1d7e
BS_       [ \t]+
Packit 1c1d7e
COMMA     {BS},{BS}
Packit 1c1d7e
ARGS_L0   ("("[^)]*")")
Packit 1c1d7e
ARGS_L1a  [^()]*"("[^)]*")"[^)]*
Packit 1c1d7e
ARGS_L1   ("("{ARGS_L1a}*")")
Packit 1c1d7e
ARGS_L2   "("({ARGS_L0}|[^()]|{ARGS_L1a}|{ARGS_L1})*")"
Packit 1c1d7e
ARGS      {BS}({ARGS_L0}|{ARGS_L1}|{ARGS_L2})
Packit 1c1d7e
Packit 1c1d7e
NUM_TYPE  (complex|integer|logical|real)
Packit 1c1d7e
LOG_OPER  (\.and\.|\.eq\.|\.eqv\.|\.ge\.|\.gt\.|\.le\.|\.lt\.|\.ne\.|\.neqv\.|\.or\.|\.not\.)
Packit 1c1d7e
KIND      {ARGS}
Packit 1c1d7e
CHAR      (CHARACTER{ARGS}?|CHARACTER{BS}"*"({BS}[0-9]+|{ARGS}))
Packit 1c1d7e
TYPE_SPEC (({NUM_TYPE}({BS}"*"{BS}[0-9]+)?)|({NUM_TYPE}{KIND})|DOUBLE{BS}COMPLEX|DOUBLE{BS}PRECISION|{CHAR}|TYPE|CLASS|PROCEDURE)
Packit 1c1d7e
Packit 1c1d7e
INTENT_SPEC intent{BS}"("{BS}(in|out|in{BS}out){BS}")"
Packit 1c1d7e
ATTR_SPEC (IMPLICIT|ALLOCATABLE|DIMENSION{ARGS}|EXTERNAL|{INTENT_SPEC}|INTRINSIC|OPTIONAL|PARAMETER|POINTER|PROTECTED|PRIVATE|PUBLIC|SAVE|TARGET|RECURSIVE|PURE|IMPURE|ELEMENTAL|VALUE|NOPASS|DEFERRED|CONTIGUOUS|VOLATILE)
Packit 1c1d7e
ACCESS_SPEC (PROTECTED|PRIVATE|PUBLIC)
Packit 1c1d7e
/* Assume that attribute statements are almost the same as attributes. */
Packit 1c1d7e
ATTR_STMT {ATTR_SPEC}|DIMENSION
Packit 1c1d7e
FLOW      (DO|SELECT|CASE|SELECT{BS}(CASE|TYPE)|WHERE|IF|THEN|ELSE|WHILE|FORALL|ELSEWHERE|ELSEIF|RETURN|CONTINUE|EXIT|GO{BS}TO)
Packit 1c1d7e
COMMANDS  (FORMAT|CONTAINS|MODULE{BS_}PROCEDURE|WRITE|READ|ALLOCATE|ALLOCATED|ASSOCIATED|PRESENT|DEALLOCATE|NULLIFY|SIZE|INQUIRE|OPEN|CLOSE|FLUSH|DATA|COMMON)
Packit 1c1d7e
IGNORE    (CALL)
Packit 1c1d7e
PREFIX    (RECURSIVE{BS_}|IMPURE{BS_}|PURE{BS_}|ELEMENTAL{BS_}){0,3}(RECURSIVE|IMPURE|PURE|ELEMENTAL)?
Packit 1c1d7e
Packit 1c1d7e
/* |  */
Packit 1c1d7e
Packit 1c1d7e
%option noyywrap
Packit 1c1d7e
%option stack
Packit 1c1d7e
%option caseless
Packit 1c1d7e
/*%option debug*/
Packit 1c1d7e
Packit 1c1d7e
%x Start
Packit 1c1d7e
%x SubCall
Packit 1c1d7e
%x FuncDef
Packit 1c1d7e
%x ClassName
Packit 1c1d7e
%x ClassVar
Packit 1c1d7e
%x Subprog
Packit 1c1d7e
%x DocBlock
Packit 1c1d7e
%x Use
Packit 1c1d7e
%x UseOnly
Packit 1c1d7e
%x Import
Packit 1c1d7e
%x Declaration
Packit 1c1d7e
%x DeclarationBinding
Packit 1c1d7e
%x DeclContLine
Packit 1c1d7e
%x Parameterlist
Packit 1c1d7e
%x String
Packit 1c1d7e
%x Subprogend
Packit 1c1d7e
Packit 1c1d7e
%%
Packit 1c1d7e
 /*==================================================================*/
Packit 1c1d7e
Packit 1c1d7e
 /*-------- ignore ------------------------------------------------------------*/
Packit 1c1d7e
Packit 1c1d7e
<Start>{IGNORE}/{BS}"("                 { // do not search keywords, intrinsics... TODO: complete list
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-------- inner construct ---------------------------------------------------*/
Packit 1c1d7e
 
Packit 1c1d7e
<Start>{COMMANDS}/{BS}[,( \t\n]         {  // highlight
Packit 1c1d7e
   					  /* font class is defined e.g. in doxygen.css */
Packit 1c1d7e
  					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>{FLOW}/{BS}[,( \t\n]               {
Packit 1c1d7e
                                          if (g_isFixedForm)
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            if ((yy_my_start == 1) && ((yytext[0] == 'c') || (yytext[0] == 'C'))) YY_FTN_REJECT;
Packit 1c1d7e
                                          }
Packit 1c1d7e
   					  /* font class is defined e.g. in doxygen.css */
Packit 1c1d7e
  					  startFontClass("keywordflow");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>{BS}(CASE|CLASS|TYPE){BS_}(IS|DEFAULT) {
Packit 1c1d7e
                                          startFontClass("keywordflow");
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                          endFontClass();
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>{BS}"end"({BS}{FLOW})/[ \t\n]       { // list is a bit long as not all have possible end
Packit 1c1d7e
  					  startFontClass("keywordflow");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>"implicit"{BS}("none"|{TYPE_SPEC})  { 
Packit 1c1d7e
  					  startFontClass("keywordtype"); 
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>^{BS}"namelist"/[//]             {  // Namelist specification
Packit 1c1d7e
                                          startFontClass("keywordtype");
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                          endFontClass();
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-------- use statement -------------------------------------------*/
Packit 1c1d7e
<Start>"use"{BS_}                       { 
Packit 1c1d7e
  					  startFontClass("keywordtype"); 
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
					  BEGIN(Use);     
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Use>"ONLY"                             { // TODO: rename
Packit 1c1d7e
                                          startFontClass("keywordtype");
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                          endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          BEGIN(UseOnly);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Use>{ID}                               {
Packit 1c1d7e
                                          QCString tmp = yytext;
Packit 1c1d7e
                                          tmp = tmp.lower();
Packit 1c1d7e
					  g_insideBody=TRUE;
Packit 1c1d7e
                                          generateLink(*g_code, yytext);
Packit 1c1d7e
					  g_insideBody=FALSE;
Packit 1c1d7e
Packit 1c1d7e
					  /* append module name to use dict */
Packit 1c1d7e
                                          useEntry = new UseEntry();
Packit 1c1d7e
					  //useEntry->module = yytext;
Packit 1c1d7e
                                          //useMembers->append(yytext, useEntry);
Packit 1c1d7e
					  //addUse(yytext);
Packit 1c1d7e
					  useEntry->module = tmp;
Packit 1c1d7e
                                          useMembers->append(tmp, useEntry);
Packit 1c1d7e
					  addUse(tmp);
Packit 1c1d7e
                                        }           
Packit 1c1d7e
<Use,UseOnly,Import>{BS},{BS}           { codifyLines(yytext); }
Packit 1c1d7e
<UseOnly,Import>{BS}&{BS}"\n"           { codifyLines(yytext);
Packit 1c1d7e
                                          g_contLineNr++;
Packit 1c1d7e
                                          YY_FTN_RESET}
Packit 1c1d7e
<UseOnly>{ID}                           {
Packit 1c1d7e
                                          QCString tmp = yytext;
Packit 1c1d7e
                                          tmp = tmp.lower();
Packit 1c1d7e
                                          useEntry->onlyNames.append(tmp);
Packit 1c1d7e
                                          g_insideBody=TRUE;
Packit 1c1d7e
                                          generateLink(*g_code, yytext);
Packit 1c1d7e
                                          g_insideBody=FALSE;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Use,UseOnly,Import>"\n"                {
Packit 1c1d7e
                                          unput(*yytext);
Packit 1c1d7e
                                          yy_pop_state();YY_FTN_RESET
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>"import"{BS_}                    {
Packit 1c1d7e
                                          startFontClass("keywordtype");
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                          endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          BEGIN(Import);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Import>{ID}                            {
Packit 1c1d7e
                                          g_insideBody=TRUE;
Packit 1c1d7e
                                          generateLink(*g_code, yytext);
Packit 1c1d7e
                                          g_insideBody=FALSE;
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-------- fortran module  -----------------------------------------*/
Packit 1c1d7e
<Start>("block"{BS}"data"|"program"|"module"|"interface")/{BS_}|({COMMA}{ACCESS_SPEC})|\n {  //
Packit 1c1d7e
                                          startScope();
Packit 1c1d7e
  					  startFontClass("keyword"); 
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
					  BEGIN(ClassName); 
Packit 1c1d7e
	                                  if (!qstricmp(yytext,"module")) currentModule="module";
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>("type")/{BS_}|({COMMA}({ACCESS_SPEC}|ABSTRACT|EXTENDS))|\n {  //
Packit 1c1d7e
            startScope();
Packit 1c1d7e
              startFontClass("keyword");
Packit 1c1d7e
              codifyLines(yytext);
Packit 1c1d7e
            endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
            BEGIN(ClassName);
Packit 1c1d7e
            currentClass="class";
Packit 1c1d7e
          }
Packit 1c1d7e
<ClassName>{ID}               	        {
Packit 1c1d7e
	                                  if (currentModule == "module")
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            currentModule=yytext;
Packit 1c1d7e
                                            currentModule = currentModule.lower();
Packit 1c1d7e
                                          }
Packit 1c1d7e
					  generateLink(*g_code,yytext);
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
 					}
Packit 1c1d7e
<ClassName>({ACCESS_SPEC}|ABSTRACT|EXTENDS)/[,:( ] { //| variable deklaration
Packit 1c1d7e
              startFontClass("keyword");
Packit 1c1d7e
            g_code->codify(yytext);
Packit 1c1d7e
            endFontClass();
Packit 1c1d7e
            }
Packit 1c1d7e
<ClassName>\n				{ // interface may be without name
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
					  YY_FTN_REJECT;
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>^{BS}"end"({BS_}"type").*        { // just reset currentClass, rest is done in following rule
Packit 1c1d7e
                                          currentClass=0;
Packit 1c1d7e
            YY_FTN_REJECT;
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>^{BS}"end"({BS_}"module").*      { // just reset currentModule, rest is done in following rule
Packit 1c1d7e
                                          currentModule=0;
Packit 1c1d7e
					  YY_FTN_REJECT;
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-------- subprog definition -------------------------------------*/
Packit 1c1d7e
<Start>({PREFIX}{BS_})?{TYPE_SPEC}{BS_}({PREFIX}{BS_})?{BS}/{SUBPROG}{BS_}  {   // TYPE_SPEC is for old function style function result
Packit 1c1d7e
   					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                       }              
Packit 1c1d7e
<Start>({PREFIX}{BS_})?{SUBPROG}{BS_}                  {  // Fortran subroutine or function found
Packit 1c1d7e
   					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          BEGIN(Subprog);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Subprog>{ID}                           { // subroutine/function name
Packit 1c1d7e
                                          DBG_CTX((stderr, "===> start subprogram %s\n", yytext));
Packit 1c1d7e
					  startScope();
Packit 1c1d7e
					  generateLink(*g_code,yytext);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Subprog>"result"/{BS}"("[^)]*")"       {
Packit 1c1d7e
   					  startFontClass("keyword");
Packit 1c1d7e
 					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Subprog>"("[^)]*")"                    { // ignore rest of line 
Packit 1c1d7e
 					  codifyLines(yytext);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Subprog,Subprogend>"\n"                { codifyLines(yytext);
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface")?{BS}     {  // Fortran subroutine or function ends
Packit 1c1d7e
                                          //cout << "===> end function " << yytext << endl;
Packit 1c1d7e
                                          endScope();
Packit 1c1d7e
   					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          BEGIN(Subprogend);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Subprogend>{ID}/{BS}(\n|!)             {
Packit 1c1d7e
					  generateLink(*g_code,yytext);
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>^{BS}"end"{BS}("block"{BS}"data"|{SUBPROG}|"module"|"program"|"type"|"interface"){BS}/(\n|!) {  // Fortran subroutine or function ends
Packit 1c1d7e
                                          //cout << "===> end function " << yytext << endl;
Packit 1c1d7e
                                          endScope();
Packit 1c1d7e
   					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-------- variable declaration ----------------------------------*/
Packit 1c1d7e
<Start>{TYPE_SPEC}/[,:( ]               { 
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
					  BEGIN(Declaration);
Packit 1c1d7e
   					  startFontClass("keywordtype");
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                       }
Packit 1c1d7e
<Start>{ATTR_SPEC}		       { 
Packit 1c1d7e
   					  startFontClass("keywordtype");
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                       }
Packit 1c1d7e
<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable deklaration
Packit 1c1d7e
  					  startFontClass("keywordtype");
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
  					}
Packit 1c1d7e
<Declaration>{ID}                       { // local var
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start == 1)
Packit 1c1d7e
                                          {
Packit 1c1d7e
  					    startFontClass("comment");
Packit 1c1d7e
					    g_code->codify(yytext);
Packit 1c1d7e
					    endFontClass();
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else if (g_currentMemberDef && ((g_currentMemberDef->isFunction() && (g_currentMemberDef->typeString() != QCString("subroutine"))) ||
Packit 1c1d7e
                                                                          g_currentMemberDef->isVariable()))
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            generateLink(*g_code, yytext);
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            g_code->codify(yytext);
Packit 1c1d7e
                                            addLocalVar(yytext);
Packit 1c1d7e
                                          }
Packit 1c1d7e
					}
Packit 1c1d7e
<Declaration>{BS}("=>"|"="){BS}                        { // Procedure binding
Packit 1c1d7e
            BEGIN(DeclarationBinding);
Packit 1c1d7e
            g_code->codify(yytext);
Packit 1c1d7e
          }
Packit 1c1d7e
<DeclarationBinding>{ID}                       { // Type bound procedure link
Packit 1c1d7e
                                          generateLink(*g_code, yytext);
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
          }
Packit 1c1d7e
<Declaration>[(]			{ // start of array specification
Packit 1c1d7e
					  bracketCount++;
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<Declaration>[)]			{ // end array specification
Packit 1c1d7e
					  bracketCount--;
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<Declaration,DeclarationBinding>"&"     { // continuation line
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
                                          if (!g_isFixedForm)
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            yy_push_state(YY_START);
Packit 1c1d7e
					    BEGIN(DeclContLine);					  
Packit 1c1d7e
 					  }
Packit 1c1d7e
 					}
Packit 1c1d7e
<DeclContLine>"\n"                      { // declaration not yet finished
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
					  bracketCount = 0;
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
 				 	}
Packit 1c1d7e
<Declaration,DeclarationBinding>"\n"    { // end declaration line (?)
Packit 1c1d7e
					  if (g_endComment)
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            g_endComment=FALSE;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            codifyLines(yytext);
Packit 1c1d7e
                                          }
Packit 1c1d7e
					  bracketCount = 0;
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          if (!(g_hasContLine && g_hasContLine[g_contLineNr - 1]))
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            yy_pop_state();
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
 					}
Packit 1c1d7e
Packit 1c1d7e
 /*-------- subprog calls  -----------------------------------------*/
Packit 1c1d7e
Packit 1c1d7e
<Start>"call"{BS_}                      {
Packit 1c1d7e
                                          startFontClass("keyword");
Packit 1c1d7e
                                          codifyLines(yytext);
Packit 1c1d7e
                                          endFontClass();
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          BEGIN(SubCall);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<SubCall>{ID}                           { // subroutine call
Packit 1c1d7e
					  g_insideBody=TRUE;
Packit 1c1d7e
                                          generateLink(*g_code, yytext);
Packit 1c1d7e
					  g_insideBody=FALSE;
Packit 1c1d7e
	                                  yy_pop_state();
Packit 1c1d7e
                                        }
Packit 1c1d7e
<Start>{ID}{BS}/"("                     { // function call
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start == 6)
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            // fixed form continuation line
Packit 1c1d7e
                                            YY_FTN_REJECT;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
					    g_insideBody=TRUE;
Packit 1c1d7e
                                            generateLink(*g_code, yytext);
Packit 1c1d7e
					    g_insideBody=FALSE;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                        }
Packit 1c1d7e
Packit 1c1d7e
 /*-------- comments ---------------------------------------------------*/
Packit 1c1d7e
<Start,Declaration,DeclarationBinding>\n?{BS}"!>"|"!<"                 { // start comment line or comment block
Packit 1c1d7e
                                          if (yytext[0] == '\n')
Packit 1c1d7e
                                          {
Packit 1c1d7e
					    g_contLineNr++;
Packit 1c1d7e
                                            yy_old_start = 0;
Packit 1c1d7e
                                            yy_my_start = 1;
Packit 1c1d7e
                                            yy_end = yyleng;
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          // Actually we should see if ! on position 6, can be continuation
Packit 1c1d7e
                                          // but the chance is very unlikely, so no effort to solve it here
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
					  BEGIN(DocBlock);
Packit 1c1d7e
                                          docBlock=yytext;
Packit 1c1d7e
					}
Packit 1c1d7e
<Declaration,DeclarationBinding>{BS}"!<"                   { // start comment line or comment block
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
					  BEGIN(DocBlock);
Packit 1c1d7e
                                          docBlock=yytext;
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<DocBlock>.*    			{ // contents of current comment line
Packit 1c1d7e
                                          docBlock+=yytext;
Packit 1c1d7e
  					}
Packit 1c1d7e
<DocBlock>"\n"{BS}("!>"|"!<"|"!!")	{ // comment block (next line is also comment line)
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          yy_old_start = 0;
Packit 1c1d7e
                                          yy_my_start = 1;
Packit 1c1d7e
                                          yy_end = yyleng;
Packit 1c1d7e
                                          // Actually we should see if ! on position 6, can be continuation
Packit 1c1d7e
                                          // but the chance is very unlikely, so no effort to solve it here
Packit 1c1d7e
					  docBlock+=yytext; 
Packit 1c1d7e
   					}
Packit 1c1d7e
<DocBlock>"\n"        			{ // comment block ends at the end of this line
Packit 1c1d7e
                                          // remove special comment (default config)
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
  					  if (Config_getBool(STRIP_CODE_COMMENTS))
Packit 1c1d7e
					  {
Packit 1c1d7e
					    g_yyLineNr+=((QCString)docBlock).contains('\n');
Packit 1c1d7e
              g_yyLineNr+=1;
Packit 1c1d7e
					    endCodeLine();
Packit 1c1d7e
					    if (g_yyLineNr
Packit 1c1d7e
					    {
Packit 1c1d7e
					      startCodeLine();
Packit 1c1d7e
					    }
Packit 1c1d7e
              g_endComment=TRUE;
Packit 1c1d7e
					  }
Packit 1c1d7e
					  else // do not remove comment
Packit 1c1d7e
					  {
Packit 1c1d7e
					    startFontClass("comment");
Packit 1c1d7e
					    codifyLines(docBlock);
Packit 1c1d7e
					    endFontClass();
Packit 1c1d7e
					  }
Packit 1c1d7e
            unput(*yytext);
Packit 1c1d7e
					  g_contLineNr--;
Packit 1c1d7e
                                         yy_pop_state();
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<*>"!"[^><\n].*|"!"$ 			{ // normal comment
Packit 1c1d7e
					  if(YY_START == String) YY_FTN_REJECT; // ignore in strings
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
Packit 1c1d7e
  					  startFontClass("comment");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
<*>^[Cc*].*              		{ // normal comment
Packit 1c1d7e
                                          if(! g_isFixedForm) YY_FTN_REJECT;
Packit 1c1d7e
Packit 1c1d7e
  					  startFontClass("comment");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
<*>"assignment"/{BS}"("{BS}"="{BS}")"   {
Packit 1c1d7e
  					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
<*>"operator"/{BS}"("[^)]*")"           {
Packit 1c1d7e
  					  startFontClass("keyword");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
					}
Packit 1c1d7e
Packit 1c1d7e
 /*------ preprocessor  --------------------------------------------*/ 
Packit 1c1d7e
<Start>"#".*\n                          {
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          startFontClass("preprocessor");
Packit 1c1d7e
  					  codifyLines(yytext);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*------ variable references?  -------------------------------------*/ 
Packit 1c1d7e
Packit 1c1d7e
<Start>"%"{BS}{ID}	 		{ // ignore references to elements 
Packit 1c1d7e
					  g_code->codify(yytext);
Packit 1c1d7e
					}
Packit 1c1d7e
<Start>{ID}                             {   
Packit 1c1d7e
  					    g_insideBody=TRUE;
Packit 1c1d7e
                                            generateLink(*g_code, yytext);
Packit 1c1d7e
					    g_insideBody=FALSE;
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*------ strings --------------------------------------------------*/ 
Packit 1c1d7e
<*>"\\\\"                               { str+=yytext; /* ignore \\  */}
Packit 1c1d7e
<*>"\\\""|\\\'                          { str+=yytext; /* ignore \"  */}
Packit 1c1d7e
Packit 1c1d7e
<String>\n                              { // string with \n inside
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          str+=yytext;
Packit 1c1d7e
  					  startFontClass("stringliteral");
Packit 1c1d7e
  					  codifyLines(str);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          str = "";
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
                                        }           
Packit 1c1d7e
<String>\"|\'                           { // string ends with next quote without previous backspace 
Packit 1c1d7e
                                          if(yytext[0]!=stringStartSymbol) YY_FTN_REJECT; // single vs double quote
Packit 1c1d7e
                                          str+=yytext;
Packit 1c1d7e
  					  startFontClass("stringliteral");
Packit 1c1d7e
  					  codifyLines(str);
Packit 1c1d7e
					  endFontClass();
Packit 1c1d7e
                                          yy_pop_state();
Packit 1c1d7e
                                        }           
Packit 1c1d7e
<String>.                               {str+=yytext;}
Packit 1c1d7e
Packit 1c1d7e
<*>\"|\'                                { /* string starts */
Packit 1c1d7e
					  /* if(YY_START == StrIgnore) YY_FTN_REJECT; // ignore in simple comments */
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start == 6) YY_FTN_REJECT;
Packit 1c1d7e
                                          yy_push_state(YY_START);
Packit 1c1d7e
                                          stringStartSymbol=yytext[0]; // single or double quote
Packit 1c1d7e
                                          BEGIN(String);
Packit 1c1d7e
					  str=yytext;
Packit 1c1d7e
                                        }
Packit 1c1d7e
 /*-----------------------------------------------------------------------------*/
Packit 1c1d7e
Packit 1c1d7e
<*>\n					{
Packit 1c1d7e
  					if (g_endComment)
Packit 1c1d7e
            {
Packit 1c1d7e
            g_endComment=FALSE;
Packit 1c1d7e
            }
Packit 1c1d7e
            else
Packit 1c1d7e
            {
Packit 1c1d7e
            codifyLines(yytext);
Packit 1c1d7e
            }
Packit 1c1d7e
					  g_contLineNr++;
Packit 1c1d7e
                                          YY_FTN_RESET
Packit 1c1d7e
  					}
Packit 1c1d7e
<*>^{BS}"type"{BS}"="                   { g_code->codify(yytext); }
Packit 1c1d7e
Packit 1c1d7e
<*>.                                    { 
Packit 1c1d7e
                                          if (g_isFixedForm && yy_my_start > fixedCommentAfter)
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            //yy_push_state(YY_START);
Packit 1c1d7e
                                            //BEGIN(DocBlock);
Packit 1c1d7e
                                            //docBlock=yytext;
Packit 1c1d7e
                                            startFontClass("comment");
Packit 1c1d7e
                                            codifyLines(yytext);
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          else
Packit 1c1d7e
                                          {
Packit 1c1d7e
                                            g_code->codify(yytext);
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                        }
Packit 1c1d7e
<*>{LOG_OPER}                           { // Fortran logical comparison keywords
Packit 1c1d7e
                                          g_code->codify(yytext);
Packit 1c1d7e
                                        }
Packit 1c1d7e
<*><<EOF>>                              {
Packit 1c1d7e
                                          if (YY_START == DocBlock) {
Packit 1c1d7e
                                            if (!Config_getBool(STRIP_CODE_COMMENTS))
Packit 1c1d7e
                                            {
Packit 1c1d7e
                                              startFontClass("comment");
Packit 1c1d7e
                                              codifyLines(docBlock);
Packit 1c1d7e
                                              endFontClass();
Packit 1c1d7e
                                            }
Packit 1c1d7e
                                          }
Packit 1c1d7e
                                          yyterminate();
Packit 1c1d7e
                                        }
Packit 1c1d7e
%%
Packit 1c1d7e
Packit 1c1d7e
/*@ ----------------------------------------------------------------------------
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
/*===================================================================*/
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
void resetFortranCodeParserState() {}
Packit 1c1d7e
Packit 1c1d7e
bool recognizeFixedForm(const char* contents, FortranFormat format); /* prototype, implementation in fortranscanner.l */
Packit 1c1d7e
const char* prepassFixedForm(const char* contents, int *hasContLine); /* prototype, implementation in fortranscanner.l */
Packit 1c1d7e
static void checkContLines(const char *s)
Packit 1c1d7e
{
Packit 1c1d7e
  int numLines = 0;
Packit 1c1d7e
  int curLine = 0;
Packit 1c1d7e
  int i = 0;
Packit 1c1d7e
  const char *p = s;
Packit 1c1d7e
Packit 1c1d7e
  numLines = 2; // one for element 0, one in case no \n at end
Packit 1c1d7e
  while (*p)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (*p == '\n') numLines++;
Packit 1c1d7e
    p++;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  g_hasContLine = (int *) malloc((numLines) * sizeof(int));
Packit 1c1d7e
  for (i = 0; i < numLines; i++)
Packit 1c1d7e
    g_hasContLine[i] = 0;
Packit 1c1d7e
  p = prepassFixedForm(s, g_hasContLine);
Packit 1c1d7e
  g_hasContLine[0] = 0;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void parseFortranCode(CodeOutputInterface &od,const char *className,const QCString &s, 
Packit 1c1d7e
                  bool exBlock, const char *exName,FileDef *fd,
Packit 1c1d7e
		  int startLine,int endLine,bool inlineFragment,
Packit 1c1d7e
		  MemberDef *memberDef,bool,Definition *searchCtx,
Packit 1c1d7e
                  bool collectXRefs, FortranFormat format)
Packit 1c1d7e
{
Packit 1c1d7e
  //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
Packit 1c1d7e
Packit 1c1d7e
  // used parameters
Packit 1c1d7e
  (void)memberDef;
Packit 1c1d7e
  (void)className;
Packit 1c1d7e
Packit 1c1d7e
  if (s.isEmpty()) return;
Packit 1c1d7e
  printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
Packit 1c1d7e
  TooltipManager::instance()->clearTooltips();
Packit 1c1d7e
  g_code = &od;
Packit 1c1d7e
  g_inputString   = s;
Packit 1c1d7e
  g_inputPosition = 0;
Packit 1c1d7e
  g_isFixedForm = recognizeFixedForm((const char*)s,format);
Packit 1c1d7e
  g_contLineNr = 1;
Packit 1c1d7e
  g_hasContLine = NULL;
Packit 1c1d7e
  if (g_isFixedForm)
Packit 1c1d7e
  {
Packit 1c1d7e
    checkContLines(g_inputString);
Packit 1c1d7e
  }
Packit 1c1d7e
  g_currentFontClass = 0;
Packit 1c1d7e
  g_needsTermination = FALSE;
Packit 1c1d7e
  g_searchCtx = searchCtx;
Packit 1c1d7e
  g_collectXRefs = collectXRefs;
Packit 1c1d7e
  if (startLine!=-1)
Packit 1c1d7e
    g_yyLineNr    = startLine;
Packit 1c1d7e
  else
Packit 1c1d7e
    g_yyLineNr    = 1;
Packit 1c1d7e
Packit 1c1d7e
  if (endLine!=-1)
Packit 1c1d7e
    g_inputLines  = endLine+1;
Packit 1c1d7e
  else
Packit 1c1d7e
    g_inputLines  = g_yyLineNr + countLines() - 1;
Packit 1c1d7e
Packit 1c1d7e
  g_exampleBlock  = exBlock; 
Packit 1c1d7e
  g_exampleName   = exName;
Packit 1c1d7e
  g_sourceFileDef = fd;
Packit 1c1d7e
  if (exBlock && fd==0)
Packit 1c1d7e
  {
Packit 1c1d7e
    // create a dummy filedef for the example
Packit 1c1d7e
    g_sourceFileDef = new FileDef("",exName);
Packit 1c1d7e
  }
Packit 1c1d7e
  if (g_sourceFileDef) 
Packit 1c1d7e
  {
Packit 1c1d7e
    setCurrentDoc("l00001");
Packit 1c1d7e
  }
Packit 1c1d7e
  g_currentDefinition = 0;
Packit 1c1d7e
  g_currentMemberDef = 0;
Packit 1c1d7e
  if (!g_exampleName.isEmpty())
Packit 1c1d7e
  {
Packit 1c1d7e
    g_exampleFile = convertNameToFile(g_exampleName+"-example");
Packit 1c1d7e
  }
Packit 1c1d7e
  g_includeCodeFragment = inlineFragment;
Packit 1c1d7e
  startCodeLine();
Packit 1c1d7e
  g_parmName.resize(0);
Packit 1c1d7e
  g_parmType.resize(0);
Packit 1c1d7e
  fortrancodeYYrestart( fortrancodeYYin );
Packit 1c1d7e
  BEGIN( Start );
Packit 1c1d7e
  fortrancodeYYlex();
Packit 1c1d7e
  if (g_needsTermination)
Packit 1c1d7e
  {
Packit 1c1d7e
    endFontClass();
Packit 1c1d7e
    g_code->endCodeLine();
Packit 1c1d7e
  }
Packit 1c1d7e
  if (fd)
Packit 1c1d7e
  {
Packit 1c1d7e
    TooltipManager::instance()->writeTooltips(*g_code);
Packit 1c1d7e
  }
Packit 1c1d7e
  if (exBlock && g_sourceFileDef)
Packit 1c1d7e
  {
Packit 1c1d7e
    // delete the temporary file definition used for this example
Packit 1c1d7e
    delete g_sourceFileDef;
Packit 1c1d7e
    g_sourceFileDef=0;
Packit 1c1d7e
  }
Packit 1c1d7e
  if (g_hasContLine) free(g_hasContLine);
Packit 1c1d7e
  g_hasContLine = NULL;
Packit 1c1d7e
  printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
Packit 1c1d7e
  return;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
#if !defined(YY_FLEX_SUBMINOR_VERSION)
Packit 1c1d7e
extern "C" { // some bogus code to keep the compiler happy
Packit 1c1d7e
  void fortrancodeYYdummy() { yy_flex_realloc(0,0); }
Packit 1c1d7e
}
Packit 1c1d7e
#elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
Packit 1c1d7e
#error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
Packit 1c1d7e
#else
Packit 1c1d7e
extern "C" { // some bogus code to keep the compiler happy
Packit 1c1d7e
  void fortrancodeYYdummy() { yy_top_state(); } 
Packit 1c1d7e
}
Packit 1c1d7e
#endif
Packit 1c1d7e