From f17b22ec882706181da4e3a661c055b101ac6e6f Mon Sep 17 00:00:00 2001 From: Rene Brun <Rene.Brun@cern.ch> Date: Thu, 3 Aug 2006 08:38:41 +0000 Subject: [PATCH] From Axel: Fix comments inside comments after strings (aka TH1::Rebin) by using a parse context _stack_. Show base classes' methods if requested. Reformat method list. Display options (inherited methods? non-public methods?) are stored in a cookie. We now also have a javascript file. Disable method sorting on Solaris until they implement a sort-with-predicate. Again, some chunks of code come from my FNAL/CMS/CD job. Builds on Solaris CC5 and Win MSVC8. git-svn-id: http://root.cern.ch/svn/root/trunk@15904 27541ba8-7e3a-0410-8455-c3a389f83636 --- html/inc/THtml.h | 14 +- html/src/THtml.cxx | 607 ++++++++++++++++++++++++++++----------------- 2 files changed, 389 insertions(+), 232 deletions(-) diff --git a/html/inc/THtml.h b/html/inc/THtml.h index 99269d1af55..78e1e805ff6 100644 --- a/html/inc/THtml.h +++ b/html/inc/THtml.h @@ -1,4 +1,4 @@ -// @(#)root/html:$Name: $:$Id: THtml.h,v 1.21 2006/07/11 17:34:02 brun Exp $ +// @(#)root/html:$Name: $:$Id: THtml.h,v 1.22 2006/07/27 19:57:14 brun Exp $ // Author: Nenad Buncic 18/10/95 /************************************************************************* @@ -36,8 +36,8 @@ #ifndef ROOT_TROOT #include "TROOT.h" #endif -#ifndef ROOT_TDictionary -#include "TDictionary.h" +#ifndef ROOT_TClass +#include "TClass.h" #endif #ifndef ROOT_TMap #include "TMap.h" @@ -80,7 +80,7 @@ protected: kNumSourceInfos }; - typedef std::map<std::string /*method name*/, Int_t > MethodNames_t; + typedef std::map<std::string /*method name*/, Int_t > MethodCount_t; TString fXwho; // by default http://xwho.cern.ch/WHO/people? TString fSourcePrefix; // prefix to relative source path @@ -91,9 +91,9 @@ protected: TString fLineExpanded; // current line with links TString fLineStripped; // current line without surrounding spaces TClass *fCurrentClass; // current class context of sources being parsed - MethodNames_t fMethodNames; // current class's method names + MethodCount_t fMethodNames; // current class's method names EDocContext fDocContext; // current context of parsed sources for documenting - EParseContext fParseContext; // current context of parsed sources + std::list<EParseContext> fParseContext; // current context of parsed sources std::set<UInt_t> fExtraLinesWithAnchor; // lines that need an additional anchor TString fSourceInfo[kNumSourceInfos];// author, last changed, ... TString fCounter; // counter string @@ -109,6 +109,7 @@ protected: std::map<TClass*,std::string> fGuessedImplFileNames; // names of additional impl file names static std::set<std::string> fgKeywords; // C++ keywords + void AddClassMethodsRecursive(TBaseClass* bc, TList methodNames[3]); void AnchorFromLine(TString& anchor); virtual void BeautifyLine(std::ostream &srcOut); void Class2Html(Bool_t force=kFALSE); @@ -122,6 +123,7 @@ protected: void CreateListOfTypes(); void CreateListOfClasses(const char* filter); void CreateSourceOutputStream(std::ofstream& out, const char* extension, TString& filename); + void CreateJavascript(); void CreateStyleSheet(); void DescendHierarchy(ofstream &out, TClass* basePtr, const char **classNames, Int_t numberOfClasses, diff --git a/html/src/THtml.cxx b/html/src/THtml.cxx index 160881d6705..8f51e463265 100644 --- a/html/src/THtml.cxx +++ b/html/src/THtml.cxx @@ -1,4 +1,4 @@ -// @(#)root/html:$Name: $:$Id: THtml.cxx,v 1.105 2006/07/30 11:20:00 rdm Exp $ +// @(#)root/html:$Name: $:$Id: THtml.cxx,v 1.106 2006/07/31 16:53:46 brun Exp $ // Author: Nenad Buncic (18/10/95), Axel Naumann <mailto:axel@fnal.gov> (09/28/01) /************************************************************************* @@ -298,7 +298,7 @@ std::set<std::string> THtml::fgKeywords; ClassImp(THtml) //______________________________________________________________________________ -THtml::THtml(): fCurrentClass(0), fDocContext(kIgnore), fParseContext(kCode), +THtml::THtml(): fCurrentClass(0), fDocContext(kIgnore), fHierarchyLines(0), fNumberOfClasses(0), fClassNames(0), fNumberOfFileNames(0), fFileNames(0) { // Create a THtml object. @@ -645,8 +645,117 @@ namespace { delete [] carr; l.swap(lsort); } + + class TMethodWrapper: public TObject { + public: + TMethodWrapper(const TMethod* m): fMeth(m) {} + + static void SetClass(const TClass* cl) { fClass = cl; } + + const char* GetName() const { return fMeth->GetName(); } + Int_t GetNargs() const { return fMeth->GetNargs(); } + const TMethod* GetMethod() const { return fMeth; } + Bool_t IsSortable() const { return kTRUE; } + + Int_t Compare(const TObject *obj) const { + const TMethodWrapper* m = dynamic_cast<const TMethodWrapper*>(obj); + if (!m) return 1; + + Int_t ret = strcasecmp(GetName(), m->GetName()); + if (ret == 0) { + if (GetNargs() < m->GetNargs()) return -1; + else if (GetNargs() > m->GetNargs()) return 1; + if (GetMethod()->GetClass()->InheritsFrom(m->GetMethod()->GetClass())) + return -1; + else + return 1; + } + + const char* l(GetName()); + const char* r(m->GetName()); + if (l[0] == '~' && r[0] == '~') { + ++l; + ++r; + } + if (fClass->InheritsFrom(l)) { + if (fClass->InheritsFrom(r)) { + if (gROOT->GetClass(l)->InheritsFrom(r)) + return -1; + else return 1; + } else return -1; + } else if (fClass->InheritsFrom(r)) + return 1; + + if (l[0] == '~') return -1; + if (r[0] == '~') return 1; + return (ret < 0) ? -1 : 1; + } + + private: + static const TClass* fClass; // current class, defining inheritance sort order + const TMethod* fMeth; // my method + }; + const TClass* TMethodWrapper::fClass = 0; +} + + +//______________________________________________________________________________ +void THtml::AddClassMethodsRecursive(TBaseClass* bc, TList methodNames[3]) +{ + // Add accessible (i.e. non-private) methods of base class bc + // and its base classes' methods to methodNames. + // If bc==0, we add fCurrentClass's methods (and also private functions). + + // make a loop on member functions + TClass *cl = fCurrentClass; + if (bc) + cl = bc->GetClassPointer(kFALSE); + if (!cl) return; + + TMethod *method; + TIter nextMethod(cl->GetListOfMethods()); + + while ((method = (TMethod *) nextMethod())) { + + if (!strcmp(method->GetName(), "Dictionary") || + !strcmp(method->GetName(), "Class_Version") || + !strcmp(method->GetName(), "Class_Name") || + !strcmp(method->GetName(), "DeclFileName") || + !strcmp(method->GetName(), "DeclFileLine") || + !strcmp(method->GetName(), "ImplFileName") || + !strcmp(method->GetName(), "ImplFileLine") || + bc && (method->GetName()[0] == '~' // d'tor + || ~strcmp(method->GetName(), method->GetReturnTypeName())) // c'tor + ) + continue; + + + Int_t mtype = 0; + if (kIsPrivate & method->Property()) + mtype = 0; + else if (kIsProtected & method->Property()) + mtype = 1; + else if (kIsPublic & method->Property()) + mtype = 2; + + if (bc) { + if (mtype == 0) continue; + if (bc->Property() & kIsPrivate) + mtype = 0; + else if ((bc->Property() & kIsProtected) && mtype == 2) + mtype = 1; + } + + methodNames[mtype].Add(new TMethodWrapper(method)); + } + + TIter iBase(cl->GetListOfBases()); + TBaseClass* base = 0; + while ((base = (TBaseClass*)iBase())) + AddClassMethodsRecursive(base, methodNames); } + //______________________________________________________________________________ void THtml::Class2Html(Bool_t force) { @@ -819,79 +928,23 @@ void THtml::Class2Html(Bool_t force) // create an html inheritance tree - if (!IsNamespace(fCurrentClass)) ClassHtmlTree(classFile, fCurrentClass); - - - // make a loop on member functions - TMethod *method; - TIter nextMethod(fCurrentClass->GetListOfMethods()); - - Int_t len, maxLen[3]; - len = maxLen[0] = maxLen[1] = maxLen[2] = 0; - - // loop to get a pointers to a method names - const Int_t nMethods = fCurrentClass->GetNmethods(); - const char **fMethodNames = new const char *[3 * 2 * nMethods]; - - Int_t mtype, num[3]; - mtype = num[0] = num[1] = num[2] = 0; - - while ((method = (TMethod *) nextMethod())) { - - if (!strcmp(method->GetName(), "Dictionary") || - !strcmp(method->GetName(), "Class_Version") || - !strcmp(method->GetName(), "Class_Name") || - !strcmp(method->GetName(), "DeclFileName") || - !strcmp(method->GetName(), "DeclFileLine") || - !strcmp(method->GetName(), "ImplFileName") || - !strcmp(method->GetName(), "ImplFileLine") - ) - continue; - - - if (kIsPrivate & method->Property()) - mtype = 0; - else if (kIsProtected & method->Property()) - mtype = 1; - else if (kIsPublic & method->Property()) - mtype = 2; - - fMethodNames[mtype * 2 * nMethods + 2 * num[mtype]] = - method->GetName(); - - if (method->GetReturnTypeName()) - len = strlen(method->GetReturnTypeName()); - else - len = 0; - - if (kIsVirtual & method->Property()) - len += 8; - if (kIsStatic & method->Property()) - len += 7; - - maxLen[mtype] = maxLen[mtype] > len ? maxLen[mtype] : len; - - const char *type = strrchr(method->GetReturnTypeName(), ' '); - if (!type) - type = method->GetReturnTypeName(); - else - type++; - - if (fCurrentClass && !strcmp(type, fCurrentClass->GetName())) - fMethodNames[mtype * 2 * nMethods + 2 * num[mtype]] = - "A00000000"; - - // if this is the destructor - while ('~' == - *fMethodNames[mtype * 2 * nMethods + 2 * num[mtype]]) - fMethodNames[mtype * 2 * nMethods + 2 * num[mtype]] = - "A00000001"; - - fMethodNames[mtype * 2 * nMethods + 2 * num[mtype] + 1] = - (char *) method; - - num[mtype]++; - } + if (!IsNamespace(fCurrentClass)) + ClassHtmlTree(classFile, fCurrentClass); + + classFile << endl << "<div id=\"functions\">" << endl; + classFile << "<div id=\"dispopt\">Display options:<br /><form>" << endl + << "<input id=\"dispoptCBInh\" type=\"checkbox\" " + "onchange=\"javascript:CBChanged(this);\" " + "title=\"Select to display inherited methods\" />Show inherited<br />" << endl + << "<input id=\"dispoptCBPub\" type=\"checkbox\" checked=\"checked\" " + "onchange=\"javascript:CBChanged(this);\" " + "title=\"Select to display non-public methods\" />Show non-public<br />" + << "</form></div>"; + + // loop to get a pointers to method names + TList methodNames[3]; + AddClassMethodsRecursive(0, methodNames); + TMethodWrapper::SetClass(fCurrentClass); const char* tab4nbsp=" "; if (fCurrentClass->Property() & kIsAbstract) @@ -901,113 +954,84 @@ void THtml::Class2Html(Bool_t force) << GetFileName((const char *) GetDeclFileName(fCurrentClass)) << "\">header</a> to check for available constructors.</b><br />" << endl; - classFile << "<pre>" << endl; + for (Int_t access = 2; access >=0 && !IsNamespace(fCurrentClass); --access) { + if (methodNames[access].GetEntries() == 0) + continue; + methodNames[access].SetOwner(); + methodNames[access].Sort(); + classFile << "<div class=\"access\" "; + const char* accessID = "funcpubl"; + + switch (access) { + case 0: + accessID = "funcpriv"; + classFile << "id=\"" << accessID << "\"><b>private:</b>"; + break; + case 1: + accessID = "funcprot"; + classFile << "id=\"" << accessID << "\"><b>protected:</b>"; + break; + case 2: + classFile << "id=\"" << accessID << "\"><b>public:</b>"; + break; + } + classFile << endl << "<table class=\"func\" id=\"tab" << accessID << "\">" << endl; + + TIter iMethWrap(&methodNames[access]); + TMethodWrapper *methWrap = 0; + while ((methWrap = (TMethodWrapper*) iMethWrap())) { + const TMethod* method = methWrap->GetMethod(); + + Int_t w = 0; + // it's a c'tor - Cint stores the class name as return type + Bool_t isctor = (!strcmp(method->GetName(), method->GetReturnTypeName())); + // it's a d'tor - Cint stores "void" as return type + Bool_t isdtor = (!isctor && method->GetName()[0] == '~'); + + classFile << "<tr class=\"func"; + if (method->GetClass() != fCurrentClass) + classFile << "inh"; + classFile << "\"><td class=\"funcret\">"; + if (kIsVirtual & method->Property()) + if (!isdtor) + classFile << "virtual "; + else + classFile << " virtual"; + + if (kIsStatic & method->Property()) + classFile << "static "; - Int_t i, j; + if (!isctor && !isdtor) + ExpandKeywords(classFile, method->GetReturnTypeName()); - if (IsNamespace(fCurrentClass)) { - j = 2; - } else { - j = 0; - } - for (; j < 3; j++) { - if (num[j]) { - qsort(fMethodNames + j * 2 * nMethods, num[j], - 2 * sizeof(fMethodNames), CaseInsensitiveSort); - - const char *ftitle = 0; - switch (j) { - case 0: - ftitle = "private:"; - break; - case 1: - ftitle = "protected:"; - break; - case 2: - ftitle = "public:"; - break; + TString mangled(method->GetClass()->GetName()); + NameSpace2FileName(mangled); + classFile << "</td><td class=\"funcname\"><a href=\""; + if (method->GetClass() != fCurrentClass) { + TString htmlFile; + GetHtmlFileName(method->GetClass(), htmlFile); + classFile << htmlFile; } - if (j) - classFile << endl; - classFile << tab4 << "<b>" << ftitle << "</b><br />" << endl; - - TString strClassNameNoScope(fCurrentClass->GetName()); - - UInt_t templateNest = 0; - Ssiz_t posLastScope = strClassNameNoScope.Length()-1; - for (;posLastScope && (templateNest || strClassNameNoScope[posLastScope] != ':'); --posLastScope) - if (strClassNameNoScope[posLastScope] == '>') ++templateNest; - else if (strClassNameNoScope[posLastScope] == '<') --templateNest; - else if (!strncmp(strClassNameNoScope.Data()+posLastScope,"operator", 8) && templateNest==1) - --templateNest; - if (strClassNameNoScope[posLastScope] == ':' - && strClassNameNoScope[posLastScope-1] == ':') - strClassNameNoScope.Remove(0, posLastScope+1); - - for (i = 0; i < num[j]; i++) { - method = - (TMethod *) fMethodNames[j * 2 * nMethods + 2 * i + - 1]; - - if (method) { - Int_t w = 0; - Bool_t isctor=false; - Bool_t isdtor=false; - if (method->GetReturnTypeName()) - len = strlen(method->GetReturnTypeName()); - else - len = 0; - if (!strcmp(method->GetName(),strClassNameNoScope.Data())) - // it's a c'tor - Cint stores the class name as return type - isctor=true; - if (!isctor && method->GetName()[0] == '~' && !strcmp(method->GetName()+1,strClassNameNoScope.Data())) - // it's a d'tor - Cint stores "void" as return type - isdtor=true; - if (isctor || isdtor) - len=0; - - if (kIsVirtual & method->Property()) - len += 8; - if (kIsStatic & method->Property()) - len += 7; - - classFile << tab6; - for (w = 0; w < (maxLen[j] - len); w++) - classFile << " "; - - if (kIsVirtual & method->Property()) - if (!isdtor) - classFile << "virtual "; - else - classFile << " virtual"; - - if (kIsStatic & method->Property()) - classFile << "static "; - - if (!isctor && !isdtor) - ExpandKeywords(classFile, method->GetReturnTypeName()); - - TString mangled(fCurrentClass->GetName()); - NameSpace2FileName(mangled); - classFile << " " << tab << "<!--BOLD-->"; - classFile << "<a href=\"#" << mangled; - classFile << ":"; - mangled = method->GetName(); - NameSpace2FileName(mangled); - classFile << mangled << "\">"; - ReplaceSpecialChars(classFile, method->GetName()); - classFile << "</a><!--PLAIN-->"; - - ExpandKeywords(classFile, method->GetSignature()); - classFile << endl; - } + classFile << "#" << mangled; + classFile << ":"; + mangled = method->GetName(); + NameSpace2FileName(mangled); + classFile << mangled << "\">"; + if (method->GetClass() != fCurrentClass) { + classFile << "<span class=\"baseclass\">"; + ReplaceSpecialChars(classFile, method->GetClass()->GetName()); + classFile << "::</span>"; } + ReplaceSpecialChars(classFile, method->GetName()); + classFile << "</a>"; + + ExpandKeywords(classFile, const_cast<TMethod*>(method)->GetSignature()); + classFile << "</td></tr>" << endl; } + classFile << endl << "</table></div>" << endl; } - delete[]fMethodNames; - - classFile << "</pre>" << endl; + classFile << "</div>" << endl; // class="functions" // make a loop on data members first = kFALSE; @@ -1015,7 +1039,7 @@ void THtml::Class2Html(Bool_t force) TIter nextMember(fCurrentClass->GetListOfDataMembers()); - Int_t len1, len2, maxLen1[3], maxLen2[3]; + Int_t len1, len2, maxLen1[3], maxLen2[3], mtype, num[3], i, j; len1 = len2 = maxLen1[0] = maxLen1[1] = maxLen1[2] = 0; maxLen2[0] = maxLen2[1] = maxLen2[2] = 0; mtype = num[0] = num[1] = num[2] = 0; @@ -1252,7 +1276,7 @@ void THtml::BeautifyLine(std::ostream &sOut) EBeautifyContext context = kNothingSpecialMoveOn; - switch (fParseContext) { + switch (fParseContext.back()) { case kCode: context = kNothingSpecialMoveOn; if (fLineStripped.Length() && fLineStripped[0] == '#') { @@ -1309,7 +1333,6 @@ void THtml::BeautifyLine(std::ostream &sOut) } if (context == kNothingSpecialMoveOn || context == kCommentC) { context = kCommentC; - fParseContext = kCComment; Ssiz_t posEndComment = lineExpandedDotDot.Index("*/", i); if (posEndComment == kNPOS) posEndComment = lineExpandedDotDot.Length(); @@ -1332,7 +1355,10 @@ void THtml::BeautifyLine(std::ostream &sOut) context == kNothingSpecialMoveOn)) { sOut << "*/"; context = kNothingSpecialMoveOn; - fParseContext = kCode; + fParseContext.pop_back(); + if (fParseContext.empty()) + fParseContext.push_back(kCode); + i += 1; } else sOut << "*"; @@ -1360,7 +1386,7 @@ TMethod* THtml::LocateMethodInCurrentLine(Ssiz_t &posMethodName, TString& ret, T Ssiz_t posBlock = fLine.Index('{'); if (posBlock == kNPOS) posBlock = fLine.Length(); - for (MethodNames_t::iterator iMethodName = fMethodNames.begin(); + for (MethodCount_t::iterator iMethodName = fMethodNames.begin(); !name.Length() && iMethodName != fMethodNames.end(); ++iMethodName) { TString lookFor(iMethodName->first); lookFor += "("; @@ -1438,7 +1464,7 @@ TMethod* THtml::LocateMethodInCurrentLine(Ssiz_t &posMethodName, TString& ret, T params = name(posParam, name.Length() - posParam); name.Remove(posParam); - MethodNames_t::const_iterator iMethodName = fMethodNames.find(name.Data()); + MethodCount_t::const_iterator iMethodName = fMethodNames.find(name.Data()); if (iMethodName == fMethodNames.end() || iMethodName->second <= 0) { ret.Remove(0); name.Remove(0); @@ -1567,7 +1593,7 @@ void THtml::WriteMethod(std::ostream & out, TString& ret, } out << "</div>" << std::endl; - MethodNames_t::iterator iMethodName = fMethodNames.find(name.Data()); + MethodCount_t::iterator iMethodName = fMethodNames.find(name.Data()); if (iMethodName != fMethodNames.end()) { --(iMethodName->second); if (iMethodName->second <= 0) @@ -1593,12 +1619,9 @@ Bool_t THtml::ExtractComments(const TString &lineExpandedStripped, // updating whether a class description was found (foundClassDescription). // Returns kTRUE if comment found. - //if (fParseContext != kCComment && fParseContext != kBeginEndHtml && - // fParseContext != kBeginEndHtmlInCComment) - // return kFALSE; - if (fParseContext != kBeginEndHtml && - fParseContext != kBeginEndHtmlInCComment && - fParseContext != kCComment && + if (fParseContext.back() != kBeginEndHtml && + fParseContext.back() != kBeginEndHtmlInCComment && + fParseContext.back() != kCComment && !lineExpandedStripped.BeginsWith("<span class=\"comment\">")) return kFALSE; @@ -1638,7 +1661,7 @@ Bool_t THtml::ExtractComments(const TString &lineExpandedStripped, // remove leading and trailing chars if non-word and identical, e.g. // * some doc *, or // some doc // - while (fParseContext != kBeginEndHtml && fParseContext != kBeginEndHtmlInCComment && + while (fParseContext.back() != kBeginEndHtml && fParseContext.back() != kBeginEndHtmlInCComment && commentLine.Length() > 2 && commentLine[0] == commentLine[commentLine.Length() - 1] && (commentLine[0] == '/' || commentLine[0] == '*')) { @@ -1733,7 +1756,8 @@ void THtml::LocateMethods(std::ofstream & out, const char* filename, srcHtmlOutName += ".h.html"; } - fParseContext = kCode; + fParseContext.clear(); + fParseContext.push_back(kCode); fDocContext = kIgnore; fLineNo = 0; @@ -1843,7 +1867,8 @@ void THtml::LocateMethods(std::ofstream & out, const char* filename, srcHtmlOut << "</pre>" << std::endl; WriteHtmlFooter(srcHtmlOut, "../"); - fParseContext = kCode; + fParseContext.clear(); + fParseContext.push_back(kCode); fDocContext = kIgnore; } @@ -2316,6 +2341,7 @@ void THtml::CreateIndex(const char **classNames, Int_t numberOfClasses) // create CSS file, we need it CreateStyleSheet(); + CreateJavascript(); // open indexFile file ofstream indexFile; @@ -3057,6 +3083,81 @@ void THtml::CreateListOfTypes() delete[]outFile; } +//______________________________________________________________________________ +void THtml::CreateJavascript() { + // Write the default ROOT style sheet. + + // open file + ofstream js; + + gSystem->ExpandPathName(fOutputDir); + char *outFile = gSystem->ConcatFileName(fOutputDir, "ROOT.js"); + js.open(outFile, ios::out); + if (!js.good()) { + delete []outFile; + return; + } + js << "function SetCSSValue(where,what,to){" << endl + << "if(document.all) r='rules';" << endl + << "else r='cssRules';" << endl + << "for(i=0;i<document.styleSheets.length;++i) " << endl + << " for(j=0;j<document.styleSheets[i][r].length;++j)" << endl + << " if(document.styleSheets[i][r][j].selectorText==where) {" << endl + << " document.styleSheets[i][r][j].style[what]=to;" << endl + << " return;" << endl + << " }" << endl + << "}" << endl + << "var elements=new Array('dispoptCBInh.checked','dispoptCBPub.checked');" << endl + << "function SetValuesFromCookie() {" << endl + << " prev=0;" << endl + << " arrcookie=document.cookie.split(\";\");" << endl + << " for(i=0; i<arrcookie.length; ++i) {" << endl + << " while(arrcookie[i].charAt(0)==' ') " << endl + << " arrcookie[i]=arrcookie[i].substring(1,arrcookie[i].length);" << endl + << " if (arrcookie[i].indexOf(\"ROOT\")==0) {" << endl + << " var arrval=arrcookie[i].substring(5).split(':');" << endl + << " for (i=0; i<arrval.length; ++i) {" << endl + << " posdelim=elements[i].indexOf(\".\");" << endl + << " what=elements[i].substring(0,posdelim);" << endl + << " mem =elements[i].substring(posdelim+1);" << endl + << " val=arrval[i];" << endl + << " if (val=='false') val=false;" << endl + << " else if (val=='true') vale=true;" << endl + << " var el=document.getElementById(what);" << endl + << " el[mem]=val;" << endl + << " CBChanged(el);" << endl + << " }" << endl + << " return;" << endl + << " }" << endl + << " }" << endl + << "}" << endl + << "function UpdateCookie() {" << endl + << " cookietxt=\"ROOT=\";" << endl + << " for (i=0; i<elements.length; ++i) {" << endl + << " posdelim=elements[i].indexOf(\".\");" << endl + << " what=elements[i].substring(0,posdelim);" << endl + << " mem =elements[i].substring(posdelim+1);" << endl + << " val=document.getElementById(what)[mem];" << endl + << " if (i>0) cookietxt+=':';" << endl + << " cookietxt+=val;" << endl + << " }" << endl + << " var ayear=new Date();" << endl + << " ayear.setTime(ayear.getTime()+31536000000);" << endl + << " cookietxt+=\";path=/;expires=\"+ayear.toUTCString();" << endl + << " document.cookie=cookietxt;" << endl + << "}" << endl + << "function CBChanged(cb){" << endl + << " if(cb.id=='dispoptCBInh') SetCSSValue('tr.funcinh','display',cb.checked?'':'none');" << endl + << " else if(cb.id=='dispoptCBPub') {" << endl + << " SetCSSValue('#funcprot','display',cb.checked?'':'none');" << endl + << " SetCSSValue('#funcpriv','display',cb.checked?'':'none');" << endl + << " }" << endl + << " UpdateCookie();" << endl + << "}" << endl + << "" << endl; + delete []outFile; +} + //______________________________________________________________________________ void THtml::CreateStyleSheet() { @@ -3190,7 +3291,6 @@ void THtml::CreateStyleSheet() { << " margin-left: 0.3em;" << std::endl << " padding-left: 1em;" << std::endl << " margin-bottom: 2em;" << std::endl - << " /*border-bottom: solid 1px Black;*/" << std::endl << " border-bottom: solid 3px #cccccc;" << std::endl << " border-left: solid 1px #cccccc;" << std::endl << " background-color: White;" << std::endl @@ -3212,15 +3312,56 @@ void THtml::CreateStyleSheet() { << " border: solid 1px Black;" << std::endl << " width: 100%;" << std::endl << "}" << std::endl - << "table.libinfo " << std::endl - << "{" << std::endl + << "table.libinfo {" << std::endl << " background-color: White;" << std::endl << " padding: 2px;" << std::endl << " border: solid 1px Gray; " << std::endl << " float: right;" << std::endl - << "}" << std::endl; - } - delete outFile; + << "}" << std::endl + << "#functions div {" << std::endl + << " margin-top: 2em;" << std::endl + << "}" << std::endl + << " div.access {" << std::endl + << " border-left: solid 3pt black;" << std::endl + << " padding-left: 1em;" << std::endl + << " margin-left: 1em;" << std::endl + << " margin-bottom: 1em;" << std::endl + << "}" << std::endl + << "#funcpubl {" << std::endl + << " border-left-color: #77ff77;" << std::endl + << "}" << std::endl + << " #funcprot {" << std::endl + << " border-left-color: #ffff00;" << std::endl + << "}" << std::endl + << "#funcpriv {" << std::endl + << " border-left-color: #ff7777;" << std::endl + << "}" << std::endl + << "tr.func {" << std::endl + << " white-space: nowrap;" << std::endl + << "}" << std::endl + << "tr.funcinh {" << std::endl + << " display: none;" << std::endl + << " white-space: nowrap;" << std::endl + << "}" << std::endl + << "span.baseclass {" << std::endl + << " font-size:x-small;" << std::endl + << "}" << std::endl + << "td.funcret {" << std::endl + << " float: right;" << std::endl + << " padding-right: 0.5em;" << std::endl + << "}" << std::endl + << "#dispopt {" << std::endl + << " background-color: White;" << std::endl + << " padding: 2px;" << std::endl + << " border: solid 1px Gray; " << std::endl + << " float: right;" << std::endl + << " position: relative;" << std::endl + << " top: -5em;" << std::endl + << " z-index: 2;" << std::endl + << "}" << std::endl + << std::endl; + } + delete []outFile; } @@ -3258,7 +3399,7 @@ void THtml::ExpandKeywords(TString& keyword) scoping = kNada; // skip until start of the word - if (fParseContext == kCode || fParseContext == kCComment) { + if (fParseContext.back() == kCode || fParseContext.back() == kCComment) { if (!strncmp(keyword.Data() + i, "::", 2)) { scoping = kScope; i += 2; @@ -3274,11 +3415,11 @@ void THtml::ExpandKeywords(TString& keyword) } else currentType = 0; if (!IsWord(keyword[i])){ - if (fParseContext != kBeginEndHtml && fParseContext != kBeginEndHtmlInCComment) { - Bool_t closeString = !fEscFlag && fParseContext == kString && + if (fParseContext.back() != kBeginEndHtml && fParseContext.back() != kBeginEndHtmlInCComment) { + Bool_t closeString = !fEscFlag && fParseContext.back() == kString && ( keyword[i] == '"' || keyword[i] == '\''); if (!fEscFlag) - if (fParseContext == kCode || fParseContext == kCComment) + if (fParseContext.back() == kCode || fParseContext.back() == kCComment) if (keyword.Length() > i + 1 && keyword[i] == '"' || keyword[i] == '\'' && ( // 'a' @@ -3287,20 +3428,23 @@ void THtml::ExpandKeywords(TString& keyword) keyword.Length() > i + 3 && keyword[i + 1] == '\'' && keyword[i + 3] == '\'')) { keyword.Insert(i, "<span class=\"string\">"); i += 21; - fParseContext = kString; + fParseContext.push_back(kString); currentType = 0; - } else if (fParseContext != kCComment && + } else if (fParseContext.back() != kCComment && keyword.Length() > i + 1 && keyword[i] == '/' && (keyword[i+1] == '/' || keyword[i+1] == '*')) { - fParseContext = kCComment; + fParseContext.push_back(kCComment); commentIsCPP = keyword[i+1] == '/'; currentType = 0; keyword.Insert(i, "<span class=\"comment\">"); i += 23; - } else if (fParseContext == kCComment && !commentIsCPP + } else if (fParseContext.back() == kCComment && !commentIsCPP && keyword.Length() > i + 1 && keyword[i] == '*' && keyword[i+1] == '/') { - fParseContext = kCode; + fParseContext.pop_back(); + if (fParseContext.empty()) + fParseContext.push_back(kCode); + currentType = 0; keyword.Insert(i + 2, "</span>"); i += 9; @@ -3310,7 +3454,10 @@ void THtml::ExpandKeywords(TString& keyword) if (closeString) { keyword.Insert(i, "</span>"); i += 7; - fParseContext = kCode; + fParseContext.pop_back(); + if (fParseContext.empty()) + fParseContext.push_back(kCode); + currentType = 0; } --i; // i already moved by ReplaceSpecialChar @@ -3347,8 +3494,8 @@ void THtml::ExpandKeywords(TString& keyword) while (endWord < keyword.Length() && IsName(keyword[endWord])) endWord++; - if (fParseContext != kCode && fParseContext != kCComment && - fParseContext != kBeginEndHtml && fParseContext != kBeginEndHtmlInCComment) { + if (fParseContext.back() != kCode && fParseContext.back() != kCComment && + fParseContext.back() != kBeginEndHtml && fParseContext.back() != kBeginEndHtmlInCComment) { // don't replace in strings, cpp, etc i = endWord - 1; continue; @@ -3357,10 +3504,10 @@ void THtml::ExpandKeywords(TString& keyword) TString word(keyword(i, endWord - i)); // check if this is a HTML block - if (fParseContext == kBeginEndHtml || fParseContext == kBeginEndHtmlInCComment) { + if (fParseContext.back() == kBeginEndHtml || fParseContext.back() == kBeginEndHtmlInCComment) { if (!word.CompareTo("end_html", TString::kIgnoreCase) && (i == 0 || keyword[i - 1] != '\"')) { - if (fParseContext == kBeginEndHtmlInCComment) + if (fParseContext.back() == kBeginEndHtmlInCComment) commentIsCPP = kFALSE; else { commentIsCPP = kTRUE; @@ -3371,7 +3518,9 @@ void THtml::ExpandKeywords(TString& keyword) i += 22; } } - fParseContext = kCComment; + fParseContext.pop_back(); + if (fParseContext.back() != kCComment) + fParseContext.push_back(kCComment); pre_is_open = kTRUE; keyword.Replace(i, word.Length(), "<pre>"); i += 4; @@ -3380,13 +3529,13 @@ void THtml::ExpandKeywords(TString& keyword) currentType = 0; continue; } - if (fParseContext == kCComment + if (fParseContext.back() == kCComment && !word.CompareTo("begin_html", TString::kIgnoreCase) && (i == 0 || keyword[i - 1] != '\"')) { if (commentIsCPP) - fParseContext = kBeginEndHtml; + fParseContext.push_back(kBeginEndHtml); else - fParseContext = kBeginEndHtmlInCComment; + fParseContext.push_back(kBeginEndHtmlInCComment); pre_is_open = kFALSE; keyword.Replace(i, word.Length(), "</pre>"); i += 5; @@ -3395,7 +3544,7 @@ void THtml::ExpandKeywords(TString& keyword) } // don't replace keywords in comments - if (fParseContext == kCode && + if (fParseContext.back() == kCode && fgKeywords.find(word.Data()) != fgKeywords.end()) { keyword.Insert(i, "<span class=\"keyword\">"); i += 22 + word.Length(); @@ -3522,22 +3671,27 @@ void THtml::ExpandKeywords(TString& keyword) --i; // due to ++i } // while i < keyword.Length() - // clean up, no CPP comment across lines - if (commentIsCPP) { + // clean up, no strings across lines + if (fParseContext.back() == kString) { keyword += "</span>"; i += 7; - if (fParseContext == kCComment) // and not BeginEndHtml - fParseContext = kCode; + fParseContext.pop_back(); + if (fParseContext.empty()) + fParseContext.push_back(kCode); currentType = 0; } - - // clean up, no strings across lines - if (fParseContext == kString) { + // clean up, no CPP comment across lines + if (commentIsCPP) { keyword += "</span>"; i += 7; - fParseContext = kCode; + if (fParseContext.back() == kCComment) {// and not BeginEndHtml + fParseContext.pop_back(); + if (fParseContext.empty()) + fParseContext.push_back(kCode); + } currentType = 0; } + } @@ -4209,10 +4363,11 @@ void THtml::WriteHtmlHeader(ofstream & out, const char *title, out << "<meta name=\"description\" content=\"ROOT - An Object Oriented Framework For Large Scale Data Analysis.\" />" << endl; - out << "<link rel=\"stylesheet\" href=\"" << dir << "ROOT.css\" type=\"text/css\" id=\"ROOTstyle\" />" << endl; + out << "<link rel=\"stylesheet\" type=\"text/css\" href=\"" << dir << "ROOT.css\" id=\"ROOTstyle\" />" << endl; + out << "<script type=\"text/javascript\" src=\"ROOT.js\"></script>" << endl; out << "</head>" << endl; - out << "<body>" << endl; + out << "<body onload=\"javascript:SetValuesFromCookie();\">" << endl; }; // do we have an additional header? if (addHeader && strlen(addHeader) > 0) { -- GitLab