77 bool angleBraceLevel =
false;
80 bool tagIsComment =
false;
82 bool tagIsXMLDecl =
false;
84 bool isInlineComment = false ;
95 for (;i<3 && file.good();++i){
98 if (pattern ==
"lt;"){
101 else if (pattern ==
"gt;"){
105 for (;i!=0 && file.good();--i){
119 case '\n': ++lineCount;
121 case '"': quotes = !quotes;
124 if (!quotes) angleBraceLevel = !angleBraceLevel;
125 if (!angleBraceLevel && !comment)
return false;
128 if (!quotes && !comment) angleBraceLevel = !angleBraceLevel;
129 if (!angleBraceLevel && !comment) br =
true;
130 if (!angleBraceLevel && comment && charMinus2==
'-' && charMinus1==
'-') br =
true;
131 if (charMinus2==
'-' && charMinus1==
'-'){
132 if (comment) { tagIsComment=
true; br=
true; }
133 else {
return false; }
135 if (charMinus1==
'?'){
136 if (xmlDecl) {tagIsXMLDecl=
true;br=
true;}
141 if (charMinus3==
'<' && charMinus2==
'!' && charMinus1==
'-') comment = !comment;
144 if (charMinus1==
'<') xmlDecl=!xmlDecl;
147 if (charMinus1==
'/' && !angleBraceLevel && !comment){
148 isInlineComment=
true;
156 if (isInlineComment){
157 out.erase(out.size()-1,1);
158 while (file.good() &&
c!=
'\n'){
163 charMinus3=charMinus2;
164 charMinus2=charMinus1;
167 if (comment && !(charMinus3==
'-' && charMinus2==
'-' && charMinus1==
'>')){
178 int startpos = out.find_first_not_of(
" \t\n");
179 int endpos = out.find_last_not_of(
" \t\n");
182 if (((
int) std::string::npos == startpos ) || ((
int) std::string::npos == endpos))
187 out = out.substr( startpos, endpos-startpos+1 );
192 if (tagIsComment || tagIsXMLDecl){
331 std::string::size_type cutend = tag.length() - 1 -
name.length();
332 if (standalone) --cutend;
333 std::string attrstr = tag.substr(1 +
name.length(), cutend);
335 if (attrstr.length() > 4) {
337 int pos = attrstr.find_last_not_of(
" \t\n");
338 attrstr = attrstr.substr(1, pos+1);
347 std::string attrtemp;
348 bool namefound =
false;
349 bool equalfound =
false;
352 bool inString =
false;
353 std::string attr_name;
354 std::string attr_value;
355 char lastsymbol =
'\0';
357 for (std::string::size_type i = 0,
e = attrstr.length()-1; i <
e; ++i) {
374 else if (isspace(
c) && !inString)
continue;
378 if (namefound && equalfound){
384 if (attr_name.length() == 0) {
404 if (attr_name==
"pattern" && attr_value.find(
"*") == std::string::npos){
405 ROOT::TMetaUtils::Warning(
nullptr,
"At line %s. A pattern, \"%s\", without wildcards is being used. This selection rule would not have any effect. Transforming it to a rule based on name.\n", lineNum, attr_value.c_str());
408 out.emplace_back(attr_name, attr_value);
423 else if (lastsymbol ==
'=') {
429 else if ((newattr || namefound) && !value){
440 if (namefound && (!equalfound || !value)) {
457 std::ifstream file(fileName, std::ios::binary);
462 bool exclusion =
false;
463 bool selection =
false;
466 bool exclEnd =
false;
468 bool inIoread =
false;
469 bool inClass =
false;
470 bool inMethod =
false;
471 bool inField =
false;
475 std::unique_ptr<ClassSelectionRule> csr;
476 std::unique_ptr<FunctionSelectionRule> fsr;
477 std::unique_ptr<VariableSelectionRule> vsr;
478 std::unique_ptr<EnumSelectionRule> esr;
483 bool tagOK =
GetNextTag(file, tagStr, lineNum);
485 const char* tagStrCharp = tagStr.c_str();
487 std::ostringstream buf;
489 std::string lineNumStr = buf.str();
490 const char* lineNumCharp = lineNumStr.c_str();
497 if (!tagStr.empty()){
498 std::vector<Attributes> attrs;
528 csr->SetRequestStreamerInfo(
true);
560 std::streampos initialPos(file.tellg());
561 const unsigned int lineCharsSize=1000;
562 char lineChars[lineCharsSize];
563 file.getline(lineChars,lineCharsSize);
564 std::string lineStr(lineChars);
566 while (lineStr ==
"" ||
567 std::count(lineStr.begin(),lineStr.end(),
' ') == (
int)lineStr.size()){
568 file.getline(lineChars,lineCharsSize);
572 size_t dataBeginPos = lineStr.find(
"<![CDATA[");
573 if (dataBeginPos==std::string::npos){
574 file.seekg(initialPos);
579 lineStr = lineStr.substr(dataBeginPos+9);
583 std::string codeAttrVal;
588 size_t dataEndPos = lineStr.find(
"]]>");
589 if (dataEndPos!=std::string::npos) {
591 codeAttrVal+=lineStr.substr(0,dataEndPos);
594 codeAttrVal+=lineStr;
596 file.getline(lineChars,lineCharsSize);
599 attrs.emplace_back(
"code", codeAttrVal);
687 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
695 bsrChild = vsr.get();
706 ROOT::TMetaUtils::Info(
nullptr,
"At line %s. A field is not supposed to have an end-tag (this message will become a warning).\n", lineNumCharp);
713 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
721 bsrChild = fsr.get();
732 ROOT::TMetaUtils::Info(
nullptr,
"At line %s. A method is not supposed to have an end-tag (this message will become a warning).\n", lineNumCharp);
739 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
784 attrs.emplace_back(
"fromTypedef",
"true");
825 std::string iAttrName;
826 std::string iAttrValue;
832 std::map<std::string,std::string> pragmaArgs;
833 for (
int i = 0,
n = attrs.size(); i <
n; ++i) {
834 pragmaArgs[attrs[i].fName]=attrs[i].fValue;
837 std::stringstream pragmaLineStream;
838 const std::string attrs[11] ={
"sourceClass",
850 for (
unsigned int i=0;i<11;++i) {
851 const std::string& attr = attrs[i];
852 if ( pragmaArgs.count(attr) == 1){
853 value = pragmaArgs[attr];
854 if (attr ==
"code") value=
"{"+value+
"}";
855 pragmaLineStream <<
" " << attr <<
"=\""<< value <<
"\"";
862 std::string error_string;
867 if (!error_string.empty())
875 if (!tagStr.empty() && tagKind !=
kVersion) {
897 else if (tagKind ==
kClass) {
927 std::string iAttrName;
928 std::string iAttrValue;
929 for (
int i = 0,
n = attrs.size(); i <
n; ++i) {
930 iAttrName=attrs[i].fName;
931 iAttrValue=attrs[i].fValue;
934 if (tagKind ==
kClass && csr &&
"noStreamer" == iAttrName){
935 if (iAttrValue ==
"true") {
936 csr->SetRequestNoStreamer(
true);
937 }
else if (iAttrValue !=
"false") {
939 "XML at line %s: class attribute 'noStreamer' must be 'true' or 'false' (it was %s)\n",
940 lineNumCharp, iAttrValue.c_str());
945 if (tagKind ==
kClass && csr &&
"rntupleStreamerMode" == iAttrName) {
946 if (iAttrValue ==
"false") {
947 if (csr->RequestedRNTupleSerializationMode() == -1) {
950 "XML at line %s: class attribute 'rntupleStreamerMode' must be either 'true' or 'false', "
952 lineNumCharp, iAttrValue.c_str());
954 csr->SetRequestedRNTupleSerializationMode(1);
956 }
else if (iAttrValue ==
"true") {
957 if (csr->RequestedRNTupleSerializationMode() == 1) {
960 "XML at line %s: class attribute 'rntupleStreamerMode' must be either 'true' or 'false', "
962 lineNumCharp, iAttrValue.c_str());
964 if (!csr->RequestedRNTupleSoARecord().empty()) {
967 "XML at line %s: class attributes rntupleStreamerMode and rntupleSoARecord "
968 "are mutually exclusive\n",
969 lineNumCharp, iAttrValue.c_str());
971 csr->SetRequestedRNTupleSerializationMode(-1);
976 "XML at line %s: class attribute 'rntupleStreamerMode' must be 'true' or 'false' "
978 lineNumCharp, iAttrValue.c_str());
983 if (tagKind ==
kClass && csr &&
"rntupleSoARecord" == iAttrName) {
984 if (csr->RequestedRNTupleSerializationMode() == -1) {
987 "XML at line %s: class attributes rntupleStreamerMode and rntupleSoARecord "
988 "are mutually exclusive\n",
989 lineNumCharp, iAttrValue.c_str());
991 csr->SetRequestedRNTupleSoARecord(iAttrValue);
995 if (tagKind ==
kClass && csr &&
"noInputOperator" == iAttrName){
996 if (iAttrValue ==
"true") {
997 csr->SetRequestNoInputOperator(
true);
998 }
else if (iAttrValue !=
"false") {
1000 "XML at line %s: class attribute 'noInputOperator' must be 'true' or 'false' (it was %s)\n",
1001 lineNumCharp, iAttrValue.c_str());
1008 "ClassVersion" == iAttrName){
1009 csr->SetRequestedVersionNumber(atoi(iAttrValue.c_str()));
1020 std::string preExistingValue;
1022 if (preExistingValue!=iAttrValue){
1024 "Line %s: assigning new value %s to attribue %s (it was %s)\n",
1025 lineNumCharp,iAttrValue.c_str(),iAttrName.c_str(),preExistingValue.c_str());
1031 if ((iAttrName ==
"file_name" || iAttrName ==
"file_pattern") && tagKind ==
kClass){
1036 else if (bsrChild) {
1038 std::string preExistingValue;
1040 if (preExistingValue!=iAttrValue){
1042 "Line %s: assigning new value %s to attribue %s (it was %s)\n",
1043 lineNumCharp,iAttrValue.c_str(),iAttrName.c_str(),preExistingValue.c_str());
1074 csr->AddFieldSelectionRule(*vsr);
1077 csr->AddMethodSelectionRule(*fsr);
1086 if (sel && !selEnd) {
1091 if (excl && !exclEnd ) {