00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TClassDocOutput.h"
00013
00014 #include "TBaseClass.h"
00015 #include "TClassEdit.h"
00016 #include "TDataMember.h"
00017 #include "TMethodArg.h"
00018 #include "TDataType.h"
00019 #include "TDocInfo.h"
00020 #include "TDocParser.h"
00021 #include "TEnv.h"
00022 #include "TError.h"
00023 #include "THtml.h"
00024 #include "TMethod.h"
00025 #include "TROOT.h"
00026 #include "TSystem.h"
00027 #include "TVirtualPad.h"
00028 #include "TVirtualMutex.h"
00029 #include "Riostream.h"
00030 #include <sstream>
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 ClassImp(TClassDocOutput);
00047
00048
00049 TClassDocOutput::TClassDocOutput(THtml& html, TClass* cl, TList* typedefs):
00050 TDocOutput(html), fHierarchyLines(0), fCurrentClass(cl),
00051 fCurrentClassesTypedefs(typedefs), fParser(0)
00052 {
00053
00054
00055
00056 fParser = new TDocParser(*this, fCurrentClass);
00057 }
00058
00059
00060 TClassDocOutput::~TClassDocOutput()
00061 {
00062
00063 delete fParser;
00064 }
00065
00066
00067 void TClassDocOutput::Class2Html(Bool_t force)
00068 {
00069
00070
00071
00072 gROOT->GetListOfGlobals(kTRUE);
00073
00074
00075 TString filename(fCurrentClass->GetName());
00076 NameSpace2FileName(filename);
00077
00078 gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
00079
00080 filename += ".html";
00081
00082 if (!force && !IsModified(fCurrentClass, kSource)
00083 && !IsModified(fCurrentClass, kDoc)) {
00084 Printf(fHtml->GetCounterFormat(), "-no change-", fHtml->GetCounter(), filename.Data());
00085 return;
00086 }
00087
00088
00089 std::ofstream classFile(filename);
00090
00091 if (!classFile.good()) {
00092 Error("Make", "Can't open file '%s' !", filename.Data());
00093 return;
00094 }
00095
00096 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), filename.Data());
00097
00098
00099 WriteHtmlHeader(classFile, fCurrentClass->GetName(), "", fCurrentClass);
00100 WriteClassDocHeader(classFile);
00101
00102
00103 TString declf;
00104 if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declf))
00105 CopyHtmlFile(declf);
00106
00107
00108 fParser->Parse(classFile);
00109
00110
00111 WriteHtmlFooter(classFile, "",
00112 fParser->GetSourceInfo(TDocParser::kInfoLastUpdate),
00113 fParser->GetSourceInfo(TDocParser::kInfoAuthor),
00114 fParser->GetSourceInfo(TDocParser::kInfoCopyright));
00115 }
00116
00117
00118 void TClassDocOutput::ListFunctions(std::ostream& classFile)
00119 {
00120
00121
00122
00123
00124 classFile << endl << "<div id=\"functions\">" << endl;
00125 TString mangled(fCurrentClass->GetName());
00126 NameSpace2FileName(mangled);
00127 classFile << "<h2><a id=\"" << mangled
00128 << ":Function_Members\"></a>Function Members (Methods)</h2>" << endl;
00129
00130 const char* tab4nbsp=" ";
00131 TString declFile;
00132 fHtml->GetDeclFileName(fCurrentClass, kFALSE, declFile);
00133 if (fCurrentClass->Property() & kIsAbstract)
00134 classFile << " <br /><b>"
00135 << tab4nbsp << "This is an abstract class, constructors will not be documented.<br />" << endl
00136 << tab4nbsp << "Look at the <a href=\""
00137 << gSystem->BaseName(declFile)
00138 << "\">header</a> to check for available constructors.</b><br />" << endl;
00139
00140 Int_t minAccess = 0;
00141 if (fHtml->IsNamespace(fCurrentClass))
00142 minAccess = TDocParser::kPublic;
00143 for (Int_t access = TDocParser::kPublic; access >= minAccess; --access) {
00144
00145 const TList* methods = fParser->GetMethods((TDocParser::EAccess)access);
00146 if (methods->GetEntries() == 0)
00147 continue;
00148
00149 classFile << "<div class=\"access\" ";
00150 const char* accessID [] = {"priv", "prot", "publ"};
00151 const char* accesstxt[] = {"private", "protected", "public"};
00152
00153 classFile << "id=\"func" << accessID[access] << "\"><b>"
00154 << accesstxt[access] << ":</b>" << endl
00155 << "<table class=\"func\" id=\"tabfunc" << accessID[access] << "\" cellspacing=\"0\">" << endl;
00156
00157 TIter iMethWrap(methods);
00158 TDocMethodWrapper *methWrap = 0;
00159 while ((methWrap = (TDocMethodWrapper*) iMethWrap())) {
00160 const TMethod* method = methWrap->GetMethod();
00161
00162
00163 Bool_t isctor = (!strcmp(method->GetName(), method->GetReturnTypeName()));
00164
00165 Bool_t isdtor = (!isctor && method->GetName()[0] == '~');
00166
00167 classFile << "<tr class=\"func";
00168 if (method->GetClass() != fCurrentClass)
00169 classFile << "inh";
00170 classFile << "\"><td class=\"funcret\">";
00171 if (kIsVirtual & method->Property()) {
00172 if (!isdtor)
00173 classFile << "virtual ";
00174 else
00175 classFile << " virtual";
00176 }
00177
00178 if (kIsStatic & method->Property())
00179 classFile << "static ";
00180
00181 if (!isctor && !isdtor)
00182 fParser->DecorateKeywords(classFile, method->GetReturnTypeName());
00183
00184 TString mangledM(method->GetClass()->GetName());
00185 NameSpace2FileName(mangledM);
00186 classFile << "</td><td class=\"funcname\"><a class=\"funcname\" href=\"";
00187 if (method->GetClass() != fCurrentClass) {
00188 TString htmlFile;
00189 fHtml->GetHtmlFileName(method->GetClass(), htmlFile);
00190 classFile << htmlFile;
00191 }
00192 classFile << "#" << mangledM;
00193 classFile << ":";
00194 mangledM = method->GetName();
00195 NameSpace2FileName(mangledM);
00196 Int_t overloadIdx = methWrap->GetOverloadIdx();
00197 if (overloadIdx) {
00198 mangledM += "%";
00199 mangledM += overloadIdx;
00200 }
00201 classFile << mangledM << "\">";
00202 if (method->GetClass() != fCurrentClass) {
00203 classFile << "<span class=\"baseclass\">";
00204 ReplaceSpecialChars(classFile, method->GetClass()->GetName());
00205 classFile << "::</span>";
00206 }
00207 ReplaceSpecialChars(classFile, method->GetName());
00208 classFile << "</a>";
00209
00210 fParser->DecorateKeywords(classFile, const_cast<TMethod*>(method)->GetSignature());
00211 bool propSignal = false;
00212 bool propMenu = false;
00213 bool propToggle = false;
00214 bool propGetter = false;
00215 if (method->GetTitle()) {
00216 propSignal = (strstr(method->GetTitle(), "*SIGNAL*"));
00217 propMenu = (strstr(method->GetTitle(), "*MENU*"));
00218 propToggle = (strstr(method->GetTitle(), "*TOGGLE*"));
00219 propGetter = (strstr(method->GetTitle(), "*GETTER"));
00220 if (propSignal || propMenu || propToggle || propGetter) {
00221 classFile << "<span class=\"funcprop\">";
00222 if (propSignal) classFile << "<abbr title=\"emits a signal\">SIGNAL</abbr> ";
00223 if (propMenu) classFile << "<abbr title=\"has a popup menu entry\">MENU</abbr> ";
00224 if (propToggle) classFile << "<abbr title=\"toggles a state\">TOGGLE</abbr> ";
00225 if (propGetter) {
00226 TString getter(method->GetTitle());
00227 Ssiz_t posGetter = getter.Index("*GETTER=");
00228 getter.Remove(0, posGetter + 8);
00229 classFile << "<abbr title=\"use " + getter + "() as getter\">GETTER</abbr> ";
00230 }
00231 classFile << "</span>";
00232 }
00233 }
00234 classFile << "</td></tr>" << endl;
00235 }
00236 classFile << endl << "</table></div>" << endl;
00237 }
00238
00239 classFile << "</div>" << endl;
00240 }
00241
00242
00243 void TClassDocOutput::ListDataMembers(std::ostream& classFile)
00244 {
00245
00246
00247
00248 Bool_t haveDataMembers = (fParser->GetDataMembers(TDocParser::kPrivate)->GetEntries() ||
00249 fParser->GetDataMembers(TDocParser::kProtected)->GetEntries() ||
00250 fParser->GetDataMembers(TDocParser::kPublic)->GetEntries() ||
00251 fParser->GetEnums(TDocParser::kPublic)->GetEntries() ||
00252 fParser->GetEnums(TDocParser::kProtected)->GetEntries() ||
00253 fParser->GetEnums(TDocParser::kPrivate)->GetEntries());
00254
00255 if (!haveDataMembers) return;
00256
00257 classFile << endl << "<div id=\"datamembers\">" << endl;
00258 TString mangled(fCurrentClass->GetName());
00259 NameSpace2FileName(mangled);
00260 classFile << "<h2><a name=\"" << mangled
00261 << ":Data_Members\"></a>Data Members</h2>" << endl;
00262
00263 for (Int_t access = 5; access >= 0 && !fHtml->IsNamespace(fCurrentClass); --access) {
00264 const TList* datamembers = 0;
00265 if (access > 2) datamembers = fParser->GetEnums((TDocParser::EAccess) (access - 3));
00266 else datamembers = fParser->GetDataMembers((TDocParser::EAccess) access);
00267 if (datamembers->GetEntries() == 0)
00268 continue;
00269
00270 classFile << "<div class=\"access\" ";
00271 const char* what = "data";
00272 if (access > 2) what = "enum";
00273 const char* accessID [] = {"priv", "prot", "publ"};
00274 const char* accesstxt[] = {"private", "protected", "public"};
00275
00276 classFile << "id=\"" << what << accessID[access%3] << "\"><b>"
00277 << accesstxt[access%3] << ":</b>" << endl
00278 << "<table class=\"data\" id=\"tab" << what << accessID[access%3] << "\" cellspacing=\"0\">" << endl;
00279
00280 TIter iDM(datamembers);
00281 TDataMember *member = 0;
00282 TString prevEnumName;
00283 Bool_t prevIsInh = kTRUE;
00284
00285 while ((member = (TDataMember*) iDM())) {
00286 Bool_t haveNewEnum = access > 2 && prevEnumName != member->GetTypeName();
00287 if (haveNewEnum) {
00288 if (prevEnumName.Length()) {
00289 classFile << "<tr class=\"data";
00290 if (prevIsInh)
00291 classFile << "inh";
00292 classFile << "\"><td class=\"datatype\">};</td><td></td><td></td></tr>" << endl;
00293 }
00294 prevEnumName = member->GetTypeName();
00295 }
00296
00297 classFile << "<tr class=\"data";
00298 prevIsInh = (member->GetClass() != fCurrentClass);
00299 if (prevIsInh)
00300 classFile << "inh";
00301 classFile << "\"><td class=\"datatype\">";
00302 if (haveNewEnum) {
00303 TString enumName(member->GetTypeName());
00304 TString myScope(fCurrentClass->GetName());
00305 myScope += "::";
00306 enumName.ReplaceAll(myScope, "");
00307 if (enumName.EndsWith("::"))
00308 enumName += "<i>[unnamed]</i>";
00309 Ssiz_t startClassName = 0;
00310 if (!enumName.BeginsWith("enum "))
00311 classFile << "enum ";
00312 else
00313 startClassName = 5;
00314
00315 Ssiz_t endClassName = enumName.Last(':');
00316 if (endClassName != kNPOS && endClassName > 0 && enumName[endClassName - 1] == ':') {
00317
00318 TSubString substr(enumName(startClassName, endClassName - startClassName + 1));
00319
00320
00321 enumName.Insert(substr.Start() + substr.Length(), "</span>");
00322 enumName.Insert(substr.Start(), "<span class=\"baseclass\">");
00323 }
00324 classFile << enumName << " { ";
00325 } else
00326 if (access < 3) {
00327 if (member->Property() & G__BIT_ISSTATIC)
00328 classFile << "static ";
00329 std::string shortTypeName(fHtml->ShortType(member->GetFullTypeName()));
00330 fParser->DecorateKeywords(classFile, shortTypeName.c_str());
00331 }
00332
00333 TString mangledM(member->GetClass()->GetName());
00334 NameSpace2FileName(mangledM);
00335 classFile << "</td><td class=\"dataname\"><a ";
00336 if (member->GetClass() != fCurrentClass) {
00337 classFile << "href=\"";
00338 TString htmlFile;
00339 fHtml->GetHtmlFileName(member->GetClass(), htmlFile);
00340 classFile << htmlFile << "#";
00341 } else
00342 classFile << "name=\"";
00343 classFile << mangledM;
00344 classFile << ":";
00345 mangledM = member->GetName();
00346 NameSpace2FileName(mangledM);
00347 classFile << mangledM << "\">";
00348 if (member->GetClass() == fCurrentClass)
00349 classFile << "</a>";
00350 if (access < 3 && member->GetClass() != fCurrentClass) {
00351 classFile << "<span class=\"baseclass\">";
00352 ReplaceSpecialChars(classFile, member->GetClass()->GetName());
00353 classFile << "::</span>";
00354 }
00355 ReplaceSpecialChars(classFile, member->GetName());
00356
00357
00358 for (Int_t indx = 0; indx < member->GetArrayDim(); ++indx)
00359 if (member->GetMaxIndex(indx) <= 0)
00360 break;
00361 else
00362 classFile << "[" << member->GetMaxIndex(indx) << "]";
00363
00364 if (member->GetClass() != fCurrentClass)
00365 classFile << "</a>";
00366 classFile << "</td>";
00367 if (member->GetTitle() && member->GetTitle()[0]) {
00368 classFile << "<td class=\"datadesc\">";
00369 ReplaceSpecialChars(classFile, member->GetTitle());
00370 } else classFile << "<td>";
00371 classFile << "</td></tr>" << endl;
00372 }
00373
00374 if (prevEnumName.Length()) {
00375 classFile << "<tr class=\"data";
00376 if (prevIsInh)
00377 classFile << "inh";
00378 classFile << "\"><td class=\"datatype\">};</td><td></td><td></td></tr>" << endl;
00379 }
00380 classFile << endl << "</table></div>" << endl;
00381 }
00382
00383 classFile << "</div>" << endl;
00384 }
00385
00386
00387 Bool_t TClassDocOutput::ClassDotCharts(std::ostream& out)
00388 {
00389
00390
00391
00392
00393
00394
00395 if (!fHtml->HaveDot())
00396 return kFALSE;
00397
00398 TString title(fCurrentClass->GetName());
00399 NameSpace2FileName(title);
00400
00401 TString dir("inh");
00402 gSystem->PrependPathName(fHtml->GetOutputDir(), dir);
00403 gSystem->MakeDirectory(dir);
00404
00405 dir = "inhmem";
00406 gSystem->PrependPathName(fHtml->GetOutputDir(), dir);
00407 gSystem->MakeDirectory(dir);
00408
00409 dir = "incl";
00410 gSystem->PrependPathName(fHtml->GetOutputDir(), dir);
00411 gSystem->MakeDirectory(dir);
00412
00413 dir = "lib";
00414 gSystem->PrependPathName(fHtml->GetOutputDir(), dir);
00415 gSystem->MakeDirectory(dir);
00416
00417 TString filenameInh(title);
00418 gSystem->PrependPathName("inh", filenameInh);
00419 gSystem->PrependPathName(fHtml->GetOutputDir(), filenameInh);
00420 filenameInh += "_Inh";
00421 if (!CreateDotClassChartInh(filenameInh + ".dot") ||
00422 !RunDot(filenameInh, &out))
00423 return kFALSE;
00424
00425 TString filenameInhMem(title);
00426 gSystem->PrependPathName("inhmem", filenameInhMem);
00427 gSystem->PrependPathName(fHtml->GetOutputDir(), filenameInhMem);
00428 filenameInhMem += "_InhMem";
00429 if (CreateDotClassChartInhMem(filenameInhMem + ".dot"))
00430 RunDot(filenameInhMem, &out);
00431
00432 TString filenameIncl(title);
00433 gSystem->PrependPathName("incl", filenameIncl);
00434 gSystem->PrependPathName(fHtml->GetOutputDir(), filenameIncl);
00435 filenameIncl += "_Incl";
00436 if (CreateDotClassChartIncl(filenameIncl + ".dot"))
00437 RunDot(filenameIncl, &out);
00438
00439 TString filenameLib(title);
00440 gSystem->PrependPathName("lib", filenameLib);
00441 gSystem->PrependPathName(fHtml->GetOutputDir(), filenameLib);
00442 filenameLib += "_Lib";
00443 if (CreateDotClassChartLib(filenameLib + ".dot"))
00444 RunDot(filenameLib, &out);
00445
00446 out << "<div class=\"tabs\">" << endl
00447 << "<a id=\"img" << title << "_Inh\" class=\"tabsel\" href=\"inh/" << title << "_Inh.png\" onclick=\"javascript:return SetImg('Charts','inh/" << title << "_Inh.png');\">Inheritance</a>" << endl
00448 << "<a id=\"img" << title << "_InhMem\" class=\"tab\" href=\"inhmem/" << title << "_InhMem.png\" onclick=\"javascript:return SetImg('Charts','inhmem/" << title << "_InhMem.png');\">Inherited Members</a>" << endl
00449 << "<a id=\"img" << title << "_Incl\" class=\"tab\" href=\"incl/" << title << "_Incl.png\" onclick=\"javascript:return SetImg('Charts','incl/" << title << "_Incl.png');\">Includes</a>" << endl
00450 << "<a id=\"img" << title << "_Lib\" class=\"tab\" href=\"lib/" << title << "_Lib.png\" onclick=\"javascript:return SetImg('Charts','lib/" << title << "_Lib.png');\">Libraries</a><br/>" << endl
00451 << "</div><div class=\"classcharts\"><div class=\"classchartswidth\"></div>" << endl
00452 << "<img id=\"Charts\" alt=\"Class Charts\" class=\"classcharts\" usemap=\"#Map" << title << "_Inh\" src=\"inh/" << title << "_Inh.png\"/></div>" << endl;
00453
00454 return kTRUE;
00455 }
00456
00457
00458 void TClassDocOutput::ClassHtmlTree(std::ostream& out, TClass * classPtr,
00459 ETraverse dir, int depth)
00460 {
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 if (dir == kBoth) {
00471 out << "<!--INHERITANCE TREE-->" << endl;
00472
00473
00474 out << "<table><tr><td width=\"10%\"></td><td width=\"70%\">"
00475 << "<a href=\"ClassHierarchy.html\">Inheritance Chart</a>:</td></tr>";
00476 out << "<tr class=\"inhtree\"><td width=\"10%\"></td><td width=\"70%\">";
00477
00478 out << "<table class=\"inhtree\"><tr><td>" << endl;
00479 out << "<table width=\"100%\" border=\"0\" ";
00480 out << "cellpadding =\"0\" cellspacing=\"2\"><tr>" << endl;
00481 } else {
00482 out << "<table><tr>";
00483 }
00484
00485
00486
00487 if (dir == kUp || dir == kBoth) {
00488
00489
00490 TBaseClass *inheritFrom;
00491 TIter nextBase(classPtr->GetListOfBases());
00492
00493 UInt_t bgcolor=255-depth*8;
00494 Bool_t first = kTRUE;
00495 while ((inheritFrom = (TBaseClass *) nextBase())) {
00496
00497 if (first) {
00498 out << "<td><table><tr>" << endl;
00499 first = kFALSE;
00500 } else
00501 out << "</tr><tr>" << endl;
00502 out << "<td bgcolor=\""
00503 << Form("#%02x%02x%02x", bgcolor, bgcolor, bgcolor)
00504 << "\" align=\"right\">" << endl;
00505
00506 TClass *classInh = fHtml->GetClass((const char *) inheritFrom->GetName());
00507 if (classInh)
00508 ClassHtmlTree(out, classInh, kUp, depth+1);
00509 else
00510 out << "<tt>"
00511 << (const char *) inheritFrom->GetName()
00512 << "</tt>";
00513 out << "</td>"<< endl;
00514 }
00515 if (!first) {
00516 out << "</tr></table></td>" << endl;
00517 out << "<td>←</td>";
00518 }
00519 }
00520
00521 out << "<td>" << endl;
00522
00523
00524
00525 const char *className = classPtr->GetName();
00526 TString htmlFile;
00527 fHtml->GetHtmlFileName(classPtr, htmlFile);
00528 TString anchor(className);
00529 NameSpace2FileName(anchor);
00530
00531 if (dir == kUp) {
00532 if (htmlFile) {
00533 out << "<center><tt><a name=\"" << anchor;
00534 out << "\" href=\"" << htmlFile << "\">";
00535 ReplaceSpecialChars(out, className);
00536 out << "</a></tt></center>" << endl;
00537 } else
00538 ReplaceSpecialChars(out, className);
00539 }
00540
00541 if (dir == kBoth) {
00542 if (htmlFile.Length()) {
00543 out << "<center><big><b><tt><a name=\"" << anchor;
00544 out << "\" href=\"" << htmlFile << "\">";
00545 ReplaceSpecialChars(out, className);
00546 out << "</a></tt></b></big></center>" << endl;
00547 } else
00548 ReplaceSpecialChars(out, className);
00549 }
00550
00551 out << "</td>" << endl;
00552
00553
00554
00555
00556 if (dir == kDown || dir == kBoth) {
00557
00558
00559
00560
00561 out << "<td><table><tr>" << endl;
00562 fHierarchyLines = 0;
00563 DescendHierarchy(out,classPtr,10);
00564
00565 out << "</tr></table>";
00566 if (dir==kBoth && fHierarchyLines>=10)
00567 out << "</td><td align=\"left\"> <a href=\"ClassHierarchy.html\">[more...]</a>";
00568 out<<"</td>" << endl;
00569
00570
00571 }
00572
00573 out << "</tr></table>" << endl;
00574 if (dir == kBoth)
00575 out << "</td></tr></table></td></tr></table>"<<endl;
00576 }
00577
00578
00579
00580 void TClassDocOutput::ClassTree(TVirtualPad * psCanvas, Bool_t force)
00581 {
00582
00583
00584
00585
00586
00587
00588
00589 if (!psCanvas || !fCurrentClass)
00590 return;
00591
00592 TString filename(fCurrentClass->GetName());
00593 NameSpace2FileName(filename);
00594
00595 gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
00596
00597
00598 filename += "_Tree.pdf";
00599
00600 if (IsModified(fCurrentClass, kTree) || force) {
00601
00602
00603 fCurrentClass->Draw("same");
00604 Int_t saveErrorIgnoreLevel = gErrorIgnoreLevel;
00605 gErrorIgnoreLevel = kWarning;
00606 psCanvas->SaveAs(filename);
00607 gErrorIgnoreLevel = saveErrorIgnoreLevel;
00608 } else
00609 Printf(fHtml->GetCounterFormat(), "-no change-", "", filename.Data());
00610 }
00611
00612
00613 Bool_t TClassDocOutput::CreateDotClassChartInh(const char* filename)
00614 {
00615
00616
00617
00618
00619
00620 std::ofstream outdot(filename);
00621 outdot << "strict digraph G {" << endl
00622 << "rankdir=RL;" << endl
00623 << "ranksep=2;" << endl
00624 << "nodesep=0;" << endl
00625 << "size=\"8,10\";" << endl
00626 << "ratio=auto;" << endl
00627 << "margin=0;" << endl
00628 << "node [shape=plaintext,fontsize=40,width=4,height=0.75];" << endl
00629 << "\"" << fCurrentClass->GetName() << "\" [shape=ellipse];" << endl;
00630
00631 std::stringstream ssDep;
00632 std::list<TClass*> writeBasesFor;
00633 writeBasesFor.push_back(fCurrentClass);
00634 Bool_t haveBases = fCurrentClass->GetListOfBases() &&
00635 fCurrentClass->GetListOfBases()->GetSize();
00636 if (haveBases) {
00637 outdot << "{" << endl;
00638 while (!writeBasesFor.empty()) {
00639 TClass* cl = writeBasesFor.front();
00640 writeBasesFor.pop_front();
00641 if (cl != fCurrentClass) {
00642 outdot << " \"" << cl->GetName() << "\"";
00643 const char* htmlFileName = fHtml->GetHtmlFileName(cl->GetName());
00644 if (htmlFileName)
00645 outdot << " [URL=\"" << htmlFileName << "\"]";
00646 outdot << ";" << endl;
00647 }
00648 if (cl->GetListOfBases() && cl->GetListOfBases()->GetSize()) {
00649 ssDep << " \"" << cl->GetName() << "\" -> {";
00650 TIter iBase(cl->GetListOfBases());
00651 TBaseClass* base = 0;
00652 while ((base = (TBaseClass*)iBase())) {
00653 ssDep << " \"" << base->GetName() << "\";";
00654 writeBasesFor.push_back(base->GetClassPointer());
00655 }
00656 ssDep << "}" << endl;
00657 }
00658 }
00659 outdot << "}" << endl;
00660 }
00661
00662 std::map<TClass*, Int_t> derivesFromMe;
00663 std::map<TClass*, unsigned int> entriesPerDerived;
00664 std::set<TClass*> wroteNode;
00665 wroteNode.insert(fCurrentClass);
00666 static const unsigned int maxClassesPerDerived = 20;
00667 fHtml->GetDerivedClasses(fCurrentClass, derivesFromMe);
00668 outdot << "{" << endl;
00669 for (Int_t level = 1; kTRUE; ++level) {
00670 Bool_t levelExists = kFALSE;
00671 for (std::map<TClass*, Int_t>::iterator iDerived = derivesFromMe.begin();
00672 iDerived != derivesFromMe.end(); ++iDerived) {
00673 if (iDerived->second != level) continue;
00674 levelExists = kTRUE;
00675 TIter iBaseOfDerived(iDerived->first->GetListOfBases());
00676 TBaseClass* baseDerived = 0;
00677 Bool_t writeNode = kFALSE;
00678 TClass* writeAndMoreFor = 0;
00679 while ((baseDerived = (TBaseClass*) iBaseOfDerived())) {
00680 TClass* clBaseDerived = baseDerived->GetClassPointer();
00681 if (clBaseDerived->InheritsFrom(fCurrentClass)
00682 && wroteNode.find(clBaseDerived) != wroteNode.end()) {
00683 unsigned int& count = entriesPerDerived[clBaseDerived];
00684 if (count < maxClassesPerDerived) {
00685 writeNode = kTRUE;
00686 ssDep << "\"" << iDerived->first->GetName() << "\" -> \""
00687 << clBaseDerived->GetName() << "\";" << endl;
00688 ++count;
00689 } else if (count == maxClassesPerDerived) {
00690 writeAndMoreFor = clBaseDerived;
00691 ssDep << "\"...andmore" << clBaseDerived->GetName() << "\"-> \""
00692 << clBaseDerived->GetName() << "\";" << endl;
00693 ++count;
00694 }
00695 }
00696 }
00697
00698 if (writeNode) {
00699 wroteNode.insert(iDerived->first);
00700 outdot << " \"" << iDerived->first->GetName() << "\"";
00701 const char* htmlFileName = fHtml->GetHtmlFileName(iDerived->first->GetName());
00702 if (htmlFileName)
00703 outdot << " [URL=\"" << htmlFileName << "\"]";
00704 outdot << ";" << endl;
00705 } else if (writeAndMoreFor) {
00706 outdot << " \"...andmore" << writeAndMoreFor->GetName()
00707 << "\" [label=\"...and more\",fontname=\"Times-Italic\",fillcolor=lightgrey,style=filled];" << endl;
00708 }
00709 }
00710 if (!levelExists) break;
00711 }
00712 outdot << "}" << endl;
00713
00714 outdot << ssDep.str();
00715
00716 outdot << "}" << endl;
00717
00718 return kTRUE;
00719 }
00720
00721
00722 Bool_t TClassDocOutput::CreateDotClassChartInhMem(const char* filename) {
00723
00724
00725
00726
00727 std::ofstream outdot(filename);
00728 outdot << "strict digraph G {" << endl
00729 << "ratio=auto;" << endl
00730 << "rankdir=RL;" << endl
00731 << "compound=true;" << endl
00732 << "constraint=false;" << endl
00733 << "ranksep=0.1;" << endl
00734 << "nodesep=0;" << endl
00735 << "margin=0;" << endl;
00736 outdot << " node [style=filled,width=0.7,height=0.15,fixedsize=true,shape=plaintext,fontsize=10];" << endl;
00737
00738 std::stringstream ssDep;
00739 const int numColumns = 3;
00740
00741 std::list<TClass*> writeBasesFor;
00742 writeBasesFor.push_back(fCurrentClass);
00743 while (!writeBasesFor.empty()) {
00744 TClass* cl = writeBasesFor.front();
00745 writeBasesFor.pop_front();
00746
00747 const char* htmlFileName = fHtml->GetHtmlFileName(cl->GetName());
00748
00749 outdot << "subgraph \"cluster" << cl->GetName() << "\" {" << endl
00750 << " color=lightgray;" << endl
00751 << " label=\"" << cl->GetName() << "\";" << endl;
00752 if (cl != fCurrentClass && htmlFileName)
00753 outdot << " URL=\"" << htmlFileName << "\"" << endl;
00754
00755
00756 Bool_t haveFuncs = cl->GetListOfMethods() && cl->GetListOfMethods()->GetSize();
00757
00758
00759 {
00760
00761
00762 std::map<std::string, TDataMember*> dmMap;
00763
00764 {
00765 TIter iDM(cl->GetListOfDataMembers());
00766 TDataMember* dm = 0;
00767 while ((dm = (TDataMember*) iDM()))
00768 dmMap[dm->GetName()] = dm;
00769 }
00770
00771 outdot << "subgraph \"clusterData0" << cl->GetName() << "\" {" << endl
00772 << " color=white;" << endl
00773 << " label=\"\";" << endl
00774 << " \"clusterNode0" << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
00775 TString prevColumnNode;
00776 Int_t pos = dmMap.size();
00777 Int_t column = 0;
00778 Int_t newColumnEvery = (pos + numColumns - 1) / numColumns;
00779 for (std::map<std::string, TDataMember*>::iterator iDM = dmMap.begin();
00780 iDM != dmMap.end(); ++iDM, --pos) {
00781 TDataMember* dm = iDM->second;
00782 TString nodeName(cl->GetName());
00783 nodeName += "::";
00784 nodeName += dm->GetName();
00785 if (iDM == dmMap.begin())
00786 prevColumnNode = nodeName;
00787
00788 outdot << "\"" << nodeName << "\" [label=\""
00789 << dm->GetName() << "\"";
00790 if (dm->Property() & kIsPrivate)
00791 outdot << ",color=\"#FFCCCC\"";
00792 else if (dm->Property() & kIsProtected)
00793 outdot << ",color=\"#FFFF77\"";
00794 else
00795 outdot << ",color=\"#CCFFCC\"";
00796 outdot << "];" << endl;
00797 if (pos % newColumnEvery == 1) {
00798 ++column;
00799 outdot << "};" << endl
00800 << "subgraph \"clusterData" << column << cl->GetName() << "\" {" << endl
00801 << " color=white;" << endl
00802 << " label=\"\";" << endl
00803 << " \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
00804 } else if (iDM != dmMap.begin() && pos % newColumnEvery == 0) {
00805 ssDep << "\"" << prevColumnNode
00806 << "\" -> \"" << nodeName << "\""<< " [style=invis,weight=100];" << endl;
00807 prevColumnNode = nodeName;
00808 }
00809 }
00810
00811 while (column < numColumns - 1) {
00812 ++column;
00813 outdot << " \"clusterNode" << column << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
00814 }
00815
00816 outdot << "};" << endl;
00817 }
00818
00819
00820 if (haveFuncs) {
00821
00822 std::map<std::string, TMethod*> methMap;
00823
00824 {
00825 TIter iMeth(cl->GetListOfMethods());
00826 TMethod* meth = 0;
00827 while ((meth = (TMethod*) iMeth()))
00828 methMap[meth->GetName()] = meth;
00829 }
00830
00831 outdot << "subgraph \"clusterFunc0" << cl->GetName() << "\" {" << endl
00832 << " color=white;" << endl
00833 << " label=\"\";" << endl
00834 << " \"clusterNode0" << cl->GetName() << "\" [height=0,width=0,style=invis];" << endl;
00835
00836 TString prevColumnNodeFunc;
00837 Int_t pos = methMap.size();
00838 Int_t column = 0;
00839 Int_t newColumnEvery = (pos + numColumns - 1) / numColumns;
00840 for (std::map<std::string, TMethod*>::iterator iMeth = methMap.begin();
00841 iMeth != methMap.end(); ++iMeth, --pos) {
00842 TMethod* meth = iMeth->second;
00843 TString nodeName(cl->GetName());
00844 nodeName += "::";
00845 nodeName += meth->GetName();
00846 if (iMeth == methMap.begin())
00847 prevColumnNodeFunc = nodeName;
00848
00849 outdot << "\"" << nodeName << "\" [label=\"" << meth->GetName() << "\"";
00850 if (cl != fCurrentClass &&
00851 fCurrentClass->GetMethodAny(meth->GetName()))
00852 outdot << ",color=\"#777777\"";
00853 else if (meth->Property() & kIsPrivate)
00854 outdot << ",color=\"#FFCCCC\"";
00855 else if (meth->Property() & kIsProtected)
00856 outdot << ",color=\"#FFFF77\"";
00857 else
00858 outdot << ",color=\"#CCFFCC\"";
00859 outdot << "];" << endl;
00860 if (pos % newColumnEvery == 1) {
00861 ++column;
00862 outdot << "};" << endl
00863 << "subgraph \"clusterFunc" << column << cl->GetName() << "\" {" << endl
00864 << " color=white;" << endl
00865 << " label=\"\";" << endl;
00866 } else if (iMeth != methMap.begin() && pos % newColumnEvery == 0) {
00867 ssDep << "\"" << prevColumnNodeFunc
00868 << "\" -> \"" << nodeName << "\""<< " [style=invis,weight=100];" << endl;
00869 prevColumnNodeFunc = nodeName;
00870 }
00871 }
00872 outdot << "};" << endl;
00873 }
00874
00875 outdot << "}" << endl;
00876
00877 for (Int_t pos = 0; pos < numColumns - 1; ++pos)
00878 ssDep << "\"clusterNode" << pos << cl->GetName() << "\" -> \"clusterNode" << pos + 1 << cl->GetName() << "\" [style=invis];" << endl;
00879
00880 if (cl->GetListOfBases() && cl->GetListOfBases()->GetSize()) {
00881 TIter iBase(cl->GetListOfBases());
00882 TBaseClass* base = 0;
00883 while ((base = (TBaseClass*)iBase())) {
00884 ssDep << " \"clusterNode" << numColumns - 1 << cl->GetName() << "\" -> "
00885 << " \"clusterNode0" << base->GetName() << "\" [ltail=\"cluster" << cl->GetName()
00886 << "\",lhead=\"cluster" << base->GetName() << "\"";
00887 if (base != cl->GetListOfBases()->First())
00888 ssDep << ",weight=0";
00889 ssDep << "];" << endl;
00890 writeBasesFor.push_back(base->GetClassPointer());
00891 }
00892 }
00893 }
00894
00895 outdot << ssDep.str();
00896
00897 outdot << "}" << endl;
00898
00899 return kTRUE;
00900 }
00901
00902
00903 Bool_t TClassDocOutput::CreateDotClassChartIncl(const char* filename) {
00904
00905
00906
00907
00908
00909 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
00910
00911 std::map<std::string, std::string> filesToParse;
00912 std::list<std::string> listFilesToParse;
00913 TString declFileName;
00914 TString implFileName;
00915 fHtml->GetImplFileName(fCurrentClass, kFALSE, implFileName);
00916 if (fHtml->GetDeclFileName(fCurrentClass, kFALSE, declFileName)) {
00917 TString real;
00918 if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, real)) {
00919 filesToParse[declFileName.Data()] = real.Data();
00920 listFilesToParse.push_back(declFileName.Data());
00921 }
00922 }
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 std::ofstream outdot(filename);
00935 outdot << "strict digraph G {" << endl
00936 << "ratio=compress;" << endl
00937 << "rankdir=TB;" << endl
00938 << "concentrate=true;" << endl
00939 << "ranksep=0;" << endl
00940 << "nodesep=0;" << endl
00941 << "size=\"8,10\";" << endl
00942 << "node [fontsize=20,shape=plaintext];" << endl;
00943
00944 for (std::list<std::string>::iterator iFile = listFilesToParse.begin();
00945 iFile != listFilesToParse.end(); ++iFile) {
00946 ifstream in(filesToParse[*iFile].c_str());
00947 std::string line;
00948 while (in && !in.eof()) {
00949 std::getline(in, line);
00950 size_t pos = 0;
00951 while (line[pos] == ' ' || line[pos] == '\t') ++pos;
00952 if (line[pos] != '#') continue;
00953 ++pos;
00954 while (line[pos] == ' ' || line[pos] == '\t') ++pos;
00955 if (line.compare(pos, 8, "include ") != 0) continue;
00956 pos += 8;
00957 while (line[pos] == ' ' || line[pos] == '\t') ++pos;
00958 if (line[pos] != '"' && line[pos] != '<')
00959 continue;
00960 char delim = line[pos];
00961 if (delim == '<') delim = '>';
00962 ++pos;
00963 line.erase(0, pos);
00964 pos = 0;
00965 pos = line.find(delim);
00966 if (pos == std::string::npos) continue;
00967 line.erase(pos);
00968 if (filesToParse.find(line) == filesToParse.end()) {
00969 TString sysfilename;
00970 if (!GetHtml()->GetPathDefinition().GetFileNameFromInclude(line.c_str(), sysfilename))
00971 continue;
00972 listFilesToParse.push_back(line);
00973 filesToParse[line] = sysfilename;
00974 if (*iFile == implFileName.Data() || *iFile == declFileName.Data())
00975 outdot << "\"" << *iFile << "\" [style=filled,fillcolor=lightgray];" << endl;
00976 }
00977 outdot << "\"" << *iFile << "\" -> \"" << line << "\";" << endl;
00978 }
00979 }
00980
00981 outdot << "}" << endl;
00982
00983 return kTRUE;
00984 }
00985
00986
00987 Bool_t TClassDocOutput::CreateDotClassChartLib(const char* filename) {
00988
00989
00990
00991
00992
00993 std::ofstream outdot(filename);
00994 outdot << "strict digraph G {" << endl
00995 << "ratio=auto;" << endl
00996 << "rankdir=RL;" << endl
00997 << "compound=true;" << endl
00998 << "constraint=false;" << endl
00999 << "ranksep=0.7;" << endl
01000 << "nodesep=0.3;" << endl
01001 << "size=\"8,8\";" << endl
01002 << "ratio=compress;" << endl;
01003
01004 TString libs(fCurrentClass->GetSharedLibs());
01005 outdot << "\"All Libraries\" [URL=\"LibraryDependencies.html\",shape=box,rank=max,fillcolor=lightgray,style=filled];" << endl;
01006
01007 if (libs.Length()) {
01008 TString firstLib(libs);
01009 Ssiz_t end = firstLib.Index(' ');
01010 if (end != kNPOS) {
01011 firstLib.Remove(end, firstLib.Length());
01012 libs.Remove(0, end + 1);
01013 } else libs = "";
01014
01015 {
01016 Ssiz_t posExt = firstLib.First(".");
01017 if (posExt != kNPOS)
01018 firstLib.Remove(posExt, firstLib.Length());
01019 }
01020
01021 outdot << "\"All Libraries\" -> \"" << firstLib << "\" [style=invis];" << endl;
01022 outdot << "\"" << firstLib << "\" -> {" << endl;
01023
01024 if (firstLib != "libCore")
01025 libs += " libCore";
01026 if (firstLib != "libCint")
01027 libs += " libCint";
01028 TString thisLib;
01029 for (Ssiz_t pos = 0; pos < libs.Length(); ++pos)
01030 if (libs[pos] != ' ')
01031 thisLib += libs[pos];
01032 else if (thisLib.Length()) {
01033 Ssiz_t posExt = thisLib.First(".");
01034 if (posExt != kNPOS)
01035 thisLib.Remove(posExt, thisLib.Length());
01036 outdot << " \"" << thisLib << "\";";
01037 thisLib = "";
01038 }
01039
01040 if (thisLib.Length()) {
01041 Ssiz_t posExt = thisLib.First(".");
01042 if (posExt != kNPOS)
01043 thisLib.Remove(posExt, thisLib.Length());
01044 outdot << " \"" << thisLib << "\";";
01045 thisLib = "";
01046 }
01047 outdot << "}" << endl;
01048 } else
01049 outdot << "\"No rlibmap information avaliable.\"" << endl;
01050
01051 outdot << "}" << endl;
01052
01053 return kTRUE;
01054 }
01055
01056
01057 void TClassDocOutput::CreateClassHierarchy(std::ostream& out, const char* docFileName)
01058 {
01059
01060
01061
01062
01063
01064 TList *bases = fCurrentClass->GetListOfBases();
01065 if (!bases || bases->IsEmpty())
01066 return;
01067
01068 out << "<hr />" << endl;
01069
01070 out << "<table><tr><td><ul><li><tt>";
01071 if (docFileName) {
01072 out << "<a name=\"" << fCurrentClass->GetName() << "\" href=\""
01073 << docFileName << "\">";
01074 ReplaceSpecialChars(out, fCurrentClass->GetName());
01075 out << "</a>";
01076 } else {
01077 ReplaceSpecialChars(out, fCurrentClass->GetName());
01078 }
01079
01080
01081 out << "</tt></li></ul></td>";
01082 fHierarchyLines = 0;
01083 DescendHierarchy(out, fCurrentClass);
01084
01085 out << "</tr></table>" << endl;
01086 }
01087
01088
01089 Bool_t TClassDocOutput::CreateHierarchyDot()
01090 {
01091
01092
01093
01094
01095
01096
01097 const char* title = "ClassHierarchy";
01098 TString filename(title);
01099 gSystem->PrependPathName(fHtml->GetOutputDir(), filename);
01100
01101
01102 std::ofstream dotout(filename + ".dot");
01103
01104 if (!dotout.good()) {
01105 Error("CreateHierarchy", "Can't open file '%s.dot' !",
01106 filename.Data());
01107 return kFALSE;
01108 }
01109
01110 dotout << "digraph G {" << endl
01111 << "ratio=auto;" << endl
01112 << "rankdir=RL;" << endl;
01113
01114
01115 TClassDocInfo* cdi = 0;
01116 TIter iClass(fHtml->GetListOfClasses());
01117 while ((cdi = (TClassDocInfo*)iClass())) {
01118
01119 TDictionary *dict = cdi->GetClass();
01120 TClass *cl = dynamic_cast<TClass*>(dict);
01121 if (cl == 0) {
01122 if (!dict)
01123 Warning("THtml::CreateHierarchy", "skipping class %s\n", cdi->GetName());
01124 continue;
01125 }
01126
01127
01128 TList *bases = cl->GetListOfBases();
01129 if (bases && !bases->IsEmpty()) {
01130 dotout << "\"" << cdi->GetName() << "\" -> { ";
01131 TIter iBase(bases);
01132 TBaseClass* base = 0;
01133 while ((base = (TBaseClass*) iBase())) {
01134
01135 if (base != bases->First())
01136 dotout << "; ";
01137 dotout << "\"" << base->GetName() << "\"";
01138 }
01139 dotout << "};" << endl;
01140 } else
01141
01142 dotout << "\"" << cdi->GetName() << "\";" << endl;
01143
01144 }
01145
01146 dotout << "}";
01147 dotout.close();
01148
01149 std::ofstream out(filename + ".html");
01150 if (!out.good()) {
01151 Error("CreateHierarchy", "Can't open file '%s.html' !",
01152 filename.Data());
01153 return kFALSE;
01154 }
01155
01156 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), (filename + ".html").Data());
01157
01158 WriteHtmlHeader(out, "Class Hierarchy");
01159 out << "<h1>Class Hierarchy</h1>" << endl;
01160
01161 WriteSearch(out);
01162
01163 RunDot(filename, &out);
01164
01165 out << "<img usemap=\"#Map" << title << "\" src=\"" << title << ".png\"/>" << endl;
01166
01167 WriteHtmlFooter(out);
01168 return kTRUE;
01169 }
01170
01171
01172 void TClassDocOutput::CreateSourceOutputStream(std::ostream& out, const char* extension,
01173 TString& sourceHtmlFileName)
01174 {
01175
01176
01177
01178 TString sourceHtmlDir("src");
01179 gSystem->PrependPathName(fHtml->GetOutputDir(), sourceHtmlDir);
01180
01181 {
01182 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
01183
01184 if (gSystem->AccessPathName(sourceHtmlDir))
01185 gSystem->MakeDirectory(sourceHtmlDir);
01186 }
01187 sourceHtmlFileName = fCurrentClass->GetName();
01188 NameSpace2FileName(sourceHtmlFileName);
01189 gSystem->PrependPathName(sourceHtmlDir, sourceHtmlFileName);
01190 sourceHtmlFileName += extension;
01191 dynamic_cast<std::ofstream&>(out).open(sourceHtmlFileName);
01192 if (!out) {
01193 Warning("LocateMethodsInSource", "Can't open beautified source file '%s' for writing!",
01194 sourceHtmlFileName.Data());
01195 sourceHtmlFileName.Remove(0);
01196 return;
01197 }
01198
01199
01200 TString title(fCurrentClass->GetName());
01201 title += " - source file";
01202 WriteHtmlHeader(out, title, "../", fCurrentClass);
01203 out << "<div id=\"codeAndLineNumbers\"><pre class=\"listing\">" << std::endl;
01204 }
01205
01206
01207 void TClassDocOutput::DescendHierarchy(std::ostream& out, TClass* basePtr, Int_t maxLines, Int_t depth)
01208 {
01209
01210
01211
01212 if (maxLines)
01213 if (fHierarchyLines >= maxLines) {
01214 out << "<td></td>" << endl;
01215 return;
01216 }
01217
01218 UInt_t numClasses = 0;
01219
01220 TClassDocInfo* cdi = 0;
01221 TIter iClass(fHtml->GetListOfClasses());
01222 while ((cdi = (TClassDocInfo*)iClass()) && (!maxLines || fHierarchyLines<maxLines)) {
01223
01224 TClass *classPtr = dynamic_cast<TClass*>(cdi->GetClass());
01225 if (!classPtr) continue;
01226
01227
01228 TList* bases=classPtr->GetListOfBases();
01229 if (!bases) continue;
01230
01231 TBaseClass *inheritFrom=(TBaseClass*)bases->FindObject(basePtr->GetName());
01232 if (!inheritFrom) continue;
01233
01234 if (!numClasses)
01235 out << "<td>←</td><td><table><tr>" << endl;
01236 else
01237 out << "</tr><tr>"<<endl;
01238 fHierarchyLines++;
01239 numClasses++;
01240 UInt_t bgcolor=255-depth*8;
01241 out << "<td bgcolor=\""
01242 << Form("#%02x%02x%02x", bgcolor, bgcolor, bgcolor)
01243 << "\">";
01244 out << "<table><tr><td>" << endl;
01245
01246 TString htmlFile(cdi->GetHtmlFileName());
01247 if (htmlFile.Length()) {
01248 out << "<center><tt><a name=\"" << cdi->GetName() << "\" href=\""
01249 << htmlFile << "\">";
01250 ReplaceSpecialChars(out, cdi->GetName());
01251 out << "</a></tt></center>";
01252 } else {
01253 ReplaceSpecialChars(out, cdi->GetName());
01254 }
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270 out << "</td>" << endl;
01271 DescendHierarchy(out,classPtr,maxLines, depth+1);
01272 out << "</tr></table></td>" << endl;
01273
01274 }
01275 if (numClasses)
01276 out << "</tr></table></td>" << endl;
01277 else
01278 out << "<td></td>" << endl;
01279 }
01280
01281
01282 void TClassDocOutput::MakeTree(Bool_t force )
01283 {
01284
01285
01286
01287
01288
01289
01290 if (!fCurrentClass || fHtml->HaveDot())
01291 return;
01292
01293 TString htmlFile;
01294 fHtml->GetHtmlFileName(fCurrentClass, htmlFile);
01295 if (htmlFile.Length()
01296 && (htmlFile.BeginsWith("http://")
01297 || htmlFile.BeginsWith("https://")
01298 || gSystem->IsAbsoluteFileName(htmlFile))
01299 ) {
01300 htmlFile.Remove(0);
01301 }
01302
01303 if (!htmlFile.Length()) {
01304 TString what(fCurrentClass->GetName());
01305 what += " (source not found)";
01306 Printf(fHtml->GetCounterFormat(), "-skipped-", "", what.Data());
01307 return;
01308 }
01309
01310 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
01311
01312
01313 Bool_t wasBatch = gROOT->IsBatch();
01314 if (!wasBatch)
01315 gROOT->SetBatch();
01316 TVirtualPad *psCanvas = (TVirtualPad*)gROOT->ProcessLineFast("new TCanvas(\"R__THtml\",\"psCanvas\",0,0,1000,1200);");
01317 if (!wasBatch)
01318 gROOT->SetBatch(kFALSE);
01319
01320 if (!psCanvas) {
01321 Error("MakeTree", "Cannot create a TCanvas!");
01322 return;
01323 }
01324
01325
01326 ClassTree(psCanvas, force);
01327
01328 psCanvas->Close();
01329 delete psCanvas;
01330 }
01331
01332
01333 void TClassDocOutput::WriteClassDescription(std::ostream& out, const TString& description)
01334 {
01335
01336
01337
01338
01339
01340
01341
01342
01343 out << "<div class=\"dropshadow\"><div class=\"withshadow\">";
01344 TString anchor(fCurrentClass->GetName());
01345 NameSpace2FileName(anchor);
01346 out << "<h1><a name=\"" << anchor;
01347 out << ":description\"></a>";
01348
01349 if (fHtml->IsNamespace(fCurrentClass))
01350 out << "namespace ";
01351 else
01352 out << "class ";
01353 ReplaceSpecialChars(out, fCurrentClass->GetName());
01354
01355
01356
01357 Bool_t first = kTRUE;
01358 TBaseClass *inheritFrom;
01359 TIter nextBase(fCurrentClass->GetListOfBases());
01360
01361 while ((inheritFrom = (TBaseClass *) nextBase())) {
01362 if (first) {
01363 out << ": ";
01364 first = kFALSE;
01365 } else
01366 out << ", ";
01367 Long_t property = inheritFrom->Property();
01368 if (property & kIsPrivate)
01369 out << "private ";
01370 else if (property & kIsProtected)
01371 out << "protected ";
01372 else
01373 out << "public ";
01374
01375
01376 TClass *classInh = fHtml->GetClass(inheritFrom->GetName());
01377
01378 TString htmlFile;
01379 fHtml->GetHtmlFileName(classInh, htmlFile);
01380
01381 if (htmlFile.Length()) {
01382
01383 out << "<a href=\"" << htmlFile << "\">";
01384 ReplaceSpecialChars(out, inheritFrom->GetName());
01385 out << "</a>";
01386 } else
01387 ReplaceSpecialChars(out, inheritFrom->GetName());
01388 }
01389 out << "</h1>" << endl;
01390
01391 out << "<div class=\"classdescr\">" << endl;
01392
01393 if (description.Length())
01394 out << "<pre>" << description << "</pre>";
01395
01396
01397 if (fCurrentClassesTypedefs && !fCurrentClassesTypedefs->IsEmpty()) {
01398 out << "<h4>This class is also known as (typedefs to this class)</h4>";
01399 TIter iTD(fCurrentClassesTypedefs);
01400 bool firsttd = true;
01401 TDataType* dt = 0;
01402 while ((dt = (TDataType*) iTD())) {
01403 if (!firsttd)
01404 out << ", ";
01405 else firsttd = false;
01406 fParser->DecorateKeywords(out, dt->GetName());
01407 }
01408 }
01409
01410 out << "</div>" << std::endl
01411 << "</div></div>" << std::endl;
01412
01413 ListFunctions(out);
01414 ListDataMembers(out);
01415
01416
01417 out << "<h2><a id=\"" << anchor
01418 << ":Class_Charts\"></a>Class Charts</h2>" << endl;
01419 if (!fHtml->IsNamespace(fCurrentClass))
01420 if (!ClassDotCharts(out))
01421 ClassHtmlTree(out, fCurrentClass);
01422
01423
01424 out << "<h2>Function documentation</h2>" << endl;
01425 }
01426
01427
01428
01429 void TClassDocOutput::WriteClassDocHeader(std::ostream& classFile)
01430 {
01431
01432
01433 classFile << "<a name=\"TopOfPage\"></a>" << endl;
01434
01435
01436
01437
01438 TString sTitle(fCurrentClass->GetName());
01439 ReplaceSpecialChars(sTitle);
01440 if (fHtml->IsNamespace(fCurrentClass))
01441 sTitle.Prepend("namespace ");
01442 else
01443 sTitle.Prepend("class ");
01444
01445 TString sInclude;
01446 TString sLib;
01447 const char* lib=fCurrentClass->GetSharedLibs();
01448 GetHtml()->GetPathDefinition().GetIncludeAs(fCurrentClass, sInclude);
01449 if (lib) {
01450 char* libDup=StrDup(lib);
01451 char* libDupSpace=strchr(libDup,' ');
01452 if (libDupSpace) *libDupSpace=0;
01453 char* libDupEnd=libDup+strlen(libDup);
01454 while (libDupEnd!=libDup)
01455 if (*(--libDupEnd)=='.') {
01456 *libDupEnd=0;
01457 break;
01458 }
01459 sLib = libDup;
01460 delete[] libDup;
01461 }
01462 classFile << "<script type=\"text/javascript\">WriteFollowPageBox('"
01463 << sTitle << "','" << sLib << "','" << sInclude << "');</script>" << endl;
01464
01465 TString modulename;
01466 fHtml->GetModuleNameForClass(modulename, fCurrentClass);
01467 TModuleDocInfo* module = (TModuleDocInfo*) fHtml->GetListOfModules()->FindObject(modulename);
01468 WriteTopLinks(classFile, module, fCurrentClass->GetName(), kFALSE);
01469
01470 classFile << "<div class=\"descrhead\"><div class=\"descrheadcontent\">" << endl
01471 << "<span class=\"descrtitle\">Source:</span>" << endl;
01472
01473
01474 TString classFileName(fCurrentClass->GetName());
01475 NameSpace2FileName(classFileName);
01476
01477 TString headerFileName;
01478 fHtml->GetDeclFileName(fCurrentClass, kFALSE, headerFileName);
01479 TString sourceFileName;
01480 fHtml->GetImplFileName(fCurrentClass, kFALSE, sourceFileName);
01481 if (headerFileName.Length())
01482 classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
01483 << ".h.html\">header file</a>" << endl;
01484 else
01485 classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
01486 << ".h.html\"></a>" << endl;
01487
01488 if (sourceFileName.Length())
01489 classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
01490 << ".cxx.html\">source file</a>" << endl;
01491 else
01492 classFile << "<a class=\"descrheadentry\" href=\"src/" << classFileName
01493 << ".cxx.html\"></a>" << endl;
01494
01495 if (!fHtml->IsNamespace(fCurrentClass) && !fHtml->HaveDot()) {
01496
01497 classFile << "<a class=\"descrheadentry\" href=\"" << classFileName << "_Tree.pdf\"";
01498 classFile << ">inheritance tree (.pdf)</a> ";
01499 }
01500
01501 const TString& viewCVSLink = GetHtml()->GetViewCVS();
01502 Bool_t mustReplace = viewCVSLink.Contains("%f");
01503 if (viewCVSLink.Length()) {
01504 if (headerFileName.Length()) {
01505 TString link(viewCVSLink);
01506 TString sHeader(headerFileName);
01507 if (GetHtml()->GetProductName() && !strcmp(GetHtml()->GetProductName(), "ROOT")
01508 && sHeader.BeginsWith("include")) {
01509 sHeader.Remove(0,7);
01510 if (sourceFileName && strstr(sourceFileName, "src")) {
01511 TString src(sourceFileName);
01512 src.Remove(src.Index("src"), src.Length());
01513 src += "inc";
01514 sHeader.Prepend(src);
01515 } else {
01516 TString src(fCurrentClass->GetSharedLibs());
01517 Ssiz_t posEndLib = src.Index(' ');
01518 if (posEndLib != kNPOS)
01519 src.Remove(posEndLib, src.Length());
01520 if (src.BeginsWith("lib"))
01521 src.Remove(0, 3);
01522 posEndLib = src.Index('.');
01523 if (posEndLib != kNPOS)
01524 src.Remove(posEndLib, src.Length());
01525 src.ToLower();
01526 src += "/inc";
01527 sHeader.Prepend(src);
01528 }
01529 if (sHeader.BeginsWith("tmva/inc/TMVA"))
01530 sHeader.Remove(8, 5);
01531 }
01532 if (mustReplace) link.ReplaceAll("%f", sHeader);
01533 else link += sHeader;
01534 classFile << "<a class=\"descrheadentry\" href=\"" << link << "\">viewVC header</a> ";
01535 } else
01536 classFile << "<a class=\"descrheadentry\"> </a> ";
01537 if (sourceFileName.Length()) {
01538 TString link(viewCVSLink);
01539 if (mustReplace) link.ReplaceAll("%f", sourceFileName);
01540 else link += sourceFileName;
01541 classFile << "<a class=\"descrheadentry\" href=\"" << link << "\">viewVC source</a> ";
01542 } else
01543 classFile << "<a class=\"descrheadentry\"> </a> ";
01544 }
01545
01546 TString currClassNameMangled(fCurrentClass->GetName());
01547 NameSpace2FileName(currClassNameMangled);
01548
01549 TString wikiLink = GetHtml()->GetWikiURL();
01550 if (wikiLink.Length()) {
01551 if (wikiLink.Contains("%c")) wikiLink.ReplaceAll("%c", currClassNameMangled);
01552 else wikiLink += currClassNameMangled;
01553 classFile << "<a class=\"descrheadentry\" href=\"" << wikiLink << "\">wiki</a> ";
01554 }
01555
01556 classFile << endl << "</div></div>" << endl;
01557
01558 classFile << "<div class=\"descrhead\"><div class=\"descrheadcontent\">" << endl
01559 << "<span class=\"descrtitle\">Sections:</span>" << endl
01560 << "<a class=\"descrheadentry\" href=\"#" << currClassNameMangled;
01561 if (fHtml->IsNamespace(fCurrentClass))
01562 classFile << ":description\">namespace description</a> ";
01563 else
01564 classFile << ":description\">class description</a> ";
01565 classFile << endl
01566 << "<a class=\"descrheadentry\" href=\"#" << currClassNameMangled << ":Function_Members\">function members</a>" << endl
01567 << "<a class=\"descrheadentry\" href=\"#" << currClassNameMangled << ":Data_Members\">data members</a>" << endl
01568 << "<a class=\"descrheadentry\" href=\"#" << currClassNameMangled << ":Class_Charts\">class charts</a>" << endl
01569 << "</div></div>" << endl
01570 << "</div>" << endl;
01571
01572 WriteLocation(classFile, module, fCurrentClass->GetName());
01573 }
01574
01575
01576
01577 void TClassDocOutput::WriteMethod(std::ostream& out, TString& ret,
01578 TString& name, TString& params,
01579 const char* filename, TString& anchor,
01580 TString& comment, TString& codeOneLiner,
01581 TDocMethodWrapper* guessedMethod)
01582 {
01583
01584
01585
01586
01587
01588
01589 fParser->DecorateKeywords(ret);
01590 out << "<div class=\"funcdoc\"><span class=\"funcname\">"
01591 << ret << " <a class=\"funcname\" name=\"";
01592 TString mangled(fCurrentClass->GetName());
01593 NameSpace2FileName(mangled);
01594 out << mangled << ":";
01595 mangled = name;
01596 NameSpace2FileName(mangled);
01597 if (guessedMethod && guessedMethod->GetOverloadIdx()) {
01598 mangled += "%";
01599 mangled += guessedMethod->GetOverloadIdx();
01600 }
01601 out << mangled << "\" href=\"src/" << filename;
01602 if (anchor.Length())
01603 out << "#" << anchor;
01604 out << "\">";
01605 ReplaceSpecialChars(out, name);
01606 out << "</a>";
01607 if (guessedMethod) {
01608 out << "(";
01609 TMethodArg* arg;
01610 TIter iParam(guessedMethod->GetMethod()->GetListOfMethodArgs());
01611 Bool_t first = kTRUE;
01612 while ((arg = (TMethodArg*) iParam())) {
01613 if (!first) out << ", ";
01614 else first = kFALSE;
01615 TString paramGuessed(arg->GetFullTypeName());
01616 paramGuessed += " ";
01617 paramGuessed += arg->GetName();
01618 if (arg->GetDefault() && strlen(arg->GetDefault())) {
01619 paramGuessed += " = ";
01620 paramGuessed += arg->GetDefault();
01621 }
01622 fParser->DecorateKeywords(paramGuessed);
01623 out << paramGuessed;
01624 }
01625 out << ")";
01626 if (guessedMethod->GetMethod()->Property() & kIsMethConst)
01627 out << " const";
01628 } else {
01629 fParser->DecorateKeywords(params);
01630 out << params;
01631 }
01632 out << "</span><br />" << std::endl;
01633
01634 if (comment.Length())
01635 out << "<div class=\"funccomm\"><pre>" << comment << "</pre></div>" << std::endl;
01636
01637 if (codeOneLiner.Length()) {
01638 out << std::endl << "<div class=\"code\"><code class=\"inlinecode\">"
01639 << codeOneLiner << "</code></div>" << std::endl
01640 << "<div style=\"clear:both;\"></div>" << std::endl;
01641 codeOneLiner.Remove(0);
01642 }
01643 out << "</div>" << std::endl;
01644 }
01645
01646
01647