00001
00002
00003
00004 #ifndef ROOT_TSchemaRuleProcessor
00005 #define ROOT_TSchemaRuleProcessor
00006
00007 #if !defined(__CINT__)
00008
00009
00010 #include <stdlib.h>
00011 #include <string>
00012 #include <list>
00013 #include <utility>
00014 #include <cstdlib>
00015 #include <iostream>
00016 #include "Rtypes.h"
00017
00018 #ifndef R__TSCHEMATYPE_H
00019 #include "TSchemaType.h"
00020 #endif
00021
00022 namespace ROOT
00023 {
00024 class TSchemaRuleProcessor
00025 {
00026 public:
00027
00028 static void SplitList( const std::string& source,
00029 std::list<std::string>& result,
00030 char delimiter=',')
00031 {
00032
00033
00034 std::string::size_type curr;
00035 std::string::size_type last = 0;
00036 std::string::size_type size;
00037 std::string elem;
00038
00039 result.clear();
00040
00041 while( last != source.size() ) {
00042 curr = source.find( delimiter, last );
00043
00044 if( curr == std::string::npos ) {
00045 curr = source.size()-1;
00046 size = curr-last+1;
00047 }
00048 else size = curr-last;
00049
00050 elem = Trim( source.substr( last, size ) );
00051 if( !elem.empty() )
00052 result.push_back( elem );
00053
00054 last = curr+1;
00055 }
00056 }
00057
00058 static void SplitDeclaration( const std::string& source,
00059 std::list<std::pair<ROOT::TSchemaType,std::string> >& result)
00060 {
00061
00062
00063
00064
00065 std::string::size_type curr;
00066 std::string::size_type last = 0;
00067 std::string::size_type size;
00068 std::string elem;
00069 std::string type;
00070 std::string dims;
00071
00072 result.clear();
00073
00074 while( last != source.size() ) {
00075
00076 curr = source.find( ';', last );
00077
00078 if( curr == std::string::npos ) {
00079 curr = source.size()-1;
00080 size = curr-last+1;
00081 }
00082 else size = curr-last;
00083
00084
00085 elem = Trim( source.substr( last, size ) );
00086 if( !elem.empty() ) {
00087 unsigned int level = 0;
00088
00089
00090
00091 for(std::string::size_type i=0; i<elem.size(); ++i) {
00092 if (elem[i]=='<') { ++level; }
00093 else if (elem[i]=='>') { --level; }
00094 else if (level == 0 && isspace(elem[i])) {
00095 type = elem.substr( 0, i );
00096
00097 while( elem[i]=='*' || elem[i]=='&' || isspace(elem[i]) ) {
00098 ++i;
00099 if (strcmp("const",elem.c_str()+i)==0 && (i+5)>elem.size()
00100 && ( elem[i+5]=='*' || elem[i+5]=='&' || isspace(elem[i+5])) ) {
00101 i += 5;
00102 type += "const ";
00103 } else if (elem[i]=='*' || elem[i]=='&') {
00104 type += elem[i];
00105 }
00106 }
00107 std::string::size_type endvar = i;
00108 while( endvar!=elem.size() && elem[endvar] != '[' ) {
00109 ++endvar;
00110 }
00111 if (endvar != elem.size() ) {
00112 dims = Trim( elem.substr(endvar, elem.size()-endvar) );
00113 }
00114 elem = Trim( elem.substr(i, endvar-i) );
00115 break;
00116 }
00117 }
00118 result.push_back( make_pair(ROOT::TSchemaType(type,dims),elem) );
00119 }
00120 last = curr+1;
00121 }
00122 }
00123
00124
00125 static std::string Trim( const std::string& source, char character = ' ' )
00126 {
00127
00128
00129
00130 std::string::size_type start, end;
00131 for( start = 0; start < source.size() && isspace(source[start]); ++start) {}
00132 if( start == source.size() )
00133 return "";
00134 for( end = source.size()-1; end > start && source[end] == character; --end ) ;
00135 return source.substr( start, end-start+1 );
00136 }
00137
00138
00139 static bool ProcessVersion( const std::string& source,
00140 std::pair<Int_t, Int_t>& result )
00141 {
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 std::string::size_type hyphenI;
00152 std::string first;
00153 std::string second;
00154
00155 std::string version = Trim( source );
00156
00157 if( version.empty() )
00158 return false;
00159
00160
00161
00162
00163 if( version == "*" ) {
00164 result.first = -10;
00165 result.second = 50000;
00166 return true;
00167 }
00168
00169
00170
00171
00172
00173 hyphenI = version.find( '-' );
00174 if( hyphenI == std::string::npos && IsANumber( version ) ) {
00175 result.first = result.second = atoi( version.c_str() );
00176 return true;
00177 }
00178
00179
00180
00181
00182 if( hyphenI == 0 ) {
00183 second = Trim( version.substr( 1 ) );
00184 if( IsANumber( second ) ) {
00185 result.first = -10;
00186 result.second = atoi( second.c_str() );
00187 return true;
00188 }
00189 }
00190
00191
00192
00193
00194 if( hyphenI == version.size()-1 ) {
00195 first = Trim( version.substr( 0, version.size()-1 ) );
00196 if( IsANumber( first ) ) {
00197 result.first = atoi( first.c_str() );
00198 result.second = 50000;
00199 return true;
00200 }
00201 }
00202
00203
00204
00205
00206 first = Trim( version.substr( 0, hyphenI ) );
00207 second = Trim( version.substr( hyphenI+1, version.size()-hyphenI-1 ) );
00208 if( IsANumber( first ) && IsANumber( second ) ) {
00209 result.first = atoi( first.c_str() );
00210 result.second = atoi( second.c_str() );
00211 return true;
00212 }
00213
00214 return false;
00215 }
00216
00217
00218 static bool IsANumber( const std::string& source )
00219 {
00220
00221
00222 if( source.empty() )
00223 return false;
00224
00225 std::string::size_type i;
00226 for( i = 0; i < source.size(); ++i )
00227 if( !isdigit( source[i] ) )
00228 return false;
00229 return true;
00230 }
00231 };
00232 }
00233 #endif // defined(__CINT__)
00234
00235 #endif // ROOT_TSchemaRuleProcessor