Blame src/vhdljjparser.cpp

Packit 1c1d7e
/******************************************************************************
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright (C) 2014 by M. Kreis
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
 */
Packit 1c1d7e
Packit 1c1d7e
#include <qcstring.h>
Packit 1c1d7e
#include <qfileinfo.h>
Packit 1c1d7e
#include <qstringlist.h>
Packit 1c1d7e
#include "vhdljjparser.h"
Packit 1c1d7e
#include "vhdlcode.h"
Packit 1c1d7e
#include "vhdldocgen.h"
Packit 1c1d7e
#include "message.h"
Packit 1c1d7e
#include "config.h"
Packit 1c1d7e
#include "doxygen.h"
Packit 1c1d7e
#include "util.h"
Packit 1c1d7e
#include "language.h"
Packit 1c1d7e
#include "commentscan.h"
Packit 1c1d7e
#include "index.h"
Packit 1c1d7e
#include "definition.h"
Packit 1c1d7e
#include "searchindex.h"
Packit 1c1d7e
#include "outputlist.h"
Packit 1c1d7e
#include "arguments.h"
Packit 1c1d7e
#include "types.h"
Packit 1c1d7e
#include "VhdlParserIF.h"
Packit 1c1d7e
Packit 1c1d7e
using namespace vhdl::parser;
Packit 1c1d7e
using namespace std;
Packit 1c1d7e
Packit 1c1d7e
static ParserInterface *g_thisParser;
Packit 1c1d7e
Packit 1c1d7e
static QCString         yyFileName;
Packit 1c1d7e
static int              yyLineNr      = 1;
Packit 1c1d7e
static int*             lineParse;
Packit 1c1d7e
static int              iDocLine      = -1;
Packit 1c1d7e
static QCString         inputString;
Packit 1c1d7e
static Entry*           gBlock        = 0;
Packit 1c1d7e
static Entry*           previous      = 0;
Packit 1c1d7e
//-------------------------------------------------------
Packit 1c1d7e
Packit 1c1d7e
static Entry* oldEntry;
Packit 1c1d7e
static bool varr=FALSE;
Packit 1c1d7e
static QCString varName;
Packit 1c1d7e
Packit 1c1d7e
static QList<Entry> instFiles;
Packit 1c1d7e
static QList<Entry> libUse;
Packit 1c1d7e
static QList<Entry> lineEntry;
Packit 1c1d7e
Packit 1c1d7e
Entry*   VhdlParser::currentCompound=0;
Packit 1c1d7e
Entry*   VhdlParser::tempEntry=0;
Packit 1c1d7e
Entry*   VhdlParser::lastEntity=0  ;
Packit 1c1d7e
Entry*   VhdlParser::lastCompound=0  ;
Packit 1c1d7e
Entry*   VhdlParser::current=0;
Packit 1c1d7e
Entry*   VhdlParser::current_root  = 0;
Packit 1c1d7e
QCString VhdlParser::compSpec;
Packit 1c1d7e
QCString VhdlParser::currName;
Packit 1c1d7e
QCString VhdlParser::confName;
Packit 1c1d7e
QCString VhdlParser::genLabels;
Packit 1c1d7e
QCString VhdlParser::lab;
Packit 1c1d7e
QCString VhdlParser::forL;
Packit 1c1d7e
Packit 1c1d7e
int VhdlParser::param_sec = 0;
Packit 1c1d7e
int VhdlParser::parse_sec=0;
Packit 1c1d7e
int VhdlParser::currP=0;
Packit 1c1d7e
int VhdlParser::levelCounter;
Packit 1c1d7e
Packit 1c1d7e
static QList<VhdlConfNode> configL;
Packit 1c1d7e
Packit 1c1d7e
static struct
Packit 1c1d7e
{
Packit 1c1d7e
  QCString doc;
Packit 1c1d7e
  bool brief;
Packit 1c1d7e
  bool pending;
Packit 1c1d7e
  int iDocLine;
Packit 1c1d7e
} str_doc;
Packit 1c1d7e
Packit 1c1d7e
static bool doxComment=FALSE; // doxygen comment ?
Packit 1c1d7e
static QCString strComment;
Packit 1c1d7e
static int iCodeLen;
Packit 1c1d7e
Packit 1c1d7e
bool  checkMultiComment(QCString& qcs,int line);
Packit 1c1d7e
QList<Entry>* getEntryAtLine(const Entry* ce,int line);
Packit 1c1d7e
Packit 1c1d7e
//-------------------------------------
Packit 1c1d7e
Packit 1c1d7e
QList<VhdlConfNode>& getVhdlConfiguration() { return  configL; }
Packit 1c1d7e
QList<Entry>& getVhdlInstList() { return  instFiles; }
Packit 1c1d7e
Packit 1c1d7e
Entry* getVhdlCompound()
Packit 1c1d7e
{
Packit 1c1d7e
  if (VhdlParser::lastEntity) return VhdlParser::lastEntity;
Packit 1c1d7e
  if (VhdlParser::lastCompound) return VhdlParser::lastCompound;
Packit 1c1d7e
  return NULL;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void startCodeBlock(int index)
Packit 1c1d7e
{
Packit 1c1d7e
  int ll=strComment.length();
Packit 1c1d7e
  if (!gBlock) gBlock = new Entry;
Packit 1c1d7e
  iCodeLen=inputString.findRev(strComment.data())+ll;
Packit 1c1d7e
  // fprintf(stderr,"\n startin code..%d %d %d\n",iCodeLen,num_chars,ll);
Packit 1c1d7e
  gBlock->reset();
Packit 1c1d7e
  int len=strComment.length();
Packit 1c1d7e
  QCString name=strComment.right(len-index);//
Packit 1c1d7e
  name=VhdlDocGen::getIndexWord(name.data(),1);
Packit 1c1d7e
  if (!name)
Packit 1c1d7e
    gBlock->name="misc"+ VhdlDocGen::getRecordNumber();
Packit 1c1d7e
  else
Packit 1c1d7e
    gBlock->name=name;
Packit 1c1d7e
Packit 1c1d7e
  gBlock->startLine=yyLineNr;
Packit 1c1d7e
  gBlock->bodyLine=yyLineNr;
Packit 1c1d7e
Packit 1c1d7e
  strComment=strComment.left(index);
Packit 1c1d7e
  VhdlDocGen::prepareComment(strComment);
Packit 1c1d7e
  gBlock->brief+=strComment;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void makeInlineDoc(int endCode)
Packit 1c1d7e
{
Packit 1c1d7e
  int len=endCode-iCodeLen;
Packit 1c1d7e
  if (!gBlock) gBlock = new Entry;
Packit 1c1d7e
  QCString par=inputString.mid(iCodeLen,len);
Packit 1c1d7e
  //fprintf(stderr,"\n inline code: \n<%s>",par.data());
Packit 1c1d7e
  gBlock->doc=par;
Packit 1c1d7e
  gBlock->inbodyDocs=par;
Packit 1c1d7e
  gBlock->section=Entry::VARIABLE_SEC;
Packit 1c1d7e
  gBlock->spec=VhdlDocGen::MISCELLANEOUS;
Packit 1c1d7e
  gBlock->fileName = yyFileName;
Packit 1c1d7e
  gBlock->endBodyLine=yyLineNr-1;
Packit 1c1d7e
  gBlock->lang=SrcLangExt_VHDL;
Packit 1c1d7e
  Entry *temp=new Entry(*gBlock);
Packit 1c1d7e
  Entry* compound=getVhdlCompound();
Packit 1c1d7e
Packit 1c1d7e
  if (compound)
Packit 1c1d7e
  {
Packit 1c1d7e
    compound->addSubEntry(temp);
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    temp->type="misc"; // global code like library ieee...
Packit 1c1d7e
    VhdlParser::current_root->addSubEntry(temp);
Packit 1c1d7e
  }
Packit 1c1d7e
  strComment.resize(0);
Packit 1c1d7e
  gBlock->reset();
Packit 1c1d7e
}// makeInlineDoc
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
bool isConstraintFile(const QCString &fileName,const QCString &ext)
Packit 1c1d7e
{
Packit 1c1d7e
  return fileName.right(ext.length())==ext;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf,Entry *root,
Packit 1c1d7e
                          bool ,QStrList&)
Packit 1c1d7e
{
Packit 1c1d7e
  g_thisParser=this;
Packit 1c1d7e
  bool inLine=false;
Packit 1c1d7e
  inputString=fileBuf;
Packit 1c1d7e
Packit 1c1d7e
 // fprintf(stderr,"\n ============= %s\n ==========\n",fileBuf);
Packit 1c1d7e
Packit 1c1d7e
  if (strlen(fileName)==0)
Packit 1c1d7e
  {
Packit 1c1d7e
    inLine=true;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  yyFileName+=fileName;
Packit 1c1d7e
Packit 1c1d7e
  bool xilinx_ucf=isConstraintFile(yyFileName,".ucf");
Packit 1c1d7e
  bool altera_qsf=isConstraintFile(yyFileName,".qsf");
Packit 1c1d7e
Packit 1c1d7e
  // support XILINX(ucf) and ALTERA (qsf) file
Packit 1c1d7e
Packit 1c1d7e
  if (xilinx_ucf)
Packit 1c1d7e
  {
Packit 1c1d7e
    VhdlDocGen::parseUCF(fileBuf,root,yyFileName,FALSE);
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
  if (altera_qsf)
Packit 1c1d7e
  {
Packit 1c1d7e
    VhdlDocGen::parseUCF(fileBuf,root,yyFileName,TRUE);
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
  libUse.setAutoDelete(true);
Packit 1c1d7e
  yyLineNr=1;
Packit 1c1d7e
  VhdlParser::current_root=root;
Packit 1c1d7e
  VhdlParser::lastCompound=0;
Packit 1c1d7e
  VhdlParser::lastEntity=0;
Packit 1c1d7e
  VhdlParser::currentCompound=0;
Packit 1c1d7e
  VhdlParser::lastEntity=0;
Packit 1c1d7e
  oldEntry = 0;
Packit 1c1d7e
  VhdlParser::current=new Entry();
Packit 1c1d7e
  VhdlParser::initEntry(VhdlParser::current);
Packit 1c1d7e
  groupEnterFile(fileName,yyLineNr);
Packit 1c1d7e
  lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h
Packit 1c1d7e
  VhdlParserIF::parseVhdlfile(fileBuf,inLine);
Packit 1c1d7e
Packit 1c1d7e
  delete VhdlParser::current;
Packit 1c1d7e
  VhdlParser::current=0;
Packit 1c1d7e
Packit 1c1d7e
  if (!inLine)
Packit 1c1d7e
  VhdlParser::mapLibPackage(root);
Packit 1c1d7e
Packit 1c1d7e
  delete[] lineParse;
Packit 1c1d7e
  yyFileName.resize(0);
Packit 1c1d7e
  libUse.clear();
Packit 1c1d7e
  VhdlDocGen::resetCodeVhdlParserState();
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::lineCount()
Packit 1c1d7e
{
Packit 1c1d7e
  yyLineNr++;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::lineCount(const char* text)
Packit 1c1d7e
{
Packit 1c1d7e
  for (const char* c=text ; *c ; ++c )
Packit 1c1d7e
  {
Packit 1c1d7e
    yyLineNr += (*c == '\n') ;
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void isVhdlDocPending()
Packit 1c1d7e
{
Packit 1c1d7e
  if (!str_doc.pending) return;
Packit 1c1d7e
Packit 1c1d7e
  str_doc.pending=FALSE;
Packit 1c1d7e
  oldEntry=0; // prevents endless recursion
Packit 1c1d7e
  iDocLine=str_doc.iDocLine;
Packit 1c1d7e
  VhdlParser::handleCommentBlock(str_doc.doc,str_doc.brief);
Packit 1c1d7e
  iDocLine=-1;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::initEntry(Entry *e)
Packit 1c1d7e
{
Packit 1c1d7e
  e->fileName = yyFileName;
Packit 1c1d7e
  e->lang     = SrcLangExt_VHDL;
Packit 1c1d7e
  isVhdlDocPending();
Packit 1c1d7e
  initGroupInfo(e);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::newEntry()
Packit 1c1d7e
{
Packit 1c1d7e
  if (current->spec==VhdlDocGen::ENTITY ||
Packit 1c1d7e
      current->spec==VhdlDocGen::PACKAGE ||
Packit 1c1d7e
      current->spec==VhdlDocGen::ARCHITECTURE ||
Packit 1c1d7e
      current->spec==VhdlDocGen::PACKAGE_BODY)
Packit 1c1d7e
  {
Packit 1c1d7e
    current_root->addSubEntry(current);
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    if (lastCompound)
Packit 1c1d7e
    {
Packit 1c1d7e
      lastCompound->addSubEntry(current);
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      if (lastEntity)
Packit 1c1d7e
      {
Packit 1c1d7e
	lastEntity->addSubEntry(current);
Packit 1c1d7e
      }
Packit 1c1d7e
      else
Packit 1c1d7e
      {
Packit 1c1d7e
	current_root->addSubEntry(current);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  previous = current;
Packit 1c1d7e
  current = new Entry ;
Packit 1c1d7e
  initEntry(current);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
bool checkInlineCode(QCString & doc)
Packit 1c1d7e
{
Packit 1c1d7e
  int index=doc.find("\\code");
Packit 1c1d7e
Packit 1c1d7e
  if (index>0)
Packit 1c1d7e
  {
Packit 1c1d7e
     strComment+=doc;
Packit 1c1d7e
	 startCodeBlock(index);
Packit 1c1d7e
	 doxComment=TRUE;
Packit 1c1d7e
	 return true;
Packit 1c1d7e
  }
Packit 1c1d7e
  return false;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::handleFlowComment(const char* doc)
Packit 1c1d7e
{
Packit 1c1d7e
	lineCount(doc);
Packit 1c1d7e
Packit 1c1d7e
  if (VhdlDocGen::getFlowMember())
Packit 1c1d7e
  {
Packit 1c1d7e
    QCString qcs(doc);
Packit 1c1d7e
    qcs=qcs.stripWhiteSpace();
Packit 1c1d7e
    qcs.stripPrefix("--#");
Packit 1c1d7e
    FlowChart::addFlowChart(FlowChart::COMMENT_NO,0,0,qcs.data());
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::handleCommentBlock(const char* doc1,bool brief)
Packit 1c1d7e
{
Packit 1c1d7e
  int position=0;
Packit 1c1d7e
  static bool isIn;
Packit 1c1d7e
  QCString doc;
Packit 1c1d7e
  doc.append(doc1);
Packit 1c1d7e
 // fprintf(stderr,"\n %s",doc.data());
Packit 1c1d7e
  if (doc.isEmpty()) return;
Packit 1c1d7e
Packit 1c1d7e
  if (checkMultiComment(doc,yyLineNr))
Packit 1c1d7e
  {
Packit 1c1d7e
    strComment.resize(0);
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  isIn=checkInlineCode(doc);
Packit 1c1d7e
  bool isEndCode=doc.contains("\\endcode");
Packit 1c1d7e
  // empty comment  --!
Packit 1c1d7e
  if (isEndCode)
Packit 1c1d7e
  {
Packit 1c1d7e
    int end=inputString.find(doc.data(),iCodeLen);
Packit 1c1d7e
    makeInlineDoc(end);
Packit 1c1d7e
    strComment.resize(0);
Packit 1c1d7e
    isIn=false;
Packit 1c1d7e
  }
Packit 1c1d7e
  if (isIn)
Packit 1c1d7e
  {
Packit 1c1d7e
    isIn=false;
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  VhdlDocGen::prepareComment(doc);
Packit 1c1d7e
Packit 1c1d7e
  bool needsEntry=FALSE;
Packit 1c1d7e
  Protection protection=Public;
Packit 1c1d7e
Packit 1c1d7e
  if (oldEntry==current)
Packit 1c1d7e
  {
Packit 1c1d7e
    //printf("\n find pending message  < %s > at line: %d \n ",doc.data(),iDocLine);
Packit 1c1d7e
    str_doc.doc=doc;
Packit 1c1d7e
    str_doc.iDocLine=iDocLine;
Packit 1c1d7e
    str_doc.brief=brief;
Packit 1c1d7e
    str_doc.pending=TRUE;
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  oldEntry=current;
Packit 1c1d7e
Packit 1c1d7e
  if (brief)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->briefLine = yyLineNr;
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    current->docLine = yyLineNr;
Packit 1c1d7e
  }
Packit 1c1d7e
  //  printf("parseCommentBlock file<%s>\n [%s]\n at line [%d] \n ",yyFileName.data(),doc.data(),iDocLine);
Packit 1c1d7e
Packit 1c1d7e
  int j=doc.find("[plant]");
Packit 1c1d7e
  if (j>=0)
Packit 1c1d7e
  {
Packit 1c1d7e
    doc=doc.remove(j,7);
Packit 1c1d7e
    current->stat=true;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  while (parseCommentBlock(
Packit 1c1d7e
        g_thisParser,
Packit 1c1d7e
        current,
Packit 1c1d7e
        doc,        // text
Packit 1c1d7e
        yyFileName, // file
Packit 1c1d7e
        iDocLine,   // line of block start
Packit 1c1d7e
        brief,
Packit 1c1d7e
        0,
Packit 1c1d7e
        FALSE,
Packit 1c1d7e
        protection,
Packit 1c1d7e
        position,
Packit 1c1d7e
        needsEntry
Packit 1c1d7e
        )
Packit 1c1d7e
      )
Packit 1c1d7e
  {
Packit 1c1d7e
    //printf("parseCommentBlock position=%d [%s]\n",position,doc.data()+position);
Packit 1c1d7e
    if (needsEntry) newEntry();
Packit 1c1d7e
  }
Packit 1c1d7e
  if (needsEntry)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (varr)
Packit 1c1d7e
    {
Packit 1c1d7e
      varr=FALSE;
Packit 1c1d7e
      current->name=varName;
Packit 1c1d7e
      current->section=Entry::VARIABLEDOC_SEC;
Packit 1c1d7e
      varName="";
Packit 1c1d7e
    }
Packit 1c1d7e
    newEntry();
Packit 1c1d7e
  }
Packit 1c1d7e
  iDocLine=-1;
Packit 1c1d7e
  strComment.resize(0);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VHDLLanguageScanner::parsePrototype(const char *text)
Packit 1c1d7e
{
Packit 1c1d7e
  varName=text;
Packit 1c1d7e
  varr=TRUE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::addCompInst(const char *n, const char* instName, const char* comp,int iLine)
Packit 1c1d7e
{
Packit 1c1d7e
  current->spec=VhdlDocGen::INSTANTIATION;
Packit 1c1d7e
  current->section=Entry::VARIABLE_SEC;
Packit 1c1d7e
  current->startLine=iLine;
Packit 1c1d7e
  current->bodyLine=iLine;
Packit 1c1d7e
  current->type=instName;                       // foo:instname e.g proto or work. proto(ttt)
Packit 1c1d7e
  current->exception=genLabels.lower();         // |arch|label1:label2...
Packit 1c1d7e
  current->name=n;                              // foo
Packit 1c1d7e
  if (lastCompound)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->args=lastCompound->name;             // architecture name
Packit 1c1d7e
  }
Packit 1c1d7e
  current->includeName=comp;                    // component/enity/configuration
Packit 1c1d7e
  int u=genLabels.find("|",1);
Packit 1c1d7e
  if (u>0)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->write=genLabels.right(genLabels.length()-u);
Packit 1c1d7e
    current->read=genLabels.left(u);
Packit 1c1d7e
  }
Packit 1c1d7e
  //printf  (" \n genlable: [%s]  inst: [%s]  name: [%s] %d\n",n,instName,comp,iLine);
Packit 1c1d7e
Packit 1c1d7e
  if (lastCompound)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->args=lastCompound->name;
Packit 1c1d7e
    if (true) // !findInstant(current->type))
Packit 1c1d7e
    {
Packit 1c1d7e
      initEntry(current);
Packit 1c1d7e
      instFiles.append(new Entry(*current));
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    Entry *temp=current;  // hold  current pointer  (temp=oldEntry)
Packit 1c1d7e
    current=new Entry;     // (oldEntry != current)
Packit 1c1d7e
    delete  temp;
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    newEntry();
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::addVhdlType(const char *n,int startLine,int section,
Packit 1c1d7e
    uint64 spec,const char* args,const char* type,Protection prot)
Packit 1c1d7e
{
Packit 1c1d7e
  QCString name(n);
Packit 1c1d7e
  if (isFuncProcProced() || VhdlDocGen::getFlowMember())  return;
Packit 1c1d7e
Packit 1c1d7e
  if (parse_sec==GEN_SEC)
Packit 1c1d7e
  {
Packit 1c1d7e
    spec= VhdlDocGen::GENERIC;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  QStringList ql=QStringList::split(",",name,FALSE);
Packit 1c1d7e
Packit 1c1d7e
  for (uint u=0;u
Packit 1c1d7e
  {
Packit 1c1d7e
    current->name=ql[u].utf8();
Packit 1c1d7e
    current->startLine=startLine;
Packit 1c1d7e
    current->bodyLine=startLine;
Packit 1c1d7e
    current->section=section;
Packit 1c1d7e
    current->spec=spec;
Packit 1c1d7e
    current->fileName=yyFileName;
Packit 1c1d7e
    if (current->args.isEmpty())
Packit 1c1d7e
    {
Packit 1c1d7e
      current->args=args;
Packit 1c1d7e
    }
Packit 1c1d7e
    current->type=type;
Packit 1c1d7e
    current->protection=prot;
Packit 1c1d7e
Packit 1c1d7e
    if (!lastCompound && (section==Entry::VARIABLE_SEC) &&  (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) )
Packit 1c1d7e
    {
Packit 1c1d7e
      libUse.append(new Entry(*current));
Packit 1c1d7e
      current->reset();
Packit 1c1d7e
    }
Packit 1c1d7e
    newEntry();
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn)
Packit 1c1d7e
{
Packit 1c1d7e
  QCString impure(imp);
Packit 1c1d7e
  QCString fname(fn);
Packit 1c1d7e
  current->spec=spec;
Packit 1c1d7e
  current->section=Entry::FUNCTION_SEC;
Packit 1c1d7e
Packit 1c1d7e
  if (impure=="impure" || impure=="pure")
Packit 1c1d7e
  {
Packit 1c1d7e
    current->exception=impure;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (parse_sec==GEN_SEC)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->spec= VhdlDocGen::GENERIC;
Packit 1c1d7e
    current->section=Entry::FUNCTION_SEC;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (currP==VhdlDocGen::PROCEDURE)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->name=impure;
Packit 1c1d7e
    current->exception="";
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    current->name=fname;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (spec==VhdlDocGen::PROCESS)
Packit 1c1d7e
  {
Packit 1c1d7e
    current->args=fname;
Packit 1c1d7e
    current->name=impure;
Packit 1c1d7e
    VhdlDocGen::deleteAllChars(current->args,' ');
Packit 1c1d7e
    if (!fname.isEmpty())
Packit 1c1d7e
    {
Packit 1c1d7e
      QStringList q1=QStringList::split(",",fname);
Packit 1c1d7e
      for (uint ii=0;ii
Packit 1c1d7e
      {
Packit 1c1d7e
        Argument *arg=new Argument;
Packit 1c1d7e
        arg->name=q1[ii].utf8();
Packit 1c1d7e
        current->argList->append(arg);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
 }
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
bool VhdlParser::isFuncProcProced()
Packit 1c1d7e
{
Packit 1c1d7e
  if (currP==VhdlDocGen::FUNCTION  ||
Packit 1c1d7e
      currP==VhdlDocGen::PROCEDURE ||
Packit 1c1d7e
      currP==VhdlDocGen::PROCESS
Packit 1c1d7e
     )
Packit 1c1d7e
  {
Packit 1c1d7e
    return TRUE;
Packit 1c1d7e
  }
Packit 1c1d7e
  return FALSE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::pushLabel( QCString &label,QCString & val)
Packit 1c1d7e
{
Packit 1c1d7e
  label+="|";
Packit 1c1d7e
  label+=val;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
 QCString  VhdlParser::popLabel(QCString & q)
Packit 1c1d7e
{
Packit 1c1d7e
  int i=q.findRev("|");
Packit 1c1d7e
  if (i<0) return "";
Packit 1c1d7e
  q = q.left(i);
Packit 1c1d7e
  return q;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf)
Packit 1c1d7e
{
Packit 1c1d7e
  VhdlConfNode* co=0;
Packit 1c1d7e
  QCString ent;
Packit 1c1d7e
  ent=a;
Packit 1c1d7e
Packit 1c1d7e
  if (b)
Packit 1c1d7e
  {
Packit 1c1d7e
    ent=b;
Packit 1c1d7e
  }
Packit 1c1d7e
  int level=0;
Packit 1c1d7e
Packit 1c1d7e
  if (!configL.isEmpty())
Packit 1c1d7e
  {
Packit 1c1d7e
    VhdlConfNode* vc=configL.getLast();
Packit 1c1d7e
    level=vc->level;
Packit 1c1d7e
    if (levelCounter==0)
Packit 1c1d7e
    {
Packit 1c1d7e
      pushLabel(forL,ent);
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (level
Packit 1c1d7e
    {
Packit 1c1d7e
      if (!isLeaf)
Packit 1c1d7e
      {
Packit 1c1d7e
        pushLabel(forL,ent);
Packit 1c1d7e
      }
Packit 1c1d7e
    }
Packit 1c1d7e
    else if (level>levelCounter)
Packit 1c1d7e
    {
Packit 1c1d7e
      forL=popLabel(forL);
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    pushLabel(forL,ent);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (inlineConf)
Packit 1c1d7e
  {
Packit 1c1d7e
    confName=lastCompound->name;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  //fprintf(stderr,"\n[%s %d %d]\n",forL.data(),levelCounter,level);
Packit 1c1d7e
  co=new VhdlConfNode(a,b,confName.lower().data(),forL.lower().data(),isLeaf);
Packit 1c1d7e
Packit 1c1d7e
  if (inlineConf)
Packit 1c1d7e
  {
Packit 1c1d7e
    co->isInlineConf=TRUE;
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  configL.append(co);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::addProto(const char *s1,const char *s2,const char *s3,
Packit 1c1d7e
    const char *s4,const char *s5,const char *s6)
Packit 1c1d7e
{
Packit 1c1d7e
  (void)s5; // avoid unused warning
Packit 1c1d7e
  QCString name=s2;
Packit 1c1d7e
  QStringList ql=QStringList::split(",",name,FALSE);
Packit 1c1d7e
Packit 1c1d7e
  for (uint u=0;u
Packit 1c1d7e
  {
Packit 1c1d7e
    Argument *arg=new Argument;
Packit 1c1d7e
    arg->name=ql[u].utf8();
Packit 1c1d7e
    if (s3)
Packit 1c1d7e
    {
Packit 1c1d7e
      arg->type=s3;
Packit 1c1d7e
    }
Packit 1c1d7e
    arg->type+=" ";
Packit 1c1d7e
    arg->type+=s4;
Packit 1c1d7e
    if (s6)
Packit 1c1d7e
    {
Packit 1c1d7e
      arg->type+=s6;
Packit 1c1d7e
    }
Packit 1c1d7e
    if (parse_sec==GEN_SEC && param_sec==0)
Packit 1c1d7e
    {
Packit 1c1d7e
      arg->defval="gen!";
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    if (parse_sec==PARAM_SEC)
Packit 1c1d7e
    {
Packit 1c1d7e
    //  assert(false);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    arg->defval+=s1;
Packit 1c1d7e
    arg->attrib="";//s6;
Packit 1c1d7e
Packit 1c1d7e
    current->argList->append(arg);
Packit 1c1d7e
    current->args+=s2;
Packit 1c1d7e
    current->args+=",";
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
/*
Packit 1c1d7e
 * adds the library|use statements to the next class (entity|package|architecture|package body
Packit 1c1d7e
 * library ieee
Packit 1c1d7e
 * entity xxx
Packit 1c1d7e
 * .....
Packit 1c1d7e
 * library
Packit 1c1d7e
 * package
Packit 1c1d7e
 * enity zzz
Packit 1c1d7e
 * .....
Packit 1c1d7e
 * and so on..
Packit 1c1d7e
 */
Packit 1c1d7e
void VhdlParser::mapLibPackage( Entry* root)
Packit 1c1d7e
{
Packit 1c1d7e
  QList<Entry> epp=libUse;
Packit 1c1d7e
  EntryListIterator eli(epp);
Packit 1c1d7e
  Entry *rt;
Packit 1c1d7e
  for (;(rt=eli.current());++eli)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (addLibUseClause(rt->name))
Packit 1c1d7e
    {
Packit 1c1d7e
      Entry *current;
Packit 1c1d7e
      EntryListIterator eLib(*root->children());
Packit 1c1d7e
      bool bFound=FALSE;
Packit 1c1d7e
      for (eLib.toFirst();(current=eLib.current());++eLib)
Packit 1c1d7e
      {
Packit 1c1d7e
        if (VhdlDocGen::isVhdlClass(current))
Packit 1c1d7e
        {
Packit 1c1d7e
          if (current->startLine > rt->startLine)
Packit 1c1d7e
          {
Packit 1c1d7e
            bFound=TRUE;
Packit 1c1d7e
            current->addSubEntry(new Entry(*rt));
Packit 1c1d7e
            break;
Packit 1c1d7e
          }
Packit 1c1d7e
        }
Packit 1c1d7e
      }//for
Packit 1c1d7e
      if (!bFound)
Packit 1c1d7e
      {
Packit 1c1d7e
        root->addSubEntry(new Entry(*rt));
Packit 1c1d7e
      }
Packit 1c1d7e
    } //if
Packit 1c1d7e
  }// for
Packit 1c1d7e
}//MapLib
Packit 1c1d7e
Packit 1c1d7e
bool VhdlParser::addLibUseClause(const QCString &type)
Packit 1c1d7e
{
Packit 1c1d7e
  static bool showIEEESTD=Config_getBool(FORCE_LOCAL_INCLUDES);
Packit 1c1d7e
Packit 1c1d7e
  if (showIEEESTD) // all standard packages and libraries will not be shown
Packit 1c1d7e
  {
Packit 1c1d7e
    if (type.lower().stripPrefix("ieee")) return FALSE;
Packit 1c1d7e
    if (type.lower().stripPrefix("std")) return FALSE;
Packit 1c1d7e
  }
Packit 1c1d7e
  return TRUE;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
int VhdlParser::getLine()
Packit 1c1d7e
{
Packit 1c1d7e
  return yyLineNr;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::setLineParsed(int tok)
Packit 1c1d7e
{
Packit 1c1d7e
  lineParse[tok]=yyLineNr;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
int VhdlParser::getLine(int tok)
Packit 1c1d7e
{
Packit 1c1d7e
  int val=lineParse[tok];
Packit 1c1d7e
  if (val<0) val=0;
Packit 1c1d7e
  //assert(val>=0 && val<=yyLineNr);
Packit 1c1d7e
  return val;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::createFlow()
Packit 1c1d7e
{
Packit 1c1d7e
  if (!VhdlDocGen::getFlowMember())
Packit 1c1d7e
  {
Packit 1c1d7e
    return;
Packit 1c1d7e
  }
Packit 1c1d7e
  QCString q,ret;
Packit 1c1d7e
Packit 1c1d7e
  if (currP==VhdlDocGen::FUNCTION)
Packit 1c1d7e
  {
Packit 1c1d7e
    q=":function( ";
Packit 1c1d7e
    FlowChart::alignFuncProc(q,tempEntry->argList,true);
Packit 1c1d7e
    q+=")";
Packit 1c1d7e
  }
Packit 1c1d7e
  else if (currP==VhdlDocGen::PROCEDURE)
Packit 1c1d7e
  {
Packit 1c1d7e
    q=":procedure (";
Packit 1c1d7e
    FlowChart::alignFuncProc(q,tempEntry->argList,false);
Packit 1c1d7e
    q+=")";
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    q=":process( "+tempEntry->args;
Packit 1c1d7e
    q+=")";
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  q.prepend(VhdlDocGen::getFlowMember()->name().data());
Packit 1c1d7e
Packit 1c1d7e
  FlowChart::addFlowChart(FlowChart::START_NO,q,0);
Packit 1c1d7e
Packit 1c1d7e
  if (currP==VhdlDocGen::FUNCTION)
Packit 1c1d7e
  {
Packit 1c1d7e
    ret="end function ";
Packit 1c1d7e
  }
Packit 1c1d7e
  else if (currP==VhdlDocGen::PROCEDURE)
Packit 1c1d7e
  {
Packit 1c1d7e
    ret="end procedure";
Packit 1c1d7e
  }
Packit 1c1d7e
  else
Packit 1c1d7e
  {
Packit 1c1d7e
    ret="end process ";
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  FlowChart::addFlowChart(FlowChart::END_NO,ret,0);
Packit 1c1d7e
  //  FlowChart::printFlowList();
Packit 1c1d7e
  FlowChart::writeFlowChart();
Packit 1c1d7e
  currP=0;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::setMultCommentLine()
Packit 1c1d7e
{
Packit 1c1d7e
  iDocLine=yyLineNr;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
void VhdlParser::oneLineComment(QCString qcs)
Packit 1c1d7e
{
Packit 1c1d7e
  bool isEndCode=qcs.contains("\\endcode");
Packit 1c1d7e
Packit 1c1d7e
  int index = qcs.find("\\code");
Packit 1c1d7e
  if (isEndCode)
Packit 1c1d7e
  {
Packit 1c1d7e
    int end = inputString.find(qcs.data(),iCodeLen);
Packit 1c1d7e
    makeInlineDoc(end);
Packit 1c1d7e
  }
Packit 1c1d7e
  else if (index > 0)
Packit 1c1d7e
  {
Packit 1c1d7e
    // assert(false);
Packit 1c1d7e
    strComment=qcs;
Packit 1c1d7e
    startCodeBlock(index);
Packit 1c1d7e
    strComment.resize(0);
Packit 1c1d7e
  }
Packit 1c1d7e
Packit 1c1d7e
  if (!isEndCode && index==-1)
Packit 1c1d7e
  {
Packit 1c1d7e
    int j=qcs.find("--!");
Packit 1c1d7e
    qcs=qcs.right(qcs.length()-3-j);
Packit 1c1d7e
    if (!checkMultiComment(qcs,iDocLine))
Packit 1c1d7e
    {
Packit 1c1d7e
      handleCommentBlock(qcs,TRUE);
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
Packit 1c1d7e
bool  checkMultiComment(QCString& qcs,int line)
Packit 1c1d7e
{
Packit 1c1d7e
  QList<Entry> *pTemp=getEntryAtLine(VhdlParser::current_root,line);
Packit 1c1d7e
Packit 1c1d7e
  if (pTemp->isEmpty()) return false;
Packit 1c1d7e
Packit 1c1d7e
  VhdlDocGen::prepareComment(qcs);
Packit 1c1d7e
  while (!pTemp->isEmpty())
Packit 1c1d7e
  {
Packit 1c1d7e
    Entry *e=(Entry*)pTemp->getFirst();
Packit 1c1d7e
    e->briefLine=line;
Packit 1c1d7e
    e->brief+=qcs;
Packit 1c1d7e
Packit 1c1d7e
    pTemp->removeFirst();
Packit 1c1d7e
  }
Packit 1c1d7e
  return true;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
// returns the vhdl parsed types at line xxx
Packit 1c1d7e
QList<Entry>* getEntryAtLine(const Entry* ce,int line)
Packit 1c1d7e
{
Packit 1c1d7e
  EntryListIterator eli(*ce->children());
Packit 1c1d7e
  Entry *rt;
Packit 1c1d7e
  for (;(rt=eli.current());++eli)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (rt->bodyLine==line)
Packit 1c1d7e
    {
Packit 1c1d7e
      lineEntry.insert(0,rt);
Packit 1c1d7e
    }
Packit 1c1d7e
Packit 1c1d7e
    getEntryAtLine(rt,line);
Packit 1c1d7e
  }
Packit 1c1d7e
  return &lineEntry;
Packit 1c1d7e
}
Packit 1c1d7e