Blame src/vhdljjparser.cpp

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