Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaArrayString.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 20-Aug-2001
2
3
5//
6// THaArrayString
7//
8// This class parses the array subscript(s) of variable.
9// In the trivial case of a scalar, it simply stores the variable name.
10// Otherwise, it extracts the individual subscript(s) and number of
11// dimensions.
12//
13// Example:
14//
15// THaArrayString txt("x[7,4]");
16//
17// gives
18// fName = "x"
19// fNdim = 2
20// fDim = [ 7, 4 ]
21// fLen = 7*4 = 28
22// fStatus = 0
23//
24// THaArrayStrings are used in particular by THaFormula and THaVar.
25//
27
28#include <iostream>
29#include <cstring>
30#include <cstdlib>
31#include "THaArrayString.h"
32
33using namespace std;
34
35//_____________________________________________________________________________
37 : fName(rhs.fName), fNdim(rhs.fNdim), fLen(rhs.fLen), fStatus(rhs.fStatus)
38{
39 // Copy constructor
40
41 if( fNdim > kMaxA ) {
42 fDim = new Int_t[fNdim];
43 for( Int_t i = 0; i<fNdim; i++ )
44 fDim[i] = rhs.fDim[i];
45 } else {
46 for( Int_t i = 0; i<fNdim; i++ )
47 fDimA[i] = rhs.fDimA[i];
48 }
49}
50
51//_____________________________________________________________________________
53{
54 // Assignment operator
55
56 if( this != &rhs ) {
57 if( fNdim>kMaxA )
58 delete [] fDim;
59 fName = rhs.fName;
60 fNdim = rhs.fNdim;
61 fLen = rhs.fLen;
62 fStatus = rhs.fStatus;
63 if( fNdim>kMaxA ) {
64 fDim = new Int_t[fNdim];
65 for( Int_t i = 0; i<fNdim; i++ )
66 fDim[i] = rhs.fDim[i];
67 } else {
68 for( Int_t i = 0; i<fNdim; i++ )
69 fDimA[i] = rhs.fDimA[i];
70 }
71 }
72 return *this;
73}
74
75//_____________________________________________________________________________
76Int_t THaArrayString::Parse( const char* string )
77{
78 // Parse the given string for array syntax.
79 // For multidimensional arrays, both C-style and comma-separated subscripts
80 // are supported.
81 //
82 // Examples of legal expressions:
83 //
84 // "x" scalar "x"
85 // "x[2]" 1-d array "x" of size 2
86 // "x[2][3]" 2-d array "x" of size 2x3=6
87 // "x[2,3]" same 2-d array
88 // "x[2][3][4]" 3-d array "x" of size 2x3x4=24
89 //
90 // Results are stored in this object and can be retrieved using
91 // GetName(), GetNdim(), GetDim(), and GetLen().
92 //
93 // The maximum length of the input string is 255 characters.
94 //
95 // Returns 0 if ok, or EStatus error code otherwise (see header).
96
97 static const size_t MAXLEN = 255;
98 bool changed = false, dyn = false;
99 char *str = nullptr, *s, *t;
100 const char *cs;
101 size_t len;
102 Int_t ncomma = 0, nl = 0, nr = 0;
103 Int_t j;
104 Long64_t llen;
105
106 if( !string || !*string ) {
107 // No string or empty string?
108 // If already initialized, just do nothing. Otherwise, we are
109 // being called from the constructor, so parse fName.
110 if( fLen != -1 ) goto ok;
111 string = fName.Data();
112 len = fName.Length();
113 } else {
114 len = strlen(string);
115 changed = true;
116 }
117 if( len > MAXLEN ) goto toolong;
118
119 // Copy string to local buffer and get rid of all whitespace
120
121 str = new char[ len+1 ];
122 t = str;
123 cs = string;
124 while( *cs ) {
125 if( *cs != ' ' && *cs != '\t' )
126 *(t++) = *cs;
127 else
128 changed = true;
129 cs++;
130 }
131 *t = 0;
132 if( t == str ) goto notinit;
133
134 // Extract name, i.e. everything up to the first bracket.
135 // Check for illegal characters in the name.
136
137 t = str;
138 while( *t && *t != '[' ) {
139 if( *t != ',' && *t != ']' && *t != '(' && *t != ')' )
140 t++;
141 else
142 goto illegalchars;
143 }
144
145 // No name? Error.
146 if( t == str ) goto badsyntax;
147
148 if( fNdim>kMaxA )
149 delete [] fDim;
150 fNdim = 0; fLen = 1;
151
152 // No bracket found? No array, we're done.
153 if( !*t ) {
154 if( changed )
155 fName = str;
156 goto ok;
157 }
158
159 // We have a bracket! Save its position and start parsing the subscripts.
160
161 s = t;
162
163 // From here on, we may only have digits, commas, and brackets.
164 // While we check, we count how many separators there are.
165
166 while( *t ) {
167 switch( *t ) {
168 case ',':
169 ncomma++; break;
170 case '[':
171 nl++; break;
172 case ']':
173 nr++; break;
174 default:
175 if ( *t < '0' || *t > '9' )
176 goto illegalchars;
177 break;
178 }
179 t++;
180 }
181
182 // Number of brackets must match, only one bracket pair for comma
183 // syntax, and last character must be a closing bracket.
184 if( nl != nr || (ncomma && nl>1) || *(t-1) != ']' )
185 goto badsyntax;
186
187 *s = 0; // Terminate name string
188 t = s+1;
189 if( ncomma )
190 fNdim = ncomma+1;
191 else
192 fNdim = nl;
193 if( fNdim>kMaxA ) {
194 dyn = true;
195 fDim = new Int_t[ fNdim ];
196 }
197
198 for( int i=0; i<fNdim; i++ ) {
199 s = t;
200 while ( *t && *t != ',' && *t != ']' ) {
201 // Two left brackets in a row? Oops.
202 if( *t == '[' ) goto badsyntax;
203 t++;
204 }
205
206 // Unexpected end of string or no string between commas?
207 if( !*t || t == s ) goto badsyntax;
208
209 // Terminate subscript string
210 *t = 0;
211
212 // Ok, we got a number.
213 j = atoi( s );
214 llen = static_cast<Long64_t>(fLen) * static_cast<Long64_t>(j);
215 if( llen > kMaxInt ) goto toolarge;
216 if( dyn ) fDim[i] = j;
217 else fDimA[i] = j;
218 fLen = llen;
219
220 t++;
221
222 // Is there anything between a right and a left bracket?
223 if( !ncomma && *t ) {
224 if( *t == '[' )
225 t++;
226 else
227 goto badsyntax;
228 }
229 }
230
231 fName = str;
232 goto ok;
233
234 badsyntax:
236 goto cleanup;
237
238 illegalchars:
240 goto cleanup;
241
242 toolarge:
244 goto cleanup;
245
246 toolong:
248 goto cleanup;
249
250 notinit:
252 goto cleanup;
253
254 ok:
255 fStatus = kOK;
256
257 cleanup:
258 delete [] str;
259
260 return fStatus;
261}
262
263//_____________________________________________________________________________
264static void WriteDims( Int_t ndim, const Int_t* dims )
265{
266 for( Int_t i = 0; i<ndim; i++ ) {
267 cout << dims[i];
268 if( i+1<ndim )
269 cout << ",";
270 }
271}
272
273//_____________________________________________________________________________
274void THaArrayString::Print( Option_t* option ) const
275{
276 // Print the name and array dimension(s), if any.
277 // If option == "dimonly", only print the dimensions, without square brackets.
278
279 TString opt(option);
280 if( !opt.Contains("dimonly") ) {
281 cout << fName ;
282 if( fNdim > 0 ) {
283 cout << "[";
284 if( fNdim > kMaxA ) WriteDims(fNdim,fDim);
285 else WriteDims(fNdim,fDimA);
286 cout << "]";
287 }
288 cout << endl;
289 }
290 else {
291 if( fNdim > kMaxA ) WriteDims(fNdim,fDim);
292 else WriteDims(fNdim,fDimA);
293 }
294}
295//_____________________________________________________________________________
int Int_t
const Int_t kMaxInt
const char Option_t
Option_t Option_t option
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 UChar_t len
static void WriteDims(Int_t ndim, const Int_t *dims)
virtual void Print(Option_t *opt="") const
Int_t fDimA[kMaxA]
static const Int_t kMaxA
virtual Int_t Parse(const char *string="")
THaArrayString & operator=(const THaArrayString &)
Ssiz_t Length() const
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
long long Long64_t
STL namespace.
ClassImp(TPyArg)