⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 code.l

📁 doxygen(一个自动从源代码生成文档的工具)的源代码
💻 L
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************** * *  * * Copyright (C) 1997-2001 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby  * granted. No representations are made about the suitability of this software  * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */%{/* *	includes */#include <stdio.h>#include <assert.h>#include <ctype.h>#include <qregexp.h>#include "qtbc.h"#include "scanner.h"#include "entry.h"#include "doxygen.h"#include "message.h"#include "outputlist.h"#include "util.h"#include "membername.h"#define YY_NEVER_INTERACTIVE 1  // Toggle for some debugging info//#define DBG_CTX(x) fprintf x#define DBG_CTX(x) do { } while(0)  #define SCOPEBLOCK (int *)4#define INNERBLOCK (int *)8/* ----------------------------------------------------------------- *	statics */  static OutputDocInterface * g_code;static ClassSDict    g_codeClassSDict(17);static ClassDef     *g_curClassDef;static QCString      g_curClassName;static QStrList      g_curClassBases;// TODO: is this still needed? if so, make it workstatic bool          g_inClass;static QCString      g_parmType;static QCString      g_parmName;static const char *  g_inputString;     //!< the code fragment as textstatic int	     g_inputPosition;   //!< read offset during parsing static int           g_inputLines;      //!< number of line in the code fragmentstatic int	     g_yyLineNr;        //!< current line numberstatic bool          g_exampleBlock;static QCString      g_exampleName;static QCString      g_exampleFile;static bool          g_insideTemplate = FALSE;static QCString      g_type;static QCString      g_name;static QCString      g_args;static QCString      g_classScope;static QCString      g_realScope;static QStack<int>   g_scopeStack;      //!< 1 if bracket starts a scope, 2 for internal blocks static int           g_anchorCount;static FileDef *     g_sourceFileDef;static Definition *  g_currentDefinition;static MemberDef *   g_currentMemberDef;static bool          g_includeCodeFragment;static const char *  g_currentFontClass;static bool          g_searchingForBody;static bool          g_insideBody;static int           g_bodyCurlyCount;static QCString      g_saveName;static QCString      g_saveType;static int	     g_bracketCount = 0;static int	     g_curlyCount   = 0;static int	     g_sharpCount   = 0;static int	     g_lastSpecialCContext;static int           g_lastStringContext;static int           g_memCallContext;static int	     g_lastCContext;//-------------------------------------------------------------------/*! Represents a stack of variable to class mappings as found in the *  code. Each scope is enclosed in pushScope() and popScope() calls. *  Variables are added by calling addVariables() and one can search *  for variable using findVariable(). */class VariableContext{  public:    class Scope : public SDict<ClassDef>    {      public:	Scope() : SDict<ClassDef>(17) {}    };        VariableContext()    {      m_scopes.setAutoDelete(TRUE);    }    virtual ~VariableContext()    {    }        void pushScope()    {      m_scopes.append(new Scope);      DBG_CTX((stderr,"** Push var context %d\n",m_scopes.count()));    }    void popScope()    {      if (m_scopes.count()>0)      {        DBG_CTX((stderr,"** Pop var context %d\n",m_scopes.count()));	m_scopes.remove(m_scopes.count()-1);      }      else      {        DBG_CTX((stderr,"** ILLEGAL: Pop var context\n"));      }    }    void clear()    {      m_scopes.clear();      m_globalScope.clear();    }    void clearExceptGlobal()    {      DBG_CTX((stderr,"** Clear var context\n"));      m_scopes.clear();    }    void addVariable(const QCString &type,const QCString &name);    ClassDef *findVariable(const QCString &name);        Scope        m_globalScope;    QList<Scope> m_scopes;};void VariableContext::addVariable(const QCString &type,const QCString &name){  QCString ltype = type.simplifyWhiteSpace();  QCString lname = name.simplifyWhiteSpace();  if (ltype.left(7)=="struct ")   {    ltype = ltype.right(ltype.length()-7);  }  else if (ltype.left(6)=="union ")  {    ltype = ltype.right(ltype.length()-6);  }  if (ltype.isEmpty() || lname.isEmpty()) return;  DBG_CTX((stderr,"** AddVariable trying: type=%s name=%s\n",ltype.data(),lname.data()));  Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();  ClassDef *varType;  int i=0;  if (      (varType=g_codeClassSDict[ltype]) ||  // look for class definitions inside the code block      (varType=getResolvedClass(g_currentDefinition,ltype)) // look for global class definitions     )   {    DBG_CTX((stderr,"** AddVariable type=%s name=%s\n",ltype.data(),lname.data()));    scope->append(lname,varType); // add it to a list  }  else if ((i=ltype.find('<'))!=-1)  {    // probably a template class, try without arguments as well    addVariable(ltype.left(i),name);  }}ClassDef *VariableContext::findVariable(const QCString &name){  if (name.isEmpty()) return 0;  ClassDef *result = 0;  QListIterator<Scope> sli(m_scopes);  Scope *scope;  // search from inner to outer scope  for (sli.toLast();(scope=sli.current());--sli)  {    result = scope->find(name);    if (result)     {      DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));      return result;    }  }  // nothing found -> also try the global scope  result=m_globalScope.find(name);  DBG_CTX((stderr,"** findVariable(%s)=%p\n",name.data(),result));  return result;}static VariableContext g_theVarContext;//-------------------------------------------------------------------class CallContext{  public:    CallContext()     {      m_classList.append(0);    }    virtual ~CallContext() {}    void setClass(ClassDef *cd)    {      DBG_CTX((stderr,"** Set call context %s (%p)\n",cd==0 ? "<null>" : cd->name().data(),cd));      m_classList.removeLast();      m_classList.append(cd);    }    void pushScope()    {      m_classList.append(0);      DBG_CTX((stderr,"** Push call context %d\n",m_classList.count()));    }    void popScope()    {      if (m_classList.count()>1)      {        DBG_CTX((stderr,"** Pop call context %d\n",m_classList.count()));	m_classList.removeLast();      }      else      {        DBG_CTX((stderr,"** ILLEGAL: Pop call context\n"));      }    }    void clear()    {      DBG_CTX((stderr,"** Clear call context\n"));      m_classList.clear();      m_classList.append(0);    }    ClassDef *getClass() const    {      return m_classList.getLast();    }  private:    QList<ClassDef> m_classList;    };static CallContext g_theCallContext;//-------------------------------------------------------------------/*! add class/namespace name s to the scope */static void pushScope(const char *s){  if (g_classScope.isEmpty())  {    g_classScope = s;  }  else  {    g_classScope += "::";    g_classScope += s;  }  //printf("pushScope() result: `%s'\n",g_classScope.data());}/*! remove the top class/namespace name from the scope */static void popScope(){  if (!g_classScope.isEmpty())  {    int i=g_classScope.findRev("::");    if (i==-1) // last name, strip all    {      g_classScope.resize(0);    }     else // strip name    {      g_classScope = g_classScope.left(i);    }  }  else  {    //err("Error: Too many end of scopes found!\n");  }  //printf("popScope() result: `%s'\n",g_classScope.data());}static void setClassScope(const QCString &name){  //printf("setClassScope(%s)\n",name.data());  QCString n=name;  n=n.simplifyWhiteSpace();  int ts=n.find('<'); // start of template  int te=n.findRev('>'); // end of template  //printf("ts=%d te=%d\n",ts,te);  if (ts!=-1 && te!=-1 && te>ts)  {    // remove template from scope    n=n.left(ts)+n.right(n.length()-te-1);  }  g_classScope = n;  //printf("--->New class scope `%s'\n",g_classScope.data());}/*! start a new line of code, inserting a line number if g_sourceFileDef * is TRUE. If a definition starts at the current line, then the line * number is linked to the documentation of that definition. */static void startCodeLine(){  //if (g_currentFontClass) { g_code->endFontClass(); }  if (g_sourceFileDef)  {    //QCString lineNumber,lineAnchor;    //lineNumber.sprintf("%05d",g_yyLineNr);    //lineAnchor.sprintf("l%05d",g_yyLineNr);       Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);    //g_code->startLineNumber();    if (!g_includeCodeFragment && d && d->isLinkableInProject())    {      g_currentDefinition = d;      g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);      QCString anchor;      g_insideBody = FALSE;      g_searchingForBody = TRUE;      g_realScope = d->name().copy();      //printf("Real scope: `%s'\n",g_realScope.data());      g_bodyCurlyCount = 0;      if (g_currentMemberDef) anchor=g_currentMemberDef->getBodyAnchor();      //g_code->startCodeAnchor(lineAnchor);      //g_code->writeCodeLink(d->getReference(),d->getOutputFileBase(),      // 	               anchor,lineNumber);      //g_code->endCodeAnchor();      g_code->writeLineNumber(d->getReference(),d->getOutputFileBase(),	                      anchor,g_yyLineNr);    }    else    {      //g_code->codify(lineNumber);      g_code->writeLineNumber(0,0,0,g_yyLineNr);    }    //g_code->endLineNumber();  }  g_code->startCodeLine();   if (g_currentFontClass)  {    g_code->startFontClass(g_currentFontClass);  }}static void endFontClass();static void endCodeLine(){  if (g_currentFontClass) { g_code->endFontClass(); }  g_code->endCodeLine();}/*! write a code fragment `text' that may span multiple lines, inserting * line numbers for each line. */static void codifyLines(char *text){  //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);  char *p=text,*sp=p;  char c;  bool done=FALSE;  while (!done)  {    sp=p;    while ((c=*p++) && c!='\n');    if (c=='\n')    {      g_yyLineNr++;      *(p-1)='\0';      g_code->codify(sp);      endCodeLine();      if (g_yyLineNr<g_inputLines)       {	startCodeLine();      }    }    else    {      g_code->codify(sp);      done=TRUE;    }  }}/*! writes a link to a fragment \a text that may span multiple lines, inserting * line numbers for each line. If \a text contains newlines, the link will be  * split into multiple links with the same destination, one for each line. */static void writeMultiLineCodeLink(OutputDocInterface &ol,                  const char *ref,const char *file,                  const char *anchor,const char *text){  bool done=FALSE;  char *p=(char *)text;  while (!done)  {    char *sp=p;    char c;    while ((c=*p++) && c!='\n');    if (c=='\n')    {      g_yyLineNr++;      *(p-1)='\0';      ol.writeCodeLink(ref,file,anchor,sp);      endCodeLine();      if (g_yyLineNr<g_inputLines)       {	startCodeLine();      }    }    else    {      ol.writeCodeLink(ref,file,anchor,sp);      done=TRUE;    }  }}static void addType(){  if (g_name=="const") { g_name.resize(0); return; }  if (!g_type.isEmpty()) g_type += ' ' ;  g_type += g_name ;  g_name.resize(0) ;  if (!g_type.isEmpty()) g_type += ' ' ;  g_type += g_args ;  g_args.resize(0) ;}static void addParmType(){  if (g_parmName=="const") { g_parmName.resize(0); return; }  if (!g_parmType.isEmpty()) g_parmType += ' ' ;  g_parmType += g_parmName ;  g_parmName.resize(0) ;}void setParameterList(MemberDef *md){  g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";  ArgumentList *al = md->argumentList();  if (al==0) return;   Argument *a = al->first();  while (a)  {    g_parmName = a->name.copy();    g_parmType = a->type.copy();    int i = g_parmType.find('*');    if (i!=-1) g_parmType = g_parmType.left(i);    i = g_parmType.find('&');    if (i!=-1) g_parmType = g_parmType.left(i);    if (g_parmType.left(6)=="const ") g_parmType = g_parmType.right(g_parmType.length()-6);    g_parmType=g_parmType.stripWhiteSpace();    g_theVarContext.addVariable(g_parmType,g_parmName);    a = al->next();  }}static ClassDef *stripClassName(const char *s){  int pos=0;  QCString type = s;  QCString className;  QCString templSpec;  while (extractClassNameFromType(type,pos,className,templSpec))  {    QCString clName=className+templSpec;    ClassDef *cd=0;    if (!g_classScope.isEmpty())    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -