Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4UIparsing 27 // 28 // Utilities for parsing/checking inputs in G4UIparameter/G4UIcommand 29 30 #ifndef G4UIparsing_hh 31 #define G4UIparsing_hh 1 32 33 #include "G4UItokenNum.hh" 34 #include "globals.hh" 35 36 #include <cctype> 37 38 class G4UIparameter; 39 class G4UIcommand; 40 41 namespace G4UIparsing 42 { 43 // Convert G4String to value of type T 44 template<typename T> 45 inline T StoT(const G4String& s) 46 { 47 T vl; 48 std::istringstream is(s); 49 is >> vl; 50 return vl; 51 } 52 53 // Convert value of type T to G4String 54 template<typename T> 55 inline G4String TtoS(T value) 56 { 57 std::ostringstream os; 58 os << value; 59 return os.str(); 60 } 61 62 // Check if the value is within the range of (long) int 63 inline G4bool ChkMax(const char* str, short maxDigits) 64 { 65 if(maxDigits > 10) { 66 // long int assumed 67 auto tmpval = std::stoll(str); 68 if(tmpval > LONG_MAX || tmpval < LONG_MIN) { 69 G4cerr << "input string '" << str << "' out-of-range for conversion to 'long int' value" << G4endl; 70 return false; 71 } 72 } else { 73 // int assumed 74 auto tmpval = std::stol(str); 75 if(tmpval > INT_MAX || tmpval < INT_MIN) { 76 G4cerr << "input string '" << str << "' out-of-range for conversion to 'int' value" << G4endl; 77 return false; 78 } 79 } 80 return true; 81 } 82 83 // Return true if `str` parses to an integral number no more than `maxDigit` digits 84 inline G4bool IsInt(const char* str, short maxDigits) 85 { 86 const char* p = str; 87 G4int length = 0; 88 if (*p == '+' || *p == '-') { 89 ++p; 90 } 91 if (isdigit((G4int)(*p)) != 0) { 92 while (isdigit((G4int)(*p)) != 0) { 93 ++p; 94 ++length; 95 } 96 if (*p == '\0') { 97 if (length > maxDigits) { 98 G4cerr << "digit length exceeds" << G4endl; 99 return false; 100 } 101 return ChkMax(str,maxDigits); 102 } 103 } 104 return false; 105 } 106 107 // Return true if `str` parses to an exponent 108 // 109 // A valid exponent is an integer of no more than 7 digits 110 inline G4bool ExpectExponent(const char* str) 111 { 112 return IsInt(str, 7); 113 } 114 115 inline G4bool IsDouble(const char* str) 116 { 117 const char* p = str; 118 switch (*p) { 119 case '+': 120 case '-': 121 ++p; 122 if (isdigit(*p) != 0) { 123 while (isdigit((G4int)(*p)) != 0) { 124 ++p; 125 } 126 switch (*p) { 127 case '\0': 128 return true; // break; 129 case 'E': 130 case 'e': 131 return ExpectExponent(++p); // break; 132 case '.': 133 ++p; 134 if (*p == '\0') { 135 return true; 136 } 137 if (*p == 'e' || *p == 'E') { 138 return ExpectExponent(++p); 139 } 140 if (isdigit(*p) != 0) { 141 while (isdigit((G4int)(*p)) != 0) { 142 ++p; 143 } 144 if (*p == '\0') { 145 return true; 146 } 147 if (*p == 'e' || *p == 'E') { 148 return ExpectExponent(++p); 149 } 150 } 151 else { 152 return false; 153 } 154 break; 155 default: 156 return false; 157 } 158 } 159 if (*p == '.') { 160 ++p; 161 if (isdigit(*p) != 0) { 162 while (isdigit((G4int)(*p)) != 0) { 163 ++p; 164 } 165 if (*p == '\0') { 166 return true; 167 } 168 if (*p == 'e' || *p == 'E') { 169 return ExpectExponent(++p); 170 } 171 } 172 } 173 break; 174 case '.': 175 ++p; 176 if (isdigit(*p) != 0) { 177 while (isdigit((G4int)(*p)) != 0) { 178 ++p; 179 } 180 if (*p == '\0') { 181 return true; 182 } 183 if (*p == 'e' || *p == 'E') { 184 return ExpectExponent(++p); 185 } 186 } 187 break; 188 default: // digit is expected 189 if (isdigit(*p) != 0) { 190 while (isdigit((G4int)(*p)) != 0) { 191 ++p; 192 } 193 if (*p == '\0') { 194 return true; 195 } 196 if (*p == 'e' || *p == 'E') { 197 return ExpectExponent(++p); 198 } 199 if (*p == '.') { 200 ++p; 201 if (*p == '\0') { 202 return true; 203 } 204 if (*p == 'e' || *p == 'E') { 205 return ExpectExponent(++p); 206 } 207 if (isdigit(*p) != 0) { 208 while (isdigit((G4int)(*p)) != 0) { 209 ++p; 210 } 211 if (*p == '\0') { 212 return true; 213 } 214 if (*p == 'e' || *p == 'E') { 215 return ExpectExponent(++p); 216 } 217 } 218 } 219 } 220 } 221 return false; 222 } 223 224 // -------------------------------------------------------------------- 225 inline G4int CompareInt(G4int arg1, G4int op, G4int arg2, G4int& errCode) 226 { 227 G4int result = -1; 228 switch (op) { 229 case G4UItokenNum::GT: 230 result = static_cast<G4int>(arg1 > arg2); 231 break; 232 case G4UItokenNum::GE: 233 result = static_cast<G4int>(arg1 >= arg2); 234 break; 235 case G4UItokenNum::LT: 236 result = static_cast<G4int>(arg1 < arg2); 237 break; 238 case G4UItokenNum::LE: 239 result = static_cast<G4int>(arg1 <= arg2); 240 break; 241 case G4UItokenNum::EQ: 242 result = static_cast<G4int>(arg1 == arg2); 243 break; 244 case G4UItokenNum::NE: 245 result = static_cast<G4int>(arg1 != arg2); 246 break; 247 default: 248 G4cerr << "Parameter range: error at CompareInt" << G4endl; 249 errCode = 1; 250 } 251 return result; 252 } 253 254 // -------------------------------------------------------------------- 255 inline G4int CompareLong(G4long arg1, G4int op, G4long arg2, G4int& errCode) 256 { 257 G4int result = -1; 258 switch (op) { 259 case G4UItokenNum::GT: 260 result = static_cast<G4int>(arg1 > arg2); 261 break; 262 case G4UItokenNum::GE: 263 result = static_cast<G4int>(arg1 >= arg2); 264 break; 265 case G4UItokenNum::LT: 266 result = static_cast<G4int>(arg1 < arg2); 267 break; 268 case G4UItokenNum::LE: 269 result = static_cast<G4int>(arg1 <= arg2); 270 break; 271 case G4UItokenNum::EQ: 272 result = static_cast<G4int>(arg1 == arg2); 273 break; 274 case G4UItokenNum::NE: 275 result = static_cast<G4int>(arg1 != arg2); 276 break; 277 default: 278 G4cerr << "Parameter range: error at CompareInt" << G4endl; 279 errCode = 1; 280 } 281 return result; 282 } 283 284 // -------------------------------------------------------------------- 285 inline G4int CompareDouble(G4double arg1, G4int op, G4double arg2, G4int& errCode) 286 { 287 G4int result = -1; 288 switch (op) { 289 case G4UItokenNum::GT: 290 result = static_cast<G4int>(arg1 > arg2); 291 break; 292 case G4UItokenNum::GE: 293 result = static_cast<G4int>(arg1 >= arg2); 294 break; 295 case G4UItokenNum::LT: 296 result = static_cast<G4int>(arg1 < arg2); 297 break; 298 case G4UItokenNum::LE: 299 result = static_cast<G4int>(arg1 <= arg2); 300 break; 301 case G4UItokenNum::EQ: 302 result = static_cast<G4int>(arg1 == arg2); 303 break; 304 case G4UItokenNum::NE: 305 result = static_cast<G4int>(arg1 != arg2); 306 break; 307 default: 308 G4cerr << "Parameter range: error at CompareDouble" << G4endl; 309 errCode = 1; 310 } 311 return result; 312 } 313 314 // -------------------------------------------------------------------- 315 // Return true if parameter is within range expression value 316 G4bool RangeCheck(const G4UIparameter& p, const char* value); 317 318 // Return true if command's parameters are within range expression value 319 G4bool RangeCheck(const G4UIcommand& p, const char* value); 320 321 } // namespace G4UIparsing 322 323 #endif 324