Doxygen
Loading...
Searching...
No Matches
msc.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2021 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 "msc.h"
17#include "portable.h"
18#include "config.h"
19#include "message.h"
20#include "docparser.h"
21#include "docnode.h"
22#include "doxygen.h"
23#include "indexlist.h"
24#include "util.h"
25#include "mscgen_api.h"
26#include "dir.h"
27#include "textstream.h"
28
29static const int maxCmdLine = 40960;
30
31static bool convertMapFile(TextStream &t,const QCString &mapName,const QCString &relPath,
32 const QCString &context,const QCString &srcFile,int srcLine)
33{
34 std::ifstream f = Portable::openInputStream(mapName);
35 if (!f.is_open())
36 {
37 err("failed to open map file %s for inclusion in the docs!\n"
38 "If you installed Graphviz/dot after a previous failing run, \n"
39 "try deleting the output directory and rerun doxygen.\n",qPrint(mapName));
40 return false;
41 }
42 const int maxLineLen=1024;
43 char url[maxLineLen];
44 char ref[maxLineLen];
45 int x1=0, y1=0, x2=0, y2=0;
46 std::string line;
47 while (getline(f,line))
48 {
49 bool isRef = false;
50 //printf("ReadLine '%s'\n",line.c_str());
51 if (qstrncmp(line.c_str(),"rect",4)==0)
52 {
53 // obtain the url and the coordinates in the order used by graphviz-1.5
54 sscanf(line.c_str(),"rect %s %d,%d %d,%d",url,&x1,&y1,&x2,&y2);
55
56 if (qstrcmp(url,"\\ref")==0 || qstrcmp(url,"@ref")==0)
57 {
58 isRef = true;
59 sscanf(line.c_str(),"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
67 bool link = false;
68 if ( isRef )
69 {
70 // handle doxygen \ref tag URL reference
71
72 auto parser { createDocParser() };
73 auto dfAst { createRef( *parser.get(), url, context, srcFile, srcLine) };
74 auto dfAstImpl = dynamic_cast<const DocNodeAST*>(dfAst.get());
75 const DocRef *df = std::get_if<DocRef>(&dfAstImpl->root);
76 if (!df->file().isEmpty() || !df->anchor().isEmpty())
77 {
78 link = true;
79 t << "<area href=\"";
80 t << externalRef(relPath,df->ref(),TRUE);
81 }
82 if (!df->file().isEmpty())
83 {
84 QCString fn = df->file();
86 t << fn;
87 }
88 if (!df->anchor().isEmpty())
89 {
90 t << "#" << df->anchor();
91 }
92 }
93 else
94 {
95 link = true;
96 t << "<area href=\"";
97 t << url;
98 }
99 if (link)
100 {
101 t << "\" shape=\"rect\" coords=\""
102 << x1 << "," << y1 << "," << x2 << "," << y2 << "\""
103 << " alt=\"\"/>\n";
104 }
105 }
106 }
107
108 return true;
109}
110
111static bool do_mscgen_generate(const QCString& inFile,const QCString& outFile,mscgen_format_t msc_format,
112 const QCString &srcFile,int srcLine)
113{
114 auto mscgen_tool = Config_getString(MSCGEN_TOOL).stripWhiteSpace();
115 if (!mscgen_tool.isEmpty()) // use external mscgen tool
116 {
117 QCString type;
118 switch (msc_format)
119 {
120 case mscgen_format_png:
121 type = "png";
122 break;
123 case mscgen_format_eps:
124 type = "eps";
125 break;
126 case mscgen_format_svg:
127 type = "svg";
128 break;
129 case mscgen_format_pngmap:
130 case mscgen_format_svgmap:
131 type = "ismap";
132 break;
133 }
134 int exitcode = Portable::system(mscgen_tool,"-T"+type+" -o "+outFile+" "+inFile);
135 if (exitcode!=0)
136 {
137 err_full(srcFile,srcLine,"Problems running external tool %s given via MSCGEN_TOOL (exit status: %d)."
138 " Look for typos in your msc file and check error messages above.",
139 qPrint(mscgen_tool),exitcode);
140 return false;
141 }
142 }
143 else // use built-in mscgen tool
144 {
145 int code = mscgen_generate(inFile.data(),outFile.data(),msc_format);
146 if (code!=0)
147 {
148 err_full(srcFile,srcLine,"Problems generating msc output (error=%s). Look for typos in you msc file '%s'",
149 mscgen_error2str(code),qPrint(inFile));
150 return false;
151 }
152 }
153 return true;
154}
155
156void writeMscGraphFromFile(const QCString &inFile,const QCString &outDir,
157 const QCString &outFile,MscOutputFormat format,
158 const QCString &srcFile,int srcLine
159 )
160{
161 QCString absOutFile = outDir;
162 absOutFile+=Portable::pathSeparator();
163 absOutFile+=outFile;
164
165 mscgen_format_t msc_format = mscgen_format_png;
166 QCString imgName = absOutFile;
167 switch (format)
168 {
170 msc_format = mscgen_format_png;
171 imgName+=".png";
172 break;
174 msc_format = mscgen_format_eps;
175 imgName+=".eps";
176 break;
178 msc_format = mscgen_format_svg;
179 imgName+=".svg";
180 break;
181 default:
182 return;
183 }
184 if (!do_mscgen_generate(inFile,imgName,msc_format,srcFile,srcLine))
185 {
186 return;
187 }
188
189 if ( (format==MscOutputFormat::EPS) && (Config_getBool(USE_PDFLATEX)) )
190 {
192 epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"",
193 qPrint(absOutFile),qPrint(absOutFile));
194 if (Portable::system("epstopdf",epstopdfArgs)!=0)
195 {
196 err_full(srcFile,srcLine,"Problems running epstopdf when processing '%s.eps'. Check your TeX installation!",
197 qPrint(absOutFile));
198 }
199 else
200 {
201 Dir().remove((absOutFile + ".eps").data());
202 }
203 }
204
205 int i=std::max(imgName.findRev('/'),imgName.findRev('\\'));
206 if (i!=-1) // strip path
207 {
208 imgName=imgName.right(imgName.length()-i-1);
209 }
210 Doxygen::indexList->addImageFile(imgName);
211
212}
213
214static QCString getMscImageMapFromFile(const QCString& inFile, const QCString& /* outDir */,
215 const QCString& relPath,const QCString& context,
216 bool writeSVGMap,const QCString &srcFile,int srcLine)
217{
218 QCString outFile = inFile + ".map";
219
220 if (!do_mscgen_generate(inFile,outFile,
221 writeSVGMap ? mscgen_format_svgmap : mscgen_format_pngmap,
222 srcFile,srcLine))
223 return "";
224
225 TextStream t;
226 convertMapFile(t, outFile, relPath, context, srcFile, srcLine);
227
228 Dir().remove(outFile.str());
229
230 return t.str();
231}
232
234 const QCString &outDir,
235 const QCString &relPath,
236 const QCString &baseName,
237 const QCString &context,
238 MscOutputFormat format,
239 const QCString &srcFile,
240 int srcLine
241 )
242{
243 QCString mapName = baseName+".map";
244 t << "<img src=\"" << relPath << baseName << ".";
245 switch (format)
246 {
248 t << "png";
249 break;
251 t << "eps";
252 break;
254 t << "svg";
255 break;
256 default:
257 t << "unknown";
258 }
259 QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context,format==MscOutputFormat::SVG,srcFile,srcLine);
260 if (!imap.isEmpty())
261 {
262 t << "\" alt=\""
263 << baseName << "\" border=\"0\" usemap=\"#" << mapName << "\"/>\n";
264 t << "<map name=\"" << mapName << "\" id=\"" << mapName << "\">" << imap << "</map>\n";
265 }
266 else
267 {
268 t << "\" alt=\"" << baseName << "\" border=\"0\"/>\n";
269 }
270}
271
Class representing a directory in the file system.
Definition dir.h:75
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:314
Class representing the abstract syntax tree of a documentation block.
Definition docnode.h:1460
Node representing a reference to some item.
Definition docnode.h:772
QCString anchor() const
Definition docnode.h:779
QCString file() const
Definition docnode.h:776
QCString ref() const
Definition docnode.h:778
static IndexList * indexList
Definition doxygen.h:134
This is an alternative implementation of QCString.
Definition qcstring.h:101
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
QCString right(size_t len) const
Definition qcstring.h:219
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
@ ExplicitSize
Definition qcstring.h:133
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string.
Definition qcstring.h:159
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
#define Config_getBool(name)
Definition config.h:33
#define Config_getString(name)
Definition config.h:32
static const int maxCmdLine
Definition dia.cpp:24
IDocParserPtr createDocParser()
factory function to create a parser
Definition docparser.cpp:54
IDocNodeASTPtr createRef(IDocParser &parserIntf, const QCString &target, const QCString &context, const QCString &srcFile, int srcLine)
#define err(fmt,...)
Definition message.h:84
#define err_full(file, line, fmt,...)
Definition message.h:89
void writeMscImageMapFromFile(TextStream &t, const QCString &inFile, const QCString &outDir, const QCString &relPath, const QCString &baseName, const QCString &context, MscOutputFormat format, const QCString &srcFile, int srcLine)
Definition msc.cpp:233
void writeMscGraphFromFile(const QCString &inFile, const QCString &outDir, const QCString &outFile, MscOutputFormat format, const QCString &srcFile, int srcLine)
Definition msc.cpp:156
static QCString getMscImageMapFromFile(const QCString &inFile, const QCString &, const QCString &relPath, const QCString &context, bool writeSVGMap, const QCString &srcFile, int srcLine)
Definition msc.cpp:214
static bool convertMapFile(TextStream &t, const QCString &mapName, const QCString &relPath, const QCString &context, const QCString &srcFile, int srcLine)
Definition msc.cpp:31
static bool do_mscgen_generate(const QCString &inFile, const QCString &outFile, mscgen_format_t msc_format, const QCString &srcFile, int srcLine)
Definition msc.cpp:111
MscOutputFormat
Definition msc.h:22
std::ifstream openInputStream(const QCString &name, bool binary=false, bool openAtEnd=false)
Definition portable.cpp:676
QCString pathSeparator()
Definition portable.cpp:391
int system(const QCString &command, const QCString &args, bool commandHasConsole=true)
Definition portable.cpp:106
Portable versions of functions that are platform dependent.
int qstrncmp(const char *str1, const char *str2, size_t len)
Definition qcstring.h:75
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
int qstrcmp(const char *str1, const char *str2)
Definition qcstring.h:69
QCString externalRef(const QCString &relPath, const QCString &ref, bool href)
Definition util.cpp:6066
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5243
A bunch of utility functions.