Logo ROOT   6.08/07
Reference Guide
THtml.cxx
Go to the documentation of this file.
1 // @(#)root/html:$Id$
2 // Author: Nenad Buncic (18/10/95), Axel Naumann (09/28/01)
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 "THtml.h"
13 #include "RConfigure.h"
14 #include "Riostream.h"
15 #include "TBaseClass.h"
16 #include "TClass.h"
17 #include "TClassDocOutput.h"
18 #include "TClassEdit.h"
19 #include "TClassTable.h"
20 #include "TDataType.h"
21 #include "TDocInfo.h"
22 #include "TDocOutput.h"
23 #include "TEnv.h"
24 #include "TInterpreter.h"
25 #include "TObjString.h"
26 #include "TPRegexp.h"
27 #include "TRegexp.h"
28 #include "TROOT.h"
29 #include "TSystem.h"
30 #include "TThread.h"
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <set>
36 #include <fstream>
37 
38 THtml *gHtml = 0;
39 
40 //______________________________________________________________________________
41 //______________________________________________________________________________
42 namespace {
43  class THtmlThreadInfo {
44  public:
45  THtmlThreadInfo(THtml* html, bool force): fHtml(html), fForce(force) {}
46  Bool_t GetForce() const {return fForce;}
47  THtml* GetHtml() const {return fHtml;}
48 
49  private:
50  THtml* fHtml;
51  Bool_t fForce;
52  };
53 };
54 
55 
56 ////////////////////////////////////////////////////////////////////////////////
57 /// Helper's destructor.
58 /// Check that no THtml object is attached to the helper - it might still need it!
59 
61 {
62  if (fHtml) {
63  fHtml->HelperDeleted(this);
64  }
65 }
66 
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Set the THtml object owning this object; if it's already set to
70 /// a different THtml object than issue an error message and signal to
71 /// the currently set object that we are not belonging to it anymore.
72 
74  if (fHtml && html && html != fHtml) {
75  Error("SetOwner()", "Object already owned by an THtml instance!");
76  fHtml->HelperDeleted(this);
77  }
78  fHtml = html;
79 }
80 
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Set out_modulename to cl's module name; return true if it's valid.
84 /// If applicable, the module contains super modules separated by "/".
85 ///
86 /// ROOT takes the directory part of cl's implementation file name
87 /// (or declaration file name, if the implementation file name is empty),
88 /// removes the last subdirectory if it is "src/" or "inc/", and interprets
89 /// the remaining path as the module hierarchy, converting it to upper case.
90 /// hist/histpainter/src/THistPainter.cxx thus becomes the module
91 /// HIST/HISTPAINTER. (Node: some ROOT packages get special treatment.)
92 /// If the file cannot be mapped into this scheme, the class's library
93 /// name (without directories, leading "lib" prefix or file extensions)
94 /// ius taken as the module name. If the module cannot be determined it is
95 /// set to "USER" and false is returned.
96 ///
97 /// If your software cannot be mapped into this scheme then derive your
98 /// own class from TModuleDefinition and pass it to THtml::SetModuleDefinition().
99 ///
100 /// The fse parameter is used to determine the relevant part of the path, i.e.
101 /// to not include parent directories of a TFileSysRoot.
102 
104  TString& out_modulename) const
105 {
106  out_modulename = "USER";
107  if (!cl) return false;
108 
109  // Filename: impl or decl?
110  TString filename;
111  if (fse) fse->GetFullName(filename, kFALSE);
112  else {
113  if (!GetOwner()->GetImplFileName(cl, kFALSE, filename))
114  if (!GetOwner()->GetDeclFileName(cl, kFALSE, filename))
115  return false;
116  }
117  TString inputdir = GetOwner()->GetInputPath();
118  TString tok;
119  Ssiz_t start = 0;
120  // For -Idir/sub and A.h in dir/sub/A.h, use sub as module name if
121  // it would eb empty otehrwise.
122  TString trailingInclude;
123  while (inputdir.Tokenize(tok, start, THtml::GetDirDelimiter())) {
124  if (filename.BeginsWith(tok)) {
125  if (tok.EndsWith("/") || tok.EndsWith("\\"))
126  tok.Remove(tok.Length() - 1);
127  trailingInclude = gSystem->BaseName(tok);
128  filename.Remove(0, tok.Length());
129  break;
130  }
131  }
132 
133  // take the directory name without "/" or leading "."
134  out_modulename = gSystem->DirName(filename);
135 
136  while (out_modulename[0] == '.')
137  out_modulename.Remove(0, 1);
138  out_modulename.ReplaceAll("\\", "/");
139  while (out_modulename[0] == '/')
140  out_modulename.Remove(0, 1);
141  while (out_modulename.EndsWith("/"))
142  out_modulename.Remove(out_modulename.Length() - 1);
143 
144  if (!out_modulename[0])
145  out_modulename = trailingInclude;
146 
147  if (!out_modulename[0])
148  out_modulename = trailingInclude;
149 
150  // remove "/src", "/inc"
151  if (out_modulename.EndsWith("/src")
152  || out_modulename.EndsWith("/inc"))
153  out_modulename.Remove(out_modulename.Length() - 4, 4);
154  else {
155  // remove "/src/whatever", "/inc/whatever"
156  Ssiz_t pos = out_modulename.Index("/src/");
157  if (pos == kNPOS)
158  pos = out_modulename.Index("/inc/");
159  if (pos != kNPOS)
160  out_modulename.Remove(pos);
161  }
162 
163  while (out_modulename.EndsWith("/"))
164  out_modulename.Remove(out_modulename.Length() - 1);
165 
166  // special treatment:
167  if (out_modulename == "MATH/GENVECTOR")
168  out_modulename = "MATHCORE";
169  else if (out_modulename == "MATH/MATRIX")
170  out_modulename = "SMATRIX";
171  else if (!out_modulename.Length()) {
172  const char* cname= cl->GetName();
173  if (strstr(cname, "::SMatrix<") || strstr(cname, "::SVector<"))
174  out_modulename = "SMATRIX";
175  else if (strstr(cname, "::TArrayProxy<") || strstr(cname, "::TClaArrayProxy<")
176  || strstr(cname, "::TImpProxy<") || strstr(cname, "::TClaImpProxy<"))
177  out_modulename = "TREEPLAYER";
178  else {
179  // determine the module name from the library name:
180  out_modulename = cl->GetSharedLibs();
181  Ssiz_t pos = out_modulename.Index(' ');
182  if (pos != kNPOS)
183  out_modulename.Remove(pos, out_modulename.Length());
184  if (out_modulename.BeginsWith("lib"))
185  out_modulename.Remove(0,3);
186  pos = out_modulename.Index('.');
187  if (pos != kNPOS)
188  out_modulename.Remove(pos, out_modulename.Length());
189 
190  if (!out_modulename.Length()) {
191  out_modulename = "USER";
192  return false;
193  }
194  }
195  }
196 
197  return true;
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Create all permutations of path and THtml's input path:
202 /// path being PP/ and THtml's input being .:include/:src/ gives
203 /// .:./PP/:include:include/PP/:src/:src/PP
204 
206 {
207  THtml* owner = GetOwner();
208  if (!owner) return;
209 
210  TString pathext;
211  TString inputdir = owner->GetInputPath();
212  TString tok;
213  Ssiz_t start = 0;
214  while (inputdir.Tokenize(tok, start, THtml::GetDirDelimiter())) {
215  if (pathext.Length())
216  pathext += GetDirDelimiter();
217  if (tok.EndsWith("\\"))
218  tok.Remove(tok.Length() - 1);
219  pathext += tok;
220  if (path.BeginsWith(tok))
221  pathext += GetDirDelimiter() + path;
222  else
223  pathext += GetDirDelimiter() + tok + "/" + path;
224  }
225  path = pathext;
226 
227 }
228 
229 ////////////////////////////////////////////////////////////////////////////////
230 /// Given a class name with a scope, split the class name into directory part
231 /// and file name: A::B::C becomes module B, filename C.
232 
234  TString& filename) const
235 {
236  TString token;
237  Ssiz_t from = 0;
238  filename = "";
239  dir = "";
240  while (clname.Tokenize(token, from, "::") ) {
241  dir = filename;
242  filename = token;
243  }
244 
245  // convert from Scope, class to module, filename.h
246  dir.ToLower();
247 }
248 
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// Determine cl's declaration file name. Usually it's just
252 /// cl->GetDeclFileName(), but sometimes conversions need to be done
253 /// like include/ to abc/cde/inc/. If no declaration file name is
254 /// available, look for b/inc/C.h for class A::B::C. out_fsys will contain
255 /// the file system's (i.e. local machine's) full path name to the file.
256 /// The function returns false if the class's header file cannot be found.
257 ///
258 /// If your software cannot be mapped into this scheme then derive your
259 /// own class from TFileDefinition and pass it to THtml::SetFileDefinition().
260 
262  TString& out_fsys, TFileSysEntry** fse) const
263 {
264  return GetFileName(cl, true, out_filename, out_fsys, fse);
265 }
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Determine cl's implementation file name. Usually it's just
269 /// cl->GetImplFileName(), but sometimes conversions need to be done.
270 /// If no implementation file name is available look for b/src/C.cxx for
271 /// class A::B::C. out_fsys will contain the file system's (i.e. local
272 /// machine's) full path name to the file.
273 /// The function returns false if the class's source file cannot be found.
274 ///
275 /// If your software cannot be mapped into this scheme then derive your
276 /// own class from TFileDefinition and pass it to THtml::SetFileDefinition().
277 
279  TString& out_fsys, TFileSysEntry** fse) const
280 {
281  return GetFileName(cl, false, out_filename, out_fsys, fse);
282 }
283 
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 /// Remove "/./" and collapse "/subdir/../" to "/"
287 
289 {
290  static const char* delim[] = {"/", "\\\\"};
291  for (int i = 0; i < 2; ++i) {
292  const char* d = delim[i];
293  filename = filename.ReplaceAll(TString::Format("%c.%c", d[0], d[0]), TString(d[0]));
294  TPRegexp reg(TString::Format("%s[^%s]+%s\\.\\.%s", d, d, d, d));
295  while (reg.Substitute(filename, TString(d[0]), "", 0, 1)) {}
296  }
297  if (filename.BeginsWith("./") || filename.BeginsWith(".\\"))
298  filename.Remove(0,2);
299 }
300 
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Find filename in the list of system files; return the system file name
304 /// and change filename to the file name as included.
305 /// filename must be normalized (no "/./" etc) before calling.
306 
308 {
309  const TList* bucket = GetOwner()->GetLocalFiles()->GetEntries().GetListForObject(gSystem->BaseName(filename));
310  TString filesysname;
311  if (bucket) {
312  TIter iFS(bucket);
313  TFileSysEntry* fsentry = 0;
314  while ((fsentry = (TFileSysEntry*) iFS())) {
315  if (!filename.EndsWith(fsentry->GetName()))
316  continue;
317  fsentry->GetFullName(filesysname, kTRUE); // get the short version
318  filename = filesysname;
319  if (!filename.EndsWith(filesysname)) {
320  // It's something - let's see whether we find something better
321  // else leave it as plan B. This helps finding Reflex sources.
322  //filesysname = "";
323  continue;
324  }
325  fsentry->GetFullName(filesysname, kFALSE); // get the long version
326  if (fse) *fse = fsentry;
327  break;
328  }
329  }
330  return filesysname;
331 }
332 
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Common implementation for GetDeclFileName(), GetImplFileName()
336 
337 bool THtml::TFileDefinition::GetFileName(const TClass* cl, bool decl,
338  TString& out_filename, TString& out_fsys,
339  TFileSysEntry** fse) const
340 {
341  out_fsys = "";
342 
343  if (!cl) {
344  out_filename = "";
345  return false;
346  }
347 
348  TString possibleFileName;
349  TString possiblePath;
350  TString filesysname;
351 
352  TString clfile = decl ? cl->GetDeclFileName() : cl->GetImplFileName();
353  NormalizePath(clfile);
354 
355  out_filename = clfile;
356  if (clfile.Length()) {
357  // check that clfile doesn't start with one of the include paths;
358  // that's not what we want (include/TObject.h), we want the actual file
359  // if it exists (core/base/inc/TObject.h)
360 
361  // special case for TMath namespace:
362  if (clfile == "include/TMathBase.h") {
363  clfile = "math/mathcore/inc/TMath.h";
364  out_filename = clfile;
365  }
366 
367  TString inclDir;
368  TString inclPath(GetOwner()->GetPathInfo().fIncludePath);
369  Ssiz_t pos = 0;
370  Ssiz_t longestMatch = kNPOS;
371  while (inclPath.Tokenize(inclDir, pos, GetOwner()->GetDirDelimiter())) {
372  if (clfile.BeginsWith(inclDir) && (longestMatch == kNPOS || inclDir.Length() > longestMatch))
373  longestMatch = inclDir.Length();
374  }
375  if (longestMatch != kNPOS) {
376  clfile.Remove(0, longestMatch);
377  if (clfile.BeginsWith("/") || clfile.BeginsWith("\\"))
378  clfile.Remove(0, 1);
379  TString asincl(clfile);
380  GetOwner()->GetPathDefinition().GetFileNameFromInclude(asincl, clfile);
381  out_filename = clfile;
382  } else {
383  // header file without a -Iinclude-dir prefix
384  filesysname = MatchFileSysName(out_filename, fse);
385  if (filesysname[0]) {
386  clfile = out_filename;
387  }
388  }
389  } else {
390  // check for a file named like the class:
391  filesysname = cl->GetName();
392  int templateLevel = 0;
393  Ssiz_t end = filesysname.Length();
394  Ssiz_t start = end - 1;
395  for (; start >= 0 && (templateLevel || filesysname[start] != ':'); --start) {
396  if (filesysname[start] == '>')
397  ++templateLevel;
398  else if (filesysname[start] == '<') {
399  --templateLevel;
400  if (!templateLevel)
401  end = start;
402  }
403  }
404  filesysname = filesysname(start + 1, end - start - 1);
405  if (decl)
406  filesysname += ".h";
407  else
408  filesysname += ".cxx";
409  out_filename = filesysname;
410  filesysname = MatchFileSysName(out_filename, fse);
411  if (filesysname[0]) {
412  clfile = out_filename;
413  }
414  }
415 
416  if (!decl && !clfile.Length()) {
417  // determine possible impl file name from the decl file name,
418  // replacing ".whatever" by ".cxx", and looking for it in the known
419  // file names
420  TString declSysFileName;
421  if (GetFileName(cl, true, filesysname, declSysFileName)) {
422  filesysname = gSystem->BaseName(filesysname);
423  Ssiz_t posExt = filesysname.Last('.');
424  if (posExt != kNPOS)
425  filesysname.Remove(posExt);
426  filesysname += ".cxx";
427  out_filename = filesysname;
428  filesysname = MatchFileSysName(out_filename, fse);
429  if (filesysname[0]) {
430  clfile = out_filename;
431  }
432  }
433  }
434 
435  if (clfile.Length() && !decl) {
436  // Do not return the source file for these packages, even though we can find them.
437  // THtml needs to have the class description in the source file if it finds the
438  // source file, and these classes have their class descriptions in the header files.
439  // THtml needs to be improved to collect all of a class' documentation before writing
440  // it out, so it can take the class doc from the header even though a source exists.
441  static const char* vetoClasses[] = {"math/mathcore/", "math/mathmore/", "math/genvector/",
442  "math/minuit2/", "math/smatrix/"};
443  for (unsigned int i = 0; i < sizeof(vetoClasses) / sizeof(char*); ++i) {
444  if (clfile.Contains(vetoClasses[i])) {
445  // of course there are exceptions from the exceptions:
446  // TComplex and TRandom, TRandom1,...
447  if (strcmp(cl->GetName(), "TComplex")
448  && strcmp(cl->GetName(), "TMath")
449  && strncmp(cl->GetName(), "TKDTree", 7)
450  && strcmp(cl->GetName(), "TVirtualFitter")
451  && strncmp(cl->GetName(), "TRandom", 7)) {
452  out_filename = "";
453  return false;
454  } else break;
455  }
456  }
457  }
458 
459 
460  if (!clfile.Length()) {
461  // determine possible decl file name from class + scope name:
462  // A::B::C::myclass will result in possible file name myclass.h
463  // in directory C/inc/
464  out_filename = cl->GetName();
465  if (!out_filename.Contains("::")) {
466  out_filename = "";
467  return false;
468  }
469  SplitClassIntoDirFile(out_filename, possiblePath, possibleFileName);
470 
471  // convert from Scope, class to module, filename.h
472  if (possibleFileName.Length()) {
473  if (decl)
474  possibleFileName += ".h";
475  else
476  possibleFileName += ".cxx";
477  }
478  if (possiblePath.Length())
479  possiblePath += "/";
480  if (decl)
481  possiblePath += "inc/";
482  else
483  possiblePath += "src/";
484  out_filename = possiblePath + "/" + possibleFileName;
485  } else {
486  possiblePath = gSystem->DirName(clfile);
487  possibleFileName = gSystem->BaseName(clfile);
488  }
489 
490  if (possiblePath.Length())
491  ExpandSearchPath(possiblePath);
492  else possiblePath=".";
493 
494  out_fsys = gSystem->FindFile(possiblePath, possibleFileName, kReadPermission);
495  if (out_fsys.Length()) {
496  NormalizePath(out_fsys);
497  return true;
498  }
499  out_filename = "";
500  return false;
501 }
502 
503 ////////////////////////////////////////////////////////////////////////////////
504 /// Determine the path to look for macros (see TDocMacroDirective) for
505 /// classes from a given module. If the path was sucessfully determined return true.
506 /// For ROOT, this directory is the "doc/macros" subdirectory of the module
507 /// directory; the path returned is GetDocDir(module) + "/macros".
508 ///
509 /// If your software cannot be mapped into this scheme then derive your
510 /// own class from TPathDefinition and pass it to THtml::SetPathDefinition().
511 
512 bool THtml::TPathDefinition::GetMacroPath(const TString& module, TString& out_dir) const
513 {
514  TString moduledoc;
515  if (!GetDocDir(module, moduledoc))
516  return false;
517  if (moduledoc.EndsWith("\\"))
518  moduledoc.Remove(moduledoc.Length() - 1);
519 
520  TString macropath(GetOwner()->GetMacroPath());
521  TString macrodirpart;
522  out_dir = "";
523  Ssiz_t pos = 0;
524  while (macropath.Tokenize(macrodirpart, pos, ":")) {
525  out_dir += moduledoc + "/" + macrodirpart + ":";
526  }
527  return true;
528 }
529 
530 
531 ////////////////////////////////////////////////////////////////////////////////
532 /// Determine the module's documentation directory. If module is empty,
533 /// set doc_dir to the product's documentation directory.
534 /// If the path was sucessfuly determined return true.
535 /// For ROOT, this directory is the subdir "doc/" in the
536 /// module's path; the directory returned is module + "/doc".
537 ///
538 /// If your software cannot be mapped into this scheme then derive your
539 /// own class from TPathDefinition and pass it to THtml::SetPathDefinition().
540 
541 bool THtml::TPathDefinition::GetDocDir(const TString& module, TString& doc_dir) const
542 {
543  doc_dir = "";
544  if (GetOwner()->GetProductName() == "ROOT") {
545  doc_dir = "$ROOTSYS";
546  gSystem->ExpandPathName(doc_dir);
547  doc_dir += "/";
548  }
549 
550  if (module.Length())
551  doc_dir += module + "/";
552  doc_dir += GetOwner()->GetPathInfo().fDocPath;
553  return true;
554 }
555 
556 
557 ////////////////////////////////////////////////////////////////////////////////
558 /// Determine the path and filename used in an include statement for the
559 /// header file of the given class. E.g. the class ROOT::Math::Boost is
560 /// meant to be included as "Math/Genvector/Boost.h" - which is what
561 /// out_dir is set to. GetIncludeAs() returns whether the include
562 /// statement's path was successfully determined.
563 ///
564 /// Any leading directory part that is part of fIncludePath (see SetIncludePath)
565 /// will be removed. For ROOT, leading "include/" is removed; everything after
566 /// is the include path.
567 ///
568 /// If your software cannot be mapped into this scheme then derive your
569 /// own class from TPathDefinition and pass it to THtml::SetPathDefinition().
570 
572 {
573  out_dir = "";
574  if (!cl || !GetOwner()) return false;
575 
576  TString hdr;
577  if (!GetOwner()->GetDeclFileName(cl, kFALSE, hdr))
578  return false;
579 
580  out_dir = hdr;
581  bool includePathMatches = false;
582  TString tok;
583  Ssiz_t pos = 0;
584  while (!includePathMatches && GetOwner()->GetPathInfo().fIncludePath.Tokenize(tok, pos, THtml::GetDirDelimiter()))
585  if (out_dir.BeginsWith(tok)) {
586  out_dir = hdr(tok.Length(), hdr.Length());
587  if (out_dir[0] == '/' || out_dir[0] == '\\')
588  out_dir.Remove(0, 1);
589  includePathMatches = true;
590  }
591 
592  if (!includePathMatches) {
593  // We probably have a file super/module/inc/optional/filename.h.
594  // That gets translated into optional/filename.h.
595  // Assume that only one occurrence of "/inc/" exists in hdr.
596  // If /inc/ is not part of the include file name then
597  // just return the full path.
598  // If we have matched any include path then this ROOT-only
599  // algorithm is skipped!
600  Ssiz_t posInc = hdr.Index("/inc/");
601  if (posInc == kNPOS) return true;
602  hdr.Remove(0, posInc + 5);
603  out_dir = hdr;
604  }
605 
606  return (out_dir.Length());
607 }
608 
609 
610 ////////////////////////////////////////////////////////////////////////////////
611 /// Set out_fsname to the full pathname corresponding to a file
612 /// included as "included". Return false if this file cannot be determined
613 /// or found. For ROOT, out_fsname corresponds to included prepended with
614 /// "include"; only THtml prefers to work on the original files, e.g.
615 /// core/base/inc/TObject.h instead of include/TObject.h, so the
616 /// default implementation searches the TFileSysDB for an entry with
617 /// basename(included) and with matching directory part, setting out_fsname
618 /// to the TFileSysEntry's path.
619 
620 bool THtml::TPathDefinition::GetFileNameFromInclude(const char* included, TString& out_fsname) const
621 {
622  if (!included) return false;
623 
624  out_fsname = included;
625 
626  TString incBase(gSystem->BaseName(included));
627  const TList* bucket = GetOwner()->GetLocalFiles()->GetEntries().GetListForObject(incBase);
628  if (!bucket) return false;
629 
630  TString alldir(gSystem->DirName(included));
631  TObjArray* arrSubDirs = alldir.Tokenize("/");
632  TIter iEntry(bucket);
633  TFileSysEntry* entry = 0;
634  while ((entry = (TFileSysEntry*) iEntry())) {
635  if (incBase != entry->GetName()) continue;
636  // find entry with matching enclosing directory
637  THtml::TFileSysDir* parent = entry->GetParent();
638  for (int i = arrSubDirs->GetEntries() - 1; parent && i >= 0; --i) {
639  const TString& subdir(((TObjString*)(*arrSubDirs)[i])->String());
640  if (!subdir.Length() || subdir == ".")
641  continue;
642  if (subdir == parent->GetName())
643  parent = parent->GetParent();
644  else parent = 0;
645  }
646  if (parent) {
647  // entry found!
648  entry->GetFullName(out_fsname, kFALSE);
649  delete arrSubDirs;
650  return true;
651  }
652  }
653  delete arrSubDirs;
654  return false;
655 }
656 
657 ////////////////////////////////////////////////////////////////////////////////
658 /// Recursively fill entries by parsing the contents of path.
659 
660 void THtml::TFileSysDir::Recurse(TFileSysDB* db, const char* path)
661 {
662  TString dir(path);
663  if (gDebug > 0 || GetLevel() < 2)
664  Info("Recurse", "scanning %s...", path);
665  TPMERegexp regexp(db->GetIgnore());
666  dir += "/";
667  void* hDir = gSystem->OpenDirectory(dir);
668  const char* direntry = 0;
669  while ((direntry = gSystem->GetDirEntry(hDir))) {
670  if (!direntry[0] || direntry[0] == '.' || regexp.Match(direntry)) continue;
671  TString entryPath(dir + direntry);
672  if (gSystem->AccessPathName(entryPath, kReadPermission))
673  continue;
674  FileStat_t buf;
675  if (!gSystem->GetPathInfo(entryPath, buf)) {
676  if (R_ISDIR(buf.fMode)) {
677  // skip if we would nest too deeply, and skip soft links:
678  if (GetLevel() > db->GetMaxLevel()
679 #ifndef R__WIN32
680  || db->GetMapIno().GetValue(buf.fIno)
681 #endif
682  ) continue;
683  TFileSysDir* subdir = new TFileSysDir(direntry, this);
684  fDirs.Add(subdir);
685 #ifndef R__WIN32
686  db->GetMapIno().Add(buf.fIno, (Long_t)subdir);
687 #endif
688  subdir->Recurse(db, entryPath);
689  } else {
690  int delen = strlen(direntry);
691  // only .cxx and .h, .hxx are taken
692  if (strcmp(direntry + delen - 4, ".cxx")
693  && strcmp(direntry + delen - 2, ".h")
694  && strcmp(direntry + delen - 4, ".hxx"))
695  continue;
696  TFileSysEntry* entry = new TFileSysEntry(direntry, this);
697  db->GetEntries().Add(entry);
698  fFiles.Add(entry);
699  }
700  } // if !gSystem->GetPathInfo()
701  } // while dir entry
702  gSystem->FreeDirectory(hDir);
703 }
704 
705 
706 ////////////////////////////////////////////////////////////////////////////////
707 /// Recursively fill entries by parsing the path specified in GetName();
708 /// can be a THtml::GetDirDelimiter() delimited list of paths.
709 
711 {
712  TString dir;
713  Ssiz_t posPath = 0;
714  while (fName.Tokenize(dir, posPath, THtml::GetDirDelimiter())) {
715  gSystem->ExpandPathName(dir);
717  Warning("Fill", "Cannot read InputPath \"%s\"!", dir.Data());
718  continue;
719  }
720  FileStat_t buf;
721  if (!gSystem->GetPathInfo(dir, buf) && R_ISDIR(buf.fMode)) {
722 #ifndef R__WIN32
723  TFileSysRoot* prevroot = (TFileSysRoot*) (Long_t)GetMapIno().GetValue(buf.fIno);
724  if (prevroot != 0) {
725  Warning("Fill", "InputPath \"%s\" already present as \"%s\"!", dir.Data(), prevroot->GetName());
726  continue;
727  }
728 #endif
729  TFileSysRoot* root = new TFileSysRoot(dir, this);
730  fDirs.Add(root);
731 #ifndef R__WIN32
732  GetMapIno().Add(buf.fIno, (Long_t)root);
733 #endif
734  root->Recurse(this, dir);
735  } else {
736  Warning("Fill", "Cannot read InputPath \"%s\"!", dir.Data());
737  }
738  }
739 }
740 
741 
742 ////////////////////////////////////////////////////////////////////////////////
743 /* BEGIN_HTML
744 <p>The THtml class is designed to easily document
745 classes, code, and code related text files (like change logs). It generates HTML
746 pages conforming to the XHTML 1.0 transitional specifications; an example of
747 these pages is ROOT's own <a href="http://root.cern.ch/root/html/ClassIndex.html">
748 reference guide</a>. This page was verified to be valid XHTML 1.0 transitional,
749 which proves that all pages generated by THtml can be valid, as long as the user
750 provided XHTML (documentation, header, etc) is valid. You can check the current
751 THtml by clicking this icon:
752 <a href="http://validator.w3.org/check?uri=referer"><img
753  src="http://www.w3.org/Icons/valid-xhtml10"
754  alt="Valid XHTML 1.0 Transitional" height="31" width="88" style="border: none;"/></a></p>
755 Overview:
756 <ol style="list-style-type: upper-roman;">
757  <li><a href="#usage">Usage</a></li>
758  <li><a href="#conf">Configuration</a>
759  <ol><li><a href="#conf:input">Input files</a></li>
760  <li><a href="#conf:output">Output directory</a></li>
761  <li><a href="#conf:liblink">Linking other documentation</a></li>
762  <li><a href="#conf:classdoc">Recognizing class documentation</a></li>
763  <li><a href="#conf:tags">Author, copyright, etc.</a></li>
764  <li><a href="#conf:header">Header and footer</a></li>
765  <li><a href="#conf:search">Links to searches, home page, ViewVC</a></li>
766  <li><a href="#conf:charset">HTML Charset</a></li>
767  </ol></li>
768  <li><a href="#syntax">Documentation syntax</a>
769  <ol><li><a href="#syntax:classdesc">Class description</a></li>
770  <li><a href="#syntax:classidx">Class index</a></li>
771  <li><a href="#syntax:meth">Method documentation</a></li>
772  <li><a href="#syntax:datamem">Data member documentation</a></li>
773  </ol></li>
774  <li><a href="#directive">Documentation directives</a>
775  <ol><li><a href="#directive:html"><tt>BEGIN<!-- -->_HTML</tt> <tt>END<!-- -->_HTML</tt>: include 'raw' HTML</a></li>
776  <li><a href="#directive:macro"><tt>BEGIN<!-- -->_MACRO</tt> <tt>END<!-- -->_MACRO</tt>: include a picture generated by a macro</a></li>
777  <li><a href="#directive:latex"><tt>BEGIN<!-- -->_LATEX</tt> <tt>END<!-- -->_LATEX</tt>: include a latex picture</a></li>
778  </ol></li>
779  <li><a href="#index">Product and module index</a></li>
780  <li><a href="#aux">Auxiliary files: style sheet, JavaScript, help page</a></li>
781  <li><a href="#charts">Class Charts</a></li>
782  <li><a href="#confvar">Configuration variables</a></li>
783  <li><a href="#how">Behind the scenes</a></li>
784 </ol>
785 
786 
787 <h3><a name="usage">I. Usage</a></h3>
788 These are typical things people do with THtml:
789 <pre>
790  root[] <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> html; // create a <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> object
791  root[] html.LoadAllLibs(); // Load all rootmap'ed libraries
792  root[] html.MakeAll(); // generate documentation for all changed classes
793 </pre>
794 or to run on just a few classes:
795 <pre>
796  root[] <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> html; // create a <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> object
797  root[] html.MakeIndex(); // create auxiliary files (style sheet etc) and indices
798  root[] html.MakeClass("TMyClass"); // create documentation for TMyClass only
799 </pre>
800 To "beautify" (i.e. create links to documentation for class names etc) some text
801 file or macro, use:
802 <pre>
803  root[] html.Convert( "hsimple.C", "Histogram example" )
804 </pre>
805 
806 
807 <h3><a name="conf">II. Configuration</a></h3>
808 Most configuration options can be set as a call to THtml, or as a TEnv variable,
809 which you can set in your .rootrc.
810 
811 <h4><a name="conf:input">II.1 Input files</a></h4>
812 
813 <p>In your .rootrc, define Root.Html.SourceDir to point to directories containing
814 .cxx and .h files (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>)
815 of the classes you want to document, or call THtml::SetInputDir()</p>
816 
817 <p>Example:</p><pre>
818  Root.Html.SourceDir: .:src:include
819  Root.Html.Root: http://root.cern.ch/root/html</pre>
820 
821 
822 <h4><a name="conf:output">II.2 Output directory</a></h4>
823 
824 <p>The output directory can be specified using the Root.Html.OutputDir
825 configuration variable (default value: "htmldoc"). If that directory
826 doesn't exist <a href="http://root.cern.ch/root/html/THtml.html">THtml</a>
827 will create it.</p>
828 
829 <p>Example:</p><pre>
830  Root.Html.OutputDir: htmldoc</pre>
831 
832 <h4><a name="conf:liblink">II.3 Linking other documentation</a></h4>
833 
834 <p>When trying to document a class, THtml searches for a source file in
835 the directories set via SetInputDir(). If it cannot find it, it assumes
836 that this class must have been documented before. Based on the library
837 this class is defined in, it checks the configuration variable
838 <tt>Root.Html.LibName</tt>, and creates a link using its value.
839 Alternatively, you can set these URLs via THtml::SetLibURL().</p>
840 
841 <p>Example:<br/>
842 If a class MyClass is defined in class mylibs/libMyLib.so, and .rootrc
843 contains</p><pre>
844  Root.Html.MyLib: ../mylib/</pre>
845 <p>THtml will create a link to "../mylib/MyClass.html".</p>
846 
847 <p>The library name association can be set up using the rootmap facility.
848 For the library in the example above, which contains a dictionary
849 generated from the linkdef MyLinkdef.h, the command to generate the
850 rootmap file is</p>
851 <pre> $ rlibmap -f -r rootmap -l mylib/libMyLib.so -d libCore.so -c MyLinkdef.h</pre>
852 <p>Here, <tt>-r</tt> specifies that the entries for libMyLib should be updated,
853 <tt>-l</tt> specifies the library we're dealing with, <tt>-d</tt> its
854 dependencies, and <tt>-c</tt> its linkdef. The rootmap file must be within
855 one of the <tt>LD_LIBRARY_PATH</tt> (or <tt>PATH</tt> for Windows) directories
856 when ROOT is started, otherwise ROOT will not use it.</p>
857 
858 <h4><a name="conf:classdoc">II.4 Recognizing class documentation</a></h4>
859 
860 <p>The class documentation has to appear in the header file containing the
861 class, right in front of its declaration. It is introduced by a string
862 defined by Root.Html.Description or SetClassDocTag(). See the section on
863 <a href="#syntax">documentation syntax</a> for further details.</p>
864 
865 <p>Example:</p><pre>
866  Root.Html.Description: //____________________</pre>
867 
868 <p>The class documentation will show which include statement is to be used
869 and which library needs to be linked to access it.
870 The include file name is determined via
871 <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetDeclFileName">
872 TClass::GetDeclFileName()</a>;
873 leading parts are removed if they match any of the ':' separated entries in
874 THtml::GetIncludePath().</p>
875 
876 <h4><a name="conf:tags">II.5 Author, copyright, etc.</a></h4>
877 
878 <p>During the conversion,
879 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will look for
880 some strings ("tags") in the source file, which have to appear right in
881 front of e.g. the author's name, copyright notice, etc. These tags can be
882 defined with the following environment variables: Root.Html.Author,
883 Root.Html.LastUpdate and Root.Html.Copyright, or with
884 SetAuthorTag(), SetLastUpdateTag(), SetCopyrightTag().</p>
885 
886 <p>If the LastUpdate tag is not found, the current date and time are used.
887 This is useful when using
888 <a href="http://root.cern.ch/root/html/THtml.html#THtml:MakeAll">THtml::MakeAll()</a>'s
889 default option force=kFALSE, in which case
890 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> generates
891 documentation only for changed classes.</p>
892 
893 Authors can be a comma separated list of author entries. Each entry has
894 one of the following two formats
895 <ul><li><tt>Name (non-alpha)</tt>.
896 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate an
897 HTML link for <tt>Name</tt>, taking the Root.Html.XWho configuration
898 variable (defaults to "http://consult.cern.ch/xwho/people?") and adding
899 all parts of the name with spaces replaces by '+'. Non-alphanumerical
900 characters are printed out behind <tt>Name</tt>.</p>
901 
902 <p>Example:</p>
903 <tt>// Author: Enrico Fermi</tt> appears in the source file.
904 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate the link
905 <tt>http://consult.cern.ch/xwho/people?Enrico+Fermi</tt>. This works well for
906 people at CERN.</li>
907 
908 <li><tt>Name &lt;link&gt; Info</tt>.
909 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate
910 an HTML link for <tt>Name</tt> as specified by <tt>link</tt> and print
911 <tt>Info</tt> behind <tt>Name</tt>.</p>
912 
913 <p>Example:</p>
914 <tt>// Author: Enrico Fermi &lt;http://www.enricos-home.it&gt;</tt> or<br/>
915 <tt>// Author: Enrico Fermi &lt;mailto:enrico@fnal.gov&gt;</tt> in the
916 source file. That's world compatible.</li>
917 </ul>
918 
919 <p>Example (with defaults given):</p><pre>
920  Root.Html.Author: // Author:
921  Root.Html.LastUpdate: // @(#)
922  Root.Html.Copyright: * Copyright
923  Root.Html.XWho: http://consult.cern.ch/xwho/people?</pre>
924 
925 
926 <h4><a name="conf:header">II.6 Header and footer</a></h4>
927 
928 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> generates
929 a default header and footer for all pages. You can
930 specify your own versions with the configuration variables Root.Html.Header
931 and Root.Html.Footer, or by calling SetHeader(), SetFooter().
932 Both variables default to "", using the standard Root
933 versions. If it has a "+" appended, <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will
934 write both versions (user and root) to a file, for the header in the order
935 1st root, 2nd user, and for the footer 1st user, 2nd root (the root
936 versions containing "&lt;html&gt;" and &lt;/html&gt; tags, resp).</p>
937 
938 <p>If you want to replace root's header you have to write a file containing
939 all HTML elements necessary starting with the &lt;doctype&gt; tag and ending with
940 (and including) the &lt;body&gt; tag. If you add your header it will be added
941 directly after Root's &lt;body&gt; tag. Any occurrence of the string <tt>%TITLE%</tt>
942 in the user's header file will be replaced by
943 a sensible, automatically generated title. If the header is generated for a
944 class, occurrences of <tt>%CLASS%</tt> will be replaced by the current class's name,
945 <tt>%SRCFILE%</tt> and <tt>%INCFILE%</tt> by the name of the source and header file, resp.
946 (as given by <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetImplFileLine">TClass::GetImplFileName()</a>,
947 <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetImplFileLine">TClass::GetDeclFileName()</a>).
948 If the header is not generated for a class, they will be replaced by "".</p>
949 
950 <p>Root's footer starts with the tag &lt;!--SIGNATURE--&gt;. It includes the
951 author(s), last update, copyright, the links to the Root home page, to the
952 user home page, to the index file (ClassIndex.html), to the top of the page
953 and <tt>this page is automatically generated</tt> infomation. It ends with the
954 tags <tt>&lt;/body&gt;&lt;/html&gt;</tt>. If you want to replace it,
955 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will search for some
956 tags in your footer: Occurrences of the strings <tt>%AUTHOR%</tt>, <tt>%UPDATE%</tt>, and
957 <tt>%COPYRIGHT%</tt> are replaced by their
958 corresponding values before writing the html file. The <tt>%AUTHOR%</tt> tag will be
959 replaced by the exact string that follows Root.Html.Author, no link
960 generation will occur.</p>
961 
962 
963 <h4><a name="conf:search">II.7 Links to searches, home page, ViewVC</a></h4>
964 
965 <p>Additional parameters can be set by Root.Html.Homepage (address of the
966 user's home page), Root.Html.SearchEngine (search engine for the class
967 documentation), Root.Html.Search (search URL, where %u is replaced by the
968 referer and %s by the escaped search expression), and a ViewVC base URL
969 Root.Html.ViewCVS. For the latter, the file name is appended or, if
970 the URL contains %f, %f is replaced by the file name.
971 All values default to "".</p>
972 
973 <p>Examples:</p><pre>
974  Root.Html.Homepage: http://www.enricos-home.it
975  Root.Html.SearchEngine: http://root.cern.ch/root/Search.phtml
976  Root.Html.Search: http://www.google.com/search?q=%s+site%3A%u</pre>
977 
978 
979 <h4><a name="conf:charset">II.8 HTML Charset</a></h4>
980 
981 <p>XHTML 1.0 transitional recommends the specification of the charset in the
982 content type meta tag, see e.g. <a href="http://www.w3.org/TR/2002/REC-xhtml1-20020801/">http://www.w3.org/TR/2002/REC-xhtml1-20020801/</a>
983 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> generates it for the HTML output files. It defaults to ISO-8859-1, and
984 can be changed using Root.Html.Charset.</p>
985 
986 <p>Example:</p><pre>
987  Root.Html.Charset: EUC-JP</pre>
988 
989 <h3><a name="syntax">III. Documentation syntax</a></h3>
990 <h4><a name="syntax:classdesc">III.1 Class description</a></h4>
991 
992 <p>A class description block, which must be placed before the first
993 member function, has a following form:</p>
994 <pre>
995 ////////////////////////////////////////////////////////////////
996 // //
997 // TMyClass //
998 // //
999 // This is the description block. //
1000 // //
1001 ////////////////////////////////////////////////////////////////
1002 </pre>
1003 <p>The environment variable Root.Html.Description
1004 (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>) contains
1005 the delimiter string (default value: <tt>//_________________</tt>). It means
1006 that you can also write your class description block like this:</p>
1007 <pre>
1008  //_____________________________________________________________
1009  // A description of the class starts with the line above, and
1010  // will take place here !
1011  //
1012 </pre>
1013 <p>Note that <b><i>everything</i></b> until the first non-commented line is considered
1014 as a valid class description block.</p>
1015 
1016 <h4><a name="syntax:classidx">III.2 Class index</a></h4>
1017 
1018 <p>All classes to be documented will have an entry in the ClassIndex.html,
1019 showing their name with a link to their documentation page and a miniature
1020 description. This discription for e.g. the class MyClass has to be given
1021 in MyClass's header as a comment right after ClassDef(MyClass, n).</p>
1022 
1023 <h4><a name="syntax:meth">III.3 Method documentation</a></h4>
1024 <p>A member function description block starts immediately after '{'
1025 and looks like this:</p>
1026 <pre>
1027  void TWorld::HelloWorldFunc(string *text)
1028  {
1029  // This is an example of description for the
1030  // TWorld member function
1031 
1032  helloWorld.Print( text );
1033  }
1034 </pre>
1035 Like in a class description block, <b><i>everything</i></b> until the first
1036 non-commented line is considered as a valid member function
1037 description block.
1038 
1039 If the rootrc variable <tt>Root.Html.DescriptionStyle</tt> is set to
1040 <tt>Doc++</tt> THtml will also look for method documentation in front of
1041 the function implementation. This feature is not recommended; source code
1042 making use of this does not comply to the ROOT documentation standards, which
1043 means future versions of THtml might not support it anymore.
1044 
1045 <h4><a name="syntax:datamem">III.4 Data member documentation</a></h4>
1046 
1047 <p>Data members are documented by putting a C++ comment behind their
1048 declaration in the header file, e.g.</p>
1049 <pre>
1050  int fIAmADataMember; // this is a data member
1051 </pre>
1052 
1053 
1054 <h3><a name="directive">IV. Documentation directives</a></h3>
1055 <em>NOTE that THtml does not yet support nested directives
1056 (i.e. latex inside html etc)!</em>
1057 
1058 <h4><a name="directive:html">IV.1 <tt>BEGIN<!-- -->_HTML</tt> <tt>END<!-- -->_HTML</tt>: include 'raw' HTML</a></h4>
1059 
1060 <p>You can insert pure html code into your documentation comments. During the
1061 generation of the documentation, this code will be inserted as is
1062 into the html file.</p>
1063 <p>Pure html code must be surrounded by the keywords
1064 <tt>BEGIN<!-- -->_HTML</tt> and <tt>END<!-- -->_HTML</tt>, where the
1065 case is ignored.
1066 An example of pure html code is this class description you are reading right now.
1067 THtml uses a
1068 <a href="http://root.cern.ch/root/html/TDocHtmlDirective.html">TDocHtmlDirective</a>
1069 object to process this directive.</p>
1070 
1071 <h4><a name="directive:macro">IV.2 <tt>BEGIN<!-- -->_MACRO</tt> <tt>END<!-- -->_MACRO</tt>: include a picture generated by a macro</a></h4>
1072 
1073 <p>THtml can create images from scripts. You can either call an external
1074 script by surrounding it by "begin_macro"/"end_macro", or include an unnamed
1075 macro within these keywords. The macro should return a pointer to an object;
1076 this object will then be saved as a GIF file.</p>
1077 <p>Objects deriving from
1078 <a href="http://root.cern.ch/root/html/TGObject.html">TGObject</a> (GUI elements)
1079 will need to run in graphics mode (non-batch). You must specify this as a parameter:
1080 "Begin_macro(GUI)...".
1081 To create a second tab that displays the source of the macro you can specify
1082 the argument "Begin_macro(source)...".
1083 Of course you can combine them,
1084 e.g. as "Begin_macro(source,gui)...".
1085 THtml uses a
1086 <a href="http://root.cern.ch/root/html/TDocMacroDirective.html">TDocMacroDirective</a>
1087 object to process this directive.</p>
1088 <p>This is an example:</p> END_HTML
1089 BEGIN_MACRO(source)
1090 {
1091  TCanvas* macro_example_canvas = new TCanvas("macro_example_canvas", "", 150, 150);
1092  macro_example_canvas->SetBorderSize(0);
1093  macro_example_canvas->SetFillStyle(1001);
1094  macro_example_canvas->SetFillColor(kWhite);
1095  macro_example_canvas->cd();
1096  TArc* macro_example_arc = new TArc(0.5,0.32,0.11,180,360);
1097  macro_example_arc->Draw();
1098  TEllipse* macro_example_ellipsis = new TEllipse(0.42,0.58,0.014,0.014,0,360,0);
1099  macro_example_ellipsis->SetFillStyle(0);
1100  macro_example_ellipsis->Draw();
1101  macro_example_ellipsis = new TEllipse(0.58,0.58,0.014,0.014,0,360,0);
1102  macro_example_ellipsis->SetFillStyle(0);
1103  macro_example_ellipsis->Draw();
1104  macro_example_ellipsis = new TEllipse(0.50,0.48,0.22,0.32,0,360,0);
1105  macro_example_ellipsis->SetFillStyle(0);
1106  macro_example_ellipsis->Draw();
1107  TLine* macro_example_line = new TLine(0.48,0.53,0.52,0.41);
1108  macro_example_line->Draw();
1109  return macro_example_canvas;
1110 }
1111 END_MACRO
1112 
1113 BEGIN_HTML
1114 <h4><a name="directive:latex">IV.3 <tt>BEGIN<!-- -->_LATEX</tt> <tt>END<!-- -->_LATEX</tt>: include a latex picture</a></h4>
1115 
1116 <p>You can specify <a href="http://root.cern.ch/root/html/TLatex.html">TLatex</a>
1117 style text and let THtml convert it into an image by surrounding it by "Begin_Latex", "End_Latex".
1118 You can have multiple lines, and e.g. align each line at the '=' sign by passing
1119 the argument <tt>separator='='</tt>. You can also specify how to align these parts;
1120 if you want the part left of the separator to be right aligned, and the right part
1121 to be left aligned, you could specify <tt>align='rl'</tt>.
1122 THtml uses a <a href="http://root.cern.ch/root/html/TDocLatexDirective.html">TDocLatexDirective</a>
1123 object to process the directive.
1124 This is an example output with arguments <tt>separator='=', align='rl'</tt>:</p>
1125 END_HTML BEGIN_LATEX(separator='=', align='rl')#kappa(x)^{2}=sin(x)^{x}
1126 x=#chi^{2} END_LATEX
1127 
1128 BEGIN_HTML
1129 
1130 <h3><a name="index">V. Product and module index</a></h3>
1131 
1132 <p><a href="#THtml:MakeIndex">THtml::MakeIndex()</a> will generate index files for classes
1133 and types, all modules, and the product which you can set by
1134 <a href="#THtml:SetProductName">THtml::SetProductName()</a>.
1135 THtml will make use of external documentation in the module and product index,
1136 either by linking it or by including it.
1137 The files for modules are searched based on the source file directory of the
1138 module's classes.</p>
1139 
1140 <p>A filename starting with "index." will be included in the index page;
1141 all other files will be linked.
1142 Only files ending on <tt>.html</tt> or <tt>.txt</tt> will be taken into account;
1143 the text files will first be run through
1144 <a href="#THtml:Convert">THtml::Convert()</a>.
1145 You can see an example <a href="http://root.cern.ch/root/html/HIST_Index.html">here</a>;
1146 the part between "Index of HIST classes" and "Jump to" is created by parsing
1147 the module's doc directory.</p>
1148 
1149 <h3><a name="aux">VI. Auxiliary files: style sheet, JavaScript, help page</a></h3>
1150 
1151 <p>The documentation pages share a common set of javascript and CSS files. They
1152 are generated automatically when running <a href="#THtml:MakeAll">MakeAll()</a>;
1153 they can be generated on
1154 demand by calling <a href="#THtml:CreateAuxiliaryFiles">CreateAuxiliaryFiles()</a>.</p>
1155 
1156 
1157 <h3><a name="charts">VII. Class Charts</a></h3>
1158 THtml can generate a number of graphical representations for a class, which
1159 are displayed as a tabbed set of imaged ontop of the class description.
1160 It can show the inheritance, inherited and hidden members, directly and
1161 indirectly included files, and library dependencies.
1162 
1163 These graphs are generated using the <a href="http://www.graphviz.org/">Graphviz</a>
1164 package. You can install it from <a href="http://www.graphviz.org">http://www.graphviz.org</a>.
1165 You can either put it into your $PATH, or tell THtml where to find it by calling
1166 <a href="#THtml:SetDotDir">SetDotDir()</a>.
1167 
1168 
1169 <h3><a name="confvar">VIII. Configuration variables</a></h3>
1170 
1171 <p>Here is a list of all configuration variables that are known to THtml.
1172 You can set them in your .rootrc file, see
1173 <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>.</p>
1174 
1175 <pre>
1176  Root.Html.OutputDir (default: htmldoc)
1177  Root.Html.SourceDir (default: .:src/:include/)
1178  Root.Html.Author (default: // Author:) - start tag for authors
1179  Root.Html.LastUpdate (default: // @(#)) - start tag for last update
1180  Root.Html.Copyright (default: * Copyright) - start tag for copyright notice
1181  Root.Html.Description (default: //____________________ ) - start tag for class descr
1182  Root.Html.HomePage (default: ) - URL to the user defined home page
1183  Root.Html.Header (default: ) - location of user defined header
1184  Root.Html.Footer (default: ) - location of user defined footer
1185  Root.Html.Root (default: ) - URL of Root's class documentation
1186  Root.Html.SearchEngine (default: ) - link to the search engine
1187  Root.Html.Search (defualt: ) - link to search by replacing "%s" with user input
1188  Root.Html.ViewCVS (default: ) - URL of ViewCVS base
1189  Root.Html.XWho (default: http://consult.cern.ch/xwho/people?) - URL of CERN's xWho
1190  Root.Html.Charset (default: ISO-8859-1) - HTML character set
1191 </pre>
1192 
1193 <h3><a name="how">IX. Behind the scene</a></h3>
1194 
1195 <p>Internally, THtml is just an API class that sets up the list of known
1196 classes, and forwards API invocations to the "work horses".
1197 <a href="http://root.cern.ch/root/html/TDocOutput.html">TDocOutput</a>
1198 generates the output by letting a
1199 <a href="http://root.cern.ch/root/html/TDocParser.html">TDocParser</a>
1200 object parse the sources, which in turn invokes objects deriving from
1201 <a href="http://root.cern.ch/root/html/TDocDirective.html">TDocDirective</a>
1202 to process directives.</p>
1203 
1204 END_HTML */
1205 ////////////////////////////////////////////////////////////////////////////////
1206 
1207 ClassImp(THtml)
1208 ////////////////////////////////////////////////////////////////////////////////
1209 /// Create a THtml object.
1210 /// In case output directory does not exist an error
1211 /// will be printed and gHtml stays 0 also zombie bit will be set.
1212 
1214  fCounterFormat("%12s %5s %s"),
1215  fProductName("(UNKNOWN PRODUCT)"),
1216  fThreadedClassIter(0), fThreadedClassCount(0), fMakeClassMutex(0),
1217  fGClient(0), fPathDef(0), fModuleDef(0), fFileDef(0),
1218  fLocalFiles(0), fBatch(kFALSE)
1219 {
1220  // check for source directory
1221  fPathInfo.fInputPath = gEnv->GetValue("Root.Html.SourceDir", "./:src/:include/");
1222 
1223  // check for output directory
1224  SetOutputDir(gEnv->GetValue("Root.Html.OutputDir", "htmldoc"));
1225 
1226  fLinkInfo.fXwho = gEnv->GetValue("Root.Html.XWho", "http://consult.cern.ch/xwho/people?");
1227  fLinkInfo.fROOTURL = gEnv->GetValue("Root.Html.Root", "http://root.cern.ch/root/html");
1228  fDocSyntax.fClassDocTag = gEnv->GetValue("Root.Html.Description", "//____________________");
1229  fDocSyntax.fAuthorTag = gEnv->GetValue("Root.Html.Author", "// Author:");
1230  fDocSyntax.fLastUpdateTag = gEnv->GetValue("Root.Html.LastUpdate", "// @(#)");
1231  fDocSyntax.fCopyrightTag = gEnv->GetValue("Root.Html.Copyright", "* Copyright");
1232  fOutputStyle.fHeader = gEnv->GetValue("Root.Html.Header", "");
1233  fOutputStyle.fFooter = gEnv->GetValue("Root.Html.Footer", "");
1234  fLinkInfo.fHomepage = gEnv->GetValue("Root.Html.Homepage", "");
1235  fLinkInfo.fSearchStemURL = gEnv->GetValue("Root.Html.Search", "");
1236  fLinkInfo.fSearchEngine = gEnv->GetValue("Root.Html.SearchEngine", "");
1237  fLinkInfo.fViewCVS = gEnv->GetValue("Root.Html.ViewCVS", "");
1238  fOutputStyle.fCharset = gEnv->GetValue("Root.Html.Charset", "ISO-8859-1");
1239  fDocSyntax.fDocStyle = gEnv->GetValue("Root.Html.DescriptionStyle", "");
1240 
1241  fDocEntityInfo.fClasses.SetOwner();
1242  fDocEntityInfo.fModules.SetOwner();
1243  // insert html object in the list of special ROOT objects
1244  if (!gHtml) {
1245  gHtml = this;
1246  gROOT->GetListOfSpecials()->Add(gHtml);
1247  }
1248 
1249 }
1250 
1251 
1252 ////////////////////////////////////////////////////////////////////////////////
1253 /// Default destructor
1254 
1256 {
1257  fDocEntityInfo.fClasses.Clear();
1258  fDocEntityInfo.fModules.Clear();
1259  if (gHtml == this) {
1260  gROOT->GetListOfSpecials()->Remove(gHtml);
1261  gHtml = 0;
1262  }
1263  delete fPathDef;
1264  delete fModuleDef;
1265  delete fFileDef;
1266  delete fLocalFiles;
1267 }
1268 
1269 ////////////////////////////////////////////////////////////////////////////////
1270 /// Add path to the directories to be searched for macro files
1271 /// that are to be executed via the TDocMacroDirective
1272 /// ("Begin_Macro"/"End_Macro"); relative to the source file
1273 /// that the directive is run on.
1274 
1275 void THtml::AddMacroPath(const char* path)
1276 {
1277  const char pathDelimiter =
1278 #ifdef R__WIN32
1279  ';';
1280 #else
1281  ':';
1282 #endif
1283  fPathInfo.fMacroPath += pathDelimiter;
1284  fPathInfo.fMacroPath += path;
1285 }
1286 
1287 
1288 ////////////////////////////////////////////////////////////////////////////////
1289 /// copy CSS, javascript file, etc to the output dir
1290 
1292 {
1293  CreateJavascript();
1294  CreateStyleSheet();
1295  CopyFileFromEtcDir("HELP.html");
1296 }
1297 
1298 ////////////////////////////////////////////////////////////////////////////////
1299 /// Return the TModuleDefinition (or derived) object as set by
1300 /// SetModuleDefinition(); create and return a TModuleDefinition object
1301 /// if none was set.
1302 
1304 {
1305  if (!fModuleDef) {
1306  fModuleDef = new TModuleDefinition();
1307  fModuleDef->SetOwner(const_cast<THtml*>(this));
1308  }
1309  return *fModuleDef;
1310 }
1311 
1312 ////////////////////////////////////////////////////////////////////////////////
1313 /// Return the TFileDefinition (or derived) object as set by
1314 /// SetFileDefinition(); create and return a TFileDefinition object
1315 /// if none was set.
1316 
1318 {
1319  if (!fFileDef) {
1320  fFileDef = new TFileDefinition();
1321  fFileDef->SetOwner(const_cast<THtml*>(this));
1322  }
1323  return *fFileDef;
1324 }
1325 
1326 ////////////////////////////////////////////////////////////////////////////////
1327 /// Return the TModuleDefinition (or derived) object as set by
1328 /// SetModuleDefinition(); create and return a TModuleDefinition object
1329 /// if none was set.
1330 
1332 {
1333  if (!fPathDef) {
1334  fPathDef = new TPathDefinition();
1335  fPathDef->SetOwner(const_cast<THtml*>(this));
1336  }
1337  return *fPathDef;
1338 }
1339 
1340 
1341 ////////////////////////////////////////////////////////////////////////////////
1342 /// Get the directory containing THtml's auxiliary files ($ROOTSYS/etc/html)
1343 
1344 const char* THtml::GetEtcDir() const
1345 {
1346  if (fPathInfo.fEtcDir.Length())
1347  return fPathInfo.fEtcDir;
1348 
1349  R__LOCKGUARD(GetMakeClassMutex());
1350 
1351  fPathInfo.fEtcDir = "html";
1352 
1353 #ifdef ROOTETCDIR
1354  gSystem->PrependPathName(ROOTETCDIR, fPathInfo.fEtcDir);
1355 #else
1356  gSystem->PrependPathName("etc", fPathInfo.fEtcDir);
1357 # ifdef ROOTPREFIX
1358  gSystem->PrependPathName(ROOTPREFIX, fPathInfo.fEtcDir);
1359 # else
1360  if (getenv("ROOTSYS"))
1361  gSystem->PrependPathName(getenv("ROOTSYS"), fPathInfo.fEtcDir);
1362 # endif
1363 #endif
1364 
1365  return fPathInfo.fEtcDir;
1366 }
1367 
1368 
1369 ////////////////////////////////////////////////////////////////////////////////
1370 /// Return the next class to be generated for MakeClassThreaded.
1371 
1373 {
1374  if (!fThreadedClassIter) return 0;
1375 
1376  R__LOCKGUARD(GetMakeClassMutex());
1377 
1378  TClassDocInfo* classinfo = 0;
1379  while ((classinfo = (TClassDocInfo*)(*fThreadedClassIter)())
1380  && !classinfo->IsSelected()) { }
1381 
1382  if (!classinfo) {
1383  delete fThreadedClassIter;
1384  fThreadedClassIter = 0;
1385  }
1386 
1387  fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - fThreadedClassCount++);
1388 
1389  return classinfo;
1390 }
1391 
1392 
1393 ////////////////////////////////////////////////////////////////////////////////
1394 /// Get the documentation URL for library lib.
1395 /// If lib == 0 or no documentation URL has been set for lib, return the ROOT
1396 /// documentation URL. The return value is always != 0.
1397 
1398 const char* THtml::GetURL(const char* lib /*=0*/) const
1399 {
1400  R__LOCKGUARD(GetMakeClassMutex());
1401 
1402  if (lib && strlen(lib)) {
1403  std::map<std::string, TString>::const_iterator iUrl = fLinkInfo.fLibURLs.find(lib);
1404  if (iUrl != fLinkInfo.fLibURLs.end()) return iUrl->second;
1405  return gEnv->GetValue(TString("Root.Html.") + lib, fLinkInfo.fROOTURL);
1406  }
1407  return fLinkInfo.fROOTURL;
1408 }
1409 
1410 ////////////////////////////////////////////////////////////////////////////////
1411 /// Check whether dot is available in $PATH or in the directory set
1412 /// by SetDotPath()
1413 
1415 {
1416  if (fPathInfo.fFoundDot != PathInfo_t::kDotUnknown)
1417  return (fPathInfo.fFoundDot == PathInfo_t::kDotFound);
1418 
1419  R__LOCKGUARD(GetMakeClassMutex());
1420 
1421  Info("HaveDot", "Checking for Graphviz (dot)...");
1422  TString runDot("dot");
1423  if (fPathInfo.fDotDir.Length())
1424  gSystem->PrependPathName(fPathInfo.fDotDir, runDot);
1425  runDot += " -V";
1426  if (gDebug > 3)
1427  Info("HaveDot", "Running: %s", runDot.Data());
1428  if (gSystem->Exec(runDot)) {
1429  fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
1430  return kFALSE;
1431  }
1432  fPathInfo.fFoundDot = PathInfo_t::kDotFound;
1433  return kTRUE;
1434 
1435 }
1436 
1437 ////////////////////////////////////////////////////////////////////////////////
1438 /// Inform the THtml object that one of its helper objects was deleted.
1439 /// Called by THtml::HelperBase::~HelperBase().
1440 
1442 {
1443  THelperBase* helpers[3] = {fPathDef, fModuleDef, fFileDef};
1444  for (int i = 0; who && i < 3; ++i)
1445  if (who == helpers[i])
1446  helpers[i] = who = 0;
1447 }
1448 
1449 
1450 ////////////////////////////////////////////////////////////////////////////////
1451 /// It converts a single text file to HTML
1452 ///
1453 ///
1454 /// Input: filename - name of the file to convert
1455 /// title - title which will be placed at the top of the HTML file
1456 /// dirname - optional parameter, if it's not specified, output will
1457 /// be placed in htmldoc/examples directory.
1458 /// relpath - optional parameter pointing to the THtml generated doc
1459 /// on the server, relative to the current page.
1460 /// includeOutput - if != kNoOutput, run the script passed as filename and
1461 /// store all created canvases in PNG files that are
1462 /// shown next to the converted source. Bitwise-ORing with
1463 /// kForceOutput re-runs the script even if output PNGs exist
1464 /// that are newer than the script. If kCompiledOutput is
1465 /// passed, the script is run through ACLiC (.x filename+)
1466 /// context - line shown verbatim at the top of the page; e.g. for links.
1467 /// If context is non-empty it is expected to also print the
1468 /// title.
1469 ///
1470 /// NOTE: Output file name is the same as filename, but with extension .html
1471 ///
1472 
1473 void THtml::Convert(const char *filename, const char *title,
1474  const char *dirname /*= ""*/, const char *relpath /*= "../"*/,
1475  Int_t includeOutput /* = kNoOutput */,
1476  const char* context /* = "" */)
1477 {
1478  gROOT->GetListOfGlobals(kTRUE); // force update of this list
1479  CreateListOfClasses("*");
1480 
1481  const char *dir;
1482 
1483  // if it's not defined, make the "examples" as a default directory
1484  if (!*dirname) {
1485  gSystem->ExpandPathName(fPathInfo.fOutputDir);
1486  dir = gSystem->ConcatFileName(fPathInfo.fOutputDir, "examples");
1487  } else
1488  dir = dirname;
1489 
1490  // create directory if necessary
1491  if (gSystem->AccessPathName(dir))
1492  gSystem->MakeDirectory(dir);
1493 
1494  // find a file
1495  char *cRealFilename =
1496  gSystem->Which(fPathInfo.fInputPath, filename, kReadPermission);
1497 
1498  if (!cRealFilename) {
1499  Error("Convert", "Can't find file '%s' !", filename);
1500  return;
1501  }
1502 
1503  TString realFilename(cRealFilename);
1504  delete[] cRealFilename;
1505  cRealFilename = 0;
1506 
1507  // open source file
1508  std::ifstream sourceFile;
1509  sourceFile.open(realFilename, std::ios::in);
1510 
1511  if (!sourceFile.good()) {
1512  Error("Convert", "Can't open file '%s' !", realFilename.Data());
1513  return;
1514  }
1515 
1516  if (gSystem->AccessPathName(dir)) {
1517  Error("Convert",
1518  "Directory '%s' doesn't exist, or it's write protected !", dir);
1519  return;
1520  }
1521  char *tmp1 =
1522  gSystem->ConcatFileName(dir, gSystem->BaseName(filename));
1523 
1524  TDocOutput output(*this);
1525  if (!fGClient)
1526  gROOT->ProcessLine(TString::Format("*((TGClient**)0x%lx) = gClient;",
1527  (ULong_t)&fGClient));
1528  if (includeOutput && !fGClient)
1529  Warning("Convert", "Output requested but cannot initialize graphics: GUI and GL windows not be available");
1530  output.Convert(sourceFile, realFilename, tmp1, title, relpath, includeOutput, context, fGClient);
1531 
1532  if (tmp1)
1533  delete[]tmp1;
1534  tmp1 = 0;
1535 }
1536 
1537 ////////////////////////////////////////////////////////////////////////////////
1538 /// Return the module name for a given class.
1539 /// Use the cached information from fDocEntityInfo.fClasses.
1540 
1542 {
1543  module = "(UNKNOWN)";
1544  if (!cl) return;
1545 
1546  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(cl->GetName());
1547  if (!cdi || !cdi->GetModule())
1548  return;
1549  module = cdi->GetModule()->GetName();
1550 }
1551 
1552 
1553 ////////////////////////////////////////////////////////////////////////////////
1554 /// Create the list of all known classes
1555 
1556 void THtml::CreateListOfClasses(const char* filter)
1557 {
1558  if (fDocEntityInfo.fClasses.GetSize() && fDocEntityInfo.fClassFilter == filter)
1559  return;
1560 
1561  Info("CreateListOfClasses", "Initializing - this might take a while...");
1562  // get total number of classes
1563  Int_t totalNumberOfClasses = gClassTable->Classes();
1564 
1565  // allocate memory
1566  fDocEntityInfo.fClasses.Clear();
1567  fDocEntityInfo.fModules.Clear();
1568 
1569  fDocEntityInfo.fClassFilter = filter;
1570 
1571  // start from begining
1572  gClassTable->Init();
1573  if (filter && (!filter[0] || !strcmp(filter, "*")))
1574  filter = ".*";
1575  TString reg = filter;
1576  TPMERegexp re(reg);
1577 
1578  bool skipROOTClasses = false;
1579  std::set<std::string> rootLibs;
1580  TList classesDeclFileNotFound;
1581  TList classesImplFileNotFound;
1582 
1583  // pre-run TObject at i == -1
1584  for (Int_t i = -1; i < totalNumberOfClasses; i++) {
1585 
1586  // get class name
1587  const char *cname = 0;
1588  if (i < 0) cname = "TObject";
1589  else cname = gClassTable->Next();
1590  if (!cname)
1591  continue;
1592 
1593  if (i >= 0 && !strcmp(cname, "TObject")) {
1594  // skip the second iteration on TObject
1595  continue;
1596  }
1597 
1598  // This is a hack for until after Cint and Reflex are one.
1599  if (strstr(cname, "__gnu_cxx::")) continue;
1600  // Work around ROOT-6016
1601  if (!strcmp(cname, "timespec")) continue;
1602 
1603  // get class & filename - use TROOT::GetClass, as we also
1604  // want those classes without decl file name!
1605  TClass *classPtr = TClass::GetClass((const char *) cname, kTRUE);
1606  if (!classPtr) continue;
1607 
1608  std::string shortName(ShortType(cname));
1609  cname = shortName.c_str();
1610 
1611  TString s = cname;
1612  Bool_t matchesSelection = re.Match(s);
1613 
1614 
1615  TString hdr;
1616  TString hdrFS;
1617  TString src;
1618  TString srcFS;
1619  TString htmlfilename;
1620  TFileSysEntry* fse = 0;
1621 
1622  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cname);
1623  if (cdi) {
1624  hdr = cdi->GetDeclFileName();
1625  hdrFS = cdi->GetDeclFileSysName();
1626  src = cdi->GetImplFileName();
1627  srcFS = cdi->GetImplFileSysName();
1628  htmlfilename = cdi->GetHtmlFileName();
1629  }
1630 
1631  if (!hdrFS.Length()) {
1632  if (!GetFileDefinition().GetDeclFileName(classPtr, hdr, hdrFS, &fse)) {
1633  // we don't even know where the class is defined;
1634  // just skip. Silence if it doesn't match the selection anyway
1635  if (i == -1 ) {
1636  skipROOTClasses = true;
1637  Info("CreateListOfClasses", "Cannot find header file for TObject at %s given the input path %s.",
1638  classPtr->GetDeclFileName(), GetInputPath().Data());
1639  Info("CreateListOfClasses", "Assuming documentation is not for ROOT classes, or you need to pass "
1640  "the proper directory to THtml::SetInputDir() so I can find %s.", classPtr->GetDeclFileName());
1641  continue;
1642  }
1643  // ignore STL
1644  if (classPtr->GetClassInfo() &&
1645  (gInterpreter->ClassInfo_Property(classPtr->GetClassInfo()) & kIsDefinedInStd))
1646  continue;
1647  if (classPtr->GetDeclFileName() && (!strncmp(classPtr->GetDeclFileName(), "prec_stl/", 9) ||
1648  strstr(classPtr->GetDeclFileName(), "include/c++/") ||
1649  !strncmp(classPtr->GetDeclFileName(), "/usr/include",12)))
1650  continue;
1651  if (classPtr->GetDeclFileName() && (
1652  !strcmp(classPtr->GetDeclFileName(), "vector") ||
1653  !strcmp(classPtr->GetDeclFileName(), "string") ||
1654  !strcmp(classPtr->GetDeclFileName(), "list") ||
1655  !strcmp(classPtr->GetDeclFileName(), "deque") ||
1656  !strcmp(classPtr->GetDeclFileName(), "map") ||
1657  !strcmp(classPtr->GetDeclFileName(), "valarray") ||
1658  !strcmp(classPtr->GetDeclFileName(), "set") ||
1659  !strcmp(classPtr->GetDeclFileName(), "typeinfo") ||
1660  !strcmp(classPtr->GetDeclFileName(), "stdlib.h") ) )
1661  {
1662  // Those are STL header, just ignore.
1663  continue;
1664  }
1665  if (skipROOTClasses) {
1666  if (classPtr->GetSharedLibs() && classPtr->GetSharedLibs()[0]) {
1667  std::string lib(classPtr->GetSharedLibs());
1668  size_t posSpace = lib.find(' ');
1669  if (posSpace != std::string::npos)
1670  lib.erase(posSpace);
1671  if (rootLibs.find(lib) == rootLibs.end()) {
1672 #ifdef ROOTLIBDIR
1673  TString rootlibdir = ROOTLIBDIR;
1674 #else
1675  TString rootlibdir = "lib";
1676  gSystem->PrependPathName(gRootDir, rootlibdir);
1677 #endif
1678  TString sLib(lib);
1679  if (sLib.Index('.') == -1) {
1680  sLib += ".";
1681  sLib += gSystem->GetSoExt();
1682  }
1683  gSystem->PrependPathName(rootlibdir, sLib);
1684  if (gSystem->AccessPathName(sLib))
1685  // the library doesn't exist in $ROOTSYS/lib, so it's not
1686  // a root lib and we need to tell the user.
1687  classesDeclFileNotFound.AddLast(classPtr);
1688  else rootLibs.insert(lib);
1689  } // end "if rootLibs does not contain lib"
1690  } else {
1691  // lib name unknown
1692  static const char* rootClassesToIgnore[] =
1693  { "ColorStruct_t", "CpuInfo_t", "Event_t", "FileStat_t", "GCValues_t", "MemInfo_t",
1694  "PictureAttributes_t", "Point_t", "ProcInfo_t", "ROOT", "ROOT::Fit",
1695  "Rectangle_t", "RedirectHandle_t", "Segment_t", "SetWindowAttributes_t",
1696  "SysInfo_t", "TCint", "UserGroup_t", "WindowAttributes_t", "timespec", 0};
1697  static const char* rootClassStemsToIgnore[] =
1698  { "ROOT::Math", "TKDTree", "TMatrixT", "TParameter", "vector", 0 };
1699  static size_t rootClassStemsToIgnoreLen[] = {0, 0, 0, 0, 0};
1700  static std::set<std::string> setRootClassesToIgnore;
1701  if (setRootClassesToIgnore.empty()) {
1702  for (int ii = 0; rootClassesToIgnore[ii]; ++ii)
1703  setRootClassesToIgnore.insert(rootClassesToIgnore[ii]);
1704  for (int ii = 0; rootClassStemsToIgnore[ii]; ++ii)
1705  rootClassStemsToIgnoreLen[ii] = strlen(rootClassStemsToIgnore[ii]);
1706  }
1707  // only complain about this class if it should not be ignored:
1708  if (setRootClassesToIgnore.find(cname) == setRootClassesToIgnore.end()) {
1709  bool matched = false;
1710  for (int ii = 0; !matched && rootClassStemsToIgnore[ii]; ++ii)
1711  matched = !strncmp(cname, rootClassStemsToIgnore[ii], rootClassStemsToIgnoreLen[ii]);
1712  if (!matched)
1713  classesDeclFileNotFound.AddLast(classPtr);
1714  }
1715  } // lib name known
1716  continue;
1717  } else {
1718  if (matchesSelection && (!classPtr->GetDeclFileName() ||
1719  !strstr(classPtr->GetDeclFileName(),"prec_stl/") ||
1720  !strstr(classPtr->GetDeclFileName(), "include/c++/") ||
1721  strncmp(classPtr->GetDeclFileName(), "/usr/include",12)))
1722  classesDeclFileNotFound.AddLast(classPtr);
1723  continue;
1724  }
1725  }
1726  }
1727 
1728  Bool_t haveSource = (srcFS.Length());
1729  if (!haveSource)
1730  haveSource = GetFileDefinition().GetImplFileName(classPtr, src, srcFS, fse ? 0 : &fse);
1731 
1732  if (!haveSource) {
1733  classesImplFileNotFound.AddLast(classPtr);
1734  }
1735 
1736  if (!htmlfilename.Length())
1737  GetHtmlFileName(classPtr, htmlfilename);
1738 
1739  if (!cdi) {
1740  cdi = new TClassDocInfo(classPtr, htmlfilename, hdrFS, srcFS, hdr, src);
1741  fDocEntityInfo.fClasses.Add(cdi);
1742  } else {
1743  cdi->SetDeclFileName(hdr);
1744  cdi->SetImplFileName(src);
1745  cdi->SetDeclFileSysName(hdrFS);
1746  cdi->SetImplFileSysName(srcFS);
1747  cdi->SetHtmlFileName(htmlfilename);
1748  }
1749 
1750  cdi->SetSelected(matchesSelection);
1751 
1752  TString modulename;
1753  GetModuleDefinition().GetModule(classPtr, fse, modulename);
1754  if (!modulename.Length() || modulename == "USER")
1755  GetModuleNameForClass(modulename, classPtr);
1756 
1757  TModuleDocInfo* module = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(modulename);
1758  if (!module) {
1759  bool moduleSelected = cdi->IsSelected();
1760 
1761  TString parentModuleName(gSystem->DirName(modulename));
1762  TModuleDocInfo* super = 0;
1763  if (parentModuleName.Length() && parentModuleName != ".") {
1764  super = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(parentModuleName);
1765  if (!super) {
1766  // create parents:
1767  TString token;
1768  Ssiz_t pos = 0;
1769  while (parentModuleName.Tokenize(token, pos, "/")) {
1770  if (!token.Length() || token == ".") continue;
1771  super = new TModuleDocInfo(token, super);
1772  super->SetSelected(moduleSelected);
1773  fDocEntityInfo.fModules.Add(super);
1774  }
1775  }
1776  }
1777  module = new TModuleDocInfo(modulename, super);
1778  module->SetSelected(moduleSelected);
1779  fDocEntityInfo.fModules.Add(module);
1780  }
1781 
1782  if (module) {
1783  module->AddClass(cdi);
1784  cdi->SetModule(module);
1785  if (cdi->HaveSource() && cdi->IsSelected())
1786  module->SetSelected();
1787  }
1788 
1789  // clear the typedefs; we fill them later
1790  cdi->GetListOfTypedefs().Clear();
1791 
1792  if (gDebug > 0)
1793  Info("CreateListOfClasses", "Adding class %s, module %s (%sselected)",
1794  cdi->GetName(), module ? module->GetName() : "[UNKNOWN]",
1795  cdi->IsSelected() ? "" : "not ");
1796  }
1797 
1798 
1799 
1800  bool cannotFind = false;
1801  if (!classesDeclFileNotFound.IsEmpty()) {
1802  Warning("CreateListOfClasses",
1803  "Cannot find the header for the following classes [reason]:");
1804  TIter iClassesDeclFileNotFound(&classesDeclFileNotFound);
1805  TClass* iClass = 0;
1806  while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1807  if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1808  Warning("CreateListOfClasses", " %s [header %s not found]", iClass->GetName(), iClass->GetDeclFileName());
1809  cannotFind = true;
1810  } else
1811  Warning("CreateListOfClasses", " %s [header file is unknown]", iClass->GetName());
1812  }
1813  }
1814 
1815  if (!classesImplFileNotFound.IsEmpty() && gDebug > 3) {
1816  Warning("CreateListOfClasses",
1817  "Cannot find the source file for the following classes [reason]:");
1818  TIter iClassesDeclFileNotFound(&classesImplFileNotFound);
1819  TClass* iClass = 0;
1820  while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1821  if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1822  Info("CreateListOfClasses", " %s [source %s not found]", iClass->GetName(), iClass->GetImplFileName());
1823  cannotFind = true;
1824  } else
1825  Info("CreateListOfClasses", " %s [source file is unknown, add \"ClassImpl(%s)\" to source file if it exists]",
1826  iClass->GetName(), iClass->GetName());
1827  }
1828  }
1829  if (cannotFind) {
1830  Warning("CreateListOfClasses", "THtml cannot find all headers and sources. ");
1831  Warning("CreateListOfClasses",
1832  "You might need to adjust the input path (currently %s) by calling THtml::SetInputDir()",
1833  GetInputPath().Data());
1834  }
1835 
1836  // fill typedefs
1837  TIter iTypedef(gROOT->GetListOfTypes());
1838  TDataType* dt = 0;
1839  TDocOutput output(*this);
1840  while ((dt = (TDataType*) iTypedef())) {
1841  if (dt->GetType() != -1) continue;
1842  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(dt->GetFullTypeName());
1843  if (cdi) {
1844  cdi->GetListOfTypedefs().Add(dt);
1845  if (gDebug > 1)
1846  Info("CreateListOfClasses", "Adding typedef %s to class %s",
1847  dt->GetName(), cdi->GetName());
1848 
1849  bool inNamespace = true;
1850  TString surroundingNamespace(dt->GetName());
1851  Ssiz_t posTemplate = surroundingNamespace.Last('>');
1852  inNamespace = inNamespace && (posTemplate == kNPOS);
1853  if (inNamespace) {
1854  Ssiz_t posColumn = surroundingNamespace.Last(':');
1855  if (posColumn != kNPOS) {
1856  surroundingNamespace.Remove(posColumn - 1);
1857  TClass* clSurrounding = GetClass(surroundingNamespace);
1858  inNamespace = inNamespace && (!clSurrounding || IsNamespace(clSurrounding));
1859  }
1860  }
1861  if (inNamespace && cdi->GetModule()) {
1862  TString htmlfilename(dt->GetName());
1863  output.NameSpace2FileName(htmlfilename);
1864  htmlfilename += ".html";
1865  TClassDocInfo* cdiTD = new TClassDocInfo(dt, htmlfilename);
1866  cdiTD->SetModule(cdi->GetModule());
1867  cdiTD->SetSelected(cdi->IsSelected());
1868  cdi->GetModule()->AddClass(cdiTD);
1869  }
1870  }
1871  }
1872 
1873  fDocEntityInfo.fClasses.Sort();
1874  fDocEntityInfo.fModules.Sort();
1875  TIter iterModule(&fDocEntityInfo.fModules);
1876  TModuleDocInfo* mdi = 0;
1877  while ((mdi = (TModuleDocInfo*) iterModule()))
1878  mdi->GetClasses()->Sort();
1879 
1880  if (fProductName == "(UNKNOWN PRODUCT)"
1881  && fDocEntityInfo.fModules.FindObject("core/base")
1882  && fDocEntityInfo.fModules.FindObject("core/cont")
1883  && fDocEntityInfo.fModules.FindObject("core/rint")
1884  && gProgName && strstr(gProgName, "root"))
1885  // if we have these modules we're probably building the root doc
1886  fProductName = "ROOT";
1887 
1888  if (fProductName == "(UNKNOWN PRODUCT)") {
1889  Warning("CreateListOfClasses", "Product not set. You should call gHtml->SetProduct(\"MyProductName\");");
1890  } else if (fProductName != "ROOT") {
1891  if (GetViewCVS().Contains("http://root.cern.ch/"))
1892  SetViewCVS("");
1893  }
1894 
1895  if (fDocEntityInfo.fModules.GetEntries() == 1
1896  && fDocEntityInfo.fModules.At(0)->GetName()
1897  && !strcmp(fDocEntityInfo.fModules.At(0)->GetName(), "(UNKNOWN)"))
1898  // Only one module, and its name is not known.
1899  // Let's call it "MAIN":
1900  ((TModuleDocInfo*) fDocEntityInfo.fModules.At(0))->SetName("MAIN");
1901 
1902  Info("CreateListOfClasses", "Initializing - DONE.");
1903 }
1904 
1905 
1906 ////////////////////////////////////////////////////////////////////////////////
1907 /// Create index of all data types and a page for each typedef-to-class
1908 
1910 {
1911  TDocOutput output(*this);
1912  output.CreateTypeIndex();
1913  output.CreateClassTypeDefs();
1914 }
1915 
1916 ////////////////////////////////////////////////////////////////////////////////
1917 /// Copy a file from $ROOTSYS/etc/html into GetOutputDir()
1918 
1919 Bool_t THtml::CopyFileFromEtcDir(const char* filename) const {
1920  R__LOCKGUARD(GetMakeClassMutex());
1921 
1922  TString outFile(filename);
1923 
1924  TString inFile(outFile);
1925  gSystem->PrependPathName(GetEtcDir(), inFile);
1926 
1927  gSystem->PrependPathName(GetOutputDir(), outFile);
1928 
1929  if (gSystem->CopyFile(inFile, outFile, kTRUE) != 0) {
1930  Warning("CopyFileFromEtcDir", "Could not copy %s to %s", inFile.Data(), outFile.Data());
1931  return kFALSE;
1932  }
1933 
1934  return kTRUE;
1935 }
1936 
1937 ////////////////////////////////////////////////////////////////////////////////
1938 /// Create the inheritance hierarchy diagram for all classes
1939 
1941 {
1942  TDocOutput output(*this);
1943  output.CreateHierarchy();
1944 }
1945 
1946 ////////////////////////////////////////////////////////////////////////////////
1947 /// Write the default ROOT style sheet.
1948 
1950  CopyFileFromEtcDir("ROOT.js");
1951 }
1952 
1953 ////////////////////////////////////////////////////////////////////////////////
1954 /// Write the default ROOT style sheet.
1955 
1957  CopyFileFromEtcDir("ROOT.css");
1958  CopyFileFromEtcDir("shadowAlpha.png");
1959  CopyFileFromEtcDir("shadow.gif");
1960 }
1961 
1962 
1963 
1964 ////////////////////////////////////////////////////////////////////////////////
1965 /// fill derived with all classes inheriting from cl and their inheritance
1966 /// distance to cl
1967 
1968 void THtml::GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived) const
1969 {
1970  TIter iClass(&fDocEntityInfo.fClasses);
1971  TClassDocInfo* cdi = 0;
1972  while ((cdi = (TClassDocInfo*) iClass())) {
1973  TClass* candidate = dynamic_cast<TClass*>(cdi->GetClass());
1974  if (!candidate) continue;
1975  if (candidate != cl && candidate->InheritsFrom(cl)) {
1976  Int_t level = 0;
1977  TClass* currentBaseOfCandidate = candidate;
1978  while (currentBaseOfCandidate != cl) {
1979  TList* bases = currentBaseOfCandidate->GetListOfBases();
1980  if (!bases) continue;
1981  TIter iBase(bases);
1982  TBaseClass* base = 0;
1983  while ((base = (TBaseClass*) iBase())) {
1984  TClass* clBase = base->GetClassPointer();
1985  if (clBase && clBase->InheritsFrom(cl)) {
1986  ++level;
1987  currentBaseOfCandidate = clBase;
1988  }
1989  }
1990  }
1991  derived[candidate] = level;
1992  }
1993  }
1994 }
1995 
1996 ////////////////////////////////////////////////////////////////////////////////
1997 /// Return real HTML filename
1998 ///
1999 ///
2000 /// Input: classPtr - pointer to a class
2001 /// filename - string containing a full name
2002 /// of the corresponding HTML file after the function returns.
2003 ///
2004 
2005 void THtml::GetHtmlFileName(TClass * classPtr, TString& filename) const
2006 {
2007  filename.Remove(0);
2008  if (!classPtr) return;
2009 
2010  TString cFilename;
2011  if (!GetImplFileName(classPtr, kFALSE, cFilename))
2012  GetDeclFileName(classPtr, kFALSE, cFilename);
2013 
2014  // classes without Impl/DeclFileName don't have docs,
2015  // and classes without docs don't have output file names
2016  if (!cFilename.Length())
2017  return;
2018 
2019  TString libName;
2020  const char *colon = strchr(cFilename, ':');
2021  if (colon)
2022  // old version, where source file name is prepended by "TAG:"
2023  libName = TString(cFilename, colon - cFilename);
2024  else
2025  // New version, check class's libname.
2026  // If libname is dir/libMyLib.so, check Root.Html.MyLib
2027  // If libname is myOtherLib.so.2.3, check Root.Html.myOtherLib
2028  // (i.e. remove directories, "lib" prefix, and any "extension")
2029  if (classPtr->GetSharedLibs()) {
2030  // first one is the class's lib
2031  TString libname(classPtr->GetSharedLibs());
2032  Ssiz_t posSpace = libname.First(' ');
2033  if (posSpace != kNPOS)
2034  libname.Remove(posSpace, libname.Length());
2035  TString libnameBase = gSystem->BaseName(libname);
2036  if (libnameBase.BeginsWith("lib"))
2037  libnameBase.Remove(0, 3);
2038  Ssiz_t posExt = libnameBase.First('.');
2039  if (posExt != '.')
2040  libnameBase.Remove(posExt, libnameBase.Length());
2041  if (libnameBase.Length())
2042  libName = libnameBase;
2043  }
2044 
2045  filename = cFilename;
2046  TString htmlFileName;
2047  if (!filename.Length() ||
2048  !gSystem->FindFile(fPathInfo.fInputPath, filename, kReadPermission)) {
2049  htmlFileName = GetURL(libName);
2050  } else
2051  htmlFileName = "./";
2052 
2053  if (htmlFileName.Length()) {
2054  filename = htmlFileName;
2055  TString className(classPtr->GetName());
2056  TDocOutput output(*const_cast<THtml*>(this));
2057  output.NameSpace2FileName(className);
2058  gSystem->PrependPathName(filename, className);
2059  filename = className;
2060  filename.ReplaceAll("\\", "/");
2061  filename += ".html";
2062  } else filename.Remove(0);
2063 }
2064 
2065 ////////////////////////////////////////////////////////////////////////////////
2066 /// Get the html file name for a class named classname.
2067 /// Returns 0 if the class is not documented.
2068 
2069 const char* THtml::GetHtmlFileName(const char* classname) const
2070 {
2071  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(classname);
2072  if (cdi)
2073  return cdi->GetHtmlFileName();
2074  return 0;
2075 }
2076 
2077 ////////////////////////////////////////////////////////////////////////////////
2078 ///*-*-*-*-*Return pointer to class with name*-*-*-*-*-*-*-*-*-*-*-*-*
2079 ///*-* =================================
2080 
2081 TClass *THtml::GetClass(const char *name1) const
2082 {
2083  if(!name1 || !name1[0]) return 0;
2084  // no doc for internal classes
2085  if (strstr(name1,"ROOT::")==name1) {
2086  Bool_t ret = kTRUE;
2087  if (!strncmp(name1 + 6,"Math", 4)) ret = kFALSE;
2088  if (!strncmp(name1 + 6,"Reflex", 6)) ret = kFALSE;
2089  if (!strncmp(name1 + 6,"Cintex", 6)) ret = kFALSE;
2090  if (ret) return 0;
2091  }
2092 
2093  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(name1);
2094  if (!cdi) return 0;
2095  TClass *cl = dynamic_cast<TClass*>(cdi->GetClass());
2096  // hack to get rid of prec_stl types
2097  // TClassEdit checks are far too slow...
2098  /*
2099  if (cl && GetDeclFileName(cl) &&
2100  (strstr(GetDeclFileName(cl),"prec_stl/") || !strstr(classPtr->GetDeclFileName(), "include/c++/") )
2101  cl = 0;
2102  */
2103  TString declFileName;
2104  if (cl && GetDeclFileName(cl, kFALSE, declFileName))
2105  return cl;
2106  return 0;
2107 }
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// Return declaration file name; return the full path if filesys is true.
2111 
2112 bool THtml::GetDeclFileName(TClass * cl, Bool_t filesys, TString& out_name) const
2113 {
2114  return GetDeclImplFileName(cl, filesys, true, out_name);
2115 }
2116 
2117 ////////////////////////////////////////////////////////////////////////////////
2118 /// Return implementation file name
2119 
2120 bool THtml::GetImplFileName(TClass * cl, Bool_t filesys, TString& out_name) const
2121 {
2122  return GetDeclImplFileName(cl, filesys, false, out_name);
2123 }
2124 
2125 ////////////////////////////////////////////////////////////////////////////////
2126 /// Combined implementation for GetDeclFileName(), GetImplFileName():
2127 /// Return declaration / implementation file name (depending on decl);
2128 /// return the full path if filesys is true.
2129 
2130 bool THtml::GetDeclImplFileName(TClass * cl, bool filesys, bool decl, TString& out_name) const
2131 {
2132  out_name = "";
2133 
2134  R__LOCKGUARD(GetMakeClassMutex());
2135  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2136  // whether we need to determine the fil name
2137  bool determine = (!cdi); // no cdi
2138  if (!determine) determine |= decl && filesys && !cdi->GetDeclFileSysName()[0];
2139  if (!determine) determine |= decl && !filesys && !cdi->GetDeclFileName()[0];
2140  if (!determine) determine |= !decl && filesys && !cdi->GetImplFileSysName()[0];
2141  if (!determine) determine |= !decl && !filesys && !cdi->GetImplFileName()[0];
2142  if (determine) {
2143  TString name;
2144  TString sysname;
2145  if (decl) {
2146  if (!GetFileDefinition().GetDeclFileName(cl, name, sysname))
2147  return false;
2148  } else {
2149  if (!GetFileDefinition().GetImplFileName(cl, name, sysname))
2150  return false;
2151  }
2152  if (cdi) {
2153  if (decl) {
2154  if (!cdi->GetDeclFileName() || !cdi->GetDeclFileName()[0])
2155  cdi->SetDeclFileName(name);
2156  if (!cdi->GetDeclFileSysName() || !cdi->GetDeclFileSysName()[0])
2157  cdi->SetDeclFileSysName(sysname);
2158  } else {
2159  if (!cdi->GetImplFileName() || !cdi->GetImplFileName()[0])
2160  cdi->SetImplFileName(name);
2161  if (!cdi->GetImplFileSysName() || !cdi->GetImplFileSysName()[0])
2162  cdi->SetImplFileSysName(sysname);
2163  }
2164  }
2165 
2166  if (filesys) out_name = sysname;
2167  else out_name = name;
2168  return true;
2169  }
2170  if (filesys) {
2171  if (decl) out_name = cdi->GetDeclFileSysName();
2172  else out_name = cdi->GetImplFileSysName();
2173  } else {
2174  if (decl) out_name = cdi->GetDeclFileName();
2175  else out_name = cdi->GetImplFileName();
2176  }
2177  return true;
2178 }
2179 
2180 ////////////////////////////////////////////////////////////////////////////////
2181 /// Return the output directory as set by SetOutputDir().
2182 /// Create it if it doesn't exist and if createDir is kTRUE.
2183 
2184 const TString& THtml::GetOutputDir(Bool_t createDir /*= kTRUE*/) const
2185 {
2186  if (createDir) {
2187  R__LOCKGUARD(GetMakeClassMutex());
2188 
2189  gSystem->ExpandPathName(const_cast<THtml*>(this)->fPathInfo.fOutputDir);
2190  Long64_t sSize;
2191  Long_t sId, sFlags, sModtime;
2192  if (fPathInfo.fOutputDir.EndsWith("/") || fPathInfo.fOutputDir.EndsWith("\\"))
2193  fPathInfo.fOutputDir.Remove(fPathInfo.fOutputDir.Length() - 1);
2194  Int_t st = gSystem->GetPathInfo(fPathInfo.fOutputDir, &sId, &sSize, &sFlags, &sModtime);
2195  if (st || !(sFlags & 2)) {
2196  if (st == 0)
2197  Error("GetOutputDir", "output directory %s is an existing file",
2198  fPathInfo.fOutputDir.Data());
2199  else if (gSystem->MakeDirectory(fPathInfo.fOutputDir) == -1)
2200  Error("GetOutputDir", "output directory %s does not exist and can't create it", fPathInfo.fOutputDir.Data());
2201  }
2202  }
2203  return fPathInfo.fOutputDir;
2204 }
2205 
2206 ////////////////////////////////////////////////////////////////////////////////
2207 /// Check whether cl is a namespace
2208 
2210 {
2211  return (cl->Property() & kIsNamespace);
2212 }
2213 
2214 ////////////////////////////////////////////////////////////////////////////////
2215 /// Load all libraries known to ROOT via the rootmap system.
2216 
2218 {
2219  TEnv* mapfile = gInterpreter->GetMapfile();
2220  if (!mapfile || !mapfile->GetTable()) return;
2221 
2222  std::set<std::string> loadedlibs;
2223  std::set<std::string> failedlibs;
2224 
2225  TEnvRec* rec = 0;
2226  TIter iEnvRec(mapfile->GetTable());
2227  while ((rec = (TEnvRec*) iEnvRec())) {
2228  TString libs = rec->GetValue();
2229  TString lib;
2230  Ssiz_t pos = 0;
2231  while (libs.Tokenize(lib, pos)) {
2232  // check that none of the libs failed to load
2233  if (failedlibs.find(lib.Data()) != failedlibs.end()) {
2234  // don't load it or any of its dependencies
2235  libs = "";
2236  break;
2237  }
2238  }
2239  pos = 0;
2240  while (libs.Tokenize(lib, pos)) {
2241  // ignore libCore - it's already loaded
2242  if (lib.BeginsWith("libCore"))
2243  continue;
2244 
2245  if (loadedlibs.find(lib.Data()) == loadedlibs.end()) {
2246  // just load the first library - TSystem will do the rest.
2247  gSystem->Load(lib);
2248  loadedlibs.insert(lib.Data());
2249  }
2250  }
2251  }
2252 }
2253 
2254 
2255 ////////////////////////////////////////////////////////////////////////////////
2256 /// Produce documentation for all the classes specified in the filter (by default "*")
2257 /// To process all classes having a name starting with XX, do:
2258 /// html.MakeAll(kFALSE,"XX*");
2259 /// If force=kFALSE (default), only the classes that have been modified since
2260 /// the previous call to this function will be generated.
2261 /// If force=kTRUE, all classes passing the filter will be processed.
2262 /// If numthreads is != -1, use numthreads threads, else decide automatically
2263 /// based on the number of CPUs.
2264 
2265 void THtml::MakeAll(Bool_t force, const char *filter, int numthreads /*= -1*/)
2266 {
2267  MakeIndex(filter);
2268 
2269  if (numthreads == 1) {
2270  // CreateListOfClasses(filter); already done by MakeIndex
2271  TClassDocInfo* classinfo = 0;
2272  TIter iClassInfo(&fDocEntityInfo.fClasses);
2273  UInt_t count = 0;
2274 
2275  while ((classinfo = (TClassDocInfo*)iClassInfo())) {
2276  if (!classinfo->IsSelected())
2277  continue;
2278  fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - count++);
2279  MakeClass(classinfo, force);
2280  }
2281  } else {
2282  if (numthreads == -1) {
2283  SysInfo_t sysinfo;
2284  gSystem->GetSysInfo(&sysinfo);
2285  numthreads = sysinfo.fCpus;
2286  if (numthreads < 1)
2287  numthreads = 2;
2288  }
2289  fThreadedClassCount = 0;
2290  fThreadedClassIter = new TIter(&fDocEntityInfo.fClasses);
2291  THtmlThreadInfo hti(this, force);
2292  if (!fMakeClassMutex && gGlobalMutex) {
2293  gGlobalMutex->Lock();
2294  fMakeClassMutex = gGlobalMutex->Factory(kTRUE);
2295  gGlobalMutex->UnLock();
2296  }
2297 
2298  TList threads;
2299  gSystem->Load("libThread");
2300  while (--numthreads >= 0) {
2301  TThread* thread = new TThread(MakeClassThreaded, &hti);
2302  thread->Run();
2303  threads.Add(thread);
2304  }
2305 
2306  TIter iThread(&threads);
2307  TThread* thread = 0;
2308  Bool_t wait = kTRUE;
2309  while (wait) {
2310  while (wait && (thread = (TThread*) iThread()))
2311  wait &= (thread->GetState() == TThread::kRunningState);
2313  gSystem->Sleep(500);
2314  }
2315 
2316  iThread.Reset();
2317  while ((thread = (TThread*) iThread()))
2318  thread->Join();
2319  }
2320  fCounter.Remove(0);
2321 }
2322 
2323 
2324 ////////////////////////////////////////////////////////////////////////////////
2325 /// Make HTML files for a single class
2326 ///
2327 ///
2328 /// Input: className - name of the class to process
2329 ///
2330 
2331 void THtml::MakeClass(const char *className, Bool_t force)
2332 {
2333  CreateListOfClasses("*");
2334 
2335  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(className);
2336  if (!cdi) {
2337  if (!TClassEdit::IsStdClass(className)) // stl classes won't be available, so no warning
2338  Error("MakeClass", "Unknown class '%s'!", className);
2339  return;
2340  }
2341 
2342  MakeClass(cdi, force);
2343 }
2344 
2345 ////////////////////////////////////////////////////////////////////////////////
2346 /// Make HTML files for a single class
2347 ///
2348 ///
2349 /// Input: cdi - doc info for class to process
2350 ///
2351 
2352 void THtml::MakeClass(void *cdi_void, Bool_t force)
2353 {
2354  if (!fDocEntityInfo.fClasses.GetSize())
2355  CreateListOfClasses("*");
2356 
2357  TClassDocInfo* cdi = (TClassDocInfo*) cdi_void;
2358  TClass* currentClass = dynamic_cast<TClass*>(cdi->GetClass());
2359 
2360  if (!currentClass) {
2361  if (!cdi->GetClass() &&
2362  !TClassEdit::IsStdClass(cdi->GetName())) // stl classes won't be available, so no warning
2363  Error("MakeClass", "Class '%s' is known, but I cannot find its TClass object!", cdi->GetName());
2364  return;
2365  }
2366  TString htmlFile(cdi->GetHtmlFileName());
2367  if (htmlFile.Length()
2368  && (htmlFile.BeginsWith("http://")
2369  || htmlFile.BeginsWith("https://")
2370  || gSystem->IsAbsoluteFileName(htmlFile))
2371  ) {
2372  htmlFile.Remove(0);
2373  }
2374  if (htmlFile.Length()) {
2375  TClassDocOutput cdo(*this, currentClass, &cdi->GetListOfTypedefs());
2376  cdo.Class2Html(force);
2377  cdo.MakeTree(force);
2378  } else {
2379  TString what(cdi->GetName());
2380  what += " (sources not found)";
2381  Printf(fCounterFormat.Data(), "-skipped-", fCounter.Data(), what.Data());
2382  }
2383 }
2384 
2385 
2386 ////////////////////////////////////////////////////////////////////////////////
2387 /// Entry point of worker threads for multi-threaded MakeAll().
2388 /// info points to an (internal) THtmlThreadInfo object containing the current
2389 /// THtml object, and whether "force" was passed to MakeAll().
2390 /// The thread will poll GetNextClass() until no further class is available.
2391 
2392 void* THtml::MakeClassThreaded(void* info) {
2393  const THtmlThreadInfo* hti = (const THtmlThreadInfo*)info;
2394  if (!hti) return 0;
2395  TClassDocInfo* classinfo = 0;
2396  while ((classinfo = hti->GetHtml()->GetNextClass()))
2397  hti->GetHtml()->MakeClass(classinfo, hti->GetForce());
2398 
2399  return 0;
2400 }
2401 
2402 ////////////////////////////////////////////////////////////////////////////////
2403 /// Create the index files for the product, modules, all types, etc.
2404 /// By default all classes are indexed (if filter="*");
2405 /// to generate an index for all classes starting with "XX", do
2406 /// html.MakeIndex("XX*");
2407 
2408 void THtml::MakeIndex(const char *filter)
2409 {
2410  CreateListOfClasses(filter);
2411 
2412  TDocOutput output(*this);
2413  // create indices
2414  output.CreateTypeIndex();
2415  output.CreateClassTypeDefs();
2416  output.CreateModuleIndex();
2417  output.CreateClassIndex();
2418  output.CreateProductIndex();
2419 
2420  // create a class hierarchy
2421  output.CreateHierarchy();
2422 }
2423 
2424 
2425 ////////////////////////////////////////////////////////////////////////////////
2426 /// Make an inheritance tree
2427 ///
2428 ///
2429 /// Input: className - name of the class to process
2430 ///
2431 
2432 void THtml::MakeTree(const char *className, Bool_t force)
2433 {
2434  // create canvas & set fill color
2435  TClass *classPtr = GetClass(className);
2436 
2437  if (!classPtr) {
2438  Error("MakeTree", "Unknown class '%s' !", className);
2439  return;
2440  }
2441 
2442  TClassDocOutput cdo(*this, classPtr, 0);
2443  cdo.MakeTree(force);
2444 }
2445 
2446 ////////////////////////////////////////////////////////////////////////////////
2447 /// Set whether "dot" (a GraphViz utility) is available
2448 
2450  if (found) fPathInfo.fFoundDot = PathInfo_t::kDotFound;
2451  else fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
2452 }
2453 
2454 ////////////////////////////////////////////////////////////////////////////////
2455 /// Fill the files available in the file system below fPathInfo.fInputPath
2456 
2458 {
2459  if (fLocalFiles) delete fLocalFiles;
2460  fLocalFiles = new TFileSysDB(fPathInfo.fInputPath, fPathInfo.fIgnorePath + "|(\\b" + GetOutputDir(kFALSE) + "\\b)" , 6);
2461 }
2462 
2463 ////////////////////////////////////////////////////////////////////////////////
2464 /// Set the module defining object to be used; can also be a user derived
2465 /// object (a la traits).
2466 
2468 {
2469  delete fModuleDef;
2470  fModuleDef = (TModuleDefinition*) md.Clone();
2471  fModuleDef->SetOwner(const_cast<THtml*>(this));
2472 }
2473 
2474 
2475 ////////////////////////////////////////////////////////////////////////////////
2476 /// Set the file defining object to be used; can also be a user derived
2477 /// object (a la traits).
2478 
2480 {
2481  delete fFileDef;
2482  fFileDef = (TFileDefinition*) md.Clone();
2483  fFileDef->SetOwner(const_cast<THtml*>(this));
2484 }
2485 
2486 
2487 ////////////////////////////////////////////////////////////////////////////////
2488 /// Set the path defining object to be used; can also be a user derived
2489 /// object (a la traits).
2490 
2492 {
2493  delete fPathDef;
2494  fPathDef = (TPathDefinition*) md.Clone();
2495  fPathDef->SetOwner(const_cast<THtml*>(this));
2496 }
2497 
2498 
2499 ////////////////////////////////////////////////////////////////////////////////
2500 /// Set the directory containing the source files.
2501 /// The source file for a class MyClass will be searched
2502 /// by prepending dir to the value of
2503 /// MyClass::Class()->GetImplFileName() - which can contain
2504 /// directory information!
2505 /// Also resets the class structure, in case new files can
2506 /// be found after this call.
2507 
2508 void THtml::SetInputDir(const char *dir)
2509 {
2510  fPathInfo.fInputPath = dir;
2511  gSystem->ExpandPathName(fPathInfo.fInputPath);
2512 
2513  // reset class table
2514  fDocEntityInfo.fClasses.Clear();
2515  fDocEntityInfo.fModules.Clear();
2516 }
2517 
2518 ////////////////////////////////////////////////////////////////////////////////
2519 /// Set the directory where the HTML pages shuold be written to.
2520 /// If the directory does not exist it will be created when needed.
2521 
2522 void THtml::SetOutputDir(const char *dir)
2523 {
2524  fPathInfo.fOutputDir = dir;
2525 #ifdef R__WIN32
2526  fPathInfo.fOutputDir.ReplaceAll("/","\\");
2527 #endif
2528 }
2529 
2530 ////////////////////////////////////////////////////////////////////////////////
2531 /// Explicitly set a decl file name for TClass cl.
2532 
2533 void THtml::SetDeclFileName(TClass* cl, const char* filename)
2534 {
2535  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2536  if (!cdi) {
2537  cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, filename);
2538  fDocEntityInfo.fClasses.Add(cdi);
2539  } else
2540  cdi->SetDeclFileName(filename);
2541 }
2542 
2543 ////////////////////////////////////////////////////////////////////////////////
2544 /// Explicitly set a impl file name for TClass cl.
2545 
2546 void THtml::SetImplFileName(TClass* cl, const char* filename)
2547 {
2548  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2549  if (!cdi) {
2550  cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, 0 /*decl*/, filename);
2551  fDocEntityInfo.fClasses.Add(cdi);
2552  } else
2553  cdi->SetImplFileName(filename);
2554 }
2555 
2556 ////////////////////////////////////////////////////////////////////////////////
2557 /// Get short type name, i.e. with default templates removed.
2558 
2559 const char* THtml::ShortType(const char* name) const
2560 {
2561  const char* tmplt = strchr(name, '<');
2562  if (!tmplt) return name;
2563  tmplt = strrchr(tmplt, ':');
2564  if (tmplt > name && tmplt[-1] == ':') {
2565  // work-around for CINT bug: template instantiation can produce bogus
2566  // typedefs e.g. in namespace ROOT::Math::ROOT::Math instead of ROOT::Math.
2567  TString namesp(name, tmplt - name - 1);
2568  // is the enclosing namespace known?
2569  if (!GetClass(namesp)) return name;
2570  }
2571  TObject* scn = fDocEntityInfo.fShortClassNames.FindObject(name);
2572  if (!scn) {
2573  scn = new TNamed(name, TClassEdit::ShortType(name, 1<<7));
2574  fDocEntityInfo.fShortClassNames.Add(scn);
2575  }
2576  return scn->GetTitle();
2577 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:929
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
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:1266
static Bool_t IsNamespace(const TClass *cl)
Check whether cl is a namespace.
Definition: THtml.cxx:2209
void MakeIndex(const char *filter="*")
Create the index files for the product, modules, all types, etc.
Definition: THtml.cxx:2408
virtual bool GetDocDir(const TString &module, TString &doc_dir) const
Determine the module&#39;s documentation directory.
Definition: THtml.cxx:541
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:87
void SetSelected(Bool_t sel=kTRUE)
Definition: TDocInfo.h:119
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:946
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3460
static void * MakeClassThreaded(void *info)
Entry point of worker threads for multi-threaded MakeAll().
Definition: THtml.cxx:2392
An array of TObjects.
Definition: TObjArray.h:39
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:421
virtual TVirtualMutex * Factory(Bool_t=kFALSE)=0
virtual bool GetImplFileName(TClass *cl, Bool_t filesys, TString &out_name) const
Return implementation file name.
Definition: THtml.cxx:2120
virtual void CreateProductIndex()
Fetch documentation from THtml::GetProductDocDir() and put it into the product index page...
Bool_t HaveDot()
Check whether dot is available in $PATH or in the directory set by SetDotPath()
Definition: THtml.cxx:1414
long long Long64_t
Definition: RtypesCore.h:69
virtual void CreateTypeIndex()
Create index of all data types.
const TString & GetInputPath() const
Definition: THtml.h:294
const char * GetDeclFileName() const
Definition: TClass.h:386
const TFileDefinition & GetFileDefinition() const
Return the TFileDefinition (or derived) object as set by SetFileDefinition(); create and return a TFi...
Definition: THtml.cxx:1317
llvm::StringRef GetFileName(const clang::Decl &decl, const cling::Interpreter &interp)
Return the header file to be included to declare the Decl.
virtual Int_t UnLock()=0
Bool_t IsNamespace(TCppScope_t scope)
Definition: Cppyy.cxx:534
const char * GetImplFileName() const
Definition: TClass.h:408
virtual void CreateJavascript() const
Write the default ROOT style sheet.
Definition: THtml.cxx:1949
Collectable string class.
Definition: TObjString.h:32
R__EXTERN TClassTable * gClassTable
Definition: TClassTable.h:97
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
EState GetState() const
Definition: TThread.h:136
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:63
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:1364
virtual bool GetImplFileName(const TClass *cl, TString &out_filename, TString &out_fsys, TFileSysEntry **fse=0) const
Determine cl&#39;s implementation file name.
Definition: THtml.cxx:278
static const char * GetDirDelimiter()
Definition: THtml.h:326
void AddClass(TClassDocInfo *cl)
Definition: TDocInfo.h:122
virtual bool GetFileName(const TClass *cl, bool decl, TString &out_filename, TString &out_fsys, TFileSysEntry **fse=0) const
Common implementation for GetDeclFileName(), GetImplFileName()
Definition: THtml.cxx:337
virtual Int_t GetEntries() const
Definition: TCollection.h:92
const char * GetImplFileSysName() const
Definition: TDocInfo.h:65
Int_t GetMaxLevel() const
Definition: THtml.h:182
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:822
void SetOwner(THtml *html)
Set the THtml object owning this object; if it&#39;s already set to a different THtml object than issue a...
Definition: THtml.cxx:73
static void LoadAllLibs()
Load all libraries known to ROOT via the rootmap system.
Definition: THtml.cxx:2217
#define gROOT
Definition: TROOT.h:364
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
const char * GetSharedLibs()
Get the list of shared libraries containing the code for class cls.
Definition: TClass.cxx:3447
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1819
void SplitClassIntoDirFile(const TString &clname, TString &dir, TString &filename) const
Given a class name with a scope, split the class name into directory part and file name: A::B::C beco...
Definition: THtml.cxx:233
virtual ~THtml()
Default destructor.
Definition: THtml.cxx:1255
The TEnv class reads config files, by default named .rootrc.
Definition: TEnv.h:128
Basic string class.
Definition: TString.h:137
const char * GetValue() const
Definition: TEnv.h:114
virtual void CreateModuleIndex()
Create the class index for each module, picking up documentation from the module&#39;s TModuleDocInfo::Ge...
Definition: TDocOutput.cxx:801
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1089
TString & GetMacroPath()
Definition: TROOT.cxx:491
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:997
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Substitute replaces the string s by a new string in which matching patterns are replaced by the repla...
Definition: TPRegexp.cxx:469
Bool_t IsSelected() const
Definition: TDocInfo.h:71
virtual const char * GetSoExt() const
Get the shared library extension.
Definition: TSystem.cxx:3875
#define gInterpreter
Definition: TInterpreter.h:517
const TString & GetIgnore() const
Definition: THtml.h:181
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1512
virtual bool GetDeclImplFileName(TClass *cl, bool filesys, bool decl, TString &out_name) const
Combined implementation for GetDeclFileName(), GetImplFileName(): Return declaration / implementation...
Definition: THtml.cxx:2130
void MakeAll(Bool_t force=kFALSE, const char *filter="*", int numthreads=1)
Produce documentation for all the classes specified in the filter (by default "*") To process all cla...
Definition: THtml.cxx:2265
void MakeTree(const char *className, Bool_t force=kFALSE)
Make an inheritance tree.
Definition: THtml.cxx:2432
virtual void GetFullName(TString &fullname, Bool_t asIncluded) const
Definition: THtml.h:116
void SetDeclFileName(TClass *cl, const char *filename)
Explicitly set a decl file name for TClass cl.
Definition: THtml.cxx:2533
void SetOutputDir(const char *dir)
Set the directory where the HTML pages shuold be written to.
Definition: THtml.cxx:2522
void Reset()
Definition: TCollection.h:161
void GetDerivedClasses(TClass *cl, std::map< TClass *, Int_t > &derived) const
fill derived with all classes inheriting from cl and their inheritance distance to cl ...
Definition: THtml.cxx:1968
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:137
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1502
virtual void CreateStyleSheet() const
Write the default ROOT style sheet.
Definition: THtml.cxx:1956
void MakeTree(Bool_t force=kFALSE)
Create an output file with a graphical representation of the class inheritance.
Int_t fMode
Definition: TSystem.h:138
virtual void Sort(Bool_t order=kSortAscending)
Sort linked list.
Definition: TList.cxx:771
const char * String
Definition: TXMLSetup.cxx:94
static void Init()
void SetImplFileName(TClass *cl, const char *filename)
Explicitly set a impl file name for TClass cl.
Definition: THtml.cxx:2546
void MakeClass(const char *className, Bool_t force=kFALSE)
Make HTML files for a single class.
Definition: THtml.cxx:2331
TClass * GetClass(T *)
Definition: TClass.h:555
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:848
TExMap & GetMapIno()
Definition: THtml.h:179
Bool_t HaveSource() const
Definition: TDocInfo.h:72
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:2335
virtual int GetSysInfo(SysInfo_t *info) const
Returns static system info, like OS type, CPU type, number of CPUs RAM size, etc into the SysInfo_t s...
Definition: TSystem.cxx:2440
virtual const char * GetEtcDir() const
Get the directory containing THtml&#39;s auxiliary files ($ROOTSYS/etc/html)
Definition: THtml.cxx:1344
virtual void CreateAuxiliaryFiles() const
copy CSS, javascript file, etc to the output dir
Definition: THtml.cxx:1291
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:442
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
virtual void CreateHierarchy()
Create a hierarchical class list The algorithm descends from the base classes and branches into all d...
Definition: TDocOutput.cxx:640
TString MatchFileSysName(TString &filename, TFileSysEntry **fse=0) const
Find filename in the list of system files; return the system file name and change filename to the fil...
Definition: THtml.cxx:307
void CreateListOfClasses(const char *filter)
Create the list of all known classes.
Definition: THtml.cxx:1556
TFileSysDir * GetParent() const
Definition: THtml.h:126
virtual Int_t Lock()=0
const char * GetImplFileName() const
Definition: TDocInfo.h:63
void Info(const char *location, const char *msgfmt,...)
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1055
std::vector< std::vector< double > > Data
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2221
ClassInfo_t * GetClassInfo() const
Definition: TClass.h:391
virtual bool GetFileNameFromInclude(const char *included, TString &out_fsname) const
Set out_fsname to the full pathname corresponding to a file included as "included".
Definition: THtml.cxx:620
void SetLocalFiles() const
Fill the files available in the file system below fPathInfo.fInputPath.
Definition: THtml.cxx:2457
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:467
void HelperDeleted(THelperBase *who)
Inform the THtml object that one of its helper objects was deleted.
Definition: THtml.cxx:1441
Int_t Run(void *arg=0)
Start the thread.
Definition: TThread.cxx:552
virtual void GetModuleNameForClass(TString &module, TClass *cl) const
Return the module name for a given class.
Definition: THtml.cxx:1541
void Error(const char *location, const char *msgfmt,...)
TDictionary * GetClass() const
Definition: TDocInfo.h:59
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
THashTable & GetEntries()
Definition: THtml.h:180
R__EXTERN TVirtualMutex * gGlobalMutex
Definition: TVirtualMutex.h:29
void NormalizePath(TString &path) const
Remove "/./" and collapse "/subdir/../" to "/".
Definition: THtml.cxx:288
R__EXTERN const char * gProgName
Definition: TSystem.h:234
TList & GetListOfTypedefs()
Definition: TDocInfo.h:83
Definition: TEnv.h:91
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 TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:380
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
Int_t fCpus
Definition: TSystem.h:165
virtual const char * GetName() const
Returns name of object.
Definition: TDocInfo.cxx:26
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
THashList * GetTable() const
Definition: TEnv.h:144
virtual void NameSpace2FileName(TString &name)
Replace "::" in name by "__" Replace "<", ">", " ", ",", "~", "=" in name by "_" Replace "A::X<A::Y>"...
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:496
const TModuleDefinition & GetModuleDefinition() const
Return the TModuleDefinition (or derived) object as set by SetModuleDefinition(); create and return a...
Definition: THtml.cxx:1303
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
TModuleDocInfo * GetModule() const
Definition: TDocInfo.h:68
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void CreateClassTypeDefs()
Create a forwarding page for each typedef pointing to a class.
Ssiz_t Length() const
Definition: TString.h:390
const char * ShortType(const char *name) const
Get short type name, i.e. with default templates removed.
Definition: THtml.cxx:2559
const char * GetURL(const char *lib=0) const
Get the documentation URL for library lib.
Definition: THtml.cxx:1398
const TString & GetOutputDir(Bool_t createDir=kTRUE) const
Return the output directory as set by SetOutputDir().
Definition: THtml.cxx:2184
void ExpandSearchPath(TString &path) const
Create all permutations of path and THtml&#39;s input path: path being PP/ and THtml&#39;s input being ...
Definition: THtml.cxx:205
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
Long_t Join(void **ret=0)
Join this thread.
Definition: TThread.cxx:499
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:658
void Convert(const char *filename, const char *title, const char *dirname="", const char *relpath="../", Int_t includeOutput=kNoOutput, const char *context="")
It converts a single text file to HTML.
Definition: THtml.cxx:1473
virtual bool GetModule(TClass *cl, TFileSysEntry *fse, TString &out_modulename) const
Set out_modulename to cl&#39;s module name; return true if it&#39;s valid.
Definition: THtml.cxx:103
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4610
void Warning(const char *location, const char *msgfmt,...)
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:2112
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5683
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
void SetFileDefinition(const TFileDefinition &fd)
Set the file defining object to be used; can also be a user derived object (a la traits).
Definition: THtml.cxx:2479
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:840
Each class (see TClass) has a linked list of its base class(es).
Definition: TBaseClass.h:35
void SetImplFileName(const char *name)
Definition: TDocInfo.h:77
#define Printf
Definition: TGeoToOCC.h:18
const char * GetHtmlFileName() const
Definition: TDocInfo.h:61
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
void Class2Html(Bool_t force=kFALSE)
Create HTML files for a single class.
void CreateListOfTypes()
Create index of all data types and a page for each typedef-to-class.
Definition: THtml.cxx:1909
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2241
virtual Bool_t IsEmpty() const
Definition: TCollection.h:99
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:311
static char * Next()
Returns next class from sorted class table.
#define ClassImp(name)
Definition: Rtypes.h:279
THtml * gHtml
Definition: THtml.cxx:38
virtual bool GetMacroPath(const TString &module, TString &out_dir) const
Determine the path to look for macros (see TDocMacroDirective) for classes from a given module...
Definition: THtml.cxx:512
void CreateHierarchy()
Create the inheritance hierarchy diagram for all classes.
Definition: THtml.cxx:1940
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:865
virtual ~THelperBase()
Helper&#39;s destructor.
Definition: THtml.cxx:60
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
unsigned long ULong_t
Definition: RtypesCore.h:51
void SetSelected(Bool_t sel=kTRUE)
Definition: TDocInfo.h:70
TList * GetClasses()
Definition: TDocInfo.h:123
void Add(TObject *obj)
Add object to the hash table.
Definition: THashTable.cxx:76
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
#define R__LOCKGUARD(mutex)
void SetImplFileSysName(const char *fsname)
Definition: TDocInfo.h:79
Bool_t CopyFileFromEtcDir(const char *filename) const
Copy a file from $ROOTSYS/etc/html into GetOutputDir()
Definition: THtml.cxx:1919
virtual void CreateClassIndex()
Create index of all classes.
Definition: TDocOutput.cxx:693
virtual void GetHtmlFileName(TClass *classPtr, TString &filename) const
Return real HTML filename.
Definition: THtml.cxx:2005
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:2893
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:349
void SetPathDefinition(const TPathDefinition &pd)
Set the path defining object to be used; can also be a user derived object (a la traits).
Definition: THtml.cxx:2491
void SetFoundDot(Bool_t found=kTRUE)
Set whether "dot" (a GraphViz utility) is available.
Definition: THtml.cxx:2449
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex &#39;this&#39; was created with.
Definition: TPRegexp.cxx:705
Mother of all ROOT objects.
Definition: TObject.h:37
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:204
virtual TClass * GetClass(const char *name) const
-*-*-*-*Return pointer to class with name-*-*-*-*-*-*-*-*-*-*-*-* *-* ===============================...
Definition: THtml.cxx:2081
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:460
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:126
void SetHtmlFileName(const char *name)
Definition: TDocInfo.h:75
void Fill()
Recursively fill entries by parsing the path specified in GetName(); can be a THtml::GetDirDelimiter(...
Definition: THtml.cxx:710
void SetInputDir(const char *dir)
Set the directory containing the source files.
Definition: THtml.cxx:2508
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
R__EXTERN const char * gRootDir
Definition: TSystem.h:233
void SetDeclFileSysName(const char *fsname)
Definition: TDocInfo.h:78
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
void Recurse(TFileSysDB *db, const char *path)
Recursively fill entries by parsing the contents of path.
Definition: THtml.cxx:660
Long_t fIno
Definition: TSystem.h:137
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1311
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:831
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
void SetModuleDefinition(const TModuleDefinition &md)
Set the module defining object to be used; can also be a user derived object (a la traits)...
Definition: THtml.cxx:2467
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1244
const char * GetName() const
Returns name of object.
Definition: THtml.h:114
const char * GetDeclFileSysName() const
Definition: TDocInfo.h:64
const char * GetDeclFileName() const
Definition: TDocInfo.h:62
const TPathDefinition & GetPathDefinition() const
Return the TModuleDefinition (or derived) object as set by SetModuleDefinition(); create and return a...
Definition: THtml.cxx:1331
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual bool GetDeclFileName(const TClass *cl, TString &out_filename, TString &out_fsys, TFileSysEntry **fse=0) const
Determine cl&#39;s declaration file name.
Definition: THtml.cxx:261
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1045
void AddMacroPath(const char *path)
Add path to the directories to be searched for macro files that are to be executed via the TDocMacroD...
Definition: THtml.cxx:1275
Definition: THtml.h:44
gr SetName("gr")
char name[80]
Definition: TGX11.cxx:109
void SetDeclFileName(const char *name)
Definition: TDocInfo.h:76
TClassDocInfo * GetNextClass()
Return the next class to be generated for MakeClassThreaded.
Definition: THtml.cxx:1372
void SetModule(TModuleDocInfo *module)
Definition: TDocInfo.h:67
const char * Data() const
Definition: TString.h:349