Geant4 Cross Reference |
1 // -*- C++ -*- 2 // --------------------------------------------------------------------------- 3 // 4 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 5 // 6 //------------------------------------------------------------- 7 8 #include <cctype> 9 #include <iostream> 10 11 namespace { 12 13 bool eatwhitespace ( std::istream & is ) { 14 // Will discard whitespace until it either encounters EOF or bad input 15 // (in which case it will return false) or it hits a non-whitespace. 16 // Will put that non whitespace character back so that after this routine 17 // returns true, is.get(c) should always work. 18 // If eatwhitespace returns false, is will always be in a fail or bad state. 19 char c; 20 bool avail = false; // avail stays false until we know there is a nonwhite 21 // character available. 22 while ( is.get(c) ) { 23 if ( !isspace(c) ) { 24 is.putback(c); 25 avail = true; 26 break; 27 } 28 } 29 return avail; 30 } 31 32 void fouledup() { 33 std::cerr << "istream mysteriously lost a putback character!\n"; 34 } 35 36 37 } // end of unnamed namespace 38 39 40 namespace CLHEP { 41 42 void ZMinput3doubles ( std::istream & is, const char * type, 43 double & x, double & y, double & z ) { 44 45 // Accepted formats are 46 // x y z 47 // x, y, z (each comma is optional, and whitespace ignored if comma present) 48 // ( x, y, z ) (commas optional) 49 50 char c; 51 bool parenthesis = false; 52 53 if ( !eatwhitespace(is) ) { 54 std::cerr << "istream ended before trying to input " << type << "\n"; 55 return; 56 } 57 58 if ( !is.get(c) ) { fouledup(); return; } 59 if ( c == '(' ) { 60 parenthesis = true; 61 if ( !eatwhitespace(is) ) { 62 std::cerr << "istream ended after ( trying to input " << type << "\n"; 63 return; 64 } 65 } else { 66 is.putback(c); 67 } 68 69 // At this point, parenthesis or not, the next item read is supposed to 70 // be the number x. 71 72 if (!(is >> x)) { 73 std::cerr << "Could not read first value in input of " << type << "\n"; 74 return; 75 } 76 77 if ( !eatwhitespace(is) ) { 78 std::cerr << "istream ended before second value of " << type << "\n"; 79 return; 80 } 81 82 if ( !is.get(c) ) { fouledup(); return; } 83 if ( c == ',' ) { 84 if ( !eatwhitespace(is) ) { 85 std::cerr << "istream ended ater one value and comma in " 86 << type << "\n"; 87 return; 88 } 89 } else { 90 is.putback(c); 91 } 92 93 // At this point, comma or not, the next item read is supposed to 94 // be the number y. 95 96 if (!(is >> y)) { 97 std::cerr << "Could not read second value in input of " << type << "\n"; 98 return; 99 } 100 101 if ( !eatwhitespace(is) ) { 102 std::cerr << "istream ended before third value of " << type << "\n"; 103 return; 104 } 105 106 if ( !is.get(c) ) { fouledup(); return; } 107 if ( c == ',' ) { 108 if ( !eatwhitespace(is) ) { 109 std::cerr << "istream ended ater two values and comma in " 110 << type << "\n"; 111 return; 112 } 113 } else { 114 is.putback(c); 115 } 116 117 // At this point, comma or not, the next item read is supposed to 118 // be the number z. 119 120 if (!(is >> z)) { 121 std::cerr << "Could not read third value in input of " << type << "\n"; 122 return; 123 } 124 125 // Finally, check for the closing parenthesis if there was an open paren. 126 127 if (parenthesis) { 128 if ( !eatwhitespace(is) ) { 129 std::cerr << "No closing parenthesis in input of " << type << "\n"; 130 return; 131 } 132 if ( !is.get(c) ) { fouledup(); return; } 133 if ( c != ')' ) { 134 std::cerr << "Missing closing parenthesis in input of " 135 << type << "\n"; 136 // Now a trick to do (as nearly as we can) what 137 // is.putback(c); is.setstate(std::ios_base::failbit); 138 // would do (because using ios_base will confuse old CLHEP compilers): 139 if ( isdigit(c) || (c=='-') || (c=='+') ) { 140 is.putback('@'); 141 } else { 142 is.putback('c'); 143 } 144 int m; 145 is >> m; // This fails, leaving the state bad, and the istream 146 // otherwise unchanged, except if the next char might 147 // have started a valid int, it turns to @ 148 return; 149 } 150 } 151 152 return; 153 154 } 155 156 void ZMinputAxisAngle ( std::istream & is, 157 double & x, double & y, double & z, 158 double & delta ) { 159 // Accepted formats are 160 // parenthesis optional, then 161 // any acceptable format for a Hep3Vector, then 162 // optional comma, then 163 // delta, then 164 // close parenthesis if opened at start. 165 // 166 // But if there is an open parenthesis, it must be for the overall 167 // object. That is, if the axis has parentheses, the form must be 168 // ( (x,y,z) , delta ) 169 170 char c; 171 bool parenthesis = false; 172 173 if ( !eatwhitespace(is) ) { 174 std::cerr << "istream ended before trying to input AxisAngle \n"; 175 return; 176 } 177 178 if ( !is.get(c) ) { fouledup(); return; } 179 if ( c == '(' ) { 180 parenthesis = true; 181 if ( !eatwhitespace(is) ) { 182 std::cerr << "istream ended after ( trying to input AxisAngle \n"; 183 return; 184 } 185 } else { 186 is.putback(c); 187 } 188 189 // At this point, parenthesis or not, the next item read is supposed to 190 // be a valid Hep3Vector axis. 191 192 ZMinput3doubles ( is, "axis of AxisAngle", x, y, z ); 193 if (!is) return; 194 195 if ( !eatwhitespace(is) ) { 196 std::cerr << "istream ended before delta of AxisAngle \n"; 197 return; 198 } 199 200 if ( !is.get(c) ) { fouledup(); return; } 201 if ( c == ',' ) { 202 if ( !eatwhitespace(is) ) { 203 std::cerr << "istream ended ater axis and comma in AxisAngle \n"; 204 return; 205 } 206 } else { 207 is.putback(c); 208 } 209 210 // At this point, comma or not, the next item read is supposed to 211 // be the number delta. 212 213 if (!(is >> delta)) { 214 std::cerr << "Could not delta value in input of AxisAngle \n"; 215 return; 216 } 217 218 // Finally, check for the closing parenthesis if there was an open paren. 219 220 if (parenthesis) { 221 if ( !eatwhitespace(is) ) { 222 std::cerr << "No closing parenthesis in input of AxisAngle \n"; 223 return; 224 } 225 if ( !is.get(c) ) { fouledup(); return; } 226 if ( c != ')' ) { 227 std::cerr << "Missing closing parenthesis in input of AxisAngle \n"; 228 if ( isdigit(c) || (c=='-') || (c=='+') ) { 229 is.putback('@'); 230 } else { 231 is.putback('c'); 232 } 233 int m; 234 is >> m; // This fails, leaving the state bad. 235 return; 236 } 237 } 238 239 return; 240 241 } 242 243 void 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 334