예제 #1
0
static QCString getListOfBibFiles(const QCString &sep,bool stripExtension)
{
  QCString result;
  QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
  const char *bibdata = citeDataList.first();
  while (bibdata)
  {
    int i;
    QCString bibFile = bibdata;
    if (stripExtension && bibFile.right(4)==".bib")
    {
      bibFile = bibFile.left(bibFile.length()-4);
    }
    if (stripExtension && (i=bibFile.findRev('/'))!=-1)
    {
      bibFile = bibFile.mid(i+1);
    }
    if (!bibFile.isEmpty())
    {
      result+=bibFile;
      bibdata = citeDataList.next();
      if (bibdata)
      {
        result+=sep;
      }
    }
    else
    {
      bibdata = citeDataList.next();
    }
  }
  return result;
}
예제 #2
0
void CiteDict::writeLatexBibliography(FTextStream &t)
{
  if (m_entries.count()==0) return;
  QCString style = Config_getString("LATEX_BIB_STYLE");
  if (style.isEmpty()) style="plain";
  t << "\\newpage \\bibliographystyle{" << style << "}" << endl;
  t << "\\bibliography{";
  QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
  const char *bibdata = citeDataList.first();
  while (bibdata)
  {
    QCString bibFile = bibdata;
    if (!bibFile.isEmpty())
    {
      t << bibFile;
      bibdata = citeDataList.next();
      if (bibdata)
      {
        t << ",";
      }
    }
    else
    {
      bibdata = citeDataList.next();
    }
  }
  t << "}" << endl;
}
예제 #3
0
void CiteDict::clean()
{
  // clean
  QDir thisDir;
  QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
  const char *bibdata = citeDataList.first();
  while (bibdata)
  {
    QCString bibFile = bibdata;
    if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
    if (!bibFile.isEmpty()) thisDir.remove(m_baseFileName+"_"+bibFile);
    bibdata = citeDataList.next();
  }

  thisDir.remove(m_baseFileName + ".aux");
  thisDir.remove(m_baseFileName + ".bbl");
  thisDir.remove(m_baseFileName + ".blg");
  thisDir.remove(m_baseFileName + ".tmp");
  thisDir.remove(m_baseFileName + ".bst");

  QCString &outputDirectory = Config_getString("OUTPUT_DIRECTORY");
  if (outputDirectory.isEmpty()) 
  {
    outputDirectory=QDir::currentDirPath();
  }
  QDir d(outputDirectory);
  d.rmdir("bib");
}
예제 #4
0
//----------------------------------------------------------------------------
// some quasi intelligent brief description abbreviator :^)
QCString abbreviate(const char *s,const char *name)
{
  QCString scopelessName=name;
  int i=scopelessName.findRev("::");
  if (i!=-1) scopelessName=scopelessName.mid(i+2);
  QCString result=s;
  result=result.stripWhiteSpace();
  // strip trailing .
  if (!result.isEmpty() && result.at(result.length()-1)=='.') 
    result=result.left(result.length()-1);

  // strip any predefined prefix
  QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
  const char *p = briefDescAbbrev.first();
  while (p)
  {
    QCString s = p;
    s.replace(QRegExp("\\$name"), scopelessName);  // replace $name with entity name
    s += " ";
    stripWord(result,s);
    p = briefDescAbbrev.next();
  }

  // capitalize first word
  if (!result.isEmpty())
  {
    int c=result[0];
    if (c>='a' && c<='z') c+='A'-'a';
    result[0]=c;
  }
  return result;
}
예제 #5
0
bool CiteDict::writeAux()
{
  //msg("..writing aux file\n");
  QCString auxFileName(m_baseFileName + ".aux");
  QFile auxFile(auxFileName);
  if (!auxFile.open(IO_WriteOnly)) 
    // point it to something valid, because warn() relies on it
  {
    err("Error opening file %s for output\n", auxFileName.data()); 
    return FALSE;
  }
  FTextStream t(&auxFile);

  QDictIterator<CiteInfo> cdi(m_entries);
  for (CiteInfo *ci = 0; (ci=cdi.current()); ++cdi)
  {
    t << "\\citation{" << ci->label << "}\n";
  }

  t << "\\bibstyle{" << m_baseFileName << "}\n";

  t << "\\bibdata{";
  QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
  const char *bibdata = citeDataList.first();
  while (bibdata)
  {
    QCString bibFile = bibdata;
    if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
    if (!bibFile.isEmpty())
    {
      QFileInfo fi(bibFile);
      if (fi.exists())
      {
        if (!copyFile(bibFile,m_baseFileName+"_"+bibFile))
        {
          return FALSE;
        }
        t << m_baseFileName+"_"+bibFile;
        bibdata = citeDataList.next();
        if (bibdata)
        {
          t << ",";
        }
      }
      else
      {
        err("The file %s specified at CITE_BIB_FILES could not be read!\n",bibdata);
        return FALSE;
      }
    }
    else
    {
      bibdata = citeDataList.next();
    }
  }
  t << "}\n";
  return TRUE;
}
예제 #6
0
static bool matchExcludedSymbols(const char *name)
{
  static QStrList &exclSyms = Config_getList("EXCLUDE_SYMBOLS");
  if (exclSyms.count()==0) return FALSE; // nothing specified
  const char *pat = exclSyms.first();
  QCString symName = name;
  while (pat)
  {
    QCString pattern = pat;
    bool forceStart=FALSE;
    bool forceEnd=FALSE;
    if (pattern.at(0)=='^') 
      pattern=pattern.mid(1),forceStart=TRUE;
    if (pattern.at(pattern.length()-1)=='$') 
      pattern=pattern.left(pattern.length()-1),forceEnd=TRUE;
    if (pattern.find('*')!=-1) // wildcard mode
    {
      QRegExp re(substitute(pattern,"*",".*"),TRUE);
      int i,pl;
      i = re.match(symName,0,&pl);
      //printf("  %d = re.match(%s) pattern=%s\n",i,symName.data(),pattern.data());
      if (i!=-1) // wildcard match
      {
        int sl=symName.length();
        // check if it is a whole word match
        if ((i==0     || pattern.at(0)=='*'    || (!isId(symName.at(i-1))  && !forceStart)) &&
            (i+pl==sl || pattern.at(i+pl)=='*' || (!isId(symName.at(i+pl)) && !forceEnd))
           )
        {
          //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
          return TRUE;
        }
      }
    }
    else if (!pattern.isEmpty()) // match words
    {
      int i = symName.find(pattern);
      if (i!=-1) // we have a match!
      {
        int pl=pattern.length();
        int sl=symName.length();
        // check if it is a whole word match
        if ((i==0     || (!isId(symName.at(i-1))  && !forceStart)) &&
            (i+pl==sl || (!isId(symName.at(i+pl)) && !forceEnd))
           )
        {
          //printf("--> name=%s pattern=%s match at %d\n",symName.data(),pattern.data(),i);
          return TRUE; 
        }
      }
    }
    pat = exclSyms.next();
  }
  //printf("--> name=%s: no match\n",name);
  return FALSE;
}
예제 #7
0
void CiteDict::resolve()
{
  QStrList &citeBibFiles = Config_getList("CITE_BIB_FILES");
  if (citeBibFiles.count()==0 || m_entries.count()==0) return; // nothing to cite

  QCString &outputDirectory = Config_getString("OUTPUT_DIRECTORY");
  if (outputDirectory.isEmpty()) 
  {
    outputDirectory=QDir::currentDirPath();
  }
  QDir d(outputDirectory);
  d.mkdir("bib");

  uint pid = portable_pid();
  m_baseFileName.sprintf("doxygen_bibtex_%d",pid);
  m_baseFileName.prepend(outputDirectory+"/bib/");

  if (writeAux() && writeBst() && execute()) 
  {
    parse();
    clean();
  }

  if (Config_getBool("GENERATE_LATEX"))
  {
    // copy bib files to the latex output dir
    QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
    QCString latexOutputDir = Config_getString("LATEX_OUTPUT")+"/";
    const char *bibdata = citeDataList.first();
    while (bibdata)
    {
      QCString bibFile = bibdata;
      if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
      if (!bibFile.isEmpty())
      {
        copyFile(bibFile,latexOutputDir+bibFile);
      }
      bibdata = citeDataList.next();
    }
  }
}
예제 #8
0
파일: dirdef.cpp 프로젝트: bithium/doxygen
/*! strip part of \a path if it matches
 *  one of the paths in the Config_getList(STRIP_FROM_PATH) list
 */
