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