ROOT  6.06/09
Reference Guide
TMakeProject.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Rene Brun 12/10/2000
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /*
13 \class TMakeProject TMakeProject.cxx
14 \ingroup IO
15 
16 Helper class implementing the TFile::MakeProject.
17 **/
18 
19 #include <ctype.h>
20 #include "TMakeProject.h"
21 #include "TClass.h"
22 #include "TClassEdit.h"
23 #include "TROOT.h"
24 #include "TMD5.h"
25 #include "TStreamerInfo.h"
26 #include "TStreamerElement.h"
27 #include "TError.h"
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 /// Add an include statement, if it has not already been added.
31 
32 void TMakeProject::AddUniqueStatement(FILE *fp, const char *statement, char *inclist)
33 {
34  if (!strstr(inclist, statement)) {
35  if (strlen(inclist)+strlen(statement) >= 50000) {
36  Fatal("AddUniqueStatement","inclist too short need %u instead of 500000",UInt_t(strlen(inclist)+strlen(statement)));
37  }
38  strcat(inclist, statement);
39  fprintf(fp, "%s", statement);
40  }
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Add an include statement, if it has not already been added.
45 
46 void TMakeProject::AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
47 {
48  TString what;
49  if (system) {
50  what.Form("#include <%s>\n", header);
51  } else {
52  what.Form("#include \"%s\"\n", header);
53  }
54  AddUniqueStatement(fp, what.Data(), inclist);
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 /// Chop the name by replacing the ending (before a potential extension) with
59 /// a md5 summary of the name.
60 
62 {
63  if (name.Length() >= limit) {
64  Bool_t has_extension = (strcmp(name.Data() + name.Length() - 2, ".h") == 0);
65  if (has_extension) {
66  name.Remove(name.Length()-2);
67  }
68  TMD5 md;
69  md.Update((const UChar_t*)name.Data(),name.Length());
70  md.Final();
71  name.Remove( limit - 32 - 5); // Chop the part longer than 255 and keep space for the md5 and leave space for an extension
72  name.Append( md.AsString() );
73  if (has_extension) {
74  name.Append( ".h" );
75  }
76  }
77 
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Return the header name containing the description of name.
82 
83 TString TMakeProject::GetHeaderName(const char *in_name, const TList *extrainfos, Bool_t includeNested)
84 {
86  std::string strname( TClassEdit::GetLong64_Name( in_name ) );
87  const char *name = strname.c_str();
88  Int_t len = strlen(name);
89  Int_t nest = 0;
90  for (Int_t i = 0; i < len; ++i) {
91  switch (name[i]) {
92  case '<':
93  ++nest;
94  result.Append('_');
95  break;
96  case '>':
97  --nest;
98  result.Append('_');
99  break;
100  case ':':
101  if (nest == 0 && name[i+1] == ':') {
102  TString nsname(name, i);
103  TClass *cl = gROOT->GetClass(nsname);
104  Bool_t definedInParent = !includeNested && cl && (cl->Size() != 0 || (cl->Size()==0 && !cl->HasInterpreterInfo() /*empty 'base' class on file*/));
105  if (!definedInParent && cl==0 && extrainfos!=0) {
106  TStreamerInfo *clinfo = (TStreamerInfo*)extrainfos->FindObject(nsname);
107  if (clinfo && clinfo->GetClassVersion() == -5) {
108  definedInParent = kTRUE;
109  }
110  }
111  if (definedInParent) {
112  // The requested class is actually nested inside
113  // the class whose name we already 'copied' to
114  // result. The declaration will be in the same
115  // header file as the outer class.
116  if (strcmp(name + strlen(name) - 2, ".h") == 0) {
117  result.Append(".h");
118  }
119  ChopFileName(result,255);
120  return result;
121  }
122  }
123  result.Append('_');
124  break;
125  case ',':
126  case '*':
127  case '[':
128  case ']':
129  case ' ':
130  case '(':
131  case ')':
132  result.Append('_');
133  break;
134  case '/':
135  case '\\':
136  default:
137  result.Append(name[i]);
138  }
139  }
140  ChopFileName(result,255);
141  return result;
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// Write the start of the class (forward) declaration.
146 /// If 'implementEmptyClass' is 3 then never add a #pragma
147 
148 UInt_t TMakeProject::GenerateClassPrefix(FILE *fp, const char *clname, Bool_t top, TString &protoname,
149  UInt_t *numberOfClasses, Int_t implementEmptyClass, Bool_t needGenericTemplate)
150 {
151  // First open the namespace (if any)
152  Int_t numberOfNamespaces = 0;
153  const char *fullname = clname;
154 
155  Bool_t istemplate = kFALSE;
156  if (strchr(clname, ':')) {
157  // We might have a namespace in front of the classname.
158  Int_t len = strlen(clname);
159  const char *name = clname;
160  UInt_t nest = 0;
161  for (Int_t cur = 0; cur < len; ++cur) {
162  switch (clname[cur]) {
163  case '<':
164  ++nest;
165  istemplate = kTRUE;
166  break;
167  case '>':
168  if (nest) --nest;
169  break;
170  case ':': {
171  if (nest == 0 && clname[cur+1] == ':') {
172  // We have a scope
173  TString nsname(clname, cur);
174  TClass *cl = gROOT->GetClass(nsname);
175  if (top) {
176  if (cl == 0 || (cl && cl->Size() == 0)) {
177  TString last(name, cur - (name - clname));
178  if ((numberOfClasses == 0 || *numberOfClasses == 0) && strchr(last.Data(), '<') == 0) {
179  fprintf(fp, "namespace %s {\n", last.Data());
180  ++numberOfNamespaces;
181  } else {
182  TString headername(GetHeaderName(last,0));
183  fprintf(fp, "#ifndef %s_h\n", headername.Data());
184  fprintf(fp, "#define %s_h\n", headername.Data());
185  GenerateClassPrefix(fp, last.Data(), top, protoname, 0);
186  fprintf(fp, "{\n");
187  fprintf(fp, "public:\n");
188  if (numberOfClasses) ++(*numberOfClasses);
189  istemplate = kFALSE;
190  }
191  name = clname + cur + 2;
192  }
193  } else {
194  istemplate = kFALSE;
195  name = clname + cur + 2;
196  }
197  }
198  break;
199  }
200  }
201  }
202  clname = name;
203  } else {
204  istemplate = strstr(clname, "<") != 0;
205  }
206 
207  protoname = clname;
208 
209  if (implementEmptyClass==1) {
210  TString headername(GetHeaderName(fullname,0));
211  fprintf(fp, "#ifndef %s_h\n", headername.Data());
212  fprintf(fp, "#define %s_h\n", headername.Data());
213  }
214  if (istemplate) {
215  std::vector<const char*> argtype;
216 
217  Ssiz_t pos = protoname.First('<');
218  UInt_t nparam = 1;
219  if (pos != kNPOS) {
220  if (isdigit(protoname[pos+1])) {
221  argtype.push_back("int");
222  } else {
223  argtype.push_back("typename");
224  }
225  UInt_t nest = 0;
226  for (Ssiz_t i = pos; i < protoname.Length(); ++i) {
227  switch (protoname[i]) {
228  case '<':
229  ++nest;
230  break;
231  case '>':
232  if (nest) --nest;
233  break;
234  case ',':
235  if (nest == 1) {
236  if (isdigit(protoname[i+1])) {
237  argtype.push_back("int");
238  } else {
239  argtype.push_back("typename");
240  }
241  ++nparam;
242  }
243  break;
244  }
245  }
246  protoname.Remove(pos);
247  }
248 
249  // Forward declaration of template.
250  fprintf(fp, "template <");
251  for (UInt_t p = 0; p < nparam; ++p) {
252  if (p >= argtype.size() ) {
253  fprintf(fp, "/* missing */ T%d", p);
254  } else {
255  fprintf(fp, "%s T%d", argtype[p], p);
256  }
257  if (p != (nparam - 1)) fprintf(fp, ", ");
258  }
259  if (needGenericTemplate) {
260  fprintf(fp, "> class %s", protoname.Data());
261  } else {
262  fprintf(fp, "> class %s;\n", protoname.Data());
263  fprintf(fp, "template <> ");
264  }
265  }
266 
267  if (implementEmptyClass) {
268  if (istemplate) {
269  if (!needGenericTemplate) {
270  fprintf(fp, "class %s", clname);
271  }
272  fprintf(fp, " {\n");
273  if (numberOfClasses) ++(*numberOfClasses);
274  fprintf(fp, "public:\n");
275  fprintf(fp, "operator int() { return 0; };\n");
276  } else {
277  fprintf(fp, "enum %s { kDefault_%s };\n", clname, clname);
278  // The nesting space of this class may not be #pragma declared (and without it
279  // the dictionary is broken), so for now skip those
280  if (implementEmptyClass==1) {
281  if (strchr(fullname, ':') == 0) {
282  // yes this is too aggressive, this needs to be fixed properly by moving the #pragma out of band.
283  fprintf(fp, "#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", fullname);
284  }
285  fprintf(fp, "#endif\n");
286  }
287  }
288  } else {
289  if (!(istemplate && needGenericTemplate)) {
290  fprintf(fp, "class %s", clname);
291  }
292  }
293  return numberOfNamespaces;
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Generate an empty StreamerInfo for the given type (no recursion) if it is not
298 /// not known in the list of class.
299 ///
300 /// If the type itself is a template,
301 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
302 
303 void TMakeProject::GenerateMissingStreamerInfo(TList *extrainfos, const char *clname, Bool_t iscope)
304 {
305  if (!TClassEdit::IsStdClass(clname) && !TClass::GetClass(clname) && gROOT->GetType(clname) == 0) {
306 
307  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(clname);
308  if (!info) {
309  // The class does not exist, let's create it
310  TStreamerInfo *newinfo = new TStreamerInfo();
311  newinfo->SetName(clname);
312  if (clname[strlen(clname)-1]=='>') {
313  newinfo->SetTitle("Generated by MakeProject as an empty class template instantiation");
314  newinfo->SetClassVersion(1);
315  } else if (iscope) {
316  newinfo->SetTitle("Generated by MakeProject as a namespace");
317  newinfo->SetClassVersion(-4 /*namespace*/);
318  } else {
319  newinfo->SetTitle("Generated by MakeProject as an enum");
320  newinfo->SetClassVersion(-3 /*enum*/);
321  }
322  extrainfos->Add(newinfo);
323  } else {
324  if (iscope) {
325  if (info->GetClassVersion() == -3) {
326  // This was marked as an enum but is also used as a scope,
327  // so it was actually a class.
328  info->SetTitle("Generated by MakeProject as an empty class");
329  info->SetClassVersion(-5 /*class*/);
330  }
331  } else {
332  if (info->GetClassVersion() == -4) {
333  // This was marked as a 'namespace' but it is also used as a template parameter,
334  // so it was actually a class.
335  info->SetTitle("Generated by MakeProject as an empty class");
336  info->SetClassVersion(-5 /*class*/);
337  }
338  }
339  }
340  }
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Generate an empty StreamerInfo for types that are used in templates parameters
345 /// but are not known in the list of class.
346 ///
347 /// If the type itself is a template, we mark it with version 1 (a class)
348 /// otherwise we mark it as version -3 (an enum).
349 
350 void TMakeProject::GenerateMissingStreamerInfos(TList *extrainfos, const char *clname)
351 {
352  UInt_t len = strlen(clname);
353  UInt_t nest = 0;
354  UInt_t last = 0;
355  //Bool_t istemplate = kFALSE; // mark whether the current right most entity is a class template.
356 
357  for (UInt_t i = 0; i < len; ++i) {
358  switch (clname[i]) {
359  case ':':
360  if (nest == 0 && clname[i+1] == ':') {
361  TString incName(clname, i);
362  GenerateMissingStreamerInfo(extrainfos, incName.Data(), kTRUE);
363  //istemplate = kFALSE;
364  }
365  break;
366  case '<':
367  ++nest;
368  if (nest == 1) last = i + 1;
369  break;
370  case '>':
371  if (nest == 0) return; // The name is not well formed, give up.
372  --nest; /* intentional fall throught to the next case */
373  case ',':
374  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
375  TString incName(clname + last, i - last);
377  if (clname[i] == '>' && nest == 1) incName.Append(">");
378 
379  if (isdigit(incName[0])) {
380  // Not a class name, nothing to do.
381  } else {
382  GenerateMissingStreamerInfos(extrainfos,incName.Data());
383  }
384  last = i + 1;
385  }
386  }
387  }
389 }
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Generate an empty StreamerInfo for types that are used in templates parameters
393 /// but are not known in the list of class.
394 ///
395 /// If the type itself is a template,
396 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
397 
399 {
400  if (element->IsBase()) {
401  TClass *elemCl = element->GetClassPointer();
402  if (elemCl) GenerateMissingStreamerInfos(extrainfos,elemCl->GetName());
403  else GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
404  } else {
405  GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
406  }
407 
408 }
409 
410 ////////////////////////////////////////////////////////////////////////////////
411 /// Insert a (complete) forward declaration for the class 'clname'
412 
413 UInt_t TMakeProject::GenerateForwardDeclaration(FILE *fp, const char *clname, char *inclist, Bool_t implementEmptyClass, Bool_t needGenericTemplate, const TList *extrainfos)
414 {
415  UInt_t ninc = 0;
416 
417  if (strchr(clname, '<')) {
418  ninc += GenerateIncludeForTemplate(fp, clname, inclist, kTRUE, extrainfos);
419  }
420  TString protoname;
421  UInt_t numberOfClasses = 0;
422  UInt_t numberOfNamespaces = GenerateClassPrefix(fp, clname, kTRUE, protoname, &numberOfClasses, implementEmptyClass, needGenericTemplate);
423 
424  if (!implementEmptyClass) fprintf(fp, ";\n");
425  for (UInt_t i = 0;i < numberOfClasses;++i) {
426  fprintf(fp, "}; // end of class.\n");
427  fprintf(fp, "#endif\n");
428  }
429  for (UInt_t i = 0;i < numberOfNamespaces;++i) {
430  fprintf(fp, "} // end of namespace.\n");
431  }
432 
433  return ninc;
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Add to the header file, the #include needed for the argument of
438 /// this template.
439 
440 UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, char *inclist, Bool_t forward, const TList *extrainfos)
441 {
442  UInt_t ninc = 0;
443  UInt_t len = strlen(clname);
444  UInt_t nest = 0;
445  UInt_t last = 0;
446 
447 
448  for (UInt_t i = 0; i < len; ++i) {
449  switch (clname[i]) {
450  case '<':
451  ++nest;
452  if (nest == 1) last = i + 1;
453  break;
454  case '>':
455  if (nest==0) return ninc; // the name is not well formed, give up.
456  --nest; /* intentional fall throught to the next case */
457  case ',':
458  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
459  TString incName(clname + last, i - last);
461  if (clname[i] == '>' && nest == 1) incName.Append(">");
462  Int_t stlType;
463  if (isdigit(incName[0])) {
464  // Not a class name, nothing to do.
465  } else if ((stlType = TClassEdit::IsSTLCont(incName))) {
466  const char *what = "";
467  switch (TMath::Abs(stlType)) {
468  case ROOT::kSTLvector:
469  what = "vector";
470  break;
471  case ROOT::kSTLlist:
472  what = "list";
473  break;
475  what = "forward_list";
476  break;
477  case ROOT::kSTLdeque:
478  what = "deque";
479  break;
480  case ROOT::kSTLmap:
481  case ROOT::kSTLmultimap:
482  what = "map";
483  break;
486  what = "unordered_map";
487  break;
488  case ROOT::kSTLset:
489  case ROOT::kSTLmultiset:
490  what = "set";
491  break;
494  what = "unordered_set";
495  case ROOT::kSTLbitset:
496  what = "bitset";
497  break;
498  default:
499  what = "undetermined_stl_container";
500  break;
501  }
502  AddInclude(fp, what, kTRUE, inclist);
503  fprintf(fp, "namespace std {} using namespace std;\n");
504  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
505  } else if (strncmp(incName.Data(), "pair<", strlen("pair<")) == 0) {
506  AddInclude(fp, "utility", kTRUE, inclist);
507  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
508  } else if (strncmp(incName.Data(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
509  AddInclude(fp, "memory", kTRUE, inclist);
510  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
511  } else if (TClassEdit::IsStdClass(incName)) {
512  // Do nothing.
513  } else {
514  TClass *cl = gROOT->GetClass(incName);
515  if (!forward && cl) {
516  if (cl->HasInterpreterInfo()) {
517  // We have the real dictionary for this class.
518 
519  const char *include = cl->GetDeclFileName();
520  if (include && include[0]) {
521 
522  if (strncmp(include, "include/", 8) == 0) {
523  include += 8;
524  }
525  if (strncmp(include, "include\\", 9) == 0) {
526  include += 9;
527  }
528  TMakeProject::AddInclude(fp, include, kFALSE, inclist);
529  }
530  GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
531  } else {
532  incName = GetHeaderName(incName,extrainfos);
533  incName.Append(".h");
534  AddInclude(fp, incName, kFALSE, inclist);
535  }
536  } else if (incName.Length() && incName[0] != ' ' && gROOT->GetType(incName) == 0) {
537  Bool_t emptyclass = !cl;
538  if (emptyclass && extrainfos) {
539  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(incName);
540  if (info && info->GetClassVersion() == -5) {
541  emptyclass = kFALSE;
542  }
543  }
544  GenerateForwardDeclaration(fp, incName, inclist, emptyclass, kFALSE, extrainfos);
545  }
546  }
547  last = i + 1;
548  }
549  }
550  }
551 
552  Int_t stlType = TClassEdit::IsSTLCont(clname);
553  if (stlType) {
554  std::vector<std::string> inside;
555  int nestedLoc;
556  TClassEdit::GetSplit( clname, inside, nestedLoc, TClassEdit::kLong64 );
557  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
558  TClass *key = TClass::GetClass(inside[1].c_str());
559  if (key) {
560  TString what;
561  switch (stlkind) {
562  case ROOT::kSTLmap:
563  case ROOT::kSTLmultimap: {
564  what = "pair<";
565  what += UpdateAssociativeToVector( inside[1].c_str() );
566  what += ",";
567  what += UpdateAssociativeToVector( inside[2].c_str() );
568  what += " >";
569  what.ReplaceAll("std::","");
570  // Only ask for it if needed.
571  TClass *paircl = TClass::GetClass(what.Data());
572  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
573  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", what.Data()), inclist);
574  }
575  break;
576  }
577  }
578  }
579  }
580 
581  if (strncmp(clname, "auto_ptr<", strlen("auto_ptr<")) == 0) {
582  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", clname), inclist);
583  }
584  return ninc;
585 }
586 
587 
588 ////////////////////////////////////////////////////////////////////////////////
589 /// Add to the header file anything that need to appear after the class
590 /// declaration (this includes some #pragma link).
591 
592 void TMakeProject::GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
593 {
594  TIter next(info->GetElements());
595  TStreamerElement *element;
596  while( (element = (TStreamerElement*)next()) ) {
597  Int_t stlType = TClassEdit::IsSTLCont(element->GetTypeName());
598  if (stlType) {
599  std::vector<std::string> inside;
600  int nestedLoc;
601  TClassEdit::GetSplit( element->GetTypeName(), inside, nestedLoc, TClassEdit::kLong64 );
602  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
603  TClass *key = TClass::GetClass(inside[1].c_str());
604  TString what;
605  if (strncmp(inside[1].c_str(),"pair<",strlen("pair<"))==0) {
606  what = inside[1].c_str();
607  } else if (key) {
608  switch (stlkind) {
609  case ROOT::kSTLmap:
610  case ROOT::kSTLmultimap:
611  {
612  // Already done (see GenerateIncludeForTemplate
613  break;
614  }
615  default:
616  break;
617  }
618  }
619  if (what.Length()) {
620  // Only ask for it if needed.
621  TClass *paircl = TClass::GetClass(what.Data());
622  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
623  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n",what.Data()), inclist);
624  }
625  }
626  }
627  }
628 }
629 
630 ////////////////////////////////////////////////////////////////////////////////
631 /// If we have a map, multimap, set or multiset, plus unordered partners,
632 /// and the key is a class, we need to replace the
633 /// container by a vector since we don't have the
634 /// comparator function.
635 /// The 'name' is modified to return the change in the name,
636 /// if any.
637 
639 {
640  TString newname( name );
641 
642  if (strchr(name,'<')!=0) {
643  std::vector<std::string> inside;
644  int nestedLoc;
645  unsigned int narg = TClassEdit::GetSplit( name, inside, nestedLoc, TClassEdit::kLong64 );
646  if (nestedLoc) --narg;
647  Int_t stlkind = TMath::Abs(TClassEdit::STLKind(inside[0].c_str()));
648 
649  for(unsigned int i = 1; i<narg; ++i) {
650  inside[i] = UpdateAssociativeToVector( inside[i].c_str() );
651  }
652  // Remove default allocator if any.
653  static const char* allocPrefix = "std::allocator<";
654  static const unsigned int allocPrefixLen (strlen(allocPrefix));
655  switch (stlkind) {
656  case ROOT::kSTLvector:
657  case ROOT::kSTLlist:
659  case ROOT::kSTLdeque:
660  if (narg>2 && strncmp(inside[2].c_str(),allocPrefix,allocPrefixLen)==0) {
661  --narg;
662  }
663  break;
664  case ROOT::kSTLset:
665  case ROOT::kSTLmultiset:
666  case ROOT::kSTLmap:
667  case ROOT::kSTLmultimap:
668  if (narg>4 && strncmp(inside[4].c_str(),allocPrefix,allocPrefixLen)==0) {
669  --narg;
670  }
671  break;
674  if (narg>5 && strncmp(inside[5].c_str(),allocPrefix,allocPrefixLen)==0) {
675  --narg;
676  }
677  break;
680  if (narg>6 && strncmp(inside[6].c_str(),allocPrefix,allocPrefixLen)==0) {
681  --narg;
682  }
683  break;
684  }
685  if (stlkind!=0) {
686  TClass *key = TClass::GetClass(inside[1].c_str());
687 
688  if (key) {
689  // We only need to translate to a vector is the key is a class
690  // (for which we do not know the sorting).
691  std::string what;
692  switch ( stlkind ) {
693  case ROOT::kSTLmap:
695  case ROOT::kSTLmultimap:
697  what = "std::pair<";
698  what += inside[1];
699  what += ",";
700  what += inside[2];
701  if (what[what.size()-1]=='>') {
702  what += " >";
703  } else {
704  what += ">";
705  }
706  inside.clear();
707  inside.push_back("std::vector");
708  inside.push_back(what);
709  narg = 2;
710  break;
711  }
712  case ROOT::kSTLset:
714  case ROOT::kSTLmultiset:
716  inside[0] = "std::vector";
717  break;
718  }
719  }
720  if (strncmp(inside[0].c_str(),"std::",5) != 0) {
721  inside[0] = "std::" + inside[0];
722  }
723  } else {
724  static const char *stlnames[] = { "pair", "greater", "less", "allocator" };
725  for(unsigned int in = 0; in < sizeof(stlnames)/sizeof(stlnames[0]); ++in) {
726  if (strncmp( inside[0].c_str(), stlnames[in], strlen(stlnames[in])) == 0 ) {
727  inside[0] = "std::" + inside[0];
728  break;
729  }
730  }
731  }
732  newname = inside[0];
733  newname.Append("<");
734  newname.Append(inside[1]);
735  for(unsigned int j=2; j<narg; ++j) {
736  if (!inside[j].empty()) {
737  newname.Append(",");
738  newname.Append(inside[j]);
739  }
740  }
741  if (newname[newname.Length()-1]=='>') {
742  newname.Append(" >");
743  } else {
744  newname.Append(">");
745  }
746  if (nestedLoc) newname.Append(inside[nestedLoc]);
747  } else if ( newname == "string" ) {
748  newname = "std::string";
749  }
750  return newname;
751 }
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
static void GenerateMissingStreamerInfo(TList *extrainfos, const char *clname, Bool_t iscope)
Generate an empty StreamerInfo for the given type (no recursion) if it is not not known in the list o...
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector,allocator> result: 0 : not stl container code of cont...
const char * GetTypeName() const
void Final()
MD5 finalization, ends an MD5 message-digest operation, writing the the message digest and zeroizing ...
Definition: TMD5.cxx:165
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Ssiz_t Length() const
Definition: TString.h:390
void Fatal(const char *location, const char *msgfmt,...)
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the splited type.
Definition: TClassEdit.cxx:937
static TString GetHeaderName(const char *name, const TList *extrainfos, Bool_t includeNested=kFALSE)
Return the header name containing the description of name.
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
virtual void SetName(const char *name)
Change (i.e.
Definition: TNamed.cxx:128
static void ChopFileName(TString &name, Int_t limit)
Chop the name by replacing the ending (before a potential extension) with a md5 summary of the name...
#define gROOT
Definition: TROOT.h:340
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
static void GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
Add to the header file anything that need to appear after the class declaration (this includes some #...
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:496
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
const char * Data() const
Definition: TString.h:349
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2334
const char * AsString() const
Return message digest as string.
Definition: TMD5.cxx:218
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:46
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
Definition: TClassEdit.cxx:467
TString & Append(const char *cs)
Definition: TString.h:492
static UInt_t GenerateForwardDeclaration(FILE *fp, const char *clname, char *inclist, Bool_t implementEmptyClass, Bool_t needGenericTemplate, const TList *extrainfos)
Insert a (complete) forward declaration for the class 'clname'.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
Definition: TClassEdit.cxx:816
Int_t GetClassVersion() const
static void AddInclude(FILE *fp, const char *header, Bool_t system, char *inclist)
Add an include statement, if it has not already been added.
A doubly linked list.
Definition: TList.h:47
static const char * what
Definition: stlLoader.cc:6
void Update(const UChar_t *buf, UInt_t len)
Update TMD5 object to reflect the concatenation of another buffer full of bytes.
Definition: TMD5.cxx:106
Bool_t HasInterpreterInfo() const
Definition: TClass.h:374
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
unsigned int UInt_t
Definition: RtypesCore.h:42
static void AddUniqueStatement(FILE *fp, const char *statement, char *inclist)
Add an include statement, if it has not already been added.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
void SetClassVersion(Int_t vers)
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
static void GenerateMissingStreamerInfos(TList *extrainfos, TStreamerElement *element)
Generate an empty StreamerInfo for types that are used in templates parameters but are not known in t...
static UInt_t GenerateIncludeForTemplate(FILE *fp, const char *clname, char *inclist, Bool_t forward, const TList *extrainfos)
Add to the header file, the #include needed for the argument of this template.
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
int Ssiz_t
Definition: RtypesCore.h:63
virtual TObjArray * GetElements() const =0
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
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
#define name(a, b)
Definition: linkTestLib0.cpp:5
static TString UpdateAssociativeToVector(const char *name)
If we have a map, multimap, set or multiset, plus unordered partners, and the key is a class...
const char * GetDeclFileName() const
Definition: TClass.h:386
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
double result[121]
unsigned char UChar_t
Definition: RtypesCore.h:34
Abstract Interface class describing Streamer information for one class.
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
static UInt_t GenerateClassPrefix(FILE *fp, const char *clname, Bool_t top, TString &protoname, UInt_t *numberOfClasses, Int_t implementEmptyClass=kFALSE, Bool_t needGenericTemplate=kFALSE)
Write the start of the class (forward) declaration.
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5325
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:466