DirDef *DirDef::mergeDirectoryInTree(const QCString &path)
{
  //printf("DirDef::mergeDirectoryInTree(%s)\n",path.data());
  int p=0,i=0;
  DirDef *dir=0;
  while ((i=path.find('/',p))!=-1)
  {
    QCString part=path.left(i+1);
    if (!matchPath(part,Config_getList(STRIP_FROM_PATH)) && (part!="/" && part!="//"))
    {
      dir=createNewDir(part); 
    }
    p=i+1;
  }
  return dir;
}
예제 #9
0
파일: cite.cpp 프로젝트: CN-Sean/doxygen
static QCString getListOfBibFiles(const QCString &sep,bool namesOnly)
{
  QCString result;
  QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
  const char *bibdata = citeDataList.first();
  while (bibdata)
  {
    int i;
    QCString bibFile = bibdata;
    if (namesOnly && bibFile.right(4)==".bib") // strip extension
    {
      bibFile = bibFile.left(bibFile.length()-4);
    }
    else
    {
      if (!namesOnly && bibFile.right(4)!=".bib") bibFile += ".bib";
    }
    if ((i=bibFile.findRev('/'))!=-1) // strip path
    {
      bibFile = bibFile.mid(i+1);
    }
    if (!bibFile.isEmpty())
    {
      if (namesOnly) // bare names
      {
        result+=bibFile;
      }
      else // add quotes for paths with spaces
      {
        result+="\""+bibFile+"\""; 
      }
      bibdata = citeDataList.next();
      if (bibdata)
      {
        result+=sep;
      }
    }
    else
    {
      bibdata = citeDataList.next();
    }
  }
  return result;
}
QCString VerilogDocGen::findFile(const char *fileName)
{
  QStrList &includePath = Config_getList("INCLUDE_PATH");

  char *s=includePath.first();

  while (s)
  {
     QCString absName;
     absName += (QCString)s+"/"+fileName;
     QFileInfo fin(absName);
    
     if( fin.exists() && fin.isFile())
      return absName;
    
     s=includePath.next();
  } 
  return "";
}
예제 #11
0
/*! constructs command line of htags(1) and executes it.
 *  \retval TRUE success
 *  \retval FALSE an error has occurred.
 */
