/****************************************************************************** * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ #include "msc.h" #include "portable.h" #include "config.h" #include "message.h" #include "docparser.h" #include "doxygen.h" #include "index.h" #include "util.h" #include "ftextstream.h" #include static const int maxCmdLine = 40960; static bool convertMapFile(FTextStream &t,const char *mapName,const QCString relPath, const QCString &context) { QFile f(mapName); if (!f.open(IO_ReadOnly)) { err("failed to open map file %s for inclusion in the docs!\n" "If you installed Graphviz/dot after a previous failing run, \n" "try deleting the output directory and rerun doxygen.\n",mapName); return FALSE; } const int maxLineLen=1024; char buf[maxLineLen]; char url[maxLineLen]; char ref[maxLineLen]; int x1,y1,x2,y2; while (!f.atEnd()) { bool isRef = FALSE; int numBytes = f.readLine(buf,maxLineLen); buf[numBytes-1]='\0'; //printf("ReadLine `%s'\n",buf); if (qstrncmp(buf,"rect",4)==0) { // obtain the url and the coordinates in the order used by graphviz-1.5 sscanf(buf,"rect %s %d,%d %d,%d",url,&x1,&y1,&x2,&y2); if (qstrcmp(url,"\\ref")==0 || qstrcmp(url,"@ref")==0) { isRef = TRUE; sscanf(buf,"rect %s %s %d,%d %d,%d",ref,url,&x1,&y1,&x2,&y2); } // sanity checks if (y2ref(),TRUE); if (!df->file().isEmpty()) t << df->file() << Doxygen::htmlFileExtension; if (!df->anchor().isEmpty()) t << "#" << df->anchor(); delete df; } else { t << url; } t << "\" shape=\"rect\" coords=\"" << x1 << "," << y1 << "," << x2 << "," << y2 << "\"" << " alt=\"\"/>" << endl; } } return TRUE; } void writeMscGraphFromFile(const char *inFile,const char *outDir, const char *outFile,MscOutputFormat format) { QCString absOutFile = outDir; absOutFile+=portable_pathSeparator(); absOutFile+=outFile; // chdir to the output dir, so dot can find the font file. QCString oldDir = QDir::currentDirPath().utf8(); // go to the html output directory (i.e. path) QDir::setCurrent(outDir); //printf("Going to dir %s\n",QDir::currentDirPath().data()); QCString mscExe = Config_getString(MSCGEN_PATH)+"mscgen"+portable_commandExtension(); QCString mscArgs; QCString imgName = outFile; switch (format) { case MSC_BITMAP: mscArgs+="-T png"; imgName+=".png"; break; case MSC_EPS: mscArgs+="-T eps"; imgName+=".eps"; break; case MSC_SVG: mscArgs+="-T svg"; imgName+=".svg"; break; default: goto error; // I am not very fond of goto statements, but when in Rome... } mscArgs+=" -i \""; mscArgs+=inFile; mscArgs+="\" -o \""; mscArgs+=imgName+"\""; int exitCode; // printf("*** running: %s %s outDir:%s %s\n",mscExe.data(),mscArgs.data(),outDir,outFile); portable_sysTimerStart(); if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0) { portable_sysTimerStop(); goto error; } portable_sysTimerStop(); if ( (format==MSC_EPS) && (Config_getBool(USE_PDFLATEX)) ) { QCString epstopdfArgs(maxCmdLine); epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", outFile,outFile); portable_sysTimerStart(); if (portable_system("epstopdf",epstopdfArgs)!=0) { err("Problems running epstopdf. Check your TeX installation!\n"); } portable_sysTimerStop(); } Doxygen::indexList->addImageFile(imgName); error: QDir::setCurrent(oldDir); } QCString getMscImageMapFromFile(const QCString& inFile, const QCString& outDir, const QCString& relPath,const QCString& context) { QCString outFile = inFile + ".map"; //printf("*** running:getMscImageMapFromFile \n"); // chdir to the output dir, so dot can find the font file. QCString oldDir = QDir::currentDirPath().utf8(); // go to the html output directory (i.e. path) QDir::setCurrent(outDir); //printf("Going to dir %s\n",QDir::currentDirPath().data()); QCString mscExe = Config_getString(MSCGEN_PATH)+"mscgen"+portable_commandExtension(); QCString mscArgs = "-T ismap -i \""; mscArgs+=inFile; mscArgs+="\" -o \""; mscArgs+=outFile + "\""; int exitCode; portable_sysTimerStart(); if ((exitCode=portable_system(mscExe,mscArgs,FALSE))!=0) { portable_sysTimerStop(); QDir::setCurrent(oldDir); return ""; } portable_sysTimerStop(); QGString result; FTextStream tmpout(&result); convertMapFile(tmpout, outFile, relPath, context); QDir().remove(outFile); QDir::setCurrent(oldDir); return result.data(); } void writeMscImageMapFromFile(FTextStream &t,const QCString &inFile, const QCString &outDir, const QCString &relPath, const QCString &baseName, const QCString &context, MscOutputFormat format ) { QCString mapName = baseName+".map"; t << "\""" << endl; QCString imap = getMscImageMapFromFile(inFile,outDir,relPath,context); t << "" << imap << "" << endl; }