source: trunk/CLHEP/src/ZMinput.cc@ 17

Last change on this file since 17 was 4, checked in by Pavel Demin, 16 years ago

first commit

File size: 8.1 KB
Line 
1#include "CLHEP/Vector/defs.h"
2
3#include <cctype>
4#include <iostream>
5
6namespace {
7
8bool eatwhitespace ( std::istream & is ) {
9 // Will discard whitespace until it either encounters EOF or bad input
10 // (in which case it will return false) or it hits a non-whitespace.
11 // Will put that non whitespace character back so that after this routine
12 // returns true, is.get(c) should always work.
13 // If eatwhitespace returns false, is will always be in a fail or bad state.
14 char c;
15 bool avail = false; // avail stays false until we know there is a nonwhite
16 // character available.
17 while ( is.get(c) ) {
18 if ( !isspace(c) ) {
19 is.putback(c);
20 avail = true;
21 break;
22 }
23 }
24 return avail;
25}
26
27void fouledup() {
28 std::cerr << "istream mysteriously lost a putback character!\n";
29}
30
31
32} // end of unnamed namespace
33
34
35namespace CLHEP {
36
37
38void ZMinput3doubles ( std::istream & is, const char * type,
39 double & x, double & y, double & z ) {
40
41// Accepted formats are
42// x y z
43// x, y, z (each comma is optional, and whitespace ignored if comma present)
44// ( x, y, z ) (commas optional)
45
46 char c;
47 bool parenthesis = false;
48
49 if ( !eatwhitespace(is) ) {
50 std::cerr << "istream ended before trying to input " << type << "\n";
51 return;
52 }
53
54 if ( !is.get(c) ) { fouledup(); return; }
55 if ( c == '(' ) {
56 parenthesis = true;
57 if ( !eatwhitespace(is) ) {
58 std::cerr << "istream ended after ( trying to input " << type << "\n";
59 return;
60 }
61 } else {
62 is.putback(c);
63 }
64
65 // At this point, parenthesis or not, the next item read is supposed to
66 // be the number x.
67
68 if (!(is >> x)) {
69 std::cerr << "Could not read first value in input of " << type << "\n";
70 return;
71 }
72
73 if ( !eatwhitespace(is) ) {
74 std::cerr << "istream ended before second value of " << type << "\n";
75 return;
76 }
77
78 if ( !is.get(c) ) { fouledup(); return; }
79 if ( c == ',' ) {
80 if ( !eatwhitespace(is) ) {
81 std::cerr << "istream ended ater one value and comma in "
82 << type << "\n";
83 return;
84 }
85 } else {
86 is.putback(c);
87 }
88
89 // At this point, comma or not, the next item read is supposed to
90 // be the number y.
91
92 if (!(is >> y)) {
93 std::cerr << "Could not read second value in input of " << type << "\n";
94 return;
95 }
96
97 if ( !eatwhitespace(is) ) {
98 std::cerr << "istream ended before third value of " << type << "\n";
99 return;
100 }
101
102 if ( !is.get(c) ) { fouledup(); return; }
103 if ( c == ',' ) {
104 if ( !eatwhitespace(is) ) {
105 std::cerr << "istream ended ater two values and comma in "
106 << type << "\n";
107 return;
108 }
109 } else {
110 is.putback(c);
111 }
112
113 // At this point, comma or not, the next item read is supposed to
114 // be the number z.
115
116 if (!(is >> z)) {
117 std::cerr << "Could not read third value in input of " << type << "\n";
118 return;
119 }
120
121 // Finally, check for the closing parenthesis if there was an open paren.
122
123 if (parenthesis) {
124 if ( !eatwhitespace(is) ) {
125 std::cerr << "No closing parenthesis in input of " << type << "\n";
126 return;
127 }
128 if ( !is.get(c) ) { fouledup(); return; }
129 if ( c != ')' ) {
130 std::cerr << "Missing closing parenthesis in input of "
131 << type << "\n";
132 // Now a trick to do (as nearly as we can) what
133 // is.putback(c); is.setstate(std::ios_base::failbit);
134 // would do (because using ios_base will confuse old CLHEP compilers):
135 if ( isdigit(c) || (c=='-') || (c=='+') ) {
136 is.putback('@');
137 } else {
138 is.putback('c');
139 }
140 int m;
141 is >> m; // This fails, leaving the state bad, and the istream
142 // otherwise unchanged, except if the next char might
143 // have started a valid int, it turns to @
144 return;
145 }
146 }
147
148 return;
149
150}
151
152
153
154void ZMinputAxisAngle ( std::istream & is,
155 double & x, double & y, double & z,
156 double & delta ) {
157// Accepted formats are
158// parenthesis optional, then
159// any acceptable format for a Hep3Vector, then
160// optional comma, then
161// delta, then
162// close parenthesis if opened at start.
163//
164// But if there is an open parenthesis, it must be for the overall
165// object. That is, if the axis has parentheses, the form must be
166// ( (x,y,z) , delta )
167
168 char c;
169 bool parenthesis = false;
170
171 if ( !eatwhitespace(is) ) {
172 std::cerr << "istream ended before trying to input AxisAngle \n";
173 return;
174 }
175
176 if ( !is.get(c) ) { fouledup(); return; }
177 if ( c == '(' ) {
178 parenthesis = true;
179 if ( !eatwhitespace(is) ) {
180 std::cerr << "istream ended after ( trying to input AxisAngle \n";
181 return;
182 }
183 } else {
184 is.putback(c);
185 }
186
187 // At this point, parenthesis or not, the next item read is supposed to
188 // be a valid Hep3Vector axis.
189
190 ZMinput3doubles ( is, "axis of AxisAngle", x, y, z );
191 if (!is) return;
192
193 if ( !eatwhitespace(is) ) {
194 std::cerr << "istream ended before delta of AxisAngle \n";
195 return;
196 }
197
198 if ( !is.get(c) ) { fouledup(); return; }
199 if ( c == ',' ) {
200 if ( !eatwhitespace(is) ) {
201 std::cerr << "istream ended ater axis and comma in AxisAngle \n";
202 return;
203 }
204 } else {
205 is.putback(c);
206 }
207
208 // At this point, comma or not, the next item read is supposed to
209 // be the number delta.
210
211 if (!(is >> delta)) {
212 std::cerr << "Could not delta value in input of AxisAngle \n";
213 return;
214 }
215
216 // Finally, check for the closing parenthesis if there was an open paren.
217
218 if (parenthesis) {
219 if ( !eatwhitespace(is) ) {
220 std::cerr << "No closing parenthesis in input of AxisAngle \n";
221 return;
222 }
223 if ( !is.get(c) ) { fouledup(); return; }
224 if ( c != ')' ) {
225 std::cerr << "Missing closing parenthesis in input of AxisAngle \n";
226 if ( isdigit(c) || (c=='-') || (c=='+') ) {
227 is.putback('@');
228 } else {
229 is.putback('c');
230 }
231 int m;
232 is >> m; // This fails, leaving the state bad.
233 return;
234 }
235 }
236
237 return;
238
239}
240
241
242
243void ZMinput2doubles ( std::istream & is, const char * type,
244 double & x, double & y ) {
245
246// Accepted formats are
247// x y
248// x, y (comma is optional, and whitespace ignored if comma present)
249// ( x, y ) (comma optional)
250
251 char c;
252 bool parenthesis = false;
253
254 if ( !eatwhitespace(is) ) {
255 std::cerr << "istream ended before trying to input " << type << "\n";
256 return;
257 }
258
259 if ( !is.get(c) ) { fouledup(); return; }
260 if ( c == '(' ) {
261 parenthesis = true;
262 if ( !eatwhitespace(is) ) {
263 std::cerr << "istream ended after ( trying to input " << type << "\n";
264 return;
265 }
266 } else {
267 is.putback(c);
268 }
269
270 // At this point, parenthesis or not, the next item read is supposed to
271 // be the number x.
272
273 if (!(is >> x)) {
274 std::cerr << "Could not read first value in input of " << type << "\n";
275 return;
276 }
277
278 if ( !eatwhitespace(is) ) {
279 std::cerr << "istream ended before second value of " << type << "\n";
280 return;
281 }
282
283 if ( !is.get(c) ) { fouledup(); return; }
284 if ( c == ',' ) {
285 if ( !eatwhitespace(is) ) {
286 std::cerr << "istream ended ater one value and comma in "
287 << type << "\n";
288 return;
289 }
290 } else {
291 is.putback(c);
292 }
293
294 // At this point, comma or not, the next item read is supposed to
295 // be the number y.
296
297 if (!(is >> y)) {
298 std::cerr << "Could not read second value in input of " << type << "\n";
299 return;
300 }
301
302 // Finally, check for the closing parenthesis if there was an open paren.
303
304 if (parenthesis) {
305 if ( !eatwhitespace(is) ) {
306 std::cerr << "No closing parenthesis in input of " << type << "\n";
307 return;
308 }
309 if ( !is.get(c) ) { fouledup(); return; }
310 if ( c != ')' ) {
311 std::cerr << "Missing closing parenthesis in input of "
312 << type << "\n";
313 // Now a trick to do (as nearly as we can) what
314 // is.putback(c); is.setstate(std::ios_base::failbit);
315 // would do (because using ios_base will confuse old CLHEP compilers):
316 if ( isdigit(c) || (c=='-') || (c=='+') ) {
317 is.putback('@');
318 } else {
319 is.putback('c');
320 }
321 int m;
322 is >> m; // This fails, leaving the state bad, and the istream
323 // otherwise unchanged, except if the next char might
324 // have started a valid int, it turns to @
325 return;
326 }
327 }
328
329 return;
330
331}
332
333} // namespace CLHEP
Note: See TracBrowser for help on using the repository browser.