ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #ifndef WIN32
123  }
124  result.Append('_');
125 #else
126  }
127  if (name[i+1] == '/') {
128  // don't replace the colon ':' in the case it's part of the drive name in a Windows path
129  // e.g. don't convert from "c:/root/..." to "c_/root/..."
130  result.Append(name[i]);
131  } else {
132  result.Append('_');
133  }
134 #endif
135  break;
136  case ',':
137  case '*':
138  case '[':
139  case ']':
140  case ' ':
141  case '(':
142  case ')':
143  result.Append('_');
144  break;
145  case '/':
146  case '\\':
147  default:
148  result.Append(name[i]);
149  }
150  }
151  ChopFileName(result,255);
152  return result;
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// Write the start of the class (forward) declaration.
157 /// If 'implementEmptyClass' is 3 then never add a #pragma
158 
159 UInt_t TMakeProject::GenerateClassPrefix(FILE *fp, const char *clname, Bool_t top, TString &protoname,
160  UInt_t *numberOfClasses, Int_t implementEmptyClass, Bool_t needGenericTemplate)
161 {
162  // First open the namespace (if any)
163  Int_t numberOfNamespaces = 0;
164  const char *fullname = clname;
165 
166  Bool_t istemplate = kFALSE;
167  if (strchr(clname, ':')) {
168  // We might have a namespace in front of the classname.
169  Int_t len = strlen(clname);
170  const char *name = clname;
171  UInt_t nest = 0;
172  for (Int_t cur = 0; cur < len; ++cur) {
173  switch (clname[cur]) {
174  case '<':
175  ++nest;
176  istemplate = kTRUE;
177  break;
178  case '>':
179  if (nest) --nest;
180  break;
181  case ':': {
182  if (nest == 0 && clname[cur+1] == ':') {
183  // We have a scope
184  TString nsname(clname, cur);
185  TClass *cl = gROOT->GetClass(nsname);
186  if (top) {
187  if (cl == 0 || (cl && cl->Size() == 0)) {
188  TString last(name, cur - (name - clname));
189  if ((numberOfClasses == 0 || *numberOfClasses == 0) && strchr(last.Data(), '<') == 0) {
190  fprintf(fp, "namespace %s {\n", last.Data());
191  ++numberOfNamespaces;
192  } else {
193  TString headername(GetHeaderName(last,0));
194  fprintf(fp, "#ifndef %s_h\n", headername.Data());
195  fprintf(fp, "#define %s_h\n", headername.Data());
196  GenerateClassPrefix(fp, last.Data(), top, protoname, 0);
197  fprintf(fp, "{\n");
198  fprintf(fp, "public:\n");
199  if (numberOfClasses) ++(*numberOfClasses);
200  istemplate = kFALSE;
201  }
202  name = clname + cur + 2;
203  }
204  } else {
205  istemplate = kFALSE;
206  name = clname + cur + 2;
207  }
208  }
209  break;
210  }
211  }
212  }
213  clname = name;
214  } else {
215  istemplate = strstr(clname, "<") != 0;
216  }
217 
218  protoname = clname;
219 
220  if (implementEmptyClass==1) {
221  TString headername(GetHeaderName(fullname,0));
222  fprintf(fp, "#ifndef %s_h\n", headername.Data());
223  fprintf(fp, "#define %s_h\n", headername.Data());
224  }
225  if (istemplate) {
226  std::vector<const char*> argtype;
227 
228  Ssiz_t pos = protoname.First('<');
229  UInt_t nparam = 1;
230  if (pos != kNPOS) {
231  if (isdigit(protoname[pos+1])) {
232  argtype.push_back("int");
233  } else {
234  argtype.push_back("typename");
235  }
236  UInt_t nest = 0;
237  for (Ssiz_t i = pos; i < protoname.Length(); ++i) {
238  switch (protoname[i]) {
239  case '<':
240  ++nest;
241  break;
242  case '>':
243  if (nest) --nest;
244  break;
245  case ',':
246  if (nest == 1) {
247  if (isdigit(protoname[i+1])) {
248  argtype.push_back("int");
249  } else {
250  argtype.push_back("typename");
251  }
252  ++nparam;
253  }
254  break;
255  }
256  }
257  protoname.Remove(pos);
258  }
259 
260  // Forward declaration of template.
261  fprintf(fp, "template <");
262  for (UInt_t p = 0; p < nparam; ++p) {
263  if (p >= argtype.size() ) {
264  fprintf(fp, "/* missing */ T%d", p);
265  } else {
266  fprintf(fp, "%s T%d", argtype[p], p);
267  }
268  if (p != (nparam - 1)) fprintf(fp, ", ");
269  }
270  if (needGenericTemplate) {
271  fprintf(fp, "> class %s", protoname.Data());
272  } else {
273  fprintf(fp, "> class %s;\n", protoname.Data());
274  fprintf(fp, "template <> ");
275  }
276  }
277 
278  if (implementEmptyClass) {
279  if (istemplate) {
280  if (!needGenericTemplate) {
281  fprintf(fp, "class %s", clname);
282  }
283  fprintf(fp, " {\n");
284  if (numberOfClasses) ++(*numberOfClasses);
285  fprintf(fp, "public:\n");
286  fprintf(fp, "operator int() { return 0; };\n");
287  } else {
288  fprintf(fp, "enum %s { kDefault_%s };\n", clname, clname);
289  // The nesting space of this class may not be #pragma declared (and without it
290  // the dictionary is broken), so for now skip those
291  if (implementEmptyClass==1) {
292  if (strchr(fullname, ':') == 0) {
293  // yes this is too aggressive, this needs to be fixed properly by moving the #pragma out of band.
294  fprintf(fp, "#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", fullname);
295  }
296  fprintf(fp, "#endif\n");
297  }
298  }
299  } else {
300  if (!(istemplate && needGenericTemplate)) {
301  fprintf(fp, "class %s", clname);
302  }
303  }
304  return numberOfNamespaces;
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Generate an empty StreamerInfo for the given type (no recursion) if it is not
309 /// not known in the list of class.
310 ///
311 /// If the type itself is a template,
312 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
313 
314 void TMakeProject::GenerateMissingStreamerInfo(TList *extrainfos, const char *clname, Bool_t iscope)
315 {
316  if (!TClassEdit::IsStdClass(clname) && !TClass::GetClass(clname) && gROOT->GetType(clname) == 0) {
317 
318  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(clname);
319  if (!info) {
320  // The class does not exist, let's create it
321  TStreamerInfo *newinfo = new TStreamerInfo();
322  newinfo->SetName(clname);
323  if (clname[strlen(clname)-1]=='>') {
324  newinfo->SetTitle("Generated by MakeProject as an empty class template instantiation");
325  newinfo->SetClassVersion(1);
326  } else if (iscope) {
327  newinfo->SetTitle("Generated by MakeProject as a namespace");
328  newinfo->SetClassVersion(-4 /*namespace*/);
329  } else {
330  newinfo->SetTitle("Generated by MakeProject as an enum");
331  newinfo->SetClassVersion(-3 /*enum*/);
332  }
333  extrainfos->Add(newinfo);
334  } else {
335  if (iscope) {
336  if (info->GetClassVersion() == -3) {
337  // This was marked as an enum but is also used as a scope,
338  // so it was actually a class.
339  info->SetTitle("Generated by MakeProject as an empty class");
340  info->SetClassVersion(-5 /*class*/);
341  }
342  } else {
343  if (info->GetClassVersion() == -4) {
344  // This was marked as a 'namespace' but it is also used as a template parameter,
345  // so it was actually a class.
346  info->SetTitle("Generated by MakeProject as an empty class");
347  info->SetClassVersion(-5 /*class*/);
348  }
349  }
350  }
351  }
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Generate an empty StreamerInfo for types that are used in templates parameters
356 /// but are not known in the list of class.
357 ///
358 /// If the type itself is a template, we mark it with version 1 (a class)
359 /// otherwise we mark it as version -3 (an enum).
360 
361 void TMakeProject::GenerateMissingStreamerInfos(TList *extrainfos, const char *clname)
362 {
363  UInt_t len = strlen(clname);
364  UInt_t nest = 0;
365  UInt_t last = 0;
366  //Bool_t istemplate = kFALSE; // mark whether the current right most entity is a class template.
367 
368  for (UInt_t i = 0; i < len; ++i) {
369  switch (clname[i]) {
370  case ':':
371  if (nest == 0 && clname[i+1] == ':') {
372  TString incName(clname, i);
373  GenerateMissingStreamerInfo(extrainfos, incName.Data(), kTRUE);
374  //istemplate = kFALSE;
375  }
376  break;
377  case '<':
378  ++nest;
379  if (nest == 1) last = i + 1;
380  break;
381  case '>':
382  if (nest == 0) return; // The name is not well formed, give up.
383  --nest; /* intentional fall throught to the next case */
384  case ',':
385  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
386  TString incName(clname + last, i - last);
388  if (clname[i] == '>' && nest == 1) incName.Append(">");
389 
390  if (isdigit(incName[0])) {
391  // Not a class name, nothing to do.
392  } else {
393  GenerateMissingStreamerInfos(extrainfos,incName.Data());
394  }
395  last = i + 1;
396  }
397  }
398  }
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////
403 /// Generate an empty StreamerInfo for types that are used in templates parameters
404 /// but are not known in the list of class.
405 ///
406 /// If the type itself is a template,
407 /// we mark it with version 1 (a class) otherwise we mark it as version -3 (an enum).
408 
410 {
411  if (element->IsBase()) {
412  TClass *elemCl = element->GetClassPointer();
413  if (elemCl) GenerateMissingStreamerInfos(extrainfos,elemCl->GetName());
414  else GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
415  } else {
416  GenerateMissingStreamerInfos(extrainfos,element->GetTypeName());
417  }
418 
419 }
420 
421 ////////////////////////////////////////////////////////////////////////////////
422 /// Insert a (complete) forward declaration for the class 'clname'
423 
424 UInt_t TMakeProject::GenerateForwardDeclaration(FILE *fp, const char *clname, char *inclist, Bool_t implementEmptyClass, Bool_t needGenericTemplate, const TList *extrainfos)
425 {
426  UInt_t ninc = 0;
427 
428  if (strchr(clname, '<')) {
429  ninc += GenerateIncludeForTemplate(fp, clname, inclist, kTRUE, extrainfos);
430  }
431  TString protoname;
432  UInt_t numberOfClasses = 0;
433  UInt_t numberOfNamespaces = GenerateClassPrefix(fp, clname, kTRUE, protoname, &numberOfClasses, implementEmptyClass, needGenericTemplate);
434 
435  if (!implementEmptyClass) fprintf(fp, ";\n");
436  for (UInt_t i = 0;i < numberOfClasses;++i) {
437  fprintf(fp, "}; // end of class.\n");
438  fprintf(fp, "#endif\n");
439  }
440  for (UInt_t i = 0;i < numberOfNamespaces;++i) {
441  fprintf(fp, "} // end of namespace.\n");
442  }
443 
444  return ninc;
445 }
446 
447 ////////////////////////////////////////////////////////////////////////////////
448 /// Add to the header file, the #include needed for the argument of
449 /// this template.
450 
451 UInt_t TMakeProject::GenerateIncludeForTemplate(FILE *fp, const char *clname, char *inclist, Bool_t forward, const TList *extrainfos)
452 {
453  UInt_t ninc = 0;
454  UInt_t len = strlen(clname);
455  UInt_t nest = 0;
456  UInt_t last = 0;
457 
458 
459  for (UInt_t i = 0; i < len; ++i) {
460  switch (clname[i]) {
461  case '<':
462  ++nest;
463  if (nest == 1) last = i + 1;
464  break;
465  case '>':
466  if (nest==0) return ninc; // the name is not well formed, give up.
467  --nest; /* intentional fall throught to the next case */
468  case ',':
469  if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
470  TString incName(clname + last, i - last);
472  if (clname[i] == '>' && nest == 1) incName.Append(">");
473  Int_t stlType;
474  if (isdigit(incName[0])) {
475  // Not a class name, nothing to do.
476  } else if ((stlType = TClassEdit::IsSTLCont(incName))) {
477  const char *what = "";
478  switch (TMath::Abs(stlType)) {
479  case ROOT::kSTLvector:
480  what = "vector";
481  break;
482  case ROOT::kSTLlist:
483  what = "list";
484  break;
486  what = "forward_list";
487  break;
488  case ROOT::kSTLdeque:
489  what = "deque";
490  break;
491  case ROOT::kSTLmap:
492  case ROOT::kSTLmultimap:
493  what = "map";
494  break;
497  what = "unordered_map";
498  break;
499  case ROOT::kSTLset:
500  case ROOT::kSTLmultiset:
501  what = "set";
502  break;
505  what = "unordered_set";
506  case ROOT::kSTLbitset:
507  what = "bitset";
508  break;
509  default:
510  what = "undetermined_stl_container";
511  break;
512  }
513  AddInclude(fp, what, kTRUE, inclist);
514  fprintf(fp, "namespace std {} using namespace std;\n");
515  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
516  } else if (strncmp(incName.Data(), "pair<", strlen("pair<")) == 0) {
517  AddInclude(fp, "utility", kTRUE, inclist);
518  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
519  } else if (strncmp(incName.Data(), "auto_ptr<", strlen("auto_ptr<")) == 0) {
520  AddInclude(fp, "memory", kTRUE, inclist);
521  ninc += GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
522  } else if (TClassEdit::IsStdClass(incName)) {
523  // Do nothing.
524  } else {
525  TClass *cl = gROOT->GetClass(incName);
526  if (!forward && cl) {
527  if (cl->HasInterpreterInfo()) {
528  // We have the real dictionary for this class.
529 
530  const char *include = cl->GetDeclFileName();
531  if (include && include[0]) {
532 
533  if (strncmp(include, "include/", 8) == 0) {
534  include += 8;
535  }
536  if (strncmp(include, "include\\", 9) == 0) {
537  include += 9;
538  }
539  TMakeProject::AddInclude(fp, include, kFALSE, inclist);
540  }
541  GenerateIncludeForTemplate(fp, incName, inclist, forward, extrainfos);
542  } else {
543  incName = GetHeaderName(incName,extrainfos);
544  incName.Append(".h");
545  AddInclude(fp, incName, kFALSE, inclist);
546  }
547  } else if (incName.Length() && incName[0] != ' ' && gROOT->GetType(incName) == 0) {
548  Bool_t emptyclass = !cl;
549  if (emptyclass && extrainfos) {
550  TStreamerInfo *info = (TStreamerInfo*)extrainfos->FindObject(incName);
551  if (info && info->GetClassVersion() == -5) {
552  emptyclass = kFALSE;
553  }
554  }
555  GenerateForwardDeclaration(fp, incName, inclist, emptyclass, kFALSE, extrainfos);
556  }
557  }
558  last = i + 1;
559  }
560  }
561  }
562 
563  Int_t stlType = TClassEdit::IsSTLCont(clname);
564  if (stlType) {
565  std::vector<std::string> inside;
566  int nestedLoc;
567  TClassEdit::GetSplit( clname, inside, nestedLoc, TClassEdit::kLong64 );
568  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
569  TClass *key = TClass::GetClass(inside[1].c_str());
570  if (key) {
571  TString what;
572  switch (stlkind) {
573  case ROOT::kSTLmap:
574  case ROOT::kSTLmultimap: {
575  what = "pair<";
576  what += UpdateAssociativeToVector( inside[1].c_str() );
577  what += ",";
578  what += UpdateAssociativeToVector( inside[2].c_str() );
579  what += " >";
580  what.ReplaceAll("std::","");
581  // Only ask for it if needed.
582  TClass *paircl = TClass::GetClass(what.Data());
583  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
584  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", what.Data()), inclist);
585  }
586  break;
587  }
588  }
589  }
590  }
591 
592  if (strncmp(clname, "auto_ptr<", strlen("auto_ptr<")) == 0) {
593  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n", clname), inclist);
594  }
595  return ninc;
596 }
597 
598 
599 ////////////////////////////////////////////////////////////////////////////////
600 /// Add to the header file anything that need to appear after the class
601 /// declaration (this includes some #pragma link).
602 
603 void TMakeProject::GeneratePostDeclaration(FILE *fp, const TVirtualStreamerInfo *info, char *inclist)
604 {
605  TIter next(info->GetElements());
606  TStreamerElement *element;
607  while( (element = (TStreamerElement*)next()) ) {
608  Int_t stlType = TClassEdit::IsSTLCont(element->GetTypeName());
609  if (stlType) {
610  std::vector<std::string> inside;
611  int nestedLoc;
612  TClassEdit::GetSplit( element->GetTypeName(), inside, nestedLoc, TClassEdit::kLong64 );
613  Int_t stlkind = TClassEdit::STLKind(inside[0].c_str());
614  TClass *key = TClass::GetClass(inside[1].c_str());
615  TString what;
616  if (strncmp(inside[1].c_str(),"pair<",strlen("pair<"))==0) {
617  what = inside[1].c_str();
618  } else if (key) {
619  switch (stlkind) {
620  case ROOT::kSTLmap:
621  case ROOT::kSTLmultimap:
622  {
623  // Already done (see GenerateIncludeForTemplate
624  break;
625  }
626  default:
627  break;
628  }
629  }
630  if (what.Length()) {
631  // Only ask for it if needed.
632  TClass *paircl = TClass::GetClass(what.Data());
633  if (paircl == 0 || !paircl->HasInterpreterInfo()) {
634  AddUniqueStatement(fp, TString::Format("#ifdef __MAKECINT__\n#pragma link C++ class %s+;\n#endif\n",what.Data()), inclist);
635  }
636  }
637  }
638  }
639 }
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// If we have a map, multimap, set or multiset, plus unordered partners,
643 /// and the key is a class, we need to replace the
644 /// container by a vector since we don't have the
645 /// comparator function.
646 /// The 'name' is modified to return the change in the name,
647 /// if any.
648 
650 {
651  TString newname( name );
652 
653  if (strchr(name,'<')!=0) {
654  std::vector<std::string> inside;
655  int nestedLoc;
656  unsigned int narg = TClassEdit::GetSplit( name, inside, nestedLoc, TClassEdit::kLong64 );
657  if (nestedLoc) --narg;
658  Int_t stlkind = TMath::Abs(TClassEdit::STLKind(inside[0].c_str()));
659 
660  for(unsigned int i = 1; i<narg; ++i) {
661  inside[i] = UpdateAssociativeToVector( inside[i].c_str() );
662  }
663  // Remove default allocator if any.
664  static const char* allocPrefix = "std::allocator<";
665  static const unsigned int allocPrefixLen (strlen(allocPrefix));
666  switch (stlkind) {
667  case ROOT::kSTLvector:
668  case ROOT::kSTLlist:
670  case ROOT::kSTLdeque:
671  if (narg>2 && strncmp(inside[2].c_str(),allocPrefix,allocPrefixLen)==0) {
672  --narg;
673  }
674  break;
675  case ROOT::kSTLset:
676  case ROOT::kSTLmultiset:
677  case ROOT::kSTLmap:
678  case ROOT::kSTLmultimap:
679  if (narg>4 && strncmp(inside[4].c_str(),allocPrefix,allocPrefixLen)==0) {
680  --narg;
681  }
682  break;
685  if (narg>5 && strncmp(inside[5].c_str(),allocPrefix,allocPrefixLen)==0) {
686  --narg;
687  }
688  break;
691  if (narg>6 && strncmp(inside[6].c_str(),allocPrefix,allocPrefixLen)==0) {
692  --narg;
693  }
694  break;
695  }
696  if (stlkind!=0) {
697  TClass *key = TClass::GetClass(inside[1].c_str());
698 
699  if (key) {
700  // We only need to translate to a vector is the key is a class
701  // (for which we do not know the sorting).
702  std::string what;
703  switch ( stlkind ) {
704  case ROOT::kSTLmap:
706  case ROOT::kSTLmultimap:
708  what = "std::pair<";
709  what += inside[1];
710  what += ",";
711  what += inside[2];
712  if (what[what.size()-1]=='>') {
713  what += " >";
714  } else {
715  what += ">";
716  }
717  inside.clear();
718  inside.push_back("std::vector");
719  inside.push_back(what);
720  narg = 2;
721  break;
722  }
723  case ROOT::kSTLset:
725  case ROOT::kSTLmultiset:
727  inside[0] = "std::vector";
728  break;
729  }
730  }
731  if (strncmp(inside[0].c_str(),"std::",5) != 0) {
732  inside[0] = "std::" + inside[0];
733  }
734  } else {
735  static const char *stlnames[] = { "pair", "greater", "less", "allocator" };
736  for(unsigned int in = 0; in < sizeof(stlnames)/sizeof(stlnames[0]); ++in) {
737  if (strncmp( inside[0].c_str(), stlnames[in], strlen(stlnames[in])) == 0 ) {
738  inside[0] = "std::" + inside[0];
739  break;
740  }
741  }
742  }
743  newname = inside[0];
744  newname.Append("<");
745  newname.Append(inside[1]);
746  for(unsigned int j=2; j<narg; ++j) {
747  if (!inside[j].empty()) {
748  newname.Append(",");
749  newname.Append(inside[j]);
750  }
751  }
752  if (newname[newname.Length()-1]=='>') {
753  newname.Append(" >");
754  } else {
755  newname.Append(">");
756  }
757  if (nestedLoc) newname.Append(inside[nestedLoc]);
758  } else if ( newname == "string" ) {
759  newname = "std::string";
760  }
761  return newname;
762 }
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<list<classA,allocator>,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:166
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:927
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:344
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:497
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:2321
const char * AsString() const
Return message digest as string.
Definition: TMD5.cxx:219
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:806
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:107
Bool_t HasInterpreterInfo() const
Definition: TClass.h:373
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
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:2801
#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:385
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:5243
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:453