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