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