htags.cpp 4.83 KB
Newer Older
1 2
/******************************************************************************
 *
3
 * Copyright (C) 1997-2011 by Dimitri van Heesch.
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 * 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 <stdio.h>

#include <qdir.h>
#include <qdict.h>

#include "qtbc.h"
#include "htags.h"
#include "util.h"
#include "message.h"
#include "config.h"
26
#include "portable.h"
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55


bool Htags::useHtags = FALSE;

static QDir g_inputDir;
static QDict<QCString> g_symbolDict(10007);

/*! constructs command line of htags(1) and executes it.
 *  \retval TRUE success
 *  \retval FALSE an error has occured.
 */
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 = convertToQCString(QDir::currentDirPath());
  if (inputSource.isEmpty())
  {
    g_inputDir.setPath(cwd);
  }
  else if (inputSource.count()==1)
  {
    g_inputDir.setPath(inputSource.first());
    if (!g_inputDir.exists())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
56
      err("error: Cannot find directory %s. "
57 58 59 60 61 62
          "Check the value of the INPUT tag in the configuration file.\n",
          inputSource.first()
         );
  }
  else
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
63
    err("error: If you use USE_HTAGS then INPUT should specific a single directory. \n");
64 65 66 67 68 69
    return FALSE;
  }

  /*
   * Construct command line for htags(1).
   */
Dimitri van Heesch's avatar
Dimitri van Heesch committed
70
  QCString commandLine = " -g -s -a -n ";
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
  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 = convertToQCString(QDir::currentDirPath());
  QDir::setCurrent(g_inputDir.absPath());
  //printf("CommandLine=[%s]\n",commandLine.data());
93
  portable_sysTimerStart();
94
  bool result=portable_system("htags",commandLine,FALSE)==0;
95
  portable_sysTimerStop();
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
  QDir::setCurrent(oldDir);
  return result;
}


/*! load filemap and make index.
 *  \param htmlDir of HTML directory generated by htags(1).
 *  \retval TRUE success
 *  \retval FALSE error
 */
bool Htags::loadFilemap(const QCString &htmlDir)
{
  QCString fileMapName = htmlDir+"/HTML/FILEMAP";
  QCString fileMap;
  QFileInfo fi(fileMapName);
  /*
   * Construct FILEMAP dictionary using QDict.
   *
   * In FILEMAP, URL includes 'html' suffix but we cut it off according
   * to the method of FileDef class.
   *
   * FILEMAP format:
   * <NAME>\t<HREF>.html\n
   * QDICT:
   * dict[<NAME>] = <HREF>
   */
  if (fi.exists() && fi.isReadable())
  {
    QFile f(fileMapName);
    const int maxlen = 8192;
    QCString line(maxlen+1);
    line.at(maxlen)='\0';
    if (f.open(IO_ReadOnly))
    {
      while (f.readLine(line.data(),maxlen)>0)
      {
        //printf("Read line: %s",line.data());
        int sep = line.find('\t');
        if (sep!=-1)
        {
          QCString key   = line.left(sep).stripWhiteSpace();
          QCString value = line.mid(sep+1).stripWhiteSpace();
          int ext=value.findRev('.');
          if (ext!=-1) value=value.left(ext); // strip extension
          g_symbolDict.setAutoDelete(TRUE);
          g_symbolDict.insert(key,new QCString(value));
          //printf("Key/Value=(%s,%s)\n",key.data(),value.data());
        }
      }
      return TRUE;
    }
    else
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
149
      err("error: file %s cannot be opened\n",fileMapName.data()); 
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    }
  }
  return FALSE;
}

/*! convert path name into the url in the hypertext generated by htags.
 *  \param path path name
 *  \returns URL NULL: not found.
 */
QCString Htags::path2URL(const QCString &path)
{
  QCString url,symName=path;
  QCString dir = convertToQCString(g_inputDir.absPath());
  int dl=dir.length();
  if ((int)symName.length()>dl+1)
  {
    symName = symName.mid(dl+1);
  }
  if (!symName.isEmpty())
  {
    QCString *result = g_symbolDict[symName];
    //printf("path2URL=%s symName=%s result=%p\n",path.data(),symName.data(),result);
    if (result)
    {
      url = "HTML/" + *result;
    }
  }
  return url;
}