Implements both a single-command if that can execute command(s), and if / elseif / else /endif
Public Member Functions | |
BLCMDif () | |
G4String | commandName () |
int | command (BLArgumentVector &argv, BLArgumentMap &namedArgs) |
BLCMDif::BLCMDif | ( | ) |
References BLCMDTYPE_CONTROL, BLCommand::registerCommand(), BLCommand::setDescription(), and BLCommand::setSynopsis().
00041 { 00042 registerCommand(BLCMDTYPE_CONTROL); 00043 setSynopsis("Conditional execution of command(s), and if/elseif/else/endif."); 00044 setDescription("Single-line format:\n" 00045 " if $i==1 CMD1 CMD2 ...\n\n" 00046 "If the expression is true (nonzero), the commands are " 00047 "executed. The commands usually need to be quoted.\n\n" 00048 "Multi-line format:\n" 00049 " if $i==1\n" 00050 " CMD1 ...\n" 00051 " elseif $i==2\n" 00052 " CMD2 ...\n" 00053 " else\n" 00054 " CMD3 ...\n" 00055 " endif\n\n" 00056 "The commands are executed in the usual way; elseif and else " 00057 "are optional, but endif is mandatory. Any number of " 00058 "elseif-s and commannds can be used. " 00059 "Do-s and multi-line if-s can be nested in any manner."); 00060 }
G4String BLCMDif::commandName | ( | ) | [inline, virtual] |
int BLCMDif::command | ( | BLArgumentVector & | argv, | |
BLArgumentMap & | namedArgs | |||
) | [virtual] |
Implements BLCommand.
References BLCommand::doCommand(), BLEvaluator::evaluate(), BLParam::expand(), BLCommand::getNextCommand(), Param, BLCommand::parseArgs(), and BLCommand::printError().
00063 { 00064 if(argv.size() < 1 || namedArgs.size() != 0) { 00065 printError("Invalid if command"); 00066 return -1; 00067 } 00068 00069 BLEvaluator eval; 00070 int retval=0; 00071 00072 if(argv.size() > 1) { 00073 // simple (old) if 00074 double val = eval.evaluate(argv[0]); 00075 if(eval.status() != HepTool::Evaluator::OK) { 00076 printError("if: Invalid expression '%s'\n", 00077 argv[0].c_str()); 00078 return -1; 00079 } 00080 if(fabs(val) > 1.0e-12) { 00081 for(unsigned i=1; i<argv.size(); ++i) { 00082 if(doCommand(argv[i]) != 0) 00083 retval = -1; 00084 } 00085 } 00086 } else { 00087 // complex (multi-line) if 00088 double val = eval.evaluate(argv[0]); 00089 if(eval.status() != HepTool::Evaluator::OK) { 00090 printError("if: Invalid expression '%s'\n", 00091 argv[0].c_str()); 00092 val = 0.0; 00093 } 00094 bool skipping = (fabs(val) < 1.0e-12); 00095 bool haveExecuted = !skipping; 00096 int level = 1; 00097 for(;;) { 00098 G4String *line = BLCommand::getNextCommand(); 00099 if(!line) { 00100 printError("Unexpected EOF in if statement."); 00101 break; 00102 } 00103 if((*line) == "endif") { 00104 if(--level == 0) break; 00105 skipping = true; 00106 continue; 00107 } else if((*line) == "else") { 00108 if(level == 1) { 00109 if(!haveExecuted) { 00110 skipping = false; 00111 haveExecuted = true; 00112 } else { 00113 skipping = true; 00114 } 00115 } 00116 continue; 00117 } else if(line->find("elseif") == 0 && 00118 line->find_first_of(" \t") == 6) { 00119 if(haveExecuted) { 00120 skipping = true; 00121 continue; 00122 } 00123 // overwrites argv and namedArgs (nobody cares) 00124 argv.clear(); 00125 namedArgs.clear(); 00126 if(parseArgs(line->substr(7),argv,namedArgs) < 0 00127 || argv.size() != 1 || namedArgs.size() != 0) { 00128 printError("elseif: invalid elseif."); 00129 skipping = true; 00130 continue; 00131 } 00132 G4String t=Param.expand(argv[0]); 00133 double val = eval.evaluate(t.c_str()); 00134 if(eval.status() != HepTool::Evaluator::OK) { 00135 printError("elseif: Invalid expression '%s'\n", 00136 line->substr(7).c_str()); 00137 val = 0.0; 00138 } 00139 if(fabs(val) > 1.0e-12) { 00140 skipping = false; 00141 haveExecuted = true; 00142 } 00143 continue; 00144 } else if(line->find("if") == 0 && 00145 line->find_first_of(" \t") == 2) { 00146 if(skipping) { 00147 // overwrites argv and namedArgs (nobody cares) 00148 argv.clear(); 00149 namedArgs.clear(); 00150 if(parseArgs(line->substr(3),argv,namedArgs) < 0) { 00151 printError("if: invalid if."); 00152 continue; 00153 } 00154 if(argv.size() == 1) ++level; 00155 } 00156 } 00157 if(!skipping) 00158 BLCommand::doCommand(*line); 00159 } 00160 } 00161 00162 return retval; 00163 }