Fix for UBSan build
[platform/upstream/doxygen.git] / src / htags.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2012 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 "qtbc.h"
22 #include "htags.h"
23 #include "util.h"
24 #include "message.h"
25 #include "config.h"
26 #include "portable.h"
27
28
29 bool Htags::useHtags = FALSE;
30
31 static QDir g_inputDir;
32 static QDict<QCString> g_symbolDict(10007);
33
34 /*! constructs command line of htags(1) and executes it.
35  *  \retval TRUE success
36  *  \retval FALSE an error has occured.
37  */
38 bool Htags::execute(const QCString &htmldir)
39 {
40   static QStrList &inputSource = Config_getList("INPUT");
41   static bool quiet = Config_getBool("QUIET");
42   static bool warnings = Config_getBool("WARNINGS");
43   static QCString htagsOptions = ""; //Config_getString("HTAGS_OPTIONS");
44   static QCString projectName = Config_getString("PROJECT_NAME");
45   static QCString projectNumber = Config_getString("PROJECT_NUMBER");
46
47   QCString cwd = convertToQCString(QDir::currentDirPath());
48   if (inputSource.isEmpty())
49   {
50     g_inputDir.setPath(cwd);
51   }
52   else if (inputSource.count()==1)
53   {
54     g_inputDir.setPath(inputSource.first());
55     if (!g_inputDir.exists())
56       err("error: Cannot find directory %s. "
57           "Check the value of the INPUT tag in the configuration file.\n",
58           inputSource.first()
59          );
60   }
61   else
62   {
63     err("error: If you use USE_HTAGS then INPUT should specific a single directory. \n");
64     return FALSE;
65   }
66
67   /*
68    * Construct command line for htags(1).
69    */
70   QCString commandLine = " -g -s -a -n ";
71   if (!quiet)   commandLine += "-v ";
72   if (warnings) commandLine += "-w ";
73   if (!htagsOptions.isEmpty()) 
74   {
75     commandLine += ' ';
76     commandLine += htagsOptions;
77   }
78   if (!projectName.isEmpty()) 
79   {
80     commandLine += "-t \"";
81     commandLine += projectName;
82     if (!projectNumber.isEmpty()) 
83     {
84       commandLine += '-';
85       commandLine += projectNumber;
86     }
87     commandLine += "\" ";
88   }
89   commandLine += " \"" + htmldir + "\"";
90   QCString oldDir = convertToQCString(QDir::currentDirPath());
91   QDir::setCurrent(g_inputDir.absPath());
92   //printf("CommandLine=[%s]\n",commandLine.data());
93   portable_sysTimerStart();
94   bool result=portable_system("htags",commandLine,FALSE)==0;
95   portable_sysTimerStop();
96   QDir::setCurrent(oldDir);
97   return result;
98 }
99
100
101 /*! load filemap and make index.
102  *  \param htmlDir of HTML directory generated by htags(1).
103  *  \retval TRUE success
104  *  \retval FALSE error
105  */
106 bool Htags::loadFilemap(const QCString &htmlDir)
107 {
108   QCString fileMapName = htmlDir+"/HTML/FILEMAP";
109   QCString fileMap;
110   QFileInfo fi(fileMapName);
111   /*
112    * Construct FILEMAP dictionary using QDict.
113    *
114    * In FILEMAP, URL includes 'html' suffix but we cut it off according
115    * to the method of FileDef class.
116    *
117    * FILEMAP format:
118    * <NAME>\t<HREF>.html\n
119    * QDICT:
120    * dict[<NAME>] = <HREF>
121    */
122   if (fi.exists() && fi.isReadable())
123   {
124     QFile f(fileMapName);
125     const int maxlen = 8192;
126     QCString line(maxlen+1);
127     line.at(maxlen)='\0';
128     if (f.open(IO_ReadOnly))
129     {
130       while (f.readLine(line.data(),maxlen)>0)
131       {
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("error: 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  */
159 QCString Htags::path2URL(const QCString &path)
160 {
161   QCString url,symName=path;
162   QCString dir = convertToQCString(g_inputDir.absPath());
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