bool Htags::execute(const QCString &htmldir)
{
  static QStrList &inputSource = Config_getList("INPUT");
  static bool quiet = Config_getBool("QUIET");
  static bool warnings = Config_getBool("WARNINGS");
  static QCString htagsOptions = ""; //Config_getString("HTAGS_OPTIONS");
  static QCString projectName = Config_getString("PROJECT_NAME");
  static QCString projectNumber = Config_getString("PROJECT_NUMBER");

  QCString cwd = QDir::currentDirPath().utf8();
  if (inputSource.isEmpty())
  {
    g_inputDir.setPath(cwd);
  }
  else if (inputSource.count()==1)
  {
    g_inputDir.setPath(inputSource.first());
    if (!g_inputDir.exists())
      err("Cannot find directory %s. "
          "Check the value of the INPUT tag in the configuration file.\n",
          inputSource.first()
         );
  }
  else
  {
    err("If you use USE_HTAGS then INPUT should specific a single directory. \n");
    return FALSE;
  }

  /*
   * Construct command line for htags(1).
   */
  QCString commandLine = " -g -s -a -n ";
  if (!quiet)   commandLine += "-v ";
  if (warnings) commandLine += "-w ";
  if (!htagsOptions.isEmpty()) 
  {
    commandLine += ' ';
    commandLine += htagsOptions;
  }
  if (!projectName.isEmpty()) 
  {
    commandLine += "-t \"";
    commandLine += projectName;
    if (!projectNumber.isEmpty()) 
    {
      commandLine += '-';
      commandLine += projectNumber;
    }
    commandLine += "\" ";
  }
  commandLine += " \"" + htmldir + "\"";
  QCString oldDir = QDir::currentDirPath().utf8();
  QDir::setCurrent(g_inputDir.absPath());
  //printf("CommandLine=[%s]\n",commandLine.data());
  portable_sysTimerStart();
  bool result=portable_system("htags",commandLine,FALSE)==0;
  portable_sysTimerStop();
  QDir::setCurrent(oldDir);
  return result;
}
예제 #12
0
void generatePlantUMLOutput(const char *baseName,const char *outDir,PlantUMLOutputFormat format)
{
  static QCString plantumlJarPath = Config_getString("PLANTUML_JAR_PATH");

  QCString pumlExe = "java";
  QCString pumlArgs = "";

  QStrList &pumlIncludePathList = Config_getList("PLANTUML_INCLUDE_PATH");
  char *s=pumlIncludePathList.first();
  if (s)
  {
    pumlArgs += "-Dplantuml.include.path=\"";
    pumlArgs += s;
    s = pumlIncludePathList.next(); 
  }
  while (s)
  {
    pumlArgs += portable_pathListSeparator();
    pumlArgs += s;
    s = pumlIncludePathList.next(); 
  }
  if (pumlIncludePathList.first()) pumlArgs += "\" ";
  pumlArgs += "-Djava.awt.headless=true -jar \""+plantumlJarPath+"plantuml.jar\" ";
  pumlArgs+="-o \"";
  pumlArgs+=outDir;
  pumlArgs+="\" ";
  QCString extension;
  switch (format)
  {
    case PUML_BITMAP:
      pumlArgs+="-tpng";
      extension=".png";
      break;
    case PUML_EPS:
      pumlArgs+="-teps";
      extension=".eps";
      break;
    case PUML_SVG:
      pumlArgs+="-tsvg";
      extension=".svg";
      break;
  }
  pumlArgs+=" \"";
  pumlArgs+=baseName;
  pumlArgs+=".pu\" ";
  pumlArgs+="-charset " + Config_getString("INPUT_ENCODING") + " ";
  int exitCode;
  //printf("*** running: %s %s outDir:%s %s\n",pumlExe.data(),pumlArgs.data(),outDir,outFile);
  msg("Running PlantUML on generated file %s.pu\n",baseName);
  portable_sysTimerStart();
  if ((exitCode=portable_system(pumlExe,pumlArgs,FALSE))!=0)
  {
    err("Problems running PlantUML. Verify that the command 'java -jar \"%splantuml.jar\" -h' works from the command line. Exit code: %d\n",
        plantumlJarPath.data(),exitCode);
  }
  else if (Config_getBool("DOT_CLEANUP"))
  {
    QFile(QCString(baseName)+".pu").remove();
  }
  portable_sysTimerStop();
  if ( (format==PUML_EPS) && (Config_getBool("USE_PDFLATEX")) )
  {
    QCString epstopdfArgs(maxCmdLine);
    epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",baseName,baseName);
    portable_sysTimerStart();
    if (exitCode=portable_system("epstopdf",epstopdfArgs)!=0)
    {
      err("Problems running epstopdf. Check your TeX installation! Exit code: %d\n",exitCode);
    }
    portable_sysTimerStop();
  }
}
예제 #13
0
파일: cite.cpp 프로젝트: CN-Sean/doxygen
void CiteDict::generatePage() const
{
  //printf("** CiteDict::generatePage() count=%d\n",m_ordering.count());

  // do not generate an empty citations page
  if (isEmpty()) return; // nothing to cite

  // 1. generate file with markers and citations to OUTPUT_DIRECTORY
  QFile f;
  QCString outputDir = Config_getString("OUTPUT_DIRECTORY");
  QCString citeListFile = outputDir+"/citelist.doc";
  f.setName(citeListFile);
  if (!f.open(IO_WriteOnly)) 
  {
    err("could not open file %s for writing\n",citeListFile.data());
  }
  FTextStream t(&f);
  t << "<!-- BEGIN CITATIONS -->" << endl;
  t << "<!--" << endl;
  QDictIterator<CiteInfo> it(m_entries);
  CiteInfo *ci;
  for (it.toFirst();(ci=it.current());++it)
  {
    t << "\\citation{" << ci->label << "}" << endl;
  }
  t << "-->" << endl;
  t << "<!-- END CITATIONS -->" << endl;
  t << "<!-- BEGIN BIBLIOGRAPHY -->" << endl;
  t << "<!-- END BIBLIOGRAPHY -->" << endl;
  f.close();

  // 2. generate bib2xhtml
  QCString bib2xhtmlFile = outputDir+"/bib2xhtml.pl";
  f.setName(bib2xhtmlFile);
  QCString bib2xhtml = bib2xhtml_pl;
  if (!f.open(IO_WriteOnly)) 
  {
    err("could not open file %s for writing\n",bib2xhtmlFile.data());
  }
  f.writeBlock(bib2xhtml, bib2xhtml.length());
  f.close();

  // 3. generate doxygen.bst
  QCString doxygenBstFile = outputDir+"/doxygen.bst";
  QCString bstData = doxygen_bst;
  f.setName(doxygenBstFile);
  if (!f.open(IO_WriteOnly)) 
  {
    err("could not open file %s for writing\n",doxygenBstFile.data());
  }
  f.writeBlock(bstData, bstData.length());
  f.close();

  // 4. for html we just copy the bib files to the output so that
  //    bibtex can find them without path (bibtex doesn't support path's
  //    with spaces!)
  QList<QCString> tempFiles;
  tempFiles.setAutoDelete(TRUE);
  QDir thisDir;
  if (Config_getBool("GENERATE_HTML"))
  {
    // copy bib files to the latex output dir
    QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
    QCString bibOutputDir = outputDir+"/";
    QFileInfo fo(bibOutputDir);
    const char *bibdata = citeDataList.first();
    while (bibdata)
    {
      QCString bibFile = bibdata;
      if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
      QFileInfo fi(bibFile);
      if (fi.exists() && fi.dirPath(TRUE)!=fo.absFilePath())
      {
        if (!bibFile.isEmpty())
        {
          QCString destFile=bibOutputDir+fi.fileName().data();
          copyFile(bibFile,destFile);
          tempFiles.append(new QCString(destFile));
        }
      }
      else if (!fi.exists())
      {
        err("bib file %s not found!\n",bibFile.data());
      }
      bibdata = citeDataList.next();
    }
  }

  QCString oldDir = QDir::currentDirPath().utf8();
  QDir::setCurrent(outputDir);

  // 5. run bib2xhtml perl script on the generated file which will insert the
  //    bibliography in citelist.doc
  portable_system("perl","\""+bib2xhtmlFile+"\" "+getListOfBibFiles(" ",FALSE)+" \""+
                         citeListFile+"\"");

  QDir::setCurrent(oldDir);

  // 6. read back the file
  f.setName(citeListFile);
  if (!f.open(IO_ReadOnly)) 
  {
    err("could not open file %s/citelist.doc for reading\n",outputDir.data());
  }
  bool insideBib=FALSE;
  
  QCString doc;
  QFileInfo fi(citeListFile);
  QCString input(fi.size()+1);
  f.readBlock(input.data(),fi.size());
  f.close();
  input.at(fi.size())='\0';
  int p=0,s;
  //printf("input=[%s]\n",input.data());
  while ((s=input.find('\n',p))!=-1)
  {
    QCString line = input.mid(p,s-p);
    //printf("p=%d s=%d line=[%s]\n",p,s,line.data());
    p=s+1;

    if      (line.find("<!-- BEGIN BIBLIOGRAPHY")!=-1) insideBib=TRUE;
    else if (line.find("<!-- END BIBLIOGRAPH")!=-1)    insideBib=FALSE;
    else if (insideBib) doc+=line+"\n";
    int i;
    // determine text to use at the location of the @cite command
    if (insideBib && (i=line.find("<a name=\"CITEREF_"))!=-1)
    {
      int j=line.find("\">[");
      int k=line.find("]</a>");
      if (j!=-1 && k!=-1)
      {
        QCString label = line.mid(i+17,j-i-17);
        QCString number = line.mid(j+2,k-j-1);
        CiteInfo *ci = m_entries.find(label);
        //printf("label='%s' number='%s' => %p\n",label.data(),number.data(),ci);
        if (ci)
        {
          ci->text = number;
        }
      }
    }
  }
  //printf("doc=[%s]\n",doc.data());

  // 7. add it as a page
  addRelatedPage(CiteConsts::fileName,
       theTranslator->trCiteReferences(),doc,0,CiteConsts::fileName,1,0,0,0);

  // 8. for latex we just copy the bib files to the output and let 
  //    latex do this work.
  if (Config_getBool("GENERATE_LATEX"))
  {
    // copy bib files to the latex output dir
    QStrList &citeDataList = Config_getList("CITE_BIB_FILES");
    QCString latexOutputDir = Config_getString("LATEX_OUTPUT")+"/";
    const char *bibdata = citeDataList.first();
    while (bibdata)
    {
      QCString bibFile = bibdata;
      if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
      QFileInfo fi(bibFile);
      if (fi.exists())
      {
        if (!bibFile.isEmpty())
        {
          copyFile(bibFile,latexOutputDir+fi.fileName().data());
        }
      }
      else
      {
        err("bib file %s not found!\n",bibFile.data());
      }
      bibdata = citeDataList.next();
    }
  }

  // 9. Remove temporary files
  thisDir.remove(citeListFile);
  thisDir.remove(doxygenBstFile);
  thisDir.remove(bib2xhtmlFile);
  while (!tempFiles.isEmpty()) 
  {
    QCString *s=tempFiles.take(0);
    thisDir.remove(*s);
  }
}
예제 #14
0
파일: cite.cpp 프로젝트: CN-Sean/doxygen
bool CiteDict::isEmpty() const
{
  QStrList &citeBibFiles = Config_getList("CITE_BIB_FILES");
  return (citeBibFiles.count()==0 || m_entries.isEmpty());
}
예제 #15
0
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
{
  static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
  static QStrList &includePath = Config_getList(INCLUDE_PATH);
  static QStrList clangOptions = Config_getList(CLANG_OPTIONS);
  static QCString clangCompileDatabase = Config_getList(CLANG_COMPILATION_DATABASE_PATH);
  if (!clangAssistedParsing) return;
  //printf("ClangParser::start(%s)\n",fileName);
  p->fileName = fileName;
  p->index    = clang_createIndex(0, 0);
  p->curLine  = 1;
  p->curToken = 0;
  QDictIterator<void> di(Doxygen::inputPaths);
  int argc=0;
  std::string error;
  // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
  // this only needs to be loaded once, and could be refactored to a higher level function
  static std::unique_ptr<clang::tooling::CompilationDatabase> db =
      clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error);
  int clang_option_len = 0;
  std::vector<clang::tooling::CompileCommand> command;
  if (strcmp(clangCompileDatabase, "0") != 0) {
      if (db == nullptr) {
          // user specified a path, but DB file was not found
          err("%s using clang compilation database path of: \"%s\"\n", error.c_str(),
              clangCompileDatabase.data());
      } else {
          // check if the file we are parsing is in the DB
          command = db->getCompileCommands(fileName);
          if (!command.empty() ) {
              // it's possible to have multiple entries for the same file, so use the last entry
              clang_option_len = command[command.size()-1].CommandLine.size();
          }
      }
  }
  char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()+clang_option_len));
  if (!command.empty() ) {
      std::vector<std::string> options = command[command.size()-1].CommandLine;
      // copy each compiler option used from the database. Skip the first which is compiler exe.
      for (auto option = options.begin()+1; option != options.end(); option++) {
          argv[argc++] = strdup(option->c_str());
      }
      // this extra addition to argv is accounted for as we are skipping the first entry in
      argv[argc++]=strdup("-w"); // finally, turn off warnings.
  } else {
  // add include paths for input files
  for (di.toFirst();di.current();++di,++argc)
  {
    QCString inc = QCString("-I")+di.currentKey();
    argv[argc]=strdup(inc.data());
    //printf("argv[%d]=%s\n",argc,argv[argc]);
  }
  // add external include paths
  for (uint i=0;i<includePath.count();i++)
  {
    QCString inc = QCString("-I")+includePath.at(i);
    argv[argc++]=strdup(inc.data());
  }
  // user specified options
  for (uint i=0;i<clangOptions.count();i++)
  {
    argv[argc++]=strdup(clangOptions.at(i));
  }
  // extra options
  argv[argc++]=strdup("-ferror-limit=0");
  argv[argc++]=strdup("-x");

  // Since we can be presented with a .h file that can contain C/C++ or
  // Objective C code and we need to configure the parser before knowing this,
  // we use the source file to detected the language. Detection will fail if you
  // pass a bunch of .h files containing ObjC code, and no sources :-(
  SrcLangExt lang = getLanguageFromFileName(fileName);
  if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
  {
    QCString fn = fileName;
    if (p->detectedLang==ClangParser::Private::Detected_Cpp && 
        (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
         fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
    { // fall back to C/C++ once we see an extension that indicates this
      p->detectedLang = ClangParser::Private::Detected_Cpp;
    }
    else if (fn.right(3).lower()==".mm") // switch to Objective C++
    {
      p->detectedLang = ClangParser::Private::Detected_ObjCpp;
    }
    else if (fn.right(2).lower()==".m") // switch to Objective C
    {
      p->detectedLang = ClangParser::Private::Detected_ObjC;
    }
  }
  switch(p->detectedLang)
  {
    case ClangParser::Private::Detected_Cpp: 
      argv[argc++]=strdup("c++"); 
      break;
    case ClangParser::Private::Detected_ObjC: 
      argv[argc++]=strdup("objective-c"); 
      break;
    case ClangParser::Private::Detected_ObjCpp: 
      argv[argc++]=strdup("objective-c++"); 
      break;
  }

  // provide the input and and its dependencies as unsaved files so we can
  // pass the filtered versions
  argv[argc++]=strdup(fileName);
  }
  static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
  //printf("source %s ----------\n%s\n-------------\n\n",
  //    fileName,p->source.data());
  uint numUnsavedFiles = filesInTranslationUnit.count()+1;
  p->numFiles = numUnsavedFiles;
  p->sources = new QCString[numUnsavedFiles];
  p->ufs     = new CXUnsavedFile[numUnsavedFiles];
  p->sources[0]      = detab(fileToString(fileName,filterSourceFiles,TRUE));
  p->ufs[0].Filename = strdup(fileName);
  p->ufs[0].Contents = p->sources[0].data();
  p->ufs[0].Length   = p->sources[0].length();
  QStrListIterator it(filesInTranslationUnit);
  uint i=1;
  for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
  {
    p->fileMapping.insert(it.current(),new uint(i));
    p->sources[i]      = detab(fileToString(it.current(),filterSourceFiles,TRUE));
    p->ufs[i].Filename = strdup(it.current());
    p->ufs[i].Contents = p->sources[i].data();
    p->ufs[i].Length   = p->sources[i].length();
  }

  // let libclang do the actual parsing
  p->tu = clang_parseTranslationUnit(p->index, 0,
                                     argv, argc, p->ufs, numUnsavedFiles, 
                                     CXTranslationUnit_DetailedPreprocessingRecord);
  // free arguments
  for (int i=0;i<argc;++i)
  {
    free(argv[i]);
  }
  free(argv);

  if (p->tu)
  {
    // filter out any includes not found by the clang parser
    determineInputFilesInSameTu(filesInTranslationUnit);

    // show any warnings that the compiler produced
    for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) 
    {
      CXDiagnostic diag = clang_getDiagnostic(p->tu, i); 
      CXString string = clang_formatDiagnostic(diag,
          clang_defaultDiagnosticDisplayOptions()); 
      err("%s [clang]\n",clang_getCString(string));
      clang_disposeString(string);
      clang_disposeDiagnostic(diag);
    }

    // create a source range for the given file
    QFileInfo fi(fileName);
    CXFile f = clang_getFile(p->tu, fileName);
    CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
    CXSourceLocation fileEnd   = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
    CXSourceRange    fileRange = clang_getRange(fileBegin, fileEnd);

    // produce a token stream for the file
    clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);

    // produce cursors for each token in the stream
    p->cursors=new CXCursor[p->numTokens];
    clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
  }
  else
  {
    p->tokens    = 0;
    p->numTokens = 0;
    p->cursors   = 0;
    err("clang: Failed to parse translation unit %s\n",fileName);
  }
}
예제 #16
0
/**
 * evaluate a variable
 */
