ROOT  6.06/08
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?
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 
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 
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 are taken
692  if (strcmp(direntry + delen - 4, ".cxx")
693  && strcmp(direntry + delen - 2, ".h"))
694  continue;
695  TFileSysEntry* entry = new TFileSysEntry(direntry, this);
696  db->GetEntries().Add(entry);
697  fFiles.Add(entry);
698  }
699  } // if !gSystem->GetPathInfo()
700  } // while dir entry
701  gSystem->FreeDirectory(hDir);
702 }
703 
704 
705 ////////////////////////////////////////////////////////////////////////////////
706 /// Recursively fill entries by parsing the path specified in GetName();
707 /// can be a THtml::GetDirDelimiter() delimited list of paths.
708 
710 {
711  TString dir;
712  Ssiz_t posPath = 0;
713  while (fName.Tokenize(dir, posPath, THtml::GetDirDelimiter())) {
714  gSystem->ExpandPathName(dir);
716  Warning("Fill", "Cannot read InputPath \"%s\"!", dir.Data());
717  continue;
718  }
719  FileStat_t buf;
720  if (!gSystem->GetPathInfo(dir, buf) && R_ISDIR(buf.fMode)) {
721 #ifndef R__WIN32
722  TFileSysRoot* prevroot = (TFileSysRoot*) (Long_t)GetMapIno().GetValue(buf.fIno);
723  if (prevroot != 0) {
724  Warning("Fill", "InputPath \"%s\" already present as \"%s\"!", dir.Data(), prevroot->GetName());
725  continue;
726  }
727 #endif
728  TFileSysRoot* root = new TFileSysRoot(dir, this);
729  fDirs.Add(root);
730 #ifndef R__WIN32
731  GetMapIno().Add(buf.fIno, (Long_t)root);
732 #endif
733  root->Recurse(this, dir);
734  } else {
735  Warning("Fill", "Cannot read InputPath \"%s\"!", dir.Data());
736  }
737  }
738 }
739 
740 
741 ////////////////////////////////////////////////////////////////////////////////
742 /* BEGIN_HTML
743 <p>The THtml class is designed to easily document
744 classes, code, and code related text files (like change logs). It generates HTML
745 pages conforming to the XHTML 1.0 transitional specifications; an example of
746 these pages is ROOT's own <a href="http://root.cern.ch/root/html/ClassIndex.html">
747 reference guide</a>. This page was verified to be valid XHTML 1.0 transitional,
748 which proves that all pages generated by THtml can be valid, as long as the user
749 provided XHTML (documentation, header, etc) is valid. You can check the current
750 THtml by clicking this icon:
751 <a href="http://validator.w3.org/check?uri=referer"><img
752  src="http://www.w3.org/Icons/valid-xhtml10"
753  alt="Valid XHTML 1.0 Transitional" height="31" width="88" style="border: none;"/></a></p>
754 Overview:
755 <ol style="list-style-type: upper-roman;">
756  <li><a href="#usage">Usage</a></li>
757  <li><a href="#conf">Configuration</a>
758  <ol><li><a href="#conf:input">Input files</a></li>
759  <li><a href="#conf:output">Output directory</a></li>
760  <li><a href="#conf:liblink">Linking other documentation</a></li>
761  <li><a href="#conf:classdoc">Recognizing class documentation</a></li>
762  <li><a href="#conf:tags">Author, copyright, etc.</a></li>
763  <li><a href="#conf:header">Header and footer</a></li>
764  <li><a href="#conf:search">Links to searches, home page, ViewVC</a></li>
765  <li><a href="#conf:charset">HTML Charset</a></li>
766  </ol></li>
767  <li><a href="#syntax">Documentation syntax</a>
768  <ol><li><a href="#syntax:classdesc">Class description</a></li>
769  <li><a href="#syntax:classidx">Class index</a></li>
770  <li><a href="#syntax:meth">Method documentation</a></li>
771  <li><a href="#syntax:datamem">Data member documentation</a></li>
772  </ol></li>
773  <li><a href="#directive">Documentation directives</a>
774  <ol><li><a href="#directive:html"><tt>BEGIN<!-- -->_HTML</tt> <tt>END<!-- -->_HTML</tt>: include 'raw' HTML</a></li>
775  <li><a href="#directive:macro"><tt>BEGIN<!-- -->_MACRO</tt> <tt>END<!-- -->_MACRO</tt>: include a picture generated by a macro</a></li>
776  <li><a href="#directive:latex"><tt>BEGIN<!-- -->_LATEX</tt> <tt>END<!-- -->_LATEX</tt>: include a latex picture</a></li>
777  </ol></li>
778  <li><a href="#index">Product and module index</a></li>
779  <li><a href="#aux">Auxiliary files: style sheet, JavaScript, help page</a></li>
780  <li><a href="#charts">Class Charts</a></li>
781  <li><a href="#confvar">Configuration variables</a></li>
782  <li><a href="#how">Behind the scenes</a></li>
783 </ol>
784 
785 
786 <h3><a name="usage">I. Usage</a></h3>
787 These are typical things people do with THtml:
788 <pre>
789  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
790  root[] html.LoadAllLibs(); // Load all rootmap'ed libraries
791  root[] html.MakeAll(); // generate documentation for all changed classes
792 </pre>
793 or to run on just a few classes:
794 <pre>
795  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
796  root[] html.MakeIndex(); // create auxiliary files (style sheet etc) and indices
797  root[] html.MakeClass("TMyClass"); // create documentation for TMyClass only
798 </pre>
799 To "beautify" (i.e. create links to documentation for class names etc) some text
800 file or macro, use:
801 <pre>
802  root[] html.Convert( "hsimple.C", "Histogram example" )
803 </pre>
804 
805 
806 <h3><a name="conf">II. Configuration</a></h3>
807 Most configuration options can be set as a call to THtml, or as a TEnv variable,
808 which you can set in your .rootrc.
809 
810 <h4><a name="conf:input">II.1 Input files</a></h4>
811 
812 <p>In your .rootrc, define Root.Html.SourceDir to point to directories containing
813 .cxx and .h files (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>)
814 of the classes you want to document, or call THtml::SetInputDir()</p>
815 
816 <p>Example:</p><pre>
817  Root.Html.SourceDir: .:src:include
818  Root.Html.Root: http://root.cern.ch/root/html</pre>
819 
820 
821 <h4><a name="conf:output">II.2 Output directory</a></h4>
822 
823 <p>The output directory can be specified using the Root.Html.OutputDir
824 configuration variable (default value: "htmldoc"). If that directory
825 doesn't exist <a href="http://root.cern.ch/root/html/THtml.html">THtml</a>
826 will create it.</p>
827 
828 <p>Example:</p><pre>
829  Root.Html.OutputDir: htmldoc</pre>
830 
831 <h4><a name="conf:liblink">II.3 Linking other documentation</a></h4>
832 
833 <p>When trying to document a class, THtml searches for a source file in
834 the directories set via SetInputDir(). If it cannot find it, it assumes
835 that this class must have been documented before. Based on the library
836 this class is defined in, it checks the configuration variable
837 <tt>Root.Html.LibName</tt>, and creates a link using its value.
838 Alternatively, you can set these URLs via THtml::SetLibURL().</p>
839 
840 <p>Example:<br/>
841 If a class MyClass is defined in class mylibs/libMyLib.so, and .rootrc
842 contains</p><pre>
843  Root.Html.MyLib: ../mylib/</pre>
844 <p>THtml will create a link to "../mylib/MyClass.html".</p>
845 
846 <p>The library name association can be set up using the rootmap facility.
847 For the library in the example above, which contains a dictionary
848 generated from the linkdef MyLinkdef.h, the command to generate the
849 rootmap file is</p>
850 <pre> $ rlibmap -f -r rootmap -l mylib/libMyLib.so -d libCore.so -c MyLinkdef.h</pre>
851 <p>Here, <tt>-r</tt> specifies that the entries for libMyLib should be updated,
852 <tt>-l</tt> specifies the library we're dealing with, <tt>-d</tt> its
853 dependencies, and <tt>-c</tt> its linkdef. The rootmap file must be within
854 one of the <tt>LD_LIBRARY_PATH</tt> (or <tt>PATH</tt> for Windows) directories
855 when ROOT is started, otherwise ROOT will not use it.</p>
856 
857 <h4><a name="conf:classdoc">II.4 Recognizing class documentation</a></h4>
858 
859 <p>The class documentation has to appear in the header file containing the
860 class, right in front of its declaration. It is introduced by a string
861 defined by Root.Html.Description or SetClassDocTag(). See the section on
862 <a href="#syntax">documentation syntax</a> for further details.</p>
863 
864 <p>Example:</p><pre>
865  Root.Html.Description: //____________________</pre>
866 
867 <p>The class documentation will show which include statement is to be used
868 and which library needs to be linked to access it.
869 The include file name is determined via
870 <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetDeclFileName">
871 TClass::GetDeclFileName()</a>;
872 leading parts are removed if they match any of the ':' separated entries in
873 THtml::GetIncludePath().</p>
874 
875 <h4><a name="conf:tags">II.5 Author, copyright, etc.</a></h4>
876 
877 <p>During the conversion,
878 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will look for
879 some strings ("tags") in the source file, which have to appear right in
880 front of e.g. the author's name, copyright notice, etc. These tags can be
881 defined with the following environment variables: Root.Html.Author,
882 Root.Html.LastUpdate and Root.Html.Copyright, or with
883 SetAuthorTag(), SetLastUpdateTag(), SetCopyrightTag().</p>
884 
885 <p>If the LastUpdate tag is not found, the current date and time are used.
886 This is useful when using
887 <a href="http://root.cern.ch/root/html/THtml.html#THtml:MakeAll">THtml::MakeAll()</a>'s
888 default option force=kFALSE, in which case
889 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> generates
890 documentation only for changed classes.</p>
891 
892 Authors can be a comma separated list of author entries. Each entry has
893 one of the following two formats
894 <ul><li><tt>Name (non-alpha)</tt>.
895 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate an
896 HTML link for <tt>Name</tt>, taking the Root.Html.XWho configuration
897 variable (defaults to "http://consult.cern.ch/xwho/people?") and adding
898 all parts of the name with spaces replaces by '+'. Non-alphanumerical
899 characters are printed out behind <tt>Name</tt>.</p>
900 
901 <p>Example:</p>
902 <tt>// Author: Enrico Fermi</tt> appears in the source file.
903 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate the link
904 <tt>http://consult.cern.ch/xwho/people?Enrico+Fermi</tt>. This works well for
905 people at CERN.</li>
906 
907 <li><tt>Name &lt;link&gt; Info</tt>.
908 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will generate
909 an HTML link for <tt>Name</tt> as specified by <tt>link</tt> and print
910 <tt>Info</tt> behind <tt>Name</tt>.</p>
911 
912 <p>Example:</p>
913 <tt>// Author: Enrico Fermi &lt;http://www.enricos-home.it&gt;</tt> or<br/>
914 <tt>// Author: Enrico Fermi &lt;mailto:enrico@fnal.gov&gt;</tt> in the
915 source file. That's world compatible.</li>
916 </ul>
917 
918 <p>Example (with defaults given):</p><pre>
919  Root.Html.Author: // Author:
920  Root.Html.LastUpdate: // @(#)
921  Root.Html.Copyright: * Copyright
922  Root.Html.XWho: http://consult.cern.ch/xwho/people?</pre>
923 
924 
925 <h4><a name="conf:header">II.6 Header and footer</a></h4>
926 
927 <p><a href="http://root.cern.ch/root/html/THtml.html">THtml</a> generates
928 a default header and footer for all pages. You can
929 specify your own versions with the configuration variables Root.Html.Header
930 and Root.Html.Footer, or by calling SetHeader(), SetFooter().
931 Both variables default to "", using the standard Root
932 versions. If it has a "+" appended, <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will
933 write both versions (user and root) to a file, for the header in the order
934 1st root, 2nd user, and for the footer 1st user, 2nd root (the root
935 versions containing "&lt;html&gt;" and &lt;/html&gt; tags, resp).</p>
936 
937 <p>If you want to replace root's header you have to write a file containing
938 all HTML elements necessary starting with the &lt;doctype&gt; tag and ending with
939 (and including) the &lt;body&gt; tag. If you add your header it will be added
940 directly after Root's &lt;body&gt; tag. Any occurrence of the string <tt>%TITLE%</tt>
941 in the user's header file will be replaced by
942 a sensible, automatically generated title. If the header is generated for a
943 class, occurrences of <tt>%CLASS%</tt> will be replaced by the current class's name,
944 <tt>%SRCFILE%</tt> and <tt>%INCFILE%</tt> by the name of the source and header file, resp.
945 (as given by <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetImplFileLine">TClass::GetImplFileName()</a>,
946 <a href="http://root.cern.ch/root/html/TClass.html#TClass:GetImplFileLine">TClass::GetDeclFileName()</a>).
947 If the header is not generated for a class, they will be replaced by "".</p>
948 
949 <p>Root's footer starts with the tag &lt;!--SIGNATURE--&gt;. It includes the
950 author(s), last update, copyright, the links to the Root home page, to the
951 user home page, to the index file (ClassIndex.html), to the top of the page
952 and <tt>this page is automatically generated</tt> infomation. It ends with the
953 tags <tt>&lt;/body&gt;&lt;/html&gt;</tt>. If you want to replace it,
954 <a href="http://root.cern.ch/root/html/THtml.html">THtml</a> will search for some
955 tags in your footer: Occurrences of the strings <tt>%AUTHOR%</tt>, <tt>%UPDATE%</tt>, and
956 <tt>%COPYRIGHT%</tt> are replaced by their
957 corresponding values before writing the html file. The <tt>%AUTHOR%</tt> tag will be
958 replaced by the exact string that follows Root.Html.Author, no link
959 generation will occur.</p>
960 
961 
962 <h4><a name="conf:search">II.7 Links to searches, home page, ViewVC</a></h4>
963 
964 <p>Additional parameters can be set by Root.Html.Homepage (address of the
965 user's home page), Root.Html.SearchEngine (search engine for the class
966 documentation), Root.Html.Search (search URL, where %u is replaced by the
967 referer and %s by the escaped search expression), and a ViewVC base URL
968 Root.Html.ViewCVS. For the latter, the file name is appended or, if
969 the URL contains %f, %f is replaced by the file name.
970 All values default to "".</p>
971 
972 <p>Examples:</p><pre>
973  Root.Html.Homepage: http://www.enricos-home.it
974  Root.Html.SearchEngine: http://root.cern.ch/root/Search.phtml
975  Root.Html.Search: http://www.google.com/search?q=%s+site%3A%u</pre>
976 
977 
978 <h4><a name="conf:charset">II.8 HTML Charset</a></h4>
979 
980 <p>XHTML 1.0 transitional recommends the specification of the charset in the
981 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>
982 <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
983 can be changed using Root.Html.Charset.</p>
984 
985 <p>Example:</p><pre>
986  Root.Html.Charset: EUC-JP</pre>
987 
988 <h3><a name="syntax">III. Documentation syntax</a></h3>
989 <h4><a name="syntax:classdesc">III.1 Class description</a></h4>
990 
991 <p>A class description block, which must be placed before the first
992 member function, has a following form:</p>
993 <pre>
994 ////////////////////////////////////////////////////////////////
995 // //
996 // TMyClass //
997 // //
998 // This is the description block. //
999 // //
1000 ////////////////////////////////////////////////////////////////
1001 </pre>
1002 <p>The environment variable Root.Html.Description
1003 (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>) contains
1004 the delimiter string (default value: <tt>//_________________</tt>). It means
1005 that you can also write your class description block like this:</p>
1006 <pre>
1007  //_____________________________________________________________
1008  // A description of the class starts with the line above, and
1009  // will take place here !
1010  //
1011 </pre>
1012 <p>Note that <b><i>everything</i></b> until the first non-commented line is considered
1013 as a valid class description block.</p>
1014 
1015 <h4><a name="syntax:classidx">III.2 Class index</a></h4>
1016 
1017 <p>All classes to be documented will have an entry in the ClassIndex.html,
1018 showing their name with a link to their documentation page and a miniature
1019 description. This discription for e.g. the class MyClass has to be given
1020 in MyClass's header as a comment right after ClassDef(MyClass, n).</p>
1021 
1022 <h4><a name="syntax:meth">III.3 Method documentation</a></h4>
1023 <p>A member function description block starts immediately after '{'
1024 and looks like this:</p>
1025 <pre>
1026  void TWorld::HelloWorldFunc(string *text)
1027  {
1028  // This is an example of description for the
1029  // TWorld member function
1030 
1031  helloWorld.Print( text );
1032  }
1033 </pre>
1034 Like in a class description block, <b><i>everything</i></b> until the first
1035 non-commented line is considered as a valid member function
1036 description block.
1037 
1038 If the rootrc variable <tt>Root.Html.DescriptionStyle</tt> is set to
1039 <tt>Doc++</tt> THtml will also look for method documentation in front of
1040 the function implementation. This feature is not recommended; source code
1041 making use of this does not comply to the ROOT documentation standards, which
1042 means future versions of THtml might not support it anymore.
1043 
1044 <h4><a name="syntax:datamem">III.4 Data member documentation</a></h4>
1045 
1046 <p>Data members are documented by putting a C++ comment behind their
1047 declaration in the header file, e.g.</p>
1048 <pre>
1049  int fIAmADataMember; // this is a data member
1050 </pre>
1051 
1052 
1053 <h3><a name="directive">IV. Documentation directives</a></h3>
1054 <em>NOTE that THtml does not yet support nested directives
1055 (i.e. latex inside html etc)!</em>
1056 
1057 <h4><a name="directive:html">IV.1 <tt>BEGIN<!-- -->_HTML</tt> <tt>END<!-- -->_HTML</tt>: include 'raw' HTML</a></h4>
1058 
1059 <p>You can insert pure html code into your documentation comments. During the
1060 generation of the documentation, this code will be inserted as is
1061 into the html file.</p>
1062 <p>Pure html code must be surrounded by the keywords
1063 <tt>BEGIN<!-- -->_HTML</tt> and <tt>END<!-- -->_HTML</tt>, where the
1064 case is ignored.
1065 An example of pure html code is this class description you are reading right now.
1066 THtml uses a
1067 <a href="http://root.cern.ch/root/html/TDocHtmlDirective.html">TDocHtmlDirective</a>
1068 object to process this directive.</p>
1069 
1070 <h4><a name="directive:macro">IV.2 <tt>BEGIN<!-- -->_MACRO</tt> <tt>END<!-- -->_MACRO</tt>: include a picture generated by a macro</a></h4>
1071 
1072 <p>THtml can create images from scripts. You can either call an external
1073 script by surrounding it by "begin_macro"/"end_macro", or include an unnamed
1074 macro within these keywords. The macro should return a pointer to an object;
1075 this object will then be saved as a GIF file.</p>
1076 <p>Objects deriving from
1077 <a href="http://root.cern.ch/root/html/TGObject.html">TGObject</a> (GUI elements)
1078 will need to run in graphics mode (non-batch). You must specify this as a parameter:
1079 "Begin_macro(GUI)...".
1080 To create a second tab that displays the source of the macro you can specify
1081 the argument "Begin_macro(source)...".
1082 Of course you can combine them,
1083 e.g. as "Begin_macro(source,gui)...".
1084 THtml uses a
1085 <a href="http://root.cern.ch/root/html/TDocMacroDirective.html">TDocMacroDirective</a>
1086 object to process this directive.</p>
1087 <p>This is an example:</p> END_HTML
1088 BEGIN_MACRO(source)
1089 {
1090  TCanvas* macro_example_canvas = new TCanvas("macro_example_canvas", "", 150, 150);
1091  macro_example_canvas->SetBorderSize(0);
1092  macro_example_canvas->SetFillStyle(1001);
1093  macro_example_canvas->SetFillColor(kWhite);
1094  macro_example_canvas->cd();
1095  TArc* macro_example_arc = new TArc(0.5,0.32,0.11,180,360);
1096  macro_example_arc->Draw();
1097  TEllipse* macro_example_ellipsis = new TEllipse(0.42,0.58,0.014,0.014,0,360,0);
1098  macro_example_ellipsis->SetFillStyle(0);
1099  macro_example_ellipsis->Draw();
1100  macro_example_ellipsis = new TEllipse(0.58,0.58,0.014,0.014,0,360,0);
1101  macro_example_ellipsis->SetFillStyle(0);
1102  macro_example_ellipsis->Draw();
1103  macro_example_ellipsis = new TEllipse(0.50,0.48,0.22,0.32,0,360,0);
1104  macro_example_ellipsis->SetFillStyle(0);
1105  macro_example_ellipsis->Draw();
1106  TLine* macro_example_line = new TLine(0.48,0.53,0.52,0.41);
1107  macro_example_line->Draw();
1108  return macro_example_canvas;
1109 }
1110 END_MACRO
1111 
1112 BEGIN_HTML
1113 <h4><a name="directive:latex">IV.3 <tt>BEGIN<!-- -->_LATEX</tt> <tt>END<!-- -->_LATEX</tt>: include a latex picture</a></h4>
1114 
1115 <p>You can specify <a href="http://root.cern.ch/root/html/TLatex.html">TLatex</a>
1116 style text and let THtml convert it into an image by surrounding it by "Begin_Latex", "End_Latex".
1117 You can have multiple lines, and e.g. align each line at the '=' sign by passing
1118 the argument <tt>separator='='</tt>. You can also specify how to align these parts;
1119 if you want the part left of the separator to be right aligned, and the right part
1120 to be left aligned, you could specify <tt>align='rl'</tt>.
1121 THtml uses a <a href="http://root.cern.ch/root/html/TDocLatexDirective.html">TDocLatexDirective</a>
1122 object to process the directive.
1123 This is an example output with arguments <tt>separator='=', align='rl'</tt>:</p>
1124 END_HTML BEGIN_LATEX(separator='=', align='rl')#kappa(x)^{2}=sin(x)^{x}
1125 x=#chi^{2} END_LATEX
1126 
1127 BEGIN_HTML
1128 
1129 <h3><a name="index">V. Product and module index</a></h3>
1130 
1131 <p><a href="#THtml:MakeIndex">THtml::MakeIndex()</a> will generate index files for classes
1132 and types, all modules, and the product which you can set by
1133 <a href="#THtml:SetProductName">THtml::SetProductName()</a>.
1134 THtml will make use of external documentation in the module and product index,
1135 either by linking it or by including it.
1136 The files for modules are searched based on the source file directory of the
1137 module's classes.</p>
1138 
1139 <p>A filename starting with "index." will be included in the index page;
1140 all other files will be linked.
1141 Only files ending on <tt>.html</tt> or <tt>.txt</tt> will be taken into account;
1142 the text files will first be run through
1143 <a href="#THtml:Convert">THtml::Convert()</a>.
1144 You can see an example <a href="http://root.cern.ch/root/html/HIST_Index.html">here</a>;
1145 the part between "Index of HIST classes" and "Jump to" is created by parsing
1146 the module's doc directory.</p>
1147 
1148 <h3><a name="aux">VI. Auxiliary files: style sheet, JavaScript, help page</a></h3>
1149 
1150 <p>The documentation pages share a common set of javascript and CSS files. They
1151 are generated automatically when running <a href="#THtml:MakeAll">MakeAll()</a>;
1152 they can be generated on
1153 demand by calling <a href="#THtml:CreateAuxiliaryFiles">CreateAuxiliaryFiles()</a>.</p>
1154 
1155 
1156 <h3><a name="charts">VII. Class Charts</a></h3>
1157 THtml can generate a number of graphical representations for a class, which
1158 are displayed as a tabbed set of imaged ontop of the class description.
1159 It can show the inheritance, inherited and hidden members, directly and
1160 indirectly included files, and library dependencies.
1161 
1162 These graphs are generated using the <a href="http://www.graphviz.org/">Graphviz</a>
1163 package. You can install it from <a href="http://www.graphviz.org">http://www.graphviz.org</a>.
1164 You can either put it into your $PATH, or tell THtml where to find it by calling
1165 <a href="#THtml:SetDotDir">SetDotDir()</a>.
1166 
1167 
1168 <h3><a name="confvar">VIII. Configuration variables</a></h3>
1169 
1170 <p>Here is a list of all configuration variables that are known to THtml.
1171 You can set them in your .rootrc file, see
1172 <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>.</p>
1173 
1174 <pre>
1175  Root.Html.OutputDir (default: htmldoc)
1176  Root.Html.SourceDir (default: .:src/:include/)
1177  Root.Html.Author (default: // Author:) - start tag for authors
1178  Root.Html.LastUpdate (default: // @(#)) - start tag for last update
1179  Root.Html.Copyright (default: * Copyright) - start tag for copyright notice
1180  Root.Html.Description (default: //____________________ ) - start tag for class descr
1181  Root.Html.HomePage (default: ) - URL to the user defined home page
1182  Root.Html.Header (default: ) - location of user defined header
1183  Root.Html.Footer (default: ) - location of user defined footer
1184  Root.Html.Root (default: ) - URL of Root's class documentation
1185  Root.Html.SearchEngine (default: ) - link to the search engine
1186  Root.Html.Search (defualt: ) - link to search by replacing "%s" with user input
1187  Root.Html.ViewCVS (default: ) - URL of ViewCVS base
1188  Root.Html.XWho (default: http://consult.cern.ch/xwho/people?) - URL of CERN's xWho
1189  Root.Html.Charset (default: ISO-8859-1) - HTML character set
1190 </pre>
1191 
1192 <h3><a name="how">IX. Behind the scene</a></h3>
1193 
1194 <p>Internally, THtml is just an API class that sets up the list of known
1195 classes, and forwards API invocations to the "work horses".
1196 <a href="http://root.cern.ch/root/html/TDocOutput.html">TDocOutput</a>
1197 generates the output by letting a
1198 <a href="http://root.cern.ch/root/html/TDocParser.html">TDocParser</a>
1199 object parse the sources, which in turn invokes objects deriving from
1200 <a href="http://root.cern.ch/root/html/TDocDirective.html">TDocDirective</a>
1201 to process directives.</p>
1202 
1203 END_HTML */
1204 ////////////////////////////////////////////////////////////////////////////////
1205 
1206 ClassImp(THtml)
1207 ////////////////////////////////////////////////////////////////////////////////
1208 /// Create a THtml object.
1209 /// In case output directory does not exist an error
1210 /// will be printed and gHtml stays 0 also zombie bit will be set.
1211 
1213  fCounterFormat("%12s %5s %s"),
1214  fProductName("(UNKNOWN PRODUCT)"),
1215  fThreadedClassIter(0), fThreadedClassCount(0), fMakeClassMutex(0),
1216  fGClient(0), fPathDef(0), fModuleDef(0), fFileDef(0),
1217  fLocalFiles(0), fBatch(kFALSE)
1218 {
1219  // check for source directory
1220  fPathInfo.fInputPath = gEnv->GetValue("Root.Html.SourceDir", "./:src/:include/");
1221 
1222  // check for output directory
1223  SetOutputDir(gEnv->GetValue("Root.Html.OutputDir", "htmldoc"));
1224 
1225  fLinkInfo.fXwho = gEnv->GetValue("Root.Html.XWho", "http://consult.cern.ch/xwho/people?");
1226  fLinkInfo.fROOTURL = gEnv->GetValue("Root.Html.Root", "http://root.cern.ch/root/html");
1227  fDocSyntax.fClassDocTag = gEnv->GetValue("Root.Html.Description", "//____________________");
1228  fDocSyntax.fAuthorTag = gEnv->GetValue("Root.Html.Author", "// Author:");
1229  fDocSyntax.fLastUpdateTag = gEnv->GetValue("Root.Html.LastUpdate", "// @(#)");
1230  fDocSyntax.fCopyrightTag = gEnv->GetValue("Root.Html.Copyright", "* Copyright");
1231  fOutputStyle.fHeader = gEnv->GetValue("Root.Html.Header", "");
1232  fOutputStyle.fFooter = gEnv->GetValue("Root.Html.Footer", "");
1233  fLinkInfo.fHomepage = gEnv->GetValue("Root.Html.Homepage", "");
1234  fLinkInfo.fSearchStemURL = gEnv->GetValue("Root.Html.Search", "");
1235  fLinkInfo.fSearchEngine = gEnv->GetValue("Root.Html.SearchEngine", "");
1236  fLinkInfo.fViewCVS = gEnv->GetValue("Root.Html.ViewCVS", "");
1237  fOutputStyle.fCharset = gEnv->GetValue("Root.Html.Charset", "ISO-8859-1");
1238  fDocSyntax.fDocStyle = gEnv->GetValue("Root.Html.DescriptionStyle", "");
1239 
1240  fDocEntityInfo.fClasses.SetOwner();
1241  fDocEntityInfo.fModules.SetOwner();
1242  // insert html object in the list of special ROOT objects
1243  if (!gHtml) {
1244  gHtml = this;
1245  gROOT->GetListOfSpecials()->Add(gHtml);
1246  }
1247 
1248 }
1249 
1250 
1251 ////////////////////////////////////////////////////////////////////////////////
1252 /// Default destructor
1253 
1255 {
1256  fDocEntityInfo.fClasses.Clear();
1257  fDocEntityInfo.fModules.Clear();
1258  if (gHtml == this) {
1259  gROOT->GetListOfSpecials()->Remove(gHtml);
1260  gHtml = 0;
1261  }
1262  delete fPathDef;
1263  delete fModuleDef;
1264  delete fFileDef;
1265  delete fLocalFiles;
1266 }
1267 
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Add path to the directories to be searched for macro files
1270 /// that are to be executed via the TDocMacroDirective
1271 /// ("Begin_Macro"/"End_Macro"); relative to the source file
1272 /// that the directive is run on.
1273 
1274 void THtml::AddMacroPath(const char* path)
1275 {
1276  const char pathDelimiter =
1277 #ifdef R__WIN32
1278  ';';
1279 #else
1280  ':';
1281 #endif
1282  fPathInfo.fMacroPath += pathDelimiter;
1283  fPathInfo.fMacroPath += path;
1284 }
1285 
1286 
1287 ////////////////////////////////////////////////////////////////////////////////
1288 /// copy CSS, javascript file, etc to the output dir
1289 
1291 {
1292  CreateJavascript();
1293  CreateStyleSheet();
1294  CopyFileFromEtcDir("HELP.html");
1295 }
1296 
1297 ////////////////////////////////////////////////////////////////////////////////
1298 /// Return the TModuleDefinition (or derived) object as set by
1299 /// SetModuleDefinition(); create and return a TModuleDefinition object
1300 /// if none was set.
1301 
1303 {
1304  if (!fModuleDef) {
1305  fModuleDef = new TModuleDefinition();
1306  fModuleDef->SetOwner(const_cast<THtml*>(this));
1307  }
1308  return *fModuleDef;
1309 }
1310 
1311 ////////////////////////////////////////////////////////////////////////////////
1312 /// Return the TFileDefinition (or derived) object as set by
1313 /// SetFileDefinition(); create and return a TFileDefinition object
1314 /// if none was set.
1315 
1317 {
1318  if (!fFileDef) {
1319  fFileDef = new TFileDefinition();
1320  fFileDef->SetOwner(const_cast<THtml*>(this));
1321  }
1322  return *fFileDef;
1323 }
1324 
1325 ////////////////////////////////////////////////////////////////////////////////
1326 /// Return the TModuleDefinition (or derived) object as set by
1327 /// SetModuleDefinition(); create and return a TModuleDefinition object
1328 /// if none was set.
1329 
1331 {
1332  if (!fPathDef) {
1333  fPathDef = new TPathDefinition();
1334  fPathDef->SetOwner(const_cast<THtml*>(this));
1335  }
1336  return *fPathDef;
1337 }
1338 
1339 
1340 ////////////////////////////////////////////////////////////////////////////////
1341 /// Get the directory containing THtml's auxiliary files ($ROOTSYS/etc/html)
1342 
1343 const char* THtml::GetEtcDir() const
1344 {
1345  if (fPathInfo.fEtcDir.Length())
1346  return fPathInfo.fEtcDir;
1347 
1348  R__LOCKGUARD(GetMakeClassMutex());
1349 
1350  fPathInfo.fEtcDir = "html";
1351  gSystem->PrependPathName(TROOT::GetEtcDir(), fPathInfo.fEtcDir);
1352 
1353  return fPathInfo.fEtcDir;
1354 }
1355 
1356 
1357 ////////////////////////////////////////////////////////////////////////////////
1358 /// Return the next class to be generated for MakeClassThreaded.
1359 
1361 {
1362  if (!fThreadedClassIter) return 0;
1363 
1364  R__LOCKGUARD(GetMakeClassMutex());
1365 
1366  TClassDocInfo* classinfo = 0;
1367  while ((classinfo = (TClassDocInfo*)(*fThreadedClassIter)())
1368  && !classinfo->IsSelected()) { }
1369 
1370  if (!classinfo) {
1371  delete fThreadedClassIter;
1372  fThreadedClassIter = 0;
1373  }
1374 
1375  fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - fThreadedClassCount++);
1376 
1377  return classinfo;
1378 }
1379 
1380 
1381 ////////////////////////////////////////////////////////////////////////////////
1382 /// Get the documentation URL for library lib.
1383 /// If lib == 0 or no documentation URL has been set for lib, return the ROOT
1384 /// documentation URL. The return value is always != 0.
1385 
1386 const char* THtml::GetURL(const char* lib /*=0*/) const
1387 {
1388  R__LOCKGUARD(GetMakeClassMutex());
1389 
1390  if (lib && strlen(lib)) {
1391  std::map<std::string, TString>::const_iterator iUrl = fLinkInfo.fLibURLs.find(lib);
1392  if (iUrl != fLinkInfo.fLibURLs.end()) return iUrl->second;
1393  return gEnv->GetValue(TString("Root.Html.") + lib, fLinkInfo.fROOTURL);
1394  }
1395  return fLinkInfo.fROOTURL;
1396 }
1397 
1398 ////////////////////////////////////////////////////////////////////////////////
1399 /// Check whether dot is available in $PATH or in the directory set
1400 /// by SetDotPath()
1401 
1403 {
1404  if (fPathInfo.fFoundDot != PathInfo_t::kDotUnknown)
1405  return (fPathInfo.fFoundDot == PathInfo_t::kDotFound);
1406 
1407  R__LOCKGUARD(GetMakeClassMutex());
1408 
1409  Info("HaveDot", "Checking for Graphviz (dot)...");
1410  TString runDot("dot");
1411  if (fPathInfo.fDotDir.Length())
1412  gSystem->PrependPathName(fPathInfo.fDotDir, runDot);
1413  runDot += " -V";
1414  if (gDebug > 3)
1415  Info("HaveDot", "Running: %s", runDot.Data());
1416  if (gSystem->Exec(runDot)) {
1417  fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
1418  return kFALSE;
1419  }
1420  fPathInfo.fFoundDot = PathInfo_t::kDotFound;
1421  return kTRUE;
1422 
1423 }
1424 
1425 ////////////////////////////////////////////////////////////////////////////////
1426 /// Inform the THtml object that one of its helper objects was deleted.
1427 /// Called by THtml::HelperBase::~HelperBase().
1428 
1430 {
1431  THelperBase* helpers[3] = {fPathDef, fModuleDef, fFileDef};
1432  for (int i = 0; who && i < 3; ++i)
1433  if (who == helpers[i])
1434  helpers[i] = who = 0;
1435 }
1436 
1437 
1438 ////////////////////////////////////////////////////////////////////////////////
1439 /// It converts a single text file to HTML
1440 ///
1441 ///
1442 /// Input: filename - name of the file to convert
1443 /// title - title which will be placed at the top of the HTML file
1444 /// dirname - optional parameter, if it's not specified, output will
1445 /// be placed in htmldoc/examples directory.
1446 /// relpath - optional parameter pointing to the THtml generated doc
1447 /// on the server, relative to the current page.
1448 /// includeOutput - if != kNoOutput, run the script passed as filename and
1449 /// store all created canvases in PNG files that are
1450 /// shown next to the converted source. Bitwise-ORing with
1451 /// kForceOutput re-runs the script even if output PNGs exist
1452 /// that are newer than the script. If kCompiledOutput is
1453 /// passed, the script is run through ACLiC (.x filename+)
1454 /// context - line shown verbatim at the top of the page; e.g. for links.
1455 /// If context is non-empty it is expected to also print the
1456 /// title.
1457 ///
1458 /// NOTE: Output file name is the same as filename, but with extension .html
1459 ///
1460 
1461 void THtml::Convert(const char *filename, const char *title,
1462  const char *dirname /*= ""*/, const char *relpath /*= "../"*/,
1463  Int_t includeOutput /* = kNoOutput */,
1464  const char* context /* = "" */)
1465 {
1466  gROOT->GetListOfGlobals(kTRUE); // force update of this list
1467  CreateListOfClasses("*");
1468 
1469  const char *dir;
1470 
1471  // if it's not defined, make the "examples" as a default directory
1472  if (!*dirname) {
1473  gSystem->ExpandPathName(fPathInfo.fOutputDir);
1474  dir = gSystem->ConcatFileName(fPathInfo.fOutputDir, "examples");
1475  } else
1476  dir = dirname;
1477 
1478  // create directory if necessary
1479  if (gSystem->AccessPathName(dir))
1480  gSystem->MakeDirectory(dir);
1481 
1482  // find a file
1483  char *cRealFilename =
1484  gSystem->Which(fPathInfo.fInputPath, filename, kReadPermission);
1485 
1486  if (!cRealFilename) {
1487  Error("Convert", "Can't find file '%s' !", filename);
1488  return;
1489  }
1490 
1491  TString realFilename(cRealFilename);
1492  delete[] cRealFilename;
1493  cRealFilename = 0;
1494 
1495  // open source file
1496  std::ifstream sourceFile;
1497  sourceFile.open(realFilename, std::ios::in);
1498 
1499  if (!sourceFile.good()) {
1500  Error("Convert", "Can't open file '%s' !", realFilename.Data());
1501  return;
1502  }
1503 
1504  if (gSystem->AccessPathName(dir)) {
1505  Error("Convert",
1506  "Directory '%s' doesn't exist, or it's write protected !", dir);
1507  return;
1508  }
1509  char *tmp1 =
1510  gSystem->ConcatFileName(dir, gSystem->BaseName(filename));
1511 
1512  TDocOutput output(*this);
1513  if (!fGClient)
1514  gROOT->ProcessLine(TString::Format("*((TGClient**)0x%lx) = gClient;",
1515  (ULong_t)&fGClient));
1516  if (includeOutput && !fGClient)
1517  Warning("Convert", "Output requested but cannot initialize graphics: GUI and GL windows not be available");
1518  output.Convert(sourceFile, realFilename, tmp1, title, relpath, includeOutput, context, fGClient);
1519 
1520  if (tmp1)
1521  delete[]tmp1;
1522  tmp1 = 0;
1523 }
1524 
1525 ////////////////////////////////////////////////////////////////////////////////
1526 /// Return the module name for a given class.
1527 /// Use the cached information from fDocEntityInfo.fClasses.
1528 
1530 {
1531  module = "(UNKNOWN)";
1532  if (!cl) return;
1533 
1534  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(cl->GetName());
1535  if (!cdi || !cdi->GetModule())
1536  return;
1537  module = cdi->GetModule()->GetName();
1538 }
1539 
1540 
1541 ////////////////////////////////////////////////////////////////////////////////
1542 /// Create the list of all known classes
1543 
1544 void THtml::CreateListOfClasses(const char* filter)
1545 {
1546  if (fDocEntityInfo.fClasses.GetSize() && fDocEntityInfo.fClassFilter == filter)
1547  return;
1548 
1549  Info("CreateListOfClasses", "Initializing - this might take a while...");
1550  // get total number of classes
1551  Int_t totalNumberOfClasses = gClassTable->Classes();
1552 
1553  // allocate memory
1554  fDocEntityInfo.fClasses.Clear();
1555  fDocEntityInfo.fModules.Clear();
1556 
1557  fDocEntityInfo.fClassFilter = filter;
1558 
1559  // start from begining
1560  gClassTable->Init();
1561  if (filter && (!filter[0] || !strcmp(filter, "*")))
1562  filter = ".*";
1563  TString reg = filter;
1564  TPMERegexp re(reg);
1565 
1566  bool skipROOTClasses = false;
1567  std::set<std::string> rootLibs;
1568  TList classesDeclFileNotFound;
1569  TList classesImplFileNotFound;
1570 
1571  // pre-run TObject at i == -1
1572  for (Int_t i = -1; i < totalNumberOfClasses; i++) {
1573 
1574  // get class name
1575  const char *cname = 0;
1576  if (i < 0) cname = "TObject";
1577  else cname = gClassTable->Next();
1578 
1579  if (i >= 0 && !strcmp(cname, "TObject")) {
1580  // skip the second iteration on TObject
1581  continue;
1582  }
1583 
1584  // This is a hack for until after Cint and Reflex are one.
1585  if (strstr(cname, "__gnu_cxx::")) continue;
1586  // Work around ROOT-6016
1587  if (!strcmp(cname, "timespec")) continue;
1588 
1589  // get class & filename - use TROOT::GetClass, as we also
1590  // want those classes without decl file name!
1591  TClass *classPtr = TClass::GetClass((const char *) cname, kTRUE);
1592  if (!classPtr) continue;
1593 
1594  std::string shortName(ShortType(cname));
1595  cname = shortName.c_str();
1596 
1597  TString s = cname;
1598  Bool_t matchesSelection = re.Match(s);
1599 
1600 
1601  TString hdr;
1602  TString hdrFS;
1603  TString src;
1604  TString srcFS;
1605  TString htmlfilename;
1606  TFileSysEntry* fse = 0;
1607 
1608  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cname);
1609  if (cdi) {
1610  hdr = cdi->GetDeclFileName();
1611  hdrFS = cdi->GetDeclFileSysName();
1612  src = cdi->GetImplFileName();
1613  srcFS = cdi->GetImplFileSysName();
1614  htmlfilename = cdi->GetHtmlFileName();
1615  }
1616 
1617  if (!hdrFS.Length()) {
1618  if (!GetFileDefinition().GetDeclFileName(classPtr, hdr, hdrFS, &fse)) {
1619  // we don't even know where the class is defined;
1620  // just skip. Silence if it doesn't match the selection anyway
1621  if (i == -1 ) {
1622  skipROOTClasses = true;
1623  Info("CreateListOfClasses", "Cannot find header file for TObject at %s given the input path %s.",
1624  classPtr->GetDeclFileName(), GetInputPath().Data());
1625  Info("CreateListOfClasses", "Assuming documentation is not for ROOT classes, or you need to pass "
1626  "the proper directory to THtml::SetInputDir() so I can find %s.", classPtr->GetDeclFileName());
1627  continue;
1628  }
1629  // ignore STL
1630  if (classPtr->GetClassInfo() &&
1631  (gInterpreter->ClassInfo_Property(classPtr->GetClassInfo()) & kIsDefinedInStd))
1632  continue;
1633  if (classPtr->GetDeclFileName() && (!strncmp(classPtr->GetDeclFileName(), "prec_stl/", 9) ||
1634  strstr(classPtr->GetDeclFileName(), "include/c++/") ||
1635  !strncmp(classPtr->GetDeclFileName(), "/usr/include",12)))
1636  continue;
1637  if (classPtr->GetDeclFileName() && (
1638  !strcmp(classPtr->GetDeclFileName(), "vector") ||
1639  !strcmp(classPtr->GetDeclFileName(), "string") ||
1640  !strcmp(classPtr->GetDeclFileName(), "list") ||
1641  !strcmp(classPtr->GetDeclFileName(), "deque") ||
1642  !strcmp(classPtr->GetDeclFileName(), "map") ||
1643  !strcmp(classPtr->GetDeclFileName(), "valarray") ||
1644  !strcmp(classPtr->GetDeclFileName(), "set") ||
1645  !strcmp(classPtr->GetDeclFileName(), "typeinfo") ||
1646  !strcmp(classPtr->GetDeclFileName(), "stdlib.h") ) )
1647  {
1648  // Those are STL header, just ignore.
1649  continue;
1650  }
1651  if (skipROOTClasses) {
1652  if (classPtr->GetSharedLibs() && classPtr->GetSharedLibs()[0]) {
1653  std::string lib(classPtr->GetSharedLibs());
1654  size_t posSpace = lib.find(' ');
1655  if (posSpace != std::string::npos)
1656  lib.erase(posSpace);
1657  if (rootLibs.find(lib) == rootLibs.end()) {
1658  TString rootlibdir = TROOT::GetLibDir();
1659  TString sLib(lib);
1660  if (sLib.Index('.') == -1) {
1661  sLib += ".";
1662  sLib += gSystem->GetSoExt();
1663  }
1664  gSystem->PrependPathName(rootlibdir, sLib);
1665  if (gSystem->AccessPathName(sLib))
1666  // the library doesn't exist in $ROOTSYS/lib, so it's not
1667  // a root lib and we need to tell the user.
1668  classesDeclFileNotFound.AddLast(classPtr);
1669  else rootLibs.insert(lib);
1670  } // end "if rootLibs does not contain lib"
1671  } else {
1672  // lib name unknown
1673  static const char* rootClassesToIgnore[] =
1674  { "ColorStruct_t", "CpuInfo_t", "Event_t", "FileStat_t", "GCValues_t", "MemInfo_t",
1675  "PictureAttributes_t", "Point_t", "ProcInfo_t", "ROOT", "ROOT::Fit",
1676  "Rectangle_t", "RedirectHandle_t", "Segment_t", "SetWindowAttributes_t",
1677  "SysInfo_t", "TCint", "UserGroup_t", "WindowAttributes_t", "timespec", 0};
1678  static const char* rootClassStemsToIgnore[] =
1679  { "ROOT::Math", "TKDTree", "TMatrixT", "TParameter", "vector", 0 };
1680  static size_t rootClassStemsToIgnoreLen[] = {0, 0, 0, 0, 0};
1681  static std::set<std::string> setRootClassesToIgnore;
1682  if (setRootClassesToIgnore.empty()) {
1683  for (int ii = 0; rootClassesToIgnore[ii]; ++ii)
1684  setRootClassesToIgnore.insert(rootClassesToIgnore[ii]);
1685  for (int ii = 0; rootClassStemsToIgnore[ii]; ++ii)
1686  rootClassStemsToIgnoreLen[ii] = strlen(rootClassStemsToIgnore[ii]);
1687  }
1688  // only complain about this class if it should not be ignored:
1689  if (setRootClassesToIgnore.find(cname) == setRootClassesToIgnore.end()) {
1690  bool matched = false;
1691  for (int ii = 0; !matched && rootClassStemsToIgnore[ii]; ++ii)
1692  matched = !strncmp(cname, rootClassStemsToIgnore[ii], rootClassStemsToIgnoreLen[ii]);
1693  if (!matched)
1694  classesDeclFileNotFound.AddLast(classPtr);
1695  }
1696  } // lib name known
1697  continue;
1698  } else {
1699  if (matchesSelection && (!classPtr->GetDeclFileName() ||
1700  !strstr(classPtr->GetDeclFileName(),"prec_stl/") ||
1701  !strstr(classPtr->GetDeclFileName(), "include/c++/") ||
1702  strncmp(classPtr->GetDeclFileName(), "/usr/include",12)))
1703  classesDeclFileNotFound.AddLast(classPtr);
1704  continue;
1705  }
1706  }
1707  }
1708 
1709  Bool_t haveSource = (srcFS.Length());
1710  if (!haveSource)
1711  haveSource = GetFileDefinition().GetImplFileName(classPtr, src, srcFS, fse ? 0 : &fse);
1712 
1713  if (!haveSource) {
1714  classesImplFileNotFound.AddLast(classPtr);
1715  }
1716 
1717  if (!htmlfilename.Length())
1718  GetHtmlFileName(classPtr, htmlfilename);
1719 
1720  if (!cdi) {
1721  cdi = new TClassDocInfo(classPtr, htmlfilename, hdrFS, srcFS, hdr, src);
1722  fDocEntityInfo.fClasses.Add(cdi);
1723  } else {
1724  cdi->SetDeclFileName(hdr);
1725  cdi->SetImplFileName(src);
1726  cdi->SetDeclFileSysName(hdrFS);
1727  cdi->SetImplFileSysName(srcFS);
1728  cdi->SetHtmlFileName(htmlfilename);
1729  }
1730 
1731  cdi->SetSelected(matchesSelection);
1732 
1733  TString modulename;
1734  GetModuleDefinition().GetModule(classPtr, fse, modulename);
1735  if (!modulename.Length() || modulename == "USER")
1736  GetModuleNameForClass(modulename, classPtr);
1737 
1738  TModuleDocInfo* module = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(modulename);
1739  if (!module) {
1740  bool moduleSelected = cdi->IsSelected();
1741 
1742  TString parentModuleName(gSystem->DirName(modulename));
1743  TModuleDocInfo* super = 0;
1744  if (parentModuleName.Length() && parentModuleName != ".") {
1745  super = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(parentModuleName);
1746  if (!super) {
1747  // create parents:
1748  TString token;
1749  Ssiz_t pos = 0;
1750  while (parentModuleName.Tokenize(token, pos, "/")) {
1751  if (!token.Length() || token == ".") continue;
1752  super = new TModuleDocInfo(token, super);
1753  super->SetSelected(moduleSelected);
1754  fDocEntityInfo.fModules.Add(super);
1755  }
1756  }
1757  }
1758  module = new TModuleDocInfo(modulename, super);
1759  module->SetSelected(moduleSelected);
1760  fDocEntityInfo.fModules.Add(module);
1761  }
1762 
1763  if (module) {
1764  module->AddClass(cdi);
1765  cdi->SetModule(module);
1766  if (cdi->HaveSource() && cdi->IsSelected())
1767  module->SetSelected();
1768  }
1769 
1770  // clear the typedefs; we fill them later
1771  cdi->GetListOfTypedefs().Clear();
1772 
1773  if (gDebug > 0)
1774  Info("CreateListOfClasses", "Adding class %s, module %s (%sselected)",
1775  cdi->GetName(), module ? module->GetName() : "[UNKNOWN]",
1776  cdi->IsSelected() ? "" : "not ");
1777  }
1778 
1779 
1780 
1781  bool cannotFind = false;
1782  if (!classesDeclFileNotFound.IsEmpty()) {
1783  Warning("CreateListOfClasses",
1784  "Cannot find the header for the following classes [reason]:");
1785  TIter iClassesDeclFileNotFound(&classesDeclFileNotFound);
1786  TClass* iClass = 0;
1787  while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1788  if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1789  Warning("CreateListOfClasses", " %s [header %s not found]", iClass->GetName(), iClass->GetDeclFileName());
1790  cannotFind = true;
1791  } else
1792  Warning("CreateListOfClasses", " %s [header file is unknown]", iClass->GetName());
1793  }
1794  }
1795 
1796  if (!classesImplFileNotFound.IsEmpty() && gDebug > 3) {
1797  Warning("CreateListOfClasses",
1798  "Cannot find the source file for the following classes [reason]:");
1799  TIter iClassesDeclFileNotFound(&classesImplFileNotFound);
1800  TClass* iClass = 0;
1801  while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1802  if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1803  Info("CreateListOfClasses", " %s [source %s not found]", iClass->GetName(), iClass->GetImplFileName());
1804  cannotFind = true;
1805  } else
1806  Info("CreateListOfClasses", " %s [source file is unknown, add \"ClassImpl(%s)\" to source file if it exists]",
1807  iClass->GetName(), iClass->GetName());
1808  }
1809  }
1810  if (cannotFind) {
1811  Warning("CreateListOfClasses", "THtml cannot find all headers and sources. ");
1812  Warning("CreateListOfClasses",
1813  "You might need to adjust the input path (currently %s) by calling THtml::SetInputDir()",
1814  GetInputPath().Data());
1815  }
1816 
1817  // fill typedefs
1818  TIter iTypedef(gROOT->GetListOfTypes());
1819  TDataType* dt = 0;
1820  TDocOutput output(*this);
1821  while ((dt = (TDataType*) iTypedef())) {
1822  if (dt->GetType() != -1) continue;
1823  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(dt->GetFullTypeName());
1824  if (cdi) {
1825  cdi->GetListOfTypedefs().Add(dt);
1826  if (gDebug > 1)
1827  Info("CreateListOfClasses", "Adding typedef %s to class %s",
1828  dt->GetName(), cdi->GetName());
1829 
1830  bool inNamespace = true;
1831  TString surroundingNamespace(dt->GetName());
1832  Ssiz_t posTemplate = surroundingNamespace.Last('>');
1833  inNamespace = inNamespace && (posTemplate == kNPOS);
1834  if (inNamespace) {
1835  Ssiz_t posColumn = surroundingNamespace.Last(':');
1836  if (posColumn != kNPOS) {
1837  surroundingNamespace.Remove(posColumn - 1);
1838  TClass* clSurrounding = GetClass(surroundingNamespace);
1839  inNamespace = inNamespace && (!clSurrounding || IsNamespace(clSurrounding));
1840  }
1841  }
1842  if (inNamespace && cdi->GetModule()) {
1843  TString htmlfilename(dt->GetName());
1844  output.NameSpace2FileName(htmlfilename);
1845  htmlfilename += ".html";
1846  TClassDocInfo* cdiTD = new TClassDocInfo(dt, htmlfilename);
1847  cdiTD->SetModule(cdi->GetModule());
1848  cdiTD->SetSelected(cdi->IsSelected());
1849  cdi->GetModule()->AddClass(cdiTD);
1850  }
1851  }
1852  }
1853 
1854  fDocEntityInfo.fClasses.Sort();
1855  fDocEntityInfo.fModules.Sort();
1856  TIter iterModule(&fDocEntityInfo.fModules);
1857  TModuleDocInfo* mdi = 0;
1858  while ((mdi = (TModuleDocInfo*) iterModule()))
1859  mdi->GetClasses()->Sort();
1860 
1861  if (fProductName == "(UNKNOWN PRODUCT)"
1862  && fDocEntityInfo.fModules.FindObject("core/base")
1863  && fDocEntityInfo.fModules.FindObject("core/cont")
1864  && fDocEntityInfo.fModules.FindObject("core/rint")
1865  && gProgName && strstr(gProgName, "root"))
1866  // if we have these modules we're probably building the root doc
1867  fProductName = "ROOT";
1868 
1869  if (fProductName == "(UNKNOWN PRODUCT)") {
1870  Warning("CreateListOfClasses", "Product not set. You should call gHtml->SetProduct(\"MyProductName\");");
1871  } else if (fProductName != "ROOT") {
1872  if (GetViewCVS().Contains("http://root.cern.ch/"))
1873  SetViewCVS("");
1874  }
1875 
1876  if (fDocEntityInfo.fModules.GetEntries() == 1
1877  && fDocEntityInfo.fModules.At(0)->GetName()
1878  && !strcmp(fDocEntityInfo.fModules.At(0)->GetName(), "(UNKNOWN)"))
1879  // Only one module, and its name is not known.
1880  // Let's call it "MAIN":
1881  ((TModuleDocInfo*) fDocEntityInfo.fModules.At(0))->SetName("MAIN");
1882 
1883  Info("CreateListOfClasses", "Initializing - DONE.");
1884 }
1885 
1886 
1887 ////////////////////////////////////////////////////////////////////////////////
1888 /// Create index of all data types and a page for each typedef-to-class
1889 
1891 {
1892  TDocOutput output(*this);
1893  output.CreateTypeIndex();
1894  output.CreateClassTypeDefs();
1895 }
1896 
1897 ////////////////////////////////////////////////////////////////////////////////
1898 /// Copy a file from $ROOTSYS/etc/html into GetOutputDir()
1899 
1901  R__LOCKGUARD(GetMakeClassMutex());
1902 
1903  TString outFile(filename);
1904 
1905  TString inFile(outFile);
1906  gSystem->PrependPathName(GetEtcDir(), inFile);
1907 
1908  gSystem->PrependPathName(GetOutputDir(), outFile);
1909 
1910  if (gSystem->CopyFile(inFile, outFile, kTRUE) != 0) {
1911  Warning("CopyFileFromEtcDir", "Could not copy %s to %s", inFile.Data(), outFile.Data());
1912  return kFALSE;
1913  }
1914 
1915  return kTRUE;
1916 }
1917 
1918 ////////////////////////////////////////////////////////////////////////////////
1919 /// Create the inheritance hierarchy diagram for all classes
1920 
1922 {
1923  TDocOutput output(*this);
1924  output.CreateHierarchy();
1925 }
1926 
1927 ////////////////////////////////////////////////////////////////////////////////
1928 /// Write the default ROOT style sheet.
1929 
1931  CopyFileFromEtcDir("ROOT.js");
1932 }
1933 
1934 ////////////////////////////////////////////////////////////////////////////////
1935 /// Write the default ROOT style sheet.
1936 
1938  CopyFileFromEtcDir("ROOT.css");
1939  CopyFileFromEtcDir("shadowAlpha.png");
1940  CopyFileFromEtcDir("shadow.gif");
1941 }
1942 
1943 
1944 
1945 ////////////////////////////////////////////////////////////////////////////////
1946 /// fill derived with all classes inheriting from cl and their inheritance
1947 /// distance to cl
1948 
1949 void THtml::GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived) const
1950 {
1951  TIter iClass(&fDocEntityInfo.fClasses);
1952  TClassDocInfo* cdi = 0;
1953  while ((cdi = (TClassDocInfo*) iClass())) {
1954  TClass* candidate = dynamic_cast<TClass*>(cdi->GetClass());
1955  if (!candidate) continue;
1956  if (candidate != cl && candidate->InheritsFrom(cl)) {
1957  Int_t level = 0;
1958  TClass* currentBaseOfCandidate = candidate;
1959  while (currentBaseOfCandidate != cl) {
1960  TList* bases = currentBaseOfCandidate->GetListOfBases();
1961  if (!bases) continue;
1962  TIter iBase(bases);
1963  TBaseClass* base = 0;
1964  while ((base = (TBaseClass*) iBase())) {
1965  TClass* clBase = base->GetClassPointer();
1966  if (clBase && clBase->InheritsFrom(cl)) {
1967  ++level;
1968  currentBaseOfCandidate = clBase;
1969  }
1970  }
1971  }
1972  derived[candidate] = level;
1973  }
1974  }
1975 }
1976 
1977 ////////////////////////////////////////////////////////////////////////////////
1978 /// Return real HTML filename
1979 ///
1980 ///
1981 /// Input: classPtr - pointer to a class
1982 /// filename - string containing a full name
1983 /// of the corresponding HTML file after the function returns.
1984 ///
1985 
1987 {
1988  filename.Remove(0);
1989  if (!classPtr) return;
1990 
1991  TString cFilename;
1992  if (!GetImplFileName(classPtr, kFALSE, cFilename))
1993  GetDeclFileName(classPtr, kFALSE, cFilename);
1994 
1995  // classes without Impl/DeclFileName don't have docs,
1996  // and classes without docs don't have output file names
1997  if (!cFilename.Length())
1998  return;
1999 
2000  TString libName;
2001  const char *colon = strchr(cFilename, ':');
2002  if (colon)
2003  // old version, where source file name is prepended by "TAG:"
2004  libName = TString(cFilename, colon - cFilename);
2005  else
2006  // New version, check class's libname.
2007  // If libname is dir/libMyLib.so, check Root.Html.MyLib
2008  // If libname is myOtherLib.so.2.3, check Root.Html.myOtherLib
2009  // (i.e. remove directories, "lib" prefix, and any "extension")
2010  if (classPtr->GetSharedLibs()) {
2011  // first one is the class's lib
2012  TString libname(classPtr->GetSharedLibs());
2013  Ssiz_t posSpace = libname.First(' ');
2014  if (posSpace != kNPOS)
2015  libname.Remove(posSpace, libname.Length());
2016  TString libnameBase = gSystem->BaseName(libname);
2017  if (libnameBase.BeginsWith("lib"))
2018  libnameBase.Remove(0, 3);
2019  Ssiz_t posExt = libnameBase.First('.');
2020  if (posExt != '.')
2021  libnameBase.Remove(posExt, libnameBase.Length());
2022  if (libnameBase.Length())
2023  libName = libnameBase;
2024  }
2025 
2026  filename = cFilename;
2027  TString htmlFileName;
2028  if (!filename.Length() ||
2029  !gSystem->FindFile(fPathInfo.fInputPath, filename, kReadPermission)) {
2030  htmlFileName = GetURL(libName);
2031  } else
2032  htmlFileName = "./";
2033 
2034  if (htmlFileName.Length()) {
2035  filename = htmlFileName;
2036  TString className(classPtr->GetName());
2037  TDocOutput output(*const_cast<THtml*>(this));
2038  output.NameSpace2FileName(className);
2039  gSystem->PrependPathName(filename, className);
2040  filename = className;
2041  filename.ReplaceAll("\\", "/");
2042  filename += ".html";
2043  } else filename.Remove(0);
2044 }
2045 
2046 ////////////////////////////////////////////////////////////////////////////////
2047 /// Get the html file name for a class named classname.
2048 /// Returns 0 if the class is not documented.
2049 
2050 const char* THtml::GetHtmlFileName(const char* classname) const
2051 {
2052  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(classname);
2053  if (cdi)
2054  return cdi->GetHtmlFileName();
2055  return 0;
2056 }
2057 
2058 ////////////////////////////////////////////////////////////////////////////////
2059 ///*-*-*-*-*Return pointer to class with name*-*-*-*-*-*-*-*-*-*-*-*-*
2060 ///*-* =================================
2061 
2062 TClass *THtml::GetClass(const char *name1) const
2063 {
2064  if(!name1 || !name1[0]) return 0;
2065  // no doc for internal classes
2066  if (strstr(name1,"ROOT::")==name1) {
2067  Bool_t ret = kTRUE;
2068  if (!strncmp(name1 + 6,"Math", 4)) ret = kFALSE;
2069  if (!strncmp(name1 + 6,"Reflex", 6)) ret = kFALSE;
2070  if (!strncmp(name1 + 6,"Cintex", 6)) ret = kFALSE;
2071  if (ret) return 0;
2072  }
2073 
2074  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(name1);
2075  if (!cdi) return 0;
2076  TClass *cl = dynamic_cast<TClass*>(cdi->GetClass());
2077  // hack to get rid of prec_stl types
2078  // TClassEdit checks are far too slow...
2079  /*
2080  if (cl && GetDeclFileName(cl) &&
2081  (strstr(GetDeclFileName(cl),"prec_stl/") || !strstr(classPtr->GetDeclFileName(), "include/c++/") )
2082  cl = 0;
2083  */
2084  TString declFileName;
2085  if (cl && GetDeclFileName(cl, kFALSE, declFileName))
2086  return cl;
2087  return 0;
2088 }
2089 
2090 ////////////////////////////////////////////////////////////////////////////////
2091 /// Return declaration file name; return the full path if filesys is true.
2092 
2093 bool THtml::GetDeclFileName(TClass * cl, Bool_t filesys, TString& out_name) const
2094 {
2095  return GetDeclImplFileName(cl, filesys, true, out_name);
2096 }
2097 
2098 ////////////////////////////////////////////////////////////////////////////////
2099 /// Return implementation file name
2100 
2101 bool THtml::GetImplFileName(TClass * cl, Bool_t filesys, TString& out_name) const
2102 {
2103  return GetDeclImplFileName(cl, filesys, false, out_name);
2104 }
2105 
2106 ////////////////////////////////////////////////////////////////////////////////
2107 /// Combined implementation for GetDeclFileName(), GetImplFileName():
2108 /// Return declaration / implementation file name (depending on decl);
2109 /// return the full path if filesys is true.
2110 
2111 bool THtml::GetDeclImplFileName(TClass * cl, bool filesys, bool decl, TString& out_name) const
2112 {
2113  out_name = "";
2114 
2115  R__LOCKGUARD(GetMakeClassMutex());
2116  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2117  // whether we need to determine the fil name
2118  bool determine = (!cdi); // no cdi
2119  if (!determine) determine |= decl && filesys && !cdi->GetDeclFileSysName()[0];
2120  if (!determine) determine |= decl && !filesys && !cdi->GetDeclFileName()[0];
2121  if (!determine) determine |= !decl && filesys && !cdi->GetImplFileSysName()[0];
2122  if (!determine) determine |= !decl && !filesys && !cdi->GetImplFileName()[0];
2123  if (determine) {
2124  TString name;
2125  TString sysname;
2126  if (decl) {
2127  if (!GetFileDefinition().GetDeclFileName(cl, name, sysname))
2128  return false;
2129  } else {
2130  if (!GetFileDefinition().GetImplFileName(cl, name, sysname))
2131  return false;
2132  }
2133  if (cdi) {
2134  if (decl) {
2135  if (!cdi->GetDeclFileName() || !cdi->GetDeclFileName()[0])
2136  cdi->SetDeclFileName(name);
2137  if (!cdi->GetDeclFileSysName() || !cdi->GetDeclFileSysName()[0])
2138  cdi->SetDeclFileSysName(sysname);
2139  } else {
2140  if (!cdi->GetImplFileName() || !cdi->GetImplFileName()[0])
2141  cdi->SetImplFileName(name);
2142  if (!cdi->GetImplFileSysName() || !cdi->GetImplFileSysName()[0])
2143  cdi->SetImplFileSysName(sysname);
2144  }
2145  }
2146 
2147  if (filesys) out_name = sysname;
2148  else out_name = name;
2149  return true;
2150  }
2151  if (filesys) {
2152  if (decl) out_name = cdi->GetDeclFileSysName();
2153  else out_name = cdi->GetImplFileSysName();
2154  } else {
2155  if (decl) out_name = cdi->GetDeclFileName();
2156  else out_name = cdi->GetImplFileName();
2157  }
2158  return true;
2159 }
2160 
2161 ////////////////////////////////////////////////////////////////////////////////
2162 /// Return the output directory as set by SetOutputDir().
2163 /// Create it if it doesn't exist and if createDir is kTRUE.
2164 
2165 const TString& THtml::GetOutputDir(Bool_t createDir /*= kTRUE*/) const
2166 {
2167  if (createDir) {
2168  R__LOCKGUARD(GetMakeClassMutex());
2169 
2170  gSystem->ExpandPathName(const_cast<THtml*>(this)->fPathInfo.fOutputDir);
2171  Long64_t sSize;
2172  Long_t sId, sFlags, sModtime;
2173  if (fPathInfo.fOutputDir.EndsWith("/") || fPathInfo.fOutputDir.EndsWith("\\"))
2174  fPathInfo.fOutputDir.Remove(fPathInfo.fOutputDir.Length() - 1);
2175  Int_t st = gSystem->GetPathInfo(fPathInfo.fOutputDir, &sId, &sSize, &sFlags, &sModtime);
2176  if (st || !(sFlags & 2)) {
2177  if (st == 0)
2178  Error("GetOutputDir", "output directory %s is an existing file",
2179  fPathInfo.fOutputDir.Data());
2180  else if (gSystem->MakeDirectory(fPathInfo.fOutputDir) == -1)
2181  Error("GetOutputDir", "output directory %s does not exist and can't create it", fPathInfo.fOutputDir.Data());
2182  }
2183  }
2184  return fPathInfo.fOutputDir;
2185 }
2186 
2187 ////////////////////////////////////////////////////////////////////////////////
2188 /// Check whether cl is a namespace
2189 
2191 {
2192  return (cl->Property() & kIsNamespace);
2193 }
2194 
2195 ////////////////////////////////////////////////////////////////////////////////
2196 /// Load all libraries known to ROOT via the rootmap system.
2197 
2199 {
2200  TEnv* mapfile = gInterpreter->GetMapfile();
2201  if (!mapfile || !mapfile->GetTable()) return;
2202 
2203  std::set<std::string> loadedlibs;
2204  std::set<std::string> failedlibs;
2205 
2206  TEnvRec* rec = 0;
2207  TIter iEnvRec(mapfile->GetTable());
2208  while ((rec = (TEnvRec*) iEnvRec())) {
2209  TString libs = rec->GetValue();
2210  TString lib;
2211  Ssiz_t pos = 0;
2212  while (libs.Tokenize(lib, pos)) {
2213  // check that none of the libs failed to load
2214  if (failedlibs.find(lib.Data()) != failedlibs.end()) {
2215  // don't load it or any of its dependencies
2216  libs = "";
2217  break;
2218  }
2219  }
2220  pos = 0;
2221  while (libs.Tokenize(lib, pos)) {
2222  // ignore libCore - it's already loaded
2223  if (lib.BeginsWith("libCore"))
2224  continue;
2225 
2226  if (loadedlibs.find(lib.Data()) == loadedlibs.end()) {
2227  // just load the first library - TSystem will do the rest.
2228  gSystem->Load(lib);
2229  loadedlibs.insert(lib.Data());
2230  }
2231  }
2232  }
2233 }
2234 
2235 
2236 ////////////////////////////////////////////////////////////////////////////////
2237 /// Produce documentation for all the classes specified in the filter (by default "*")
2238 /// To process all classes having a name starting with XX, do:
2239 /// html.MakeAll(kFALSE,"XX*");
2240 /// If force=kFALSE (default), only the classes that have been modified since
2241 /// the previous call to this function will be generated.
2242 /// If force=kTRUE, all classes passing the filter will be processed.
2243 /// If numthreads is != -1, use numthreads threads, else decide automatically
2244 /// based on the number of CPUs.
2245 
2246 void THtml::MakeAll(Bool_t force, const char *filter, int numthreads /*= -1*/)
2247 {
2248  MakeIndex(filter);
2249 
2250  if (numthreads == 1) {
2251  // CreateListOfClasses(filter); already done by MakeIndex
2252  TClassDocInfo* classinfo = 0;
2253  TIter iClassInfo(&fDocEntityInfo.fClasses);
2254  UInt_t count = 0;
2255 
2256  while ((classinfo = (TClassDocInfo*)iClassInfo())) {
2257  if (!classinfo->IsSelected())
2258  continue;
2259  fCounter.Form("%5d", fDocEntityInfo.fClasses.GetSize() - count++);
2260  MakeClass(classinfo, force);
2261  }
2262  } else {
2263  if (numthreads == -1) {
2264  SysInfo_t sysinfo;
2265  gSystem->GetSysInfo(&sysinfo);
2266  numthreads = sysinfo.fCpus;
2267  if (numthreads < 1)
2268  numthreads = 2;
2269  }
2270  fThreadedClassCount = 0;
2271  fThreadedClassIter = new TIter(&fDocEntityInfo.fClasses);
2272  THtmlThreadInfo hti(this, force);
2273  if (!fMakeClassMutex && gGlobalMutex) {
2274  gGlobalMutex->Lock();
2275  fMakeClassMutex = gGlobalMutex->Factory(kTRUE);
2276  gGlobalMutex->UnLock();
2277  }
2278 
2279  TList threads;
2280  gSystem->Load("libThread");
2281  while (--numthreads >= 0) {
2282  TThread* thread = new TThread(MakeClassThreaded, &hti);
2283  thread->Run();
2284  threads.Add(thread);
2285  }
2286 
2287  TIter iThread(&threads);
2288  TThread* thread = 0;
2289  Bool_t wait = kTRUE;
2290  while (wait) {
2291  while (wait && (thread = (TThread*) iThread()))
2292  wait &= (thread->GetState() == TThread::kRunningState);
2294  gSystem->Sleep(500);
2295  }
2296 
2297  iThread.Reset();
2298  while ((thread = (TThread*) iThread()))
2299  thread->Join();
2300  }
2301  fCounter.Remove(0);
2302 }
2303 
2304 
2305 ////////////////////////////////////////////////////////////////////////////////
2306 /// Make HTML files for a single class
2307 ///
2308 ///
2309 /// Input: className - name of the class to process
2310 ///
2311 
2312 void THtml::MakeClass(const char *className, Bool_t force)
2313 {
2314  CreateListOfClasses("*");
2315 
2316  TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(className);
2317  if (!cdi) {
2318  if (!TClassEdit::IsStdClass(className)) // stl classes won't be available, so no warning
2319  Error("MakeClass", "Unknown class '%s'!", className);
2320  return;
2321  }
2322 
2323  MakeClass(cdi, force);
2324 }
2325 
2326 ////////////////////////////////////////////////////////////////////////////////
2327 /// Make HTML files for a single class
2328 ///
2329 ///
2330 /// Input: cdi - doc info for class to process
2331 ///
2332 
2333 void THtml::MakeClass(void *cdi_void, Bool_t force)
2334 {
2335  if (!fDocEntityInfo.fClasses.GetSize())
2336  CreateListOfClasses("*");
2337 
2338  TClassDocInfo* cdi = (TClassDocInfo*) cdi_void;
2339  TClass* currentClass = dynamic_cast<TClass*>(cdi->GetClass());
2340 
2341  if (!currentClass) {
2342  if (!cdi->GetClass() &&
2343  !TClassEdit::IsStdClass(cdi->GetName())) // stl classes won't be available, so no warning
2344  Error("MakeClass", "Class '%s' is known, but I cannot find its TClass object!", cdi->GetName());
2345  return;
2346  }
2347  TString htmlFile(cdi->GetHtmlFileName());
2348  if (htmlFile.Length()
2349  && (htmlFile.BeginsWith("http://")
2350  || htmlFile.BeginsWith("https://")
2351  || gSystem->IsAbsoluteFileName(htmlFile))
2352  ) {
2353  htmlFile.Remove(0);
2354  }
2355  if (htmlFile.Length()) {
2356  TClassDocOutput cdo(*this, currentClass, &cdi->GetListOfTypedefs());
2357  cdo.Class2Html(force);
2358  cdo.MakeTree(force);
2359  } else {
2360  TString what(cdi->GetName());
2361  what += " (sources not found)";
2362  Printf(fCounterFormat.Data(), "-skipped-", fCounter.Data(), what.Data());
2363  }
2364 }
2365 
2366 
2367 ////////////////////////////////////////////////////////////////////////////////
2368 /// Entry point of worker threads for multi-threaded MakeAll().
2369 /// info points to an (internal) THtmlThreadInfo object containing the current
2370 /// THtml object, and whether "force" was passed to MakeAll().
2371 /// The thread will poll GetNextClass() until no further class is available.
2372 
2373 void* THtml::MakeClassThreaded(void* info) {
2374  const THtmlThreadInfo* hti = (const THtmlThreadInfo*)info;
2375  if (!hti) return 0;
2376  TClassDocInfo* classinfo = 0;
2377  while ((classinfo = hti->GetHtml()->GetNextClass()))
2378  hti->GetHtml()->MakeClass(classinfo, hti->GetForce());
2379 
2380  return 0;
2381 }
2382 
2383 ////////////////////////////////////////////////////////////////////////////////
2384 /// Create the index files for the product, modules, all types, etc.
2385 /// By default all classes are indexed (if filter="*");
2386 /// to generate an index for all classes starting with "XX", do
2387 /// html.MakeIndex("XX*");
2388 
2389 void THtml::MakeIndex(const char *filter)
2390 {
2391  CreateListOfClasses(filter);
2392 
2393  TDocOutput output(*this);
2394  // create indices
2395  output.CreateTypeIndex();
2396  output.CreateClassTypeDefs();
2397  output.CreateModuleIndex();
2398  output.CreateClassIndex();
2399  output.CreateProductIndex();
2400 
2401  // create a class hierarchy
2402  output.CreateHierarchy();
2403 }
2404 
2405 
2406 ////////////////////////////////////////////////////////////////////////////////
2407 /// Make an inheritance tree
2408 ///
2409 ///
2410 /// Input: className - name of the class to process
2411 ///
2412 
2413 void THtml::MakeTree(const char *className, Bool_t force)
2414 {
2415  // create canvas & set fill color
2416  TClass *classPtr = GetClass(className);
2417 
2418  if (!classPtr) {
2419  Error("MakeTree", "Unknown class '%s' !", className);
2420  return;
2421  }
2422 
2423  TClassDocOutput cdo(*this, classPtr, 0);
2424  cdo.MakeTree(force);
2425 }
2426 
2427 ////////////////////////////////////////////////////////////////////////////////
2428 /// Set whether "dot" (a GraphViz utility) is available
2429 
2431  if (found) fPathInfo.fFoundDot = PathInfo_t::kDotFound;
2432  else fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
2433 }
2434 
2435 ////////////////////////////////////////////////////////////////////////////////
2436 /// Fill the files available in the file system below fPathInfo.fInputPath
2437 
2439 {
2440  if (fLocalFiles) delete fLocalFiles;
2441  fLocalFiles = new TFileSysDB(fPathInfo.fInputPath, fPathInfo.fIgnorePath + "|(\\b" + GetOutputDir(kFALSE) + "\\b)" , 6);
2442 }
2443 
2444 ////////////////////////////////////////////////////////////////////////////////
2445 /// Set the module defining object to be used; can also be a user derived
2446 /// object (a la traits).
2447 
2449 {
2450  delete fModuleDef;
2451  fModuleDef = (TModuleDefinition*) md.Clone();
2452  fModuleDef->SetOwner(const_cast<THtml*>(this));
2453 }
2454 
2455 
2456 ////////////////////////////////////////////////////////////////////////////////
2457 /// Set the file defining object to be used; can also be a user derived
2458 /// object (a la traits).
2459 
2461 {
2462  delete fFileDef;
2463  fFileDef = (TFileDefinition*) md.Clone();
2464  fFileDef->SetOwner(const_cast<THtml*>(this));
2465 }
2466 
2467 
2468 ////////////////////////////////////////////////////////////////////////////////
2469 /// Set the path defining object to be used; can also be a user derived
2470 /// object (a la traits).
2471 
2473 {
2474  delete fPathDef;
2475  fPathDef = (TPathDefinition*) md.Clone();
2476  fPathDef->SetOwner(const_cast<THtml*>(this));
2477 }
2478 
2479 
2480 ////////////////////////////////////////////////////////////////////////////////
2481 /// Set the directory containing the source files.
2482 /// The source file for a class MyClass will be searched
2483 /// by prepending dir to the value of
2484 /// MyClass::Class()->GetImplFileName() - which can contain
2485 /// directory information!
2486 /// Also resets the class structure, in case new files can
2487 /// be found after this call.
2488 
2489 void THtml::SetInputDir(const char *dir)
2490 {
2491  fPathInfo.fInputPath = dir;
2492  gSystem->ExpandPathName(fPathInfo.fInputPath);
2493 
2494  // reset class table
2495  fDocEntityInfo.fClasses.Clear();
2496  fDocEntityInfo.fModules.Clear();
2497 }
2498 
2499 ////////////////////////////////////////////////////////////////////////////////
2500 /// Set the directory where the HTML pages shuold be written to.
2501 /// If the directory does not exist it will be created when needed.
2502 
2503 void THtml::SetOutputDir(const char *dir)
2504 {
2505  fPathInfo.fOutputDir = dir;
2506 #ifdef R__WIN32
2507  fPathInfo.fOutputDir.ReplaceAll("/","\\");
2508 #endif
2509 }
2510 
2511 ////////////////////////////////////////////////////////////////////////////////
2512 /// Explicitly set a decl file name for TClass cl.
2513 
2515 {
2516  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2517  if (!cdi) {
2518  cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, filename);
2519  fDocEntityInfo.fClasses.Add(cdi);
2520  } else
2521  cdi->SetDeclFileName(filename);
2522 }
2523 
2524 ////////////////////////////////////////////////////////////////////////////////
2525 /// Explicitly set a impl file name for TClass cl.
2526 
2528 {
2529  TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2530  if (!cdi) {
2531  cdi = new TClassDocInfo(cl, "" /*html*/, "" /*fsdecl*/, "" /*fsimpl*/, 0 /*decl*/, filename);
2532  fDocEntityInfo.fClasses.Add(cdi);
2533  } else
2534  cdi->SetImplFileName(filename);
2535 }
2536 
2537 ////////////////////////////////////////////////////////////////////////////////
2538 /// Get short type name, i.e. with default templates removed.
2539 
2540 const char* THtml::ShortType(const char* name) const
2541 {
2542  const char* tmplt = strchr(name, '<');
2543  if (!tmplt) return name;
2544  tmplt = strrchr(tmplt, ':');
2545  if (tmplt > name && tmplt[-1] == ':') {
2546  // work-around for CINT bug: template instantiation can produce bogus
2547  // typedefs e.g. in namespace ROOT::Math::ROOT::Math instead of ROOT::Math.
2548  TString namesp(name, tmplt - name - 1);
2549  // is the enclosing namespace known?
2550  if (!GetClass(namesp)) return name;
2551  }
2552  TObject* scn = fDocEntityInfo.fShortClassNames.FindObject(name);
2553  if (!scn) {
2554  scn = new TNamed(name, TClassEdit::ShortType(name, 1<<7));
2555  fDocEntityInfo.fShortClassNames.Add(scn);
2556  }
2557  return scn->GetTitle();
2558 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
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:1264
static Bool_t IsNamespace(const TClass *cl)
Check whether cl is a namespace.
Definition: THtml.cxx:2190
void MakeIndex(const char *filter="*")
Create the index files for the product, modules, all types, etc.
Definition: THtml.cxx:2389
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:85
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:945
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
Definition: TClass.cxx:3438
static void * MakeClassThreaded(void *info)
Entry point of worker threads for multi-threaded MakeAll().
Definition: THtml.cxx:2373
An array of TObjects.
Definition: TObjArray.h:39
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:420
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:2101
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:1402
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:1316
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:513
const char * GetImplFileName() const
Definition: TClass.h:408
virtual void CreateJavascript() const
Write the default ROOT style sheet.
Definition: THtml.cxx:1930
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:138
TClass * GetClassPointer(Bool_t load=kTRUE)
Get pointer to the base class TClass.
Definition: TBaseClass.cxx:62
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:1362
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:821
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:2198
static const char * filename()
#define gROOT
Definition: TROOT.h:352
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:3425
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1817
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:1254
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:1088
TString & GetMacroPath()
Definition: TROOT.cxx:379
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
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:468
Bool_t IsSelected() const
Definition: TDocInfo.h:71
virtual const char * GetSoExt() const
Get the shared library extension.
Definition: TSystem.cxx:3792
#define gInterpreter
Definition: TInterpreter.h:502
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:1510
virtual bool GetDeclImplFileName(TClass *cl, bool filesys, bool decl, TString &out_name) const
Combined implementation for GetDeclFileName(), GetImplFileName(): Return declaration / implementation...
Definition: THtml.cxx:2111
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:2246
void MakeTree(const char *className, Bool_t force=kFALSE)
Make an inheritance tree.
Definition: THtml.cxx:2413
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:2514
void SetOutputDir(const char *dir)
Set the directory where the HTML pages shuold be written to.
Definition: THtml.cxx:2503
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:1949
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:136
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1500
virtual void CreateStyleSheet() const
Write the default ROOT style sheet.
Definition: THtml.cxx:1937
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:770
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:2527
void MakeClass(const char *className, Bool_t force=kFALSE)
Make HTML files for a single class.
Definition: THtml.cxx:2312
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:847
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:2334
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:2399
virtual const char * GetEtcDir() const
Get the directory containing THtml&#39;s auxiliary files ($ROOTSYS/etc/html)
Definition: THtml.cxx:1343
virtual void CreateAuxiliaryFiles() const
copy CSS, javascript file, etc to the output dir
Definition: THtml.cxx:1290
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:441
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:1544
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:1054
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:2220
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:2438
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:466
void HelperDeleted(THelperBase *who)
Inform the THtml object that one of its helper objects was deleted.
Definition: THtml.cxx:1429
Int_t Run(void *arg=0)
Start the thread.
Definition: TThread.cxx:551
virtual void GetModuleNameForClass(TString &module, TClass *cl) const
Return the module name for a given class.
Definition: THtml.cxx:1529
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:379
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:171
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:480
const TModuleDefinition & GetModuleDefinition() const
Return the TModuleDefinition (or derived) object as set by SetModuleDefinition(); create and return a...
Definition: THtml.cxx:1302
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:2540
const char * GetURL(const char *lib=0) const
Get the documentation URL for library lib.
Definition: THtml.cxx:1386
const TString & GetOutputDir(Bool_t createDir=kTRUE) const
Return the output directory as set by SetOutputDir().
Definition: THtml.cxx:2165
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:498
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:657
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:1461
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:4568
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:2093
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5641
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:2460
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:839
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:1890
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
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
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:1921
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:864
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
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2601
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:75
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:1900
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:1986
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:2871
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:348
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:2472
void SetFoundDot(Bool_t found=kTRUE)
Set whether "dot" (a GraphViz utility) is available.
Definition: THtml.cxx:2430
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:704
#define name(a, b)
Definition: linkTestLib0.cpp:5
Mother of all ROOT objects.
Definition: TObject.h:58
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
Definition: TObject.cxx:203
virtual TClass * GetClass(const char *name) const
*-*-*-*-*Return pointer to class with name*-*-*-*-*-*-*-*-*-*-*-*-* *-* =============================...
Definition: THtml.cxx:2062
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:459
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:709
void SetInputDir(const char *dir)
Set the directory containing the source files.
Definition: THtml.cxx:2489
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition: TROOT.cxx:2559
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
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:1309
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:830
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:2448
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1242
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
static void output(int code)
Definition: gifencode.c:226
const TPathDefinition & GetPathDefinition() const
Return the TModuleDefinition (or derived) object as set by SetModuleDefinition(); create and return a...
Definition: THtml.cxx:1330
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
module
Definition: ROOT.py:93
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1044
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:1274
Definition: THtml.h:44
gr SetName("gr")
void SetDeclFileName(const char *name)
Definition: TDocInfo.h:76
TClassDocInfo * GetNextClass()
Return the next class to be generated for MakeClassThreaded.
Definition: THtml.cxx:1360
void SetModule(TModuleDocInfo *module)
Definition: TDocInfo.h:67
const char * Data() const
Definition: TString.h:349