htags.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <stdio.h>
17 
18 #include <qdir.h>
19 #include <qdict.h>
20 
21 #include "htags.h"
22 #include "util.h"
23 #include "message.h"
24 #include "config.h"
25 #include "portable.h"
26 
27 
28 bool Htags::useHtags = FALSE;
29 
31 static QDict<QCString> g_symbolDict(10007);
32 
33 /*! constructs command line of htags(1) and executes it.
34  * \retval TRUE success
35  * \retval FALSE an error has occurred.
36  */
37 bool Htags::execute(const QCString &htmldir)
38 {
39  static QStrList &inputSource = Config_getList("INPUT");
40  static bool quiet = Config_getBool("QUIET");
41  static bool warnings = Config_getBool("WARNINGS");
42  static QCString htagsOptions = ""; //Config_getString("HTAGS_OPTIONS");
43  static QCString projectName = Config_getString("PROJECT_NAME");
44  static QCString projectNumber = Config_getString("PROJECT_NUMBER");
45 
47  if (inputSource.isEmpty())
48  {
49  g_inputDir.setPath(cwd);
50  }
51  else if (inputSource.count()==1)
52  {
53  g_inputDir.setPath(inputSource.first());
54  if (!g_inputDir.exists())
55  err("Cannot find directory %s. "
56  "Check the value of the INPUT tag in the configuration file.\n",
57  inputSource.first()
58  );
59  }
60  else
61  {
62  err("If you use USE_HTAGS then INPUT should specify a single directory.\n");
63  return FALSE;
64  }
65 
66  /*
67  * Construct command line for htags(1).
68  */
69  QCString commandLine = " -g -s -a -n ";
70  if (!quiet) commandLine += "-v ";
71  if (warnings) commandLine += "-w ";
72  if (!htagsOptions.isEmpty())
73  {
74  commandLine += ' ';
75  commandLine += htagsOptions;
76  }
77  if (!projectName.isEmpty())
78  {
79  commandLine += "-t \"";
80  commandLine += projectName;
81  if (!projectNumber.isEmpty())
82  {
83  commandLine += '-';
84  commandLine += projectNumber;
85  }
86  commandLine += "\" ";
87  }
88  commandLine += " \"" + htmldir + "\"";
89  QCString oldDir = QDir::currentDirPath().utf8();
90  QDir::setCurrent(g_inputDir.absPath());
91  //printf("CommandLine=[%s]\n",commandLine.data());
93  bool result=portable_system("htags",commandLine,FALSE)==0;
95  QDir::setCurrent(oldDir);
96  return result;
97 }
98 
99 
100 /*! load filemap and make index.
101  * \param htmlDir of HTML directory generated by htags(1).
102  * \retval TRUE success
103  * \retval FALSE error
104  */
105 bool Htags::loadFilemap(const QCString &htmlDir)
106 {
107  QCString fileMapName = htmlDir+"/HTML/FILEMAP";
108  QFileInfo fi(fileMapName);
109  /*
110  * Construct FILEMAP dictionary using QDict.
111  *
112  * In FILEMAP, URL includes 'html' suffix but we cut it off according
113  * to the method of FileDef class.
114  *
115  * FILEMAP format:
116  * <NAME>\t<HREF>.html\n
117  * QDICT:
118  * dict[<NAME>] = <HREF>
119  */
120  if (fi.exists() && fi.isReadable())
121  {
122  QFile f(fileMapName);
123  const int maxlen = 8192;
124  QCString line(maxlen+1);
125  line.at(maxlen)='\0';
126  if (f.open(IO_ReadOnly))
127  {
128  int len;
129  while ((len=f.readLine(line.rawData(),maxlen))>0)
130  {
131  line.resize(len+1);
132  //printf("Read line: %s",line.data());
133  int sep = line.find('\t');
134  if (sep!=-1)
135  {
136  QCString key = line.left(sep).stripWhiteSpace();
137  QCString value = line.mid(sep+1).stripWhiteSpace();
138  int ext=value.findRev('.');
139  if (ext!=-1) value=value.left(ext); // strip extension
140  g_symbolDict.setAutoDelete(TRUE);
141  g_symbolDict.insert(key,new QCString(value));
142  //printf("Key/Value=(%s,%s)\n",key.data(),value.data());
143  }
144  }
145  return TRUE;
146  }
147  else
148  {
149  err("file %s cannot be opened\n",fileMapName.data());
150  }
151  }
152  return FALSE;
153 }
154 
155 /*! convert path name into the url in the hypertext generated by htags.
156  * \param path path name
157  * \returns URL NULL: not found.
158  */
160 {
161  QCString url,symName=path;
162  QCString dir = g_inputDir.absPath().utf8();
163  int dl=dir.length();
164  if ((int)symName.length()>dl+1)
165  {
166  symName = symName.mid(dl+1);
167  }
168  if (!symName.isEmpty())
169  {
170  QCString *result = g_symbolDict[symName];
171  //printf("path2URL=%s symName=%s result=%p\n",path.data(),symName.data(),result);
172  if (result)
173  {
174  url = "HTML/" + *result;
175  }
176  }
177  return url;
178 }
179 
Traverses directory structures and contents in a platform-independent way.
Definition: qdir.h:52
bool resize(uint newlen)
Definition: qcstring.h:225
char * rawData() const
Definition: qcstring.h:216
void portable_sysTimerStop()
Definition: portable.cpp:415
QCString stripWhiteSpace() const
Definition: qcstring.cpp:295
static QCString result
bool isEmpty() const
Definition: qcstring.h:189
static const int maxlen
Definition: qregexp.cpp:904
static bool loadFilemap(const QCString &htmldir)
Definition: htags.cpp:105
uint length() const
Definition: qcstring.h:195
virtual void setPath(const QString &path)
Definition: qdir.cpp:248
type * first()
Definition: qinternallist.h:87
char & at(uint i) const
Definition: qcstring.h:326
static bool execute(const QCString &htmldir)
Definition: htags.cpp:37
const bool FALSE
Definition: qglobal.h:370
int readLine(char *data, uint maxlen)
Definition: qfile.cpp:268
#define Config_getList(val)
Definition: config.cpp:662
QCString left(uint len) const
Definition: qcstring.cpp:213
string dir
int find(char c, int index=0, bool cs=TRUE) const
Definition: qcstring.cpp:41
virtual QString absPath() const
Definition: qdir.cpp:276
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition: qcstring.cpp:95
static QDir g_inputDir
Definition: htags.cpp:30
void portable_sysTimerStart()
Definition: portable.cpp:410
#define IO_ReadOnly
Definition: qiodevice.h:61
static QDict< QCString > g_symbolDict(10007)
static QCString path2URL(const QCString &path)
Definition: htags.cpp:159
def key(type, name=None)
Definition: graph.py:13
bool open(int)
Definition: qfile_unix.cpp:134
static QString currentDirPath()
Definition: qdir_unix.cpp:141
A bunch of utility functions.
const char * data() const
Definition: qcstring.h:207
#define Config_getString(val)
Definition: config.cpp:660
#define Config_getBool(val)
Definition: config.cpp:664
void err(const char *fmt,...)
Definition: message.cpp:226
QCString mid(uint index, uint len=0xffffffff) const
Definition: qcstring.cpp:246
The QFile class is an I/O device that operates on files.
Definition: qfile.h:50
static bool useHtags
Definition: htags.h:23
void line(double t, double *p, double &x, double &y, double &z)
bool isEmpty() const
Definition: qinternallist.h:57
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:51
uint count() const
Definition: qinternallist.h:56
QCString utf8() const
Definition: qstring.cpp:14507
virtual bool exists() const
Definition: qdir.cpp:820
const bool TRUE
Definition: qglobal.h:371
Portable versions of functions that are platform dependent.
static bool setCurrent(const QString &path)
Definition: qdir_unix.cpp:134
bool exists() const
Definition: qfileinfo.cpp:265
int portable_system(const char *command, const char *args, bool commandHasConsole)
Definition: portable.cpp:33
bool isReadable() const
Definition: qfileinfo.cpp:405