29 static void RemoveEscapeSequences(std::string& rawString)
31 const std::vector<std::pair<std::string, std::string>> subPairs { {
"\\\\",
"\\"},
35 for (
auto const & subPair : subPairs){
37 auto from = subPair.first;
38 auto to = subPair.second;
39 while((start_pos = rawString.find(from, start_pos)) != std::string::npos) {
40 rawString.replace(start_pos, from.length(), to);
41 start_pos += to.length();
51 typedef std::list<std::pair<ROOT::Internal::TSchemaType,std::string> >
SourceTypeList_t;
60 static Bool_t ValidateRule(
const std::map<std::string, std::string>& rule, std::string &error_string );
66 if (command.length() == 0)
return std::string::npos;
67 std::string::size_type
cursor;
68 unsigned int level = 0;
71 switch( command[
cursor] ) {
75 case '=':
if (level==0) {
76 std::string::size_type sub_cursor =
cursor;
77 while( isspace(command[sub_cursor]) ) {
80 if ( command[sub_cursor] ==
'=' ) {
88 case '<': ++level;
break;
89 case '>':
if (level==0) {
return std::string::npos; }
105 std::string &error_string )
107 std::string::size_type
l=0;
114 if( command[command.size()-1] ==
';' )
115 command = command.substr( 0, command.size()-1 );
124 if ( endsymbol == command.length() || command[endsymbol] ==
' ' || command[endsymbol] ==
'\t' ) {
132 if (endsymbol < command.length()) {
146 if ( endsymbol == command.length() || command[endsymbol] ==
' ' || command[endsymbol] ==
'\t' ) {
148 result[
"source"] = membervalue;
149 result[
"target"] = membervalue;
159 while( !command.empty() ) {
164 std::string::size_type pos = command.find(
'=' );
170 if( pos == std::string::npos ) {
171 error_string =
"Parsing error, no key found!";
186 if( command.size() < 1 ) {
187 error_string =
"Parsing error, wrond or no value specified for key: " + key;
191 Bool_t hasquote = command[0] ==
'"';
197 if( key ==
"code" ) {
203 auto clean_command = [](
const std::string &
c) {
206 first_trim.substr(first_trim.find_first_of(
'"') + 1, first_trim.find_last_of(
'"') - 1);
208 return '"' + second_trim +
'"';
210 command = clean_command(command);
212 if( command[1] !=
'{' ) {
213 error_string =
"Parsing error while processing key: code\n";
214 error_string +=
"Expected \"{ at the beginning of the value.";
217 l = command.find(
"}\"" );
218 if(
l == std::string::npos ) {
219 error_string =
"Parsing error while processing key: \"" + key +
"\"\n";
220 error_string +=
"Expected }\" at the end of the value.";
223 auto rawCode = command.substr( 2,
l-2 );
224 RemoveEscapeSequences(rawCode);
234 l = command.find(
'"', 1 );
235 if (
l == std::string::npos ) {
236 error_string =
"\nParsing error while processing key: \"" + key +
"\"\n";
237 error_string +=
"Expected \" at the end of the value.";
240 result[key] = command.substr( 1,
l-1 );
242 l = command.find(
' ', 1);
243 if (
l == std::string::npos)
l = command.size();
244 result[key] = command.substr( 0,
l );
252 if(
l == command.size() )
254 command = command.substr(
l+1 );
256 std::map<std::string, std::string>::const_iterator it1;
257 it1 =
result.find(
"oldtype");
258 if ( it1 !=
result.end() ) {
259 std::map<std::string, std::string>::const_iterator it2;
260 it2 =
result.find(
"source");
261 if ( it2 !=
result.end() ) {
262 result[
"source"] = it1->second +
" " + it2->second;
266 result[
"version"] =
"[1-]";
274 auto const includeKeyName =
"include";
275 auto includeTag =
result.find(includeKeyName);
276 if (includeTag !=
result.end()){
277 auto & includeTagValue = includeTag->second;
278 std::replace_if (includeTagValue.begin(),
279 includeTagValue.end(),
280 [](
char c){ return c ==
';';},
282 result[includeKeyName] = includeTagValue;
291 static Bool_t ValidateRule(
const std::map<std::string, std::string>& rule, std::string &error_string )
297 std::map<std::string, std::string>::const_iterator it1, it2;
298 std::list<std::string> lst;
300 it1 = rule.find(
"targetClass" );
301 if( it1 == rule.end() ) {
302 error_string =
"You always have to specify the targetClass ";
303 error_string +=
"when specyfying an IO rule";
308 std::string warning =
"IO rule for class " + className;
314 it1 = rule.find(
"sourceClass" );
315 if( it1 == rule.end())
317 error_string = warning +
" - sourceClass parameter is missing";
325 it1 = rule.find(
"version" );
326 it2 = rule.find(
"checksum" );
327 if( it1 == rule.end() && it2 == rule.end() ) {
328 error_string = warning +
" - you need to specify either version or ";
329 error_string +=
"checksum";
337 if( it2 != rule.end() ) {
338 if( it2->second.size() < 2 || it2->second[0] !=
'[' ||
339 it2->second[it2->second.size()-1] !=
']' ) {
340 error_string = warning +
" - a comma separated list of ints";
341 error_string +=
" enclosed in square brackets expected";
342 error_string +=
" as a value of checksum parameter";
349 error_string += warning +
" - the list of checksums is empty\n";
352 for(
const auto& chk : lst ) {
354 error_string = warning +
" - " + chk +
" is not a valid value";
355 error_string +=
" of checksum parameter - an integer (decimal/hex) expected";
365 std::pair<Int_t, Int_t> ver;
366 if( it1 != rule.end() ) {
367 if( it1->second.size() < 2 || it1->second[0] !=
'[' ||
368 it1->second[it1->second.size()-1] !=
']' ) {
369 error_string = warning +
" - a comma separated list of version specifiers ";
370 error_string +=
"enclosed in square brackets expected";
371 error_string +=
"as a value of version parameter";
378 error_string = warning +
" - the list of versions is empty";
381 for(
const auto& version : lst )
383 error_string = warning +
" - " + version +
" is not a valid value";
384 error_string +=
" of version parameter";
394 if( rule.size() == 3 || (rule.size() == 4 && it1 != rule.end() && it2 != rule.end()) )
400 std::string keys[] = {
"target",
"source"};
401 for(
int i = 0; i < 2; ++i ) {
402 it1 = rule.find( keys[i] );
403 if( it1 == rule.end() ) {
404 error_string = warning +
" - required parameter is missing: ";
405 error_string += keys[i];
414 it1 = rule.find(
"code");
415 if (it1 != rule.end() && it1->second !=
"") {
418 SourceTypeList_t::const_iterator it;
419 for( it = source.begin(); it != source.end(); ++it ) {
420 if ( ( it->first.fType ==
"" && it->second !=
"") ) {
421 error_string = warning +
" - type required when listing a rule's source: ";
422 error_string +=
"source=\""+ rule.find(
"source")->second +
"\"";
433 it1 = rule.find(
"embed" );
434 if( it1 != rule.end() ) {
436 if( emValue !=
"true" && emValue !=
"false" ) {
437 error_string = warning +
" - true or false expected as a value ";
438 error_string +=
"of embed parameter";
447 it1 = rule.find(
"include" );
448 if( it1 != rule.end() ) {
449 if( it1->second.empty() ) {
450 error_string = warning +
" - the include list is empty";
463 std::string& error_string)
465 std::list<std::string> mem;
466 std::list<std::string>::iterator it;
475 for( it = mem.begin(); it != mem.end(); ++it ) {
476 if( members.find( *it ) == members.end() ) {
477 error_string +=
"IO rule for class " + rule[
"targetClass"]
478 +
" data member: " + *it +
" was specified as a "
479 "target in the rule but doesn't seem to appear in "
493 std::string& className, std::string& mappedName,
496 if (!source.empty()) {
498 SourceTypeList_t::const_iterator it;
505 Bool_t generateOnFile =
false;
506 output <<
"#if 0" << std::endl;
507 for( it = source.begin(); it != source.end(); ++it ) {
509 output <<
"static Int_t id_" << it->second <<
" = oldObj->GetId(";
510 output <<
"\"" << it->second <<
"\");" << std::endl;
512 if( it->first.fType !=
"" )
513 generateOnFile =
true;
515 output <<
"#endif" << std::endl;
521 if( generateOnFile ) {
522 std::string onfileStructName = mappedName +
"_Onfile";
524 output <<
"struct " << onfileStructName <<
" {\n";
531 for( it = source.begin(); it != source.end(); ++it ) {
532 if( it->first.fType.size() ) {
533 if ( it->first.fDimensions.size() ) {
534 output <<
" typedef " << it->first.fType;
535 output <<
" onfile_" << it->second <<
"_t" << it->first.fDimensions <<
";\n";
537 output <<
"onfile_" << it->second <<
"_t &" << it->second <<
";\n";
541 output << it->first.fType <<
" &" << it->second <<
";\n";
550 output <<
" " << onfileStructName <<
"(";
551 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
552 if( it->first.fType.size() == 0)
560 if (it->first.fDimensions.size() == 0) {
561 output << it->first.fType <<
" &onfile_" << it->second;
563 output <<
" onfile_" << it->second <<
"_t" <<
" &onfile_" << it->second;
572 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
573 if( it->first.fType ==
"" )
581 output << it->second <<
"(onfile_" << it->second <<
")";
590 for( it = source.begin(); it != source.end(); ++it ) {
592 output <<
"static Long_t offset_Onfile_" << mappedName;
593 output <<
"_" << it->second <<
" = oldObj->GetClass()->GetDataMemberOffset(\"";
594 output << it->second <<
"\");\n";
596 output <<
" " <<
"char *onfile_add = (char*)oldObj->GetObject();\n";
597 output <<
" " << mappedName <<
"_Onfile onfile(\n";
599 for( start =
true, it = source.begin(); it != source.end(); ++it ) {
600 if( it->first.fType ==
"" )
611 if (it->first.fDimensions.size() == 0) {
612 output << it->first.fType;
614 output << mappedName <<
"_Onfile::onfile_" << it->second <<
"_t";
616 output <<
"*)(onfile_add+offset_Onfile_";
617 output << mappedName <<
"_" << it->second <<
")";
628 output <<
" static TClassRef cls(\"";
629 output << className <<
"\");" << std::endl;
631 std::list<std::string>::const_iterator it;
634 output <<
" static Long_t offset_" << *it <<
" = ";
635 output <<
"cls->GetDataMemberOffset(\"" << *it <<
"\");";
639 output <<
" " << *it <<
"_t& " << *it <<
" = ";
640 output <<
"*(" << *it <<
"_t *)(target+offset_" << *it;
641 output <<
");" << std::endl;
643 output <<
" " << memData.
fType <<
"& " << *it <<
" = ";
644 output <<
"*(" << memData.
fType <<
"*)(target+offset_" << *it;
645 output <<
");" << std::endl;
659 std::string className = rule[
"targetClass"];
665 std::ostringstream func;
666 func <<
"read_" << mappedName <<
"_" <<
index;
667 rule[
"funcname"] = func.str();
673 output <<
" static void " << func.str();
674 output <<
"( char* target, TVirtualObject *oldObj )" << std::endl;
675 output <<
" {" << std::endl;
676 output <<
" //--- Automatically generated variables ---" << std::endl;
682 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
683 std::list<std::string>
target;
688 output <<
" " << className <<
"* newObj = (" << className;
689 output <<
"*)target;" << std::endl;
690 output <<
" // Supress warning message.\n";
691 output <<
" " <<
"(void)oldObj;\n\n";
692 output <<
" " <<
"(void)newObj;\n\n";
698 output <<
" //--- User's code ---" << std::endl;
699 output <<
" " << rule[
"code"] << std::endl;
700 output <<
" }" << std::endl;
712 std::string className = rule[
"targetClass"];
718 std::ostringstream func;
719 func <<
"readraw_" << mappedName <<
"_" <<
index;
720 rule[
"funcname"] = func.str();
726 output <<
" static void " << func.str();
727 output <<
"( char* target, TBuffer &b )" << std::endl;
728 output <<
" {" << std::endl;
729 output <<
"#if 0" << std::endl;
730 output <<
" //--- Automatically generated variables ---" << std::endl;
736 std::list<std::pair<ROOT::Internal::TSchemaType,std::string> > source;
737 std::list<std::string>
target;
741 output <<
" " << className <<
"* newObj = (" << className;
742 output <<
"*)target;" << std::endl << std::endl;
748 output <<
" //--- User's code ---" << std::endl;
749 output << rule[
"code"] << std::endl;
750 output <<
"#endif" << std::endl;
751 output <<
" }" << std::endl;
757 static void StrReplace( std::string& proc,
const std::string& pat,
758 const std::string& tr )
760 std::string::size_type it = 0;
761 std::string::size_type s = pat.size();
762 std::string::size_type tr_len= tr.size();
767 it = proc.find( pat, it );
768 if( it == std::string::npos )
771 proc.replace( it, s, tr );
780 const std::string& listName, std::ostream&
output )
782 std::list<SchemaRuleMap_t>::iterator it;
789 for( it = rules.begin(); it != rules.end(); ++it ) {
790 output <<
" rule = &" << listName <<
"[" << i++;
791 output <<
"];" << std::endl;
797 output <<
" rule->fSourceClass = \"" << (*it)[
"sourceClass"];
798 output <<
"\";" << std::endl;
800 if( it->find(
"target" ) != it->end() ) {
801 output <<
" rule->fTarget = \"" << (*it)[
"target"];
802 output <<
"\";" << std::endl;
805 if( it->find(
"source" ) != it->end() ) {
806 output <<
" rule->fSource = \"" << (*it)[
"source"];
807 output <<
"\";" << std::endl;
814 if( it->find(
"funcname" ) != it->end() ) {
815 std::string code = (*it)[
"code"];
819 output <<
" rule->fFunctionPtr = (void *)TFunc2void( ";
820 output << (*it)[
"funcname"] <<
");" << std::endl;
821 output <<
" rule->fCode = \"" << code;
822 output <<
"\";" << std::endl;
825 if( it->find(
"version" ) != it->end() ) {
826 output <<
" rule->fVersion = \"" << (*it)[
"version"];
827 output <<
"\";" << std::endl;
830 if( it->find(
"checksum" ) != it->end() ) {
831 output <<
" rule->fChecksum = \"" << (*it)[
"checksum"];
832 output <<
"\";" << std::endl;
835 if( it->find(
"embed" ) != it->end() ) {
836 output <<
" rule->fEmbed = " << (*it)[
"embed"];
837 output <<
";" << std::endl;
840 if( it->find(
"include" ) != it->end() ) {
841 output <<
" rule->fInclude = \"" << (*it)[
"include"];
842 output <<
"\";" << std::endl;
845 if( it->find(
"attributes" ) != it->end() ) {
846 output <<
" rule->fAttributes = \"" << (*it)[
"attributes"];
847 output <<
"\";" << std::endl;
857 std::list<std::string> tmp;
858 std::list<SchemaRuleMap_t>::iterator rule;
859 SchemaRuleMap_t::iterator
attr;
860 SchemaRuleClassMap_t::iterator it;
867 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
868 attr = rule->find(
"include" );
869 if(
attr == rule->end() )
continue;
871 result.splice(
result.begin(), tmp, tmp.begin(), tmp.end() );
880 for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
881 attr = rule->find(
"include" );
882 if(
attr == rule->end() )
continue;
884 result.splice(
result.begin(), tmp, tmp.begin(), tmp.end() );
905 std::map<std::string, std::string> rule;
906 if( !
ParseRule( args, rule, error_string ) ) {
907 error_string +=
"\nThe following rule has been omitted:\n read ";
908 error_string += args;
909 error_string +=
"\n";
917 SchemaRuleClassMap_t::iterator it;
918 std::string targetClass = rule[
"targetClass"];
919 std::string normalizedTargetName;
924 std::list<SchemaRuleMap_t> lst;
925 lst.push_back( rule );
929 it->second.push_back( rule );
941 std::map<std::string, std::string> rule;
942 if( !
ParseRule( args, rule, error_string ) ) {
943 error_string +=
"\nThe following rule has been omitted:\n readraw ";
944 error_string += args;
945 error_string +=
"\n";
953 SchemaRuleClassMap_t::iterator it;
954 std::string targetClass = rule[
"targetClass"];
955 std::string normalizedTargetName;
959 std::list<SchemaRuleMap_t> lst;
960 lst.push_back( rule );
964 it->second.push_back( rule );
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 Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
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 index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
static bool IsANumber(const std::string &source, bool acceptHex=false)
Check if given string consists of digits.
static std::string Trim(const std::string &source)
static void SplitDeclaration(const std::string &source, std::list< std::pair< ROOT::Internal::TSchemaType, std::string > > &result)
static bool ProcessVersion(const std::string &source, std::pair< Int_t, Int_t > &result)
static void SplitList(const std::string &source, std::list< std::string > &result, char delimiter=',')
std::map< std::string, std::string > MembersMap_t
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::list< std::pair< ROOT::Internal::TSchemaType, std::string > > SourceTypeList_t
std::map< std::string, std::list< SchemaRuleMap_t > > SchemaRuleClassMap_t
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.
static std::string::size_type FindEndSymbol(std::string &command)
static void StrReplace(std::string &proc, const std::string &pat, const std::string &tr)
Replace all accurances of given string with other string.
void ProcessReadPragma(const char *args, std::string &error_string)
I am being called when a read pragma is encountered.
void WriteSchemaList(std::list< SchemaRuleMap_t > &rules, const std::string &listName, std::ostream &output)
Write schema rules.
std::map< std::string, ROOT::Internal::TSchemaType > MembersTypeMap_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"].
static Bool_t ValidateRule(const std::map< std::string, std::string > &rule, std::string &error_string)
Validate if the user specified rules are correct.
R__EXTERN SchemaRuleClassMap_t gReadRules
std::map< std::string, std::string > SchemaRuleMap_t
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members, std::string &error_string)
Check if given rule contains references to valid data members.
void GetRuleIncludes(std::list< std::string > &result)
Get the list of includes specified in the shema rules.
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"...
void ProcessReadRawPragma(const char *args, std::string &error_string)
I am being called then a readraw pragma is encountered.
R__EXTERN SchemaRuleClassMap_t gReadRawRules
bool ParseRule(std::string rule, ROOT::Internal::MembersMap_t &result, std::string &error_string)
Parse the schema rule as specified in the LinkDef file.
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.