13 #include "RConfigure.h"
43 class THtmlThreadInfo {
45 THtmlThreadInfo(THtml* html,
bool force): fHtml(html), fForce(force) {}
46 Bool_t GetForce()
const {
return fForce;}
47 THtml* GetHtml()
const {
return fHtml;}
60 THtml::THelperBase::~THelperBase()
63 fHtml->HelperDeleted(
this);
73 void THtml::THelperBase::SetOwner(THtml* html) {
74 if (fHtml && html && html != fHtml) {
75 Error(
"SetOwner()",
"Object already owned by an THtml instance!");
76 fHtml->HelperDeleted(
this);
103 bool THtml::TModuleDefinition::GetModule(TClass* cl, TFileSysEntry* fse,
104 TString& out_modulename)
const
106 out_modulename =
"USER";
107 if (!cl)
return false;
111 if (fse) fse->GetFullName(filename, kFALSE);
113 if (!GetOwner()->GetImplFileName(cl, kFALSE, filename))
114 if (!GetOwner()->GetDeclFileName(cl, kFALSE, filename))
117 TString inputdir = GetOwner()->GetInputPath();
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());
134 out_modulename = gSystem->DirName(filename);
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);
144 if (!out_modulename[0])
145 out_modulename = trailingInclude;
147 if (!out_modulename[0])
148 out_modulename = trailingInclude;
151 if (out_modulename.EndsWith(
"/src")
152 || out_modulename.EndsWith(
"/inc"))
153 out_modulename.Remove(out_modulename.Length() - 4, 4);
156 Ssiz_t pos = out_modulename.Index(
"/src/");
158 pos = out_modulename.Index(
"/inc/");
160 out_modulename.Remove(pos);
163 while (out_modulename.EndsWith(
"/"))
164 out_modulename.Remove(out_modulename.Length() - 1);
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";
180 out_modulename = cl->GetSharedLibs();
181 Ssiz_t pos = out_modulename.Index(
' ');
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(
'.');
188 out_modulename.Remove(pos, out_modulename.Length());
190 if (!out_modulename.Length()) {
191 out_modulename =
"USER";
205 void THtml::TFileDefinition::ExpandSearchPath(TString& path)
const
207 THtml* owner = GetOwner();
211 TString inputdir = owner->GetInputPath();
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);
220 if (path.BeginsWith(tok))
221 pathext += GetDirDelimiter() + path;
223 pathext += GetDirDelimiter() + tok +
"/" + path;
233 void THtml::TFileDefinition::SplitClassIntoDirFile(
const TString& clname, TString& dir,
234 TString& filename)
const
240 while (clname.Tokenize(token, from,
"::") ) {
261 bool THtml::TFileDefinition::GetDeclFileName(
const TClass* cl, TString& out_filename,
262 TString& out_fsys, TFileSysEntry** fse)
const
264 return GetFileName(cl,
true, out_filename, out_fsys, fse);
278 bool THtml::TFileDefinition::GetImplFileName(
const TClass* cl, TString& out_filename,
279 TString& out_fsys, TFileSysEntry** fse)
const
281 return GetFileName(cl,
false, out_filename, out_fsys, fse);
288 void THtml::TFileDefinition::NormalizePath(TString& filename)
const
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)) {}
297 if (filename.BeginsWith(
"./") || filename.BeginsWith(
".\\"))
298 filename.Remove(0,2);
307 TString THtml::TFileDefinition::MatchFileSysName(TString& filename, TFileSysEntry** fse)
const
309 const TList* bucket = GetOwner()->GetLocalFiles()->GetEntries().GetListForObject(gSystem->BaseName(filename));
313 TFileSysEntry* fsentry = 0;
314 while ((fsentry = (TFileSysEntry*) iFS())) {
315 if (!filename.EndsWith(fsentry->GetName()))
317 fsentry->GetFullName(filesysname, kTRUE);
318 filename = filesysname;
319 if (!filename.EndsWith(filesysname)) {
325 fsentry->GetFullName(filesysname, kFALSE);
326 if (fse) *fse = fsentry;
337 bool THtml::TFileDefinition::GetFileName(
const TClass* cl,
bool decl,
338 TString& out_filename, TString& out_fsys,
339 TFileSysEntry** fse)
const
348 TString possibleFileName;
349 TString possiblePath;
352 TString clfile = decl ? cl->GetDeclFileName() : cl->GetImplFileName();
353 NormalizePath(clfile);
355 out_filename = clfile;
356 if (clfile.Length()) {
362 if (clfile ==
"include/TMathBase.h") {
363 clfile =
"math/mathcore/inc/TMath.h";
364 out_filename = clfile;
368 TString inclPath(GetOwner()->GetPathInfo().fIncludePath);
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();
375 if (longestMatch != kNPOS) {
376 clfile.Remove(0, longestMatch);
377 if (clfile.BeginsWith(
"/") || clfile.BeginsWith(
"\\"))
379 TString asincl(clfile);
380 GetOwner()->GetPathDefinition().GetFileNameFromInclude(asincl, clfile);
381 out_filename = clfile;
384 filesysname = MatchFileSysName(out_filename, fse);
385 if (filesysname[0]) {
386 clfile = out_filename;
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] ==
'>')
398 else if (filesysname[start] ==
'<') {
404 filesysname = filesysname(start + 1, end - start - 1);
408 filesysname +=
".cxx";
409 out_filename = filesysname;
410 filesysname = MatchFileSysName(out_filename, fse);
411 if (filesysname[0]) {
412 clfile = out_filename;
416 if (!decl && !clfile.Length()) {
420 TString declSysFileName;
421 if (GetFileName(cl,
true, filesysname, declSysFileName)) {
422 filesysname = gSystem->BaseName(filesysname);
423 Ssiz_t posExt = filesysname.Last(
'.');
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;
435 if (clfile.Length() && !decl) {
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])) {
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)) {
460 if (!clfile.Length()) {
464 out_filename = cl->GetName();
465 if (!out_filename.Contains(
"::")) {
469 SplitClassIntoDirFile(out_filename, possiblePath, possibleFileName);
472 if (possibleFileName.Length()) {
474 possibleFileName +=
".h";
476 possibleFileName +=
".cxx";
478 if (possiblePath.Length())
481 possiblePath +=
"inc/";
483 possiblePath +=
"src/";
484 out_filename = possiblePath +
"/" + possibleFileName;
486 possiblePath = gSystem->DirName(clfile);
487 possibleFileName = gSystem->BaseName(clfile);
490 if (possiblePath.Length())
491 ExpandSearchPath(possiblePath);
492 else possiblePath=
".";
494 out_fsys = gSystem->FindFile(possiblePath, possibleFileName, kReadPermission);
495 if (out_fsys.Length()) {
496 NormalizePath(out_fsys);
512 bool THtml::TPathDefinition::GetMacroPath(
const TString& module, TString& out_dir)
const
515 if (!GetDocDir(module, moduledoc))
517 if (moduledoc.EndsWith(
"\\"))
518 moduledoc.Remove(moduledoc.Length() - 1);
520 TString macropath(GetOwner()->GetMacroPath());
521 TString macrodirpart;
524 while (macropath.Tokenize(macrodirpart, pos,
":")) {
525 out_dir += moduledoc +
"/" + macrodirpart +
":";
541 bool THtml::TPathDefinition::GetDocDir(
const TString& module, TString& doc_dir)
const
544 if (GetOwner()->GetProductName() ==
"ROOT") {
545 doc_dir =
"$ROOTSYS";
546 gSystem->ExpandPathName(doc_dir);
551 doc_dir += module +
"/";
552 doc_dir += GetOwner()->GetPathInfo().fDocPath;
571 bool THtml::TPathDefinition::GetIncludeAs(TClass* cl, TString& out_dir)
const
574 if (!cl || !GetOwner())
return false;
577 if (!GetOwner()->GetDeclFileName(cl, kFALSE, hdr))
581 bool includePathMatches =
false;
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;
592 if (!includePathMatches) {
600 Ssiz_t posInc = hdr.Index(
"/inc/");
601 if (posInc == kNPOS)
return true;
602 hdr.Remove(0, posInc + 5);
606 return (out_dir.Length());
620 bool THtml::TPathDefinition::GetFileNameFromInclude(
const char* included, TString& out_fsname)
const
622 if (!included)
return false;
624 out_fsname = included;
626 TString incBase(gSystem->BaseName(included));
627 const TList* bucket = GetOwner()->GetLocalFiles()->GetEntries().GetListForObject(incBase);
628 if (!bucket)
return false;
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;
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 ==
".")
642 if (subdir == parent->GetName())
643 parent = parent->GetParent();
648 entry->GetFullName(out_fsname, kFALSE);
660 void THtml::TFileSysDir::Recurse(TFileSysDB* db,
const char* path)
663 if (gDebug > 0 || GetLevel() < 2)
664 Info(
"Recurse",
"scanning %s...", path);
665 TPMERegexp regexp(db->GetIgnore());
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))
675 if (!gSystem->GetPathInfo(entryPath, buf)) {
676 if (R_ISDIR(buf.fMode)) {
678 if (GetLevel() > db->GetMaxLevel()
680 || db->GetMapIno().GetValue(buf.fIno)
683 TFileSysDir* subdir =
new TFileSysDir(direntry,
this);
686 db->GetMapIno().Add(buf.fIno, (Long_t)subdir);
688 subdir->Recurse(db, entryPath);
690 int delen = strlen(direntry);
692 if (strcmp(direntry + delen - 4,
".cxx")
693 && strcmp(direntry + delen - 2,
".h")
694 && strcmp(direntry + delen - 4,
".hxx"))
696 TFileSysEntry* entry =
new TFileSysEntry(direntry,
this);
697 db->GetEntries().Add(entry);
702 gSystem->FreeDirectory(hDir);
710 void THtml::TFileSysDB::Fill()
714 while (fName.Tokenize(dir, posPath, THtml::GetDirDelimiter())) {
715 gSystem->ExpandPathName(dir);
716 if (gSystem->AccessPathName(dir, kReadPermission)) {
717 Warning(
"Fill",
"Cannot read InputPath \"%s\"!", dir.Data());
721 if (!gSystem->GetPathInfo(dir, buf) && R_ISDIR(buf.fMode)) {
723 TFileSysRoot* prevroot = (TFileSysRoot*) (Long_t)GetMapIno().GetValue(buf.fIno);
725 Warning(
"Fill",
"InputPath \"%s\" already present as \"%s\"!", dir.Data(), prevroot->GetName());
729 TFileSysRoot* root =
new TFileSysRoot(dir,
this);
732 GetMapIno().Add(buf.fIno, (Long_t)root);
734 root->Recurse(
this, dir);
736 Warning(
"Fill",
"Cannot read InputPath \"%s\"!", dir.Data());
999 // This is the description block. //
1003 <p>The environment variable Root.Html.Description
1004 (see: <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>) contains
1005 the delimiter string (default value: <tt>//_________________</tt>). It means
1006 that you can also write your class description block like this:</p>
1008 //_____________________________________________________________
1009 // A description of the class starts with the line above, and
1010 // will take place here !
1013 <p>Note that <b><i>everything</i></b> until the first non-commented line is considered
1014 as a valid class description block.</p>
1016 <h4><a name="syntax:classidx">III.2 Class index</a></h4>
1018 <p>All classes to be documented will have an entry in the ClassIndex.html,
1019 showing their name with a link to their documentation page and a miniature
1020 description. This discription for e.g. the class MyClass has to be given
1021 in MyClass's header as a comment right after ClassDef(MyClass, n).</p>
1023 <h4><a name="syntax:meth">III.3 Method documentation</a></h4>
1024 <p>A member function description block starts immediately after '{'
1025 and looks like this:</p>
1027 void TWorld::HelloWorldFunc(string *text)
1029 // This is an example of description for the
1030 // TWorld member function
1032 helloWorld.Print( text );
1035 Like in a class description block, <b><i>everything</i></b> until the first
1036 non-commented line is considered as a valid member function
1039 If the rootrc variable <tt>Root.Html.DescriptionStyle</tt> is set to
1040 <tt>Doc++</tt> THtml will also look for method documentation in front of
1041 the function implementation. This feature is not recommended; source code
1042 making use of this does not comply to the ROOT documentation standards, which
1043 means future versions of THtml might not support it anymore.
1045 <h4><a name="syntax:datamem">III.4 Data member documentation</a></h4>
1047 <p>Data members are documented by putting a C++ comment behind their
1048 declaration in the header file, e.g.</p>
1050 int fIAmADataMember; // this is a data member
1054 <h3><a name="directive">IV. Documentation directives</a></h3>
1055 <em>NOTE that THtml does not yet support nested directives
1056 (i.e. latex inside html etc)!</em>
1058 <h4><a name="directive:html">IV.1 <tt>BEGIN<!-- -->_HTML</tt> <tt>END<!-- -->_HTML</tt>: include 'raw' HTML</a></h4>
1060 <p>You can insert pure html code into your documentation comments. During the
1061 generation of the documentation, this code will be inserted as is
1062 into the html file.</p>
1063 <p>Pure html code must be surrounded by the keywords
1064 <tt>BEGIN<!-- -->_HTML</tt> and <tt>END<!-- -->_HTML</tt>, where the
1066 An example of pure html code is this class description you are reading right now.
1068 <a href="http://root.cern.ch/root/html/TDocHtmlDirective.html">TDocHtmlDirective</a>
1069 object to process this directive.</p>
1071 <h4><a name="directive:macro">IV.2 <tt>BEGIN<!-- -->_MACRO</tt> <tt>END<!-- -->_MACRO</tt>: include a picture generated by a macro</a></h4>
1073 <p>THtml can create images from scripts. You can either call an external
1074 script by surrounding it by "begin_macro"/"end_macro", or include an unnamed
1075 macro within these keywords. The macro should return a pointer to an object;
1076 this object will then be saved as a GIF file.</p>
1077 <p>Objects deriving from
1078 <a href="http://root.cern.ch/root/html/TGObject.html">TGObject</a> (GUI elements)
1079 will need to run in graphics mode (non-batch). You must specify this as a parameter:
1080 "Begin_macro(GUI)...".
1081 To create a second tab that displays the source of the macro you can specify
1082 the argument "Begin_macro(source)...".
1083 Of course you can combine them,
1084 e.g. as "Begin_macro(source,gui)...".
1086 <a href="http://root.cern.ch/root/html/TDocMacroDirective.html">TDocMacroDirective</a>
1087 object to process this directive.</p>
1088 <p>This is an example:</p> END_HTML
1091 TCanvas* macro_example_canvas = new TCanvas("macro_example_canvas", "", 150, 150);
1092 macro_example_canvas->SetBorderSize(0);
1093 macro_example_canvas->SetFillStyle(1001);
1094 macro_example_canvas->SetFillColor(kWhite);
1095 macro_example_canvas->cd();
1096 TArc* macro_example_arc = new TArc(0.5,0.32,0.11,180,360);
1097 macro_example_arc->Draw();
1098 TEllipse* macro_example_ellipsis = new TEllipse(0.42,0.58,0.014,0.014,0,360,0);
1099 macro_example_ellipsis->SetFillStyle(0);
1100 macro_example_ellipsis->Draw();
1101 macro_example_ellipsis = new TEllipse(0.58,0.58,0.014,0.014,0,360,0);
1102 macro_example_ellipsis->SetFillStyle(0);
1103 macro_example_ellipsis->Draw();
1104 macro_example_ellipsis = new TEllipse(0.50,0.48,0.22,0.32,0,360,0);
1105 macro_example_ellipsis->SetFillStyle(0);
1106 macro_example_ellipsis->Draw();
1107 TLine* macro_example_line = new TLine(0.48,0.53,0.52,0.41);
1108 macro_example_line->Draw();
1109 return macro_example_canvas;
1114 <h4><a name="directive:latex">IV.3 <tt>BEGIN<!-- -->_LATEX</tt> <tt>END<!-- -->_LATEX</tt>: include a latex picture</a></h4>
1116 <p>You can specify <a href="http://root.cern.ch/root/html/TLatex.html">TLatex</a>
1117 style text and let THtml convert it into an image by surrounding it by "Begin_Latex", "End_Latex".
1118 You can have multiple lines, and e.g. align each line at the '=' sign by passing
1119 the argument <tt>separator='='</tt>. You can also specify how to align these parts;
1120 if you want the part left of the separator to be right aligned, and the right part
1121 to be left aligned, you could specify <tt>align='rl'</tt>.
1122 THtml uses a <a href="http://root.cern.ch/root/html/TDocLatexDirective.html">TDocLatexDirective</a>
1123 object to process the directive.
1124 This is an example output with arguments <tt>separator='=', align='rl'</tt>:</p>
1125 END_HTML BEGIN_LATEX(separator='=', align='rl')#kappa(x)^{2}=sin(x)^{x}
1126 x=#chi^{2} END_LATEX
1130 <h3><a name="index">V. Product and module index</a></h3>
1132 <p><a href="#THtml:MakeIndex">THtml::MakeIndex()</a> will generate index files for classes
1133 and types, all modules, and the product which you can set by
1134 <a href="#THtml:SetProductName">THtml::SetProductName()</a>.
1135 THtml will make use of external documentation in the module and product index,
1136 either by linking it or by including it.
1137 The files for modules are searched based on the source file directory of the
1138 module's classes.</p>
1140 <p>A filename starting with "index." will be included in the index page;
1141 all other files will be linked.
1142 Only files ending on <tt>.html</tt> or <tt>.txt</tt> will be taken into account;
1143 the text files will first be run through
1144 <a href="#THtml:Convert">THtml::Convert()</a>.
1145 You can see an example <a href="http://root.cern.ch/root/html/HIST_Index.html">here</a>;
1146 the part between "Index of HIST classes" and "Jump to" is created by parsing
1147 the module's doc directory.</p>
1149 <h3><a name="aux">VI. Auxiliary files: style sheet, JavaScript, help page</a></h3>
1151 <p>The documentation pages share a common set of javascript and CSS files. They
1152 are generated automatically when running <a href="#THtml:MakeAll">MakeAll()</a>;
1153 they can be generated on
1154 demand by calling <a href="#THtml:CreateAuxiliaryFiles">CreateAuxiliaryFiles()</a>.</p>
1157 <h3><a name="charts">VII. Class Charts</a></h3>
1158 THtml can generate a number of graphical representations for a class, which
1159 are displayed as a tabbed set of imaged ontop of the class description.
1160 It can show the inheritance, inherited and hidden members, directly and
1161 indirectly included files, and library dependencies.
1163 These graphs are generated using the <a href="http://www.graphviz.org/">Graphviz</a>
1164 package. You can install it from <a href="http://www.graphviz.org">http://www.graphviz.org</a>.
1165 You can either put it into your $PATH, or tell THtml where to find it by calling
1166 <a href="#THtml:SetDotDir">SetDotDir()</a>.
1169 <h3><a name="confvar">VIII. Configuration variables</a></h3>
1171 <p>Here is a list of all configuration variables that are known to THtml.
1172 You can set them in your .rootrc file, see
1173 <a href="http://root.cern.ch/root/html/TEnv.html">TEnv</a>.</p>
1176 Root.Html.OutputDir (default: htmldoc)
1177 Root.Html.SourceDir (default: .:src/:include/)
1178 Root.Html.Author (default: // Author:) - start tag for authors
1179 Root.Html.LastUpdate (default: // @(#)) - start tag for last update
1180 Root.Html.Copyright (default: * Copyright) - start tag for copyright notice
1181 Root.Html.Description (default: //____________________ ) - start tag for class descr
1182 Root.Html.HomePage (default: ) - URL to the user defined home page
1183 Root.Html.Header (default: ) - location of user defined header
1184 Root.Html.Footer (default: ) - location of user defined footer
1185 Root.Html.Root (default: ) - URL of Root's class documentation
1186 Root.Html.SearchEngine (default: ) - link to the search engine
1187 Root.Html.Search (defualt: ) - link to search by replacing "%s" with user input
1188 Root.Html.ViewCVS (default: ) - URL of ViewCVS base
1189 Root.Html.XWho (default: http://consult.cern.ch/xwho/people?) - URL of CERN's xWho
1190 Root.Html.Charset (default: ISO-8859-1) - HTML character set
1193 <h3><a name="how">IX. Behind the scene</a></h3>
1195 <p>Internally, THtml is just an API class that sets up the list of known
1196 classes, and forwards API invocations to the "work horses".
1197 <a href="http://root.cern.ch/root/html/TDocOutput.html">TDocOutput</a>
1198 generates the output by letting a
1199 <a href="http://root.cern.ch/root/html/TDocParser.html">TDocParser</a>
1200 object parse the sources, which in turn invokes objects deriving from
1201 <a href="http://root.cern.ch/root/html/TDocDirective.html">TDocDirective</a>
1202 to process directives.</p>
1214 fCounterFormat(
"%12s %5s %s"),
1215 fProductName(
"(UNKNOWN PRODUCT)"),
1216 fThreadedClassIter(0), fThreadedClassCount(0), fMakeClassMutex(0),
1217 fGClient(0), fPathDef(0), fModuleDef(0), fFileDef(0),
1218 fLocalFiles(0), fBatch(kFALSE)
1221 fPathInfo.fInputPath = gEnv->GetValue(
"Root.Html.SourceDir",
"./:src/:include/");
1224 SetOutputDir(gEnv->GetValue(
"Root.Html.OutputDir",
"htmldoc"));
1226 fLinkInfo.fXwho = gEnv->GetValue(
"Root.Html.XWho",
"http://consult.cern.ch/xwho/people?");
1227 fLinkInfo.fROOTURL = gEnv->GetValue(
"Root.Html.Root",
"http://root.cern.ch/root/html");
1228 fDocSyntax.fClassDocTag = gEnv->GetValue(
"Root.Html.Description",
"//____________________");
1229 fDocSyntax.fAuthorTag = gEnv->GetValue(
"Root.Html.Author",
"// Author:");
1230 fDocSyntax.fLastUpdateTag = gEnv->GetValue(
"Root.Html.LastUpdate",
"// @(#)");
1231 fDocSyntax.fCopyrightTag = gEnv->GetValue(
"Root.Html.Copyright",
"* Copyright");
1232 fOutputStyle.fHeader = gEnv->GetValue(
"Root.Html.Header",
"");
1233 fOutputStyle.fFooter = gEnv->GetValue(
"Root.Html.Footer",
"");
1234 fLinkInfo.fHomepage = gEnv->GetValue(
"Root.Html.Homepage",
"");
1235 fLinkInfo.fSearchStemURL = gEnv->GetValue(
"Root.Html.Search",
"");
1236 fLinkInfo.fSearchEngine = gEnv->GetValue(
"Root.Html.SearchEngine",
"");
1237 fLinkInfo.fViewCVS = gEnv->GetValue(
"Root.Html.ViewCVS",
"");
1238 fOutputStyle.fCharset = gEnv->GetValue(
"Root.Html.Charset",
"ISO-8859-1");
1239 fDocSyntax.fDocStyle = gEnv->GetValue(
"Root.Html.DescriptionStyle",
"");
1241 fDocEntityInfo.fClasses.SetOwner();
1242 fDocEntityInfo.fModules.SetOwner();
1246 gROOT->GetListOfSpecials()->Add(gHtml);
1257 fDocEntityInfo.fClasses.Clear();
1258 fDocEntityInfo.fModules.Clear();
1259 if (gHtml ==
this) {
1260 gROOT->GetListOfSpecials()->Remove(gHtml);
1275 void THtml::AddMacroPath(
const char* path)
1277 const char pathDelimiter =
1283 fPathInfo.fMacroPath += pathDelimiter;
1284 fPathInfo.fMacroPath += path;
1291 void THtml::CreateAuxiliaryFiles()
const
1295 CopyFileFromEtcDir(
"HELP.html");
1303 const THtml::TModuleDefinition& THtml::GetModuleDefinition()
const
1306 fModuleDef =
new TModuleDefinition();
1307 fModuleDef->SetOwner(const_cast<THtml*>(
this));
1317 const THtml::TFileDefinition& THtml::GetFileDefinition()
const
1320 fFileDef =
new TFileDefinition();
1321 fFileDef->SetOwner(const_cast<THtml*>(
this));
1331 const THtml::TPathDefinition& THtml::GetPathDefinition()
const
1334 fPathDef =
new TPathDefinition();
1335 fPathDef->SetOwner(const_cast<THtml*>(
this));
1344 const char* THtml::GetEtcDir()
const
1346 if (fPathInfo.fEtcDir.Length())
1347 return fPathInfo.fEtcDir;
1349 R__LOCKGUARD(GetMakeClassMutex());
1351 fPathInfo.fEtcDir =
"html";
1352 gSystem->PrependPathName(TROOT::GetEtcDir(), fPathInfo.fEtcDir);
1354 return fPathInfo.fEtcDir;
1361 TClassDocInfo *THtml::GetNextClass()
1363 if (!fThreadedClassIter)
return 0;
1365 R__LOCKGUARD(GetMakeClassMutex());
1367 TClassDocInfo* classinfo = 0;
1368 while ((classinfo = (TClassDocInfo*)(*fThreadedClassIter)())
1369 && !classinfo->IsSelected()) { }
1372 delete fThreadedClassIter;
1373 fThreadedClassIter = 0;
1376 fCounter.Form(
"%5d", fDocEntityInfo.fClasses.GetSize() - fThreadedClassCount++);
1387 const char* THtml::GetURL(
const char* lib )
const
1389 R__LOCKGUARD(GetMakeClassMutex());
1391 if (lib && strlen(lib)) {
1392 std::map<std::string, TString>::const_iterator iUrl = fLinkInfo.fLibURLs.find(lib);
1393 if (iUrl != fLinkInfo.fLibURLs.end())
return iUrl->second;
1394 return gEnv->GetValue(TString(
"Root.Html.") + lib, fLinkInfo.fROOTURL);
1396 return fLinkInfo.fROOTURL;
1403 Bool_t THtml::HaveDot()
1405 if (fPathInfo.fFoundDot != PathInfo_t::kDotUnknown)
1406 return (fPathInfo.fFoundDot == PathInfo_t::kDotFound);
1408 R__LOCKGUARD(GetMakeClassMutex());
1410 Info(
"HaveDot",
"Checking for Graphviz (dot)...");
1411 TString runDot(
"dot");
1412 if (fPathInfo.fDotDir.Length())
1413 gSystem->PrependPathName(fPathInfo.fDotDir, runDot);
1416 Info(
"HaveDot",
"Running: %s", runDot.Data());
1417 if (gSystem->Exec(runDot)) {
1418 fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
1421 fPathInfo.fFoundDot = PathInfo_t::kDotFound;
1430 void THtml::HelperDeleted(THtml::THelperBase* who)
1432 THelperBase* helpers[3] = {fPathDef, fModuleDef, fFileDef};
1433 for (
int i = 0; who && i < 3; ++i)
1434 if (who == helpers[i])
1435 helpers[i] = who = 0;
1462 void THtml::Convert(
const char *filename,
const char *title,
1463 const char *dirname ,
const char *relpath ,
1464 Int_t includeOutput ,
1465 const char* context )
1467 gROOT->GetListOfGlobals(kTRUE);
1468 CreateListOfClasses(
"*");
1474 gSystem->ExpandPathName(fPathInfo.fOutputDir);
1475 dir = gSystem->ConcatFileName(fPathInfo.fOutputDir,
"examples");
1480 if (gSystem->AccessPathName(dir))
1481 gSystem->MakeDirectory(dir);
1484 char *cRealFilename =
1485 gSystem->Which(fPathInfo.fInputPath, filename, kReadPermission);
1487 if (!cRealFilename) {
1488 Error(
"Convert",
"Can't find file '%s' !", filename);
1492 TString realFilename(cRealFilename);
1493 delete[] cRealFilename;
1497 std::ifstream sourceFile;
1498 sourceFile.open(realFilename, std::ios::in);
1500 if (!sourceFile.good()) {
1501 Error(
"Convert",
"Can't open file '%s' !", realFilename.Data());
1505 if (gSystem->AccessPathName(dir)) {
1507 "Directory '%s' doesn't exist, or it's write protected !", dir);
1511 gSystem->ConcatFileName(dir, gSystem->BaseName(filename));
1513 TDocOutput output(*
this);
1515 gROOT->ProcessLine(TString::Format(
"*((TGClient**)0x%lx) = gClient;",
1516 (ULong_t)&fGClient));
1517 if (includeOutput && !fGClient)
1518 Warning(
"Convert",
"Output requested but cannot initialize graphics: GUI and GL windows not be available");
1519 output.Convert(sourceFile, realFilename, tmp1, title, relpath, includeOutput, context, fGClient);
1530 void THtml::GetModuleNameForClass(TString& module, TClass* cl)
const
1532 module =
"(UNKNOWN)";
1535 TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(cl->GetName());
1536 if (!cdi || !cdi->GetModule())
1538 module = cdi->GetModule()->GetName();
1545 void THtml::CreateListOfClasses(
const char* filter)
1547 if (fDocEntityInfo.fClasses.GetSize() && fDocEntityInfo.fClassFilter == filter)
1550 Info(
"CreateListOfClasses",
"Initializing - this might take a while...");
1552 Int_t totalNumberOfClasses = gClassTable->Classes();
1555 fDocEntityInfo.fClasses.Clear();
1556 fDocEntityInfo.fModules.Clear();
1558 fDocEntityInfo.fClassFilter = filter;
1561 gClassTable->Init();
1562 if (filter && (!filter[0] || !strcmp(filter,
"*")))
1564 TString reg = filter;
1567 bool skipROOTClasses =
false;
1568 std::set<std::string> rootLibs;
1569 TList classesDeclFileNotFound;
1570 TList classesImplFileNotFound;
1573 for (Int_t i = -1; i < totalNumberOfClasses; i++) {
1576 const char *cname = 0;
1577 if (i < 0) cname =
"TObject";
1578 else cname = gClassTable->Next();
1582 if (i >= 0 && !strcmp(cname,
"TObject")) {
1588 if (strstr(cname,
"__gnu_cxx::"))
continue;
1590 if (!strcmp(cname,
"timespec"))
continue;
1592 if (!strncmp(cname,
"tuple<", 6))
continue;
1596 TClass *classPtr = TClass::GetClass((
const char *) cname, kTRUE);
1597 if (!classPtr)
continue;
1599 std::string shortName(ShortType(cname));
1600 cname = shortName.c_str();
1603 Bool_t matchesSelection = re.Match(s);
1610 TString htmlfilename;
1611 TFileSysEntry* fse = 0;
1613 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cname);
1615 hdr = cdi->GetDeclFileName();
1616 hdrFS = cdi->GetDeclFileSysName();
1617 src = cdi->GetImplFileName();
1618 srcFS = cdi->GetImplFileSysName();
1619 htmlfilename = cdi->GetHtmlFileName();
1622 if (!hdrFS.Length()) {
1623 if (!GetFileDefinition().GetDeclFileName(classPtr, hdr, hdrFS, &fse)) {
1627 skipROOTClasses =
true;
1628 Info(
"CreateListOfClasses",
"Cannot find header file for TObject at %s given the input path %s.",
1629 classPtr->GetDeclFileName(), GetInputPath().Data());
1630 Info(
"CreateListOfClasses",
"Assuming documentation is not for ROOT classes, or you need to pass "
1631 "the proper directory to THtml::SetInputDir() so I can find %s.", classPtr->GetDeclFileName());
1635 if (classPtr->GetClassInfo() &&
1636 (gInterpreter->ClassInfo_Property(classPtr->GetClassInfo()) & kIsDefinedInStd))
1638 if (classPtr->GetDeclFileName() && (!strncmp(classPtr->GetDeclFileName(),
"prec_stl/", 9) ||
1639 strstr(classPtr->GetDeclFileName(),
"include/c++/") ||
1640 !strncmp(classPtr->GetDeclFileName(),
"/usr/include",12)))
1642 if (classPtr->GetDeclFileName() && (
1643 !strcmp(classPtr->GetDeclFileName(),
"vector") ||
1644 !strcmp(classPtr->GetDeclFileName(),
"string") ||
1645 !strcmp(classPtr->GetDeclFileName(),
"list") ||
1646 !strcmp(classPtr->GetDeclFileName(),
"deque") ||
1647 !strcmp(classPtr->GetDeclFileName(),
"map") ||
1648 !strcmp(classPtr->GetDeclFileName(),
"valarray") ||
1649 !strcmp(classPtr->GetDeclFileName(),
"set") ||
1650 !strcmp(classPtr->GetDeclFileName(),
"typeinfo") ||
1651 !strcmp(classPtr->GetDeclFileName(),
"stdlib.h") ) )
1656 if (skipROOTClasses) {
1657 if (classPtr->GetSharedLibs() && classPtr->GetSharedLibs()[0]) {
1658 std::string lib(classPtr->GetSharedLibs());
1659 size_t posSpace = lib.find(
' ');
1660 if (posSpace != std::string::npos)
1661 lib.erase(posSpace);
1662 if (rootLibs.find(lib) == rootLibs.end()) {
1663 TString rootlibdir = TROOT::GetLibDir();
1665 if (sLib.Index(
'.') == -1) {
1667 sLib += gSystem->GetSoExt();
1669 gSystem->PrependPathName(rootlibdir, sLib);
1670 if (gSystem->AccessPathName(sLib))
1673 classesDeclFileNotFound.AddLast(classPtr);
1674 else rootLibs.insert(lib);
1678 static const char* rootClassesToIgnore[] =
1679 {
"ColorStruct_t",
"CpuInfo_t",
"Event_t",
"FileStat_t",
"GCValues_t",
"MemInfo_t",
1680 "PictureAttributes_t",
"Point_t",
"ProcInfo_t",
"ROOT",
"ROOT::Fit",
1681 "Rectangle_t",
"RedirectHandle_t",
"Segment_t",
"SetWindowAttributes_t",
1682 "SysInfo_t",
"TCint",
"UserGroup_t",
"WindowAttributes_t",
"timespec", 0};
1683 static const char* rootClassStemsToIgnore[] =
1684 {
"ROOT::Math",
"TKDTree",
"TMatrixT",
"TParameter",
"vector", 0 };
1685 static size_t rootClassStemsToIgnoreLen[] = {0, 0, 0, 0, 0};
1686 static std::set<std::string> setRootClassesToIgnore;
1687 if (setRootClassesToIgnore.empty()) {
1688 for (
int ii = 0; rootClassesToIgnore[ii]; ++ii)
1689 setRootClassesToIgnore.insert(rootClassesToIgnore[ii]);
1690 for (
int ii = 0; rootClassStemsToIgnore[ii]; ++ii)
1691 rootClassStemsToIgnoreLen[ii] = strlen(rootClassStemsToIgnore[ii]);
1694 if (setRootClassesToIgnore.find(cname) == setRootClassesToIgnore.end()) {
1695 bool matched =
false;
1696 for (
int ii = 0; !matched && rootClassStemsToIgnore[ii]; ++ii)
1697 matched = !strncmp(cname, rootClassStemsToIgnore[ii], rootClassStemsToIgnoreLen[ii]);
1699 classesDeclFileNotFound.AddLast(classPtr);
1704 if (matchesSelection && (!classPtr->GetDeclFileName() ||
1705 !strstr(classPtr->GetDeclFileName(),
"prec_stl/") ||
1706 !strstr(classPtr->GetDeclFileName(),
"include/c++/") ||
1707 strncmp(classPtr->GetDeclFileName(),
"/usr/include",12)))
1708 classesDeclFileNotFound.AddLast(classPtr);
1714 Bool_t haveSource = (srcFS.Length());
1716 haveSource = GetFileDefinition().GetImplFileName(classPtr, src, srcFS, fse ? 0 : &fse);
1719 classesImplFileNotFound.AddLast(classPtr);
1722 if (!htmlfilename.Length())
1723 GetHtmlFileName(classPtr, htmlfilename);
1726 cdi =
new TClassDocInfo(classPtr, htmlfilename, hdrFS, srcFS, hdr, src);
1727 fDocEntityInfo.fClasses.Add(cdi);
1729 cdi->SetDeclFileName(hdr);
1730 cdi->SetImplFileName(src);
1731 cdi->SetDeclFileSysName(hdrFS);
1732 cdi->SetImplFileSysName(srcFS);
1733 cdi->SetHtmlFileName(htmlfilename);
1736 cdi->SetSelected(matchesSelection);
1739 GetModuleDefinition().GetModule(classPtr, fse, modulename);
1740 if (!modulename.Length() || modulename ==
"USER")
1741 GetModuleNameForClass(modulename, classPtr);
1743 TModuleDocInfo* module = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(modulename);
1745 bool moduleSelected = cdi->IsSelected();
1747 TString parentModuleName(gSystem->DirName(modulename));
1748 TModuleDocInfo* super = 0;
1749 if (parentModuleName.Length() && parentModuleName !=
".") {
1750 super = (TModuleDocInfo*) fDocEntityInfo.fModules.FindObject(parentModuleName);
1755 while (parentModuleName.Tokenize(token, pos,
"/")) {
1756 if (!token.Length() || token ==
".")
continue;
1757 super =
new TModuleDocInfo(token, super);
1758 super->SetSelected(moduleSelected);
1759 fDocEntityInfo.fModules.Add(super);
1763 module =
new TModuleDocInfo(modulename, super);
1764 module->SetSelected(moduleSelected);
1765 fDocEntityInfo.fModules.Add(module);
1769 module->AddClass(cdi);
1770 cdi->SetModule(module);
1771 if (cdi->HaveSource() && cdi->IsSelected())
1772 module->SetSelected();
1776 cdi->GetListOfTypedefs().Clear();
1779 Info(
"CreateListOfClasses",
"Adding class %s, module %s (%sselected)",
1780 cdi->GetName(), module ? module->GetName() :
"[UNKNOWN]",
1781 cdi->IsSelected() ?
"" :
"not ");
1786 bool cannotFind =
false;
1787 if (!classesDeclFileNotFound.IsEmpty()) {
1788 Warning(
"CreateListOfClasses",
1789 "Cannot find the header for the following classes [reason]:");
1790 TIter iClassesDeclFileNotFound(&classesDeclFileNotFound);
1792 while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1793 if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1794 Warning(
"CreateListOfClasses",
" %s [header %s not found]", iClass->GetName(), iClass->GetDeclFileName());
1797 Warning(
"CreateListOfClasses",
" %s [header file is unknown]", iClass->GetName());
1801 if (!classesImplFileNotFound.IsEmpty() && gDebug > 3) {
1802 Warning(
"CreateListOfClasses",
1803 "Cannot find the source file for the following classes [reason]:");
1804 TIter iClassesDeclFileNotFound(&classesImplFileNotFound);
1806 while ((iClass = (TClass*)iClassesDeclFileNotFound())) {
1807 if (iClass->GetDeclFileName() && iClass->GetDeclFileName()[0]) {
1808 Info(
"CreateListOfClasses",
" %s [source %s not found]", iClass->GetName(), iClass->GetImplFileName());
1811 Info(
"CreateListOfClasses",
" %s [source file is unknown, add \"ClassImpl(%s)\" to source file if it exists]",
1812 iClass->GetName(), iClass->GetName());
1816 Warning(
"CreateListOfClasses",
"THtml cannot find all headers and sources. ");
1817 Warning(
"CreateListOfClasses",
1818 "You might need to adjust the input path (currently %s) by calling THtml::SetInputDir()",
1819 GetInputPath().Data());
1823 TIter iTypedef(gROOT->GetListOfTypes());
1825 TDocOutput output(*
this);
1826 while ((dt = (TDataType*) iTypedef())) {
1827 if (dt->GetType() != -1)
continue;
1828 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(dt->GetFullTypeName());
1830 cdi->GetListOfTypedefs().Add(dt);
1832 Info(
"CreateListOfClasses",
"Adding typedef %s to class %s",
1833 dt->GetName(), cdi->GetName());
1835 bool inNamespace =
true;
1836 TString surroundingNamespace(dt->GetName());
1837 Ssiz_t posTemplate = surroundingNamespace.Last(
'>');
1838 inNamespace = inNamespace && (posTemplate == kNPOS);
1840 Ssiz_t posColumn = surroundingNamespace.Last(
':');
1841 if (posColumn != kNPOS) {
1842 surroundingNamespace.Remove(posColumn - 1);
1843 TClass* clSurrounding = GetClass(surroundingNamespace);
1844 inNamespace = inNamespace && (!clSurrounding || IsNamespace(clSurrounding));
1847 if (inNamespace && cdi->GetModule()) {
1848 TString htmlfilename(dt->GetName());
1849 output.NameSpace2FileName(htmlfilename);
1850 htmlfilename +=
".html";
1851 TClassDocInfo* cdiTD =
new TClassDocInfo(dt, htmlfilename);
1852 cdiTD->SetModule(cdi->GetModule());
1853 cdiTD->SetSelected(cdi->IsSelected());
1854 cdi->GetModule()->AddClass(cdiTD);
1859 fDocEntityInfo.fClasses.Sort();
1860 fDocEntityInfo.fModules.Sort();
1861 TIter iterModule(&fDocEntityInfo.fModules);
1862 TModuleDocInfo* mdi = 0;
1863 while ((mdi = (TModuleDocInfo*) iterModule()))
1864 mdi->GetClasses()->Sort();
1866 if (fProductName ==
"(UNKNOWN PRODUCT)"
1867 && fDocEntityInfo.fModules.FindObject(
"core/base")
1868 && fDocEntityInfo.fModules.FindObject(
"core/cont")
1869 && fDocEntityInfo.fModules.FindObject(
"core/rint")
1870 && gProgName && strstr(gProgName,
"root"))
1872 fProductName =
"ROOT";
1874 if (fProductName ==
"(UNKNOWN PRODUCT)") {
1875 Warning(
"CreateListOfClasses",
"Product not set. You should call gHtml->SetProduct(\"MyProductName\");");
1876 }
else if (fProductName !=
"ROOT") {
1877 if (GetViewCVS().Contains(
"http://root.cern.ch/"))
1881 if (fDocEntityInfo.fModules.GetEntries() == 1
1882 && fDocEntityInfo.fModules.At(0)->GetName()
1883 && !strcmp(fDocEntityInfo.fModules.At(0)->GetName(),
"(UNKNOWN)"))
1886 ((TModuleDocInfo*) fDocEntityInfo.fModules.At(0))->SetName(
"MAIN");
1888 Info(
"CreateListOfClasses",
"Initializing - DONE.");
1895 void THtml::CreateListOfTypes()
1897 TDocOutput output(*
this);
1898 output.CreateTypeIndex();
1899 output.CreateClassTypeDefs();
1905 Bool_t THtml::CopyFileFromEtcDir(
const char* filename)
const {
1906 R__LOCKGUARD(GetMakeClassMutex());
1908 TString outFile(filename);
1910 TString inFile(outFile);
1911 gSystem->PrependPathName(GetEtcDir(), inFile);
1913 gSystem->PrependPathName(GetOutputDir(), outFile);
1915 if (gSystem->CopyFile(inFile, outFile, kTRUE) != 0) {
1916 Warning(
"CopyFileFromEtcDir",
"Could not copy %s to %s", inFile.Data(), outFile.Data());
1926 void THtml::CreateHierarchy()
1928 TDocOutput output(*
this);
1929 output.CreateHierarchy();
1935 void THtml::CreateJavascript()
const {
1936 CopyFileFromEtcDir(
"ROOT.js");
1942 void THtml::CreateStyleSheet()
const {
1943 CopyFileFromEtcDir(
"ROOT.css");
1944 CopyFileFromEtcDir(
"shadowAlpha.png");
1945 CopyFileFromEtcDir(
"shadow.gif");
1954 void THtml::GetDerivedClasses(TClass* cl, std::map<TClass*, Int_t>& derived)
const
1956 TIter iClass(&fDocEntityInfo.fClasses);
1957 TClassDocInfo* cdi = 0;
1958 while ((cdi = (TClassDocInfo*) iClass())) {
1959 TClass* candidate =
dynamic_cast<TClass*
>(cdi->GetClass());
1960 if (!candidate)
continue;
1961 if (candidate != cl && candidate->InheritsFrom(cl)) {
1963 TClass* currentBaseOfCandidate = candidate;
1964 while (currentBaseOfCandidate != cl) {
1965 TList* bases = currentBaseOfCandidate->GetListOfBases();
1966 if (!bases)
continue;
1968 TBaseClass* base = 0;
1969 while ((base = (TBaseClass*) iBase())) {
1970 TClass* clBase = base->GetClassPointer();
1971 if (clBase && clBase->InheritsFrom(cl)) {
1973 currentBaseOfCandidate = clBase;
1977 derived[candidate] = level;
1991 void THtml::GetHtmlFileName(TClass * classPtr, TString& filename)
const
1994 if (!classPtr)
return;
1997 if (!GetImplFileName(classPtr, kFALSE, cFilename))
1998 GetDeclFileName(classPtr, kFALSE, cFilename);
2002 if (!cFilename.Length())
2006 const char *colon = strchr(cFilename,
':');
2009 libName = TString(cFilename, colon - cFilename);
2015 if (classPtr->GetSharedLibs()) {
2017 TString libname(classPtr->GetSharedLibs());
2018 Ssiz_t posSpace = libname.First(
' ');
2019 if (posSpace != kNPOS)
2020 libname.Remove(posSpace, libname.Length());
2021 TString libnameBase = gSystem->BaseName(libname);
2022 if (libnameBase.BeginsWith(
"lib"))
2023 libnameBase.Remove(0, 3);
2024 Ssiz_t posExt = libnameBase.First(
'.');
2026 libnameBase.Remove(posExt, libnameBase.Length());
2027 if (libnameBase.Length())
2028 libName = libnameBase;
2031 filename = cFilename;
2032 TString htmlFileName;
2033 if (!filename.Length() ||
2034 !gSystem->FindFile(fPathInfo.fInputPath, filename, kReadPermission)) {
2035 htmlFileName = GetURL(libName);
2037 htmlFileName =
"./";
2039 if (htmlFileName.Length()) {
2040 filename = htmlFileName;
2041 TString className(classPtr->GetName());
2042 TDocOutput output(*const_cast<THtml*>(
this));
2043 output.NameSpace2FileName(className);
2044 gSystem->PrependPathName(filename, className);
2045 filename = className;
2046 filename.ReplaceAll(
"\\",
"/");
2047 filename +=
".html";
2048 }
else filename.Remove(0);
2055 const char* THtml::GetHtmlFileName(
const char* classname)
const
2057 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(classname);
2059 return cdi->GetHtmlFileName();
2066 TClass *THtml::GetClass(
const char *name1)
const
2068 if(!name1 || !name1[0])
return 0;
2070 if (strstr(name1,
"ROOT::")==name1) {
2072 if (!strncmp(name1 + 6,
"Math", 4)) ret = kFALSE;
2076 TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(name1);
2078 TClass *cl =
dynamic_cast<TClass*
>(cdi->GetClass());
2086 TString declFileName;
2087 if (cl && GetDeclFileName(cl, kFALSE, declFileName))
2095 bool THtml::GetDeclFileName(TClass * cl, Bool_t filesys, TString& out_name)
const
2097 return GetDeclImplFileName(cl, filesys,
true, out_name);
2103 bool THtml::GetImplFileName(TClass * cl, Bool_t filesys, TString& out_name)
const
2105 return GetDeclImplFileName(cl, filesys,
false, out_name);
2113 bool THtml::GetDeclImplFileName(TClass * cl,
bool filesys,
bool decl, TString& out_name)
const
2117 R__LOCKGUARD(GetMakeClassMutex());
2118 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2120 bool determine = (!cdi);
2121 if (!determine) determine |= decl && filesys && !cdi->GetDeclFileSysName()[0];
2122 if (!determine) determine |= decl && !filesys && !cdi->GetDeclFileName()[0];
2123 if (!determine) determine |= !decl && filesys && !cdi->GetImplFileSysName()[0];
2124 if (!determine) determine |= !decl && !filesys && !cdi->GetImplFileName()[0];
2129 if (!GetFileDefinition().GetDeclFileName(cl, name, sysname))
2132 if (!GetFileDefinition().GetImplFileName(cl, name, sysname))
2137 if (!cdi->GetDeclFileName() || !cdi->GetDeclFileName()[0])
2138 cdi->SetDeclFileName(name);
2139 if (!cdi->GetDeclFileSysName() || !cdi->GetDeclFileSysName()[0])
2140 cdi->SetDeclFileSysName(sysname);
2142 if (!cdi->GetImplFileName() || !cdi->GetImplFileName()[0])
2143 cdi->SetImplFileName(name);
2144 if (!cdi->GetImplFileSysName() || !cdi->GetImplFileSysName()[0])
2145 cdi->SetImplFileSysName(sysname);
2149 if (filesys) out_name = sysname;
2150 else out_name = name;
2154 if (decl) out_name = cdi->GetDeclFileSysName();
2155 else out_name = cdi->GetImplFileSysName();
2157 if (decl) out_name = cdi->GetDeclFileName();
2158 else out_name = cdi->GetImplFileName();
2167 const TString& THtml::GetOutputDir(Bool_t createDir )
const
2170 R__LOCKGUARD(GetMakeClassMutex());
2172 gSystem->ExpandPathName(const_cast<THtml*>(
this)->fPathInfo.fOutputDir);
2174 Long_t sId, sFlags, sModtime;
2175 if (fPathInfo.fOutputDir.EndsWith(
"/") || fPathInfo.fOutputDir.EndsWith(
"\\"))
2176 fPathInfo.fOutputDir.Remove(fPathInfo.fOutputDir.Length() - 1);
2177 Int_t st = gSystem->GetPathInfo(fPathInfo.fOutputDir, &sId, &sSize, &sFlags, &sModtime);
2178 if (st || !(sFlags & 2)) {
2180 Error(
"GetOutputDir",
"output directory %s is an existing file",
2181 fPathInfo.fOutputDir.Data());
2182 else if (gSystem->MakeDirectory(fPathInfo.fOutputDir) == -1)
2183 Error(
"GetOutputDir",
"output directory %s does not exist and can't create it", fPathInfo.fOutputDir.Data());
2186 return fPathInfo.fOutputDir;
2192 Bool_t THtml::IsNamespace(
const TClass*cl)
2194 return (cl->Property() & kIsNamespace);
2200 void THtml::LoadAllLibs()
2202 gSystem->LoadAllLibraries();
2216 void THtml::MakeAll(Bool_t force,
const char *filter,
int numthreads )
2220 if (numthreads == 1) {
2222 TClassDocInfo* classinfo = 0;
2223 TIter iClassInfo(&fDocEntityInfo.fClasses);
2226 while ((classinfo = (TClassDocInfo*)iClassInfo())) {
2227 if (!classinfo->IsSelected())
2229 fCounter.Form(
"%5d", fDocEntityInfo.fClasses.GetSize() - count++);
2230 MakeClass(classinfo, force);
2233 if (numthreads == -1) {
2235 gSystem->GetSysInfo(&sysinfo);
2236 numthreads = sysinfo.fCpus;
2240 fThreadedClassCount = 0;
2241 fThreadedClassIter =
new TIter(&fDocEntityInfo.fClasses);
2242 THtmlThreadInfo hti(
this, force);
2243 if (!fMakeClassMutex && gGlobalMutex) {
2244 gGlobalMutex->Lock();
2245 fMakeClassMutex = gGlobalMutex->Factory(kTRUE);
2246 gGlobalMutex->UnLock();
2250 gSystem->Load(
"libThread");
2251 while (--numthreads >= 0) {
2252 TThread* thread =
new TThread(MakeClassThreaded, &hti);
2254 threads.Add(thread);
2257 TIter iThread(&threads);
2258 TThread* thread = 0;
2259 Bool_t wait = kTRUE;
2261 while (wait && (thread = (TThread*) iThread()))
2262 wait &= (thread->GetState() == TThread::kRunningState);
2263 gSystem->ProcessEvents();
2264 gSystem->Sleep(500);
2268 while ((thread = (TThread*) iThread()))
2282 void THtml::MakeClass(
const char *className, Bool_t force)
2284 CreateListOfClasses(
"*");
2286 TClassDocInfo* cdi = (TClassDocInfo*)fDocEntityInfo.fClasses.FindObject(className);
2288 if (!TClassEdit::IsStdClass(className))
2289 Error(
"MakeClass",
"Unknown class '%s'!", className);
2293 MakeClass(cdi, force);
2303 void THtml::MakeClass(
void *cdi_void, Bool_t force)
2305 if (!fDocEntityInfo.fClasses.GetSize())
2306 CreateListOfClasses(
"*");
2308 TClassDocInfo* cdi = (TClassDocInfo*) cdi_void;
2309 TClass* currentClass =
dynamic_cast<TClass*
>(cdi->GetClass());
2311 if (!currentClass) {
2312 if (!cdi->GetClass() &&
2313 !TClassEdit::IsStdClass(cdi->GetName()))
2314 Error(
"MakeClass",
"Class '%s' is known, but I cannot find its TClass object!", cdi->GetName());
2317 TString htmlFile(cdi->GetHtmlFileName());
2318 if (htmlFile.Length()
2319 && (htmlFile.BeginsWith(
"http://")
2320 || htmlFile.BeginsWith(
"https://")
2321 || gSystem->IsAbsoluteFileName(htmlFile))
2325 if (htmlFile.Length()) {
2326 TClassDocOutput cdo(*
this, currentClass, &cdi->GetListOfTypedefs());
2327 cdo.Class2Html(force);
2328 cdo.MakeTree(force);
2330 TString what(cdi->GetName());
2331 what +=
" (sources not found)";
2332 Printf(fCounterFormat.Data(),
"-skipped-", fCounter.Data(), what.Data());
2343 void* THtml::MakeClassThreaded(
void* info) {
2344 const THtmlThreadInfo* hti = (
const THtmlThreadInfo*)info;
2346 TClassDocInfo* classinfo = 0;
2347 while ((classinfo = hti->GetHtml()->GetNextClass()))
2348 hti->GetHtml()->MakeClass(classinfo, hti->GetForce());
2359 void THtml::MakeIndex(
const char *filter)
2361 CreateListOfClasses(filter);
2363 TDocOutput output(*
this);
2365 output.CreateTypeIndex();
2366 output.CreateClassTypeDefs();
2367 output.CreateModuleIndex();
2368 output.CreateClassIndex();
2369 output.CreateProductIndex();
2372 output.CreateHierarchy();
2383 void THtml::MakeTree(
const char *className, Bool_t force)
2386 TClass *classPtr = GetClass(className);
2389 Error(
"MakeTree",
"Unknown class '%s' !", className);
2393 TClassDocOutput cdo(*
this, classPtr, 0);
2394 cdo.MakeTree(force);
2400 void THtml::SetFoundDot(Bool_t found) {
2401 if (found) fPathInfo.fFoundDot = PathInfo_t::kDotFound;
2402 else fPathInfo.fFoundDot = PathInfo_t::kDotNotFound;
2408 void THtml::SetLocalFiles()
const
2410 if (fLocalFiles)
delete fLocalFiles;
2411 fLocalFiles =
new TFileSysDB(fPathInfo.fInputPath, fPathInfo.fIgnorePath +
"|(\\b" + GetOutputDir(kFALSE) +
"\\b)" , 6);
2418 void THtml::SetModuleDefinition(
const TModuleDefinition& md)
2421 fModuleDef = (TModuleDefinition*) md.Clone();
2422 fModuleDef->SetOwner(const_cast<THtml*>(
this));
2430 void THtml::SetFileDefinition(
const TFileDefinition& md)
2433 fFileDef = (TFileDefinition*) md.Clone();
2434 fFileDef->SetOwner(const_cast<THtml*>(
this));
2442 void THtml::SetPathDefinition(
const TPathDefinition& md)
2445 fPathDef = (TPathDefinition*) md.Clone();
2446 fPathDef->SetOwner(const_cast<THtml*>(
this));
2459 void THtml::SetInputDir(
const char *dir)
2461 fPathInfo.fInputPath = dir;
2462 gSystem->ExpandPathName(fPathInfo.fInputPath);
2465 fDocEntityInfo.fClasses.Clear();
2466 fDocEntityInfo.fModules.Clear();
2473 void THtml::SetOutputDir(
const char *dir)
2475 fPathInfo.fOutputDir = dir;
2477 fPathInfo.fOutputDir.ReplaceAll(
"/",
"\\");
2484 void THtml::SetDeclFileName(TClass* cl,
const char* filename)
2486 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2488 cdi =
new TClassDocInfo(cl,
"" ,
"" ,
"" , filename);
2489 fDocEntityInfo.fClasses.Add(cdi);
2491 cdi->SetDeclFileName(filename);
2497 void THtml::SetImplFileName(TClass* cl,
const char* filename)
2499 TClassDocInfo* cdi = (TClassDocInfo*) fDocEntityInfo.fClasses.FindObject(cl->GetName());
2501 cdi =
new TClassDocInfo(cl,
"" ,
"" ,
"" , 0 , filename);
2502 fDocEntityInfo.fClasses.Add(cdi);
2504 cdi->SetImplFileName(filename);
2510 const char* THtml::ShortType(
const char* name)
const
2512 const char* tmplt = strchr(name,
'<');
2513 if (!tmplt)
return name;
2514 tmplt = strrchr(tmplt,
':');
2515 if (tmplt > name && tmplt[-1] ==
':') {
2518 TString namesp(name, tmplt - name - 1);
2520 if (!GetClass(namesp))
return name;
2522 TObject* scn = fDocEntityInfo.fShortClassNames.FindObject(name);
2524 scn =
new TNamed(name, TClassEdit::ShortType(name, 1<<7));
2525 fDocEntityInfo.fShortClassNames.Add(scn);
2527 return scn->GetTitle();