32using std::string, std::string_view, std::vector, std::set;
38 struct ShuttingDownSignaler :
public T {
41 ShuttingDownSignaler() =
default;
42 ShuttingDownSignaler(T &&in) :
T(std::move(in)) {}
44 ~ShuttingDownSignaler()
46 if (gInterpreterHelper)
59 if (
name.compare(0,5,
"std::")==0) {
64 if (gInterpreterHelper) {
65 for(
size_t i = 5; i <
name.length(); ++i) {
66 if (
name[i] ==
'<')
break;
68 std::string scope(
name.data(),i);
72 static ShuttingDownSignaler<std::set<std::string>> gInlined;
73 static std::atomic_flag spinFlag = ATOMIC_FLAG_INIT;
78 isInlined = (gInlined.find(scope) != gInlined.end());
83 if (i+1<
name.length() &&
name[i+1]==
':') {
87 std::string scoperesult;
94 gInlined.insert(scope);
97 if (i+1<
name.length() &&
name[i+1]==
':') {
139 if (0 == strncmp(clName,
"complex<", 8)) {
140 const char *clNamePlus8 = clName + 8;
141 if (0 == strcmp(
"float>", clNamePlus8)) {
142 return EComplexType::kFloat;
144 if (0 == strcmp(
"double>", clNamePlus8)) {
145 return EComplexType::kDouble;
147 if (0 == strcmp(
"int>", clNamePlus8)) {
148 return EComplexType::kInt;
150 if (0 == strcmp(
"long>", clNamePlus8)) {
151 return EComplexType::kLong;
154 return EComplexType::kNone;
165 if (
this == gInterpreterHelper)
166 gInterpreterHelper =
nullptr;
173 gInterpreterHelper = helper;
209 if (fElements[0].empty())
return 0;
210 int numb = fElements.size();
211 if (!fElements[numb-1].empty() && fElements[numb-1][0]==
'*') --numb;
213 if ( fNestedLocation ) {
219 int kind =
STLKind(fElements[0]);
224 if (testAlloc && (numb-1 > nargs) && !
IsDefAlloc(fElements[numb-1].c_str(),fElements[1].c_str())) {
236 if (k<0) kind = -kind;
242 if(kind>2) kind = - kind;
262 int narg = fElements.size();
273 if (fElements[narg-1].empty() ==
false &&
274 (fElements[narg-1][0]==
'*'
275 || fElements[narg-1][0]==
'&'
276 || fElements[narg-1][0]==
'['
277 || 0 == fElements[narg-1].compare(0,6,
"const*")
278 || 0 == fElements[narg-1].compare(0,6,
"const&")
279 || 0 == fElements[narg-1].compare(0,6,
"const[")
280 || 0 == fElements[narg-1].compare(
"const")
283 if ((
mode&1)==0) tailLoc = narg-1;
285 else { assert(fElements[narg-1].empty()); };
289 if (fNestedLocation) narg--;
294 const int kind =
STLKind(fElements[0]);
295 const int iall =
STLArgs(kind);
299 while(narg-1>iall) { fElements.pop_back(); narg--;}
300 if (!fElements[0].empty() && tailLoc) {
303 fElements[0].clear();
311 bool allocRemoved =
false;
317 if (narg-1 == iall+1) {
319 bool dropAlloc =
false;
334 dropAlloc =
IsDefAlloc(fElements[iall+1].c_str(),fElements[1].c_str());
340 dropAlloc =
IsDefAlloc(fElements[iall+1].c_str(),fElements[1].c_str(),fElements[2].c_str());
358 if (
IsDefComp( fElements[iall].c_str(), fElements[1].c_str() ) ) {
373 if (!allocRemoved && narg-1 == iall+1) {
377 if (narg-1 == iall) narg--;
400 bool predRemoved =
false;
403 if (
IsDefPred( fElements[iall].c_str(), fElements[1].c_str() ) ) {
410 if (
IsDefHash( fElements[iall-1].c_str(), fElements[1].c_str() ) ) {
418 unsigned int offset = (0==strncmp(
"const ",fElements[0].c_str(),6)) ? 6 : 0;
419 offset += (0==strncmp(
"std::",fElements[0].c_str()+
offset,5)) ? 5 : 0;
420 if (0 == strcmp(fElements[0].c_str()+
offset,
"__shared_ptr"))
423 static const std::string sharedPtrDef = std::to_string(__gnu_cxx::__default_lock_policy);
425 static const std::string sharedPtrDef = std::to_string(2);
427 if (fElements[2] == sharedPtrDef) {
435 for (
int i=1;i<narg; i++) {
436 if (!strchr(fElements[i].c_str(),
'<')) {
438 unsigned int offset = (0==strncmp(
"const ",fElements[i].c_str(),6)) ? 6 : 0;
452 if (gInterpreterHelper &&
455 if (!typeresult.empty()) fElements[i] = typeresult;
460 unsigned int tailOffset = 0;
461 if (tailLoc && fElements[tailLoc].compare(0,5,
"const") == 0) {
465 if (!fElements[0].empty()) {answ += fElements[0]; answ +=
"<";}
474 int nargNonDefault = 0;
475 std::string nonDefName = answ;
477 std::string nameSuperLong = fName;
478 if (gInterpreterHelper)
480 while (++nargNonDefault < narg) {
483 const char* closeTemplate =
" >";
484 if (nonDefName[nonDefName.length() - 1] !=
'>')
486 string nondef = nonDefName + closeTemplate;
487 if (gInterpreterHelper &&
490 if (nargNonDefault>1) nonDefName +=
",";
491 nonDefName += fElements[nargNonDefault];
493 if (nargNonDefault < narg)
494 narg = nargNonDefault;
498 {
for (
int i=1;i<narg-1; i++) { answ += fElements[i]; answ+=
",";} }
499 if (narg>1) { answ += fElements[narg-1]; }
501 if (!fElements[0].empty()) {
502 if ( answ.at(answ.size()-1) ==
'>') {
508 if (fNestedLocation) {
511 answ += fElements[fNestedLocation];
514 if (tailLoc) answ += fElements[tailLoc].c_str()+tailOffset;
521 return !fElements[0].empty();
530 if (
type.length() == 0)
533 if (
type.compare(0,6,
"const ")==0) {
offset += 6; }
540 static const char *stls[] =
541 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
542 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
nullptr};
543 static const size_t stllen[] =
544 { 3, 6, 4, 5, 3, 8, 3, 8, 6,
545 12, 13, 18, 13, 18, 0};
561 for (
int k = 1; stls[k]; ++k) {
562 if (
len == stllen[k]) {
577 static const char stln[] =
579 { 1, 1, 1, 1, 3, 3, 2, 2, 1,
582 assert(std::size_t(kind) <
sizeof(stln) &&
"index is out of bounds");
592 for(
size_t i = 0; i < full.length(); ++i) {
594 case '<': { ++level;
break; }
596 if (level == 0)
return i;
601 if (level == 0)
return i;
607 return full.length();
614 return pos +
findNameEnd( {full.data()+pos,full.length()-pos} );
623 string_view
a( allocname );
626 if (
a==
"alloc")
return true;
627 if (
a==
"__default_alloc_template<true,0>")
return true;
628 if (
a==
"__malloc_alloc_template<0>")
return true;
630 const static int alloclen = strlen(
"allocator<");
631 if (
a.compare(0,alloclen,
"allocator<") != 0) {
634 a.remove_prefix(alloclen);
638 string_view k = classname;
641 if (
a.compare(0,k.length(),k) != 0) {
645 std::string valuepart;
648 std::string norm_value;
651 if (valuepart != norm_value) {
654 a.remove_prefix(end);
656 a.remove_prefix(k.length());
659 if (
a.compare(0,1,
">")!=0 &&
a.compare(0,2,
" >")!=0) {
671 const char *keyclassname,
672 const char *valueclassname)
674 if (
IsDefAlloc(allocname,keyclassname))
return true;
676 string_view
a( allocname );
679 const static int alloclen = strlen(
"allocator<");
680 if (
a.compare(0,alloclen,
"allocator<") != 0) {
683 a.remove_prefix(alloclen);
687 const static int pairlen = strlen(
"pair<");
688 if (
a.compare(0,pairlen,
"pair<") != 0) {
691 a.remove_prefix(pairlen);
693 const static int constlen = strlen(
"const");
694 if (
a.compare(0,constlen+1,
"const ") == 0) {
695 a.remove_prefix(constlen+1);
700 string_view k = keyclassname;
702 if (k.compare(0,constlen+1,
"const ") == 0) {
703 k.remove_prefix(constlen+1);
706 if (
a.compare(0,k.length(),k) != 0) {
710 std::string alloc_keypart;
713 std::string norm_key;
716 if (alloc_keypart != norm_key) {
717 if ( norm_key[norm_key.length()-1] ==
'*' ) {
721 norm_key +=
" const";
723 if (alloc_keypart != norm_key) {
727 a.remove_prefix(end);
729 size_t end = k.length();
730 if ( (
a[end-1] ==
'*') ||
a[end]==
' ' ) {
731 size_t skipSpace = (
a[end] ==
' ');
732 if (
a.compare(end+skipSpace,constlen,
"const") == 0) {
733 end += constlen+skipSpace;
736 a.remove_prefix(end);
745 string_view
v = valueclassname;
748 if (
a.compare(0,
v.length(),
v) != 0) {
752 std::string valuepart;
755 std::string norm_value;
758 if (valuepart != norm_value) {
761 a.remove_prefix(end);
763 a.remove_prefix(
v.length());
766 if (
a.compare(0,1,
">")!=0 &&
a.compare(0,2,
" >")!=0) {
777static bool IsDefElement(
const char *elementName,
const char* defaultElementName,
const char *classname)
779 string c = elementName;
783 const int elementlen = strlen(defaultElementName);
784 if (
c.compare(pos,elementlen,defaultElementName) != 0) {
789 string k = classname;
790 if (
c.compare(pos,k.length(),k) != 0) {
799 std::string norm_key;
802 if (keypart != norm_key) {
810 if (
c.compare(pos,1,
">")!=0 &&
c.compare(pos,2,
" >")!=0) {
861 norm_name = std::string(
name);
876 std::string first, second;
879 norm_name = splitname.
fElements[0] +
"<" + first +
"," + second;
880 if (!second.empty() && second.back() ==
'>')
890 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
891 norm_name.erase(0,2);
894 if (gInterpreterHelper) {
896 std::string typeresult;
900 if (!typeresult.empty()) norm_name = typeresult;
921 static const char* longlong_s =
"long long";
922 static const char* ulonglong_s =
"unsigned long long";
923 static const unsigned int longlong_len = strlen(longlong_s);
924 static const unsigned int ulonglong_len = strlen(ulonglong_s);
929 while( (pos =
result.find(ulonglong_s,pos) ) >=0 ) {
930 result.replace(pos, ulonglong_len,
"ULong64_t");
933 while( (pos =
result.find(longlong_s,pos) ) >=0 ) {
934 result.replace(pos, longlong_len,
"Long64_t");
944 const char *lastPos = original;
950 else if ( *
cursor ==
':' ) {
951 if (depth==0 && *(
cursor+1) ==
':' && *(
cursor+2) !=
'\0') {
966 const char *t = full.c_str();
967 const unsigned int tlen( full.size() );
969 const char *starloc = t + tlen - 1;
970 bool hasconst =
false;
972 && (starloc-t) > 4 && 0 == strncmp((starloc-4),
"const",5)
973 && ( (*(starloc-5)) ==
' ' || (*(starloc-5)) ==
'*' || (*(starloc-5)) ==
'&'
974 || (*(starloc-5)) ==
'>' || (*(starloc-5)) ==
']') ) {
977 if ((*starloc-1)==
' ') {
983 if ( hasconst || (*starloc)==
'*' || (*starloc)==
'&' || (*starloc)==
']' ) {
984 bool isArray = ( (*starloc)==
']' );
985 while( t<=(starloc-1) && ((*(starloc-1))==
'*' || (*(starloc-1))==
'&' || (*(starloc-1))==
't' || isArray)) {
988 isArray = ! ( (*starloc)==
'[' );
989 }
else if ( (*(starloc-1))==
't' ) {
990 if ( (starloc-1-t) > 5 && 0 == strncmp((starloc-5),
"const",5)
991 && ( (*(starloc-6)) ==
' ' || (*(starloc-6)) ==
'*' || (*(starloc-6)) ==
'&'
992 || (*(starloc-6)) ==
'>' || (*(starloc-6)) ==
']')) {
1003 if ((*(starloc-1))==
' ') {
1008 const unsigned int starlen = strlen(starloc);
1009 full.erase(tlen-starlen,starlen);
1010 }
else if (hasconst) {
1012 const unsigned int starlen = strlen(starloc);
1013 full.erase(tlen-starlen,starlen);
1033 if (strlen(
type)==0)
return 0;
1035 int cleantypeMode = 1 ;
1044 unsigned int const_offset = (0==strncmp(
"const ",full.c_str(),6)) ? 6 : 0;
1045 bool isString =
false;
1046 bool isStdString =
false;
1047 size_t std_offset = const_offset;
1048 static const char* basic_string_std =
"std::basic_string<char";
1049 static const unsigned int basic_string_std_len = strlen(basic_string_std);
1051 if (full.compare(const_offset,basic_string_std_len,basic_string_std) == 0
1052 && full.size() > basic_string_std_len) {
1056 }
else if (full.compare(const_offset,basic_string_std_len-5,basic_string_std+5) == 0
1057 && full.size() > (basic_string_std_len-5)) {
1060 }
else if (full.find(
"basic_string") != std::string::npos) {
1061 size_t len =
StdLen(full.c_str() + const_offset);
1062 if (
len &&
len != 5 && full.compare(const_offset +
len, basic_string_std_len-5, basic_string_std+5) == 0) {
1069 size_t offset = basic_string_std_len - 5;
1071 if ( full[
offset] ==
'>' ) {
1073 }
else if (full[
offset] ==
',') {
1075 if (full.compare(
offset, 5,
"std::") == 0) {
1078 static const char* char_traits_s =
"char_traits<char>";
1079 static const unsigned int char_traits_len = strlen(char_traits_s);
1080 if (full.compare(
offset, char_traits_len, char_traits_s) == 0) {
1081 offset += char_traits_len;
1082 if ( full[
offset] ==
'>') {
1084 }
else if (full[
offset] ==
' ' && full[
offset+1] ==
'>') {
1087 }
else if (full[
offset] ==
',') {
1089 if (full.compare(
offset, 5,
"std::") == 0) {
1092 static const char* allocator_s =
"allocator<char>";
1093 static const unsigned int allocator_len = strlen(allocator_s);
1094 if (full.compare(
offset, allocator_len, allocator_s) == 0) {
1096 if ( full[
offset] ==
'>') {
1098 }
else if (full[
offset] ==
' ' && full[
offset+1] ==
'>') {
1119 output.push_back(
string());
1122 output.push_back(
"const std::string");
1124 output.push_back(
"const string");
1128 output.push_back(
"std::string");
1130 output.push_back(
"string");
1133 if (
offset < full.length()) {
1136 string right( full.substr(
offset) );
1139 output.back().append(right.c_str()+1);
1150 unsigned int offset = (0==strncmp(
"const ",full.c_str(),6)) ? 6 : 0;
1155 if ( !full.empty() ) {
1159 const char *
c = strchr(full.c_str(),
'<');
1162 output.push_back(
string(full,0,
c - full.c_str()));
1166 int parenthesis = 0;
1171 }
else if (*
cursor ==
')') {
1178 case '<': ++level;
break;
1179 case '>': --level;
break;
1189 if (*(
cursor-1) ==
' ') {
1198 nestedLoc =
output.size();
1201 }
else if (level >= 0) {
1207 output.push_back(
string());
1234 static const char* remove[] = {
"class",
"const",
"volatile",
nullptr};
1235 auto initLengthsVector = []() {
1236 std::vector<size_t> create_lengths;
1237 for (
int k=0; remove[k]; ++k) {
1238 create_lengths.push_back(strlen(remove[k]));
1240 return create_lengths;
1242 static std::vector<size_t> lengths{ initLengthsVector() };
1245 result.reserve(strlen(typeDesc)*2);
1249 for(
c=typeDesc;*
c;
c++) {
1252 if (!isalnum(
c[ 1]) &&
c[ 1] !=
'_')
continue;
1254 if (kbl && (
mode>=2 || lev==0)) {
1256 int n = (
mode) ? 999 : 1;
1259 for (
int k=0; k<
n && remove[k]; k++) {
1260 int rlen = lengths[k];
1263 if (strncmp(remove[k],
c,rlen))
continue;
1266 if (isalnum(
c[rlen]) ||
c[rlen]==
'_' ||
c[rlen]==
'$')
continue;
1268 c+=rlen-1; done = 1;
break;
1273 kbl = (!isalnum(
c[ 0]) &&
c[ 0]!=
'_' &&
c[ 0]!=
'$' &&
c[0]!=
'[' &&
c[0]!=
']' &&
c[0]!=
'-' &&
c[0]!=
'@');
1277 if (*
c ==
'<' || *
c ==
'(') lev++;
1278 if (lev==0 && !isalnum(*
c)) {
1279 if (!strchr(
"*&:._$ []-@",*
c))
break;
1287 if (*
c ==
'>' || *
c ==
')') lev--;
1325 if (
len < 2 || strncmp(
type+
len-2,
"_t",2) != 0)
return false;
1327 unsigned char offset = 0;
1328 if (strncmp(
type,
"const ",6)==0) {
offset += 6; }
1329 static const char *names[] = {
"CallFunc_t",
"ClassInfo_t",
"BaseClassInfo_t",
1330 "DataMemberInfo_t",
"FuncTempInfo_t",
"MethodInfo_t",
"MethodArgInfo_t",
1331 "TypeInfo_t",
"TypedefInfo_t",
nullptr};
1333 for(
int k=1;names[k];k++) {
if (strcmp(
type+
offset,names[k])==0)
return true;}
1343 if ( strncmp(classname+
offset,
"bitset<",strlen(
"bitset<"))==0)
return true;
1361 if (
type.compare(0,6,
"const ",6) == 0)
1362 type.remove_prefix(6);
1364 while(
type[
type.length()-1]==
'*' ||
1367 type.remove_suffix(1);
1380 auto pos =
type.find(
'<');
1384 for (
decltype(
type.length()) level = 1;
c <
type.length(); ++
c) {
1385 if (
type[
c] ==
'<') ++level;
1386 if (
type[
c] ==
'>') --level;
1387 if (level == 0)
break;
1389 if (
c != (
type.length()-1) ) {
1409 if (!strchr(
type,
'<'))
return 0;
1420 classname +=
StdLen( classname );
1421 if ( strcmp(classname,
"string")==0 )
return true;
1422 if ( strncmp(classname,
"bitset<",strlen(
"bitset<"))==0)
return true;
1423 if (
IsStdPair(classname) )
return true;
1424 if ( strcmp(classname,
"allocator")==0)
return true;
1425 if ( strncmp(classname,
"allocator<",strlen(
"allocator<"))==0)
return true;
1426 if ( strncmp(classname,
"greater<",strlen(
"greater<"))==0)
return true;
1427 if ( strncmp(classname,
"less<",strlen(
"less<"))==0)
return true;
1428 if ( strncmp(classname,
"equal_to<",strlen(
"equal_to<"))==0)
return true;
1429 if ( strncmp(classname,
"hash<",strlen(
"hash<"))==0)
return true;
1430 if ( strncmp(classname,
"auto_ptr<",strlen(
"auto_ptr<"))==0)
return true;
1432 if ( strncmp(classname,
"vector<",strlen(
"vector<"))==0)
return true;
1433 if ( strncmp(classname,
"list<",strlen(
"list<"))==0)
return true;
1434 if ( strncmp(classname,
"forward_list<",strlen(
"forward_list<"))==0)
return true;
1435 if ( strncmp(classname,
"deque<",strlen(
"deque<"))==0)
return true;
1436 if ( strncmp(classname,
"map<",strlen(
"map<"))==0)
return true;
1437 if ( strncmp(classname,
"multimap<",strlen(
"multimap<"))==0)
return true;
1438 if ( strncmp(classname,
"set<",strlen(
"set<"))==0)
return true;
1439 if ( strncmp(classname,
"multiset<",strlen(
"multiset<"))==0)
return true;
1440 if ( strncmp(classname,
"unordered_set<",strlen(
"unordered_set<"))==0)
return true;
1441 if ( strncmp(classname,
"unordered_multiset<",strlen(
"unordered_multiset<"))==0)
return true;
1442 if ( strncmp(classname,
"unordered_map<",strlen(
"unordered_map<"))==0)
return true;
1443 if ( strncmp(classname,
"unordered_multimap<",strlen(
"unordered_multimap<"))==0)
return true;
1444 if ( strncmp(classname,
"bitset<",strlen(
"bitset<"))==0)
return true;
1445 if ( strncmp(classname,
"ROOT::VecOps::RVec<",strlen(
"ROOT::VecOps::RVec<"))==0)
return true;
1466 unsigned int start_of_type,
1467 unsigned int end_of_type,
1468 unsigned int mod_start_of_type,
1472 std::string
type(modified && (mod_start_of_type <
result.length()) ?
1473 result.substr(mod_start_of_type, string::npos)
1474 : string(tname, start_of_type, end_of_type == 0 ?
cursor - start_of_type : end_of_type - start_of_type));
1479 if (!typeresult.empty()) {
1482 result.replace(mod_start_of_type, string::npos,
1487 result += string(tname,0,start_of_type);
1488 if (constprefix && typeresult.compare(0,6,
"const ",6) == 0) {
1489 result += typeresult.substr(6,string::npos);
1494 }
else if (modified) {
1495 result.replace(mod_start_of_type, string::npos,
1499 if (end_of_type != 0 && end_of_type!=
cursor) {
1500 result += std::string(tname,end_of_type,
cursor-end_of_type);
1507 if (end_of_type != 0 && end_of_type!=
cursor) {
1508 result += std::string(tname,end_of_type,
cursor-end_of_type);
1527 bool constprefix =
false;
1529 if (tname[
cursor]==
' ') {
1538 if (strncmp(tname+
cursor,
"const ",6) == 0) {
1540 if (modified)
result +=
"const ";
1546 if (
len > 2 && strncmp(tname+
cursor,
"::",2) == 0) {
1550 unsigned int start_of_type =
cursor;
1551 unsigned int end_of_type = 0;
1552 unsigned int mod_start_of_type =
result.length();
1553 unsigned int prevScope =
cursor;
1559 if (modified)
result += (tname+prevScope);
1564 scope =
result.substr(mod_start_of_type, string::npos);
1565 scope += std::string(tname+prevScope,
cursor-prevScope);
1567 scope = std::string(tname, start_of_type,
cursor - start_of_type);
1569 std::string scoperesult;
1570 bool isInlined =
false;
1574 if (!scoperesult.empty()) {
1577 if (constprefix && scoperesult.compare(0,6,
"const ",6) != 0) mod_start_of_type -= 6;
1578 result.replace(mod_start_of_type, string::npos,
1583 mod_start_of_type = start_of_type;
1584 result += string(tname,0,start_of_type);
1589 }
else if (modified) {
1590 result += std::string(tname+prevScope,
cursor+2-prevScope);
1594 if (modified)
result += std::string(tname+prevScope,
cursor+2-prevScope);
1595 }
else if (isInlined) {
1599 mod_start_of_type = start_of_type;
1600 result += string(tname,0,start_of_type);
1602 result += string(tname,start_of_type,prevScope - start_of_type);
1604 }
else if (modified) {
1605 result += std::string(tname+prevScope,
cursor+2-prevScope);
1615 result += std::string(tname+prevScope,
cursor+1-prevScope);
1629 if (modified)
result +=
"::";
1635 if (modified)
result +=
',';
1640 if (modified)
result +=
" >";
1646 if (tname[
cursor] !=
' ')
break;
1647 if (modified) prevScope =
cursor+1;
1659 if (strncmp(tname+next,
"const",5) == 0 && ((next+5)==
len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
']'))
1664 result += string(tname,0,start_of_type);
1666 mod_start_of_type = start_of_type + 6;
1667 result += string(tname,start_of_type,end_of_type-start_of_type);
1668 }
else if (mod_start_of_type <
result.length()) {
1669 result.insert(mod_start_of_type,
"const ");
1670 mod_start_of_type += 6;
1673 mod_start_of_type += 6;
1674 result += string(tname,start_of_type,end_of_type-start_of_type);
1678 prevScope = end_of_type;
1679 if ((next+5)==
len || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
'[') {
1682 }
else if (next!=
len && tname[next] !=
'*' && tname[next] !=
'&') {
1695 if (strncmp(tname+next,
"const",5) == 0) {
1696 if ((next+5)==
len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
'[') {
1701 (tname[next] ==
' ' || tname[next] ==
'*' || tname[next] ==
'&')) {
1704 if (strncmp(tname+next,
"const",5) == 0) {
1705 if ((next+5)==
len || tname[next+5] ==
' ' || tname[next+5] ==
'*' || tname[next+5] ==
'&' || tname[next+5] ==
',' || tname[next+5] ==
'>' || tname[next+5] ==
'[') {
1717 if (modified && prevScope) {
1718 result += std::string(tname+prevScope,(end_of_type == 0 ?
cursor : end_of_type)-prevScope);
1722 if (modified)
result +=
',';
1726 if (modified && prevScope) {
1727 result += std::string(tname+prevScope,(end_of_type == 0 ?
cursor : end_of_type)-prevScope);
1731 if (modified)
result +=
'>';
1739 if (prevScope && modified)
result += std::string(tname+prevScope,(end_of_type == 0 ?
cursor : end_of_type)-prevScope);
1756 if (!tname || *tname == 0)
1758 if (!gInterpreterHelper)
1767 if (
result.empty())
return tname;
1771 unsigned int len = strlen(tname);
1774 bool modified =
false;
1777 if (!modified)
return tname;
1791 static const char* sSTLtypes[] = {
1804 "basic_istringstream",
1807 "basic_ostringstream",
1811 "basic_stringstream",
1840 "istreambuf_iterator",
1849 "localedef utility",
1866 "moneypunct_byname",
1878 "ostreambuf_iterator",
1884 "pointer_to_binary_function",
1885 "pointer_to_unary_function",
1889 "raw_storage_iterator",
1908 "unordered_multimap",
1909 "unordered_multiset",
1916 if (!tname || *tname == 0)
return "";
1918 auto initSetSTLtypes = []() {
1919 std::set<std::string> iSetSTLtypes;
1921 const size_t nSTLtypes =
sizeof(sSTLtypes) /
sizeof(
const char*);
1922 for (
size_t i = 0; i < nSTLtypes; ++i)
1923 iSetSTLtypes.insert(sSTLtypes[i]);
1924 return iSetSTLtypes;
1926 static ShuttingDownSignaler<std::set<std::string>> sSetSTLtypes{ initSetSTLtypes() };
1929 size_t len = strlen(tname);
1931 ret.reserve(
len + 20);
1935 bool precScope =
false;
1936 while (!(isalnum(tname[
b]) || tname[
b] ==
'_') &&
b <
len) {
1937 precScope = (
b <
len - 2) && (tname[
b] ==
':') && (tname[
b + 1] ==
':');
1949 while (
e <
len && (isalnum(tname[
e]) || tname[
e] ==
'_'))
1953 set<string>::const_iterator iSTLtype = sSetSTLtypes.find(
id);
1954 if (iSTLtype != sSetSTLtypes.end())
1971 std::vector<std::unique_ptr<NameCleanerForIO>> fArgumentNodes = {};
1973 bool fHasChanged =
false;
1977 if (!mother)
return false;
1978 bool isSTLContOrArray =
true;
1979 while (
nullptr != mother){
1985 return isSTLContOrArray;
1993 if (clName.back() !=
'>') {
1998 std::vector<std::string>
v;
2003 auto argsEnd =
v.end();
2004 auto argsBeginPlusOne = ++
v.begin();
2005 auto argPos = std::find_if(argsBeginPlusOne, argsEnd,
2006 [](std::string& arg){
return (!arg.empty() && arg.front() ==
':');});
2007 if (argPos != argsEnd) {
2008 const int length = clName.size();
2009 int wedgeBalance = 0;
2010 int lastOpenWedge = 0;
2011 for (
int i=
length-1;i>-1;i--) {
2012 auto&
c = clName.at(i);
2016 }
else if (
c ==
'>') {
2018 }
else if (
c ==
':' && 0 == wedgeBalance) {
2020 auto nameToClean = clName.substr(0,i-1);
2029 cleanName += clName.substr(i+1,lastOpenWedge-i-1);
2032 auto lastTemplate = &clName.data()[i+1];
2044 unsigned int nargs =
v.size() - 2;
2045 for (
unsigned int i=0;i<nargs;++i) {
2054 std::string
name(fName);
2056 if (fArgumentNodes.empty())
return name;
2061 name = fArgumentNodes.front()->ToString();
2071 auto stlContType = AreAncestorsSTLContOrArray();
2073 name = fArgumentNodes.front()->ToString();
2080 for (
auto& node : fArgumentNodes) {
2081 name += node->ToString() +
",";
2082 fHasChanged |= node->HasChanged();
2085 name +=
name.back() ==
'>' ?
" >" :
">";
2090 const std::vector<std::unique_ptr<NameCleanerForIO>>*
GetChildNodes()
const {
return &fArgumentNodes;}
2118 std::string& typeNameBuf,
2119 std::array<int, 5>& maxIndices,
2129 for (ndim = 1;ndim <=5 ; ndim++) {
2130 maxIndices[ndim-1] = std::atoi(childNodes->back()->GetName().c_str());
2131 auto& frontNode = childNodes->front();
2132 typeNameBuf = frontNode->GetName();
2134 typeNameBuf = frontNode->ToString();
2137 childNodes = frontNode->GetChildNodes();
2150 const char* mangled_name = ti.name();
2156struct FunctionSplitInfo {
2158 std::string fReturnType;
2161 std::string fScopeName;
2164 std::string fFunctionName;
2168 std::vector<std::string> fFunctionTemplateArguments;
2171 std::vector<std::string> fFunctionParameters;
2178 std::size_t FindNonNestedNeedles(std::string_view haystack, string_view needles)
2180 std::stack<char> expected;
2181 for (std::size_t pos = 0, end = haystack.length(); pos < end; ++pos) {
2182 char c = haystack[pos];
2183 if (expected.empty()) {
2184 if (needles.find(
c) != std::string_view::npos)
2187 if (
c == expected.top()) {
2193 case '<': expected.emplace(
'>');
break;
2194 case '(': expected.emplace(
')');
break;
2195 case '[': expected.emplace(
']');
break;
2198 return std::string_view::npos;
2202 std::size_t FindNonNestedDoubleColons(std::string_view haystack)
2204 std::size_t lenHaystack = haystack.length();
2205 std::size_t prevAfterColumn = 0;
2207 std::size_t posColumn = FindNonNestedNeedles(haystack.substr(prevAfterColumn),
":");
2208 if (posColumn == std::string_view::npos)
2209 return std::string_view::npos;
2210 prevAfterColumn += posColumn;
2212 if (prevAfterColumn + 1 >= lenHaystack)
2213 return std::string_view::npos;
2216 if (haystack[prevAfterColumn] ==
':')
2217 return prevAfterColumn - 1;
2221 return std::string_view::npos;
2224 std::string_view StripSurroundingSpace(std::string_view str)
2226 while (!str.empty() && std::isspace(str[0]))
2227 str.remove_prefix(1);
2228 while (!str.empty() && std::isspace(str.back()))
2229 str.remove_suffix(1);
2233 std::string
ToString(std::string_view sv)
2237 return std::string(sv.data(), sv.length());
2250 std::size_t posArgs = FindNonNestedNeedles(decl,
"(");
2251 std::string_view declNoArgs = decl.substr(0, posArgs);
2253 std::size_t prevAfterWhiteSpace = 0;
2254 static const char whitespace[] =
" \t\n";
2255 while (declNoArgs.length() > prevAfterWhiteSpace) {
2256 std::size_t posWS = FindNonNestedNeedles(declNoArgs.substr(prevAfterWhiteSpace), whitespace);
2257 if (posWS == std::string_view::npos)
2259 prevAfterWhiteSpace += posWS + 1;
2260 while (declNoArgs.length() > prevAfterWhiteSpace
2261 && strchr(whitespace, declNoArgs[prevAfterWhiteSpace]))
2262 ++prevAfterWhiteSpace;
2266 std::size_t endReturn = prevAfterWhiteSpace;
2267 while (declNoArgs.length() > endReturn
2268 && strchr(
"&* \t \n", declNoArgs[endReturn]))
2271 result.fReturnType = ToString(StripSurroundingSpace(declNoArgs.substr(0, endReturn)));
2274 std::string_view scopeFunctionTmplt = declNoArgs.substr(endReturn);
2275 std::size_t prevAtScope = FindNonNestedDoubleColons(scopeFunctionTmplt);
2276 while (prevAtScope != std::string_view::npos
2277 && scopeFunctionTmplt.length() > prevAtScope + 2) {
2278 std::size_t posScope = FindNonNestedDoubleColons(scopeFunctionTmplt.substr(prevAtScope + 2));
2279 if (posScope == std::string_view::npos)
2281 prevAtScope += posScope + 2;
2284 std::size_t afterScope = prevAtScope + 2;
2285 if (prevAtScope == std::string_view::npos) {
2290 result.fScopeName = ToString(StripSurroundingSpace(scopeFunctionTmplt.substr(0, prevAtScope)));
2291 std::string_view funcNameTmplArgs = scopeFunctionTmplt.substr(afterScope);
2293 result.fFunctionTemplateArguments.clear();
2294 std::size_t posTmpltOpen = FindNonNestedNeedles(funcNameTmplArgs,
"<");
2295 if (posTmpltOpen != std::string_view::npos) {
2296 result.fFunctionName = ToString(StripSurroundingSpace(funcNameTmplArgs.substr(0, posTmpltOpen)));
2299 std::string_view tmpltArgs = funcNameTmplArgs.substr(posTmpltOpen + 1);
2300 std::size_t posTmpltClose = FindNonNestedNeedles(tmpltArgs,
">");
2301 if (posTmpltClose != std::string_view::npos) {
2302 tmpltArgs = tmpltArgs.substr(0, posTmpltClose);
2303 std::size_t prevAfterArg = 0;
2304 while (tmpltArgs.length() > prevAfterArg) {
2305 std::size_t posComma = FindNonNestedNeedles(tmpltArgs.substr(prevAfterArg),
",");
2306 if (posComma == std::string_view::npos) {
2309 result.fFunctionTemplateArguments.emplace_back(ToString(StripSurroundingSpace(tmpltArgs.substr(prevAfterArg, posComma))));
2310 prevAfterArg += posComma + 1;
2313 result.fFunctionTemplateArguments.emplace_back(ToString(StripSurroundingSpace(tmpltArgs.substr(prevAfterArg))));
2316 result.fFunctionName = ToString(StripSurroundingSpace(funcNameTmplArgs));
2319 result.fFunctionParameters.clear();
2320 if (posArgs != std::string_view::npos) {
2322 std::string_view params = decl.substr(posArgs + 1);
2323 std::size_t posEndArgs = FindNonNestedNeedles(params,
")");
2324 if (posEndArgs != std::string_view::npos) {
2325 params = params.substr(0, posEndArgs);
2326 std::size_t prevAfterArg = 0;
2327 while (params.length() > prevAfterArg) {
2328 std::size_t posComma = FindNonNestedNeedles(params.substr(prevAfterArg),
",");
2329 if (posComma == std::string_view::npos) {
2330 result.fFunctionParameters.emplace_back(ToString(StripSurroundingSpace(params.substr(prevAfterArg))));
2333 result.fFunctionParameters.emplace_back(ToString(StripSurroundingSpace(params.substr(prevAfterArg, posComma))));
2334 prevAfterArg += posComma + 1;
static void R__FindTrailing(std::string &full, std::string &stars)
static void ResolveTypedefImpl(const char *tname, unsigned int len, unsigned int &cursor, bool &modified, std::string &result)
static size_t findNameEnd(const std::string_view full)
static bool IsDefElement(const char *elementName, const char *defaultElementName, const char *classname)
return whether or not 'elementName' is the STL default Element for type 'classname'
static void ResolveTypedefProcessType(const char *tname, unsigned int, unsigned int cursor, bool constprefix, unsigned int start_of_type, unsigned int end_of_type, unsigned int mod_start_of_type, bool &modified, std::string &result)
static void RemoveStd(std::string &name, size_t pos=0)
Remove std:: and any potential inline namespace (well compiler detail namespace.
static size_t StdLen(const std::string_view name)
Return the length, if any, taken by std:: and any potential inline namespace (well compiler detail na...
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t cursor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
An helper class to dismount the name and remount it changed whenever necessary.
NameCleanerForIO(const std::string &clName="", TClassEdit::EModType mode=TClassEdit::kNone, NameCleanerForIO *mother=nullptr)
NameCleanerForIO * fMother
const std::string & GetName()
const std::vector< std::unique_ptr< NameCleanerForIO > > * GetChildNodes() const
bool AreAncestorsSTLContOrArray()
A spin mutex-as-code-guard class.
virtual bool GetPartiallyDesugaredNameWithScopeHandling(const std::string &, std::string &, bool=true)=0
virtual ~TInterpreterLookupHelper()
virtual bool IsAlreadyPartiallyDesugaredName(const std::string &, const std::string &)=0
virtual bool IsDeclaredScope(const std::string &, bool &)=0
virtual void ShuttingDownSignal()=0
virtual void GetPartiallyDesugaredName(std::string &)=0
virtual bool ExistingTypeCheck(const std::string &, std::string &)=0
std::string ToString(const T &val)
Utility function for conversion to strings.
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
bool IsDefComp(const char *comp, const char *classname)
return whether or not 'compare' is the STL default comparator for type 'classname'
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
bool IsStdArray(std::string_view name)
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
bool IsDefHash(const char *hashname, const char *classname)
return whether or not 'hashname' is the STL default hash for type 'classname'
bool IsStdPair(std::string_view name)
bool IsInterpreterDetail(const char *type)
Return true if the type is one the interpreter details which are only forward declared (ClassInfo_t e...
std::string InsertStd(const char *tname)
bool SplitFunction(std::string_view decl, FunctionSplitInfo &result)
Split a function declaration into its different parts.
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
bool IsDefPred(const char *predname, const char *classname)
return whether or not 'predname' is the STL default predicate for type 'classname'
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
const char * GetUnqualifiedName(const char *name)
Return the start of the unqualified name include in 'original'.
bool IsVectorBool(const char *name)
void Init(TClassEdit::TInterpreterLookupHelper *helper)
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 CleanType(const char *typeDesc, int mode=0, const char **tail=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
char * DemangleName(const char *mangled_name, int &errorCode)
bool IsArtificial(std::string_view name)
bool GetStdArrayProperties(const char *typeName, std::string &typeNameBuf, std::array< int, 5 > &maxIndices, int &ndim)
std::string GetNameForIO(const std::string &templateInstanceName, TClassEdit::EModType mode=TClassEdit::kNone, bool *hasChanged=nullptr)
int STLArgs(int kind)
Return number of arguments for STL container before allocator.
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.
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
bool IsDefAlloc(const char *alloc, const char *classname)
return whether or not 'allocname' is the STL default allocator for type 'classname'
bool IsUniquePtr(std::string_view name)
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>
ROOT::ESTLType UnderlyingIsSTLCont(std::string_view type)
Return the type of STL collection, if any, that is the underlying type of the given type.
EComplexType GetComplexType(const char *)
Result of splitting a function declaration into fReturnType fScopeName::fFunctionName<fFunctionTempla...
bool IsTemplate()
Check if the type is a template.
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator,...
TSplitType(const char *type2split, EModType mode=TClassEdit::kNone)
default constructor
std::vector< std::string > fElements
ROOT::ESTLType IsInSTL() const
type : type name: vector<list<classA,allocator>,allocator>[::iterator] result: 0 : not stl container ...
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.