bool CondParser::evalVariable(const char *varName)
{
  if (Config_getList("ENABLED_SECTIONS").find(varName)==-1) return FALSE;
  return TRUE;
}
예제 #17
0
void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
{
  static bool clangAssistedParsing = Config_getBool("CLANG_ASSISTED_PARSING");
  static QStrList &includePath = Config_getList("INCLUDE_PATH");
  static QStrList clangOptions = Config_getList("CLANG_OPTIONS");
  if (!clangAssistedParsing) return;
  //printf("ClangParser::start(%s)\n",fileName);
  p->fileName = fileName;
  p->index    = clang_createIndex(0, 0);
  p->curLine  = 1;
  p->curToken = 0;
  char **argv = (char**)malloc(sizeof(char*)*(4+Doxygen::inputPaths.count()+includePath.count()+clangOptions.count()));
  QDictIterator<void> di(Doxygen::inputPaths);
  int argc=0;
  // add include paths for input files
  for (di.toFirst();di.current();++di,++argc)
  {
    QCString inc = QCString("-I")+di.currentKey();
    argv[argc]=strdup(inc.data());
    //printf("argv[%d]=%s\n",argc,argv[argc]);
  }
  // add external include paths
  for (uint i=0;i<includePath.count();i++)
  {
    QCString inc = QCString("-I")+includePath.at(i);
    argv[argc++]=strdup(inc.data());
  }
  // user specified options
  for (uint i=0;i<clangOptions.count();i++)
  {
    argv[argc++]=strdup(clangOptions.at(i));
  }
  // extra options
  argv[argc++]=strdup("-ferror-limit=0");
  argv[argc++]=strdup("-x");

  // Since we can be presented with a .h file that can contain C/C++ or
  // Objective C code and we need to configure the parser before knowing this,
  // we use the source file to detected the language. Detection will fail if you
  // pass a bunch of .h files containing ObjC code, and no sources :-(
  SrcLangExt lang = getLanguageFromFileName(fileName);
  if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
  {
    QCString fn = fileName;
    if (p->detectedLang==ClangParser::Private::Detected_Cpp && 
        (fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
         fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
    { // fall back to C/C++ once we see an extension that indicates this
      p->detectedLang = ClangParser::Private::Detected_Cpp;
    }
    else if (fn.right(3).lower()==".mm") // switch to Objective C++
    {
      p->detectedLang = ClangParser::Private::Detected_ObjCpp;
    }
    else if (fn.right(2).lower()==".m") // switch to Objective C
    {
      p->detectedLang = ClangParser::Private::Detected_ObjC;
    }
  }
  switch(p->detectedLang)
  {
    case ClangParser::Private::Detected_Cpp: 
      argv[argc++]=strdup("c++"); 
      break;
    case ClangParser::Private::Detected_ObjC: 
      argv[argc++]=strdup("objective-c"); 
      break;
    case ClangParser::Private::Detected_ObjCpp: 
      argv[argc++]=strdup("objective-c++"); 
      break;
  }

  // provide the input and and its dependencies as unsaved files so we can
  // pass the filtered versions
  argv[argc++]=strdup(fileName);
  static bool filterSourceFiles = Config_getBool("FILTER_SOURCE_FILES");
  //printf("source %s ----------\n%s\n-------------\n\n",
  //    fileName,p->source.data());
  uint numUnsavedFiles = filesInTranslationUnit.count()+1;
  p->numFiles = numUnsavedFiles;
  p->sources = new QCString[numUnsavedFiles];
  p->ufs     = new CXUnsavedFile[numUnsavedFiles];
  p->sources[0]      = detab(fileToString(fileName,filterSourceFiles,TRUE));
  p->ufs[0].Filename = strdup(fileName);
  p->ufs[0].Contents = p->sources[0].data();
  p->ufs[0].Length   = p->sources[0].length();
  QStrListIterator it(filesInTranslationUnit);
  uint i=1;
  for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
  {
    p->fileMapping.insert(it.current(),new uint(i));
    p->sources[i]      = detab(fileToString(it.current(),filterSourceFiles,TRUE));
    p->ufs[i].Filename = strdup(it.current());
    p->ufs[i].Contents = p->sources[i].data();
    p->ufs[i].Length   = p->sources[i].length();
  }

  // let libclang do the actual parsing
  p->tu = clang_parseTranslationUnit(p->index, 0,
                                     argv, argc, p->ufs, numUnsavedFiles, 
                                     CXTranslationUnit_DetailedPreprocessingRecord);
  // free arguments
  for (int i=0;i<argc;++i)
  {
    free(argv[i]);
  }
  free(argv);

  if (p->tu)
  {
    // filter out any includes not found by the clang parser
    determineInputFilesInSameTu(filesInTranslationUnit);

    // show any warnings that the compiler produced
    for (uint i=0, n=clang_getNumDiagnostics(p->tu); i!=n; ++i) 
    {
      CXDiagnostic diag = clang_getDiagnostic(p->tu, i); 
      CXString string = clang_formatDiagnostic(diag,
          clang_defaultDiagnosticDisplayOptions()); 
      err("%s [clang]\n",clang_getCString(string));
      clang_disposeString(string);
      clang_disposeDiagnostic(diag);
    }

    // create a source range for the given file
    QFileInfo fi(fileName);
    CXFile f = clang_getFile(p->tu, fileName);
    CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
    CXSourceLocation fileEnd   = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
    CXSourceRange    fileRange = clang_getRange(fileBegin, fileEnd);

    // produce a token stream for the file
    clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);

    // produce cursors for each token in the stream
    p->cursors=new CXCursor[p->numTokens];
    clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
  }
  else
  {
    p->tokens    = 0;
    p->numTokens = 0;
    p->cursors   = 0;
    err("clang: Failed to parse translation unit %s\n",fileName);
  }
}
예제 #18
0
void writeInstallScript()
{
  QCString fileName=Config_getString("HTML_OUTPUT")+"/installdox";
  QFile f(fileName);
  if (f.open(IO_WriteOnly))
  {
    FTextStream t(&f);
    t << "#!" << Config_getString("PERL_PATH") << endl << endl << "%subst = ( ";
    
    char *s=Config_getList("TAGFILES").first();
    while (s)
    {
      QCString tagLine=s;
      QCString fileName;
      int eqPos = tagLine.find('=');
      if (eqPos!=-1) // strip destination part
      {
        fileName = tagLine.left(eqPos).stripWhiteSpace();
      }
      else
      {
        fileName = tagLine;
      }
      QFileInfo fi(fileName);
      t << "\"" << fi.fileName() << "\", \"\"";
      s=Config_getList("TAGFILES").next();
      if (s) t << ", ";
    }
    
    t << ");\n";
    t << "$quiet   = 0;\n";
    t << "\n";
    t << "if (open(F,\"search.cfg\"))\n";
    t << "{\n";
    t << "  $_=<F> ; s/[ \\t\\n]*$//g ; $subst{\"_doc\"} = $_;\n";
    t << "  $_=<F> ; s/[ \\t\\n]*$//g ; $subst{\"_cgi\"} = $_;\n";
    t << "}\n";
    t << "\n";
    t << "while ( @ARGV ) {\n";
    t << "  $_ = shift @ARGV;\n";
    t << "  if ( s/^-// ) {\n";
    t << "    if ( /^l(.*)/ ) {\n";
    t << "      $v = ($1 eq \"\") ? shift @ARGV : $1;\n";
    t << "      ($v =~ /\\/$/) || ($v .= \"/\");\n";
    t << "      $_ = $v;\n";
    t << "      if ( /(.+)\\@(.+)/ ) {\n";
    t << "        if ( exists $subst{$1} ) {\n";
    t << "          $subst{$1} = $2;\n";
    t << "        } else {\n";
    t << "          print STDERR \"Unknown tag file $1 given with option -l\\n\";\n";
    t << "          &usage();\n";
    t << "        }\n";
    t << "      } else {\n";
    t << "        print STDERR \"Argument $_ is invalid for option -l\\n\";\n";
    t << "        &usage();\n";
    t << "      }\n";
    t << "    }\n";
    t << "    elsif ( /^q/ ) {\n";
    t << "      $quiet = 1;\n";
    t << "    }\n";
    t << "    elsif ( /^\\?|^h/ ) {\n";
    t << "      &usage();\n";
    t << "    }\n";
    t << "    else {\n";
    t << "      print STDERR \"Illegal option -$_\\n\";\n";
    t << "      &usage();\n";
    t << "    }\n";
    t << "  }\n";
    t << "  else {\n";
    t << "    push (@files, $_ );\n";
    t << "  }\n";
    t << "}\n";
    t << "\n";
    t << "foreach $sub (keys %subst)\n";
    t << "{\n";
    t << "  if ( $subst{$sub} eq \"\" ) \n";
    t << "  {\n";
    t << "    print STDERR \"No substitute given for tag file `$sub'\\n\";\n";
    t << "    &usage();\n";
    t << "  }\n";
    t << "  elsif ( ! $quiet && $sub ne \"_doc\" && $sub ne \"_cgi\" )\n";
    t << "  {\n";
    t << "    print \"Substituting $subst{$sub} for each occurrence of tag file $sub\\n\"; \n";
    t << "  }\n";
    t << "}\n";
    t << "\n";
    t << "if ( ! @files ) {\n";
    t << "  if (opendir(D,\".\")) {\n";
    t << "    foreach $file ( readdir(D) ) {\n";
    t << "      $match = \"" << Config_getString("HTML_FILE_EXTENSION") << "\";\n";
    t << "      next if ( $file =~ /^\\.\\.?$/ );\n";
    t << "      ($file =~ /$match/) && (push @files, $file);\n";
    t << "      ($file =~ \"tree.js\") && (push @files, $file);\n";
    t << "    }\n";
    t << "    closedir(D);\n";
    t << "  }\n";
    t << "}\n";
    t << "\n";
    t << "if ( ! @files ) {\n";
    t << "  print STDERR \"Warning: No input files given and none found!\\n\";\n";
    t << "}\n";
    t << "\n";
    t << "foreach $f (@files)\n";
    t << "{\n";
    t << "  if ( ! $quiet ) {\n";
    t << "    print \"Editing: $f...\\n\";\n";
    t << "  }\n";
    t << "  $oldf = $f;\n";
    t << "  $f   .= \".bak\";\n";
    t << "  unless (rename $oldf,$f) {\n";
    t << "    print STDERR \"Error: cannot rename file $oldf\\n\";\n";
    t << "    exit 1;\n";
    t << "  }\n";
    t << "  if (open(F,\"<$f\")) {\n";
    t << "    unless (open(G,\">$oldf\")) {\n";
    t << "      print STDERR \"Error: opening file $oldf for writing\\n\";\n";
    t << "      exit 1;\n";
    t << "    }\n";
    t << "    if ($oldf ne \"tree.js\") {\n";
    t << "      while (<F>) {\n";
    t << "        s/doxygen\\=\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\" (href|src)=\\\"\\2/doxygen\\=\\\"$1:$subst{$1}\\\" \\3=\\\"$subst{$1}/g;\n";
    t << "        print G \"$_\";\n";
    t << "      }\n";
    t << "    }\n";
    t << "    else {\n";
    t << "      while (<F>) {\n";
    t << "        s/\\\"([^ \\\"\\:\\t\\>\\<]*)\\:([^ \\\"\\t\\>\\<]*)\\\", \\\"\\2/\\\"$1:$subst{$1}\\\" ,\\\"$subst{$1}/g;\n";
    t << "        print G \"$_\";\n";
    t << "      }\n";
    t << "    }\n";
    t << "  } \n";
    t << "  else {\n";
    t << "    print STDERR \"Warning file $f does not exist\\n\";\n";
    t << "  }\n";
    t << "  unlink $f;\n";
    t << "}\n";
    t << "\n";
    t << "sub usage {\n";
    t << "  print STDERR \"Usage: installdox [options] [html-file [html-file ...]]\\n\";\n";
    t << "  print STDERR \"Options:\\n\";\n";
    t << "  print STDERR \"     -l tagfile\\@linkName   tag file + URL or directory \\n\";\n";
    t << "  print STDERR \"     -q                    Quiet mode\\n\\n\";\n";
    t << "  exit 1;\n";
    t << "}\n";
  }
  else
  {
    err("Error: Cannot open file %s for writing\n",fileName.data());
  }
  f.close();
  struct stat stat_struct;
  stat(fileName,&stat_struct);
#if !defined(_WIN32)
  chmod(fileName,stat_struct.st_mode|S_IXUSR|S_IXGRP|S_IXOTH);
#endif
}
예제 #19
0
파일: doxyapp.cpp 프로젝트: kaos/doxygen
int main(int argc,char **argv)
{
  char cmd[256];

  if (argc<2)
  {
    printf("Usage: %s [source_file | source_dir]\n",argv[0]);
    exit(1);
  }

  // initialize data structures 
  initDoxygen();

  // setup the non-default configuration options

  // we need a place to put intermediate files
  Config_getString("OUTPUT_DIRECTORY")="/tmp/doxygen"; 
  // disable html output
  Config_getBool("GENERATE_HTML")=FALSE;
  // disable latex output
  Config_getBool("GENERATE_LATEX")=FALSE;
  // be quiet
  Config_getBool("QUIET")=TRUE;
  // turn off warnings
  Config_getBool("WARNINGS")=FALSE;
  Config_getBool("WARN_IF_UNDOCUMENTED")=FALSE;
  Config_getBool("WARN_IF_DOC_ERROR")=FALSE;
  // Extract as much as possible
  Config_getBool("EXTRACT_ALL")=TRUE;
  Config_getBool("EXTRACT_STATIC")=TRUE;
  Config_getBool("EXTRACT_PRIVATE")=TRUE;
  Config_getBool("EXTRACT_LOCAL_METHODS")=TRUE;
  // Extract source browse information, needed 
  // to make doxygen gather the cross reference info
  Config_getBool("SOURCE_BROWSER")=TRUE;

  // set the input
  Config_getList("INPUT").append(argv[1]);

  // check and finialize the configuration
  checkConfiguration();
  adjustConfiguration();

  // parse the files
  parseInput();

  // iterate over the input files
  FileNameListIterator fnli(*Doxygen::inputNameList); 
  FileName *fn;
  // foreach file with a certain name
  for (fnli.toFirst();(fn=fnli.current());++fnli)
  {
    FileNameIterator fni(*fn);
    FileDef *fd;
    // for each file definition
    for (;(fd=fni.current());++fni)
    {
      // get the references (linked and unlinked) found in this file
      findXRefSymbols(fd);
    }
  }

  // remove temporary files
  if (!Doxygen::objDBFileName.isEmpty()) unlink(Doxygen::objDBFileName);
  if (!Doxygen::entryDBFileName.isEmpty()) unlink(Doxygen::entryDBFileName);
  // clean up after us
  rmdir("/tmp/doxygen");

  while (1)
  {
    printf("> Type a symbol name or\n> .list for a list of symbols or\n> .quit to exit\n> ");
    fgets(cmd,256,stdin);
    QCString s(cmd);
    if (s.at(s.length()-1)=='\n') s=s.left(s.length()-1); // strip trailing \n
    if (s==".list") 
      listSymbols();
    else if (s==".quit") 
      exit(0);
    else 
      lookupSymbols(s);
  }
}