ROOT  6.06/09
Reference Guide
TDocParser_002.C
Go to the documentation of this file.
1 
3  Ssiz_t& copiedToCommentUpTo)
4 {
5  Bool_t begin = kTRUE;
6  TClass* clDirective = IsDirective(line, pos, word, begin);
7  if (!clDirective)
8  return kFALSE;
9 
10  // we'll need end later on: afer the begin block, both end _and_ begin can be true.
11  Bool_t end = !begin;
12 
13  TDocDirective* directive = 0; // allow re-use of object from begin block in end
14 
15  if (begin) {
16  // copy from fLineSource to fLineComment, starting at copiedToCommentUpTo
17  if (InContext(kDirective))
18  ((TDocDirective*)fDirectiveHandlers.Last())->AddLine(fLineSource(copiedToCommentUpTo, pos - copiedToCommentUpTo));
19  else
20  fLineComment += fLineSource(copiedToCommentUpTo, pos - copiedToCommentUpTo);
21  copiedToCommentUpTo = pos;
22 
23  pos += word.Length(); // skip the keyword
24 
25  directive = (TDocDirective*) clDirective->New();
26  if (!directive)
27  return kFALSE;
28 
29  directive->SetParser(this);
31  directive->SetTag(fCurrentMethodTag);
32  directive->SetCounter(fDirectiveCount++);
33 
34  // parse parameters
35  TString params;
36  if (begin && line[pos] == '(') {
37  std::list<char> waitForClosing;
38  Ssiz_t endParam = pos + 1;
39  for (; endParam < line.Length()
40  && (line[endParam] != ')' || !waitForClosing.empty()); ++endParam) {
41  const char c = line[endParam];
42  if (!waitForClosing.empty() && waitForClosing.back() == c) {
43  waitForClosing.pop_back();
44  continue;
45  }
46  switch (c) {
47  case '"':
48  if (waitForClosing.empty() || waitForClosing.back() != '\'')
49  waitForClosing.push_back('"');
50  break;
51  case '\'':
52  if (waitForClosing.empty() || waitForClosing.back() != '"')
53  waitForClosing.push_back('\'');
54  break;
55  case '(':
56  if (waitForClosing.empty() || (waitForClosing.back() != '"' && waitForClosing.back() != '\''))
57  waitForClosing.push_back(')');
58  break;
59  case '\\':
60  ++endParam; // skip next char
61  default:
62  break;
63  };
64  }
65  if (waitForClosing.empty()) {
66  params = line(pos + 1, endParam - (pos + 1));
67  pos += params.Length() + 2; // params + parentheses
68  }
69  directive->SetParameters(params);
70  }
71 
72  // check for end tag in current line
73  Ssiz_t posEndTag = pos;
74  const char* endTag = directive->GetEndTag();
75  Ssiz_t lenEndTag = strlen(endTag);
76  while (kNPOS != (posEndTag = line.Index(endTag, posEndTag, TString::kIgnoreCase))) {
77  if (line[posEndTag - 1] == '"') {
78  posEndTag += lenEndTag;
79  continue; // escaping '"'
80  }
81  break;
82  }
83  if (posEndTag != kNPOS) {
84  end = kTRUE; // we just continue below!
85  } else {
86  fDirectiveHandlers.AddLast(directive);
87 
88  fParseContext.push_back(kDirective);
90  fParseContext.back() |= kCXXComment;
91 
92  posEndTag = line.Length();
93  }
94 
95  directive->AddLine(line(pos, posEndTag - pos));
96  TString remainder(line(posEndTag, line.Length()));
97  line.Remove(posEndTag, line.Length());
98 
99  while (pos < line.Length())
100  fDocOutput->ReplaceSpecialChars(line, pos);
101 
102  pos = line.Length();
103  // skip the remainder of the line
104  copiedToCommentUpTo = line.Length();
105  line += remainder;
106  }
107 
108  // no else - "end" can also be set by begin having an end tag!
109  if (end) {
110 
111  if (!begin)
112  pos += word.Length(); // skip the keyword
113  else pos += word.Length() - 2; // "Begin" is 2 chars longer than "End"
114 
115  if (!directive) directive = (TDocDirective*) fDirectiveHandlers.Last();
116 
117  if (!directive) {
118  Warning("HandleDirective", "Cannot find directive handler object %s !",
119  fLineRaw.Data());
120  return kFALSE;
121  }
122 
123  if (!begin) {
124  Ssiz_t start = 0;
126  // means we are in a C++ comment
127  while (isspace((UChar_t)fLineRaw[start])) ++start;
128  if (fLineRaw[start] == '/' && fLineRaw[start + 1] == '/')
129  start += 2;
130  else start = 0;
131  }
132  directive->AddLine(line(start, pos - word.Length() - start));
133 
134  TString remainder(line(pos, line.Length()));
135  line.Remove(pos, line.Length());
137  pos = line.Length();
138  line += remainder;
139  }
140  copiedToCommentUpTo = pos;
141 
142  TString result;
143  directive->GetResult(result);
144 
145  if (!begin)
147  delete directive;
148 
149  if (!begin) {
150  // common to all directives: pop context
151  Bool_t isInCxxComment = InContext(kDirective) & kCXXComment;
152  if (fParseContext.size()>1)
153  fParseContext.pop_back();
154  if (isInCxxComment && !InContext(kComment)) {
155  fParseContext.push_back(kComment | kCXXComment);
157  }
158  }
159 
161  ((TDocDirective*)fDirectiveHandlers.Last())->AddLine(result(0, result.Length()));
162  else
163  fLineComment += result;
164 
165  /* NO - this can happen e.g. for "BEGIN_HTML / *..." (see doc in this class)
166  if (Context() != kComment) {
167  Warning("HandleDirective", "Popping back a directive context, but enclosing context is not a comment! At:\n%s",
168  fLineRaw.Data());
169  fParseContext.push_back(kComment);
170  }
171  */
172  }
173 
174  return kTRUE;
175 }
176 
177 ////////////////////////////////////////////////////////////////////////////////
178 /// checks whether we are in a parse context, return the entry closest
179 /// to the current context.
180 /// If context is a EParseContextFlag just look for the first match in
181 /// the flags
182 
184 {
185  UInt_t lowerContext = context & kParseContextMask;
186  UInt_t contextFlag = context & kParseContextFlagMask;
187 
188  for (std::list<UInt_t>::const_reverse_iterator iPC = fParseContext.rbegin();
189  iPC != fParseContext.rend(); ++iPC)
190  if (!lowerContext || ((lowerContext && ((*iPC & kParseContextMask) == lowerContext))
191  && (!contextFlag || (contextFlag && (*iPC & contextFlag)))))
192  return *iPC;
193 
194  return 0;
195 }
196 
197 ////////////////////////////////////////////////////////////////////////////////
198 /// fill C++ keywords into fgKeywords
199 
201 {
202  if (!fgKeywords.empty())
203  return;
204 
205  fgKeywords.insert("asm");
206  fgKeywords.insert("auto");
207  fgKeywords.insert("bool");
208  fgKeywords.insert("break");
209  fgKeywords.insert("case");
210  fgKeywords.insert("catch");
211  fgKeywords.insert("char");
212  fgKeywords.insert("class");
213  fgKeywords.insert("const");
214  fgKeywords.insert("const_cast");
215  fgKeywords.insert("continue");
216  fgKeywords.insert("default");
217  fgKeywords.insert("delete");
218  fgKeywords.insert("do");
219  fgKeywords.insert("double");
220  fgKeywords.insert("dynamic_cast");
221  fgKeywords.insert("else");
222  fgKeywords.insert("enum");
223  fgKeywords.insert("explicit");
224  fgKeywords.insert("export");
225  fgKeywords.insert("extern");
226  fgKeywords.insert("false");
227  fgKeywords.insert("float");
228  fgKeywords.insert("for");
229  fgKeywords.insert("friend");
230  fgKeywords.insert("goto");
231  fgKeywords.insert("if");
232  fgKeywords.insert("inline");
233  fgKeywords.insert("int");
234  fgKeywords.insert("long");
235  fgKeywords.insert("mutable");
236  fgKeywords.insert("namespace");
237  fgKeywords.insert("new");
238  fgKeywords.insert("operator");
239  fgKeywords.insert("private");
240  fgKeywords.insert("protected");
241  fgKeywords.insert("public");
242  fgKeywords.insert("register");
243  fgKeywords.insert("reinterpret_cast");
244  fgKeywords.insert("return");
245  fgKeywords.insert("short");
246  fgKeywords.insert("signed");
247  fgKeywords.insert("sizeof");
248  fgKeywords.insert("static");
249  fgKeywords.insert("static_cast");
250  fgKeywords.insert("struct");
251  fgKeywords.insert("switch");
252  fgKeywords.insert("template");
253  fgKeywords.insert("this");
254  fgKeywords.insert("throw");
255  fgKeywords.insert("true");
256  fgKeywords.insert("try");
257  fgKeywords.insert("typedef");
258  fgKeywords.insert("typeid");
259  fgKeywords.insert("typename");
260  fgKeywords.insert("union");
261  fgKeywords.insert("unsigned");
262  fgKeywords.insert("using");
263  fgKeywords.insert("virtual");
264  fgKeywords.insert("void");
265  fgKeywords.insert("volatile");
266  fgKeywords.insert("wchar_t");
267  fgKeywords.insert("while");
268 }
269 
270 ////////////////////////////////////////////////////////////////////////////////
271 /// return whether word at line's pos is a valid directive, and returns its
272 /// TDocDirective's TClass object, or 0 if it's not a directive. Set begin
273 /// to kTRUE for "Begin_..."
274 /// You can implement your own handlers by implementing a class deriving
275 /// from TDocHandler, and calling it TDocTagDirective for "BEGIN_TAG",
276 /// "END_TAG" blocks.
277 
279  const TString& word, Bool_t& begin) const
280 {
281  // '"' serves as escape char
282  if (pos > 0 && line[pos - 1] == '"')
283  return 0;
284 
285  begin = word.BeginsWith("begin_", TString::kIgnoreCase);
286  Bool_t end = word.BeginsWith("end_", TString::kIgnoreCase);
287 
288  if (!begin && !end)
289  return 0;
290 
291  /* NO - we can have "BEGIN_HTML / * ..."
292  if (!InContext(kComment))
293  return 0;
294  */
295 
296  TString tag = word( begin ? 6 : 4, word.Length());
297 
298  if (!tag.Length())
299  return 0;
300 
301  tag.ToLower();
302  tag[0] -= 'a' - 'A'; // first char is caps
303  tag.Prepend("TDoc");
304  tag += "Directive";
305 
306  TClass* clDirective = TClass::GetClass(tag, kFALSE);
307 
308  if (gDebug > 0 && !clDirective)
309  Warning("IsDirective", "Unknown THtml directive %s in line %d!", word.Data(), fLineNo);
310 
311  return clDirective;
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Check if c is a valid C++ name character
316 ///
317 ///
318 /// Input: c - a single character
319 ///
320 /// Output: TRUE if c is a valid C++ name character
321 /// and FALSE if it's not.
322 ///
323 /// NOTE: Valid name characters are [a..zA..Z0..9_~],
324 ///
325 
327 {
328  Bool_t ret = kFALSE;
329 
330  if (isalnum(c) || c == '_' || c == '~')
331  ret = kTRUE;
332 
333  return ret;
334 }
335 
336 
337 ////////////////////////////////////////////////////////////////////////////////
338 /// Check if c is a valid first character for C++ name
339 ///
340 ///
341 /// Input: c - a single character
342 ///
343 /// Output: TRUE if c is a valid first character for C++ name,
344 /// and FALSE if it's not.
345 ///
346 /// NOTE: Valid first characters are [a..zA..Z_~]
347 ///
348 
350 {
351  Bool_t ret = kFALSE;
352 
353  if (isalpha(c) || c == '_' || c == '~')
354  ret = kTRUE;
355 
356  return ret;
357 }
358 
359 
360 ////////////////////////////////////////////////////////////////////////////////
361 /// Search for a method starting at posMethodName, and return its return type,
362 /// its name, and its arguments. If the end of arguments is not found in the
363 /// current line, get a new line from sourceFile, beautify it to srcOut, creating
364 /// an anchor as necessary. When this function returns, posMethodName points to the
365 /// end of the function declaration, i.e. right after the arguments' closing bracket.
366 /// If posMethodName == kNPOS, we look for the first matching method in fMethodCounts.
367 
369  TString& name, TString& params,
370  Bool_t& isconst, std::ostream &srcOut,
371  TString &anchor, std::ifstream& sourceFile,
372  Bool_t allowPureVirtual)
373 {
374  typedef std::map<std::string /*method name*/, Int_t > MethodCount_t;
375  isconst = false;
376 
377  if (posMethodName == kNPOS) {
378  name.Remove(0);
379  TMethod * meth = 0;
380  Ssiz_t posBlock = fLineRaw.Index('{');
381  Ssiz_t posQuote = fLineRaw.Index('"');
382  if (posQuote != kNPOS && (posBlock == kNPOS || posQuote < posBlock))
383  posBlock = posQuote;
384  if (posBlock == kNPOS)
385  posBlock = fLineRaw.Length();
386  for (MethodCount_t::iterator iMethodName = fMethodCounts.begin();
387  !name.Length() && iMethodName != fMethodCounts.end(); ++iMethodName) {
388  TString lookFor(iMethodName->first);
389  posMethodName = fLineRaw.Index(lookFor);
390  if (posMethodName != kNPOS && posMethodName < posBlock
391  && (posMethodName == 0 || !IsWord(fLineRaw[posMethodName - 1]))) {
392  // check whether the method name is followed by optional spaces and
393  // an opening parathesis
394  Ssiz_t posMethodEnd = posMethodName + lookFor.Length();
395  while (isspace((UChar_t)fLineRaw[posMethodEnd])) ++posMethodEnd;
396  if (fLineRaw[posMethodEnd] == '(') {
397  meth = LocateMethodInCurrentLine(posMethodName, ret, name, params, isconst,
398  srcOut, anchor, sourceFile, allowPureVirtual);
399  if (name.Length())
400  return meth;
401  }
402  }
403  }
404  return 0;
405  }
406 
407  name = fLineRaw(posMethodName, fLineRaw.Length() - posMethodName);
408 
409  // extract return type
410  ret = fLineRaw(0, posMethodName);
411  if (ret.Length()) {
412  while (ret.Length() && (IsName(ret[ret.Length() - 1]) || ret[ret.Length()-1] == ':'))
413  ret.Remove(ret.Length() - 1, 1);
414  Strip(ret);
415  Bool_t didSomething = kTRUE;
416  while (didSomething) {
417  didSomething = kFALSE;
418  if (ret.BeginsWith("inline ")) {
419  didSomething = kTRUE;
420  ret.Remove(0, 7);
421  }
422  if (ret.BeginsWith("static ")) {
423  didSomething = kTRUE;
424  ret.Remove(0, 7);
425  }
426  if (ret.BeginsWith("virtual ")) {
427  didSomething = kTRUE;
428  ret.Remove(0, 8);
429  }
430  } // while replacing static, virtual, inline
431  Strip(ret);
432  }
433 
434  // extract parameters
435  Ssiz_t posParam = name.First('(');
436  if (posParam == kNPOS ||
437  // no strange return types, please
438  ret.Contains("{") || ret.Contains("}") || ret.Contains("(") || ret.Contains(")")
439  || ret.Contains("=")) {
440  ret.Remove(0);
441  name.Remove(0);
442  params.Remove(0);
443  return 0;
444  }
445 
446  if (name.BeginsWith("operator")) {
447  // op () (...)
448  Ssiz_t checkOpBracketParam = posParam + 1;
449  while (isspace((UChar_t)name[checkOpBracketParam]))
450  ++checkOpBracketParam;
451  if (name[checkOpBracketParam] == ')') {
452  ++checkOpBracketParam;
453  while (isspace((UChar_t)name[checkOpBracketParam]))
454  ++checkOpBracketParam;
455  if (name[checkOpBracketParam] == '(')
456  posParam = checkOpBracketParam;
457  }
458  } // check for op () (...)
459 
460  if (posParam == kNPOS) {
461  ret.Remove(0);
462  name.Remove(0);
463  params.Remove(0);
464  return 0;
465  }
466 
467  params = name(posParam, name.Length() - posParam);
468  name.Remove(posParam);
469  while (name.Length() && isspace((UChar_t)name[name.Length() - 1]))
470  name.Remove(name.Length() - 1);
471  if (!name.Length()) {
472  ret.Remove(0);
473  name.Remove(0);
474  params.Remove(0);
475  return 0;
476  }
477 
478  MethodCount_t::const_iterator iMethodName = fMethodCounts.find(name.Data());
479  if (iMethodName == fMethodCounts.end() || iMethodName->second <= 0) {
480  ret.Remove(0);
481  name.Remove(0);
482  params.Remove(0);
483  return 0;
484  }
485 
486  // find end of param
487  Ssiz_t posParamEnd = 1;
488  Int_t bracketLevel = 1;
489  while (bracketLevel) {
490  const char* paramEnd = strpbrk(params.Data() + posParamEnd, ")(\"'");
491  if (!paramEnd) {
492  // func with params over multiple lines
493  // gotta write out this line before it gets lost
494  if (!anchor.Length()) {
495  // request an anchor, just in case...
496  AnchorFromLine(fLineStripped, anchor);
497  if (srcOut)
498  srcOut << "<a name=\"" << anchor << "\"></a>";
499  }
500  ++fLineNumber;
501  if (srcOut)
502  WriteSourceLine(srcOut);
503 
504  fLineRaw.ReadLine(sourceFile, kFALSE);
505  if (sourceFile.eof()) {
506  Error("LocateMethodInCurrentLine",
507  "Cannot find end of signature for function %s!",
508  name.Data());
509  break;
510  }
511 
513 
514  // replace class names etc
517 
520 
521  posParamEnd = params.Length();
522  params += fLineRaw;
523  } else
524  posParamEnd = paramEnd - params.Data();
525  switch (params[posParamEnd]) {
526  case '(': ++bracketLevel; ++posParamEnd; break;
527  case ')': --bracketLevel; ++posParamEnd; break;
528  case '"': // skip ")"
529  ++posParamEnd;
530  while (params.Length() > posParamEnd && params[posParamEnd] != '"') {
531  // skip '\"'
532  if (params[posParamEnd] == '\\') ++posParamEnd;
533  ++posParamEnd;
534  }
535  if (params.Length() <= posParamEnd) {
536  // something is seriously wrong - skip :-/
537  ret.Remove(0);
538  name.Remove(0);
539  params.Remove(0);
540  return 0;
541  }
542  ++posParamEnd; // skip trailing '"'
543  break;
544  case '\'': // skip ')'
545  ++posParamEnd;
546  if (params[posParamEnd] == '\\') ++posParamEnd;
547  posParamEnd += 2;
548  break;
549  default:
550  ++posParamEnd;
551  }
552  } // while bracketlevel, i.e. (...(..)...)
553 
554  {
555  TString pastParams(params(posParamEnd, params.Length()));
556  pastParams = pastParams.Strip(TString::kLeading);
557  isconst = pastParams.BeginsWith("const") && !(isalnum(pastParams[5]) || pastParams[5] == '_');
558  }
559 
560  Ssiz_t posBlock = params.Index('{', posParamEnd);
561  Ssiz_t posSemicolon = params.Index(';', posParamEnd);
562  Ssiz_t posPureVirt = params.Index('=', posParamEnd);
563  if (posSemicolon != kNPOS)
564  if ((posBlock == kNPOS || (posSemicolon < posBlock)) &&
565  (posPureVirt == kNPOS || !allowPureVirtual)
566  && !allowPureVirtual) // allow any "func();" if pv is allowed
567  params.Remove(0);
568 
569  if (params.Length())
570  params.Remove(posParamEnd);
571 
572  if (!params.Length()) {
573  ret.Remove(0);
574  name.Remove(0);
575  return 0;
576  }
577  // update posMethodName to point behind the method
578  posMethodName = posParam + posParamEnd;
579  if (fCurrentClass) {
580  TMethod* meth = fCurrentClass->GetMethodAny(name);
581  if (meth) {
582  fDirectiveCount = 0;
583  fCurrentMethodTag = name + "_";
585  return meth;
586  }
587  }
588 
589  return 0;
590 }
591 
592 
593 ////////////////////////////////////////////////////////////////////////////////
594 /// Locate methods, starting in the source file, then inline, then
595 /// immediately inside the class declaration. While doing that also
596 /// find the class description and special tags like the macro tag etc.
597 
598 void TDocParser::Parse(std::ostream& out)
599 {
601 
603 
607 
608  if (!fSourceInfo[kInfoLastUpdate].Length()) {
609  TDatime date;
611  }
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// Collect methods from the source or header file called filename.
616 /// It generates a beautified version of the source file on the fly;
617 /// the output file is given by the fCurrentClass's name, and sourceExt.
618 /// Documentation is extracted to out.
619 /// lookForSourceInfo: if set, author, lastUpdate, and copyright are
620 /// extracted (i.e. the values contained in fSourceInfo)
621 /// useDocxxStyle: if set, documentation can be in front of the method
622 /// name, not only inside the method. Useful doc Doc++/Doxygen style,
623 /// and inline methods.
624 /// lookForClassDescr: if set, the first line matching the class description
625 /// rules is assumed to be the class description for fCurrentClass; the
626 /// description is written to out.
627 /// methodPattern: if set, methods have to be prepended by this tag. Usually
628 /// the class name + "::". In header files, looking for in-place function
629 /// definitions, this should be 0. In that case, only functions in
630 /// fMethodCounts are searched for.
631 
632 void TDocParser::LocateMethods(std::ostream& out, const char* filename,
633  Bool_t lookForSourceInfo /*= kTRUE*/,
634  Bool_t useDocxxStyle /*= kFALSE*/,
635  Bool_t allowPureVirtual /*= kFALSE*/,
636  const char* methodPattern /*= 0*/,
637  const char* sourceExt /*= 0 */)
638 {
639  TString sourceFileName(filename);
641  if (!sourceFileName.Length()) {
642  fHtml->GetImplFileName(fCurrentClass, kFALSE, sourceFileName);
643  Error("LocateMethods", "Can't find source file '%s' for class %s!",
644  sourceFileName.Data(), fCurrentClass->GetName());
645  return;
646  }
647  std::ifstream sourceFile(sourceFileName.Data());
648  if (!sourceFile || !sourceFile.good()) {
649  Error("LocateMethods", "Can't open file '%s' for reading!", sourceFileName.Data());
650  return;
651  }
652 
653  TPMERegexp patternRE(methodPattern ? methodPattern : "");
654 
655  TString codeOneLiner;
656  TString methodRet;
657  TString methodName;
658  TString methodParam;
659  Bool_t methodIsConst = kFALSE;
660  TString anchor;
661  TString docxxComment;
662 
663  Bool_t wroteMethodNowWaitingForOpenBlock = kFALSE;
664 
665  std::ofstream srcHtmlOut;
666  TString srcHtmlOutName;
667  if (sourceExt && sourceExt[0]) {
668  static_cast<TClassDocOutput*>(fDocOutput)->CreateSourceOutputStream(srcHtmlOut, sourceExt, srcHtmlOutName);
669  fLineNumber = 0;
670  } else {
671  sourceExt = 0;
672  srcHtmlOutName = fCurrentClass->GetName();
673  fDocOutput->NameSpace2FileName(srcHtmlOutName);
674  gSystem->PrependPathName("src", srcHtmlOutName);
675  srcHtmlOutName += ".h.html";
676  }
677 
678  fParseContext.clear();
679  fParseContext.push_back(kCode);
681  fLineNo = 0;
682 
683  while (!sourceFile.eof()) {
684  Bool_t needAnchor = kFALSE;
685 
686  ++fLineNo; // we count fortrany
687 
688  fLineRaw.ReadLine(sourceFile, kFALSE);
689  if (sourceFile.eof()) break;
690 
692 
693  // replace class names etc
696 
698  fLineComment = "";
700 
701  if (!ProcessComment()) {
702  // not a commented line
703 
705  TString strippedComment(fComment);
706  Strip(strippedComment);
707  if (strippedComment.Length() > 0) {
712  }
713  }
715  }
716 
717  Ssiz_t impIdx = fLineStripped.Index("ClassImp(");
718  if (impIdx == 0 && fClassDocState == kClassDoc_LookingHaveSomething) {
720  // take unscoped version
721  Ssiz_t posLastScope = kNPOS;
722  while ((posLastScope = name.Index("::")) != kNPOS)
723  name.Remove(0, posLastScope + 2);
724 
725  Ssiz_t posName = fLineStripped.Index(name, impIdx);
726  if (posName != kNPOS) {
727  Ssiz_t posClosingParen = posName + name.Length();
728  while (isspace(fLineStripped[posClosingParen])) ++posClosingParen;
729  if (fLineStripped[posClosingParen] == ')') {
730  WriteClassDoc(out, kFALSE);
732  }
733  }
734  }
735 
736  if (fLineStripped.Length())
737  // remove last class doc if it not followed by ClassImp
738  // (with optional empty lines in between)
739  fLastClassDoc = "";
740 
741  // write previous method
742  if (methodName.Length() && !wroteMethodNowWaitingForOpenBlock) {
743  TString savedComment;
744  if (useDocxxStyle && docxxComment.Length()) {
745  savedComment = fComment;
746  fComment = docxxComment;
747  }
748  WriteMethod(out, methodRet, methodName, methodParam, methodIsConst,
749  gSystem->BaseName(srcHtmlOutName), anchor, codeOneLiner);
750  docxxComment.Remove(0);
751  if (savedComment[0]) {
752  fComment = savedComment;
753  }
754  }
755 
756  if (!wroteMethodNowWaitingForOpenBlock) {
757  // check for method
758  Ssiz_t posPattern = kNPOS;
759  if (methodPattern) {
760  posPattern = fLineRaw.Index((TPRegexp&)patternRE);
761  }
762  if (posPattern != kNPOS && methodPattern) {
763  // no strings, no blocks in front of function declarations / implementations
764  static const char vetoChars[] = "{\"";
765  for (int ich = 0; posPattern != kNPOS && vetoChars[ich]; ++ich) {
766  Ssiz_t posVeto = fLineRaw.Index(vetoChars[ich]);
767  if (posVeto != kNPOS && posVeto < posPattern)
768  posPattern = kNPOS;
769  }
770  }
771  if (posPattern != kNPOS || !methodPattern) {
772  if (methodPattern) {
773  patternRE.Match(fLineRaw);
774  posPattern += patternRE[0].Length();
775  }
776  LocateMethodInCurrentLine(posPattern, methodRet, methodName,
777  methodParam, methodIsConst, srcHtmlOut,
778  anchor, sourceFile, allowPureVirtual);
779  if (methodName.Length()) {
781  needAnchor = !anchor.Length();
782  if (useDocxxStyle)
783  docxxComment = fComment;
784  fComment.Remove(0);
785  codeOneLiner.Remove(0);
786 
787  wroteMethodNowWaitingForOpenBlock = fLineRaw.Index("{", posPattern) == kNPOS;
788  wroteMethodNowWaitingForOpenBlock &= fLineRaw.Index(";", posPattern) == kNPOS;
789  } else if (fLineRaw.First("{};") != kNPOS)
790  // these chars reset the preceding comment
791  fComment.Remove(0);
792  } // pattern matches - could be a method
793  else
794  fComment.Remove(0);
795  } else {
796  wroteMethodNowWaitingForOpenBlock &= fLineRaw.Index("{") == kNPOS;
797  wroteMethodNowWaitingForOpenBlock &= fLineRaw.Index(";") == kNPOS;
798  } // if !wroteMethodNowWaitingForOpenBlock
799 
800  if (methodName.Length() && !wroteMethodNowWaitingForOpenBlock) {
801  // make sure we don't have more '{' in commentLine than in fLineRaw
802  if (!codeOneLiner.Length() &&
803  fLineSource.CountChar('{') == 1 &&
804  fLineSource.CountChar('}') == 1) {
805  // a one-liner
806  codeOneLiner = fLineSource;
807  codeOneLiner.Remove(0, codeOneLiner.Index('{'));
808  codeOneLiner.Remove(codeOneLiner.Index('}') + 1);
809  }
810  } // if method name and '{'
811  // else not a comment, and we don't need the previous one:
812  else if (!methodName.Length() && !useDocxxStyle)
813  fComment.Remove(0);
814 
815  if (needAnchor || fExtraLinesWithAnchor.find(fLineNo) != fExtraLinesWithAnchor.end()) {
816  AnchorFromLine(fLineStripped, anchor);
817  if (sourceExt)
818  srcHtmlOut << "<a name=\"" << anchor << "\"></a>";
819  }
820  // else anchor.Remove(0); - NO! WriteMethod will need it later!
821  } // if !comment
822 
823  // check for last update,...
824  Ssiz_t posTag = kNPOS;
825  if (lookForSourceInfo)
826  for (Int_t si = 0; si < (Int_t) kNumSourceInfos; ++si)
827  if (!fSourceInfo[si].Length() && (posTag = fLineRaw.Index(fSourceInfoTags[si])) != kNPOS) {
828  fSourceInfo[si] = fLineRaw(posTag + strlen(fSourceInfoTags[si]), fLineRaw.Length() - posTag);
829  if (si == kInfoAuthor)
831  }
832 
833 
834  // write to .cxx.html
835  ++fLineNumber;
836  if (srcHtmlOut)
837  WriteSourceLine(srcHtmlOut);
838  else if (needAnchor)
840  } // while !sourceFile.eof()
841 
842  // deal with last func
843  if (methodName.Length()) {
844  if (useDocxxStyle && docxxComment.Length())
845  fComment = docxxComment;
846  WriteMethod(out, methodRet, methodName, methodParam, methodIsConst,
847  gSystem->BaseName(srcHtmlOutName), anchor, codeOneLiner);
848  docxxComment.Remove(0);
849  } else
850  WriteClassDoc(out);
851 
852  srcHtmlOut << "</pre>" << std::endl;
853 
855 
856  srcHtmlOut << "</div>" << std::endl;
857 
858  fDocOutput->WriteHtmlFooter(srcHtmlOut, "../");
859 
860  fParseContext.clear();
861  fParseContext.push_back(kCode);
863  fCurrentFile = "";
864 }
865 
866 ////////////////////////////////////////////////////////////////////////////////
867 /// Given fCurrentClass, look for methods in its source file,
868 /// and extract documentation to out, while beautifying the source
869 /// file in parallel.
870 
872 {
873  // for Doc++ style
874  Bool_t useDocxxStyle = (fHtml->GetDocStyle() == "Doc++");
875 
877  // take unscoped version
878  Ssiz_t posLastScope = kNPOS;
879  while ((posLastScope = pattern.Index("::")) != kNPOS)
880  pattern.Remove(0, posLastScope + 2);
881  pattern += "::";
882 
883  TString implFileName;
884  if (fHtml->GetImplFileName(fCurrentClass, kTRUE, implFileName)) {
885  LocateMethods(out, implFileName, kFALSE /*source info*/, useDocxxStyle,
886  kFALSE /*allowPureVirtual*/, pattern, ".cxx.html");
887  Ssiz_t posGt = pattern.Index('>');
888  if (posGt != kNPOS) {
889  // template! Re-run with pattern '...<.*>::'
890  Ssiz_t posLt = pattern.Index('<');
891  if (posLt != kNPOS && posLt < posGt) {
892  pattern.Replace(posLt + 1, posGt - posLt - 1, ".*");
893  LocateMethods(out, implFileName, kFALSE /*source info*/, useDocxxStyle,
894  kFALSE /*allowPureVirtual*/, pattern, ".cxx.html");
895  }
896  }
897  }
898 }
899 
900 ////////////////////////////////////////////////////////////////////////////////
901 /// Given fCurrentClass, look for methods in its header file,
902 /// and extract documentation to out.
903 
905 {
906  // for inline methods, always allow doc before func
907  Bool_t useDocxxStyle = kTRUE;
908 
910  // take unscoped version
911  Ssiz_t posLastScope = kNPOS;
912  while ((posLastScope = pattern.Index("::")) != kNPOS)
913  pattern.Remove(0, posLastScope + 1);
914  pattern += "::";
915 
916  TString declFileName;
917  if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declFileName)) {
918  LocateMethods(out, declFileName, kTRUE /*source info*/, useDocxxStyle,
919  kFALSE /*allowPureVirtual*/, pattern, 0);
920  Ssiz_t posGt = pattern.Index('>');
921  if (posGt != kNPOS) {
922  // template! Re-run with pattern '...<.*>::'
923  Ssiz_t posLt = pattern.Index('<');
924  if (posLt != kNPOS && posLt < posGt) {
925  pattern.Replace(posLt + 1, posGt - posLt - 1, ".*");
926  LocateMethods(out, declFileName, kTRUE /*source info*/, useDocxxStyle,
927  kFALSE /*allowPureVirtual*/, pattern, 0);
928  }
929  }
930  }
931 }
932 
933 ////////////////////////////////////////////////////////////////////////////////
934 /// Given fCurrentClass, look for methods in its header file's
935 /// class declaration block, and extract documentation to out,
936 /// while beautifying the header file in parallel.
937 
939 {
940  TString declFileName;
941  if (fHtml->GetDeclFileName(fCurrentClass, kTRUE, declFileName))
942  LocateMethods(out, declFileName, kTRUE/*source info*/, kTRUE /*useDocxxStyle*/,
943  kTRUE /*allowPureVirtual*/, 0, ".h.html");
944 }
945 
946 ////////////////////////////////////////////////////////////////////////////////
947 /// Parse the current line as a comment, handling directives and re-formatting
948 /// the comment: remove "/*", "*/", "//", similar characters surrounding lines,
949 /// etc.
950 ///
951 /// Return kFALSE if the line is not a comment.
952 
954 {
955  if (!fCommentAtBOL
956  && !(fLineStripped[0] == '/'
957  && (fLineStripped[1] == '/' || fLineStripped[1] == '*'))
959  fLineComment = "";
960  return kFALSE;
961  }
962 
963  //if (InContext(kDirective))
964  // return kTRUE; - NO! we might have a comment from a previous directive!
965 
966  // don't write out empty lines if the current directive is eating the line
968  return kTRUE;
969 
970  TString commentLine(fLineComment.Strip());
971 
972  // remove all <span class="comment"> tags
973  Bool_t mustDealWithCommentAtBOL = fCommentAtBOL; // whether we had a closing "*/"
974  Ssiz_t posComment = kNPOS;
975  if (!fCommentAtBOL)
976  posComment = commentLine.Index("<span class=\"comment\">", 0, TString::kIgnoreCase);
977  Ssiz_t posSpanEnd = commentLine.Index("</span>", posComment == kNPOS?0:posComment, TString::kIgnoreCase);
978  while ((mustDealWithCommentAtBOL && posSpanEnd != kNPOS) || posComment != kNPOS) {
979  Int_t spanLevel = 1;
980  Ssiz_t posSpan = commentLine.Index("<span", posComment + 1, TString::kIgnoreCase);
981  while (spanLevel > 1 || (posSpan != kNPOS && posSpan < posSpanEnd)) {
982  // another span was opened, take the next </span>
983  if (posSpan != kNPOS && posSpan < posSpanEnd) {
984  ++spanLevel;
985  posSpan = commentLine.Index("<span", posSpan + 1, TString::kIgnoreCase);
986  // posSpanEnd doesn't change
987  continue;
988  } // else
989  --spanLevel;
990  // posSpan doesn't change
991  posSpanEnd = commentLine.Index("</span>", posSpanEnd + 1, TString::kIgnoreCase);
992  }
993  if (posSpanEnd != kNPOS) {
994  // only remove span if </span> if it exists (or we end up with unbalanced spans)
995  commentLine.Remove(posSpanEnd, 7);
996  if (posComment != kNPOS)
997  commentLine.Remove(posComment, 22);
998  else {
999  mustDealWithCommentAtBOL = kFALSE;
1000  // now remove C comments
1001  posComment = 0;
1002  }
1003  posComment = commentLine.Index("<span class=\"comment\">", posComment, TString::kIgnoreCase);
1004  } else break;
1005  }
1006  if (posComment != kNPOS)
1007  commentLine.Remove(posComment, 22);
1008 
1009  // don't strip in C comments, do strip if opening:
1011  || (fLineStripped[0] == '/' && fLineStripped[1] == '*'))
1012  Strip(commentLine);
1013 
1014  // look for start tag of class description
1017  && !fComment.Length()
1018  && fDocContext == kIgnore && commentLine.Contains(fClassDescrTag)) {
1020  }
1021 
1022  char start_or_end = 0;
1023  // remove leading /*, //
1024  if (commentLine.Length()>1 && commentLine[0] == '/'
1025  && (commentLine[1] == '/' || commentLine[1] == '*')) {
1026  start_or_end = commentLine[1];
1027  commentLine.Remove(0, 2);
1028  }
1029  // remove trailing */
1030  if (start_or_end != '/' && commentLine.Length()>1
1031  && commentLine[commentLine.Length() - 2] == '*'
1032  && commentLine[commentLine.Length() - 1] == '/') {
1033  start_or_end = commentLine[commentLine.Length() - 2];
1034  commentLine.Remove(commentLine.Length()-2);
1035  }
1036 
1037  // remove repeating characters from the end of the line
1038  if (start_or_end && commentLine.Length() > 3) {
1039  TString lineAllOneChar(commentLine.Strip());
1040 
1041  Ssiz_t len = lineAllOneChar.Length();
1042  if (len > 2) {
1043  Char_t c = lineAllOneChar[len - 1];
1044  if (c == lineAllOneChar[len - 2] && c == lineAllOneChar[len - 3]) {
1045  TString lineAllOneCharStripped = lineAllOneChar.Strip(TString::kTrailing, c);
1046  Strip(lineAllOneCharStripped);
1047  if (!lineAllOneCharStripped.Length()) {
1048  commentLine.Remove(0);
1049 
1050  // also a class doc signature: line consists of ////
1053  && !fComment.Length()
1054  && fDocContext == kIgnore && start_or_end=='/') {
1056  }
1057  }
1058  }
1059  }
1060  }
1061 
1062  // remove leading and trailing chars from e.g. // some doc //
1063  if (commentLine.Length() > 0 && start_or_end == commentLine[commentLine.Length() - 1])
1064  // we already removed it as part of // or / *; also remove the trailing
1065  commentLine = commentLine.Strip(TString::kTrailing, start_or_end);
1066 
1067  if (commentLine.Length() > 2 && Context() != kDirective)
1068  while (commentLine.Length() > 2
1069  && !IsWord(commentLine[0])
1070  && commentLine[0] == commentLine[commentLine.Length() - 1])
1071  commentLine = commentLine.Strip(TString::kBoth, commentLine[0]);
1072 
1073  // remove leading '/' if we had // or '*' if we had / *
1074  while (start_or_end && commentLine[0] == start_or_end)
1075  commentLine.Remove(0, 1);
1076 
1077  fComment += commentLine + "\n";
1078 
1079  return kTRUE;
1080 }
1081 
1082 ////////////////////////////////////////////////////////////////////////////////
1083 /// remove the top-most comment context that matches cxxcomment,
1084 
1086 {
1087  UInt_t lookFor = kComment;
1088  if (cxxcomment) lookFor |= kCXXComment;
1089  std::list<UInt_t>::iterator iComment = fParseContext.end();
1090  for (std::list<UInt_t>::iterator iContext = fParseContext.begin();
1091  iContext != fParseContext.end(); ++ iContext)
1092  if (*iContext == lookFor) iComment =iContext;
1093  if (iComment != fParseContext.end())
1094  fParseContext.erase(iComment);
1095 }
1096 
1097 ////////////////////////////////////////////////////////////////////////////////
1098 /// strips ' ', tabs, and newlines from both sides of str
1099 
1101 {
1102  Bool_t changed = str[0] == ' ' || str[0] == '\t' || str[0] == '\n';
1103  changed |= str.Length()
1104  && (str[str.Length() - 1] == ' ' || str[str.Length() - 1] == '\t'
1105  || str[str.Length() - 1] == '\n');
1106  if (!changed) return kFALSE;
1107  Ssiz_t i = 0;
1108  while (str[i] == ' ' || str[i] == '\t' || str[i] == '\n')
1109  ++i;
1110  str.Remove(0,i);
1111  i = str.Length() - 1;
1112  while (i >= 0 && (str[i] == ' ' || str[i] == '\t' || str[i] == '\n'))
1113  --i;
1114  str.Remove(i + 1, str.Length());
1115  return kTRUE;
1116 }
1117 
1118 ////////////////////////////////////////////////////////////////////////////////
1119 /// Write the class description depending (among others) on fClassDocState.
1120 
1121 void TDocParser::WriteClassDoc(std::ostream& out, Bool_t first /*= kTRUE*/)
1122 {
1124  TString& classDoc = first || !fLastClassDoc.Length() ? fFirstClassDoc : fLastClassDoc;
1125  static_cast<TClassDocOutput*>(fDocOutput)->WriteClassDescription(out, classDoc);
1127  }
1128 
1129 }
1130 
1131 namespace {
1132  static void RemoveUnneededSpaces(TString& s) {
1133  // Remove spaces except between identifier characters.
1134  // Assumes s is stripped (does not start nor end with space).
1135  for (Ssiz_t i = 1; i < s.Length() - 1; ++i) {
1136  if (s[i] == ' ') {
1137  char p = s[i - 1];
1138  char n = s[i + 1];
1139  if (((isalnum(p) || p == '_') && (isalnum(n) || n == '_'))
1140  || (p == '>' && n == '>')) {
1141  // "id id" or "> >": keep space
1142  } else {
1143  while (isspace(s[i])) {
1144  s.Remove(i, 1);
1145  }
1146  }
1147  }
1148  }
1149  }
1150 
1151  static void ParseParameters(TString& strippedParams, TList& paramArr) {
1152  // Extract a list of strings (the parameters without initializers) from
1153  // the signature.
1154  int nest = 0;
1155  bool init = false;
1156  bool quoted = false;
1157  Ssiz_t len = strippedParams.Length();
1158  TString arg;
1159  for (Ssiz_t i = 0; i < len; ++i) {
1160  switch (strippedParams[i]) {
1161  case '<': // fallthrough
1162  case '(': // fallthrough
1163  case '[': ++nest; break;
1164  case '>': // fallthrough
1165  case ')': // fallthrough
1166  case ']': --nest; break;
1167  case '=': init = true; break;
1168  case '\'': ++i; if (strippedParams[i] == '\\') ++i; ++i; continue;
1169  case '\\': ++i; continue; break;
1170  case '"': quoted = !quoted; break;
1171  case ',': {
1172  if (!quoted && !nest) {
1173  TString strippedArg(arg.Strip(TString::kBoth));
1174  paramArr.AddLast(new TObjString(strippedArg));
1175  init = false;
1176  arg.Remove(0);
1177  continue;
1178  }
1179  }
1180  }
1181  if (!init) {
1182  arg += strippedParams[i];
1183  }
1184  }
1185  TString strippedLastArg(arg.Strip(TString::kBoth));
1186  if (strippedLastArg.Length()) {
1187  paramArr.AddLast(new TObjString(strippedLastArg));
1188  }
1189  }
1190 
1191  void MatchOverloadSignatures(TCollection* candidates, TList* paramArr)
1192  {
1193  // Check type identity of candidate signatures. For each argument, check whether it
1194  // reduces the list of candidates to > 0 elements.
1195  TList suppressed;
1196  TIter iCandidate(candidates);
1197  int nparams = paramArr->GetSize();
1198  for (int iparam = 0; iparam < nparams && candidates->GetSize() > 1; ++iparam) {
1199  TString& srcArg = ((TObjString*)paramArr->At(iparam))->String();
1200  TString noParName(srcArg);
1201  while (noParName.Length()
1202  && (isalnum(noParName[noParName.Length() - 1]) || noParName[noParName.Length() - 1] == '_'))
1203  noParName.Remove(noParName.Length() - 1);
1204  noParName = noParName.Strip(TString::kTrailing);
1205 
1206  if (noParName.Length()) {
1207  RemoveUnneededSpaces(noParName);
1208  }
1209  RemoveUnneededSpaces(srcArg);
1210  // comparison:
1211  // 0: strcmp
1212  // 1: source's parameter has last identifier (parameter name?) removed
1213  // 2: candidate type name contained in source parameter
1214  for (int comparison = 0; comparison < 5; ++comparison) {
1215  if (comparison == 1 && noParName == srcArg)
1216  // there is no parameter name to ignore
1217  continue;
1218  suppressed.Clear();
1219  iCandidate.Reset();
1220  TDocMethodWrapper* method = 0;
1221  while ((method = (TDocMethodWrapper*) iCandidate())) {
1222  TMethodArg* methArg = (TMethodArg*) method->GetMethod()->GetListOfMethodArgs()->At(iparam);
1223  TString sMethArg = methArg->GetFullTypeName();
1224  RemoveUnneededSpaces(sMethArg);
1225  bool matches = false;
1226  switch (comparison) {
1227  case 0: matches = (srcArg == sMethArg); break;
1228  case 1: matches = (noParName == sMethArg); break;
1229  case 2: matches = srcArg.Contains(sMethArg) || sMethArg.Contains(srcArg); break;
1230  }
1231  if (!matches) {
1232  suppressed.Add(method);
1233  }
1234  }
1235  if (suppressed.GetSize()
1236  && suppressed.GetSize() < candidates->GetSize()) {
1237  candidates->RemoveAll(&suppressed);
1238  break;
1239  }
1240  if (!suppressed.GetSize()) {
1241  // we have a match, no point in trying a looser matching
1242  break;
1243  }
1244  }
1245  }
1246  if (candidates->GetSize() > 1) {
1247  // use TDocMethodWrapper::kDocumented bit
1248  suppressed.Clear();
1249  iCandidate.Reset();
1250  TDocMethodWrapper* method = 0;
1251  while ((method = (TDocMethodWrapper*) iCandidate())) {
1252  if (method->TestBit(TDocMethodWrapper::kDocumented)) {
1253  suppressed.AddLast(method);
1254  }
1255  }
1256  if (suppressed.GetSize()
1257  && suppressed.GetSize() < candidates->GetSize()) {
1258  candidates->RemoveAll(&suppressed);
1259  }
1260  }
1261  }
1262 }
1263 
1264 ////////////////////////////////////////////////////////////////////////////////
1265 /// Write a method, forwarding to TClassDocOutput
1266 
1267 void TDocParser::WriteMethod(std::ostream& out, TString& ret,
1268  TString& name, TString& params, Bool_t isconst,
1269  const char* filename, TString& anchor,
1270  TString& codeOneLiner)
1271 {
1272  // if we haven't found the class description until now it's too late.
1274  WriteClassDoc(out);
1275 
1276  TString strippedParams(params);
1277  if (strippedParams[0] == '(') {
1278  strippedParams.Remove(0, 1);
1279  strippedParams.Remove(strippedParams.Length() - 1);
1280  strippedParams = strippedParams.Strip(TString::kBoth);
1281  }
1282 
1283  TList paramArr;
1284  paramArr.SetOwner();
1285  ParseParameters(strippedParams, paramArr);
1286  int nparams = paramArr.GetSize();
1287 
1288  // Collect overload candidates
1289  TList candidates;
1290  for (int access = 0; access < 3; ++access) {
1291  const TList* methList = fMethods[access].GetListForObject(name);
1292  if (!methList) continue;
1293 
1294  TIter nextMethod(methList);
1295  TDocMethodWrapper* method = 0;
1296  while ((method = (TDocMethodWrapper *) nextMethod())) {
1297  if (name == method->GetName()
1298  && isconst == ((method->GetMethod()->Property() & kIsConstMethod) > 0)
1299  && method->GetMethod()->GetListOfMethodArgs()->GetSize() == nparams) {
1300  candidates.Add(method);
1301  }
1302  }
1303  }
1304 
1305  if (nparams && candidates.GetSize() > 1) {
1306  MatchOverloadSignatures(&candidates, &paramArr);
1307  }
1308 
1309  TDocMethodWrapper* guessedMethod = 0;
1310  if (candidates.GetSize() == 1) {
1311  guessedMethod = (TDocMethodWrapper*) candidates.First();
1312  guessedMethod->SetBit(TDocMethodWrapper::kDocumented);
1313  }
1314 
1315  static_cast<TClassDocOutput*>(fDocOutput)->WriteMethod(out, ret, name, params, filename, anchor,
1316  fComment, codeOneLiner, guessedMethod);
1317 
1318  DecrementMethodCount(name);
1319  ret.Remove(0);
1320  name.Remove(0);
1321  params.Remove(0);
1322  anchor.Remove(0);
1323  fComment.Remove(0);
1324 
1325  fDocContext = kIgnore;
1326 }
1327 
1328 ////////////////////////////////////////////////////////////////////////////////
1329 /// Write fLineSource to out.
1330 /// Adjust relative paths first.
1331 
1333 {
1335  out << fLineSource << std::endl;
1336 
1337 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
THtml * fHtml
Definition: TDocParser.h:95
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
Collectable string class.
Definition: TObjString.h:32
TMethod * LocateMethodInCurrentLine(Ssiz_t &posMethodName, TString &ret, TString &name, TString &params, Bool_t &isconst, std::ostream &srcOut, TString &anchor, std::ifstream &sourcefile, Bool_t allowPureVirtual)
Search for a method starting at posMethodName, and return its return type, its name, and its arguments.
std::istream & ReadLine(std::istream &str, Bool_t skipWhite=kTRUE)
Read a line from stream upto newline skipping any whitespace.
Definition: Stringio.cxx:65
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void SetTag(const char *tag)
Definition: TDocDirective.h:60
UInt_t fLineNo
Definition: TDocParser.h:97
virtual Bool_t GetResult(TString &result)=0
enum TDocParser::@112 fClassDocState
TString fSourceInfoTags[kNumSourceInfos]
Definition: TDocParser.h:126
TString fComment
Definition: TDocParser.h:102
static const char * filename()
Basic string class.
Definition: TString.h:137
void DecrementMethodCount(const char *name)
reduce method count for method called name, removing it from fMethodCounts once the count reaches 0...
Definition: TDocParser.cxx:869
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1088
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Each ROOT method (see TMethod) has a linked list of its arguments.
Definition: TMethodArg.h:33
TString & Prepend(const char *cs)
Definition: TString.h:604
THashList fMethods[3]
Definition: TDocParser.h:131
void WriteClassDoc(std::ostream &out, Bool_t first=kTRUE)
Write the class description depending (among others) on fClassDocState.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
Long_t fLineNumber
Definition: TDocParser.h:110
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:310
virtual void DecorateEntityBegin(TString &str, Ssiz_t &pos, TDocParser::EParseContext type)
Add some colors etc to a source entity, contained in str.
virtual void AddLast(TObject *obj)
Add object at the end of the list.
Definition: TList.cxx:136
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
const TList * GetListForObject(const char *name) const
Return the THashTable's list (bucket) in which obj can be found based on its hash; see THashTable::Ge...
Definition: THashList.cxx:229
const char * String
Definition: TXMLSetup.cxx:94
void RemoveCommentContext(Bool_t cxxcomment)
remove the top-most comment context that matches cxxcomment,
const char * Data() const
Definition: TString.h:349
TString fLastClassDoc
Definition: TDocParser.h:104
virtual void InitKeywords() const
fill C++ keywords into fgKeywords
virtual Bool_t ProcessComment()
void WriteSourceLine(std::ostream &out)
Write fLineSource to out.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4683
void SetCounter(Int_t count)
Definition: TDocDirective.h:61
virtual TObjLink * LastLink() const
Definition: TList.h:104
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1054
static Bool_t Strip(TString &s)
strips ' ', tabs, and newlines from both sides of str
static const std::string pattern("pattern")
void WriteHtmlFooter(std::ostream &out, const char *dir, const char *lastUpdate, const char *author, const char *copyright, const char *footer)
Write HTML footer.
TList fDirectiveHandlers
Definition: TDocParser.h:127
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TDocOutput * fDocOutput
Definition: TDocParser.h:96
static std::set< std::string > fgKeywords
Definition: TDocParser.h:134
void SetParser(TDocParser *parser)
Set the parser, and fDocOutput, fHtml from that.
char * out
Definition: TBase64.cxx:29
TString fClassDescrTag
Definition: TDocParser.h:125
virtual void Parse(std::ostream &out)
Locate methods, starting in the source file, then inline, then immediately inside the class declarati...
static Bool_t IsWord(UChar_t c)
Check if c is a valid first character for C++ name.
A doubly linked list.
Definition: TList.h:47
virtual void AdjustSourcePath(TString &line, const char *relpath="../")
adjust the path of links for source files, which are in src/, but need to point to relpath (usually "...
Definition: TDocOutput.cxx:297
TClass * fCurrentClass
Definition: TDocParser.h:105
virtual TList * GetListOfMethodArgs()
Returns methodarg list and additionally updates fDataMember in TMethod by calling FindDataMember();...
Definition: TMethod.cxx:305
void WriteMethod(std::ostream &out, TString &ret, TString &name, TString &params, Bool_t isconst, const char *file, TString &anchor, TString &codeOneLiner)
Write a method, forwarding to TClassDocOutput.
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
TString fCurrentMethodTag
Definition: TDocParser.h:108
virtual const char * ReplaceSpecialChars(char c)
Replace ampersand, less-than and greater-than character, writing to out.
static void AnchorFromLine(const TString &line, TString &anchor)
Create an anchor from the given line, by hashing it and convertig the hash into a custom base64 strin...
Definition: TDocParser.cxx:381
virtual void NameSpace2FileName(TString &name)
Replace "::" in name by "__" Replace "<", ">", " ", ",", "~", "=" in name by "_" Replace "A::X"...
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:674
virtual Bool_t HandleDirective(TString &keyword, Ssiz_t &pos, TString &word, Ssiz_t &copiedToCommentUpTo)
Definition: TDocParser_002.C:2
Bool_t fCommentAtBOL
Definition: TDocParser.h:124
Collection abstract base class.
Definition: TCollection.h:48
static Bool_t IsName(UChar_t c)
Check if c is a valid C++ name character.
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
std::map< std::string, Int_t > fMethodCounts
Definition: TDocParser.h:112
Int_t fDirectiveCount
Definition: TDocParser.h:109
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1069
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
void LocateMethodsInHeaderInline(std::ostream &out)
Given fCurrentClass, look for methods in its header file, and extract documentation to out...
virtual TClass * IsDirective(const TString &line, Ssiz_t pos, const TString &word, Bool_t &begin) const
return whether word at line's pos is a valid directive, and returns its TDocDirective's TClass object...
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:183
virtual TMethod * GetMethod() const =0
Int_t CountChar(Int_t c) const
Return number of times character c occurs in the string.
Definition: TString.cxx:443
virtual void DeleteDirectiveOutput() const
Delete output generated by prior runs of all known directives; the output file names might have chang...
Definition: TDocParser.cxx:884
const TString & GetDocStyle() const
Definition: THtml.h:315
EParseContext Context() const
Definition: TDocParser.h:138
void LocateMethodsInHeaderClassDecl(std::ostream &out)
Given fCurrentClass, look for methods in its header file's class declaration block, and extract documentation to out, while beautifying the header file in parallel.
virtual void FixupAuthorSourceInfo(TString &authors)
Special author treatment; called when TDocParser::fSourceInfo[kInfoAuthor] is set.
virtual TObject * Last() const
Return the last object in the list. Returns 0 when list is empty.
Definition: TList.cxx:580
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
int Ssiz_t
Definition: RtypesCore.h:63
virtual bool GetDeclFileName(TClass *cl, Bool_t filesys, TString &out_name) const
Return declaration file name; return the full path if filesys is true.
Definition: THtml_001.C:838
TString fSourceInfo[kNumSourceInfos]
Definition: TDocParser.h:130
void SetParameters(const char *params)
Given a string containing parameters in params, we call AddParameter() for each of them...
TString fLineRaw
Definition: TDocParser.h:98
std::set< UInt_t > fExtraLinesWithAnchor
Definition: TDocParser.h:129
virtual Int_t GetSize() const
Definition: TCollection.h:95
TString fLineComment
Definition: TDocParser.h:100
TString fCurrentFile
Definition: TDocParser.h:111
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
virtual void DecorateKeywords(std::ostream &out, const char *text)
Expand keywords in text, writing to out.
Definition: TDocParser.cxx:450
TString fFirstClassDoc
Definition: TDocParser.h:103
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2881
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:348
void WriteLineNumbers(std::ostream &out, Long_t nLines, const TString &infileBase) const
Create a div containing the line numbers (for a source listing) 1 to nLines.
std::list< UInt_t > fParseContext
Definition: TDocParser.h:114
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition: TPRegexp.cxx:704
#define name(a, b)
Definition: linkTestLib0.cpp:5
virtual const char * GetEndTag() const =0
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Definition: TList.cxx:556
char Char_t
Definition: RtypesCore.h:29
TString fLineStripped
Definition: TDocParser.h:99
const char * GetFullTypeName() const
Get full type description of method argument, e.g.: "class TDirectory*".
Definition: TMethodArg.cxx:75
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition: TPRegexp.h:103
EDocContext fDocContext
Definition: TDocParser.h:113
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:40
void LocateMethods(std::ostream &out, const char *filename, Bool_t lookForSourceInfo=kTRUE, Bool_t useDocxxStyle=kFALSE, Bool_t allowPureVirtual=kFALSE, const char *methodPattern=0, const char *sourceExt=0)
Collect methods from the source or header file called filename.
ClassImp(TSlaveInfo) Int_t TSlaveInfo const TSlaveInfo * si
Used to sort slaveinfos by ordinal.
Definition: TProof.cxx:167
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
double result[121]
unsigned char UChar_t
Definition: RtypesCore.h:34
TMethod * GetMethodAny(const char *method)
Return pointer to method without looking at parameters.
Definition: TClass.cxx:4108
UInt_t InContext(Int_t context) const
checks whether we are in a parse context, return the entry closest to the current context...
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:99
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual bool GetImplFileName(TClass *cl, Bool_t filesys, TString &out_name) const
Return implementation file name.
Definition: THtml_001.C:846
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:466
void LocateMethodsInSource(std::ostream &out)
Given fCurrentClass, look for methods in its source file, and extract documentation to out...
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:39
virtual void AddLine(const TSubString &line)=0
TString fLineSource
Definition: TDocParser.h:101
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904