ROOT  6.06/09
Reference Guide
TSchemaRuleProcessor.h
Go to the documentation of this file.
1 // @(#)root/core:$Id$
2 // author: Lukasz Janyst <ljanyst@cern.ch>
3 
4 #ifndef ROOT_TSchemaRuleProcessor
5 #define ROOT_TSchemaRuleProcessor
6 
7 #if !defined(__CINT__)
8 // Do no clutter the dictionary (in particular with STL containers)
9 
10 #include <stdlib.h>
11 #include <string>
12 #include <list>
13 #include <utility>
14 #include <cstdlib>
15 #include <iostream>
16 #include "Rtypes.h"
17 
18 #ifndef R__TSCHEMATYPE_H
19 #include "TSchemaType.h"
20 #endif
21 
22 namespace ROOT {
23 namespace Internal {
25  {
26  public:
27  //---------------------------------------------------------------------
28  static void SplitList( const std::string& source,
29  std::list<std::string>& result,
30  char delimiter=',')
31  {
32  // Split the string producing a list of substrings
33 
34  std::string::size_type curr;
35  std::string::size_type last = 0;
36  std::string::size_type size;
37  std::string elem;
38 
39  result.clear();
40 
41  while( last != source.size() ) {
42  curr = source.find( delimiter, last );
43 
44  if( curr == std::string::npos ) {
45  curr = source.size()-1;
46  size = curr-last+1;
47  }
48  else size = curr-last;
49 
50  elem = Trim( source.substr( last, size ) );
51  if( !elem.empty() )
52  result.push_back( elem );
53 
54  last = curr+1;
55  }
56  }
57 
58  static void SplitDeclaration( const std::string& source,
59  std::list<std::pair<ROOT::Internal::TSchemaType,std::string> >& result)
60  {
61  // Split a declaration string producing a list of substrings
62  // Typically we have:
63  // int mem; SomeType mem2; SomeTmp<const key, const value> mem3;
64 
65  std::string::size_type curr;
66  std::string::size_type last = 0;
67  std::string::size_type size;
68  std::string elem;
69  std::string type;
70  std::string dims;
71 
72  result.clear();
73 
74  while( last != source.size() ) {
75  // Split on semi-colons.
76  curr = source.find( ';', last );
77 
78  if( curr == std::string::npos ) {
79  curr = source.size()-1;
80  size = curr-last+1;
81  }
82  else size = curr-last;
83 
84  // Extra spaces.
85  elem = Trim( source.substr( last, size ) );
86  if( !elem.empty() ) {
87  unsigned int level = 0;
88 
89  // Split between the typename and the membername
90  // Take in consideration template names.
91  for(std::string::size_type j=elem.size(); j>0; --j) {
92  std::string::size_type i = j-1;
93  if (elem[i]=='<') { ++level; }
94  else if (elem[i]=='>') { if (level==0) { continue; } ; --level; }
95  else if (level == 0 && isspace(elem[i])) {
96  type = elem.substr( 0, i );
97  // At the first iteration we know we have a space.
98  while( elem[i]=='*' || elem[i]=='&' || isspace(elem[i]) ) {
99  ++i;
100  if (strcmp("const",elem.c_str()+i)==0 && (i+5)>elem.size()
101  && ( elem[i+5]=='*' || elem[i+5]=='&' || isspace(elem[i+5])) ) {
102  i += 5;
103  type += "const ";
104  } else if (elem[i]=='*' || elem[i]=='&') {
105  type += elem[i];
106  }
107  }
108  std::string::size_type endvar = i;
109  while( endvar!=elem.size() && elem[endvar] != '[' ) {
110  ++endvar;
111  }
112  if (endvar != elem.size() ) {
113  dims = Trim( elem.substr(endvar, elem.size()-endvar) );
114  }
115  elem = Trim( elem.substr(i, endvar-i) );
116  break;
117  }
118  }
119  result.push_back( make_pair(ROOT::Internal::TSchemaType(type,dims),elem) );
120  }
121  last = curr+1;
122  }
123  }
124 
125  //---------------------------------------------------------------------
126  static std::string Trim( const std::string& source )
127  {
128  // Trim the whitespaces at the beginning and at the end of
129  // given source string
130 
131  std::string::size_type start, end;
132  for( start = 0; start < source.size(); ++start) {
133  if ( isspace(source[start]) ) {
134  continue;
135  } else if ( source[start] == '\\' && (start+1)<source.size() && (source[start+1]=='\n' || source[start+1]=='\r') ) {
136  ++start;
137  continue;
138  } else {
139  // Not a white space.
140  break;
141  }
142  }
143  if( start == source.size() )
144  return "";
145  for( end = source.size()-1; end > start; --end ) {
146  if ( (source[end]=='\n' || source[end]=='\r') && end > (start+1) && source[end-1] == '\\' ) {
147  --end;
148  continue;
149  } else if ( isspace(source[end]) ) {
150  continue;
151  } else {
152  // Not a white space.
153  break;
154  }
155  }
156  return source.substr( start, end-start+1 );
157  }
158 
159  //---------------------------------------------------------------------
160  static bool ProcessVersion( const std::string& source,
161  std::pair<Int_t, Int_t>& result )
162  {
163  // Check if a version is specified correctly
164  // The result is set the following way:
165  // x : first = x second = x
166  // -x : first = -10 second = x
167  // x-y : first = x second = y
168  // x- : first = x second = 50000
169  // if the given string is invalid (false is returned)
170  // then the state of the result is undefined
171 
172  std::string::size_type hyphenI;
173  std::string first;
174  std::string second;
175 
176  std::string version = Trim( source );
177 
178  if( version.empty() )
179  return false;
180 
181  //------------------------------------------------------------------
182  // Do we have a star?
183  //------------------------------------------------------------------
184  if( version == "*" ) {
185  result.first = -10;
186  result.second = 50000;
187  return true;
188  }
189 
190  //------------------------------------------------------------------
191  // Check if we have a minus somewhere, if not then single version
192  // number was specified
193  //------------------------------------------------------------------
194  hyphenI = version.find( '-' );
195  if( hyphenI == std::string::npos && IsANumber( version ) ) {
196  result.first = result.second = atoi( version.c_str() );
197  return true;
198  }
199 
200  //------------------------------------------------------------------
201  // We start with the hyphen
202  //------------------------------------------------------------------
203  if( hyphenI == 0 ) {
204  second = Trim( version.substr( 1 ) );
205  if( IsANumber( second ) ) {
206  result.first = -10;
207  result.second = atoi( second.c_str() );
208  return true;
209  }
210  }
211 
212  //------------------------------------------------------------------
213  // We end with the hyphen
214  //------------------------------------------------------------------
215  if( hyphenI == version.size()-1 ) {
216  first = Trim( version.substr( 0, version.size()-1 ) );
217  if( IsANumber( first ) ) {
218  result.first = atoi( first.c_str() );
219  result.second = 50000;
220  return true;
221  }
222  }
223 
224  //------------------------------------------------------------------
225  // We have the hyphen somewhere in the middle
226  //------------------------------------------------------------------
227  first = Trim( version.substr( 0, hyphenI ) );
228  second = Trim( version.substr( hyphenI+1, version.size()-hyphenI-1 ) );
229  if( IsANumber( first ) && IsANumber( second ) ) {
230  result.first = atoi( first.c_str() );
231  result.second = atoi( second.c_str() );
232  return true;
233  }
234 
235  return false;
236  }
237 
238  //---------------------------------------------------------------------
239  static bool IsANumber( const std::string& source )
240  {
241  // check if given string si consisted of digits
242 
243  if( source.empty() )
244  return false;
245 
246  std::string::size_type i;
247  for( i = 0; i < source.size(); ++i )
248  if( !isdigit( source[i] ) )
249  return false;
250  return true;
251  }
252  };
253 } // namespace Internal
254 } // namespace ROOT
255 #endif // defined(__CINT__)
256 
257 #endif // ROOT_TSchemaRuleProcessor
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
static bool IsANumber(const std::string &source)
static void SplitDeclaration(const std::string &source, std::list< std::pair< ROOT::Internal::TSchemaType, std::string > > &result)
static void SplitList(const std::string &source, std::list< std::string > &result, char delimiter=',')
int type
Definition: TGX11.cxx:120
double result[121]
static std::string Trim(const std::string &source)
static bool ProcessVersion(const std::string &source, std::pair< Int_t, Int_t > &result)