16 static void RemoveEscapeSequences(std::string& rawString)
18 const std::vector<std::pair<std::string, std::string>> subPairs { {
"\\\\",
"\\"},
22 for (
auto const & subPair : subPairs){
24 auto from = subPair.first;
25 auto to = subPair.second;
26 while((start_pos = rawString.find(from, start_pos)) != std::string::npos) {
27 rawString.replace(start_pos, from.length(), to);
28 start_pos += to.length();
36 using namespace Internal;
38 typedef std::list<std::pair<ROOT::Internal::TSchemaType,std::string> >
SourceTypeList_t;
47 static Bool_t ValidateRule(
const std::map<std::string, std::string>& rule, std::string &error_string );
53 if (command.length() == 0)
return std::string::npos;
54 std::string::size_type cursor;
55 unsigned int level = 0;
56 for (cursor = 0 ; cursor < command.length(); ++cursor)
58 switch( command[cursor] ) {
62 case '=':
if (level==0) {
63 std::string::size_type sub_cursor = cursor;
64 while( isspace(command[sub_cursor]) ) {
67 if ( command[sub_cursor] ==
'=' ) {
75 case '<': ++level;
break;
76 case '>':
if (level==0) {
return std::string::npos; }
92 std::string &error_string )
94 std::string::size_type
l=0;
101 if( command[command.size()-1] ==
';' )
102 command = command.substr( 0, command.size()-1 );
111 if ( endsymbol == command.length() || command[endsymbol] ==
' ' || command[endsymbol] ==
'\t' ) {
117 result[
"sourceClass"] = value;
118 result[
"targetClass"] = value;
119 if (endsymbol < command.length()) {
133 if ( endsymbol == command.length() || command[endsymbol] ==
' ' || command[endsymbol] ==
'\t' ) {
135 result[
"source"] = membervalue;
136 result[
"target"] = membervalue;
146 while( !command.empty() ) {
151 std::string::size_type pos = command.find(
'=' );
157 if( pos == std::string::npos ) {
158 error_string =
"Parsing error, no key found!";
173 if( command.size() < 1 ) {
174 error_string =
"Parsing error, wrond or no value specified for key: " + key;
178 Bool_t hasquote = command[0] ==
'"';
184 if( key ==
"code" ) {
185 if( command[1] !=
'{' ) {
186 error_string =
"Parsing error while processing key: code\n";
187 error_string +=
"Expected \"{ at the beginning of the value.";
190 l = command.find(
"}\"" );
191 if( l == std::string::npos ) {
192 error_string =
"Parsing error while processing key: \"" + key +
"\"\n";
193 error_string +=
"Expected }\" at the end of the value.";
196 auto rawCode = command.substr( 2, l-2 );
197 RemoveEscapeSequences(rawCode);
198 result[key] = rawCode;
207 l = command.find(
'"', 1 );
208 if (l == std::string::npos ) {
209 error_string =
"\nParsing error while processing key: \"" + key +
"\"\n";
210 error_string +=
"Expected \" at the end of the value.";
213 result[key] = command.substr( 1, l-1 );
215 l = command.find(
' ', 1);
216 if (l == std::string::npos) l = command.size();
217 result[key] = command.substr( 0, l );
225 if( l == command.size() )
227 command = command.substr( l+1 );
229 std::map<std::string, std::string>::const_iterator it1;
230 it1 = result.find(
"oldtype");
231 if ( it1 != result.end() ) {
232 std::map<std::string, std::string>::const_iterator it2;
233 it2 = result.find(
"source");
234 if ( it2 != result.end() ) {
235 result[
"source"] = it1->second +
" " + it2->second;
238 if ( result.find(
"version") == result.end() && result.find(
"checksum") == result.end() ) {
239 result[
"version"] =
"[1-]";
247 auto const includeKeyName =
"include";
248 auto includeTag = result.find(includeKeyName);
249 if (includeTag != result.end()){
250 auto & includeTagValue = includeTag->second;
251 std::replace_if (includeTagValue.begin(),
252 includeTagValue.end(),
253 [](
char c){
return c ==
';';},
255 result[includeKeyName] = includeTagValue;
264 static Bool_t ValidateRule(
const std::map<std::string, std::string>& rule, std::string &error_string )
270 std::map<std::string, std::string>::const_iterator it1, it2;
271 std::list<std::string> lst;
272 std::list<std::string>::iterator lsIt;
274 it1 = rule.find(
"targetClass" );
275 if( it1 == rule.end() ) {
276 error_string =
"You always have to specify the targetClass ";
277 error_string +=
"when specyfying an IO rule";
282 std::string warning =
"IO rule for class " + className;
288 it1 = rule.find(
"sourceClass" );
289 if( it1 == rule.end())
291 error_string = warning +
" - sourceClass parameter is missing";
299 it1 = rule.find(
"version" );
300 it2 = rule.find(
"checksum" );
301 if( it1 == rule.end() && it2 == rule.end() ) {
302 error_string = warning +
" - you need to specify either version or ";
303 error_string +=
"checksum";
311 if( it2 != rule.end() ) {
312 if( it2->second.size() < 2 || it2->second[0] !=
'[' ||
313 it2->second[it2->second.size()-1] !=
']' ) {
314 error_string = warning +
" - a comma separated list of ints";
315 error_string +=
" enclosed in square brackets expected";
316 error_string +=
" as a value of checksum parameter";
323 error_string += warning +
" - the list of checksums is empty\n";
326 for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
328 error_string = warning +
" - " + *lsIt +
" is not a valid value";
329 error_string +=
" of checksum parameter - an integer expected";
338 std::pair<Int_t, Int_t> ver;
339 if( it1 != rule.end() ) {
340 if( it1->second.size() < 2 || it1->second[0] !=
'[' ||
341 it1->second[it1->second.size()-1] !=
']' ) {
342 error_string = warning +
" - a comma separated list of version specifiers ";
343 error_string +=
"enclosed in square brackets expected";
344 error_string +=
"as a value of version parameter";
351 error_string = warning +
" - the list of versions is empty";
354 for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
356 error_string = warning +
" - " + *lsIt +
" is not a valid value";
357 error_string +=
" of version parameter";
367 if( rule.size() == 3 || (rule.size() == 4 && it1 != rule.end() && it2 != rule.end()) )
373 std::string keys[] = {
"target",
"source"};
374 for(
int i = 0; i < 2; ++i ) {
375 it1 = rule.find( keys[i] );
376 if( it1 == rule.end() ) {
377 error_string = warning +
" - required parameter is missing: ";
378 error_string += keys[i];
387 it1 = rule.find(
"code");
388 if (it1 != rule.end() && it1->second !=
"") {
389 SourceTypeList_t source;
391 SourceTypeList_t::const_iterator it;
392 for( it = source.begin(); it != source.end(); ++it ) {
393 if ( ( it->first.fType ==
"" && it->second !=
"") ) {
394 error_string = warning +
" - type required when listing a rule's source: ";
395 error_string +=
"source=\""+ rule.find(
"source")->second +
"\"";
406 it1 = rule.find(
"embed" );
407 if( it1 != rule.end() ) {
409 if( emValue !=
"true" && emValue !=
"false" ) {
410 error_string = warning +
" - true or false expected as a value ";
411 error_string +=
"of embed parameter";
420 it1 = rule.find(
"include" );
421 if( it1 != rule.end() ) {
422 if( it1->second.empty() ) {
423 error_string = warning +
" - the include list is empty";
436 std::string& error_string)
438 std::list<std::string> mem;
439 std::list<std::string>::iterator it;
448 for( it = mem.begin(); it != mem.end(); ++it ) {
449 if( members.find( *it ) == members.end() ) {
450 error_string +=
"IO rule for class " + rule[
"targetClass"]
451 +
" data member: " + *it +
" was specified as a " 452 "target in the rule but doesn't seem to appear in " 464 const SourceTypeList_t& source,
466 std::string& className, std::string& mappedName,
469 if (!source.empty()) {
471 SourceTypeList_t::const_iterator it;
478 Bool_t generateOnFile =
false;
479 output <<
"#if 0" << std::endl;
480 for( it = source.begin(); it != source.end(); ++it ) {
482 output <<
"static Int_t id_" << it->second <<
" = oldObj->GetId(";
483 output <<
"\"" << it->second <<
"\");" << std::endl;
485 if( it->first.fType !=
"" )
486 generateOnFile =
true;
488 output <<
"#endif" << std::endl;
494 if( generateOnFile ) {
495 std::string onfileStructName = mappedName +
"_Onfile";
497 output <<
"struct " << onfileStructName <<
" {\n";
504 for( it = source.begin(); it != source.end(); ++it ) {
505 if( it->first.fType.size() ) {
506 if ( it->first.fDimensions.size() ) {
507 output <<
" typedef " << it->first.fType;
508 output <<
" onfile_" << it->second <<
"_t" << it->first.fDimensions <<
";\n";
510 output <<
"onfile_" << it->second <<
"_t &" << it->second <<
";\n";
514 output << it->first.fType <<
" &" << it->second <<
";\n";
523 output <<
" " << onfileStructName <<
"(";
524 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
525 if( it->first.fType.size() == 0)
533 if (it->first.fDimensions.size() == 0) {
534 output << it->first.fType <<
" &onfile_" << it->second;
536 output <<
" onfile_" << it->second <<
"_t" <<
" &onfile_" << it->second;
545 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
546 if( it->first.fType ==
"" )
554 output << it->second <<
"(onfile_" << it->second <<
")";
557 output <<
" " <<
"};\n";
563 for( it = source.begin(); it != source.end(); ++it ) {
565 output <<
"static Long_t offset_Onfile_" << mappedName;
566 output <<
"_" << it->second <<
" = oldObj->GetClass()->GetDataMemberOffset(\"";
567 output << it->second <<
"\");\n";
569 output <<
" " <<
"char *onfile_add = (char*)oldObj->GetObject();\n";
570 output <<
" " << mappedName <<
"_Onfile onfile(\n";
572 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
573 if( it->first.fType ==
"" )
584 if (it->first.fDimensions.size() == 0) {
585 output << it->first.fType;
587 output << mappedName <<
"_Onfile::onfile_" << it->second <<
"_t";
589 output <<
"*)(onfile_add+offset_Onfile_";
590 output << mappedName <<
"_" << it->second <<
")";
600 if( !target.empty() ) {
601 output <<
" static TClassRef cls(\"";
602 output << className <<
"\");" << std::endl;
604 std::list<std::string>::const_iterator it;
605 for( it = target.begin(); it != target.end(); ++it ) {
607 output <<
" static Long_t offset_" << *it <<
" = ";
608 output <<
"cls->GetDataMemberOffset(\"" << *it <<
"\");";
611 output <<
" typedef " << memData.
fType <<
" " << *it <<
"_t" << memData.
fDimensions <<
";" << std::endl;
612 output <<
" " << *it <<
"_t& " << *it <<
" = ";
613 output <<
"*(" << *it <<
"_t *)(target+offset_" << *it;
614 output <<
");" << std::endl;
616 output <<
" " << memData.
fType <<
"& " << *it <<
" = ";
617 output <<
"*(" << memData.
fType <<
"*)(target+offset_" << *it;
618 output <<
");" << std::endl;
632 std::string className = rule[
"targetClass"];
638 std::ostringstream func;
639 func <<
"read_" << mappedName <<
"_" << index;
640 rule[
"funcname"] = func.str();
646 output <<
" static void " << func.str();
647 output <<
"( char* target, TVirtualObject *oldObj )" << std::endl;
648 output <<
" {" << std::endl;
649 output <<
" //--- Automatically generated variables ---" << std::endl;
655 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
656 std::list<std::string> target;
661 output <<
" " << className <<
"* newObj = (" << className;
662 output <<
"*)target;" << std::endl;
663 output <<
" // Supress warning message.\n";
664 output <<
" " <<
"if (oldObj) {}\n\n";
665 output <<
" " <<
"if (newObj) {}\n\n";
671 output <<
" //--- User's code ---" << std::endl;
672 output <<
" " << rule[
"code"] << std::endl;
673 output <<
" }" << std::endl;
685 std::string className = rule[
"targetClass"];
691 std::ostringstream func;
692 func <<
"readraw_" << mappedName <<
"_" << index;
693 rule[
"funcname"] = func.str();
699 output <<
" static void " << func.str();
700 output <<
"( char* target, TBuffer &b )" << std::endl;
701 output <<
" {" << std::endl;
702 output <<
"#if 0" << std::endl;
703 output <<
" //--- Automatically generated variables ---" << std::endl;
709 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
710 std::list<std::string> target;
714 output <<
" " << className <<
"* newObj = (" << className;
715 output <<
"*)target;" << std::endl << std::endl;
721 output <<
" //--- User's code ---" << std::endl;
722 output << rule[
"code"] << std::endl;
723 output <<
"#endif" << std::endl;
724 output <<
" }" << std::endl;
730 static void StrReplace( std::string& proc,
const std::string& pat,
731 const std::string& tr )
733 std::string::size_type it = 0;
734 std::string::size_type
s = pat.size();
735 std::string::size_type tr_len= tr.size();
740 it = proc.find( pat, it );
741 if( it == std::string::npos )
744 proc.replace( it, s, tr );
753 const std::string& listName, std::ostream&
output )
755 std::list<SchemaRuleMap_t>::iterator it;
762 for( it = rules.begin(); it != rules.end(); ++it ) {
763 output <<
" rule = &" << listName <<
"[" << i++;
764 output <<
"];" << std::endl;
770 output <<
" rule->fSourceClass = \"" << (*it)[
"sourceClass"];
771 output <<
"\";" << std::endl;
773 if( it->find(
"target" ) != it->end() ) {
774 output <<
" rule->fTarget = \"" << (*it)[
"target"];
775 output <<
"\";" << std::endl;
778 if( it->find(
"source" ) != it->end() ) {
779 output <<
" rule->fSource = \"" << (*it)[
"source"];
780 output <<
"\";" << std::endl;
787 if( it->find(
"funcname" ) != it->end() ) {
788 std::string code = (*it)[
"code"];
792 output <<
" rule->fFunctionPtr = (void *)TFunc2void( ";
793 output << (*it)[
"funcname"] <<
");" << std::endl;
794 output <<
" rule->fCode = \"" << code;
795 output <<
"\";" << std::endl;
798 if( it->find(
"version" ) != it->end() ) {
799 output <<
" rule->fVersion = \"" << (*it)[
"version"];
800 output <<
"\";" << std::endl;
803 if( it->find(
"checksum" ) != it->end() ) {
804 output <<
" rule->fChecksum = \"" << (*it)[
"checksum"];
805 output <<
"\";" << std::endl;
808 if( it->find(
"embed" ) != it->end() ) {
809 output <<
" rule->fEmbed = " << (*it)[
"embed"];
810 output <<
";" << std::endl;
813 if( it->find(
"include" ) != it->end() ) {
814 output <<
" rule->fInclude = \"" << (*it)[
"include"];
815 output <<
"\";" << std::endl;
818 if( it->find(
"attributes" ) != it->end() ) {
819 output <<
" rule->fAttributes = \"" << (*it)[
"attributes"];
820 output <<
"\";" << std::endl;
830 std::list<std::string> tmp;
831 std::list<SchemaRuleMap_t>::iterator rule;
832 SchemaRuleMap_t::iterator attr;
833 SchemaRuleClassMap_t::iterator it;
839 for( it = gReadRules.begin(); it != gReadRules.end(); ++it ) {
840 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
841 attr = rule->find(
"include" );
842 if( attr == rule->end() )
continue;
844 result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
852 for( it = gReadRawRules.begin(); it != gReadRawRules.end(); ++it ) {
853 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
854 attr = rule->find(
"include" );
855 if( attr == rule->end() )
continue;
857 result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
878 std::map<std::string, std::string> rule;
879 if( !
ParseRule( args, rule, error_string ) ) {
880 error_string +=
"\nThe following rule has been omitted:\n read ";
881 error_string += args;
882 error_string +=
"\n";
890 SchemaRuleClassMap_t::iterator it;
891 std::string targetClass = rule[
"targetClass"];
892 it = gReadRules.find( targetClass );
893 if( it == gReadRules.end() ) {
894 std::list<SchemaRuleMap_t> lst;
895 lst.push_back( rule );
896 gReadRules[targetClass] = lst;
899 it->second.push_back( rule );
911 std::map<std::string, std::string> rule;
912 if( !
ParseRule( args, rule, error_string ) ) {
913 error_string +=
"\nThe following rule has been omitted:\n readraw ";
914 error_string += args;
915 error_string +=
"\n";
923 SchemaRuleClassMap_t::iterator it;
924 std::string targetClass = rule[
"targetClass"];
925 it = gReadRawRules.find( targetClass );
926 if( it == gReadRawRules.end() ) {
927 std::list<SchemaRuleMap_t> lst;
928 lst.push_back( rule );
929 gReadRawRules[targetClass] = lst;
932 it->second.push_back( rule );
void WriteReadRawRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for ReadRaw rule, the function name is being written to rule["funcname"...
std::map< std::string, ROOT::Internal::TSchemaType > MembersTypeMap_t
Namespace for new ROOT classes and functions.
void WriteSchemaList(std::list< SchemaRuleMap_t > &rules, const std::string &listName, std::ostream &output)
Write schema rules.
std::list< std::pair< ROOT::Internal::TSchemaType, std::string > > SourceTypeList_t
void ProcessReadPragma(const char *args, std::string &error_string)
I am being called when a read pragma is encountered.
static bool IsANumber(const std::string &source)
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members, std::string &error_string)
Check if given rule contains references to valid data members.
static void SplitDeclaration(const std::string &source, std::list< std::pair< ROOT::Internal::TSchemaType, std::string > > &result)
static std::string::size_type FindEndSymbol(std::string &command)
void GetRuleIncludes(std::list< std::string > &result)
Get the list of includes specified in the shema rules.
R__EXTERN SchemaRuleClassMap_t gReadRules
static void SplitList(const std::string &source, std::list< std::string > &result, char delimiter=',')
static void WriteAutoVariables(const std::list< std::string > &target, const SourceTypeList_t &source, MembersTypeMap_t &members, std::string &className, std::string &mappedName, std::ostream &output)
Write down the sources.
std::map< std::string, std::list< SchemaRuleMap_t > > SchemaRuleClassMap_t
void WriteReadRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for Read rule, the function name is being written to rule["funcname"]...
void ProcessReadRawPragma(const char *args, std::string &error_string)
I am being called then a readraw pragma is encountered.
R__EXTERN SchemaRuleClassMap_t gReadRawRules
static constexpr double s
static void StrReplace(std::string &proc, const std::string &pat, const std::string &tr)
Replace all accurances of given string with other string.
static Bool_t ValidateRule(const std::map< std::string, std::string > &rule, std::string &error_string)
Validate if the user specified rules are correct.
bool ParseRule(std::string rule, ROOT::Internal::MembersMap_t &result, std::string &error_string)
Parse the schema rule as specified in the LinkDef file.
std::map< std::string, std::string > SchemaRuleMap_t
static std::string Trim(const std::string &source)
std::map< std::string, std::string > MembersMap_t
static bool ProcessVersion(const std::string &source, std::pair< Int_t, Int_t > &result)