Fix for UBSan build
[platform/upstream/doxygen.git] / src / msc.cpp
1 /******************************************************************************
2  *
3  * $Id: msc.cpp,v 1.14 2001/03/19 19:27:40 root Exp $
4  *
5  * Copyright (C) 1997-2012 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include "msc.h"
19 #include "portable.h"
20 #include "config.h"
21 #include "message.h"
22 #include "docparser.h"
23 #include "doxygen.h"
24
25 #include <qdir.h>
26
27 static const int maxCmdLine = 40960;
28
29 static bool convertMapFile(QTextStream &t,const char *mapName,const QCString relPath,
30                            const QCString &context)
31 {
32   QFile f(mapName);
33   if (!f.open(IO_ReadOnly))
34   {
35     err("error: failed to open map file %s for inclusion in the docs!\n"
36         "If you installed Graphviz/dot after a previous failing run, \n"
37         "try deleting the output directory and rerun doxygen.\n",mapName);
38     return FALSE;
39   }
40   const int maxLineLen=1024;
41   char buf[maxLineLen];
42   char url[maxLineLen];
43   char ref[maxLineLen];
44   int x1,y1,x2,y2;
45   while (!f.atEnd())
46   {
47     bool isRef = FALSE;
48     int numBytes = f.readLine(buf,maxLineLen);
49     buf[numBytes-1]='\0';
50     //printf("ReadLine `%s'\n",buf);
51     if (strncmp(buf,"rect",4)==0)
52     {
53       // obtain the url and the coordinates in the order used by graphviz-1.5
54       sscanf(buf,"rect %s %d,%d %d,%d",url,&x1,&y1,&x2,&y2);
55
56       if ( strcmp(url,"\\ref") == 0 )
57       {
58         isRef = TRUE;
59         sscanf(buf,"rect %s %s %d,%d %d,%d",ref,url,&x1,&y1,&x2,&y2);
60       }
61
62       // sanity checks
63       if (y2<y1) { int temp=y2; y2=y1; y1=temp; }
64       if (x2<x1) { int temp=x2; x2=x1; x1=temp; }
65
66       t << "<area href=\"";
67
68       if ( isRef )
69       {
70         // handle doxygen \ref tag URL reference
71         DocRef *df = new DocRef( (DocNode*) 0, url, context );
72         t << externalRef(relPath,df->ref(),TRUE);
73         if (!df->file().isEmpty()) t << df->file() << Doxygen::htmlFileExtension;
74         if (!df->anchor().isEmpty()) t << "#" << df->anchor();
75       }
76       else
77       {
78         t << url;
79       }
80       t << "\" shape=\"rect\" coords=\""
81         << x1 << "," << y1 << "," << x2 << "," << y2 << "\""
82         << " alt=\"\"/>" << endl;
83     }
84   }
85
86   return TRUE;
87 }
88
89 void writeMscGraphFromFile(const char *inFile,const char *outDir,
90                            const char *outFile,MscOutputFormat format)
91 {
92   QCString absOutFile = outDir;
93   absOutFile+=portable_pathSeparator();
94   absOutFile+=outFile;
95
96   // chdir to the output dir, so dot can find the font file.
97   QCString oldDir = convertToQCString(QDir::currentDirPath());
98   // go to the html output directory (i.e. path)
99   QDir::setCurrent(outDir);
100   //printf("Going to dir %s\n",QDir::currentDirPath().data());
101   QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension();
102   QCString mscArgs;
103   QCString extension;
104   if (format==MSC_BITMAP)
105   {
106     mscArgs+="-T png";
107     extension=".png";
108   }
109   else if (format==MSC_EPS)
110   {
111     mscArgs+="-T eps";
112     extension=".eps";
113   }
114   mscArgs+=" -i \"";
115   mscArgs+=inFile;
116  
117   mscArgs+="\" -o \"";
118   mscArgs+=outFile;
119   mscArgs+=extension+"\"";
120   int exitCode;
121 //  printf("*** running: %s %s outDir:%s %s\n",mscExe.data(),mscArgs.data(),outDir,outFile);
122   portable_sysTimerStart();
123   if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0)
124   {
125     portable_sysTimerStop();
126     goto error;
127   }
128   portable_sysTimerStop();
129   if ( (format==MSC_EPS) && (Config_getBool("USE_PDFLATEX")) )
130   {
131     QCString epstopdfArgs(maxCmdLine);
132     epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
133                          outFile,outFile);
134     portable_sysTimerStart();
135     if (portable_system("epstopdf",epstopdfArgs)!=0)
136     {
137       err("error: Problems running epstopdf. Check your TeX installation!\n");
138     }
139     portable_sysTimerStop();
140   }
141
142 error:
143   QDir::setCurrent(oldDir);
144 }
145
146 QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir,
147                                 const QCString& relPath,const QCString& context)
148 {
149   QCString outFile = inFile + ".map";
150
151
152   //printf("*** running:getMscImageMapFromFile \n");
153   // chdir to the output dir, so dot can find the font file.
154   QCString oldDir = convertToQCString(QDir::currentDirPath());
155   // go to the html output directory (i.e. path)
156   QDir::setCurrent(outDir);
157   //printf("Going to dir %s\n",QDir::currentDirPath().data());
158
159   QCString mscExe = Config_getString("MSCGEN_PATH")+"mscgen"+portable_commandExtension();
160   QCString mscArgs = "-T ismap -i \"";
161   mscArgs+=inFile;
162   QFileInfo fi(inFile);
163   mscArgs+="\" -o \"";
164   mscArgs+=outFile + "\"";
165
166   int exitCode;
167   portable_sysTimerStart();
168   if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0)
169   {
170     portable_sysTimerStop();
171     QDir::setCurrent(oldDir);
172     return "";
173   }
174   portable_sysTimerStop();
175   
176   QString result;
177   QTextOStream tmpout(&result);
178   convertMapFile(tmpout, outFile, relPath, context);
179   QDir().remove(outFile);
180
181   QDir::setCurrent(oldDir);
182   return result.data();
183 }
184
185 void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile,
186                               const QCString &outDir,
187                               const QCString &relPath,
188                               const QCString &baseName,
189                               const QCString &context)
190 {
191   QCString mapName = baseName+".map";
192   QCString mapFile = inFile+".map";
193   t << "<img src=\"" << relPath << baseName << ".png\" alt=\""
194     << baseName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>" << endl;
195   QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context);
196   t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">" << imap << "</map>" << endl;
197 }
198