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