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; }
91 std::map<std::string, std::string> &
result,
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 std::string warn = warning +
" - the list of checksums is empty\n";
327 for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
329 error_string = warning +
" - " + *lsIt +
" is not a valid value";
330 error_string +=
" of checksum parameter - an integer expected";
339 std::pair<Int_t, Int_t> ver;
340 if( it1 != rule.end() ) {
341 if( it1->second.size() < 2 || it1->second[0] !=
'[' ||
342 it1->second[it1->second.size()-1] !=
']' ) {
343 error_string = warning +
" - a comma separated list of version specifiers ";
344 error_string +=
"enclosed in square brackets expected";
345 error_string +=
"as a value of version parameter";
352 error_string = warning +
" - the list of versions is empty";
355 for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
357 error_string = warning +
" - " + *lsIt +
" is not a valid value";
358 error_string +=
" of version parameter";
368 if( rule.size() == 3 || (rule.size() == 4 && it1 != rule.end() && it2 != rule.end()) )
374 std::string keys[] = {
"target",
"source"};
375 for(
int i = 0; i < 2; ++i ) {
376 it1 = rule.find( keys[i] );
377 if( it1 == rule.end() ) {
378 error_string = warning +
" - required parameter is missing: ";
379 error_string += keys[i];
388 it1 = rule.find(
"code");
389 if (it1 != rule.end() && it1->second !=
"") {
390 SourceTypeList_t source;
392 SourceTypeList_t::const_iterator it;
393 for( it = source.begin(); it != source.end(); ++it ) {
394 if ( ( it->first.fType ==
"" && it->second !=
"") ) {
395 error_string = warning +
" - type required when listing a rule's source: ";
396 error_string +=
"source=\""+ rule.find(
"source")->second +
"\"";
407 it1 = rule.find(
"embed" );
408 if( it1 != rule.end() ) {
410 if( emValue !=
"true" && emValue !=
"false" ) {
411 error_string = warning +
" - true or false expected as a value ";
412 error_string +=
"of embed parameter";
421 it1 = rule.find(
"include" );
422 if( it1 != rule.end() ) {
423 if( it1->second.empty() ) {
424 error_string = warning +
" - the include list is empty";
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 std::string warn =
"IO rule for class " + rule[
"targetClass"];
451 warn +=
" data member: " + *it +
" was specified as a ";
452 warn +=
"target in the rule but doesn't seem to appear in ";
453 warn +=
"target class\n";
467 const SourceTypeList_t& source,
469 std::string& className, std::string& mappedName,
472 if (!source.empty()) {
474 SourceTypeList_t::const_iterator it;
481 Bool_t generateOnFile =
false;
482 output <<
"#if 0" << std::endl;
483 for( it = source.begin(); it != source.end(); ++it ) {
485 output <<
"static Int_t id_" << it->second <<
" = oldObj->GetId(";
486 output <<
"\"" << it->second <<
"\");" << std::endl;
488 if( it->first.fType !=
"" )
489 generateOnFile =
true;
491 output <<
"#endif" << std::endl;
497 if( generateOnFile ) {
498 std::string onfileStructName = mappedName +
"_Onfile";
500 output <<
"struct " << onfileStructName <<
" {\n";
507 for( it = source.begin(); it != source.end(); ++it ) {
508 if( it->first.fType.size() ) {
509 if ( it->first.fDimensions.size() ) {
510 output <<
" typedef " << it->first.fType;
511 output <<
" onfile_" << it->second <<
"_t" << it->first.fDimensions <<
";\n";
513 output <<
"onfile_" << it->second <<
"_t &" << it->second <<
";\n";
517 output << it->first.fType <<
" &" << it->second <<
";\n";
526 output <<
" " << onfileStructName <<
"(";
527 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
528 if( it->first.fType.size() == 0)
536 if (it->first.fDimensions.size() == 0) {
537 output << it->first.fType <<
" &onfile_" << it->second;
539 output <<
" onfile_" << it->second <<
"_t" <<
" &onfile_" << it->second;
548 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
549 if( it->first.fType ==
"" )
557 output << it->second <<
"(onfile_" << it->second <<
")";
560 output <<
" " <<
"};\n";
566 for( it = source.begin(); it != source.end(); ++it ) {
568 output <<
"static Long_t offset_Onfile_" << mappedName;
569 output <<
"_" << it->second <<
" = oldObj->GetClass()->GetDataMemberOffset(\"";
570 output << it->second <<
"\");\n";
572 output <<
" " <<
"char *onfile_add = (char*)oldObj->GetObject();\n";
573 output <<
" " << mappedName <<
"_Onfile onfile(\n";
575 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
576 if( it->first.fType ==
"" )
587 if (it->first.fDimensions.size() == 0) {
588 output << it->first.fType;
590 output << mappedName <<
"_Onfile::onfile_" << it->second <<
"_t";
592 output <<
"*)(onfile_add+offset_Onfile_";
593 output << mappedName <<
"_" << it->second <<
")";
603 if( !target.empty() ) {
604 output <<
" static TClassRef cls(\"";
605 output << className <<
"\");" << std::endl;
607 std::list<std::string>::const_iterator it;
608 for( it = target.begin(); it != target.end(); ++it ) {
610 output <<
" static Long_t offset_" << *it <<
" = ";
611 output <<
"cls->GetDataMemberOffset(\"" << *it <<
"\");";
614 output <<
" typedef " << memData.
fType <<
" " << *it <<
"_t" << memData.
fDimensions <<
";" << std::endl;
615 output <<
" " << *it <<
"_t& " << *it <<
" = ";
616 output <<
"*(" << *it <<
"_t *)(target+offset_" << *it;
617 output <<
");" << std::endl;
619 output <<
" " << memData.
fType <<
"& " << *it <<
" = ";
620 output <<
"*(" << memData.
fType <<
"*)(target+offset_" << *it;
621 output <<
");" << std::endl;
635 std::string className = rule[
"targetClass"];
641 std::ostringstream
func;
642 func <<
"read_" << mappedName <<
"_" << index;
643 rule[
"funcname"] = func.str();
649 output <<
" static void " << func.str();
650 output <<
"( char* target, TVirtualObject *oldObj )" << std::endl;
651 output <<
" {" << std::endl;
652 output <<
" //--- Automatically generated variables ---" << std::endl;
658 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
659 std::list<std::string> target;
664 output <<
" " << className <<
"* newObj = (" << className;
665 output <<
"*)target;" << std::endl;
666 output <<
" // Supress warning message.\n";
667 output <<
" " <<
"if (oldObj) {}\n\n";
668 output <<
" " <<
"if (newObj) {}\n\n";
674 output <<
" //--- User's code ---" << std::endl;
675 output <<
" " << rule[
"code"] << std::endl;
676 output <<
" }" << std::endl;
688 std::string className = rule[
"targetClass"];
694 std::ostringstream
func;
695 func <<
"readraw_" << mappedName <<
"_" << index;
696 rule[
"funcname"] = func.str();
702 output <<
" static void " << func.str();
703 output <<
"( char* target, TBuffer &b )" << std::endl;
704 output <<
" {" << std::endl;
705 output <<
"#if 0" << std::endl;
706 output <<
" //--- Automatically generated variables ---" << std::endl;
712 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
713 std::list<std::string> target;
717 output <<
" " << className <<
"* newObj = (" << className;
718 output <<
"*)target;" << std::endl << std::endl;
724 output <<
" //--- User's code ---" << std::endl;
725 output << rule[
"code"] << std::endl;
726 output <<
"#endif" << std::endl;
727 output <<
" }" << std::endl;
733 static void StrReplace( std::string& proc,
const std::string& pat,
734 const std::string& tr )
736 std::string::size_type it = 0;
737 std::string::size_type s = pat.size();
738 std::string::size_type tr_len= tr.size();
743 it = proc.find( pat, it );
744 if( it == std::string::npos )
747 proc.replace( it, s, tr );
756 const std::string& listName, std::ostream&
output )
758 std::list<SchemaRuleMap_t>::iterator it;
765 for( it = rules.begin(); it != rules.end(); ++it ) {
766 output <<
" rule = &" << listName <<
"[" << i++;
767 output <<
"];" << std::endl;
773 output <<
" rule->fSourceClass = \"" << (*it)[
"sourceClass"];
774 output <<
"\";" << std::endl;
776 if( it->find(
"target" ) != it->end() ) {
777 output <<
" rule->fTarget = \"" << (*it)[
"target"];
778 output <<
"\";" << std::endl;
781 if( it->find(
"source" ) != it->end() ) {
782 output <<
" rule->fSource = \"" << (*it)[
"source"];
783 output <<
"\";" << std::endl;
790 if( it->find(
"funcname" ) != it->end() ) {
791 std::string code = (*it)[
"code"];
795 output <<
" rule->fFunctionPtr = (void *)TFunc2void( ";
796 output << (*it)[
"funcname"] <<
");" << std::endl;
797 output <<
" rule->fCode = \"" << code;
798 output <<
"\";" << std::endl;
801 if( it->find(
"version" ) != it->end() ) {
802 output <<
" rule->fVersion = \"" << (*it)[
"version"];
803 output <<
"\";" << std::endl;
806 if( it->find(
"checksum" ) != it->end() ) {
807 output <<
" rule->fChecksum = \"" << (*it)[
"checksum"];
808 output <<
"\";" << std::endl;
811 if( it->find(
"embed" ) != it->end() ) {
812 output <<
" rule->fEmbed = " << (*it)[
"embed"];
813 output <<
";" << std::endl;
816 if( it->find(
"include" ) != it->end() ) {
817 output <<
" rule->fInclude = \"" << (*it)[
"include"];
818 output <<
"\";" << std::endl;
821 if( it->find(
"attributes" ) != it->end() ) {
822 output <<
" rule->fAttributes = \"" << (*it)[
"attributes"];
823 output <<
"\";" << std::endl;
833 std::list<std::string> tmp;
834 std::list<SchemaRuleMap_t>::iterator rule;
835 SchemaRuleMap_t::iterator attr;
836 SchemaRuleClassMap_t::iterator it;
842 for( it = gReadRules.begin(); it != gReadRules.end(); ++it ) {
843 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
844 attr = rule->find(
"include" );
845 if( attr == rule->end() )
continue;
847 result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
855 for( it = gReadRawRules.begin(); it != gReadRawRules.end(); ++it ) {
856 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
857 attr = rule->find(
"include" );
858 if( attr == rule->end() )
continue;
860 result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
881 std::map<std::string, std::string> rule;
882 std::string error_string;
883 if( !
ParseRule( args, rule, error_string ) ) {
884 error_string +=
"\nThe following rule has been omitted:\n read ";
885 error_string += args;
886 error_string +=
"\n";
895 SchemaRuleClassMap_t::iterator it;
896 std::string targetClass = rule[
"targetClass"];
897 it = gReadRules.find( targetClass );
898 if( it == gReadRules.end() ) {
899 std::list<SchemaRuleMap_t> lst;
900 lst.push_back( rule );
901 gReadRules[targetClass] = lst;
904 it->second.push_back( rule );
916 std::map<std::string, std::string> rule;
917 std::string error_string;
918 if( !
ParseRule( args, rule, error_string ) ) {
919 error_string +=
"\nThe following rule has been omitted:\n readraw ";
920 error_string += args;
921 error_string +=
"\n";
930 SchemaRuleClassMap_t::iterator it;
931 std::string targetClass = rule[
"targetClass"];
932 it = gReadRawRules.find( targetClass );
933 if( it == gReadRawRules.end() ) {
934 std::list<SchemaRuleMap_t> lst;
935 lst.push_back( rule );
936 gReadRawRules[targetClass] = lst;
939 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
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
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
static bool IsANumber(const std::string &source)
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members)
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)
bool ParseRule(std::string rule, MembersMap_t &result, std::string &error_string)
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.
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)
I am being called then a readraw pragma is encountered.
SchemaRuleClassMap_t gReadRawRules
void ProcessReadPragma(const char *args)
I am being called when a read pragma is encountered.
double func(double *x, double *p)
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.
std::map< std::string, std::string > SchemaRuleMap_t
static std::string Trim(const std::string &source)
static bool ProcessVersion(const std::string &source, std::pair< Int_t, Int_t > &result)