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

📄 pre.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 <iostream.h>#include <assert.h>#include <ctype.h>#include "qtbc.h"#include <qarray.h>#include <qstack.h>#include <qfile.h>#include <qstrlist.h>#include <qdict.h>#include <qregexp.h>#include <qfileinfo.h>#include <qdir.h>  #include "pre.h"#include "constexp.h"#include "define.h"#include "doxygen.h"#include "message.h"#include "util.h"#include "defargs.h"#include "debug.h"#include "bufstr.h"#if defined(_MSC_VER) || defined(__BORLANDC__)#define popen _popen#define pclose _pclose#endif#define YY_NEVER_INTERACTIVE 1  struct FileState{  int lineNr;  FILE *filePtr;  YY_BUFFER_STATE bufState;  QCString fileName;};  /* ----------------------------------------------------------------- * *	scanner's state */static int                g_yyLineNr   = 1;static QCString           g_yyFileName;static FileDef           *g_yyFileDef;static int                g_ifcount    = 0;static QStrList          *g_pathList = 0;  static QStack<FileState>  g_includeStack;static QDict<int>        *g_argDict;static int                g_defArgs = -1;static QCString           g_defName;static QCString           g_defText;static QCString           g_defLitText;static QCString           g_defArgsStr;static bool               g_defVarArgs;static int                g_level;static int                g_lastCContext;static int                g_lastCPPContext;static QArray<int>        g_levelGuard;static BufStr            *g_outputBuf;static int                g_roundCount;static bool               g_quoteArg;static DefineDict        *g_fileDefineDict;static DefineDict        *g_expandedDict;static int                g_findDefArgContext;static QCString           g_lastGuardName;static QCString           g_incName;static QCString           g_guardExpr;static int                g_curlyCount;static bool               g_nospaces; // add extra spaces during macro expansionstatic bool               g_macroExpansion; // from the configurationstatic bool               g_expandOnlyPredef; // from the configurationstatic void setFileName(const char *name){  bool ambig;  g_yyFileName=name;  g_yyFileDef=findFileDef(Doxygen::inputNameDict,g_yyFileName,ambig);}static void incrLevel(){  g_level++;  g_levelGuard.resize(g_level);  g_levelGuard[g_level-1]=FALSE;  //printf("%s line %d: incrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level);}static void decrLevel(){  //printf("%s line %d: decrLevel %d\n",g_yyFileName.data(),g_yyLineNr,g_level);  if (g_level > 0)  {    g_level--;    g_levelGuard.resize(g_level);  }  else  {    err("%s:%d: Error: More #endif's than #if's found.\n",	g_yyFileName.data(),g_yyLineNr);  }}static bool otherCaseDone(){  if (g_level==0)  {    err("%s:%d: Error: Found an #else without a preceding #if.\n",	g_yyFileName.data(),g_yyLineNr);    return TRUE;  }  else  {    return g_levelGuard[g_level-1];  }}static void setCaseDone(bool value){  g_levelGuard[g_level-1]=value;}static Define *isDefined(const char *name){  if (name)  {    Define *def;    //if ((def=fileDefineCache->findDefine(g_yyFileName,name)) && !def->undef)     //	return def;    if ((def=g_fileDefineDict->find(name)) && !def->undef) return def;   }  return 0;}static FILE *checkAndOpenFile(const QCString &absName){  FILE *f = 0;  QFileInfo fi(absName);  if (fi.exists() && fi.isFile())  {    if (!Config_getString("INPUT_FILTER").isEmpty())    {      QCString cmd = Config_getString("INPUT_FILTER")+" "+absName;      f=popen(cmd,"r");      if (!f) err("Error: could not execute filter %s\n",cmd.data());    }    else    {      f=fopen(absName,"r");      if (!f) err("Error: could not open file %s for reading\n",absName.data());    }  }  return f;}static FILE *findFile(const char *fileName,bool localInclude){  if (localInclude && g_yyFileDef)  {    QCString absName = g_yyFileDef->getPath()+"/"+fileName;    FILE *f = checkAndOpenFile(absName);    if (f)    {      setFileName(absName);      g_yyLineNr=1;      return f;    }  }  if (g_pathList==0)   {    return 0;  }  char *s=g_pathList->first();  while (s)  {    QCString absName = (QCString)s+"/"+fileName;    FILE *f = checkAndOpenFile(absName);    if (f)    {      setFileName(absName);      g_yyLineNr=1;      return f;    }    s=g_pathList->next();  }   return 0;}static int getNextChar(const QCString &expr,QCString *rest,uint &pos);static int getCurrentChar(const QCString &expr,QCString *rest,uint pos);static void unputChar(const QCString &expr,QCString *rest,uint &pos,char c);static void expandExpression(QCString &expr,QCString *rest,int pos);static QCString stringize(const QCString &s){  QCString result;  uint i=0;  bool inString=FALSE;  bool inChar=FALSE;  char c,pc;  while (i<s.length())  {    if (!inString && !inChar)    {      while (i<s.length() && !inString && !inChar)      {	c=s.at(i++);	if (c=='"')	{	  result+="\\\"";	  inString=TRUE;	}	else if (c=='\'')	{	  result+=c;	  inChar=TRUE;	}	else	{	  result+=c;	}      }    }    else if (inChar)    {      while (i<s.length() && inChar)      {	c=s.at(i++);	if (c=='\'')	{	  result+='\'';	  inChar=FALSE;	}	else if (c=='\\')	{	  result+="\\\\";	}	else	{	  result+=c;	}      }    }    else    {      pc=0;      while (i<s.length() && inString)      {	char c=s.at(i++);	if (c=='"') 	{	  result+="\\\"";	  inString= pc=='\\';	}	else if (c=='\\')	  result+="\\\\";	else	  result+=c;	pc=c;      }    }  }  //printf("stringize `%s'->`%s'\n",s.data(),result.data());  return result;}/*! Execute all ## operators in expr.  * If the macro name before or after the operator contains a no-rescan  * marker (@-) then this is removed (before the concatenated macro name * may be expanded again. */static void processConcatOperators(QCString &expr){  //printf("processConcatOperators: in=`%s'\n",expr.data());  QRegExp r("[ \\t\\n]*##[ \\t\\n]*");   int l,n,i=0;  if (expr.isEmpty()) return;  while ((n=r.match(expr,i,&l))!=-1)  {    //printf("Match: `%s'\n",expr.data()+i);    if (n+l+1<(int)expr.length() && expr.at(n+l)=='@' && expr.at(n+l+1)=='-')    {      // remove no-rescan marker after ID      l+=2;    }    //printf("found `%s'\n",expr.mid(n,l).data());    // remove the ## operator and the surrounding whitespace    expr=expr.left(n)+expr.right(expr.length()-n-l);    int k=n-1;    while (k>=0 && isId(expr.at(k))) k--;     if (k>0 && expr.at(k)=='-' && expr.at(k-1)=='@')    {      // remove no-rescan marker before ID      expr=expr.left(k-1)+expr.right(expr.length()-k-1);      n-=2;    }    i=n;  }  //printf("processConcatOperators: out=`%s'\n",expr.data());}/*! replaces the function macro \a def whose argument list starts at * \a pos in expression \a expr.  * Notice that this routine may scan beyond the \a expr string if needed. * In that case the characters will be read from the input file. * The replacement string will be returned in \a result and the  * length of the (unexpanded) argument list is stored in \a len. */ static bool replaceFunctionMacro(const QCString &expr,QCString *rest,int pos,int &len,const Define *def,QCString &result){  //printf("replaceFunctionMacro(expr=%s,rest=%s,pos=%d,def=%s) level=%d\n",expr.data(),rest ? rest->data() : 0,pos,def->name.data(),g_level);  uint j=pos;  len=0;  result.resize(0);  int cc;  while ((cc=getCurrentChar(expr,rest,j))!=EOF && cc==' ')   {     len++;     getNextChar(expr,rest,j);   }  if (cc!='(')   {     unputChar(expr,rest,j,' ');     return FALSE;   }  getNextChar(expr,rest,j); // eat the `(' character  QDict<QCString> argTable;  // list of arguments  argTable.setAutoDelete(TRUE);  QCString arg;  int argCount=0;  bool done=FALSE;    // PHASE 1: read the macro arguments  if (def->nargs==0)  {    while ((cc=getNextChar(expr,rest,j))!=EOF)    {      char c = (char)cc;      if (c==')') break;    }  }  else  {    while (!done && (argCount<def->nargs || def->varArgs) && 	((cc=getNextChar(expr,rest,j))!=EOF)	  )    {      char c=(char)cc;      if (c=='(') // argument is a function => search for matching )      {	int level=1;	arg+=c;	char term='\0';	while ((cc=getNextChar(expr,rest,j))!=EOF)	{	  char c=(char)cc;	  if (c=='\'' || c=='\"') // skip ('s and )'s inside strings	  {	    if (term!='\0') 	    { 	      if (c==term && expr.at(j-2)!='\\') term='\0'; 	    } 	    else 	    { 	      term=c; 	    }	  }	  if (term=='\0' && c==')')	  {	    level--;	    arg+=c;	    if (level==0) break;	  }	  else if (term=='\0' && c=='(')	  {	    level++;	    arg+=c;	  }	  else	    arg+=c;	}      }      else if (c==')' || c==',') // last or next argument found      {	if (c==',' && argCount==def->nargs-1 && def->varArgs)	{	  arg=arg.stripWhiteSpace();	  arg+=',';	}	else	{	  QCString argKey;	  argKey.sprintf("@%d",argCount++); // key name	  arg=arg.stripWhiteSpace();	  // add argument to the lookup table	  argTable.insert(argKey, new QCString(arg));	  arg.resize(0);	  if (c==')') // end of the argument list	  {	    done=TRUE;	  }	}      }       else if (c=='\"') // append literal strings      {	arg+=c; 	bool found=FALSE;	while (!found && (cc=getNextChar(expr,rest,j))!=EOF)	{	  found = cc=='"';	  if (cc=='\\')	  {	    c=(char)cc;	  	    arg+=c;	    if ((cc=getNextChar(expr,rest,j))==EOF) break;	  }	  c=(char)cc;	  	  arg+=c;	}      }      else if (c=='\'') // append literal characters      {	arg+=c;	bool found=FALSE;	while (!found && (cc=getNextChar(expr,rest,j))!=EOF)	{	  found = cc=='\'';	  if (cc=='\\')	  {	    c=(char)cc;	  	    arg+=c;	    if ((cc=getNextChar(expr,rest,j))==EOF) break;	  }	  c=(char)cc;	  arg+=c;	}      }	          else // append other characters      {	arg+=c;      }    }  }  // PHASE 2: apply the macro function  if (argCount==def->nargs ||       (argCount>def->nargs && def->varArgs)) // matching parameters lists  {    uint k=0;    // substitution of all formal arguments    QCString resExpr;    const QCString d=def->definition.stripWhiteSpace();    bool inString=FALSE;    while (k<d.length())    {      if (d.at(k)=='@') // maybe a marker, otherwise an escaped @      {	if (d.at(k+1)=='@') // escaped @ => copy it (is unescaped later)	{	  k+=2;	  resExpr+="@@"; // we unescape these later	}	else if (d.at(k+1)=='-') // no-rescan marker	{	  k+=2;	  resExpr+="@-";	}	else // argument marker => read the argument number	{	  QCString key="@";	  QCString *subst=0;	  bool hash=FALSE;	  int l=k-1;	  // search for ## backward	  if (l>=0 && d.at(l)=='"') l--;	  while (l>=0 && d.at(l)==' ') l--;	  if (l>0 && d.at(l)=='#' && d.at(l-1)=='#') hash=TRUE;	  k++;	  // scan the number

⌨️ 快捷键说明

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