RConversionRuleParser.cxx

Go to the documentation of this file.
00001 // @(#)root/core:$Id: RConversionRuleParser.cxx 35021 2010-08-26 04:37:19Z pcanal $
00002 // author: Lukasz Janyst <ljanyst@cern.ch>
00003 
00004 #include "RConversionRuleParser.h"
00005 #include "TSchemaRuleProcessor.h"
00006 
00007 #include <iostream>
00008 #include <string>
00009 #include <utility>
00010 #include <map>
00011 #include <sstream>
00012 
00013 namespace ROOT
00014 {
00015    //--------------------------------------------------------------------------
00016    // Allocate global variables
00017    //--------------------------------------------------------------------------
00018    SchemaRuleClassMap_t G__ReadRules;
00019    SchemaRuleClassMap_t G__ReadRawRules;
00020 
00021    static bool ValidateRule( const std::map<std::string, std::string>& rule, string &error_string );
00022    
00023    static std::string::size_type FindEndSymbol(std::string &command) 
00024    {
00025       // Find the end of a symbol.
00026       
00027       if (command.length() == 0) return std::string::npos;
00028       std::string::size_type cursor;
00029       unsigned int level = 0;
00030       for (cursor = 0 ; cursor < command.length(); ++cursor) 
00031       {
00032          switch( command[cursor] ) {
00033             case ' ':
00034             case '\t':
00035             case '\r':
00036             case '=': if (level==0) {
00037                std::string::size_type sub_cursor = cursor;
00038                while( isspace(command[sub_cursor]) ) {
00039                   ++sub_cursor;
00040                }
00041                if ( command[sub_cursor] == '=' ) {
00042                   return sub_cursor;
00043                } else {
00044                   return cursor;
00045                }
00046             } else {
00047                break;
00048             }
00049             case '<': ++level; break;
00050             case '>': --level; break;
00051             default: {
00052                // nothing to do
00053             }
00054          };
00055       }
00056       return cursor;
00057    }
00058    
00059    
00060    //--------------------------------------------------------------------------
00061    Bool_t ParseRule( std::string command,
00062                      std::map<std::string, std::string> &result,
00063                      std::string &error_string )
00064    {
00065       // Parse the schema rule as specified in the LinkDef file
00066 
00067       std::string::size_type l;
00068       command = TSchemaRuleProcessor::Trim( command );
00069 
00070       //-----------------------------------------------------------------------
00071       // Remove the semicolon from the end if declared
00072       //-----------------------------------------------------------------------
00073       if( command[command.size()-1] == ';' )
00074          command = command.substr( 0, command.size()-1 );
00075       
00076       //-----------------------------------------------------------------------
00077       // If the first symbol does not end is not followed by equal then it
00078       // defaults to being the sourceClass.
00079       //-----------------------------------------------------------------------
00080       {
00081          std::string::size_type endsymbol = FindEndSymbol( command );
00082          if ( endsymbol == command.length() || command[endsymbol] == ' ' || command[endsymbol] == '\t' ) {
00083             
00084 //         std::string::size_type space_pos = command.find( ' ' );
00085 //         std::string::size_type equal_pos = command.find( '=' );
00086 //         if ( space_pos < equal_pos) {
00087             std::string value = TSchemaRuleProcessor::Trim( command.substr( 0, endsymbol ) );
00088             result["sourceClass"] = value;
00089             result["targetClass"] = value;
00090             if (endsymbol < command.length()) {
00091                command = TSchemaRuleProcessor::Trim( command.substr( endsymbol+1 ) );
00092             } else {
00093                command.clear();
00094             }
00095 
00096             //-----------------------------------------------------------------------
00097             // If the first symbol is the targetClass then the 2nd symbol can be 
00098             // the source data member name.
00099             //-----------------------------------------------------------------------
00100 //            space_pos = command.find( ' ' );
00101 //            equal_pos = command.find( '=' );
00102 //            if ( space_pos < equal_pos ) {
00103             endsymbol = FindEndSymbol( command );
00104             if ( endsymbol == command.length() || command[endsymbol] == ' ' || command[endsymbol] == '\t' ) {
00105                std::string membervalue = TSchemaRuleProcessor::Trim( command.substr( 0, endsymbol ) );
00106                result["source"] = membervalue;
00107                result["target"] = membervalue;
00108                command = TSchemaRuleProcessor::Trim( command.substr( endsymbol+1 ) );
00109             }               
00110          }
00111       }
00112 
00113       //-----------------------------------------------------------------------
00114       // Process the input until there are no characters left
00115       //-----------------------------------------------------------------------
00116       while( !command.empty() ) {
00117 
00118          //--------------------------------------------------------------------
00119          // Find key token
00120          //--------------------------------------------------------------------
00121          std::string::size_type pos = command.find( '=' );
00122 
00123          //--------------------------------------------------------------------
00124          // No equality sign found - no keys left
00125          //--------------------------------------------------------------------
00126          if( pos == std::string::npos ) {
00127             error_string = "Parsing error, no key found!";
00128             return false;
00129          }
00130 
00131          //--------------------------------------------------------------------
00132          // The key was found - process the arguments
00133          //--------------------------------------------------------------------
00134          std::string key = TSchemaRuleProcessor::Trim( command.substr( 0, pos ) );
00135          command = TSchemaRuleProcessor::Trim( command.substr( pos+1 ) );
00136 
00137          //--------------------------------------------------------------------
00138          // Nothing left to be processed
00139          //--------------------------------------------------------------------
00140          if( command.size() < 1 ) {
00141             error_string = "Parsing error, wrond or no value specified for key: " + key;
00142             return false;
00143          }
00144 
00145          bool hasquote = command[0] == '"';
00146 
00147          //--------------------------------------------------------------------
00148          // Processing code tag: "{ code }"
00149          //--------------------------------------------------------------------
00150          if( key == "code" ) {
00151             if( command[1] != '{' ) {
00152                error_string = "Parsing error while processing key: code\n";
00153                error_string += "Expected \"{ at the beginning of the value.";
00154                return false;
00155             }
00156             l = command.find( "}\"" );
00157             if( l == std::string::npos ) {
00158                error_string = "Parsing error while processing key: \"" + key + "\"\n";
00159                error_string += "Expected }\" at the end of the value.";
00160                return false;
00161             }
00162             result[key] = command.substr( 2, l-2 );
00163             ++l;
00164          }
00165          //--------------------------------------------------------------------
00166          // Processing normal tag: "value"
00167          //--------------------------------------------------------------------
00168          else {
00169             
00170             if( hasquote) {
00171                l = command.find( '"', 1 );
00172                if (l == std::string::npos ) {
00173                   error_string = "\nParsing error while processing key: \"" + key + "\"\n";
00174                   error_string += "Expected \" at the end of the value.";
00175                   return false;
00176                }
00177                result[key] = command.substr( 1, l-1 );
00178             } else {
00179                l = command.find(' ', 1);
00180                if (l == std::string::npos) l = command.size();
00181                result[key] = command.substr( 0, l );
00182             }               
00183          }
00184 
00185          //--------------------------------------------------------------------
00186          // Everything went ok
00187          //--------------------------------------------------------------------
00188          if( l == command.size() )
00189             break;
00190          command = command.substr( l+1 );
00191       }
00192       std::map<std::string, std::string>::const_iterator it1;
00193       it1 = result.find("oldtype");
00194       if ( it1 != result.end() ) {
00195          std::map<std::string, std::string>::const_iterator it2;
00196          it2 = result.find("source");
00197          if ( it2 != result.end() ) {
00198             result["source"] = it1->second + " " + it2->second;
00199          }
00200       }
00201       if ( result.find("version") == result.end() && result.find("checksum") == result.end() ) {
00202          result["version"] = "[1-]";
00203       }
00204       return ValidateRule( result, error_string);
00205    }
00206 
00207    //--------------------------------------------------------------------------
00208    static bool ValidateRule( const std::map<std::string, std::string>& rule, string &error_string )
00209    {
00210       // Validate if the user specified rules are correct
00211 
00212       //-----------------------------------------------------------------------
00213       // Check if we have target class name
00214       //-----------------------------------------------------------------------
00215       std::map<std::string, std::string>::const_iterator it1, it2;
00216       std::list<std::string>                             lst;
00217       std::list<std::string>::iterator                   lsIt;
00218 
00219       it1 = rule.find( "targetClass" );
00220       if( it1 == rule.end() ) {
00221          error_string = "WARNING: You always have to specify the targetClass ";
00222          error_string += "when specyfying an IO rule";
00223          return false;
00224       }
00225 
00226       std::string className = TSchemaRuleProcessor::Trim( it1->second );
00227       std::string warning = "WARNING: IO rule for class " + className;
00228 
00229       //-----------------------------------------------------------------------
00230       // Check if we have the source tag
00231       //-----------------------------------------------------------------------
00232       it1 = rule.find( "sourceClass" );
00233       if( it1 == rule.end())
00234       {
00235          error_string = warning + " - sourceClass parameter is missing";
00236          return false;
00237       }
00238 
00239       //-----------------------------------------------------------------------
00240       // Check if we have either version or checksum specified
00241       //-----------------------------------------------------------------------
00242       it1 = rule.find( "version" );
00243       it2 = rule.find( "checksum" );
00244       if( it1 == rule.end() && it2 == rule.end() ) {
00245          error_string = warning + " - you need to specify either version or ";
00246          error_string += "checksum";
00247          return false;
00248       }
00249 
00250       //-----------------------------------------------------------------------
00251       // Check if the checksum has been set to right value
00252       //-----------------------------------------------------------------------
00253       if( it2 != rule.end() ) {
00254          if( it2->second.size() < 2 || it2->second[0] != '[' ||
00255              it2->second[it2->second.size()-1] != ']' ) {
00256             error_string = warning + " - a comma separated list of ints ";
00257             error_string += "enclosed in square brackets expected";
00258             error_string += "as a value of checksum parameter";
00259             return false;
00260          }
00261 
00262          TSchemaRuleProcessor::SplitList( it2->second.substr( 1, it2->second.size()-2 ),
00263                                           lst );
00264          if( lst.empty() ) {
00265             std::cout << warning << " - the list of checksums is empty";
00266             std::cout << std::endl;
00267          }
00268 
00269          for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
00270             if( !TSchemaRuleProcessor::IsANumber( *lsIt ) ) {
00271                error_string = warning + " - " + *lsIt + " is not a valid value";
00272                error_string += " of checksum parameter - an integer expected";
00273                return false;
00274             }
00275       }
00276 
00277       //-----------------------------------------------------------------------
00278       // Check if the version is correct
00279       //-----------------------------------------------------------------------
00280       std::pair<Int_t, Int_t> ver;
00281       if( it1 != rule.end() ) {
00282          if( it1->second.size() < 2 || it1->second[0] != '[' ||
00283              it1->second[it1->second.size()-1] != ']' ) {
00284             error_string = warning + " - a comma separated list of version specifiers ";
00285             error_string += "enclosed in square brackets expected";
00286             error_string += "as a value of version parameter";
00287             return false;
00288          }
00289 
00290          TSchemaRuleProcessor::SplitList( it1->second.substr( 1, it1->second.size()-2 ),
00291                                           lst );
00292          if( lst.empty() ) {
00293             error_string = warning + " - the list of versions is empty";
00294          }
00295 
00296          for( lsIt = lst.begin(); lsIt != lst.end(); ++lsIt )
00297             if( !TSchemaRuleProcessor::ProcessVersion( *lsIt, ver ) ) {
00298                error_string = warning + " - " + *lsIt + " is not a valid value";
00299                error_string += " of version parameter";
00300                return false;
00301             }
00302       }
00303 
00304       //-----------------------------------------------------------------------
00305       // Check if we're dealing with renameing declaration - sourceClass,
00306       // targetClass and either version or checksum required
00307       //-----------------------------------------------------------------------
00308       if( rule.size() == 3 || (rule.size() == 4 && it1 != rule.end() && it2 != rule.end()) )
00309          return true;
00310 
00311       //-----------------------------------------------------------------------
00312       // Check if we have all the keys we need
00313       //-----------------------------------------------------------------------
00314       std::string keys[] = {"target", "source"};
00315       for( int i = 0; i < 2; ++i ) {
00316          it1 = rule.find( keys[i] );
00317          if( it1 == rule.end() ) {
00318             error_string = warning + " - required parameter is missing: ";
00319             error_string += keys[i];
00320             return false;
00321          }
00322       }
00323 
00324       //-----------------------------------------------------------------------
00325       // Check if we have an embed aparameter and if so if it has been set to
00326       // the right value
00327       //-----------------------------------------------------------------------
00328       it1 = rule.find( "embed" );
00329       if( it1 != rule.end() ) {
00330          std::string emValue = TSchemaRuleProcessor::Trim( it1->second );
00331          if( emValue != "true" && emValue != "false" ) {
00332             error_string = warning + " - true or false expected as a value ";
00333             error_string += "of embed parameter";
00334             return false;
00335          }
00336       }
00337 
00338       //-----------------------------------------------------------------------
00339       // Check if the include list is not empty
00340       //-----------------------------------------------------------------------
00341       it1 = rule.find( "include" );
00342       if( it1 != rule.end() ) {
00343          if( it1->second.empty() ) {
00344             error_string = warning + " - the include list is empty";
00345             return false;
00346          }
00347       }
00348 
00349       return true;
00350    }
00351 
00352    //--------------------------------------------------------------------------
00353    void CreateNameTypeMap( G__ClassInfo &cl, MembersTypeMap_t& nameType )
00354    {
00355       // Create the data member name-type map for given class
00356 
00357       G__DataMemberInfo member( cl );
00358       std::string dims;
00359       while( member.Next() ) {
00360          if (((member.Type()->Property() & G__BIT_ISCONSTANT)
00361               && (member.Type()->Property() & G__BIT_ISENUM))  // an enum const
00362              || (member.Property() & G__BIT_ISSTATIC)) // a static member
00363             continue;
00364          if (strcmp("G__virtualinfo", member.Name()) == 0) continue;
00365          
00366          dims.clear();
00367          for (int dim = 0; dim < member.ArrayDim(); dim++) {
00368             char cdim[24];
00369             static const int maxsize = sizeof(cdim)/sizeof(cdim[0]);
00370 #ifdef _MSC_VER
00371            int result = _snprintf(cdim,maxsize,"[%d]",member.MaxIndex(dim));
00372 #else
00373            int result = snprintf(cdim,maxsize,"[%d]",member.MaxIndex(dim));
00374 #endif
00375            if (result > maxsize) {
00376                std::cout << "Error: array size is to large, the size '" << member.MaxIndex(dim) << "' does not fit in " << maxsize << " characters.\n";
00377             }
00378             dims += cdim;
00379          }         
00380          nameType[member.Name()] = TSchemaType(member.Type()->Name(),dims.c_str());
00381       }
00382 
00383       G__BaseClassInfo base( cl );
00384       while( base.Next() ) {
00385          nameType[base.Name()] = TSchemaType(base.Name(),"");
00386       }
00387    }
00388 
00389    //---------------------------------------------------------------------------
00390    bool HasValidDataMembers( SchemaRuleMap_t& rule,
00391                              MembersTypeMap_t& members )
00392    {
00393       // Check if given rule contains references to valid data members
00394       std::list<std::string>           mem;
00395       std::list<std::string>::iterator it;
00396       // MembersMap_t::iterator           rIt;
00397 
00398       TSchemaRuleProcessor::SplitList( rule["target"], mem );
00399 
00400       //-----------------------------------------------------------------------
00401       // Loop over the data members
00402       //-----------------------------------------------------------------------
00403       for( it = mem.begin(); it != mem.end(); ++it ) {
00404          if( members.find( *it ) == members.end() ) {
00405             std::cout << "WARNING: IO rule for class " + rule["targetClass"];
00406             std::cout << " data member: " << *it << " was specified as a ";
00407             std::cout << "target in the rule but doesn't seem to appear in ";
00408             std::cout << "target class" << std::endl;
00409             return false;
00410          }
00411       }
00412       return true;
00413    }
00414 
00415    typedef std::list<std::pair<ROOT::TSchemaType,std::string> > SourceTypeList_t;
00416    //--------------------------------------------------------------------------
00417    static void WriteAutoVariables( const std::list<std::string>& target,
00418                                    const SourceTypeList_t& source,
00419                                    MembersTypeMap_t& members,
00420                                    std::string& className, std::string& mappedName,
00421                                    std::ostream& output )
00422    {
00423       //-----------------------------------------------------------------------
00424       // Write down the sources
00425       //-----------------------------------------------------------------------
00426       if (!source.empty()) {
00427          bool start = true;
00428          SourceTypeList_t::const_iterator it;
00429 
00430          //--------------------------------------------------------------------
00431          // Write IDs and check if we should generate the onfile structure
00432          // this is done if the type was declared
00433          //--------------------------------------------------------------------
00434          bool generateOnFile = false;
00435          output << "#if 0" << std::endl; // this is to be removed later
00436          for( it = source.begin(); it != source.end(); ++it ) {
00437             output << "      ";
00438             output << "static Int_t id_" << it->second << " = oldObj->GetId(";
00439             output << "\"" << it->second << "\");" << std::endl;
00440 
00441             if( it->first.fType != "" )
00442                generateOnFile = true;
00443          }
00444          output << "#endif" << std::endl; // this is to be removed later
00445 
00446          //--------------------------------------------------------------------
00447          // Declare the on-file structure - if needed
00448          //--------------------------------------------------------------------
00449          if( generateOnFile ) {
00450             std::string onfileStructName = mappedName + "_Onfile";
00451             output << "      ";
00452             output << "struct " << onfileStructName << " {\n";
00453 
00454             //-----------------------------------------------------------------
00455             // List the data members with non-empty type declarations
00456             //-----------------------------------------------------------------
00457             for( it = source.begin(); it != source.end(); ++it ) {
00458                // fprintf(stderr, "Seeing %s %s %s\n", it->first.fType.c_str(), it->second.c_str(), it->first.fDimensions.c_str());
00459                if( it->first.fType.size() ) {
00460                   if ( it->first.fDimensions.size() ) {
00461                      output << "         typedef " << it->first.fType;
00462                      output << " onfile_" << it->second << "_t" << it->first.fDimensions << ";\n";
00463                      output << "         ";
00464                      output << "onfile_" << it->second << "_t &" << it->second << ";\n"; 
00465                      
00466                   } else {
00467                      output << "         ";
00468                      output << it->first.fType << " &" << it->second << ";\n"; 
00469                   }
00470                }
00471             }
00472 
00473             //-----------------------------------------------------------------
00474             // Generate the constructor
00475             //-----------------------------------------------------------------
00476             output << "         " << onfileStructName << "(";
00477             for( start = true, it = source.begin(); it != source.end(); ++it ) {
00478                if( it->first.fType.size() == 0)
00479                   continue;
00480 
00481                if( !start )
00482                   output << ", ";
00483                else
00484                   start = false;
00485 
00486                if (it->first.fDimensions.size() == 0) {
00487                   output << it->first.fType << " &onfile_" << it->second;
00488                } else {
00489                   output << " onfile_" << it->second << "_t" << " &onfile_" << it->second;                  
00490                }
00491             }
00492             output << " ): ";
00493 
00494             //-----------------------------------------------------------------
00495             // Generate the constructor's initializer list
00496             //-----------------------------------------------------------------
00497             for( start = true, it = source.begin(); it != source.end(); ++it ) {
00498                if( it->first.fType == "" )
00499                   continue;
00500 
00501                if( !start )
00502                   output << ", ";
00503                else
00504                   start = false;
00505 
00506                output << it->second << "(onfile_" << it->second << ")";
00507             }
00508             output << " {}\n";
00509             output << "      " << "};\n";
00510 
00511             //-----------------------------------------------------------------
00512             // Initialize the structure - to be changed later
00513             //-----------------------------------------------------------------
00514             for( it = source.begin(); it != source.end(); ++it ) {
00515                output << "      ";
00516                output << "static Long_t offset_Onfile_" << mappedName;
00517                output << "_" << it->second << " = oldObj->GetClass()->GetDataMemberOffset(\"";
00518                output << it->second << "\");\n";
00519             }
00520             output << "      " << "char *onfile_add = (char*)oldObj->GetObject();\n";
00521             output << "      " << mappedName << "_Onfile onfile(\n";
00522 
00523             for( start = true, it = source.begin(); it != source.end(); ++it ) {
00524                if( it->first.fType == "" )
00525                   continue;
00526 
00527                if( !start )
00528                   output << ",\n";
00529 
00530                else
00531                   start = false;
00532 
00533                output << "         ";
00534                output << "*(";
00535                if (it->first.fDimensions.size() == 0) {
00536                   output << it->first.fType;
00537                } else {
00538                   output << mappedName << "_Onfile::onfile_" << it->second << "_t";
00539                }
00540                output << "*)(onfile_add+offset_Onfile_";
00541                output << mappedName << "_" << it->second << ")";  
00542             }
00543             output << " );\n\n";
00544          }
00545       }
00546 
00547       //-----------------------------------------------------------------------
00548       // Write down the targets
00549       //-----------------------------------------------------------------------
00550       if( !target.empty() ) {
00551          output << "      static TClassRef cls(\"";
00552          output << className << "\");" << std::endl;
00553 
00554          std::list<std::string>::const_iterator it;
00555          for( it = target.begin(); it != target.end(); ++it ) {
00556             TSchemaType memData = members[*it];
00557             output << "      static Long_t offset_" << *it << " = ";
00558             output << "cls->GetDataMemberOffset(\"" << *it << "\");";
00559             output << std::endl;
00560             if (memData.fDimensions.size()) {
00561                output << "      typedef " << memData.fType << " " << *it << "_t" << memData.fDimensions << ";" << std::endl;
00562                output << "      " << *it << "_t& " << *it << " = ";
00563                output << "*(" << *it << "_t *)(target+offset_" << *it;
00564                output << ");" << std::endl;
00565             } else {
00566                output << "      " << memData.fType << "& " << *it << " = ";
00567                output << "*(" << memData.fType << "*)(target+offset_" << *it;
00568                output << ");" << std::endl;
00569             }
00570          }
00571       }
00572    }
00573 
00574    //--------------------------------------------------------------------------
00575    void WriteReadRuleFunc( SchemaRuleMap_t& rule, int index,
00576                            std::string& mappedName, MembersTypeMap_t& members,
00577                            std::ostream& output )
00578    {
00579       // Write the conversion function for Read rule, the function name
00580       // is being written to rule["funcname"]
00581 
00582       std::string className = rule["targetClass"]; 
00583 
00584       //-----------------------------------------------------------------------
00585       // Create the function name
00586       //-----------------------------------------------------------------------
00587       std::ostringstream func;
00588       func << "read_" << mappedName << "_" << index;
00589       rule["funcname"] = func.str();
00590 
00591       //-----------------------------------------------------------------------
00592       // Write the header
00593       //-----------------------------------------------------------------------
00594       output << "   static void " << func.str();
00595       output << "( char* target, TVirtualObject *oldObj )" << std::endl;
00596       output << "   {" << std::endl;
00597       output << "      //--- Automatically generated variables ---" << std::endl;
00598 
00599       //-----------------------------------------------------------------------
00600       // Write the automatically generated variables
00601       //-----------------------------------------------------------------------
00602       std::list<std::pair<ROOT::TSchemaType,std::string> > source;
00603       std::list<std::string> target;
00604       TSchemaRuleProcessor::SplitDeclaration( rule["source"], source );
00605       TSchemaRuleProcessor::SplitList( rule["target"], target );
00606 
00607       WriteAutoVariables( target, source, members, className, mappedName, output );
00608       output << "      " << className << "* newObj = (" << className;
00609       output << "*)target;" << std::endl;
00610       output << "      // Supress warning message.\n";
00611       output << "      " << "if (oldObj) {}\n\n";
00612       output << "      " << "if (newObj) {}\n\n";
00613 
00614       //-----------------------------------------------------------------------
00615       // Write the user's code
00616       //-----------------------------------------------------------------------
00617       output << "      //--- User's code ---" << std::endl;
00618       output << "     " << rule["code"] << std::endl;
00619       output << "   }" << std::endl;
00620    }
00621 
00622 
00623    //--------------------------------------------------------------------------
00624    void WriteReadRawRuleFunc( SchemaRuleMap_t& rule, int index,
00625                               std::string& mappedName, MembersTypeMap_t& members,
00626                               std::ostream& output )
00627    {
00628       // Write the conversion function for ReadRaw rule, the function name
00629       // is being written to rule["funcname"]
00630 
00631       std::string className = rule["targetClass"]; 
00632 
00633       //-----------------------------------------------------------------------
00634       // Create the function name
00635       //-----------------------------------------------------------------------
00636       std::ostringstream func;
00637       func << "readraw_" << mappedName << "_" << index;
00638       rule["funcname"] = func.str();
00639 
00640       //-----------------------------------------------------------------------
00641       // Write the header
00642       //-----------------------------------------------------------------------
00643       output << "   static void " << func.str();
00644       output << "( char* target, TBuffer &b )" << std::endl;
00645       output << "   {" << std::endl;
00646       output << "#if 0" << std::endl;
00647       output << "      //--- Automatically generated variables ---" << std::endl;
00648 
00649       //-----------------------------------------------------------------------
00650       // Write the automatically generated variables
00651       //-----------------------------------------------------------------------
00652       std::list<std::pair<ROOT::TSchemaType,std::string> > source;
00653       std::list<std::string> target;
00654       TSchemaRuleProcessor::SplitList( rule["target"], target );
00655 
00656       WriteAutoVariables( target, source, members, className, mappedName, output );
00657       output << "      " << className << "* newObj = (" << className;
00658       output << "*)target;" << std::endl << std::endl;
00659 
00660       //-----------------------------------------------------------------------
00661       // Write the user's code
00662       //-----------------------------------------------------------------------
00663       output << "      //--- User's code ---" << std::endl;
00664       output << rule["code"] << std::endl;
00665       output << "#endif" << std::endl;
00666       output << "   }" << std::endl;
00667    }
00668 
00669    //--------------------------------------------------------------------------
00670    static void StrReplace( std::string& proc, const std::string& pat,
00671                            const std::string& tr )
00672    {
00673       // Replace all accurances of given string with other string
00674       std::string::size_type it = 0;
00675       std::string::size_type s  = pat.size();
00676       std::string::size_type tr_len= tr.size();
00677       
00678       if( s == 0 ) return;
00679 
00680       while( 1 ) {
00681          it = proc.find( pat, it );
00682          if( it == std::string::npos )
00683             break;
00684 
00685          proc.replace( it, s, tr );
00686          it += tr_len;
00687       }
00688    }
00689 
00690    //--------------------------------------------------------------------------
00691    void WriteSchemaList( std::list<SchemaRuleMap_t>& rules,
00692                          const std::string& listName, std::ostream& output )
00693    {
00694       // Write schema rules
00695       std::list<SchemaRuleMap_t>::iterator it;
00696       int                                  i = 0;
00697 
00698       //-----------------------------------------------------------------------
00699       // Loop over the rules
00700       //-----------------------------------------------------------------------
00701       for( it = rules.begin(); it != rules.end(); ++it ) {
00702          output << "      rule = &" << listName << "[" << i++;
00703          output << "];" << std::endl;
00704 
00705          //--------------------------------------------------------------------
00706          // Write down the mandatory fields
00707          //--------------------------------------------------------------------
00708          output << "      rule->fSourceClass = \"" << (*it)["sourceClass"];
00709          output << "\";" << std::endl;
00710 
00711          if( it->find( "target" ) != it->end() ) {
00712             output << "      rule->fTarget      = \"" << (*it)["target"];
00713             output << "\";" << std::endl;
00714          }
00715 
00716          if( it->find( "source" ) != it->end() ) {
00717             output << "      rule->fSource      = \"" << (*it)["source"];
00718             output << "\";" << std::endl;
00719          }
00720 
00721          //--------------------------------------------------------------------
00722          // Deal with nonmandatory keys
00723          //--------------------------------------------------------------------
00724          if( it->find( "funcname" ) != it->end() ) {
00725             std::string code = (*it)["code"];
00726             StrReplace( code, "\n", "\\n" );
00727             StrReplace( code, "\"", "\\\"");
00728 
00729             output << "      rule->fFunctionPtr = (void *)G__func2void( ";
00730             output << (*it)["funcname"] << ");" << std::endl;
00731             output << "      rule->fCode        = \"" << code;
00732             output << "\";" << std::endl;
00733          }
00734  
00735          if( it->find( "version" ) != it->end() ) {
00736             output << "      rule->fVersion     = \"" << (*it)["version"];
00737             output << "\";" << std::endl;
00738          }
00739 
00740          if( it->find( "checksum" ) != it->end() ) {
00741             output << "      rule->fChecksum    = \"" << (*it)["checksum"];
00742             output << "\";" << std::endl;
00743          }
00744 
00745          if( it->find( "embed" ) != it->end() ) {
00746             output << "      rule->fEmbed       = " <<  (*it)["embed"];
00747             output << ";" << std::endl;
00748          }
00749 
00750          if( it->find( "include" ) != it->end() ) {
00751             output << "      rule->fInclude     = \"" << (*it)["include"];
00752             output << "\";" << std::endl;
00753          }
00754 
00755          if( it->find( "attributes" ) != it->end() ) {
00756             output << "      rule->fAttributes   = \"" << (*it)["attributes"];
00757             output << "\";" << std::endl;
00758          }
00759       }
00760    }
00761 
00762    //--------------------------------------------------------------------------
00763    void GetRuleIncludes( std::list<std::string> &result )
00764    {
00765       // Get the list of includes specified in the shema rules
00766       std::list<std::string>               tmp;
00767       std::list<SchemaRuleMap_t>::iterator rule;
00768       SchemaRuleMap_t::iterator            attr;
00769       SchemaRuleClassMap_t::iterator       it;
00770 
00771       //-----------------------------------------------------------------------
00772       // Processing read rules
00773       //-----------------------------------------------------------------------
00774       for( it = G__ReadRules.begin(); it != G__ReadRules.end(); ++it ) {
00775          for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
00776             attr = rule->find( "include" );
00777             if( attr == rule->end() ) continue;
00778             TSchemaRuleProcessor::SplitList( attr->second, tmp );
00779             result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
00780          }
00781       }
00782 
00783       //-----------------------------------------------------------------------
00784       // Processing read raw rules
00785       //-----------------------------------------------------------------------
00786       for( it = G__ReadRawRules.begin(); it != G__ReadRawRules.end(); ++it ) {
00787          for( rule = it->second.begin(); rule != it->second.end(); ++rule ) {
00788             attr = rule->find( "include" );
00789             if( attr == rule->end() ) continue;
00790             TSchemaRuleProcessor::SplitList( attr->second, tmp );
00791             result.splice( result.begin(), tmp, tmp.begin(), tmp.end() );
00792          }
00793       }
00794 
00795       //-----------------------------------------------------------------------
00796       // Removing duplicates
00797       //-----------------------------------------------------------------------
00798       result.sort();
00799       result.unique();
00800    }
00801 
00802    //--------------------------------------------------------------------------
00803    void ProcessReadPragma( char* args )
00804    {
00805       // I am being called when a read pragma is encountered
00806 
00807       //-----------------------------------------------------------------------
00808       // Parse the rule and check it's validity
00809       //-----------------------------------------------------------------------
00810       std::map<std::string, std::string> rule;
00811       std::string error_string;
00812       if( !ParseRule( args, rule, error_string ) ) {
00813          std::cout << error_string << '\n';
00814          std::cout << "The rule has been omited!" << std::endl;
00815          return;
00816       }
00817 
00818       //-----------------------------------------------------------------------
00819       // Append the rule to the list
00820       //-----------------------------------------------------------------------
00821       SchemaRuleClassMap_t::iterator it;
00822       std::string                    targetClass = rule["targetClass"];
00823       it = G__ReadRules.find( targetClass );
00824       if( it == G__ReadRules.end() ) {
00825          std::list<SchemaRuleMap_t> lst;
00826          lst.push_back( rule );
00827          G__ReadRules[targetClass] = lst;
00828       }
00829       else
00830          it->second.push_back( rule );
00831    }
00832 
00833    //--------------------------------------------------------------------------
00834    void ProcessReadRawPragma( char* args )
00835    {
00836       // I am being called then a readraw pragma is encountered
00837 
00838       //-----------------------------------------------------------------------
00839       // Parse the rule and check it's validity
00840       //-----------------------------------------------------------------------
00841       std::map<std::string, std::string> rule;
00842       std::string error_string;
00843       if( !ParseRule( args, rule, error_string ) ) {
00844          std::cout << error_string << '\n';
00845          std::cout << "The rule has been omited!" << std::endl;
00846          return;
00847       }
00848 
00849       //-----------------------------------------------------------------------
00850       // Append the rule to the list
00851       //-----------------------------------------------------------------------
00852       SchemaRuleClassMap_t::iterator it;
00853       std::string                    targetClass = rule["targetClass"];
00854       it = G__ReadRawRules.find( targetClass );
00855       if( it == G__ReadRawRules.end() ) {
00856          std::list<SchemaRuleMap_t> lst;
00857          lst.push_back( rule );
00858          G__ReadRawRules[targetClass] = lst;
00859       }
00860       else
00861          it->second.push_back( rule );
00862    }
00863    
00864    
00865 }

Generated on Tue Jul 5 14:11:56 2011 for ROOT_528-00b_version by  doxygen 1.5.1