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

📄 util.cpp

📁 doxygen(一个自动从源代码生成文档的工具)的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************** * * $Id: util.cpp,v 1.74 2001/03/19 19:27:42 root Exp $ * * 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. * */#include <stdlib.h>#include <ctype.h>#ifdef _WIN32#include <windows.h>#endif#include "qtbc.h"#include <qregexp.h>#include <qfileinfo.h>#include <qdir.h>#include "util.h"#include "message.h"#include "classdef.h"#include "filedef.h"#include "doxygen.h"#include "doc.h"#include "outputlist.h"#include "defargs.h"#include "language.h"#include "config.h"#include "htmlhelp.h"#include "example.h"#include "version.h"#include "groupdef.h"#include "reflist.h"#include "page.h"#ifndef _WIN32#include <unistd.h>#include <stdlib.h>#include <sys/types.h>#include <sys/wait.h>#include <errno.h>extern char **environ;#endif#if defined(_MSC_VER) || defined(__BORLANDC__)#define popen _popen#define pclose _pclose#endif//------------------------------------------------------------------------// TextGeneratorOLImpl implementation//------------------------------------------------------------------------TextGeneratorOLImpl::TextGeneratorOLImpl(OutputDocInterface &od) : m_od(od) {}void TextGeneratorOLImpl::writeString(const char *s) const{   m_od.docify(s); }void TextGeneratorOLImpl::writeBreak() const{   m_od.pushGeneratorState();  m_od.disableAllBut(OutputGenerator::Html);  m_od.lineBreak();  m_od.popGeneratorState();}void TextGeneratorOLImpl::writeLink(const char *extRef,const char *file,                                    const char *anchor,const char *text                                   ) const{  m_od.writeObjectLink(extRef,file,anchor,text);}//------------------------------------------------------------------------//------------------------------------------------------------------------    /*! Implements an interruptable system call on Unix/Windows */int iSystem(const char *command,const char *args,bool isBatchFile){#ifndef _WIN32  isBatchFile=isBatchFile;  /*! taken from the system() manpage on my Linux box */  int pid,status;  if (command==0) return 1;  pid = fork();  if (pid==-1) return -1;  if (pid==0)  {    char buf[4096];    strcpy(buf,command);    strcat(buf," ");    strcat(buf,args);    const char * argv[4];    argv[0] = "sh";    argv[1] = "-c";    argv[2] = buf;    argv[3] = 0;    execve("/bin/sh",(char * const *)argv,environ);    exit(127);  }  for (;;)  {    if (waitpid(pid,&status,0)==-1)    {      if (errno!=EINTR) return -1;    }    else    {      return status;    }  }#else  if (isBatchFile)  {    QCString fullCmd = command;    fullCmd += " ";    fullCmd += args;    return system(fullCmd);  }  else  {    SHELLEXECUTEINFO sInfo = {      sizeof(SHELLEXECUTEINFO),   /* structure size */      SEE_MASK_NOCLOSEPROCESS,    /* leave the process running */      NULL,                       /* window handle */      NULL,                       /* action to perform: open */      command,                    /* file to execute */      args,                       /* argument list */       NULL,                       /* use current working dir */      SW_HIDE,                    /* minimize on start-up */      0,                          /* application instance handle */      NULL,                       /* ignored: id list */      NULL,                       /* ignored: class name */      NULL,                       /* ignored: key class */      0,                          /* ignored: hot key */      NULL,                       /* ignored: icon */      NULL                        /* resulting application handle */    };    if (!ShellExecuteEx(&sInfo))    {      return -1;    }    else if (sInfo.hProcess)      /* executable was launched, wait for it to finish */    {      WaitForSingleObject(sInfo.hProcess,INFINITE);       CloseHandle(sInfo.hProcess);    }  }  return 0;  //return system(command);#endif}// an inheritance tree of depth of 100000 should be enough for everyone :-)const int maxInheritanceDepth = 100000; bool isId(char c){  return c=='_' || isalnum(c);}/*!   Removes all anoymous scopes from string s  Possible examples:\verbatim   "bla::@10::blep"      => "bla::blep"   "bla::@10::@11::blep" => "bla::blep"   "@10::blep"           => "blep"   " @10::blep"          => "blep"   "@9::@10::blep"       => "blep"   "bla::@1"             => "bla"   "bla::@1::@2"         => "bla"   "bla @1"              => "bla"\endverbatim */QCString removeAnonymousScopes(const QCString &s){  QCString result;  if (s.isEmpty()) return result;  static QRegExp re("[ :]*@[0-9]+[: ]*");  int i,l,sl=s.length();  int p=0;  while ((i=re.match(s,p,&l))!=-1)  {    result+=s.mid(p,i-p);    int c=i;    bool b1=FALSE,b2=FALSE;    while (c<i+l && s.at(c)!='@') if (s.at(c++)==':') b1=TRUE;    c=i+l-1;    while (c>=i && s.at(c)!='@') if (s.at(c--)==':') b2=TRUE;    if (b1 && b2)     {       result+="::";     }    p=i+l;  }  result+=s.right(sl-p);  //printf("removeAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());  return result;}// replace anonymous scopes with __anonymous__ QCString replaceAnonymousScopes(const QCString &s){  QCString result;  if (s.isEmpty()) return result;  static QRegExp re("@[0-9]+");  int i,l,sl=s.length();  int p=0;  while ((i=re.match(s,p,&l))!=-1)  {    result+=s.mid(p,i-p);    result+="__anonymous__";    p=i+l;  }  result+=s.right(sl-p);  //printf("replaceAnonymousScopes(`%s')=`%s'\n",s.data(),result.data());  return result;}// strip annonymous left hand side part of the scopeQCString stripAnonymousNamespaceScope(const QCString &s){#if 0  int oi=0,i=0,p=0;  p=s.find('@');  if (p==-1) return s;  while (s.at(p)=='@' && (i=s.find("::@",p))!=-1 &&          Doxygen::namespaceDict[s.left(i)]!=0) { oi=i; p=i+2; }  if (oi==0)   {    //printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),s.data());    return s;  }  else   {    //printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),s.right(s.length()-oi-2).data());    return s.right(s.length()-oi-2);  }#endif  int i,p=0,l;  QCString newScope;  while ((i=getScopeFragment(s,p,&l))!=-1)  {    //printf("Scope fragment %s\n",s.mid(i,l).data());    if (Doxygen::namespaceSDict[s.left(i+l)]!=0)    {      if (s.at(i)!='@')      {        if (!newScope.isEmpty()) newScope+="::";        newScope+=s.mid(i,l);      }    }    else    {      if (!newScope.isEmpty()) newScope+="::";      newScope+=s.right(s.length()-i);      goto done;    }    p=i+l;  }done:  //printf("stripAnonymousNamespaceScope(`%s')=`%s'\n",s.data(),newScope.data());  return newScope;}void writePageRef(OutputDocInterface &od,const char *cn,const char *mn){  od.pushGeneratorState();    od.disable(OutputGenerator::Html);  od.disable(OutputGenerator::Man);  if (Config_getBool("PDF_HYPERLINKS")) od.disable(OutputGenerator::Latex);  if (Config_getBool("RTF_HYPERLINKS")) od.disable(OutputGenerator::RTF);  od.startPageRef();  od.docify(theTranslator->trPageAbbreviation());  od.endPageRef(cn,mn);  od.popGeneratorState();}/*! Generate a place holder for a position in a list. Used for *  translators to be able to specify different elements orders *  depending on whether text flows from left to right or visa versa. */QCString generateMarker(int id){  QCString result;  result.sprintf("@%d\n",id);  return result;}/*! strip part of \a path if it matches *  one of the paths in the Config_getList("STRIP_FROM_PATH") list */QCString stripFromPath(const QCString &path){  const char *s=Config_getList("STRIP_FROM_PATH").first();  while (s)  {    QCString prefix = s;    if (path.left(prefix.length())==prefix)    {      return path.right(path.length()-prefix.length());    }    s = Config_getList("STRIP_FROM_PATH").next();  }  return path;}/*! try to determine if \a name is a source or a header file name by looking * at the extension. A number of variations is allowed in both upper and  * lower case) If anyone knows or uses another extension please let me know :-) */int guessSection(const char *name){  QCString n=((QCString)name).lower();  if (n.right(2)==".c"    || // source      n.right(3)==".cc"   ||      n.right(4)==".cxx"  ||      n.right(4)==".cpp"  ||      n.right(4)==".c++"  ||      n.right(5)==".java" ||      n.right(3)==".ii"   || // inline      n.right(4)==".ixx"  ||      n.right(4)==".ipp"  ||      n.right(4)==".i++"  ||      n.right(4)==".inl"     ) return Entry::SOURCE_SEC;  if (n.right(2)==".h"   || // header      n.right(3)==".hh"  ||      n.right(4)==".hxx" ||      n.right(4)==".hpp" ||      n.right(4)==".h++" ||      n.right(4)==".idl"     ) return Entry::HEADER_SEC;  return 0;}QCString resolveTypeDef(Definition *d,const QCString &name){  //printf("resolveTypeDef(%s,%s)\n",d ? d->name().data() : "<none>",name.data());  QCString result;  if (name.isEmpty()) return result;  Definition *mContext=d;  MemberDef *md=0;  while (mContext && md==0)  {    MemberNameSDict *mnd=0;    if (mContext->definitionType()==Definition::TypeClass)    {      mnd=&Doxygen::memberNameSDict;    }    else    {      mnd=&Doxygen::functionNameSDict;    }    MemberName *mn=mnd->find(name);    if (mn)    {      MemberNameIterator mni(*mn);      MemberDef *tmd=0;      for (;(tmd=mni.current());++mni)      {        //printf("Found member %s scope=%p mContext=%p\n",tmd->name().data(),        //    tmd->getOuterScope(),mContext);        if (tmd->isTypedef() && tmd->getOuterScope()==mContext)        {          md=tmd;        }      }    }    mContext=mContext->getOuterScope();  }  if (md)  {    //printf("Found typedef name `%s' in scope `%s' value=`%s'\n",    //    name.data(),d->name().data(),md->typeString()    //    );    result=md->typeString();  }  else  {    //printf("Typedef `%s' not found in scope `%s'!\n",    //    name.data(),d ? d->name().data() : "<global>");  }  return result;  }/*! Get a class definition given its name.  *  Returns 0 if the class is not found. */ClassDef *getClass(const char *name){  if (name==0 || name[0]=='\0') return 0;  return Doxygen::classSDict.find(name);}NamespaceDef *getResolvedNamespace(const char *name){  if (name==0 || name[0]=='\0') return 0;  QCString *subst = Doxygen::namespaceAliasDict[name];  if (subst)  {    int count=0; // recursion detection guard    QCString *newSubst;    while ((newSubst=Doxygen::namespaceAliasDict[*subst]) && count<10)    {      subst=newSubst;      count++;    }    if (count==10)    {      warn_cont("Warning: possible recursive namespace alias detected for %s!\n",name);    }    return Doxygen::namespaceSDict[subst->data()];  }  else  {

⌨️ 快捷键说明

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