76 bool angleBraceLevel =
false;
79 bool tagIsComment =
false;
81 bool tagIsXMLDecl =
false;
83 bool isInlineComment = false ;
94 for (;i<3 &&
file.good();++i){
97 if (pattern ==
"lt;"){
100 else if (pattern ==
"gt;"){
104 for (;i!=0 &&
file.good();--i){
118 case '\n': ++lineCount;
120 case '"': quotes = !quotes;
123 if (!quotes) angleBraceLevel = !angleBraceLevel;
124 if (!angleBraceLevel && !comment)
return false;
127 if (!quotes && !comment) angleBraceLevel = !angleBraceLevel;
128 if (!angleBraceLevel && !comment) br =
true;
129 if (!angleBraceLevel && comment && charMinus2==
'-' && charMinus1==
'-') br =
true;
130 if (charMinus2==
'-' && charMinus1==
'-'){
131 if (comment) { tagIsComment=
true; br=
true; }
132 else {
return false; }
134 if (charMinus1==
'?'){
135 if (xmlDecl) {tagIsXMLDecl=
true;br=
true;}
140 if (charMinus3==
'<' && charMinus2==
'!' && charMinus1==
'-') comment = !comment;
143 if (charMinus1==
'<') xmlDecl=!xmlDecl;
146 if (charMinus1==
'/' && !angleBraceLevel && !comment){
147 isInlineComment=
true;
155 if (isInlineComment){
156 out.erase(out.size()-1,1);
157 while (
file.good() &&
c!=
'\n'){
162 charMinus3=charMinus2;
163 charMinus2=charMinus1;
166 if (comment && !(charMinus3==
'-' && charMinus2==
'-' && charMinus1==
'>')){
177 int startpos = out.find_first_not_of(
" \t\n");
178 int endpos = out.find_last_not_of(
" \t\n");
181 if (((
int) std::string::npos == startpos ) || ((
int) std::string::npos == endpos))
186 out = out.substr( startpos, endpos-startpos+1 );
191 if (tagIsComment || tagIsXMLDecl){
217 if (tag.at(0) !=
'<'){
223 if (isspace(tag.at(1))){
224 ROOT::TMetaUtils::Error(
nullptr,
"Malformed tag %s (there should be no white-spaces between < and name-of-tag)!\n", tag.c_str());
230 for (std::string::size_type i = tag.length()-2;
true ; --i) {
237 if (
c ==
'/' && countWSp>0) {
238 ROOT::TMetaUtils::Error(
nullptr,
"Malformed tag %s (there should be no white-spaces between / and >)!\n", tag.c_str());
251 int pos1 = tag.find(
">");
253 for (std::string::size_type i = pos1+1,
e = tag.length(); i <
e; ++i) {
277 std::string tagEnd = tag.substr(tag.length()-2, 2);
278 return (tagEnd ==
"/>");
287 std::string tagBegin = tag.substr(0, 2);
288 return (tagBegin ==
"</");
298 for (std::string::size_type i = 0,
e = tag.length(); i <
e; ++i) {
300 if (isspace(
c))
break;
301 if ((
c !=
'<') && (
c !=
'>'))
305 std::map<std::string, ETagNames>::iterator it;
330 std::string::size_type cutend = tag.length() - 1 -
name.length();
331 if (standalone) --cutend;
332 std::string attrstr = tag.substr(1 +
name.length(), cutend);
334 if (attrstr.length() > 4) {
336 int pos = attrstr.find_last_not_of(
" \t\n");
337 attrstr = attrstr.substr(1, pos+1);
346 std::string attrtemp;
347 bool namefound =
false;
348 bool equalfound =
false;
351 bool inString =
false;
352 std::string attr_name;
353 std::string attr_value;
354 char lastsymbol =
'\0';
356 for (std::string::size_type i = 0,
e = attrstr.length()-1; i <
e; ++i) {
373 else if (isspace(
c) && !inString)
continue;
377 if (namefound && equalfound){
383 if (attr_name.length() == 0) {
403 if (attr_name==
"pattern" && attr_value.find(
"*") == std::string::npos){
404 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());
407 out.emplace_back(attr_name, attr_value);
422 else if (lastsymbol ==
'=') {
428 else if ((newattr || namefound) && !value){
439 if (namefound && (!equalfound || !value)) {
456 std::ifstream
file(fileName);
461 bool exclusion =
false;
462 bool selection =
false;
465 bool exclEnd =
false;
467 bool inIoread =
false;
468 bool inClass =
false;
469 bool inMethod =
false;
470 bool inField =
false;
474 std::unique_ptr<ClassSelectionRule> csr;
475 std::unique_ptr<FunctionSelectionRule> fsr;
476 std::unique_ptr<VariableSelectionRule> vsr;
477 std::unique_ptr<EnumSelectionRule> esr;
484 const char* tagStrCharp = tagStr.c_str();
486 std::ostringstream buf;
488 std::string lineNumStr = buf.str();
489 const char* lineNumCharp = lineNumStr.c_str();
496 if (!tagStr.empty()){
497 std::vector<Attributes> attrs;
527 csr->SetRequestStreamerInfo(
true);
559 std::streampos initialPos(
file.tellg());
560 const unsigned int lineCharsSize=1000;
561 char lineChars[lineCharsSize];
562 file.getline(lineChars,lineCharsSize);
563 std::string lineStr(lineChars);
565 while (lineStr ==
"" ||
566 std::count(lineStr.begin(),lineStr.end(),
' ') == (
int)lineStr.size()){
567 file.getline(lineChars,lineCharsSize);
571 size_t dataBeginPos = lineStr.find(
"<![CDATA[");
572 if (dataBeginPos==std::string::npos){
573 file.seekg(initialPos);
578 lineStr = lineStr.substr(dataBeginPos+9);
582 std::string codeAttrVal;
587 size_t dataEndPos = lineStr.find(
"]]>");
588 if (dataEndPos!=std::string::npos) {
590 codeAttrVal+=lineStr.substr(0,dataEndPos);
593 codeAttrVal+=lineStr;
595 file.getline(lineChars,lineCharsSize);
598 attrs.emplace_back(
"code", codeAttrVal);
686 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
694 bsrChild = vsr.get();
705 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);
712 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
720 bsrChild = fsr.get();
731 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);
738 ROOT::TMetaUtils::Error(
nullptr,
"At line %s. Tag %s not inside a <class> element\n", lineNumCharp,tagStrCharp);
783 attrs.emplace_back(
"fromTypedef",
"true");
824 std::string iAttrName;
825 std::string iAttrValue;
831 std::map<std::string,std::string> pragmaArgs;
832 for (
int i = 0,
n = attrs.size(); i <
n; ++i) {
833 pragmaArgs[attrs[i].fName]=attrs[i].fValue;
836 std::stringstream pragmaLineStream;
837 const std::string attrs[11] ={
"sourceClass",
849 for (
unsigned int i=0;i<11;++i) {
850 const std::string& attr = attrs[i];
851 if ( pragmaArgs.count(attr) == 1){
852 value = pragmaArgs[attr];
853 if (attr ==
"code") value=
"{"+value+
"}";
854 pragmaLineStream <<
" " << attr <<
"=\""<< value <<
"\"";
861 std::string error_string;
866 if (!error_string.empty())
874 if (!tagStr.empty() && tagKind !=
kVersion) {
896 else if (tagKind ==
kClass) {
926 std::string iAttrName;
927 std::string iAttrValue;
928 for (
int i = 0,
n = attrs.size(); i <
n; ++i) {
929 iAttrName=attrs[i].fName;
930 iAttrValue=attrs[i].fValue;
933 if (tagKind ==
kClass && csr &&
"noStreamer" == iAttrName){
934 if (iAttrValue ==
"true") {
935 csr->SetRequestNoStreamer(
true);
936 }
else if (iAttrValue !=
"false") {
938 "XML at line %s: class attribute 'noStreamer' must be 'true' or 'false' (it was %s)\n",
939 lineNumCharp, iAttrValue.c_str());
944 if (tagKind ==
kClass && csr &&
"noInputOperator" == iAttrName){
945 if (iAttrValue ==
"true") {
946 csr->SetRequestNoInputOperator(
true);
947 }
else if (iAttrValue !=
"false") {
949 "XML at line %s: class attribute 'noInputOperator' must be 'true' or 'false' (it was %s)\n",
950 lineNumCharp, iAttrValue.c_str());
957 "ClassVersion" == iAttrName){
958 csr->SetRequestedVersionNumber(atoi(iAttrValue.c_str()));
969 std::string preExistingValue;
971 if (preExistingValue!=iAttrValue){
973 "Line %s: assigning new value %s to attribue %s (it was %s)\n",
974 lineNumCharp,iAttrValue.c_str(),iAttrName.c_str(),preExistingValue.c_str());
980 if ((iAttrName ==
"file_name" || iAttrName ==
"file_pattern") && tagKind ==
kClass){
987 std::string preExistingValue;
989 if (preExistingValue!=iAttrValue){
991 "Line %s: assigning new value %s to attribue %s (it was %s)\n",
992 lineNumCharp,iAttrValue.c_str(),iAttrName.c_str(),preExistingValue.c_str());
1023 csr->AddFieldSelectionRule(*vsr);
1026 csr->AddMethodSelectionRule(*fsr);
1035 if (sel && !selEnd) {
1040 if (excl && !exclEnd ) {
VariableSelectionRule EnumSelectionRule
VariableSelectionRule FunctionSelectionRule
void SetAttributeValue(const std::string &attributeName, const std::string &attributeValue)
bool GetAttributeValue(const std::string &attributeName, std::string &returnValue) const
void SetSelected(ESelect sel)
bool HasAttributeWithName(const std::string &attributeName) const
The class representing the collection of selection rules.
void AddVariableSelectionRule(const VariableSelectionRule &varSel)
void AddClassSelectionRule(const ClassSelectionRule &classSel)
void AddEnumSelectionRule(const EnumSelectionRule &enumSel)
void ClearSelectionRules()
void AddFunctionSelectionRule(const FunctionSelectionRule &funcSel)
void SetHasFileNameRule(bool file_rule)
cling::Interpreter & fInterp
static bool IsClosingTag(const std::string &tag)
static void PopulateMap()
static std::map< std::string, ETagNames > fgMapTagNames
static bool CheckIsTagOK(const std::string &tag)
bool Parse(const std::string &fileName, SelectionRules &out)
static bool GetNextTag(std::ifstream &file, std::string &out, int &lineCount)
static bool GetAttributes(const std::string &tag, std::vector< Attributes > &out, const char *lineNum)
static ETagNames GetNameOfTag(const std::string &tag, std::string &name)
static bool IsStandaloneTag(const std::string &tag)
void ProcessReadPragma(const char *args, std::string &error_string)
I am being called when a read pragma is encountered.
void ProcessReadRawPragma(const char *args, std::string &error_string)
I am being called then a readraw pragma is encountered.