Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

THtml.h

Go to the documentation of this file.
00001 // @(#)root/html:$Name:  $:$Id: THtml.h,v 1.10 2003/02/15 05:41:04 brun Exp $
00002 // Author: Nenad Buncic   18/10/95
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 #ifndef ROOT_THtml
00013 #define ROOT_THtml
00014 
00015 
00017 //                                                                        //
00018 // THtml                                                                  //
00019 //                                                                        //
00020 // Html makes a documentation for all ROOT classes                        //
00021 // using Hypertext Markup Language 2.0                                    //
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 //#include "Type.h"
00032 //#include "G__ci.h"
00033 //#include "Typedf.h"
00034 //#include "Class.h"
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 // doc for TDocElement
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; // documentation for the element
00085       TString fSourceLink; // link to source where this element is defined
00086       TString fDocLink; // link to documentation of this element
00087       ClassDef(TDocElement, 0)
00088    };
00089 
00090    //______________________________________________________
00091    // 
00092    // Addendum to TROOT's list of classes, containing
00093    // * additional, non-linkdef'ed classes
00094    // * enums 
00095    // * structs
00096    // * typedefs
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; // type name
00146       TString fDeclName; // file name containing declaration
00147       TString fTypedefReal; // "A" for "typedef A B;"
00148       ESpec fSpec; // type of type
00149       Int_t fDeclLine; // line number in file containing declaration
00150       ClassDef(TLocalType,0) // additional types found while parsing
00151    };
00152 
00153    
00154 //_____________________________________________________
00155 // doc for TParseStack
00156 //
00157    class TParseStack{
00158    public:
00159       enum EContext {
00160          kTop, // topmost - i.e. no - context
00161          kComment, // within comment /* ... */
00162          kBlock, // { ... }
00163          kParameter, // ( ... )
00164          kTemplate, // < ... >
00165          kArray, // [ ... ]
00166          kString, // " ... "
00167          kUndefined
00168       };
00169       enum EBlockSpec {
00170          kClassDecl, // class ...{ (or enum or struct)
00171          kMethodDef, // some method is defined here
00172          kMethodDefCand, // some method might be defined here (not sure, e.g. unknown param type)
00173          kNamespace, // within namespace ...{
00174          kBlkUndefined
00175       };
00176 
00177       //____________________________________________
00178       // doc for TParseElement
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+=" "; // as delimiter
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          // fill fTypes
00251          // start with classes
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 //printf("Warning in <TParseStack::Pop>: Stack is already empty!\n");
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          // prepend the surrounding class and namepace names 
00304          // (separated by "::") to whatever is in fqi
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       // returns the part of cIdentifier that is not covered by a using directive
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             // only look for next part of identifier 
00326             // this doesn't work if there's a using namespace::class directive...
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          // first try local type
00339          TString fqi(type);
00340          GetFQI(fqi);
00341          // if they are the same this doesn't get us anywhere
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          // maybe THtml found its own type
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          // find a class named strClassName, if necessary add
00369          // "using"-used or surrounding classes / namespaces
00370          Bool_t bFound=FindTypeFQI(strClassName, dict);
00371 
00372          // iterate through parse stack, try to find FQI
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          } // for (parse elements in stack)
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; // hashed list of known types
00407       THashList fTypedefs; // hashed list of known typedefs
00408 
00409       ClassDef(TParseStack, 0);
00410    };
00411 
00412 protected:
00413     TString      fXwho;            // by default http://xwho.cern.ch/WHO/people?
00414   const char    *fSourcePrefix;    // prefix to relative source path
00415   const char    *fSourceDir;       // source path
00416   const char    *fOutputDir;       // output directory
00417         char    *fLine;            // current line
00418         Int_t    fLen;             // maximum line length
00419         char    *fCounter;         // counter string
00420         Bool_t   fEscFlag;         // Flag to mark the symbol must be written "as is"
00421         char     fEsc;             // The special symbol ("backslash" by default) to mark "the next symbol should not be converted
00422         TMap    *fMapDocElements;  // map of <TDictionary*, TDocElement*> for all objects for which doc was parsed
00423         static THashList fgLocalTypes;    // list of types that are not in TROOT::GetClass
00424         TList fFilesParsed; // list of files on which ExtractDocumentatoin was run
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)  //Convert class(es) into HTML file(s)
00504 };
00505 
00506 R__EXTERN THtml *gHtml;
00507 
00508 #endif

Generated on Thu Dec 18 14:52:21 2003 for ROOT by doxygen1.2.16