Logo ROOT  
Reference Guide
TDocOutput.cxx
Go to the documentation of this file.
1// @(#)root/html:$Id: 7ff9b72609794c66acf6b369c4eeddfbfc63cf55 $
2// Author: Axel Naumann 2007-01-09
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TDocOutput.h"
13
14#include "Riostream.h"
15#include "TClassDocOutput.h"
16#include "TClassEdit.h"
17#include "TDataMember.h"
18#include "TDataType.h"
19#include "TDocInfo.h"
20#include "TDocParser.h"
21#include "TEnv.h"
22#include "THtml.h"
23#include "TInterpreter.h"
24#include "TMethod.h"
25#include "TPRegexp.h"
26#include "TROOT.h"
27#include "TSystem.h"
28#include "TUrl.h"
29#include "TVirtualMutex.h"
30#include "TVirtualPad.h"
31#include "TVirtualViewer3D.h"
32#include <vector>
33#include <list>
34#include <set>
35#include <sstream>
36#include <stdlib.h>
37
38namespace {
39
40 typedef std::vector<std::string> Words_t;
41 typedef Words_t::const_iterator SectionStart_t;
42
43 class TSectionInfo {
44 public:
45 TSectionInfo(SectionStart_t start, size_t chars, size_t size):
46 fStart(start), fChars(chars), fSize(size) {};
47
48 SectionStart_t fStart;
49 size_t fChars;
50 size_t fSize;
51 };
52 typedef std::list<TSectionInfo> SectionStarts_t;
53
54 static void Sections_BuildIndex(SectionStarts_t& sectionStarts,
55 SectionStart_t begin, SectionStart_t end,
56 size_t maxPerSection)
57 {
58 // for each assumed section border, check that previous entry's
59 // char[selectionChar] differs, else move section start forward
60
61 SectionStart_t cursor = begin;
62 if (sectionStarts.empty() || sectionStarts.back().fStart != cursor)
63 sectionStarts.push_back(TSectionInfo(cursor, 1, 0));
64
65 SectionStarts_t::iterator prevSection = sectionStarts.end();
66 --prevSection;
67
68 while (cursor != end) {
69 size_t numLeft = end - cursor;
70 size_t assumedNumSections = (numLeft + maxPerSection - 1 ) / maxPerSection;
71 size_t step = ((numLeft + assumedNumSections - 1) / assumedNumSections);
72 if (!step || step >= numLeft) return;
73 cursor += step;
74 if (cursor == end) break;
75
76 SectionStart_t addWhichOne = prevSection->fStart;
77
78 size_t selectionChar=1;
79 for (; selectionChar <= cursor->length() && addWhichOne == prevSection->fStart;
80 ++selectionChar) {
81 SectionStart_t checkPrev = cursor;
82 while (--checkPrev != prevSection->fStart
83 && !strncasecmp(checkPrev->c_str(), cursor->c_str(), selectionChar)) { }
84
85 SectionStart_t checkNext = cursor;
86 while (++checkNext != end
87 && !strncasecmp(checkNext->c_str(), cursor->c_str(), selectionChar)) { }
88
89 // if the previous matching one is closer but not previous section start, take it!
90 if (checkPrev != prevSection->fStart) {
91 if ((cursor - checkPrev) <= (checkNext - cursor))
92 addWhichOne = ++checkPrev;
93 else if (checkNext != end
94 && (size_t)(checkNext - cursor) < maxPerSection) {
95 addWhichOne = checkNext;
96 }
97 }
98 }
99 if (addWhichOne == prevSection->fStart)
100 addWhichOne = cursor;
101
102 selectionChar = 1;
103 while (selectionChar <= prevSection->fStart->length()
104 && selectionChar <= addWhichOne->length()
105 && !strncasecmp(prevSection->fStart->c_str(), addWhichOne->c_str(), selectionChar))
106 ++selectionChar;
107
108 sectionStarts.push_back(TSectionInfo(addWhichOne, selectionChar, 0));
109 cursor = addWhichOne;
110 ++prevSection;
111 } // while cursor != end
112 }
113
114 static void Sections_SetSize(SectionStarts_t& sectionStarts, const Words_t &words)
115 {
116 // Update the length of the sections
117 for (SectionStarts_t::iterator iSectionStart = sectionStarts.begin();
118 iSectionStart != sectionStarts.end(); ++iSectionStart) {
119 SectionStarts_t::iterator next = iSectionStart;
120 ++next;
121 if (next == sectionStarts.end()) {
122 iSectionStart->fSize = (words.end() - iSectionStart->fStart);
123 break;
124 }
125 iSectionStart->fSize = (next->fStart - iSectionStart->fStart);
126 }
127 }
128
129 static void Sections_PostMerge(SectionStarts_t& sectionStarts, const size_t maxPerSection)
130 {
131 // Merge sections that ended up being too small, up to maxPerSection entries
132 for (SectionStarts_t::iterator iSectionStart = sectionStarts.begin();
133 iSectionStart != sectionStarts.end();) {
134 SectionStarts_t::iterator iNextSectionStart = iSectionStart;
135 ++iNextSectionStart;
136 if (iNextSectionStart == sectionStarts.end()) break;
137 if (iNextSectionStart->fSize + iSectionStart->fSize < maxPerSection) {
138 iSectionStart->fSize += iNextSectionStart->fSize;
139 sectionStarts.erase(iNextSectionStart);
140 } else ++iSectionStart;
141 }
142 }
143
144 static void GetIndexChars(const Words_t& words, UInt_t numSectionsIn,
145 std::vector<std::string> &sectionMarkersOut)
146 {
147 // Given a list of words (class names, in this case), this function builds an
148 // optimal set of about numSectionIn sections (even if almost all words start
149 // with a "T"...), and returns the significant characters for each section start
150 // in sectionMarkersOut.
151
152 const size_t maxPerSection = (words.size() + numSectionsIn - 1)/ numSectionsIn;
153 SectionStarts_t sectionStarts;
154 Sections_BuildIndex(sectionStarts, words.begin(), words.end(), maxPerSection);
155 Sections_SetSize(sectionStarts, words);
156 Sections_PostMerge(sectionStarts, maxPerSection);
157
158 // convert to index markers
159 sectionMarkersOut.clear();
160 sectionMarkersOut.resize(sectionStarts.size());
161 size_t idx = 0;
162 for (SectionStarts_t::iterator iSectionStart = sectionStarts.begin();
163 iSectionStart != sectionStarts.end(); ++iSectionStart)
164 sectionMarkersOut[idx++] =
165 iSectionStart->fStart->substr(0, iSectionStart->fChars);
166 }
167
168 static void GetIndexChars(const std::list<std::string>& wordsIn, UInt_t numSectionsIn,
169 std::vector<std::string> &sectionMarkersOut)
170 {
171 // initialize word vector
172 Words_t words(wordsIn.size());
173 size_t idx = 0;
174 for (std::list<std::string>::const_iterator iWord = wordsIn.begin(); iWord != wordsIn.end(); ++iWord)
175 words[idx++] = *iWord;
176 GetIndexChars(words, numSectionsIn, sectionMarkersOut);
177 }
178
179}
180
181extern "C" { // std::qsort on solaris wants the sorter to be extern "C"
182
183 /////////////////////////////////////////////////////////////////////////////
184 /// Friend function for sorting strings, case insensitive
185 ///
186 ///
187 /// Input: name1 - pointer to the first string
188 /// name2 - pointer to the second string
189 ///
190 /// NOTE: This function compares its arguments and returns an integer less
191 /// than, equal to, or greater than zero, depending on whether name1
192 /// is lexicographically less than, equal to, or greater than name2,
193 /// but characters are forced to lower-case prior to comparison.
194 ///
195 ///
196
197 static int CaseInsensitiveSort(const void *name1, const void *name2)
198 {
199 return (strcasecmp(*((char **) name1), *((char **) name2)));
200 }
201}
202
203namespace {
204
205 // std::list::sort(with_stricmp_predicate) doesn't work with Solaris CC...
206 static void sort_strlist_stricmp(std::vector<std::string>& l)
207 {
208 // sort strings ignoring case - easier for humans
209 struct posList {
210 const char* str;
211 size_t pos;
212 };
213 posList* carr = new posList[l.size()];
214 size_t idx = 0;
215 for (size_t iS = 0, iSE = l.size(); iS < iSE; ++iS) {
216 carr[idx].pos = iS;
217 carr[idx++].str = l[iS].c_str();
218 }
219 qsort(&carr[0].str, idx, sizeof(posList), CaseInsensitiveSort);
220 std::vector<std::string> lsort(l.size());
221 for (size_t iS = 0, iSE = l.size(); iS < iSE; ++iS) {
222 lsort[iS].swap(l[carr[iS].pos]);
223 }
224 delete [] carr;
225 l.swap(lsort);
226 }
227
228}
229
230//______________________________________________________________________________
231//
232// THtml generated documentation is written to file by TDocOutput. So far only
233// output of HTML is implemented. Customization of the output should be done
234// with THtml's interfaces - TDocOutput should not be used nor re-implemented
235// directly.
236//
237// TDocOutput generates the index tables:
238// * classes (THtml invokes TClassDocOutput for each),
239// * inheritance hierarchy,
240// * types and typedefs,
241// * libraries,
242// * the product index, and
243// * the module index (including the links to per-module documentation).
244// It invokes AT&T's GraphViz tool (dot) if available; charts benefit a lot
245// from it.
246//
247// TDocOutput also writes all pages' header and footer, which can be customized
248// by calling THtml::SetHeader(), THtml::SetFooter().
249//______________________________________________________________________________
250
252
253////////////////////////////////////////////////////////////////////////////////
254
255TDocOutput::TDocOutput(THtml& html): fHtml(&html)
256{}
257
258////////////////////////////////////////////////////////////////////////////////
259
261{}
262
263////////////////////////////////////////////////////////////////////////////////
264/// Add a link around str, with title comment.
265/// Update str so it surrounds the link.
266
267void TDocOutput::AddLink(TSubString& str, TString& link, const char* comment)
268{
269 // prepend "./" to allow callers to replace a different relative directory
270 if (ReferenceIsRelative(link) && !link.BeginsWith("./"))
271 link.Prepend("./");
272 link.Prepend("<a href=\"");
273 link += "\"";
274 if (comment && strlen(comment)) {
275 link += " title=\"";
276 TString description(comment);
277 ReplaceSpecialChars(description);
278 description.ReplaceAll("\"", "&quot;");
279 link += description;
280 link += "\"";
281 }
282 link += ">";
283
284 str.String().Insert(str.Start() + str.Length(), "</a>");
285 str.String().Insert(str.Start(), link);
286
287 TString &strString = str.String();
288 TSubString update = strString(str.Start(), str.Length() + link.Length() + 4);
289 str = update;
290}
291
292////////////////////////////////////////////////////////////////////////////////
293/// adjust the path of links for source files, which are in src/, but need
294/// to point to relpath (usually "../"). Simply replaces "=\"./" by "=\"../"
295
296void TDocOutput::AdjustSourcePath(TString& line, const char* relpath /*= "../"*/)
297{
298 TString replWithRelPath("=\"@!@");
299 line.ReplaceAll("=\"../", replWithRelPath + "../" + relpath);
300 line.ReplaceAll("=\"./", replWithRelPath + relpath);
301 line.ReplaceAll("=\"@!@","=\"");
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// Convert a text file into a html file.
306/// outfilename doesn't have an extension yet; up to us to decide.
307/// We generate HTML, so our extension is ".html".
308/// See THtml::Convert() for the other parameters.
309
310void TDocOutput::Convert(std::istream& in, const char* infilename,
311 const char* outfilename, const char *title,
312 const char *relpath /*= "../"*/, Int_t includeOutput /*=0*/,
313 const char* context /*= ""*/,
314 TGClient* gclient /*= 0*/)
315{
316 TString htmlFilename(outfilename);
317 htmlFilename += ".html";
318
319 std::ofstream out(htmlFilename);
320
321 if (!out.good()) {
322 Error("Convert", "Can't open file '%s' !", htmlFilename.Data());
323 return;
324 }
325
326 // write a HTML header
327 WriteHtmlHeader(out, title, relpath);
328
329 if (context && context[0])
330 out << context << std::endl;
331 else if (title && title[0])
332 out << "<h1 class=\"convert\">" << title << "</h1>" << std::endl;
333
334 Int_t numReuseCanvases = 0;
335 if (includeOutput && !(includeOutput & THtml::kForceOutput)) {
336 void* dirHandle = gSystem->OpenDirectory(gSystem->DirName(htmlFilename));
337 if (dirHandle) {
338 FileStat_t infile_stat;
339 if (!gSystem->GetPathInfo(infilename, infile_stat)) {
340 // can stat.
341 const char* outfile = 0;
342 TString firstCanvasFileBase(gSystem->BaseName(outfilename));
343 firstCanvasFileBase += "_0.png";
344 // first check whether the firstCanvasFile exists:
345 Bool_t haveFirstCanvasFile = false;
346 while ((outfile = gSystem->GetDirEntry(dirHandle))) {
347 if (firstCanvasFileBase == outfile) {
348 haveFirstCanvasFile = true;
349 break;
350 }
351 }
352 gSystem->FreeDirectory(dirHandle);
353
354 FileStat_t outfile_stat;
355 TString firstCanvasFile = outfilename;
356 firstCanvasFile += "_0.png";
357 Int_t maxIdx = -1;
358 if (haveFirstCanvasFile && !gSystem->GetPathInfo(firstCanvasFile, outfile_stat)
359 && outfile_stat.fMtime > infile_stat.fMtime) {
360 // the first canvas file exists and it is newer than the script, so we reuse
361 // the canvas files. We need to know how many there are:
362 dirHandle = gSystem->OpenDirectory(gSystem->DirName(htmlFilename));
363 TString stem(gSystem->BaseName(outfilename));
364 stem += "_";
365 TString dir(gSystem->DirName(htmlFilename));
366 while ((outfile = gSystem->GetDirEntry(dirHandle))) {
367 if (strncmp(outfile, stem, stem.Length()))
368 continue;
369 const char* posext = strrchr(outfile, '.');
370 if (!posext || strcmp(posext, ".png"))
371 continue;
372
373 // extract the mod time of the PNG file
374 if (gSystem->GetPathInfo(dir + "/" + outfile, outfile_stat))
375 // can't stat!
376 continue;
377
378 if (outfile_stat.fMtime > infile_stat.fMtime) {
379 ++numReuseCanvases;
380 // The canvas PNG is newer than the script, so
381 // extract the index of the canvas
382 TString idxStr(outfile + stem.Length());
383 idxStr.Remove(idxStr.Length() - 4);
384 Int_t idx = idxStr.Atoi();
385 if (maxIdx < idx)
386 maxIdx = idx;
387 }
388 }
389 gSystem->FreeDirectory(dirHandle);
390 if (maxIdx + 1 != numReuseCanvases)
391 // bad: the number of canvases to reuse noes not correspond to the highest index we saw.
392 // we will need to regenerate everything.
393 numReuseCanvases = 0;
394 }
395 } // infile can be stat'ed
396 } // can open output directory
397 } // canvases wanted
398
399 if (numReuseCanvases)
400 Printf("Convert: %s (reusing %d saved canvas%s)", htmlFilename.Data(), numReuseCanvases, (numReuseCanvases > 1 ? "es" : ""));
401 else
402 Printf("Convert: %s", htmlFilename.Data());
403
404 UInt_t nCanvases = numReuseCanvases;
405 if (includeOutput) {
406 if (!numReuseCanvases) {
407 // need to run the script
408 if (includeOutput & THtml::kSeparateProcessOutput) {
409 TString baseInFileName = gSystem->BaseName(infilename);
410 TPMERegexp reOutFile(baseInFileName + "_[[:digit:]]+\\.png");
411
412 // remove all files matching what saveScriptOutput.C could produce:
413 void* outdirH = gSystem->OpenDirectory(gSystem->DirName(outfilename));
414 if (outdirH) {
415 // the directory exists.
416 const char* outdirE = 0;
417 while ((outdirE = gSystem->GetDirEntry(outdirH))) {
418 if (reOutFile.Match(outdirE)) {
419 gSystem->Unlink(outdirE);
420 }
421 }
422 gSystem->FreeDirectory(outdirH);
423 }
424
425 gSystem->Exec(TString::Format("ROOT_HIST=0 root.exe -l -q %s $ROOTSYS/etc/html/saveScriptOutput.C\\(\\\"%s\\\",\\\"%s\\\",%d\\)",
426 gROOT->IsBatch() ? "-b" : "",
427 infilename,
428 gSystem->DirName(outfilename),
429 includeOutput & THtml::kCompiledOutput));
430
431 // determine how many output files were created:
432 outdirH = gSystem->OpenDirectory(gSystem->DirName(outfilename));
433 if (outdirH) {
434 // the directory exists.
435 const char* outdirE = 0;
436 while ((outdirE = gSystem->GetDirEntry(outdirH))) {
437 if (reOutFile.Match(outdirE)) {
438 ++nCanvases;
439 }
440 }
441 gSystem->FreeDirectory(outdirH);
442 }
443 } else {
444 // run in this ROOT process
445 TString pwd(gSystem->pwd());
446 gSystem->cd(gSystem->DirName(infilename));
447
448 TList* gClientGetListOfWindows = 0;
449 TObject* gClientGetDefaultRoot = 0;
450 std::set<TObject*> previousWindows;
451 if (gclient) {
452 gROOT->ProcessLine(TString::Format("*((TList**)0x%lx) = ((TGClient*)0x%lx)->GetListOfWindows();",
453 (ULong_t)&gClientGetListOfWindows, (ULong_t)gclient));
454 gROOT->ProcessLine(TString::Format("*((TObject**)0x%lx) = ((TGClient*)0x%lx)->GetDefaultRoot();",
455 (ULong_t)&gClientGetDefaultRoot, (ULong_t)gclient));
456 TObject* win = 0;
457 TIter iWin(gClientGetListOfWindows);
458 while((win = iWin())) {
459 TObject* winGetParent = 0;
460 gROOT->ProcessLine(TString::Format("*((TObject**)0x%lx) = ((TGWindow*)0x%lx)->GetParent();",
461 (ULong_t)&winGetParent, (ULong_t)win));
462 if (winGetParent == gClientGetDefaultRoot)
463 previousWindows.insert(win);
464 }
465 } else {
466 if (gROOT->GetListOfCanvases()->GetSize())
467 previousWindows.insert(gROOT->GetListOfCanvases()->Last());
468 }
469 TIter iTimer(gSystem->GetListOfTimers());
470 std::set<TObject*> timersBefore;
471 TObject* timerOld = 0;
472 while ((timerOld = iTimer()))
473 timersBefore.insert(timerOld);
474
475 TString cmd(".x ");
476 cmd += gSystem->BaseName(infilename);
477 if (includeOutput & THtml::kCompiledOutput)
478 cmd += "+";
479 gInterpreter->SaveContext();
480 gInterpreter->SaveGlobalsContext();
481 Int_t err;
482 gROOT->ProcessLine(cmd, &err);
484 gSystem->cd(pwd);
485
486 if (err == TInterpreter::kNoError) {
487 if (gclient) {
488 TClass* clRootCanvas = TClass::GetClass("TRootCanvas");
489 TClass* clGMainFrame = TClass::GetClass("TGMainFrame");
490 TObject* win = 0;
491 TIter iWin(gClientGetListOfWindows);
492 while((win = iWin())) {
493 TObject* winGetParent = 0;
494 gROOT->ProcessLine(TString::Format("*((TObject**)0x%lx) = ((TGWindow*)0x%lx)->GetParent();",
495 (ULong_t)&winGetParent, (ULong_t)win));
496 Bool_t winIsMapped = kFALSE;
497 if (winGetParent == gClientGetDefaultRoot)
498 gROOT->ProcessLine(TString::Format("*((Bool_t*)0x%lx) = ((TGWindow*)0x%lx)->IsMapped();",
499 (ULong_t)&winIsMapped, (ULong_t)win));
500 if (winIsMapped && previousWindows.find(win) == previousWindows.end()
501 && win->InheritsFrom(clGMainFrame)) {
502 gROOT->ProcessLine(TString::Format("((TGWindow*)0x%lx)->MapRaised();", (ULong_t)win));
503 Bool_t isRootCanvas = win->InheritsFrom(clRootCanvas);
504 Bool_t hasEditor = false;
505 if (isRootCanvas) {
506 gROOT->ProcessLine(TString::Format("*((Bool_t*)0x%lx) = ((TRootCanvas*)0x%lx)->HasEditor();",
507 (ULong_t)&hasEditor, (ULong_t)win));
508 }
509 if (isRootCanvas && !hasEditor) {
510 TVirtualPad* pad = 0;
511 gROOT->ProcessLine(TString::Format("*((TVirtualPad**)0x%lx) = ((TRootCanvas*)0x%lx)->Canvas();",
512 (ULong_t)&pad, (ULong_t)win));
513 if (!pad->HasViewer3D() || pad->GetViewer3D()->InheritsFrom("TViewer3DPad")) {
514 pad->SaveAs(TString::Format("%s_%d.png", outfilename, nCanvases++));
515 }
516 } else
517 gROOT->ProcessLine(TString::Format("((TGWindow*)0x%lx)->SaveAs(\"%s_%d.png\");",
518 (ULong_t)win, outfilename, nCanvases++));
519 }
520 }
521 } else {
522 // no gClient
523 TVirtualPad* pad = 0;
524 TVirtualPad* last = 0;
525 if (!previousWindows.empty())
526 last = (TVirtualPad*) *previousWindows.begin();
527 TIter iCanvas(gROOT->GetListOfCanvases());
528 while ((pad = (TVirtualPad*) iCanvas())) {
529 if (last) {
530 if (last == pad) last = 0;
531 continue;
532 }
533 pad->SaveAs(TString::Format("%s_%d.png", outfilename, nCanvases++));
534 }
535 }
536 gInterpreter->Reset();
537 gInterpreter->ResetGlobals();
538 TIter iTimerRemove(gSystem->GetListOfTimers());
539 TTimer* timer = 0;
540 while ((timer = (TTimer*) iTimerRemove()))
541 if (timersBefore.find(timer) == timersBefore.end())
542 gSystem->RemoveTimer(timer);
543 }
544 } // run script in this ROOT process
545 }
546 out << "<table><tr><td style=\"vertical-align:top;padding-right:2em;\">" << std::endl;
547 }
548 out << "<div class=\"listing\"><pre class=\"listing\">" << std::endl;
549
550 TDocParser parser(*this);
551 parser.Convert(out, in, relpath, (includeOutput) /* determines whether it's code or not */,
552 kFALSE /*interpretDirectives*/);
553
554 out << "</pre></div>" << std::endl;
555
556 WriteLineNumbers(out, parser.GetLineNumber(), gSystem->BaseName(infilename));
557
558 if (includeOutput) {
559 out << "</td><td style=\"vertical-align:top;\">" << std::endl;
560 out << "<table>" << std::endl;
561 for (UInt_t i = 0; i < nCanvases; ++i) {
562 TString pngname = TString::Format("%s_%d.png", gSystem->BaseName(outfilename), i);
563 out << "<tr><td><a href=\"" << pngname << "\">" << std::endl
564 << "<img src=\"" << pngname << "\" id=\"canv" << i << "\" alt=\"thumb\" style=\"border:none;width:22em;\" "
565 "onmouseover=\"javascript:canv" << i << ".style.width='auto';\" />" << std::endl
566 << "</a></td></tr>" << std::endl;
567 }
568 out << "</table>" << std::endl;
569 out << "</td></tr></table>" << std::endl;
570 }
571
572 // write a HTML footer
573 WriteHtmlFooter(out, relpath);
574}
575
576////////////////////////////////////////////////////////////////////////////////
577/// Copy file to HTML directory
578///
579///
580/// Input: sourceName - source file name (fully qualified i.e. file system path)
581/// destName - optional destination name, if not
582/// specified it would be the same
583/// as the source file name
584///
585/// Output: TRUE if file is successfully copied, or
586/// FALSE if it's not
587///
588///
589/// NOTE: The destination directory is always fHtml->GetOutputDir()
590///
591
592Bool_t TDocOutput::CopyHtmlFile(const char *sourceName, const char *destName)
593{
594 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
595
596 TString sourceFile(sourceName);
597
598 if (!sourceFile.Length()) {
599 Error("Copy", "Can't copy file '%s' to '%s' directory - source file name invalid!", sourceName,
600 fHtml->GetOutputDir().Data());
601 return kFALSE;
602 }
603
604 // destination file name
605 TString destFile;
606 if (!destName || !*destName)
607 destFile = gSystem->BaseName(sourceFile);
608 else
609 destFile = gSystem->BaseName(destName);
610
612
613 // Get info about a file
614 Long64_t size;
615 Long_t id, flags, sModtime, dModtime;
616 sModtime = 0;
617 dModtime = 0;
618 if (gSystem->GetPathInfo(sourceFile, &id, &size, &flags, &sModtime)
619 || gSystem->GetPathInfo(destFile, &id, &size, &flags, &dModtime)
620 || sModtime > dModtime)
621 if (gSystem->CopyFile(sourceFile, destFile, kTRUE) < 0) {
622 Error("Copy", "Can't copy file '%s' to '%s'!",
623 sourceFile.Data(), destFile.Data());
624 return kFALSE;
625 }
626
627 return kTRUE;
628}
629
630
631
632////////////////////////////////////////////////////////////////////////////////
633/// Create a hierarchical class list
634/// The algorithm descends from the base classes and branches into
635/// all derived classes. Mixing classes are displayed several times.
636///
637///
638
640{
641 // if (CreateHierarchyDot()) return;
642
643 TString filename("ClassHierarchy.html");
645
646 // open out file
647 std::ofstream out(filename);
648
649 if (!out.good()) {
650 Error("CreateHierarchy", "Can't open file '%s' !", filename.Data());
651 return;
652 }
653
654 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), filename.Data());
655
656 // write out header
657 WriteHtmlHeader(out, "Class Hierarchy");
658
659 WriteTopLinks(out, 0);
660
661 out << "<h1>Class Hierarchy</h1>" << std::endl;
662
663
664 // loop on all classes
665 TClassDocInfo* cdi = 0;
666 TIter iClass(fHtml->GetListOfClasses());
667 while ((cdi = (TClassDocInfo*)iClass())) {
668 if (!cdi->HaveSource())
669 continue;
670
671 // get class
672 TDictionary *dictPtr = cdi->GetClass();
673 TClass *basePtr = dynamic_cast<TClass*>(dictPtr);
674 if (basePtr == 0) {
675 if (!dictPtr)
676 Warning("THtml::CreateHierarchy", "skipping class %s\n", cdi->GetName());
677 continue;
678 }
679
680 TClassDocOutput cdo(*fHtml, basePtr, 0);
681 cdo.CreateClassHierarchy(out, cdi->GetHtmlFileName());
682 }
683
684 // write out footer
685 WriteHtmlFooter(out);
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Create index of all classes
690///
691
693{
694 // create CSS file, we need it
696
697 TString filename("ClassIndex.html");
699
700 // open indexFile file
701 std::ofstream indexFile(filename.Data());
702
703 if (!indexFile.good()) {
704 Error("CreateClassIndex", "Can't open file '%s' !", filename.Data());
705 return;
706 }
707
708 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), filename.Data());
709
710 // write indexFile header
711 WriteHtmlHeader(indexFile, "Class Index");
712
713 WriteTopLinks(indexFile, 0);
714
715 indexFile << "<h1>Class Index</h1>" << std::endl;
716
717 WriteModuleLinks(indexFile);
718
719 std::vector<std::string> indexChars;
720 if (fHtml->GetListOfClasses()->GetSize() > 10) {
721 std::vector<std::string> classNames;
722 {
723 TIter iClass(fHtml->GetListOfClasses());
724 TClassDocInfo* cdi = 0;
725 while ((cdi = (TClassDocInfo*)iClass()))
726 if (cdi->IsSelected() && cdi->HaveSource())
727 classNames.push_back(cdi->GetName());
728 }
729
730 if (classNames.size() > 10) {
731 indexFile << "<div id=\"indxShortX\"><h4>Jump to</h4>" << std::endl;
732 // find index chars
733 GetIndexChars(classNames, 50 /*sections*/, indexChars);
734 for (UInt_t iIdxEntry = 0; iIdxEntry < indexChars.size(); ++iIdxEntry) {
735 indexFile << "<a href=\"#idx" << iIdxEntry << "\">";
736 ReplaceSpecialChars(indexFile, indexChars[iIdxEntry].c_str());
737 indexFile << "</a>" << std::endl;
738 }
739 indexFile << "</div><br />" << std::endl;
740 }
741 }
742
743 indexFile << "<ul id=\"indx\">" << std::endl;
744
745 // loop on all classes
746 UInt_t currentIndexEntry = 0;
747 TIter iClass(fHtml->GetListOfClasses());
748 TClassDocInfo* cdi = 0;
749 Int_t i = 0;
750 while ((cdi = (TClassDocInfo*)iClass())) {
751 if (!cdi->IsSelected() || !cdi->HaveSource())
752 continue;
753
754 // get class
755 TDictionary *currentDict = cdi->GetClass();
756 TClass* currentClass = dynamic_cast<TClass*>(currentDict);
757 if (!currentClass) {
758 if (!currentDict)
759 Warning("THtml::CreateClassIndex", "skipping class %s\n", cdi->GetName());
760 continue;
761 }
762
763 indexFile << "<li class=\"idxl" << (i++)%2 << "\">";
764 if (currentIndexEntry < indexChars.size()
765 && !strncmp(indexChars[currentIndexEntry].c_str(), cdi->GetName(),
766 indexChars[currentIndexEntry].length()))
767 indexFile << "<a name=\"idx" << currentIndexEntry++ << "\"></a>";
768
769 TString htmlFile(cdi->GetHtmlFileName());
770 if (htmlFile.Length()) {
771 indexFile << "<a href=\"";
772 indexFile << htmlFile;
773 indexFile << "\"><span class=\"typename\">";
774 ReplaceSpecialChars(indexFile, cdi->GetName());
775 indexFile << "</span></a> ";
776 } else {
777 indexFile << "<span class=\"typename\">";
778 ReplaceSpecialChars(indexFile, cdi->GetName());
779 indexFile << "</span> ";
780 }
781
782 // write title == short doc
783 ReplaceSpecialChars(indexFile, currentClass->GetTitle());
784 indexFile << "</li>" << std::endl;
785 }
786
787 indexFile << "</ul>" << std::endl;
788
789 // write indexFile footer
790 WriteHtmlFooter(indexFile);
791}
792
793
794////////////////////////////////////////////////////////////////////////////////
795/// Create the class index for each module, picking up documentation from the
796/// module's TModuleDocInfo::GetInputPath() plus the (possibly relative)
797/// THtml::GetModuleDocPath(). Also creates the library dependency plot if dot
798/// exists, see THtml::HaveDot().
799
801{
802 const char* title = "LibraryDependencies";
803 TString dotfilename(title);
804 gSystem->PrependPathName(fHtml->GetOutputDir(), dotfilename);
805
806 std::ofstream libDepDotFile(dotfilename + ".dot");
807 libDepDotFile << "digraph G {" << std::endl
808 << "ratio=compress;" << std::endl
809 << "node [fontsize=22,labeldistance=0.1];" << std::endl
810 << "edge [len=0.01];" << std::endl
811 << "fontsize=22;" << std::endl
812 << "size=\"16,16\";" << std::endl
813 << "overlap=false;" << std::endl
814 << "splines=true;" << std::endl
815 << "K=0.1;" << std::endl;
816
817 TModuleDocInfo* module = 0;
818 TIter iterModule(fHtml->GetListOfModules());
819
820 std::stringstream sstrCluster;
821 std::stringstream sstrDeps;
822 while ((module = (TModuleDocInfo*)iterModule())) {
823 if (!module->IsSelected())
824 continue;
825
826 std::vector<std::string> indexChars;
827 TString filename(module->GetName());
828 filename.ToUpper();
829 filename.ReplaceAll("/","_");
830 filename += "_Index.html";
832 std::ofstream outputFile(filename.Data());
833 if (!outputFile.good()) {
834 Error("CreateModuleIndex", "Can't open file '%s' !", filename.Data());
835 continue;
836 }
837 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), filename.Data());
838
839 TString htmltitle("Index of ");
840 TString moduletitle(module->GetName());
841 moduletitle.ToUpper();
842 htmltitle += moduletitle;
843 WriteHtmlHeader(outputFile, htmltitle);
844
845 WriteTopLinks(outputFile, module);
846
847 outputFile << "<h2>" << htmltitle << "</h2>" << std::endl;
848
849 // Module doc
850 if (GetHtml()->GetModuleDocPath().Length()) {
851 TString outdir(module->GetName());
852 gSystem->PrependPathName(GetHtml()->GetOutputDir(), outdir);
853
854 TString moduleDocDir;
855 GetHtml()->GetPathDefinition().GetDocDir(module->GetName(), moduleDocDir);
856 ProcessDocInDir(outputFile, moduleDocDir, outdir, module->GetName());
857 }
858
859 WriteModuleLinks(outputFile, module);
860
861 std::list<std::string> classNames;
862 {
863 TIter iClass(module->GetClasses());
864 TClassDocInfo* cdi = 0;
865 while ((cdi = (TClassDocInfo*) iClass())) {
866 if (!cdi->IsSelected() || !cdi->HaveSource())
867 continue;
868 classNames.push_back(cdi->GetName());
869
870 if (classNames.size() > 1) continue;
871
872 TClass* cdiClass = dynamic_cast<TClass*>(cdi->GetClass());
873 if (!cdiClass)
874 continue;
875
876 TString libs(cdiClass->GetSharedLibs());
877 Ssiz_t posDepLibs = libs.Index(' ');
878 TString thisLib(libs);
879 if (posDepLibs != kNPOS)
880 thisLib.Remove(posDepLibs, thisLib.Length());
881
882 {
883 Ssiz_t posExt = thisLib.First('.');
884 if (posExt != kNPOS)
885 thisLib.Remove(posExt, thisLib.Length());
886 }
887
888 if (!thisLib.Length())
889 continue;
890
891 // allocate entry, even if no dependencies
892 TLibraryDocInfo *libdeps =
894 if (!libdeps) {
895 libdeps = new TLibraryDocInfo(thisLib);
896 fHtml->GetLibraryDependencies()->Add(libdeps);
897 }
898 libdeps->AddModule(module->GetName());
899 if (posDepLibs != kNPOS) {
900 std::string lib;
901 for(Ssiz_t pos = posDepLibs + 1; libs[pos]; ++pos) {
902 if (libs[pos] == ' ') {
903 if (thisLib.Length() && lib.length()) {
904 size_t posExt = lib.find('.');
905 if (posExt != std::string::npos)
906 lib.erase(posExt);
907 libdeps->AddDependency(lib);
908 }
909 lib.erase();
910 } else
911 lib += libs[pos];
912 }
913 if (lib.length() && thisLib.Length()) {
914 size_t posExt = lib.find('.');
915 if (posExt != std::string::npos)
916 lib.erase(posExt);
917 libdeps->AddDependency(lib);
918 }
919 } // if dependencies
920 } // while next class in module
921 } // just a scope block
922
923 TIter iClass(module->GetClasses());
924 TClassDocInfo* cdi = 0;
925 UInt_t count = 0;
926 UInt_t currentIndexEntry = 0;
927 while ((cdi = (TClassDocInfo*) iClass())) {
928 if (!cdi->IsSelected() || !cdi->HaveSource())
929 continue;
930
931 TDictionary *classPtr = cdi->GetClass();
932 if (!classPtr) {
933 Error("CreateModuleIndex", "Unknown class '%s' !", cdi->GetName());
934 continue;
935 }
936
937 if (!count) {
938 outputFile << "<h2>Class Index</h2>" << std::endl;
939
940 if (classNames.size() > 10) {
941 outputFile << "<div id=\"indxShortX\"><h4>Jump to</h4>" << std::endl;
942 UInt_t numSections = classNames.size() / 10;
943 if (numSections < 10) numSections = 10;
944 if (numSections > 50) numSections = 50;
945 // find index chars
946 GetIndexChars(classNames, numSections, indexChars);
947 for (UInt_t iIdxEntry = 0; iIdxEntry < indexChars.size(); ++iIdxEntry) {
948 outputFile << "<a href=\"#idx" << iIdxEntry << "\">";
949 ReplaceSpecialChars(outputFile, indexChars[iIdxEntry].c_str());
950 outputFile << "</a>" << std::endl;
951 }
952 outputFile << "</div><br />" << std::endl;
953 }
954
955 outputFile << "<ul id=\"indx\">" << std::endl;
956 }
957
958 // write a classname to an index file
959 outputFile << "<li class=\"idxl" << (count++)%2 << "\">";
960 if (currentIndexEntry < indexChars.size()
961 && !strncmp(indexChars[currentIndexEntry].c_str(), cdi->GetName(),
962 indexChars[currentIndexEntry].length()))
963 outputFile << "<a name=\"idx" << currentIndexEntry++ << "\"></a>";
964
965 TString htmlFile(cdi->GetHtmlFileName());
966 if (htmlFile.Length()) {
967 outputFile << "<a href=\"";
968 outputFile << htmlFile;
969 outputFile << "\"><span class=\"typename\">";
970 ReplaceSpecialChars(outputFile, classPtr->GetName());
971 outputFile << "</span></a> ";
972 } else {
973 outputFile << "<span class=\"typename\">";
974 ReplaceSpecialChars(outputFile, classPtr->GetName());
975 outputFile << "</span> ";
976 }
977
978 // write title
979 ReplaceSpecialChars(outputFile, classPtr->GetTitle());
980 outputFile << "</li>" << std::endl;
981 }
982
983
984 if (count)
985 outputFile << "</ul>" << std::endl;
986
987 // write outputFile footer
988 WriteHtmlFooter(outputFile);
989 } // while next module
990
991 // libCint is missing as we don't have class doc for it
992 // We need it for dependencies nevertheless, so add it by hand.
993 /*
994 sstrCluster << "subgraph clusterlibCint {" << std::endl
995 << "style=filled;" << std::endl
996 << "color=lightgray;" << std::endl
997 << "label=\"libCint\";" << std::endl
998 << "\"CINT\" [style=filled,color=white,fontsize=10]" << std::endl
999 << "}" << std::endl;
1000 */
1001
1002 // simplify the library dependencies, by removing direct links
1003 // that are equivalent to indirect ones, e.g. instead of having both
1004 // A->C, A->B->C, keep only A->B->C.
1005
1007 TLibraryDocInfo* libinfo = 0;
1008 while ((libinfo = (TLibraryDocInfo*)iLib())) {
1009 if (!libinfo->GetName() || !libinfo->GetName()[0]) continue;
1010
1011 std::set<std::string>& deps = libinfo->GetDependencies();
1012 for (std::set<std::string>::iterator iDep = deps.begin();
1013 iDep != deps.end(); ) {
1014 Bool_t already_indirect = kFALSE;
1015 for (std::set<std::string>::const_iterator iDep2 = deps.begin();
1016 !already_indirect && iDep2 != deps.end(); ++iDep2) {
1017 if (iDep == iDep2) continue;
1018 TLibraryDocInfo* libinfo2 = (TLibraryDocInfo*)
1019 fHtml->GetLibraryDependencies()->FindObject(iDep2->c_str());
1020 if (!libinfo2) continue;
1021 const std::set<std::string>& deps2 = libinfo2->GetDependencies();
1022 already_indirect |= deps2.find(*iDep) != deps2.end();
1023 }
1024 if (already_indirect) {
1025 std::set<std::string>::iterator iRemove = iDep;
1026 // Advance the iterator before erasing the element which invalidates the iterator.
1027 ++iDep;
1028 deps.erase(iRemove);
1029 } else {
1030 ++iDep;
1031 }
1032 } // for library dependencies of module in library
1033 } // for libraries
1034
1035 iLib.Reset();
1036 while ((libinfo = (TLibraryDocInfo*)iLib())) {
1037 if (!libinfo->GetName() || !libinfo->GetName()[0]) continue;
1038
1039 const std::set<std::string>& modules = libinfo->GetModules();
1040 if (modules.size() > 1) {
1041 sstrCluster << "subgraph cluster" << libinfo->GetName() << " {" << std::endl
1042 << "style=filled;" << std::endl
1043 << "color=lightgray;" << std::endl
1044 << "label=\"";
1045 if (!strcmp(libinfo->GetName(), "libCore"))
1046 sstrCluster << "Everything depends on ";
1047 sstrCluster << libinfo->GetName() << "\";" << std::endl;
1048
1049 for (std::set<std::string>::const_iterator iModule = modules.begin();
1050 iModule != modules.end(); ++iModule) {
1051 TString modURL(*iModule);
1052 modURL.ReplaceAll("/", "_");
1053 modURL.ToUpper();
1054 sstrCluster << "\"" << *iModule << "\" [style=filled,color=white,URL=\""
1055 << modURL << "_Index.html\"];" << std::endl;
1056 }
1057 sstrCluster << std::endl
1058 << "}" << std::endl;
1059 } else {
1060 // only one module
1061 TString modURL(*modules.begin());
1062 modURL.ReplaceAll("/", "_");
1063 modURL.ToUpper();
1064 sstrCluster << "\"" << *modules.begin()
1065 << "\" [label=\"" << libinfo->GetName()
1066 << "\",style=filled,color=lightgray,shape=box,URL=\""
1067 << modURL << "_Index.html\"];" << std::endl;
1068 }
1069
1070 // GetSharedLib doesn't mention libCore or libCint; add them by hand
1071 /*
1072 if (iLibDep->first != "libCore")
1073 sstrDeps << "\"" << iModule->first << "\" -> \"BASE\" [lhead=clusterlibCore];" << std::endl;
1074 sstrDeps << "\"" << iModule->first << "\" -> \"CINT\" [lhead=clusterlibCint];" << std::endl;
1075 */
1076
1077 const std::string& mod = *(modules.begin());
1078 const std::set<std::string>& deps = libinfo->GetDependencies();
1079 for (std::set<std::string>::const_iterator iDep = deps.begin();
1080 iDep != deps.end(); ++iDep) {
1081 // cannot create dependency on iDep directly, use its first module instead.
1082 TLibraryDocInfo* depLibInfo = (TLibraryDocInfo*)
1083 fHtml->GetLibraryDependencies()->FindObject(iDep->c_str());
1084 if (!depLibInfo || depLibInfo->GetModules().empty())
1085 continue; // ouch!
1086
1087 const std::string& moddep = *(depLibInfo->GetModules().begin());
1088 sstrDeps << "\"" << mod << "\" -> \"" << moddep << "\";" << std::endl;
1089 }
1090 // make sure libCore ends up at the bottom
1091 sstrDeps << "\"" << mod << "\" -> \"CONT\" [style=invis];" << std::endl;
1092 } // for libs
1093
1094 libDepDotFile << sstrCluster.str() << std::endl
1095 << sstrDeps.str();
1096 libDepDotFile << "}" << std::endl;
1097 libDepDotFile.close();
1098
1099 std::ofstream out(dotfilename + ".html");
1100 if (!out.good()) {
1101 Error("CreateModuleIndex", "Can't open file '%s.html' !",
1102 dotfilename.Data());
1103 return;
1104 }
1105
1106 Printf(fHtml->GetCounterFormat(), "", fHtml->GetCounter(), (dotfilename + ".html").Data());
1107 // write out header
1108 WriteHtmlHeader(out, "Library Dependencies");
1109
1110 WriteTopLinks(out, 0);
1111
1112 out << "<h1>Library Dependencies</h1>" << std::endl;
1113
1114 RunDot(dotfilename, &out, kFdp);
1115
1116 out << "<img alt=\"Library Dependencies\" class=\"classcharts\" usemap=\"#Map" << title << "\" src=\"" << title << ".png\"/>" << std::endl;
1117
1118 // write out footer
1119 WriteHtmlFooter(out);
1120}
1121
1122////////////////////////////////////////////////////////////////////////////////
1123/// Fetch documentation from THtml::GetProductDocDir() and put it into the
1124/// product index page.
1125
1127{
1128 //TString outFile(GetHtml()->GetProductName());
1129 //outFile += ".html";
1130 TString outFile("index.html");
1131 gSystem->PrependPathName(GetHtml()->GetOutputDir(), outFile);
1132 std::ofstream out(outFile);
1133
1134 if (!out.good()) {
1135 Error("CreateProductIndex", "Can't open file '%s' !", outFile.Data());
1136 return;
1137 }
1138
1139 Printf(fHtml->GetCounterFormat(), "", "", outFile.Data());
1140
1141 WriteHtmlHeader(out, GetHtml()->GetProductName() + " Reference Guide");
1142
1143 WriteTopLinks(out, 0);
1144
1145 out << "<h1>" << GetHtml()->GetProductName() + " Reference Guide</h1>" << std::endl;
1146
1147 TString prodDoc;
1148 if (GetHtml()->GetPathDefinition().GetDocDir("", prodDoc))
1149 ProcessDocInDir(out, prodDoc, GetHtml()->GetOutputDir(), "./");
1150
1151 WriteModuleLinks(out);
1152
1153 out << "<h2>Chapters</h2>" << std::endl
1154 << "<h3><a href=\"./ClassIndex.html\">Class Index</a></h3>" << std::endl
1155 << "<p>A complete list of all classes defined in " << GetHtml()->GetProductName() << "</p>" << std::endl
1156 << "<h3><a href=\"./ClassHierarchy.html\">Class Hierarchy</a></h3>" << std::endl
1157 << "<p>A hierarchy graph of all classes, showing each class's base and derived classes</p>" << std::endl
1158 << "<h3><a href=\"./ListOfTypes.html\">Type Index</a></h3>" << std::endl
1159 << "<p>A complete list of all types</p>" << std::endl
1160 << "<h3><a href=\"./LibraryDependencies.html\">Library Dependency</a></h3>" << std::endl
1161 << "<p>A diagram showing all of " << GetHtml()->GetProductName() << "'s libraries and their dependencies</p>" << std::endl;
1162
1163 WriteHtmlFooter(out);
1164}
1165
1166////////////////////////////////////////////////////////////////////////////////
1167/// Create a forwarding page for each typedef pointing to a class.
1168
1170{
1171 TDocParser parser(*this);
1172
1173 TIter iClass(GetHtml()->GetListOfClasses());
1174 TClassDocInfo* cdi = 0;
1175 while ((cdi = (TClassDocInfo*) iClass())) {
1176 if (cdi->GetListOfTypedefs().IsEmpty())
1177 continue;
1178 TIter iTypedefs(&cdi->GetListOfTypedefs());
1179 TDataType* dt = 0;
1180 while ((dt = (TDataType*) iTypedefs())) {
1181 if (gDebug > 0)
1182 Info("CreateClassTypeDefs", "Creating typedef %s to class %s",
1183 dt->GetName(), cdi->GetName());
1184 // create a filename
1185 TString filename(dt->GetName());
1186 NameSpace2FileName(filename);
1187
1189
1190 filename += ".html";
1191
1192 // open class file
1193 std::ofstream outfile(filename);
1194
1195 if (!outfile.good()) {
1196 Error("CreateClassTypeDefs", "Can't open file '%s' !", filename.Data());
1197 continue;
1198 }
1199
1200 WriteHtmlHeader(outfile, dt->GetName());
1201
1202 outfile << "<a name=\"TopOfPage\"></a>" << std::endl;
1203
1204 TString dtName(dt->GetName());
1205 ReplaceSpecialChars(dtName);
1206 TString sTitle("typedef ");
1207 sTitle += dtName;
1208
1209 TClass* cls = dynamic_cast<TClass*>(cdi->GetClass());
1210 if (cls) {
1211 // show box with lib, include
1212 // needs to go first to allow title on the left
1213 TString sInclude;
1214 TString sLib;
1215 const char* lib=cls->GetSharedLibs();
1216 GetHtml()->GetPathDefinition().GetIncludeAs(cls, sInclude);
1217 if (lib) {
1218 char* libDup=StrDup(lib);
1219 char* libDupSpace=strchr(libDup,' ');
1220 if (libDupSpace) *libDupSpace = 0;
1221 char* libDupEnd=libDup+strlen(libDup);
1222 while (libDupEnd!=libDup)
1223 if (*(--libDupEnd)=='.') {
1224 *libDupEnd=0;
1225 break;
1226 }
1227 sLib = libDup;
1228 delete[] libDup;
1229 }
1230 outfile << "<script type=\"text/javascript\">WriteFollowPageBox('"
1231 << sTitle << "','" << sLib << "','" << sInclude << "');</script>" << std::endl;
1232 }
1233
1234 TString modulename;
1235 fHtml->GetModuleNameForClass(modulename, cls);
1236 TModuleDocInfo* module = (TModuleDocInfo*) fHtml->GetListOfModules()->FindObject(modulename);
1237 WriteTopLinks(outfile, module, dt->GetName());
1238
1239 outfile << "<div class=\"dropshadow\"><div class=\"withshadow\">";
1240 outfile << "<h1>" << sTitle << "</h1>" << std::endl
1241 << "<div class=\"classdescr\">" << std::endl;
1242
1243 outfile << dtName << " is a typedef to ";
1244 std::string shortClsName(fHtml->ShortType(cdi->GetName()));
1245 parser.DecorateKeywords(outfile, shortClsName.c_str());
1246 outfile << std::endl
1247 << "</div>" << std::endl
1248 << "</div></div><div style=\"clear:both;\"></div>" << std::endl;
1249
1250 // the typedef isn't a data member, but the CSS is applicable nevertheless
1251 outfile << std::endl << "<div id=\"datamembers\">" << std::endl
1252 << "<table class=\"data\" cellspacing=\"0\">" << std::endl;
1253 outfile << "<tr class=\"data";
1254 outfile << "\"><td class=\"datatype\">typedef ";
1255 parser.DecorateKeywords(outfile, dt->GetFullTypeName());
1256 outfile << "</td><td class=\"dataname\">";
1257 ReplaceSpecialChars(outfile, dt->GetName());
1258 if (dt->GetTitle() && dt->GetTitle()[0]) {
1259 outfile << "</td><td class=\"datadesc\">";
1260 ReplaceSpecialChars(outfile, dt->GetTitle());
1261 } else outfile << "</td><td>";
1262 outfile << "</td></tr>" << std::endl
1263 << "</table></div>" << std::endl;
1264
1265 // write footer
1266 WriteHtmlFooter(outfile);
1267
1268 }
1269 }
1270}
1271
1272////////////////////////////////////////////////////////////////////////////////
1273/// Create index of all data types
1274
1276{
1277 // open file
1278 TString outFile("ListOfTypes.html");
1280 std::ofstream typesList(outFile);
1281
1282 if (!typesList.good()) {
1283 Error("CreateTypeIndex", "Can't open file '%s' !", outFile.Data());
1284 return;
1285 }
1286
1287 Printf(fHtml->GetCounterFormat(), "", "", outFile.Data());
1288
1289 // write typesList header
1290 WriteHtmlHeader(typesList, "List of data types");
1291 typesList << "<h2> List of data types </h2>" << std::endl;
1292
1293 typesList << "<dl><dd>" << std::endl;
1294
1295 // make loop on data types
1296 std::vector<std::string> typeNames(gROOT->GetListOfTypes()->GetSize());
1297
1298 {
1299 TDataType *type;
1300 TIter nextType(gROOT->GetListOfTypes());
1301 size_t tnIdx = 0;
1302
1303 while ((type = (TDataType *) nextType()))
1304 // no templates ('<' and '>'), no idea why the '(' is in here...
1305 if (*type->GetTitle() && !strchr(type->GetName(), '(')
1306 && !( strchr(type->GetName(), '<') && strchr(type->GetName(),'>'))
1307 && type->GetName())
1308 typeNames[tnIdx++] = type->GetName();
1309 typeNames.resize(tnIdx);
1310 }
1311
1312 sort_strlist_stricmp(typeNames);
1313
1314 std::vector<std::string> indexChars;
1315 if (typeNames.size() > 10) {
1316 typesList << "<div id=\"indxShortX\"><h4>Jump to</h4>" << std::endl;
1317 // find index chars
1318 GetIndexChars(typeNames, 10 /*sections*/, indexChars);
1319 for (UInt_t iIdxEntry = 0; iIdxEntry < indexChars.size(); ++iIdxEntry) {
1320 typesList << "<a href=\"#idx" << iIdxEntry << "\">";
1321 ReplaceSpecialChars(typesList, indexChars[iIdxEntry].c_str());
1322 typesList << "</a>" << std::endl;
1323 }
1324 typesList << "</div><br />" << std::endl;
1325 }
1326
1327 typesList << "<ul id=\"indx\">" << std::endl;
1328
1329 int idx = 0;
1330 UInt_t currentIndexEntry = 0;
1331
1332 for (std::vector<std::string>::iterator iTypeName = typeNames.begin();
1333 iTypeName != typeNames.end(); ++iTypeName) {
1334 TDataType* type = gROOT->GetType(iTypeName->c_str(), kFALSE);
1335 typesList << "<li class=\"idxl" << idx%2 << "\">";
1336 if (currentIndexEntry < indexChars.size()
1337 && !strncmp(indexChars[currentIndexEntry].c_str(), iTypeName->c_str(),
1338 indexChars[currentIndexEntry].length()))
1339 typesList << "<a name=\"idx" << currentIndexEntry++ << "\"></a>" << std::endl;
1340 typesList << "<a name=\"";
1341 ReplaceSpecialChars(typesList, iTypeName->c_str());
1342 typesList << "\"><span class=\"typename\">";
1343 ReplaceSpecialChars(typesList, iTypeName->c_str());
1344 typesList << "</span></a> ";
1345 ReplaceSpecialChars(typesList, type->GetTitle());
1346 typesList << "</li>" << std::endl;
1347 ++idx;
1348 }
1349 typesList << "</ul>" << std::endl;
1350
1351 // write typesList footer
1352 WriteHtmlFooter(typesList);
1353
1354 // close file
1355 typesList.close();
1356
1357}
1358
1359
1360////////////////////////////////////////////////////////////////////////////////
1361/// Add some colors etc to a source entity, contained in str.
1362/// The type of what's contained in str is given by type.
1363/// It's called e.g. by TDocParser::BeautifyLine().
1364/// This function should assume that only str.Begin() is valid.
1365/// When inserting into str.String(), str.Begin() must be updated.
1366
1368{
1369 Ssiz_t originalLen = str.Length();
1370
1371 switch (type) {
1372 case TDocParser::kCode: break;
1374 str.Insert(pos, "<span class=\"comment\">");
1375 break;
1377 break;
1379 str.Insert(pos, "<span class=\"string\">");
1380 break;
1382 str.Insert(pos, "<span class=\"keyword\">");
1383 break;
1384 case TDocParser::kCPP:
1385 str.Insert(pos, "<span class=\"cpp\">");
1386 break;
1388 str.Insert(pos, "<pre>");
1389 break;
1390 default:
1391 Error("DecorateEntityBegin", "Unhandled / invalid entity type %d!", (Int_t)type);
1392 return;
1393 }
1394
1395 Ssiz_t addedLen = str.Length() - originalLen;
1396 pos += addedLen;
1397}
1398
1399////////////////////////////////////////////////////////////////////////////////
1400/// Add some colors etc to a source entity, contained in str.
1401/// The type of what's contained in str is given by type.
1402/// It's called e.g. by TDocParser::BeautifyLine().
1403/// This function should assume that only str."End()"
1404/// (i.e. str.Begin()+str.Length()) is valid.
1405/// When inserting into str.String(), str.Length() must be updated.
1406
1408{
1409 Ssiz_t originalLen = str.Length();
1410
1411 switch (type) {
1412 case TDocParser::kCode: break;
1414 str.Insert(pos, "</span>");
1415 break;
1417 break;
1419 str.Insert(pos, "</span>");
1420 break;
1422 str.Insert(pos, "</span>");
1423 break;
1424 case TDocParser::kCPP:
1425 str.Insert(pos, "</span>");
1426 break;
1428 str.Insert(pos, "</pre>");
1429 break;
1430 default:
1431 Error("DecorateEntityBegin", "Unhandled / invalid entity type %d!", (Int_t)type);
1432 return;
1433 }
1434 Ssiz_t addedLen = str.Length() - originalLen;
1435 pos += addedLen;
1436}
1437
1438////////////////////////////////////////////////////////////////////////////////
1439/// Special author treatment; called when TDocParser::fSourceInfo[kInfoAuthor] is set.
1440/// Modifies the author(s) description, which is a comma separated list of tokens
1441/// either in the format
1442/// (i) "FirstName LastName " or
1443/// (ii) "FirstName LastName <link> more stuff"
1444/// The first one generates an XWho link (CERN compatible),
1445/// the second a http link (WORLD compatible), <link> being e.g.
1446/// <mailto:user@host.bla> or <http://www.host.bla/page>.
1447
1449{
1450 TString original(authors);
1451 authors = "";
1452
1453 TString author;
1454 Ssiz_t pos = 0;
1455 Bool_t firstAuthor = kTRUE;
1456 while (original.Tokenize(author, pos, ",")) {
1457 author.Strip(TString::kBoth);
1458
1459 if (!firstAuthor)
1460 authors += ", ";
1461 firstAuthor = kFALSE;
1462
1463 // do we have a link for the current name?
1464 Ssiz_t cLink = author.First('<'); // look for link start tag
1465 if (cLink != kNPOS) {
1466 // split NAME <LINK> POST
1467 // into <a href="LINK">NAME</a> POST
1468 Ssiz_t endLink = author.Index(">", cLink + 1);
1469 if(endLink == kNPOS)
1470 endLink = author.Length();
1471 authors += "<a href=\"";
1472 authors += author(cLink + 1, endLink - (cLink + 1));
1473 authors += "\">";
1474 authors += author(0, cLink);
1475 authors += "</a>";
1476 if (endLink != author.Length())
1477 authors += author(endLink + 1, author.Length());
1478 } else {
1479 authors += "<a href=\"";
1480 authors += fHtml->GetXwho();
1481
1482 // separate Firstname Middlename Lastname by '+'
1483 TString namePart;
1484 Ssiz_t posNamePart = 0;
1485 Bool_t firstNamePart = kTRUE;
1486 while (author.Tokenize(namePart, posNamePart, " ")) {
1487 namePart.Strip(TString::kBoth);
1488 if (!namePart.Length())
1489 continue;
1490 if (isdigit(namePart[0])) continue; //likely a date
1491 if (!firstNamePart)
1492 authors += '+';
1493 firstNamePart = kFALSE;
1494 authors += namePart;
1495 }
1496 authors += "\">";
1497 authors += author;
1498 authors += "</a>";
1499 }
1500 } // while next author
1501}
1502
1503////////////////////////////////////////////////////////////////////////////////
1504/// Check if file is modified
1505///
1506///
1507/// Input: classPtr - pointer to the class
1508/// type - file type to compare with
1509/// values: kSource, kInclude, kTree
1510///
1511/// Output: TRUE - if file is modified since last time
1512/// FALSE - if file is up to date
1513///
1514
1516{
1517 TString sourceFile;
1518 TString classname(classPtr->GetName());
1519 TString filename;
1520 TString dir;
1521
1522 switch (type) {
1523 case kSource:
1524 {
1525 TString declFile;
1526 if (classPtr->GetImplFileLine()) {
1527 fHtml->GetImplFileName(classPtr, kTRUE, sourceFile);
1528 }
1529 fHtml->GetDeclFileName(classPtr, kTRUE, declFile);
1530 Long64_t size;
1531 Long_t id, flags, iModtime, dModtime;
1532 if (!(gSystem->GetPathInfo(sourceFile, &id, &size, &flags, &iModtime))) {
1533 if (!(gSystem->GetPathInfo(declFile, &id, &size, &flags, &dModtime))) {
1534 if (iModtime < dModtime) {
1535 // decl is newer than impl
1536 sourceFile = declFile;
1537 }
1538 }
1539 }
1540 dir = "src";
1542 filename = classname;
1543 NameSpace2FileName(filename);
1544 gSystem->PrependPathName(dir, filename);
1545 if (classPtr->GetImplFileLine())
1546 filename += ".cxx.html";
1547 else
1548 filename += ".h.html";
1549 break;
1550 }
1551
1552 case kInclude:
1553 fHtml->GetDeclFileName(classPtr, kFALSE, filename);
1554 filename = gSystem->BaseName(filename);
1555 fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
1557 break;
1558
1559 case kTree:
1560 fHtml->GetDeclFileName(classPtr, kTRUE, sourceFile);
1561 NameSpace2FileName(classname);
1562 gSystem->PrependPathName(fHtml->GetOutputDir(), classname);
1563 filename = classname;
1564 filename += "_Tree.pdf";
1565 break;
1566
1567 case kDoc:
1568 {
1569 TString declFile;
1570 if (classPtr->GetImplFileLine()) {
1571 fHtml->GetImplFileName(classPtr, kTRUE, sourceFile);
1572 }
1573 fHtml->GetDeclFileName(classPtr, kTRUE, declFile);
1574 Long64_t size;
1575 Long_t id, flags, iModtime, dModtime;
1576 if (!(gSystem->GetPathInfo(sourceFile, &id, &size, &flags, &iModtime))) {
1577 if (!(gSystem->GetPathInfo(declFile, &id, &size, &flags, &dModtime))) {
1578 if (iModtime < dModtime) {
1579 // decl is newer than impl
1580 sourceFile = declFile;
1581 }
1582 }
1583 }
1584 filename = classname;
1585 NameSpace2FileName(filename);
1587 filename += ".html";
1588 break;
1589 }
1590
1591 default:
1592 Error("IsModified", "Unknown file type !");
1593 }
1594
1595 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
1596
1597 // Get info about a file
1598 Long64_t size;
1599 Long_t id, flags, sModtime, dModtime;
1600
1601 if (!(gSystem->GetPathInfo(sourceFile, &id, &size, &flags, &sModtime))) {
1602 if (!(gSystem->GetPathInfo(filename, &id, &size, &flags, &dModtime))) {
1603 return (sModtime > dModtime);
1604 }
1605 }
1606
1607 return kTRUE;
1608}
1609
1610
1611////////////////////////////////////////////////////////////////////////////////
1612/// Replace "::" in name by "__"
1613/// Replace "<", ">", " ", ",", "~", "=" in name by "_"
1614/// Replace "A::X<A::Y>" by "A::X<-p0Y>",
1615/// "A::B::X<A::B::Y>" by "A::B::X<-p1Y>", etc
1616
1618{
1619 TString encScope(name);
1620 Ssiz_t posTemplate = encScope.Index('<');
1621 if (posTemplate != kNPOS) {
1622 // strip default template params
1624 TString templateArgs = encScope(posTemplate, encScope.Length());
1625 encScope.Remove(posTemplate, encScope.Length());
1626 // shorten the name a bit:
1627 // convert A::B::X<A::B::Y> to A::X<-p1Y>, i.e.
1628 // the filename A__X_A__Y_ to A__X_-p1Y_
1629 // The rule: if the enclosing scope up to the N-th scope matches,
1630 // the name becomes -pN
1631 Ssiz_t posName = encScope.Last(':');
1632 if (posName != kNPOS) {
1633 Int_t numDblColumn = encScope.CountChar(':');
1634 while (numDblColumn > 1) {
1635 encScope.Remove(posName + 1, encScope.Length());
1636 numDblColumn -= 2;
1637 templateArgs.ReplaceAll(encScope, TString::Format("-p%d", numDblColumn / 2));
1638 encScope.Remove(encScope.Length() - 2, 2);
1639 posName = encScope.Last(':');
1640 if (posName == kNPOS)
1641 break; // should be handled by numDblColumn...
1642 }
1643 name.Replace(posTemplate, name.Length(), templateArgs);
1644 }
1645 }
1646
1647 if (name.Length() > 240) { // really 240! It might get some extra prefix or extension
1648 // 8.3 is dead, but e.g. ext2 can only hold 255 chars in a file name.
1649 // So mangle name to "beginning_of_name"-h"hash"."extension", where
1650 // beginning_of_name is short enough such that the full name is <255 characters.
1651
1652 TString hash;
1654 hash.Prepend("-h");
1655 Ssiz_t posDot = name.Last('.');
1656 TString ext;
1657 if (posDot != kNPOS)
1658 ext = name(posDot, name.Length());
1659 Ssiz_t namelen = 240 - hash.Length() - ext.Length();
1660 name = name(0, namelen) + hash + ext;
1661 }
1662
1663 const char* replaceWhat = ":<> ,~=";
1664 for (Ssiz_t i=0; i < name.Length(); ++i)
1665 if (strchr(replaceWhat, name[i]))
1666 name[i] = '_';
1667}
1668
1669////////////////////////////////////////////////////////////////////////////////
1670/// Write links to files indir/*.txt, indir/*.html (non-recursive) to out.
1671/// If one of the files is called "index.{html,txt}" it will be
1672/// included in out (instead of copying it to outdir and generating a link
1673/// to linkdir). txt files are passed through Convert().
1674/// The files' links are sorted alphabetically.
1675
1676void TDocOutput::ProcessDocInDir(std::ostream& out, const char* indir,
1677 const char* outdir, const char* linkdir)
1678{
1679 R__LOCKGUARD(GetHtml()->GetMakeClassMutex());
1680
1681 void * dirHandle = gSystem->OpenDirectory(indir);
1682 if (!dirHandle) return;
1683
1684 const char* entry = 0;
1685 std::list<std::string> files;
1686 while ((entry = gSystem->GetDirEntry(dirHandle))) {
1687 FileStat_t stat;
1688 TString filename(entry);
1689 gSystem->PrependPathName(indir, filename);
1690 if (gSystem->GetPathInfo(filename, stat)) // funny ret
1691 continue;
1692 if (!R_ISREG(stat.fMode)) continue;
1693
1694 if (TString(entry).BeginsWith("index.", TString::kIgnoreCase)) {
1695 // This is the part we put directly (verbatim) into the module index.
1696 // If it ends on ".txt" we run Convert first.
1697 if (filename.EndsWith(".txt", TString::kIgnoreCase)) {
1698 std::ifstream in(filename);
1699 if (in) {
1700 out << "<pre>"; // this is what e.g. the html directive expects
1701 TDocParser parser(*this);
1702 parser.Convert(out, in, "./", kFALSE /* no code */, kTRUE /*process Directives*/);
1703 out << "</pre>";
1704 }
1705 } else if (filename.EndsWith(".html", TString::kIgnoreCase)) {
1706 std::ifstream in(filename);
1707 TString line;
1708 while (in) {
1709 if (!line.ReadLine(in)) break;
1710 out << line << std::endl;
1711 }
1712 } else
1713 files.push_back(filename.Data());
1714 } else
1715 files.push_back(filename.Data());
1716 }
1717
1718 std::stringstream furtherReading;
1719 files.sort();
1720 for (std::list<std::string>::const_iterator iFile = files.begin();
1721 iFile != files.end(); ++iFile) {
1722 TString filename(iFile->c_str());
1723 if (gSystem->AccessPathName(outdir))
1724 if (gSystem->mkdir(outdir, kTRUE) == -1)
1725 // bad - but let's still try to create the output
1726 Error("CreateModuleIndex", "Cannot create output directory %s", outdir);
1727
1728 TString outfile(gSystem->BaseName(filename));
1729 gSystem->PrependPathName(outdir, outfile);
1730
1731 if (!filename.EndsWith(".txt", TString::kIgnoreCase)
1732 && !filename.EndsWith(".html", TString::kIgnoreCase)) {
1733 // copy to outdir, who know whether it's needed...
1734 if (gSystem->CopyFile(filename, outfile, kTRUE) == -1) {
1735 Error("CreateModuleIndex", "Cannot copy file %s to %s",
1736 filename.Data(), outfile.Data());
1737 continue;
1738 }
1739 continue;
1740 }
1741
1742 // Just copy and link this page.
1743 if (outfile.EndsWith(".txt", TString::kIgnoreCase)) {
1744 // convert first
1745 outfile.Remove(outfile.Length()-3, 3);
1746 outfile += "html";
1747 std::ifstream inFurther(filename);
1748 std::ofstream outFurther(outfile);
1749 if (inFurther && outFurther) {
1750 outFurther << "<pre>"; // this is what e.g. the html directive expects
1751 TDocParser parser(*this);
1752 parser.Convert(outFurther, inFurther, "../", kFALSE /*no code*/, kTRUE /*process Directives*/);
1753 outFurther << "</pre>";
1754 }
1755 } else {
1756 if (gSystem->CopyFile(filename, outfile, kTRUE) == -1)
1757 continue;
1758 }
1759 TString showname(gSystem->BaseName(outfile));
1760 furtherReading << "<a class=\"linkeddoc\" href=\"" << linkdir << "/" << showname << "\">";
1761 showname.Remove(showname.Length() - 5, 5); // .html
1762 showname.ReplaceAll("_", " ");
1763 ReplaceSpecialChars(furtherReading, showname);
1764 furtherReading << "</a> " << std::endl;
1765 }
1766
1767 gSystem->FreeDirectory(dirHandle);
1768 if (furtherReading.str().length())
1769 out << "<h3>Further Reading</h3><div id=\"furtherreading\">" << std::endl
1770 << furtherReading.str() << "</div><h3>List of Classes</h3>" << std::endl;
1771}
1772
1773////////////////////////////////////////////////////////////////////////////////
1774/// Create a reference to a class documentation page.
1775/// str encloses the text to create the reference for (e.g. name of instance).
1776/// comment will be added e.g. as tooltip text.
1777/// After the reference is put into str.String(), str will enclose the reference
1778/// and the original text. Example:
1779/// Input:
1780/// str.String(): "a gHtml test"
1781/// str.Begin(): 2
1782/// str.Length(): 5
1783/// Output:
1784/// str.String(): "a <a href="THtml.html">gHtml</a> test"
1785/// str.Begin(): 2
1786/// str.Length(): 30
1787
1788void TDocOutput::ReferenceEntity(TSubString& str, TClass* entity, const char* comment /*= 0*/)
1789{
1790 TString link;
1791 fHtml->GetHtmlFileName(entity, link);
1792
1793 if (comment && !strcmp(comment, entity->GetName()))
1794 comment = "";
1795
1796 AddLink(str, link, comment);
1797}
1798
1799////////////////////////////////////////////////////////////////////////////////
1800/// Create a reference to a data member documentation page.
1801/// str encloses the text to create the reference for (e.g. name of instance).
1802/// comment will be added e.g. as tooltip text.
1803/// After the reference is put into str.String(), str will enclose the reference
1804/// and the original text. Example:
1805/// Input:
1806/// str.String(): "a gHtml test"
1807/// str.Begin(): 2
1808/// str.Length(): 5
1809/// Output:
1810/// str.String(): "a <a href="THtml.html">gHtml</a> test"
1811/// str.Begin(): 2
1812/// str.Length(): 30
1813
1814void TDocOutput::ReferenceEntity(TSubString& str, TDataMember* entity, const char* comment /*= 0*/)
1815{
1816 TString link;
1817 TClass* scope = entity->GetClass();
1818 fHtml->GetHtmlFileName(scope, link);
1819 link += "#";
1820
1821 TString mangledName;
1822 if (scope) {
1823 mangledName = scope->GetName();
1824 NameSpace2FileName(mangledName);
1825 link += mangledName;
1826 link += ":";
1827 }
1828
1829 mangledName = entity->GetName();
1830 NameSpace2FileName(mangledName);
1831 link += mangledName;
1832
1833 TString description;
1834 if (!comment) {
1835 description = entity->GetFullTypeName();
1836 description += " ";
1837 if (scope) {
1838 description += scope->GetName();
1839 description += "::";
1840 }
1841 description += entity->GetName();
1842 comment = description.Data();
1843 }
1844
1845 if (comment && !strcmp(comment, entity->GetName()))
1846 comment = "";
1847
1848 AddLink(str, link, comment);
1849}
1850
1851////////////////////////////////////////////////////////////////////////////////
1852/// Create a reference to a type documentation page.
1853/// str encloses the text to create the reference for (e.g. name of instance).
1854/// comment will be added e.g. as tooltip text.
1855/// After the reference is put into str.String(), str will enclose the reference
1856/// and the original text. Example:
1857/// Input:
1858/// str.String(): "a gHtml test"
1859/// str.Begin(): 2
1860/// str.Length(): 5
1861/// Output:
1862/// str.String(): "a <a href="THtml.html">gHtml</a> test"
1863/// str.Begin(): 2
1864/// str.Length(): 30
1865
1866void TDocOutput::ReferenceEntity(TSubString& str, TDataType* entity, const char* comment /*= 0*/)
1867{
1868 TString mangledEntity(entity->GetName());
1869 NameSpace2FileName(mangledEntity);
1870
1871 TString link;
1872 TClassDocInfo* cdi = 0;
1873 bool isClassTypedef = entity->GetType() == -1;
1874 if (isClassTypedef)
1875 /* is class/ struct / union */
1876 isClassTypedef = isClassTypedef && (entity->Property() & 7);
1877 if (isClassTypedef) {
1878 std::string shortTypeName(fHtml->ShortType(entity->GetFullTypeName()));
1879 cdi = (TClassDocInfo*) GetHtml()->GetListOfClasses()->FindObject(shortTypeName.c_str());
1880 }
1881 if (cdi) {
1882 link = mangledEntity + ".html";
1883 } else {
1884 link = "ListOfTypes.html#";
1885 link += mangledEntity;
1886 }
1887
1888 if (comment && !strcmp(comment, entity->GetName()))
1889 comment = "";
1890
1891 AddLink(str, link, comment);
1892}
1893
1894////////////////////////////////////////////////////////////////////////////////
1895/// Create a reference to a method documentation page.
1896/// str encloses the text to create the reference for (e.g. name of instance).
1897/// comment will be added e.g. as tooltip text.
1898/// After the reference is put into str.String(), str will enclose the reference
1899/// and the original text. Example:
1900/// Input:
1901/// str.String(): "a gHtml test"
1902/// str.Begin(): 2
1903/// str.Length(): 5
1904/// Output:
1905/// str.String(): "a <a href="THtml.html">gHtml</a> test"
1906/// str.Begin(): 2
1907/// str.Length(): 30
1908
1909void TDocOutput::ReferenceEntity(TSubString& str, TMethod* entity, const char* comment /*= 0*/)
1910{
1911 TString link;
1912 TClass* scope = entity->GetClass();
1913 fHtml->GetHtmlFileName(scope, link);
1914 link += "#";
1915
1916 TString mangledName(scope->GetName());
1917 NameSpace2FileName(mangledName);
1918 link += mangledName;
1919 link += ":";
1920
1921 mangledName = entity->GetName();
1922 NameSpace2FileName(mangledName);
1923 link += mangledName;
1924
1925 TString description;
1926 if (!comment && entity->GetClass()) {
1927 TIter iMeth(scope->GetListOfMethods());
1928 TMethod* mCand = 0;
1929 while ((mCand = (TMethod*)iMeth()))
1930 if (!strcmp(mCand->GetName(), entity->GetName())) {
1931 if (description.Length()) {
1932 description += " or overloads";
1933 break;
1934 }
1935 description = mCand->GetPrototype();
1936 }
1937 comment = description.Data();
1938 }
1939
1940 if (comment && !strcmp(comment, entity->GetName()))
1941 comment = "";
1942
1943 AddLink(str, link, comment);
1944}
1945
1946////////////////////////////////////////////////////////////////////////////////
1947/// Check whether reference is a relative reference, and can (or should)
1948/// be prependen by relative paths. For HTML, check that it doesn't start
1949/// with "http://" or "https://"
1950
1951Bool_t TDocOutput::ReferenceIsRelative(const char* reference) const
1952{
1953 return !reference ||
1954 strncmp(reference, "http", 4) ||
1955 (strncmp(reference + 4, "://", 3) && strncmp(reference + 4, "s://", 4));
1956}
1957
1958////////////////////////////////////////////////////////////////////////////////
1959/// Replace ampersand, less-than and greater-than character, writing to out.
1960/// If 0 is returned, no replacement needs to be done.
1961
1963{
1964 /*
1965 if (fEscFlag) {
1966 fEscFlag = kFALSE;
1967 return buf;
1968 } else if (c == fEsc) {
1969 // text.Remove(pos, 1); - NO! we want to keep it nevertheless!
1970 fEscFlag = kTRUE;
1971 return buf;
1972 }
1973
1974 */
1975 switch (c) {
1976 case '<': return "&lt;";
1977 case '&': return "&amp;";
1978 case '>': return "&gt;";
1979 };
1980 return 0;
1981}
1982
1983////////////////////////////////////////////////////////////////////////////////
1984/// Replace ampersand, less-than and greater-than character
1985///
1986///
1987/// Input: text - text where replacement will happen,
1988/// pos - index of char to be replaced; will point to next char to be
1989/// replaced when function returns
1990///
1991
1993{
1994 const char c = text[pos];
1995 const char* replaced = ReplaceSpecialChars(c);
1996 if (replaced) {
1997 text.Replace(pos, 1, replaced);
1998 pos += strlen(replaced) - 1;
1999 }
2000 ++pos;
2001}
2002
2003////////////////////////////////////////////////////////////////////////////////
2004/// Replace ampersand, less-than and greater-than character
2005///
2006///
2007/// Input: text - text where replacement will happen,
2008///
2009
2011 Ssiz_t pos = 0;
2012 while (pos < text.Length())
2014}
2015
2016////////////////////////////////////////////////////////////////////////////////
2017/// Replace ampersand, less-than and greater-than characters, writing to out
2018///
2019///
2020/// Input: out - output file stream
2021/// string - pointer to an array of characters
2022///
2023
2024void TDocOutput::ReplaceSpecialChars(std::ostream& out, const char *string)
2025{
2026 while (string && *string) {
2027 const char* replaced = ReplaceSpecialChars(*string);
2028 if (replaced)
2029 out << replaced;
2030 else
2031 out << *string;
2032 string++;
2033 }
2034}
2035
2036////////////////////////////////////////////////////////////////////////////////
2037/// Run filename".dot", creating filename".png", and - if outMap is !=0,
2038/// filename".map", which gets then included literally into outMap.
2039
2040Bool_t TDocOutput::RunDot(const char* filename, std::ostream* outMap /* =0 */,
2041 EGraphvizTool gvwhat /*= kDot*/) {
2042 if (!fHtml->HaveDot())
2043 return kFALSE;
2044
2045 TString runDot;
2046 switch (gvwhat) {
2047 case kNeato: runDot = "neato"; break;
2048 case kFdp: runDot = "fdp"; break;
2049 case kCirco: runDot = "circo"; break;
2050 default: runDot = "dot";
2051 };
2052 if (fHtml->GetDotDir() && *fHtml->GetDotDir())
2054 runDot += " -q1 -Tpng -o";
2055 runDot += filename;
2056 runDot += ".png ";
2057 if (outMap) {
2058 runDot += "-Tcmap -o";
2059 runDot += filename;
2060 runDot += ".map ";
2061 }
2062 runDot += filename;
2063 runDot += ".dot";
2064
2065 if (gDebug > 3)
2066 Info("RunDot", "Running: %s", runDot.Data());
2067 Int_t retDot = gSystem->Exec(runDot);
2068 if (gDebug < 4 && !retDot)
2069 gSystem->Unlink(Form("%s.dot", filename));
2070
2071 if (!retDot && outMap) {
2072 std::ifstream inmap(Form("%s.map", filename));
2073 std::string line;
2074 std::getline(inmap, line);
2075 if (inmap && !inmap.eof()) {
2076 *outMap << "<map name=\"Map" << gSystem->BaseName(filename)
2077 << "\" id=\"Map" << gSystem->BaseName(filename) << "\">" << std::endl;
2078 while (inmap && !inmap.eof()) {
2079 if (line.compare(0, 6, "<area ") == 0) {
2080 size_t posEndTag = line.find('>');
2081 if (posEndTag != std::string::npos)
2082 line.replace(posEndTag, 1, "/>");
2083 }
2084 *outMap << line << std::endl;
2085 std::getline(inmap, line);
2086 }
2087 *outMap << "</map>" << std::endl;
2088 }
2089 inmap.close();
2090 if (gDebug < 7)
2091 gSystem->Unlink(Form("%s.map", filename));
2092 }
2093
2094 if (retDot) {
2095 Error("RunDot", "Error running %s!", runDot.Data());
2097 return kFALSE;
2098 }
2099
2100 return kTRUE;
2101}
2102
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// Write HTML header
2106///
2107/// Internal method invoked by the overload
2108
2109void TDocOutput::WriteHtmlHeader(std::ostream& out, const char *titleNoSpecial,
2110 const char* dir /*=""*/, TClass *cls /*=0*/,
2111 const char* header)
2112{
2113 std::ifstream addHeaderFile(header);
2114
2115 if (!addHeaderFile.good()) {
2116 Warning("THtml::WriteHtmlHeader",
2117 "Can't open html header file %s\n", header);
2118 return;
2119 }
2120
2121 TString declFileName;
2122 if (cls) fHtml->GetDeclFileName(cls, kFALSE, declFileName);
2123 TString implFileName;
2124 if (cls) fHtml->GetImplFileName(cls, kFALSE, implFileName);
2125
2126 const TString& charset = GetHtml()->GetCharset();
2127 TDatime date;
2128 TString strDate(date.AsString());
2129 TString line;
2130
2131 while (!addHeaderFile.eof()) {
2132
2133 line.ReadLine(addHeaderFile, kFALSE);
2134 if (addHeaderFile.eof())
2135 break;
2136
2137 if (line) {
2138
2139 if (!cls && (
2140 line.Index("%CLASS%") != kNPOS ||
2141 line.Index("%INCFILE%") != kNPOS ||
2142 line.Index("%SRCFILE%") != kNPOS))
2143 continue; // skip class line for non-class files
2144
2145 TString txt(line);
2146
2147 txt.ReplaceAll("%TITLE%", titleNoSpecial);
2148 txt.ReplaceAll("%DATE%", strDate);
2149 txt.ReplaceAll("%RELDIR%", dir);
2150 txt.ReplaceAll("%CHARSET%", charset);
2151
2152 if (cls) {
2153 txt.ReplaceAll("%CLASS%", cls->GetName());
2154 txt.ReplaceAll("%INCFILE%", declFileName);
2155 txt.ReplaceAll("%SRCFILE%", implFileName);
2156 }
2157
2158 out << txt << std::endl;
2159 }
2160 }
2161}
2162
2163////////////////////////////////////////////////////////////////////////////////
2164/// Write HTML header
2165///
2166///
2167/// Input: out - output file stream
2168/// title - title for the HTML page
2169/// cls - current class
2170/// dir - relative directory to reach the top
2171/// ("" for html doc, "../" for src/*cxx.html etc)
2172///
2173/// evaluates the Root.Html.Header setting:
2174/// * if not set, the standard header is written. (ROOT)
2175/// * if set, and ends with a "+", the standard header is written and this file
2176/// included afterwards. (ROOT, USER)
2177/// * if set but doesn't end on "+" the file specified will be written instead
2178/// of the standard header (USER)
2179///
2180/// Any occurrence of "%TITLE%" (without the quotation marks) in the user
2181/// provided header file will be replaced by the value of this method's
2182/// parameter "title" before written to the output file. %CLASS% is replaced by
2183/// the class name, %INCFILE% by the header file name as given by
2184/// TClass::GetDeclFileName() and %SRCFILE% by the source file name as given by
2185/// TClass::GetImplFileName(). If the header is written for a non-class page,
2186/// i.e. cls==0, lines containing %CLASS%, %INCFILE%, or %SRCFILE% will be
2187/// skipped.
2188
2189void TDocOutput::WriteHtmlHeader(std::ostream& out, const char *title,
2190 const char* dir /*=""*/, TClass *cls/*=0*/)
2191{
2192 TString userHeader = GetHtml()->GetHeader();
2193 TString noSpecialCharTitle(title);
2194 ReplaceSpecialChars(noSpecialCharTitle);
2195
2196 Ssiz_t lenUserHeader = userHeader.Length();
2197 // standard header output if Root.Html.Header is not set, or it's set and it ends with a "+".
2198 Bool_t bothHeaders = lenUserHeader > 0 && userHeader[lenUserHeader - 1] == '+';
2199 if (lenUserHeader == 0 || bothHeaders) {
2200 TString header("header.html");
2202 WriteHtmlHeader(out, noSpecialCharTitle, dir, cls, header);
2203 }
2204
2205 if (lenUserHeader != 0) {
2206 if (bothHeaders)
2207 userHeader.Remove(lenUserHeader - 1);
2208 WriteHtmlHeader(out, noSpecialCharTitle, dir, cls, userHeader);
2209 };
2210}
2211
2212////////////////////////////////////////////////////////////////////////////////
2213/// Write HTML footer
2214///
2215/// Internal method invoked by the overload
2216
2217void TDocOutput::WriteHtmlFooter(std::ostream& out, const char* /*dir*/,
2218 const char* lastUpdate, const char* author,
2219 const char* copyright, const char* footer)
2220{
2221 static const char* templateSITags[TDocParser::kNumSourceInfos] = { "%UPDATE%", "%AUTHOR%", "%COPYRIGHT%", "%CHANGED%", "%GENERATED%"};
2222
2223 TString today;
2224 TDatime dtToday;
2225 today.Form("%d-%02d-%02d %02d:%02d", dtToday.GetYear(), dtToday.GetMonth(), dtToday.GetDay(), dtToday.GetHour(), dtToday.GetMinute());
2226
2227 TString datimeString;
2228 if (!lastUpdate || !lastUpdate[0]) {
2229 lastUpdate = today;
2230 }
2231 const char* siValues[TDocParser::kNumSourceInfos] = { lastUpdate, author, copyright, lastUpdate, today };
2232
2233 std::ifstream addFooterFile(footer);
2234
2235 if (!addFooterFile.good()) {
2236 Warning("THtml::WriteHtmlFooter",
2237 "Can't open html footer file %s\n", footer);
2238 return;
2239 }
2240
2241 TString line;
2242 while (!addFooterFile.eof()) {
2243
2244 line.ReadLine(addFooterFile, kFALSE);
2245 if (addFooterFile.eof())
2246 break;
2247
2248 if (!line)
2249 continue;
2250
2251 for (Int_t siTag = 0; siTag < (Int_t) TDocParser::kNumSourceInfos; ++siTag) {
2252 Ssiz_t siPos = line.Index(templateSITags[siTag]);
2253 if (siPos != kNPOS) {
2254 if (siValues[siTag] && siValues[siTag][0])
2255 line.Replace(siPos, strlen(templateSITags[siTag]), siValues[siTag]);
2256 else
2257 line = ""; // skip e.g. %AUTHOR% lines if no author is set
2258 }
2259 }
2260
2261 out << line << std::endl;
2262 }
2263
2264}
2265
2266////////////////////////////////////////////////////////////////////////////////
2267/// Write HTML footer
2268///
2269///
2270/// Input: out - output file stream
2271/// dir - usually equal to "" or "../", depends of
2272/// current file directory position, i.e. if
2273/// file is in the fHtml->GetOutputDir(), then dir will be ""
2274/// lastUpdate - last update string
2275/// author - author's name
2276/// copyright - copyright note
2277///
2278/// Allows optional user provided footer to be written. Root.Html.Footer holds
2279/// the file name for this footer. For details see THtml::WriteHtmlHeader (here,
2280/// the "+" means the user's footer is written in front of Root's!) Occurrences
2281/// of %AUTHOR%, %CHANGED%, %GENERATED%, and %COPYRIGHT% in the user's file are replaced by
2282/// their corresponding values (author, lastUpdate, today, and copyright) before
2283/// written to out.
2284/// If no author is set (author == "", e.g. for ClassIndex.html") skip the whole
2285/// line of the footer template containing %AUTHOR%. Accordingly for %COPYRIGHT%.
2286
2287void TDocOutput::WriteHtmlFooter(std::ostream& out, const char *dir,
2288 const char *lastUpdate, const char *author,
2289 const char *copyright)
2290{
2291 out << std::endl;
2292
2293 TString userFooter = GetHtml()->GetFooter();
2294
2295 if (userFooter.Length() != 0) {
2296 TString footer(userFooter);
2297 if (footer.EndsWith("+"))
2298 footer.Remove(footer.Length() - 1);
2299 WriteHtmlFooter(out, dir, lastUpdate, author, copyright, footer);
2300 };
2301
2302 if (userFooter.Length() == 0 || userFooter.EndsWith("+")) {
2303 TString footer("footer.html");
2305 WriteHtmlFooter(out, dir, lastUpdate, author, copyright, footer);
2306 }
2307}
2308
2309////////////////////////////////////////////////////////////////////////////////
2310/// Create a div containing links to all topmost modules
2311
2312void TDocOutput::WriteModuleLinks(std::ostream& out)
2313{
2314 if (fHtml->GetListOfModules()->GetSize()) {
2315 out << "<div id=\"indxModules\"><h4>Modules</h4>" << std::endl;
2316 // find index chars
2318 TIter iModule(fHtml->GetListOfModules());
2319 TModuleDocInfo* module = 0;
2320 while ((module = (TModuleDocInfo*) iModule())) {
2321 if (!module->GetName() || strchr(module->GetName(), '/'))
2322 continue;
2323 if (module->IsSelected()) {
2324 TString name(module->GetName());
2325 name.ToUpper();
2326 out << "<a href=\"" << name << "_Index.html\">"
2327 << name << "</a>" << std::endl;
2328 }
2329 }
2330 out<< "</div><br />" << std::endl;
2331 }
2332}
2333
2334////////////////////////////////////////////////////////////////////////////////
2335/// Create a div containing the line numbers (for a source listing) 1 to nLines.
2336/// Create links to the source file's line number and anchors, such that one can
2337/// jump to SourceFile.cxx.html#27 (using the anchor), and one can copy and paste
2338/// the link into e.g. gdb to get the text "SourceFile.cxx:27".
2339
2340void TDocOutput::WriteLineNumbers(std::ostream& out, Long_t nLines, const TString& infileBase) const
2341{
2342 out << "<div id=\"linenums\">";
2343 for (Long_t i = 0; i < nLines; ++i) {
2344 // &nbsp; to force correct line height
2345 out << "<div class=\"ln\">&nbsp;<span class=\"lnfile\">" << infileBase
2346 << ":</span><a name=\"" << i + 1 << "\" href=\"#" << i + 1
2347 << "\" class=\"ln\">" << i + 1 << "</a></div>";
2348 }
2349 out << "</div>" << std::endl;
2350
2351}
2352
2353////////////////////////////////////////////////////////////////////////////////
2354/// Create a div containing links to all modules
2355
2356void TDocOutput::WriteModuleLinks(std::ostream& out, TModuleDocInfo* super)
2357{
2358 if (super->GetSub().GetSize()) {
2359 TString superName(super->GetName());
2360 superName.ToUpper();
2361 out << "<div id=\"indxModules\"><h4>" << superName << " Modules</h4>" << std::endl;
2362 // find index chars
2363 super->GetSub().Sort();
2364 TIter iModule(&super->GetSub());
2365 TModuleDocInfo* module = 0;
2366 while ((module = (TModuleDocInfo*) iModule())) {
2367 if (module->IsSelected()) {
2368 TString name(module->GetName());
2369 name.ToUpper();
2370 TString link(name);
2371 link.ReplaceAll("/", "_");
2372 Ssiz_t posSlash = name.Last('/');
2373 if (posSlash != kNPOS)
2374 name.Remove(0, posSlash + 1);
2375 out << "<a href=\"" << link << "_Index.html\">" << name << "</a>" << std::endl;
2376 }
2377 }
2378 out<< "</div><br />" << std::endl;
2379 }
2380}
2381
2382////////////////////////////////////////////////////////////////////////////////
2383/// Write a search link or a search box, based on THtml::GetSearchStemURL()
2384/// and THtml::GetSearchEngine(). The first one is preferred.
2385
2386void TDocOutput::WriteSearch(std::ostream& out)
2387{
2388 // e.g. searchCmd = "http://www.google.com/search?q=%s+site%3A%u+-site%3A%u%2Fsrc%2F+-site%3A%u%2Fexamples%2F";
2389 const TString& searchCmd = GetHtml()->GetSearchStemURL();
2390 const TString& searchEngine = GetHtml()->GetSearchEngine();
2391
2392 if (!searchCmd.Length() && !searchEngine.Length())
2393 return;
2394
2395 if (searchCmd.Length()) {
2396 TUrl url(searchCmd);
2397 TString serverName(url.GetHost());
2398 if (serverName.Length()) {
2399 serverName.Prepend(" title=\"");
2400 serverName += "\" ";
2401 }
2402 // create search input
2403 out << "<script type=\"text/javascript\">" << std::endl
2404 << "function onSearch() {" << std::endl
2405 << "var s='" << searchCmd <<"';" << std::endl
2406 << "var ref=String(document.location.href).replace(/https?:\\/\\//,'').replace(/\\/[^\\/]*$/,'').replace(/\\//g,'%2F');" << std::endl
2407 << "window.location.href=s.replace(/%u/ig,ref).replace(/%s/ig,escape(document.searchform.t.value));" << std::endl
2408 << "return false;}" << std::endl
2409 << "</script>" << std::endl
2410 << "<form id=\"searchform\" name=\"searchform\" onsubmit=\"return onSearch()\" action=\"javascript:onSearch();\" method=\"post\">" << std::endl
2411 << "<input name=\"t\" size=\"30\" value=\"Search documentation...\" onfocus=\"if (document.searchform.t.value=='Search documentation...') document.searchform.t.value='';\"></input>" << std::endl
2412 << "<a id=\"searchlink\" " << serverName << " href=\"javascript:onSearch();\" onclick=\"return onSearch()\">Search</a></form>" << std::endl;
2413 } else if (searchEngine.Length())
2414 // create link to search engine page
2415 out << "<a class=\"descrheadentry\" href=\"" << searchEngine
2416 << "\">Search the Class Reference Guide</a>" << std::endl;
2417}
2418
2419
2420////////////////////////////////////////////////////////////////////////////////
2421/// make a link to the description
2422
2423void TDocOutput::WriteLocation(std::ostream& out, TModuleDocInfo* module, const char* classname)
2424{
2425 out << "<div class=\"location\">" << std::endl; // location
2426 const char *productName = fHtml->GetProductName();
2427 out << "<a class=\"locationlevel\" href=\"index.html\">" << productName << "</a>" << std::endl;
2428
2429 if (module) {
2430 TString modulename(module->GetName());
2431 modulename.ToUpper();
2432 TString modulePart;
2433 TString modulePath;
2434 Ssiz_t pos = 0;
2435 while (modulename.Tokenize(modulePart, pos, "/")) {
2436 if (pos == kNPOS && !classname)
2437 // we are documenting the module itself, no need to link it:
2438 break;
2439 if (modulePath.Length()) modulePath += "_";
2440 modulePath += modulePart;
2441 out << " &#187; <a class=\"locationlevel\" href=\"./" << modulePath << "_Index.html\">" << modulePart << "</a>" << std::endl;
2442 }
2443 }
2444
2445 TString entityName;
2446 if (classname) entityName = classname;
2447 else if (module) {
2448 entityName = module->GetName();
2449 Ssiz_t posSlash = entityName.Last('/');
2450 if (posSlash != kNPOS)
2451 entityName.Remove(0, posSlash + 1);
2452 entityName.ToUpper();
2453 }
2454 if (entityName.Length()) {
2455 out << " &#187; <a class=\"locationlevel\" href=\"#TopOfPage\">";
2456 ReplaceSpecialChars(out, entityName);
2457 out << "</a>" << std::endl;
2458 }
2459 out << "</div>" << std::endl; // location
2460}
2461
2462
2463////////////////////////////////////////////////////////////////////////////////
2464/// Write the first part of the links shown ontop of each doc page;
2465/// one <div> has to be closed by caller so additional items can still
2466/// be added.
2467
2468void TDocOutput::WriteTopLinks(std::ostream& out, TModuleDocInfo* module, const char* classname,
2469 Bool_t withLocation)
2470{
2471 out << "<div id=\"toplinks\">" << std::endl;
2472
2473 out << "<div class=\"descrhead\"><div class=\"descrheadcontent\">" << std::endl // descrhead line 1
2474 << "<span class=\"descrtitle\">Quick Links:</span>" << std::endl;
2475
2476 // link to the user home page (if exist)
2477 const char* userHomePage = GetHtml()->GetHomepage();
2478 const char* productName = fHtml->GetProductName();
2479 if (!productName) {
2480 productName = "";
2481 } else if (!strcmp(productName, "ROOT")) {
2482 userHomePage = "";
2483 }
2484 if (userHomePage && *userHomePage)
2485 out << "<a class=\"descrheadentry\" href=\"" << userHomePage << "\">" << productName << "</a>" << std::endl;
2486 out << "<a class=\"descrheadentry\" href=\"http://root.cern.ch\">ROOT Homepage</a>" << std::endl
2487 << "<a class=\"descrheadentry\" href=\"./ClassIndex.html\">Class Index</a>" << std::endl
2488 << "<a class=\"descrheadentry\" href=\"./ClassHierarchy.html\">Class Hierarchy</a></div>" << std::endl;
2489 WriteSearch(out);
2490 out << "</div>" << std::endl; // descrhead, line 1
2491
2492 if (withLocation) {
2493 out << "</div>" << std::endl; //toplinks
2494 WriteLocation(out, module, classname); // descrhead line 2
2495 }
2496 // else {
2497 // Closed by caller!
2498 // out << "</div>" << std::endl; // toplinks
2499 // }
2500
2501}
#define c(i)
Definition: RSha256.hxx:101
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
const Ssiz_t kNPOS
Definition: RtypesCore.h:111
int Int_t
Definition: RtypesCore.h:41
int Ssiz_t
Definition: RtypesCore.h:63
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
static int CaseInsensitiveSort(const void *name1, const void *name2)
Friend function for sorting strings, case insensitive.
Definition: TDocOutput.cxx:197
XFontStruct * id
Definition: TGX11.cxx:108
char name[80]
Definition: TGX11.cxx:109
int type
Definition: TGX11.cxx:120
#define gInterpreter
Definition: TInterpreter.h:555
#define gROOT
Definition: TROOT.h:415
char * Form(const char *fmt,...)
void Printf(const char *fmt,...)
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2490
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:119
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
#define R__LOCKGUARD(mutex)
Bool_t HaveSource() const
Definition: TDocInfo.h:71
virtual const char * GetName() const
Returns name of object.
Definition: TDocInfo.cxx:26
const char * GetHtmlFileName() const
Definition: TDocInfo.h:60
Bool_t IsSelected() const
Definition: TDocInfo.h:70
TList & GetListOfTypedefs()
Definition: TDocInfo.h:82
TDictionary * GetClass() const
Definition: TDocInfo.h:58
void CreateClassHierarchy(std::ostream &out, const char *docFileName)
Create the hierarchical class list part for the current class's base classes.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
TList * GetListOfMethods(Bool_t load=kTRUE)
Return list containing the TMethods of a class.
Definition: TClass.cxx:3655
const char * GetSharedLibs()
Get the list of shared libraries containing the code for class cls.
Definition: TClass.cxx:3483
Short_t GetImplFileLine() const
Definition: TClass.h:427
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2906
virtual Bool_t IsEmpty() const
Definition: TCollection.h:186
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
const char * GetFullTypeName() const
Get full type description of data member, e,g.: "class TDirectory*".
TClass * GetClass() const
Definition: TDataMember.h:73
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TDataType.cxx:287
const char * GetFullTypeName() const
Get full type description of typedef, e,g.: "class TDirectory*".
Definition: TDataType.cxx:175
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:37
Int_t GetMonth() const
Definition: TDatime.h:66
Int_t GetDay() const
Definition: TDatime.h:67
Int_t GetHour() const
Definition: TDatime.h:69
Int_t GetYear() const
Definition: TDatime.h:65
Int_t GetMinute() const
Definition: TDatime.h:70
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:101
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:162
virtual Bool_t IsModified(TClass *classPtr, EFileType type)
Check if file is modified.
void Convert(std::istream &in, const char *infilename, const char *outfilename, const char *title, const char *relpath="../", Int_t includeOutput=0, const char *context="", TGClient *gclient=0)
Convert a text file into a html file.
Definition: TDocOutput.cxx:310
virtual void DecorateEntityBegin(TString &str, Ssiz_t &pos, TDocParser::EParseContext type)
Add some colors etc to a source entity, contained in str.
virtual void NameSpace2FileName(TString &name)
Replace "::" in name by "__" Replace "<", ">", " ", ",", "~", "=" in name by "_" Replace "A::X<A::Y>"...
void WriteTopLinks(std::ostream &out, TModuleDocInfo *module, const char *classname=0, Bool_t withLocation=kTRUE)
Write the first part of the links shown ontop of each doc page; one <div> has to be closed by caller ...
virtual void CreateProductIndex()
Fetch documentation from THtml::GetProductDocDir() and put it into the product index page.
virtual void CreateClassTypeDefs()
Create a forwarding page for each typedef pointing to a class.
void WriteLineNumbers(std::ostream &out, Long_t nLines, const TString &infileBase) const
Create a div containing the line numbers (for a source listing) 1 to nLines.
virtual void ReferenceEntity(TSubString &str, TClass *entity, const char *comment=0)
Create a reference to a class documentation page.
Bool_t CopyHtmlFile(const char *sourceName, const char *destName="")
Copy file to HTML directory.
Definition: TDocOutput.cxx:592
virtual void CreateHierarchy()
Create a hierarchical class list The algorithm descends from the base classes and branches into all d...
Definition: TDocOutput.cxx:639
void WriteHtmlFooter(std::ostream &out, const char *dir, const char *lastUpdate, const char *author, const char *copyright, const char *footer)
Write HTML footer.
virtual const char * ReplaceSpecialChars(char c)
Replace ampersand, less-than and greater-than character, writing to out.
virtual Bool_t ReferenceIsRelative(const char *reference) const
Check whether reference is a relative reference, and can (or should) be prependen by relative paths.
Bool_t RunDot(const char *filename, std::ostream *outMap=0, EGraphvizTool gvwhat=kDot)
Run filename".dot", creating filename".png", and - if outMap is !=0, filename".map",...
virtual void CreateClassIndex()
Create index of all classes.
Definition: TDocOutput.cxx:692
THtml * fHtml
Definition: TDocOutput.h:46
virtual void CreateTypeIndex()
Create index of all data types.
virtual void DecorateEntityEnd(TString &str, Ssiz_t &pos, TDocParser::EParseContext type)
Add some colors etc to a source entity, contained in str.
virtual void FixupAuthorSourceInfo(TString &authors)
Special author treatment; called when TDocParser::fSourceInfo[kInfoAuthor] is set.
virtual void CreateModuleIndex()
Create the class index for each module, picking up documentation from the module's TModuleDocInfo::Ge...
Definition: TDocOutput.cxx:800
virtual void AdjustSourcePath(TString &line, const char *relpath="../")
adjust the path of links for source files, which are in src/, but need to point to relpath (usually "...
Definition: TDocOutput.cxx:296
THtml * GetHtml()
Definition: TDocOutput.h:90
void ProcessDocInDir(std::ostream &out, const char *indir, const char *outdir, const char *linkdir)
Write links to files indir/*.txt, indir/*.html (non-recursive) to out.
virtual ~TDocOutput()
Definition: TDocOutput.cxx:260
void WriteModuleLinks(std::ostream &out)
Create a div containing links to all topmost modules.
void WriteHtmlHeader(std::ostream &out, const char *titleNoSpecial, const char *dir, TClass *cls, const char *header)
Write HTML header.
virtual void WriteSearch(std::ostream &out)
Write a search link or a search box, based on THtml::GetSearchStemURL() and THtml::GetSearchEngine().
TDocOutput(THtml &html)
Definition: TDocOutput.cxx:255
void WriteLocation(std::ostream &out, TModuleDocInfo *module, const char *classname=0)
make a link to the description
void AddLink(TSubString &str, TString &link, const char *comment)
Add a link around str, with title comment.
Definition: TDocOutput.cxx:267
static void AnchorFromLine(const TString &line, TString &anchor)
Create an anchor from the given line, by hashing it and convertig the hash into a custom base64 strin...
Definition: TDocParser.cxx:381
@ kNumSourceInfos
Definition: TDocParser.h:60
Long_t GetLineNumber() const
Definition: TDocParser.h:174
void Convert(std::ostream &out, std::istream &in, const char *relpath, Bool_t isCode, Bool_t interpretDirectives)
Parse text file "in", add links etc, and write output to "out".
Definition: TDocParser.cxx:402
virtual void DecorateKeywords(std::ostream &out, const char *text)
Expand keywords in text, writing to out.
Definition: TDocParser.cxx:450
virtual const char * GetPrototype() const
Returns the prototype of a function as defined by CINT, or 0 in case of error.
Definition: TFunction.cxx:245
virtual bool GetIncludeAs(TClass *cl, TString &out_include_as) const
Determine the path and filename used in an include statement for the header file of the given class.
Definition: THtml.cxx:571
virtual bool GetDocDir(const TString &module, TString &doc_dir) const
Determine the module's documentation directory.
Definition: THtml.cxx:541
Definition: THtml.h:40
const char * GetCounter() const
Definition: THtml.h:323
@ kForceOutput
Definition: THtml.h:237
@ kCompiledOutput
Definition: THtml.h:236
@ kSeparateProcessOutput
Definition: THtml.h:238
const TString & GetFooter() const
Definition: THtml.h:309
const TString & GetSearchStemURL() const
Definition: THtml.h:311
const TString & GetCharset() const
Definition: THtml.h:315
const char * ShortType(const char *name) const
Get short type name, i.e. with default templates removed.
Definition: THtml.cxx:2510
const TString & GetHomepage() const
Definition: THtml.h:310
const TString & GetProductName() const
Definition: THtml.h:294
void SortListOfModules()
Definition: THtml.h:339
const char * GetCounterFormat() const
Definition: THtml.h:303
TList * GetLibraryDependencies()
Definition: THtml.h:338
const TList * GetListOfModules() const
Definition: THtml.h:340
const TString & GetDotDir() const
Definition: THtml.h:299
const TString & GetSearchEngine() const
Definition: THtml.h:312
Bool_t HaveDot()
Check whether dot is available in $PATH or in the directory set by SetDotPath()
Definition: THtml.cxx:1403
virtual void CreateAuxiliaryFiles() const
copy CSS, javascript file, etc to the output dir
Definition: THtml.cxx:1291
virtual bool GetDeclFileName(TClass *cl, Bool_t filesys, TString &out_name) const
Return declaration file name; return the full path if filesys is true.
Definition: THtml.cxx:2095
const TString & GetHeader() const
Definition: THtml.h:308
void SetFoundDot(Bool_t found=kTRUE)
Set whether "dot" (a GraphViz utility) is available.
Definition: THtml.cxx:2400
virtual const char * GetEtcDir() const
Get the directory containing THtml's auxiliary files ($ROOTSYS/etc/html)
Definition: THtml.cxx:1344
virtual void GetHtmlFileName(TClass *classPtr, TString &filename) const
Return real HTML filename.
Definition: THtml.cxx:1991
virtual void GetModuleNameForClass(TString &module, TClass *cl) const
Return the module name for a given class.
Definition: THtml.cxx:1530
const TString & GetOutputDir(Bool_t createDir=kTRUE) const
Return the output directory as set by SetOutputDir().
Definition: THtml.cxx:2167
virtual bool GetImplFileName(TClass *cl, Bool_t filesys, TString &out_name) const
Return implementation file name.
Definition: THtml.cxx:2103
const TList * GetListOfClasses() const
Definition: THtml.h:341
const TPathDefinition & GetPathDefinition() const
Return the TModuleDefinition (or derived) object as set by SetModuleDefinition(); create and return a...
Definition: THtml.cxx:1331
const TString & GetXwho() const
Definition: THtml.h:301
void Reset()
Definition: TCollection.h:252
void AddDependency(const std::string &lib)
Definition: TDocInfo.h:148
std::set< std::string > & GetDependencies()
Definition: TDocInfo.h:146
std::set< std::string > & GetModules()
Definition: TDocInfo.h:147
void AddModule(const std::string &module)
Definition: TDocInfo.h:149
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:575
virtual void Sort(Bool_t order=kSortAscending)
Sort linked list.
Definition: TList.cxx:934
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
TClass * GetClass() const
Definition: TMethod.h:55
THashList & GetSub()
Definition: TDocInfo.h:125
Bool_t IsSelected() const
Definition: TDocInfo.h:119
TList * GetClasses()
Definition: TDocInfo.h:122
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:443
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:97
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:708
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
TString & Insert(Ssiz_t pos, const char *s)
Definition: TString.h:644
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2177
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1106
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:499
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kBoth
Definition: TString.h:262
@ kIgnoreCase
Definition: TString.h:263
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:892
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1138
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2197
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
TString & Prepend(const char *cs)
Definition: TString.h:656
Int_t CountChar(Int_t c) const
Return number of times character c occurs in the string.
Definition: TString.cxx:476
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
A zero length substring is legal.
Definition: TString.h:77
TString & String()
Definition: TString.h:116
Ssiz_t Start() const
Definition: TString.h:115
Ssiz_t Length() const
Definition: TString.h:114
virtual TSeqCollection * GetListOfTimers() const
Definition: TSystem.h:395
Bool_t cd(const char *path)
Definition: TSystem.h:424
const char * pwd()
Definition: TSystem.h:425
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1014
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:853
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:844
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1332
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:914
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:663
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1389
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1072
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1287
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:861
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:942
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:426
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition: TSystem.cxx:491
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1372
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
This class represents a WWW compatible URL.
Definition: TUrl.h:35
const char * GetHost() const
Definition: TUrl.h:69
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:50
virtual void SaveAs(const char *filename="", Option_t *option="") const =0
Save this object in the file specified by filename.
virtual TVirtualViewer3D * GetViewer3D(Option_t *type="")=0
virtual Bool_t HasViewer3D() const =0
TText * text
TLine * line
Int_t fMode
Definition: TSystem.h:128
Long_t fMtime
Definition: TSystem.h:132
auto * l
Definition: textangle.C:4