00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ROOT_THtml
00013 #define ROOT_THtml
00014
00015
00017
00018
00019
00020
00021
00022
00024
00025 #ifndef __CINT__
00026 #include "TCint.h"
00027 #include "Api.h"
00028 #undef G__FPROTO_H
00029 #include "fproto.h"
00030 #endif
00031
00032
00033
00034
00035
00036 #ifndef ROOT_TROOT
00037 #include "TROOT.h"
00038 #endif
00039 #ifndef ROOT_TDictionary
00040 #include "TDictionary.h"
00041 #endif
00042 #ifndef ROOT_TMap
00043 #include "TMap.h"
00044 #endif
00045 #ifndef ROOT_THashList
00046 #include "THashList.h"
00047 #endif
00048
00049 class TClass;
00050 class TVirtualPad;
00051 class TPaveText;
00052
00053 class THtml : public TObject {
00054
00055 public:
00056
00057
00058
00059 class TDocElement: public TObject {
00060 public:
00061 inline TDocElement(const TString doc,
00062 const TString sourceLink="", const TString docLink=""):
00063 fDoc(doc), fSourceLink(sourceLink),
00064 fDocLink(docLink) {};
00065
00066 inline const TString& GetDoc() const {
00067 return fDoc;}
00068 inline void AddToDoc(const char* doc) {
00069 fDoc+=doc;
00070 }
00071 inline const TString& GetDocLink() const {
00072 return fDocLink;}
00073 inline const TString& GetSourceLink() const {
00074 return fSourceLink;}
00075
00076 inline TDocElement& SetDoc(const TString doc) {
00077 fDoc=doc;
00078 return *this; }
00079 inline TDocElement& SetDocLink(const TString docLink) {
00080 fDocLink=docLink;
00081 return *this; }
00082
00083 private:
00084 TString fDoc;
00085 TString fSourceLink;
00086 TString fDocLink;
00087 ClassDef(TDocElement, 0)
00088 };
00089
00090
00091
00092
00093
00094
00095
00096
00097 class TLocalType: public TDictionary {
00098 public:
00099 enum ESpec {
00100 kUndefined,
00101 kClass,
00102 kEnum,
00103 kStruct,
00104 kTypedef,
00105 kNumSpecs
00106 };
00107
00108 inline TLocalType(const char* nameFQI,
00109 ESpec spec,
00110 const char* declFileName, Int_t declFileLine,
00111 const char* realTypdefName = 0):
00112 fName(nameFQI),
00113 fDeclName(declFileName),
00114 fTypedefReal(realTypdefName),
00115 fSpec(spec), fDeclLine(declFileLine) {}
00116
00117 inline virtual ~TLocalType() {}
00118 inline const char* GetName() const {
00119 return fName; }
00120 inline const char* GetDeclFileName() const {
00121 return fDeclName;
00122 }
00123 inline Int_t GetDeclFileLine() const {
00124 return fDeclLine;
00125 }
00126 inline const char* RealTypedefName() const {
00127 return fTypedefReal; }
00128 inline ESpec Spec() const {
00129 return fSpec;
00130 }
00131 inline int Compare(const TObject *obj) const {
00132 return strcmp(fName, ((TDictionary*)obj)->GetName());
00133 }
00134 const char *GetTitle() const {
00135 return 0;
00136 }
00137 ULong_t Hash() const {
00138 return fName.Hash();
00139 }
00140 Long_t Property() const {
00141 return 0;
00142 }
00143
00144 private:
00145 TString fName;
00146 TString fDeclName;
00147 TString fTypedefReal;
00148 ESpec fSpec;
00149 Int_t fDeclLine;
00150 ClassDef(TLocalType,0)
00151 };
00152
00153
00154
00155
00156
00157 class TParseStack{
00158 public:
00159 enum EContext {
00160 kTop,
00161 kComment,
00162 kBlock,
00163 kParameter,
00164 kTemplate,
00165 kArray,
00166 kString,
00167 kUndefined
00168 };
00169 enum EBlockSpec {
00170 kClassDecl,
00171 kMethodDef,
00172 kMethodDefCand,
00173 kNamespace,
00174 kBlkUndefined
00175 };
00176
00177
00178
00179
00180 class TParseElement: public TNamed {
00181 public:
00182 inline TParseElement(EContext ctx=kUndefined, EBlockSpec bsp=kBlkUndefined,
00183 const char* fName=0, const char* fTitle=0, TDictionary* dict=0):
00184 TNamed(fName, fTitle), fCtx(ctx), fBsp(bsp), fPStrUsing(0), fDict(dict) {};
00185 inline TParseElement(char cStart, EBlockSpec bsp=kBlkUndefined,
00186 const char* fName=0, const char* fTitle=0, TDictionary* dict=0):
00187 TNamed(fName, fTitle), fBsp(bsp), fPStrUsing(0), fDict(dict) {
00188 if(cStart=='/') fCtx=kComment;
00189 else if (cStart=='{') fCtx=kBlock;
00190 else if (cStart=='(') fCtx=kParameter;
00191 else if (cStart=='[') fCtx=kArray;
00192 else if (cStart=='<') fCtx=kTemplate;
00193 else if (cStart=='"') fCtx=kString;
00194 }
00195
00196 virtual ~TParseElement() {
00197 if (fPStrUsing) delete fPStrUsing;
00198 }
00199
00200 inline void AddUsing(const char* cIdentifier) {
00201 if (!fPStrUsing) fPStrUsing=new TString(" ");
00202 *fPStrUsing+=cIdentifier;
00203 *fPStrUsing+=" ";
00204 }
00205 inline EContext Context() const {
00206 return fCtx; }
00207 inline EBlockSpec BlockSpec() const {
00208 return fBsp; }
00209 inline TDictionary* Dict() const {
00210 return fDict; }
00211 inline TParseElement& SetContext(EContext ctx) {
00212 fCtx=ctx;
00213 return *this;
00214 }
00215 inline Bool_t IsUsing(const char* cIdentifier) const {
00216 if (strcmp(cIdentifier, fName)==0) return kTRUE;
00217 if (!fPStrUsing) return kFALSE;
00218 TString strSearch(" ");
00219 strSearch+=cIdentifier;
00220 strSearch+=" ";
00221 return (fPStrUsing->Contains(strSearch));
00222 }
00223 inline TString* GetUsing() const {
00224 return fPStrUsing;
00225 }
00226
00227 inline const char* GetCloseTag() const {
00228 switch (fCtx) {
00229 case kComment: return "*/";
00230 case kBlock: return "}";
00231 case kParameter: return ")";
00232 case kTemplate: return ">";
00233 case kArray: return "]";
00234 case kString: return "\"";
00235 default: return NULL;
00236 }
00237 }
00238
00239 private:
00240 EContext fCtx;
00241 EBlockSpec fBsp;
00242 TString* fPStrUsing;
00243 TDictionary* fDict;
00244 ClassDef(TParseElement, 0)
00245 };
00246
00247 inline TParseStack(){
00248 Push(kTop);
00249
00250
00251
00252 G__ClassInfo clinfo;
00253 while (clinfo.Next())
00254 fTypes.Add(new TNamed(clinfo.Fullname(), clinfo.Title()));
00255
00256 G__TypedefInfo typeinfo;
00257 while (typeinfo.Next())
00258 fTypedefs.Add(new TNamed(typeinfo.Name(), typeinfo.TrueName()));
00259 };
00260 virtual ~TParseStack();
00261 inline TParseElement& Push(EContext ctx, EBlockSpec bsp=kBlkUndefined,
00262 const char* name="", const char* title="") {
00263 return Push(new TParseElement(ctx, bsp, name, title));
00264 }
00265 inline TParseElement& Push(char cStart, EBlockSpec bsp=kBlkUndefined,
00266 const char* name="", const char* title="") {
00267 return Push(new TParseElement(cStart, bsp, name, title));
00268 }
00269 inline TParseElement& Push(TParseElement* pe) {
00270 fStack.AddLast(pe);
00271 return *pe;
00272 }
00273 inline TParseElement* Pop() {
00274 if (fStack.GetSize()==1) {
00275
00276 return 0;
00277 } else
00278 return (TParseElement*) fStack.Remove(fStack.LastLink());
00279 }
00280 inline void PopAndDel() {
00281 delete Pop();
00282 }
00283 inline TParseElement& Top() const{
00284 return *((TParseElement*) fStack.Last());
00285 }
00286 inline TList* Stack() {
00287 return &fStack;
00288 }
00289
00290 inline EContext Context() const {
00291 return Top().Context();
00292 }
00293
00294 inline EBlockSpec BlockSpec() const {
00295 return Top().BlockSpec();
00296 }
00297
00298 inline TDictionary* Dict() const {
00299 return Top().Dict();
00300 }
00301
00302 inline void GetFQI(TString& fqi) const{
00303
00304
00305 TIter psi(&fStack, kIterBackward);
00306 TParseElement* pe;
00307 while ((pe=(TParseElement*) psi()))
00308 if (pe->Context()==kBlock &&
00309 (pe->BlockSpec()==kClassDecl || pe->BlockSpec()==kNamespace)){
00310 fqi.Prepend("::");
00311 fqi.Prepend(pe->GetName());
00312 }
00313 }
00314
00315 inline const char* IsUsing(const char* cIdentifier) const{
00316
00317 static char cID[1024];
00318 char* cFindNext=cID;
00319 strcpy(cID, cIdentifier);
00320
00321 TIter psi(&fStack);
00322 TParseElement* pe;
00323
00324 while (cFindNext) {
00325
00326
00327 char* cCol=strchr(cFindNext, ':');
00328 if (cCol) *cCol=0;
00329
00330 while ((pe=(TParseElement*) psi()) && !pe->IsUsing(cFindNext));
00331 if (pe && cCol) cFindNext=&cCol[2];
00332 if (!pe) return &cIdentifier[cFindNext-cID];
00333 }
00334 return 0;
00335 }
00336
00337 inline Bool_t FindTypeFQI(TString& type, TDictionary*& dict) {
00338
00339 TString fqi(type);
00340 GetFQI(fqi);
00341
00342 if (strcmp(fqi, type)) {
00343 if (fTypes.FindObject(fqi)) {
00344 dict=THtml::GetType(fqi);
00345 type=fqi;
00346 return kTRUE;
00347 }
00348 if (fTypedefs.FindObject(fqi)) {
00349 type=fqi;
00350 return kTRUE;
00351 }
00352 }
00353
00354 dict=THtml::GetType(type);
00355
00356 if (dict)
00357 return kTRUE;
00358
00359 return (fTypedefs.FindObject(type)) ;
00360 }
00361
00362 inline Bool_t FindType(TString& strClassName){
00363 TDictionary* dict;
00364 return FindType(strClassName, dict);
00365 }
00366
00367 inline Bool_t FindType(TString& strClassName, TDictionary*& dict){
00368
00369
00370 Bool_t bFound=FindTypeFQI(strClassName, dict);
00371
00372
00373 TParseElement* pe=0;
00374 TIter iPE(&fStack, kFALSE);
00375 while (!bFound && (pe=(TParseElement*) iPE())) {
00376 TString *strUsing=pe->GetUsing();
00377 if (strUsing) {
00378 const char* pos=strUsing->Data();
00379 Int_t end;
00380 TString strClassUsing;
00381 ParseWord(pos, end, strClassUsing, ":");
00382 strClassUsing+=strClassName;
00383 bFound=FindTypeFQI(strClassUsing, dict);
00384 if (bFound) strClassName=strClassUsing;
00385 }
00386 }
00387 return bFound;
00388 }
00389
00390 Bool_t IsInStack(EContext ctx, EBlockSpec bsp=kBlkUndefined) const {
00391 TIter psi(&fStack, kIterBackward);
00392 TParseElement* pe;
00393 while ((pe=(TParseElement*) psi()))
00394 if (pe->Context()==ctx &&
00395 (bsp==kBlkUndefined || pe->BlockSpec()==bsp))
00396 return kTRUE;
00397 return kFALSE;
00398 }
00399
00400 inline void AddCustomType(const char* type) {
00401 fTypes.Add(new TNamed(type,0));
00402 }
00403
00404 private:
00405 TList fStack;
00406 THashList fTypes;
00407 THashList fTypedefs;
00408
00409 ClassDef(TParseStack, 0);
00410 };
00411
00412 protected:
00413 TString fXwho;
00414 const char *fSourcePrefix;
00415 const char *fSourceDir;
00416 const char *fOutputDir;
00417 char *fLine;
00418 Int_t fLen;
00419 char *fCounter;
00420 Bool_t fEscFlag;
00421 char fEsc;
00422 TMap *fMapDocElements;
00423 static THashList fgLocalTypes;
00424 TList fFilesParsed;
00425
00426 void Class2Html(TClass *classPtr, Bool_t force=kFALSE);
00427 void ClassDescription(ofstream &out, TClass *classPtr, Bool_t &flag);
00428 void ClassTree(TVirtualPad *canvas, TClass *classPtr, Bool_t force=kFALSE);
00429 Bool_t CopyHtmlFile(const char *sourceName, const char *destName="");
00430 void CreateIndex(const char **classNames, Int_t numberOfClasses);
00431 void CreateIndexByTopic(char **filenames, Int_t numberOfNames, Int_t maxLen);
00432 void CreateListOfTypes();
00433 void DerivedClasses(ofstream &out, TClass *classPtr);
00434 void ExpandKeywords(ofstream &out, char *text, TClass *ptr2class, Bool_t &flag, const char *dir="");
00435 void ExpandPpLine(ofstream &out, char *line);
00436 TClass *GetClass(const char *name, Bool_t load=kTRUE);
00437 const char *GetFileName(const char *filename);
00438 char *GetSourceFileName(const char *filename);
00439 char *GetHtmlFileName(TClass *classPtr);
00440 Bool_t IsModified(TClass *classPtr, const Int_t type);
00441 static Bool_t IsName(Int_t c);
00442 static Bool_t IsWord(Int_t c);
00443 void NameSpace2FileName(char *name);
00444 void ReplaceSpecialChars(ofstream &out, const char c);
00445 void ReplaceSpecialChars(ofstream &out, const char *string);
00446 void SortNames(const char **strings, Int_t num, Bool_t type=0);
00447 char *StrDup(const char *s1, Int_t n = 1);
00448
00449 friend Int_t CaseSensitiveSort(const void *name1, const void *name2);
00450 friend Int_t CaseInsensitiveSort(const void *name1, const void *name2);
00451
00452 TClass* ParseClassDecl(char* &cfirstLinePos,
00453 const TParseStack& parseStack, TString& strClassName);
00454 TDocElement* AddDocElement(TDictionary* dict, TString& strDoc, const char* filename);
00455 TDocElement* GetDocElement(TDictionary* dict) const {
00456 return (TDocElement*)(fMapDocElements?fMapDocElements->GetValue(dict):0);
00457 }
00458
00459 Bool_t FindMethodImpl(TString strMethFullName, TList& listMethodSameName,
00460 TList& listArgs, TParseStack& parseStack, Bool_t done=kFALSE) const;
00461
00462 public:
00463 THtml();
00464 virtual ~THtml();
00465 void Convert(const char *filename, const char *title, const char *dirname = "");
00466 const char *GetSourceDir() { return fSourceDir; }
00467 const char *GetOutputDir() { return fOutputDir; }
00468 const char *GetXwho() const { return fXwho.Data(); }
00469 void MakeAll(Bool_t force=kFALSE, const char *filter="*");
00470 void MakeClass(const char *className, Bool_t force=kFALSE);
00471 void MakeIndex(const char *filter="*");
00472 void MakeTree(const char *className, Bool_t force=kFALSE);
00473 void SetEscape(char esc='\\') { fEsc = esc; }
00474 void SetSourcePrefix(const char *prefix) { fSourcePrefix = prefix; }
00475 void SetSourceDir(const char *dir) { fSourceDir = dir; }
00476 void SetOutputDir(const char *dir) { fOutputDir = dir; }
00477 void SetXwho(const char *xwho) { fXwho = xwho; }
00478 virtual void WriteHtmlHeader(ofstream &out, const char *title);
00479 virtual void WriteHtmlFooter(ofstream &out, const char *dir="", const char *lastUpdate="",
00480 const char *author="", const char *copyright="");
00481
00482 void ExtractDocumentation(const char* cFileName, TList* listClassesFound);
00483 void ExtractClassDocumentation(const TClass* classPtr);
00484 static Bool_t ParseWord(const char* begin, Int_t &step,
00485 const char* allowedChars=0);
00486 static Bool_t ParseWord(const char* begin, Int_t &step,
00487 TString &strWord, const char* allowedChars=0);
00488
00489 static inline TDictionary* GetType(const char* type) {
00490 TDictionary* dict=(TDictionary*) gROOT->GetClass(type);
00491 if (!dict) return (TDictionary*) fgLocalTypes.FindObject(type);
00492 else return dict;
00493 }
00494
00495 const char* GetDoc(TDictionary* dict) const {
00496 TDocElement* de=GetDocElement(dict);
00497 return de ? de->GetDoc().Data() : 0;
00498 }
00499 TMap* MakeHelp(TClass* cl);
00500 TPaveText* GetDocPave(TDictionary* dict);
00501
00502
00503 ClassDef(THtml,0)
00504 };
00505
00506 R__EXTERN THtml *gHtml;
00507
00508 #endif