00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00030 #ifndef EXPANDLIB_CMD_IF_H_INCLUDED
00031 #define EXPANDLIB_CMD_IF_H_INCLUDED
00032
00033 #include <locale>
00034
00035 #include <boost/lexical_cast.hpp>
00036
00037 #include "expandlib-cmd.h"
00038
00039 namespace expander {
00040
00042
00049 template<
00050
00051 class StringType = ::std::string
00052 >
00053 class expcmd_if : public expandcmd<StringType> {
00054 protected:
00055
00057 inline bool IsValidOpStartChar(const StringType::value_type ch) const throw()
00058 {
00059 return ( ch == _T('<') || ch == _T('>') || ch == _T('=') || ch == _T('!') );
00060 };
00061
00063 inline bool IsValidOpChar(const StringType::value_type ch) const throw()
00064 {
00065 return ( ch == _T('<') || ch == _T('>') || ch == _T('=') || ch == _T('!') || ch == _T('@') );
00066 };
00067
00069 const std::locale loc;
00071
00072
00073 public:
00075
00078 expcmd_if(expandable<StringType> * const eobj) : expandcmd<StringType>(eobj, _T("if")), loc("") {};
00079
00091 virtual void operator()(StringType &dest, const FParamVectorType ¶ms, const FVarMapType &vars, ExpandResultsType &results) const
00092 {
00093 if ( params.size() == 3 ) {
00094 ExpandResultsType result;
00095
00096 {
00097 StringType d;
00098 expobj->expand(d, params[0], vars, result);
00099 }
00100
00101 {
00102
00103 if ( result.MissedVars() == 0 ) {
00104 expobj->expand(dest, params[1], vars, results);
00105 } else {
00106 expobj->expand(dest, params[2], vars, results);
00107 }
00108 }
00109 } else if ( params.size() == 5 ) {
00110 if ( params[1].size() > 3 ) {
00111 throw expand_error(_T("expcmd_if"),_T("Illegal operator"),params[1].c_str());
00112 }
00113
00114 StringType operand1, operand2;
00115 struct {
00116 bool equalto;
00117 bool greaterthan;
00118 bool lessthan;
00119 bool not;
00120 } comp;
00121 enum {
00122 nocomp,
00123 binary,
00124 textual,
00125 numeric
00126 } comptype;
00127 ExpandResultsType resultop1, resultop2;
00128
00129 expobj->expand(operand1, params[0], vars, resultop1);
00130 expobj->expand(operand2, params[2], vars, resultop2);
00131
00132
00133 comp.equalto=false;
00134 comp.greaterthan=false;
00135 comp.lessthan=false;
00136 comp.not=false;
00137 comptype=nocomp;
00138
00139 {
00140 StringType op(params[1]);
00141 if ( op.size() >= 1 ) {
00142 comptype=binary;
00143 if ( op.size() >= 2 ) {
00144 if ( op[op.size()-1] == _T('@') ) {
00145 comptype=textual;
00146 op.erase(op.end() - 1);
00147 } else if ( op[op.size()-1] == _T('!') ) {
00148 comptype=numeric;
00149 op.erase(op.end() - 1);
00150 } else if ( op.size() == 3 && op[op.size()-1] == _T('=') ) {
00151 op.erase(op.end() - 1);
00152 }
00153 }
00154
00155 if ( op == _T("==") ) {
00156 comp.equalto=true;
00157 } else if ( op == _T(">=") ) {
00158 comp.equalto=true;
00159 comp.greaterthan=true;
00160 } else if ( op == _T("<=") ) {
00161 comp.equalto=true;
00162 comp.lessthan=true;
00163 } else if ( op == _T("!=") ) {
00164 comp.equalto=true;
00165 comp.not=true;
00166 } else if ( op == _T(">") ) {
00167 comp.greaterthan=true;
00168 } else if ( op == _T("<") ) {
00169 comp.lessthan=true;
00170 } else {
00171 comptype=nocomp;
00172 }
00173 }
00174 }
00175
00176 {
00177
00178 bool correct=false;
00179
00180
00181
00182
00183
00184
00185 switch(comptype) {
00186 case binary:
00187 {
00188 if ( comp.equalto ) {
00189 if ( operand1 == operand2 ) correct=correct || true;
00190 }
00191 if ( comp.greaterthan ) {
00192 if ( operand1 > operand2 ) correct=correct || true;
00193 }
00194 if ( comp.lessthan ) {
00195 if ( operand1 < operand2 ) correct=correct || true;
00196 }
00197 if ( comp.not ) {
00198 correct=(correct?false:true);
00199 }
00200 if ( correct ) {
00201 expobj->expand(dest, params[3], vars, results);
00202 } else {
00203 expobj->expand(dest, params[4], vars, results);
00204 }
00205 }
00206 break;
00207 case textual:
00208 {
00209 using namespace std;
00210 use_facet< ctype<StringType::value_type> >(loc).toupper(operand1.begin(), operand1.end());
00211 use_facet< ctype<StringType::value_type> >(loc).toupper(operand2.begin(), operand2.end());
00212 if ( comp.equalto ) {
00213 if ( operand1 == operand2 ) correct=correct || true;
00214 }
00215 if ( comp.greaterthan ) {
00216 if ( operand1 > operand2 ) correct=correct || true;
00217 }
00218 if ( comp.lessthan ) {
00219 if ( operand1 < operand2 ) correct=correct || true;
00220 }
00221 if ( comp.not ) {
00222 correct=(correct?false:true);
00223 }
00224 if ( correct ) {
00225 expobj->expand(dest, params[3], vars, results);
00226 } else {
00227 expobj->expand(dest, params[4], vars, results);
00228 }
00229 }
00230 break;
00231 case numeric:
00232 {
00233 try {
00234 const int num1=boost::lexical_cast<int>(operand1);
00235 const int num2=boost::lexical_cast<int>(operand2);
00236
00237 if ( comp.equalto ) {
00238 if ( num1 == num2 ) correct=correct || true;
00239 }
00240 if ( comp.greaterthan ) {
00241 if ( num1 > num2 ) correct=correct || true;
00242 }
00243 if ( comp.lessthan ) {
00244 if ( num1 < num2 ) correct=correct || true;
00245 }
00246 if ( comp.not ) {
00247 correct=(correct?false:true);
00248 }
00249 if ( correct ) {
00250 expobj->expand(dest, params[3], vars, results);
00251 } else {
00252 expobj->expand(dest, params[4], vars, results);
00253 }
00254 } catch(boost::bad_lexical_cast) {
00255 dest+=_T("#Illegal operand(s)#");
00256 return;
00257 }
00258 }
00259 break;
00260 }
00261 }
00262 } else {
00263 throw expand_error(_T("expcmd_if"),_T("Parameter error"));
00264 }
00265 }
00266 };
00267
00268 }
00269
00270 #endif //EXPANDLIB_CMD_IF_H_INCLUDED