00001
00002
00003 #include "index.h"
00004 #include "functions.h"
00005 #include "arithmetics.h"
00006 #include "datetime.h"
00007 #include "cache.h"
00008 #include "configuration.h"
00009 #ifndef DEBUG
00010 #include "apiHeaderAll.h"
00011 #include "rsApiHandler.h"
00012 #endif
00013
00014
00015
00016 #if defined(USE_BOOST)
00017 #include <boost/regex.h>
00018 #elif defined(_POSIX_VERSION)
00019 #include <regex.h>
00020 #endif
00021
00022
00023 #ifndef DEBUG
00024 #include "execMyRule.h"
00025 #include "msParam.h"
00026 #include "reFuncDefs.h"
00027 #include "rsMisc.h"
00028 #include "stringOpr.h"
00029 #include "miscServerFunct.h"
00030 #endif
00031
00032 #define GC_BEGIN Region *_rnew = make_region(0, NULL), *_rnew2 = NULL;
00033 #define GC_REGION _rnew
00034 #define GC_ON(env) \
00035 if(region_size(_rnew) > DEFAULT_BLOCK_SIZE) {\
00036 _rnew2 = make_region(0, NULL); \
00037 cpEnv2((env), _rnew, _rnew2); \
00038 region_free(_rnew); \
00039 _rnew = _rnew2;}
00040 #define GC_END region_free(_rnew);
00041
00042
00043
00044 int fileConcatenate(char *file1, char *file2, char *file3);
00045
00046 Node *wrapToActions(Node *node, Region *r) {
00047 if(getNodeType(node)!=N_ACTIONS) {
00048 Node *actions[1];
00049 actions[0] = node;
00050 Label expr;
00051 expr.base = node->base;
00052 expr.exprloc = NODE_EXPR_POS(node);
00053 return createActionsNode(actions, 1, &expr, r);
00054 }
00055 return node;
00056 }
00057 Res *smsi_ifExec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t* errmsg, Region *r) {
00058 Res *res = evaluateExpression3((Node *)params[0], 0, 1, rei,reiSaveFlag,env,errmsg,r);
00059 if(getNodeType(res) == N_ERROR) {
00060 return res;
00061 }
00062 if(RES_BOOL_VAL(res) == 0) {
00063 return evaluateActions(wrapToActions(params[2],r), wrapToActions(params[4],r),0,rei, reiSaveFlag, env, errmsg, r);
00064 } else {
00065 return evaluateActions(wrapToActions(params[1],r), wrapToActions(params[3],r),0,rei, reiSaveFlag, env, errmsg, r);
00066 }
00067 }
00068
00069 Res *smsi_if2Exec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t* errmsg, Region *r) {
00070 Res *res = evaluateExpression3((Node *)params[0], 0,1,rei,reiSaveFlag,env,errmsg,r);
00071 if(getNodeType(res) == N_ERROR) {
00072 return res;
00073 }
00074 if(RES_BOOL_VAL(res) == 0) {
00075 return evaluateExpression3((Node *)params[2], 0, 1, rei,reiSaveFlag,env,errmsg,r);
00076 } else {
00077 return evaluateExpression3((Node *)params[1], 0, 1, rei,reiSaveFlag,env,errmsg,r);
00078 }
00079 }
00080
00081 Res *smsi_do(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00082 switch(getNodeType(params[0])) {
00083 case N_ACTIONS:
00084 return evaluateActions((Node *)params[0], NULL,0, rei, reiSaveFlag,env, errmsg, r);
00085 default:
00086 return evaluateExpression3((Node *)params[0], 0, 1, rei,reiSaveFlag,env,errmsg,r);
00087 }
00088
00089 }
00090 Res *smsi_letExec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t* errmsg, Region *r) {
00091 Res *res = evaluateExpression3(params[1], 0, 1,rei,reiSaveFlag,env,errmsg,r);
00092 if(getNodeType(res) == N_ERROR) {
00093 return res;
00094 }
00095 Env *nEnv = newEnv(newHashTable2(100, r), env, NULL, r);
00096 Res *pres = matchPattern(params[0], res, nEnv, rei, reiSaveFlag, errmsg, r);
00097 if(getNodeType(pres) == N_ERROR) {
00098
00099 return pres;
00100 }
00101
00102 res = evaluateExpression3(params[2], 0,1, rei,reiSaveFlag,nEnv,errmsg,r);
00103
00104 return res;
00105 }
00106 Res *smsi_matchExec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t* errmsg, Region *r) {
00107 Res *res = evaluateExpression3(params[0], 0, 1,rei,reiSaveFlag,env,errmsg,r);
00108 if(getNodeType(res) == N_ERROR) {
00109 return res;
00110 }
00111 int i;
00112 for(i=1;i<n;i++) {
00113 Env *nEnv = newEnv(newHashTable2(100, r), env, NULL, r);
00114 Res *pres = matchPattern(params[i]->subtrees[0], res, nEnv, rei, reiSaveFlag, errmsg, r);
00115 if(getNodeType(pres) == N_ERROR) {
00116
00117 addRErrorMsg(errmsg, RE_PATTERN_NOT_MATCHED, ERR_MSG_SEP);
00118 continue;
00119 }
00120 res = evaluateExpression3(params[i]->subtrees[1], 0,0, rei,reiSaveFlag,nEnv,errmsg,r);
00121
00122 return res;
00123 }
00124 generateAndAddErrMsg("pattern not matched", node, RE_PATTERN_NOT_MATCHED, errmsg);
00125 return newErrorRes(r, RE_PATTERN_NOT_MATCHED);
00126 }
00127
00128
00129 Res *smsi_whileExec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00130
00131 Res *cond, *res;
00132 GC_BEGIN
00133 while(1) {
00134
00135 cond = evaluateExpression3((Node *)params[0], 0,1, rei,reiSaveFlag, env,errmsg,GC_REGION);
00136 if(getNodeType(cond) == N_ERROR) {
00137 res = cond;
00138 break;
00139 }
00140 if(RES_BOOL_VAL(cond) == 0) {
00141 res = newIntRes(r, 0);
00142 break;
00143 }
00144 res = evaluateActions((Node *)params[1],(Node *)params[2],0, rei,reiSaveFlag, env,errmsg,GC_REGION);
00145 if(getNodeType(res) == N_ERROR) {
00146 break;
00147 } else
00148 if(TYPE(res) == T_BREAK) {
00149 res = newIntRes(r, 0);
00150 break;
00151 } else
00152 if(TYPE(res) == T_SUCCESS) {
00153 break;
00154 }
00155 GC_ON(env);
00156
00157 }
00158 cpEnv(env, r);
00159 res = cpRes(res, r);
00160 GC_END
00161 return res;
00162
00163 }
00164
00165 Res *smsi_forExec(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00166
00167 Res *init, *cond, *res, *step;
00168 Region *rnew = make_region(0, NULL);
00169 init = evaluateExpression3((Node *)params[0], 0,1,rei,reiSaveFlag, env,errmsg,rnew);
00170 if(getNodeType(init) == N_ERROR) {
00171 res = init;
00172 cpEnv(env, r);
00173 res = cpRes2(res, rnew, r);
00174 region_free(rnew);
00175 return res;
00176 }
00177 GC_BEGIN
00178 while(1) {
00179
00180 cond = evaluateExpression3((Node *)params[1], 0, 1,rei,reiSaveFlag, env,errmsg,GC_REGION);
00181 if(getNodeType(cond) == N_ERROR) {
00182
00183 break;
00184 }
00185 if(RES_BOOL_VAL(cond) == 0) {
00186 res = newIntRes(r, 0);
00187 break;
00188 }
00189 res = evaluateActions((Node *)params[3],(Node *)params[4], 0, rei,reiSaveFlag, env,errmsg,GC_REGION);
00190 if(getNodeType(res) == N_ERROR) {
00191 break;
00192 } else
00193 if(TYPE(res) == T_BREAK) {
00194 res =
00195 newIntRes(r, 0);
00196 break;
00197 } else
00198 if(TYPE(res) == T_SUCCESS) {
00199 break;
00200 }
00201 step = evaluateExpression3((Node *)params[2], 0,1,rei,reiSaveFlag, env,errmsg,GC_REGION);
00202 if(getNodeType(step) == N_ERROR) {
00203
00204 break;
00205 }
00206 GC_ON(env);
00207 }
00208 cpEnv(env, r);
00209 res = cpRes(res, r);
00210 GC_END
00211 region_free(rnew);
00212 return res;
00213
00214 }
00215
00216 Res *smsi_split(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r);
00217
00218 Res *collType(Res *coll, Node *node, rError_t *errmsg, Region *r) {
00219 if(TYPE(coll) == T_STRING) {
00220 Res *paramsr[2];
00221 paramsr[0] = coll;
00222 paramsr[1] = newStringRes(r, ",");
00223 return smsi_split(paramsr, 2, node, NULL, 0, NULL, errmsg, r);
00224 } else if(TYPE(coll) != T_CONS &&
00225 (TYPE(coll) != T_IRODS || (
00226 strcmp(coll->exprType->text, StrArray_MS_T) != 0 &&
00227 strcmp(coll->exprType->text, IntArray_MS_T) != 0 &&
00228 strcmp(coll->exprType->text, GenQueryOut_MS_T) != 0))) {
00229 char errbuf[ERR_MSG_LEN];
00230 snprintf(errbuf, ERR_MSG_LEN, "%s is not a collection type.", typeName_Res(coll));
00231 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
00232 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
00233 } else {
00234 return coll;
00235 }
00236 }
00237 Res *smsi_forEach2Exec(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
00238 {
00239 Res *res = newRes(r);
00240 char* varName = ((Node *)subtrees[0])->text;
00241 Res* coll = evaluateExpression3(subtrees[1], 0, 1, rei, reiSaveFlag, env, errmsg, r);
00242 CASCADE_N_ERROR(coll = collType(coll, subtrees[1], errmsg, r));
00243 res = newIntRes(r, 0);
00244 if(TYPE(coll) == T_CONS && strcmp(coll->exprType->text, LIST) == 0) {
00245 int i;
00246 Res* elem;
00247 for(i=0;i<coll->degree;i++) {
00248 elem = coll->subtrees[i];
00249 setVariableValue(varName, elem, rei, env, errmsg, r);
00250 res = evaluateActions(subtrees[2], subtrees[3], 0, rei,reiSaveFlag, env,errmsg,r);
00251 if(getNodeType(res) == N_ERROR) {
00252 break;
00253 } else
00254 if(TYPE(res) == T_BREAK) {
00255 break;
00256 } else
00257 if(TYPE(res) == T_SUCCESS) {
00258 break;
00259 }
00260 }
00261 if(getNodeType(res) != N_ERROR) {
00262 res = newIntRes(r,0);
00263 }
00264 } else {
00265 int i;
00266 Res* elem;
00267 int len = getCollectionSize(coll->exprType->text, RES_UNINTER_STRUCT(coll), r);
00268 GC_BEGIN
00269 for(i=0;i<len;i++) {
00270
00271
00272 GC_ON(env);
00273 elem = getValueFromCollection(coll->exprType->text, RES_UNINTER_STRUCT(coll), i, GC_REGION);
00274 setVariableValue(varName, elem, rei, env, errmsg, GC_REGION);
00275 res = evaluateActions((Node *)subtrees[2], (Node *)subtrees[3], 0, rei,reiSaveFlag, env,errmsg,GC_REGION);
00276 clearKeyVal((keyValPair_t *)RES_UNINTER_STRUCT(elem));
00277 free(RES_UNINTER_STRUCT(elem));
00278
00279
00280 if(getNodeType(res) == N_ERROR) {
00281 break;
00282 }
00283 if(TYPE(res) == T_BREAK) {
00284 break;
00285 }
00286 }
00287
00288
00289 cpEnv(env, r);
00290 res = cpRes(res, r);
00291 GC_END
00292
00293 if(getNodeType(res) != N_ERROR) {
00294 res = newIntRes(r,0);
00295 }
00296
00297 }
00298 return res;
00299 }
00300 Res *smsi_forEachExec(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
00301 {
00302 Res *res = newRes(r);
00303 char* varName = ((Node *)subtrees[0])->text;
00304 Res* orig = evaluateVar3(varName, ((Node *)subtrees[0]), rei, reiSaveFlag, env, errmsg, r);
00305 Res *coll;
00306 CASCADE_N_ERROR(coll = collType(orig, subtrees[0], errmsg, r));
00307 res = newIntRes(r, 0);
00308 if(TYPE(coll) == T_CONS && strcmp(coll->exprType->text, LIST) == 0) {
00309 int i;
00310 Res* elem;
00311 for(i=0;i<coll->degree;i++) {
00312 elem = coll->subtrees[i];
00313 setVariableValue(varName, elem, rei, env, errmsg, r);
00314 res = evaluateActions(subtrees[1], subtrees[2], 0, rei,reiSaveFlag, env,errmsg,r);
00315 if(getNodeType(res) == N_ERROR) {
00316 break;
00317 } else
00318 if(TYPE(res) == T_BREAK) {
00319 break;
00320 } else
00321 if(TYPE(res) == T_SUCCESS) {
00322 break;
00323 }
00324 }
00325 if(getNodeType(res) != N_ERROR) {
00326 res = newIntRes(r,0);
00327 }
00328 } else {
00329 int i;
00330 Res* elem;
00331 int len = getCollectionSize(coll->exprType->text, RES_UNINTER_STRUCT(coll), r);
00332 GC_BEGIN
00333 for(i=0;i<len;i++) {
00334
00335
00336 GC_ON(env);
00337 elem = getValueFromCollection(coll->exprType->text, RES_UNINTER_STRUCT(coll), i, GC_REGION);
00338 setVariableValue(varName, elem, rei, env, errmsg, GC_REGION);
00339 res = evaluateActions((Node *)subtrees[1], (Node *)subtrees[2], 0, rei,reiSaveFlag, env,errmsg,GC_REGION);
00340 clearKeyVal((keyValPair_t *)RES_UNINTER_STRUCT(elem));
00341 free(RES_UNINTER_STRUCT(elem));
00342
00343 if(getNodeType(res) == N_ERROR) {
00344 break;
00345 }
00346 if(TYPE(res) == T_BREAK) {
00347 break;
00348 }
00349 }
00350
00351
00352 cpEnv(env, r);
00353 res = cpRes(res, r);
00354 GC_END
00355
00356 if(getNodeType(res) != N_ERROR) {
00357 res = newIntRes(r,0);
00358 }
00359
00360 }
00361 setVariableValue(varName, orig, rei, env, errmsg, r);
00362 return res;
00363 }
00364 Res *smsi_break(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00365
00366 Res * res = newRes(r);
00367 res->exprType = newSimpType(T_BREAK, r);
00368 return res;
00369 }
00370 Res *smsi_succeed(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00371
00372 Res * res = newRes(r);
00373 res->exprType = newSimpType(T_SUCCESS, r);
00374 return res;
00375 }
00376 Res *smsi_fail(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00377
00378 Res * res = newErrorRes(r, n == 0 ?FAIL_ACTION_ENCOUNTERED_ERR:RES_INT_VAL(subtrees[0]));
00379 generateAndAddErrMsg("fail action encountered", node, RES_ERR_CODE(res), errmsg);
00380 return res;
00381 }
00382
00383
00384 Res *smsi_assign(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00385
00386
00387
00388 Res *val = evaluateExpression3((Node *)subtrees[1], 0, 1, rei, reiSaveFlag, env, errmsg,r);
00389 if(getNodeType(val) == N_ERROR) {
00390 return val;
00391 }
00392 Res *ret = matchPattern(subtrees[0], val, env, rei, reiSaveFlag, errmsg, r);
00393
00394 return ret;
00395 }
00396
00397 Res *smsi_listvars(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 char buf[1024];
00427 printHashtable(env->current, buf);
00428 Res *res= newStringRes(r, buf);
00429 return res;
00430 }
00431 Res *smsi_listcorerules(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00432 Res *coll = newCollRes(ruleEngineConfig.coreRuleSet->len, newSimpType(T_STRING, r), r);
00433 int i;
00434 for(i=0;i<ruleEngineConfig.coreRuleSet->len;i++) {
00435 coll->subtrees[i] = newStringRes(r, ruleEngineConfig.coreRuleSet->rules[i]->node->subtrees[0]->text);
00436 }
00437 return coll;
00438 }
00439 Res *smsi_listapprules(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00440 Res *coll = newCollRes(ruleEngineConfig.appRuleSet->len, newSimpType(T_STRING, r), r);
00441 int i;
00442 for(i=0;i<ruleEngineConfig.appRuleSet->len;i++) {
00443 coll->subtrees[i] = newStringRes(r, ruleEngineConfig.appRuleSet->rules[i]->node->subtrees[0]->text);
00444 }
00445 return coll;
00446 }
00447 Res *smsi_listextrules(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00448 Res *coll = newCollRes(ruleEngineConfig.extRuleSet->len, newSimpType(T_STRING, r), r);
00449 int i;
00450 for(i=0;i<ruleEngineConfig.extRuleSet->len;i++) {
00451 coll->subtrees[i] = newStringRes(r, ruleEngineConfig.extRuleSet->rules[i]->node->subtrees[0]->text);
00452 }
00453 return coll;
00454 }
00455 Res *smsi_true(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00456 return newBoolRes(r, 1);
00457 }
00458 Res *smsi_false(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00459 return newBoolRes(r, 0);
00460 }
00461
00462 Res *smsi_max(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00463 int init=0;
00464 double max=0;
00465 int i;
00466 for(i=0;i<n;i++) {
00467 double x = params[i]->dval;
00468 if(init==0) {
00469 max = x;
00470 init = 1;
00471 } else {
00472 max = x > max? x: max;
00473 }
00474 }
00475 Res *res = newDoubleRes(r, max);
00476 return res;
00477 }
00478 Res *smsi_min(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00479 int init=0;
00480 double min=0;
00481 int i;
00482 for(i=0;i<n;i++) {
00483 double x = params[i]->dval;
00484 if(init==0) {
00485 min = x;
00486 init = 1;
00487 } else {
00488 min = x < min? x: min;
00489 }
00490 }
00491 Res *res = newDoubleRes(r, min);
00492 return res;
00493 }
00494 Res *smsi_average(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00495 double sum=0;
00496 int i;
00497 for(i=0;i<n;i++) {
00498 double x = params[i]->dval;
00499 sum += x;
00500 }
00501 Res *res = newDoubleRes(r, sum/n);
00502 return res;
00503 }
00504 Res *smsi_hd(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00505 if(params[0]->degree > 0) {
00506 return params[0]->subtrees[0];
00507 } else {
00508 generateAndAddErrMsg("error: hd: empty list", node, RE_RUNTIME_ERROR, errmsg);
00509 return newErrorRes(r, RE_RUNTIME_ERROR);
00510 }
00511 }
00512 Res *smsi_tl(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00513 if(params[0]->degree > 0) {
00514 Res *res = newRes(r);
00515 ExprType *elemType = T_CONS_TYPE_ARG(((Res *)params[0])->exprType, 0);
00516
00517 res->exprType = newCollType(elemType, r);
00518 res->degree = params[0]->degree-1;
00519 res->subtrees = (Res **) region_alloc(r, sizeof(Res *)*res->degree);
00520 int i;
00521 for(i=0;i<res->degree;i++) {
00522 res->subtrees[i] = params[0]->subtrees[i+1];
00523 }
00524 return res;
00525 } else {
00526 generateAndAddErrMsg("error: tl: empty list", node, RE_RUNTIME_ERROR, errmsg);
00527 return newErrorRes(r, RE_RUNTIME_ERROR);
00528 }
00529 }
00530 Res *smsi_cons(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00531 Res *res = newRes(r);
00532 ExprType *elemType = params[0]->exprType;
00533
00534 res->exprType = newCollType(elemType, r);
00535 res->degree = params[1]->degree+1;
00536 res->subtrees = (Res **) region_alloc(r, sizeof(Res *)*res->degree);
00537 int i;
00538 res->subtrees[0] = params[0];
00539 for(i=1;i<res->degree;i++) {
00540 res->subtrees[i] = params[1]->subtrees[i-1];
00541 }
00542 return res;
00543 }
00544 Res *smsi_setelem(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00545 Res *res = newRes(r);
00546 Res *coll = params[0];
00547 Res *indexRes = params[1];
00548 Res *val = params[2];
00549 ExprType *elemType = coll->exprType->subtrees[0];
00550 int index = RES_INT_VAL(indexRes);
00551 if(0>index || index >= coll->degree) {
00552 char errbuf[ERR_MSG_LEN];
00553 snprintf(errbuf, ERR_MSG_LEN, "setelem: index out of bound %d", index);
00554 generateAndAddErrMsg(errbuf, node, RE_RUNTIME_ERROR, errmsg);
00555 return newErrorRes(r, RE_RUNTIME_ERROR);
00556 }
00557
00558
00559 res->exprType = newCollType(elemType, r);
00560 res->degree = coll->degree;
00561 res->subtrees = (Res **) region_alloc(r, sizeof(Res *)*res->degree);
00562 memcpy(res->subtrees, coll->subtrees, sizeof(Res *)*res->degree);
00563 res->subtrees[index] = val;
00564 return res;
00565 }
00566 Res *smsi_list(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00567 Res *res = newRes(r);
00568 ExprType *elemType =
00569 n == 0?newSimpType(T_UNSPECED, r):params[0]->exprType;
00570
00571 res->exprType = newCollType(elemType, r);
00572 res->degree = n;
00573 res->subtrees = (Res **) region_alloc(r, sizeof(Res *)*n);
00574 int i;
00575 for(i=0;i<n;i++) {
00576 res->subtrees[i] = params[i];
00577 }
00578 return res;
00579 }
00580 Res *smsi_tuple(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00581 Res *res = newRes(r);
00582
00583 ExprType **elemTypes = (ExprType **)region_alloc(r, n*sizeof(ExprType *));
00584 int i;
00585 for(i=0;i<n;i++) {
00586 elemTypes[i] = params[i]->exprType;
00587 }
00588 res->exprType = newConsType(n, cpStringExt(TUPLE, r), elemTypes, r);
00589 res->degree = n;
00590 res->text = cpStringExt(TUPLE, r);
00591
00592 res->subtrees = (Res **) region_alloc(r, sizeof(Res *)*n);
00593 for(i=0;i<n;i++) {
00594 res->subtrees[i] = params[i];
00595 }
00596 return res;
00597 }
00598 Res *smsi_elem(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00599 char errbuf[ERR_MSG_LEN];
00600 int index = RES_INT_VAL(params[1]);
00601 if(TYPE(params[0]) == T_CONS) {
00602 if(index <0 || index >= params[0]->degree ) {
00603 snprintf(errbuf, ERR_MSG_LEN, "error: index out of range %d.", index);
00604 addRErrorMsg(errmsg, RE_RUNTIME_ERROR, errbuf);
00605 return newErrorRes(r, RE_RUNTIME_ERROR);
00606 }
00607 Res *res = params[0]->subtrees[index];
00608 return res;
00609 } else {
00610 if(index <0 || index >= getCollectionSize(params[0]->exprType->text,
00611 RES_UNINTER_STRUCT(params[0]), r) ) {
00612 snprintf(errbuf, ERR_MSG_LEN, "error: index out of range %d. %s", index, ((Res *)params[0])->exprType->text);
00613 addRErrorMsg(errmsg, RE_RUNTIME_ERROR, errbuf);
00614 return newErrorRes(r, RE_RUNTIME_ERROR);
00615 }
00616 Res *res2 = getValueFromCollection(params[0]->exprType->text,
00617 RES_UNINTER_STRUCT(params[0]),
00618 index,r);
00619
00620 return res2;
00621 }
00622 }
00623 Res *smsi_size(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00624 Res * res = newRes(r);
00625 res->exprType = newSimpType(T_INT,r);
00626 if(TYPE(params[0]) == T_CONS) {
00627 RES_INT_VAL_LVAL(res) = params[0]->degree;
00628 } else {
00629 RES_INT_VAL_LVAL(res) = getCollectionSize(params[0]->exprType->text,
00630 RES_UNINTER_STRUCT(params[0]),r);
00631 }
00632 return res;
00633 }
00634 Res *smsi_datetime(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00635 char errbuf[ERR_MSG_LEN];
00636 Res *res = newRes(r);
00637 Res* timestr = params[0];
00638 char* format;
00639 if(TYPE(params[0])!=T_STRING ||
00640 (n == 2 && TYPE(params[1])!=T_STRING)) {
00641 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00642 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported operator or type. can not apply datetime to type (%s[,%s]).", typeName_Res((Res *)params[0]), n==2?typeName_Res((Res *)params[1]):"null");
00643 addRErrorMsg(errmsg, RE_UNSUPPORTED_OP_OR_TYPE, errbuf);
00644 } else {
00645 if(n == 2) {
00646 format = params[1]->text;
00647 } else {
00648 format="";
00649 }
00650 strttime(timestr->text, format, &(RES_TIME_VAL(res)));
00651 res->exprType = newSimpType(T_DATETIME,r);
00652 }
00653 return res;
00654 }
00655
00656 Res *smsi_time(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00657 time_t t;
00658 time(&t);
00659 Res*res = newDatetimeRes(r, t);
00660 return res;
00661 }
00662 Res *smsi_timestr(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00663 char errbuf[ERR_MSG_LEN];
00664 Res *res = newRes(r);
00665 Res* dtime = params[0];
00666 char* format;
00667 if(TYPE(params[0])!=T_DATETIME ||
00668 (n == 2 && TYPE(params[1])!=T_STRING)) {
00669 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00670 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported operator or type. can not apply datetime to type (%s[,%s]).", typeName_Res((Res *)params[0]), n==2?typeName_Res((Res *)params[1]):"null");
00671 addRErrorMsg(errmsg, RE_UNSUPPORTED_OP_OR_TYPE, errbuf);
00672 } else {
00673 if(n == 2) {
00674 format = params[1]->text;
00675 } else {
00676 format = "";
00677 }
00678 char buf[1024];
00679 ttimestr(buf, 1024-1, format, &RES_TIME_VAL(dtime));
00680 res = newStringRes(r, buf);
00681 }
00682 return res;
00683 }
00684 Res *smsi_type(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00685 Res *val = params[0], *res;
00686 char typeName[128];
00687 typeToString(val->exprType, NULL, typeName, 128);
00688 res=newStringRes(r, typeName);
00689 return res;
00690 }
00691 Res *smsi_arity(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00692 Res *val = params[0];
00693 RuleIndexListNode *ruleInxLstNode;
00694 if(findNextRule2(val->text, 0, &ruleInxLstNode)<0) {
00695 return newErrorRes(r, RE_RUNTIME_ERROR);
00696 }
00697 int ri;
00698 if(ruleInxLstNode->secondaryIndex) {
00699 return newErrorRes(r, RE_RUNTIME_ERROR);
00700 } else {
00701 ri = ruleInxLstNode->ruleIndex;
00702 }
00703 RuleDesc *rd = getRuleDesc(ri);
00704 return newIntRes(r, RULE_NODE_NUM_PARAMS(rd->node));
00705 }
00706 Res *smsi_str(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00707 char errbuf[ERR_MSG_LEN];
00708 char errmsgbuf[ERR_MSG_LEN];
00709 Res *val = params[0], *res;
00710 if(TYPE(val) == T_INT
00711 || TYPE(val) == T_DOUBLE
00712 || TYPE(val) == T_BOOL
00713 || TYPE(val) == T_CONS
00714 || TYPE(val) == T_STRING
00715 || TYPE(val) == T_DATETIME) {
00716 char *buf = convertResToString(val);
00717 if(buf != NULL) {
00718 res = newStringRes(r, buf);
00719 free(buf);
00720 } else {
00721 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00722 snprintf(errbuf, ERR_MSG_LEN, "error: converting value of type %s to string.", typeName_Res(val));
00723 generateAndAddErrMsg(errbuf, node, RE_UNSUPPORTED_OP_OR_TYPE, errmsg);
00724
00725 }
00726 } else {
00727 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00728 snprintf(errmsgbuf, ERR_MSG_LEN, "error: unsupported type. can not convert %s to string.", typeName_Res(val));
00729 generateAndAddErrMsg(errbuf, node, RE_UNSUPPORTED_OP_OR_TYPE, errmsg);
00730 }
00731 return res;
00732 }
00733
00734 Res *smsi_double(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00735 char errbuf[ERR_MSG_LEN];
00736 Res *val = params[0], *res = newRes(r);
00737 if(TYPE(val) == T_STRING) {
00738 res->exprType = newSimpType(T_DOUBLE,r);
00739 RES_DOUBLE_VAL_LVAL(res) = atof(val->text);
00740 } else if(TYPE(val) == T_DATETIME) {
00741 res->exprType = newSimpType(T_DOUBLE,r);
00742 RES_DOUBLE_VAL_LVAL(res) = (double)RES_TIME_VAL(val);
00743 } else if(TYPE(val) == T_DOUBLE) {
00744 res = val;
00745 } else {
00746 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00747 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported operator or type. can not convert %s to double.", typeName_Res(val));
00748 generateAndAddErrMsg(errbuf, node, RE_UNSUPPORTED_OP_OR_TYPE, errmsg);
00749 }
00750 return res;
00751 }
00752 Res *smsi_int(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00753 char errbuf[ERR_MSG_LEN];
00754 Res *val = params[0], *res = newRes(r);
00755 if(TYPE(val) == T_STRING) {
00756 res->exprType = newSimpType(T_INT,r);
00757 RES_INT_VAL_LVAL(res) = atoi(val->text);
00758 } else if(TYPE(val) == T_DOUBLE) {
00759 res->exprType = newSimpType(T_INT, r);
00760 RES_INT_VAL_LVAL(res) = (int)RES_DOUBLE_VAL(val);
00761 } else if(TYPE(val) == T_INT) {
00762 res = val;
00763 } else {
00764 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00765 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported operator or type. can not convert %s to integer.", typeName_Res(val));
00766 generateAndAddErrMsg(errbuf, node, RE_UNSUPPORTED_OP_OR_TYPE, errmsg);
00767 }
00768 return res;
00769 }
00770 Res *smsi_bool(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00771 char errbuf[ERR_MSG_LEN];
00772 Res *val = params[0], *res = newRes(r);
00773 res->exprType = newSimpType(T_BOOL, r);
00774 if(TYPE(val) == T_BOOL) {
00775 res = val;
00776 } else if(TYPE(val) == T_STRING && (strcmp(val->text, "true")==0 || strcmp(val->text, "1") == 0)) {
00777 RES_BOOL_VAL_LVAL(res) = 1;
00778 } else if(TYPE(val) == T_STRING && (strcmp(val->text, "false")==0 || strcmp(val->text, "0") == 0)) {
00779 RES_BOOL_VAL_LVAL(res) = 0;
00780 } else if(TYPE(val) == T_DOUBLE) {
00781 RES_BOOL_VAL_LVAL(res) = (int)RES_DOUBLE_VAL(val)?1:0;
00782 } else if(TYPE(val) == T_INT) {
00783 RES_BOOL_VAL_LVAL(res) = (int)RES_INT_VAL(val)?1:0;
00784 } else {
00785 res = newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00786 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported operator or type. can not convert %s to boolean.", typeName_Res(val));
00787 generateAndAddErrMsg(errbuf, node, RE_UNSUPPORTED_OP_OR_TYPE, errmsg);
00788 }
00789 return res;
00790 }
00791 Res *smsi_lmsg(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00792 writeToTmp("re.log", params[0]->text);
00793 Res *res = newIntRes(r, 0);
00794 return res;
00795 }
00796 Res *smsi_not(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00797 return newBoolRes(r, !RES_BOOL_VAL(params[0])?1:0);
00798
00799 }
00800 Res *smsi_negate(Node **args, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00801 if(TYPE(args[0])==T_INT) {
00802 return newIntRes(r, -RES_INT_VAL(args[0]));
00803 } else {
00804 return newDoubleRes(r, -RES_DOUBLE_VAL(args[0]));
00805 }
00806 }
00807 Res *smsi_abs(Node **args, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00808 if(TYPE(args[0])==T_INT) {
00809 int val = RES_INT_VAL(args[0]);
00810 return newIntRes(r, (int)(val < 0?-val:val));
00811 } else {
00812 double val = RES_DOUBLE_VAL(args[0]);
00813 return newDoubleRes(r, (val < 0?-val:val));
00814 }
00815 }
00816 Res *smsi_exp(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00817 Res **args = (Res **)params;
00818 double val = RES_DOUBLE_VAL(args[0]);
00819 return newDoubleRes(r, exp(val));
00820 }
00821 Res *smsi_log(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00822 Res **args = (Res **)params;
00823 double val = RES_DOUBLE_VAL(args[0]);
00824 return newDoubleRes(r, log(val));
00825
00826 }
00827 Res *smsi_floor(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00828 Res **args = (Res **)params;
00829 double val = RES_DOUBLE_VAL(args[0]);
00830 return newDoubleRes(r, floor(val));
00831
00832 }
00833 Res *smsi_ceiling(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00834 Res **args = (Res **)params;
00835 double val = RES_DOUBLE_VAL(args[0]);
00836 return newDoubleRes(r, ceil(val));
00837
00838 }
00839
00840 Res *smsi_and(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00841 Res **args = (Res **)params;
00842 return newBoolRes(r, RES_BOOL_VAL(args[0])&&RES_BOOL_VAL(args[1])?1:0);
00843
00844 }
00845
00846 Res *smsi_or(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00847 Res **args = (Res **)params;
00848 return newBoolRes(r, RES_BOOL_VAL(args[0])||RES_BOOL_VAL(args[1])?1:0);
00849 }
00850
00851 Res *smsi_add(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00852 if(TYPE(params[0])==T_INT) {
00853 return newIntRes(r, RES_INT_VAL(params[0])+RES_INT_VAL(params[1]));
00854 } else {
00855 return newDoubleRes(r, RES_DOUBLE_VAL(params[0])+RES_DOUBLE_VAL(params[1]));
00856 }
00857 }
00858 Res *smsi_subtract(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00859 if(TYPE(params[0])==T_INT) {
00860 return newIntRes(r, RES_INT_VAL(params[0])-RES_INT_VAL(params[1]));
00861 } else {
00862 return newDoubleRes(r, RES_DOUBLE_VAL(params[0])-RES_DOUBLE_VAL(params[1]));
00863 }
00864 }
00865 Res *smsi_multiply(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00866 if(TYPE(params[0])==T_INT) {
00867 return newIntRes(r, RES_INT_VAL(params[0])*RES_INT_VAL(params[1]));
00868 } else {
00869 return newDoubleRes(r, RES_DOUBLE_VAL(params[0])*RES_DOUBLE_VAL(params[1]));
00870 }
00871 }
00872 Res *smsi_divide(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00873 if(TYPE(params[0])==T_INT) {
00874 if(RES_INT_VAL(params[1]) != 0) {
00875 return newDoubleRes(r, RES_INT_VAL(params[0])/(double)RES_INT_VAL(params[1]));
00876 }
00877 } else {
00878 if(RES_DOUBLE_VAL(params[1]) != 0) {
00879 return newDoubleRes(r, RES_DOUBLE_VAL(params[0])/RES_DOUBLE_VAL(params[1]));
00880 }
00881 }
00882 generateAndAddErrMsg("division by zero.", node, RE_DIVISION_BY_ZERO, errmsg);
00883 return newErrorRes(r, RE_DIVISION_BY_ZERO);
00884 }
00885
00886 Res *smsi_modulo(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00887 if(RES_INT_VAL(params[1]) != 0) {
00888 return newDoubleRes(r, RES_INT_VAL(params[0])%RES_INT_VAL(params[1]));
00889 }
00890 generateAndAddErrMsg("division by zero.", node, RE_DIVISION_BY_ZERO, errmsg);
00891 return newErrorRes(r, RE_DIVISION_BY_ZERO);
00892 }
00893
00894 Res *smsi_power(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00895 return newDoubleRes(r, pow(RES_DOUBLE_VAL(params[0]), RES_DOUBLE_VAL(params[1])));
00896 }
00897 Res *smsi_root(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00898 if(RES_DOUBLE_VAL(params[1]) != 0) {
00899 return newDoubleRes(r, pow(RES_DOUBLE_VAL(params[0]), 1/RES_DOUBLE_VAL(params[1])));
00900 }
00901 generateAndAddErrMsg("division by zero.", node, RE_DIVISION_BY_ZERO, errmsg);
00902 return newErrorRes(r, RE_DIVISION_BY_ZERO);
00903 }
00904
00905 Res *smsi_concat(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00906 Res **args = (Res **)params;
00907
00908
00909
00910
00911
00912 char *newbuf = (char *)malloc((RES_STRING_STR_LEN(args[0]) + RES_STRING_STR_LEN(args[1])+1)*sizeof(char));
00913
00914 strcpy(newbuf, args[0]->text);
00915 strcpy(newbuf+RES_STRING_STR_LEN(args[0]), args[1]->text);
00916
00917 Res *res = newStringRes(r, newbuf);
00918 free(newbuf);
00919 return res;
00920
00921 }
00922
00923 Res *smsi_lt(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00924 switch(TYPE(params[0])) {
00925 case T_INT:
00926 return newBoolRes(r, RES_INT_VAL(params[0]) < RES_INT_VAL(params[1])?1:0);
00927 break;
00928 case T_DOUBLE:
00929 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) < RES_DOUBLE_VAL(params[1])?1:0);
00930 break;
00931 case T_DATETIME:
00932 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))<0?1:0);
00933 break;
00934 case T_STRING:
00935 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) <0?1:0);
00936 break;
00937 default:
00938 break;
00939 }
00940 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
00941 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
00942 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
00943 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
00944
00945 }
00946 Res *smsi_le(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00947 switch(TYPE(params[0])) {
00948 case T_INT:
00949 return newBoolRes(r, RES_INT_VAL(params[0]) <= RES_INT_VAL(params[1])?1:0);
00950 break;
00951 case T_DOUBLE:
00952 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) <= RES_DOUBLE_VAL(params[1])?1:0);
00953 break;
00954 case T_DATETIME:
00955 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))<=0?1:0);
00956 break;
00957 case T_STRING:
00958 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) <=0?1:0);
00959 break;
00960 default:
00961 break;
00962 }
00963 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
00964 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
00965 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
00966 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
00967
00968 }
00969 Res *smsi_gt(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00970 switch(TYPE(params[0])) {
00971 case T_INT:
00972 return newBoolRes(r, RES_INT_VAL(params[0]) > RES_INT_VAL(params[1])?1:0);
00973 break;
00974 case T_DOUBLE:
00975 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) > RES_DOUBLE_VAL(params[1])?1:0);
00976 break;
00977 case T_DATETIME:
00978 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))>0?1:0);
00979 break;
00980 case T_STRING:
00981 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) >0?1:0);
00982 break;
00983 default:
00984 break;
00985 }
00986 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
00987 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
00988 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
00989 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
00990
00991 }
00992 Res *smsi_ge(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
00993 switch(TYPE(params[0])) {
00994 case T_INT:
00995 return newBoolRes(r, RES_INT_VAL(params[0]) >= RES_INT_VAL(params[1])?1:0);
00996 break;
00997 case T_DOUBLE:
00998 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) >= RES_DOUBLE_VAL(params[1])?1:0);
00999 break;
01000 case T_DATETIME:
01001 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))>=0?1:0);
01002 break;
01003 case T_STRING:
01004 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) >=0?1:0);
01005 break;
01006 default:
01007 break;
01008 }
01009 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
01010 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
01011 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
01012 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
01013 }
01014 Res *smsi_eq(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01015 switch(TYPE(params[0])) {
01016 case T_BOOL:
01017 return newBoolRes(r, RES_BOOL_VAL(params[0]) == RES_BOOL_VAL(params[1])?1:0);
01018 break;
01019 case T_INT:
01020 return newBoolRes(r, RES_INT_VAL(params[0]) == RES_INT_VAL(params[1])?1:0);
01021 break;
01022 case T_DOUBLE:
01023 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) == RES_DOUBLE_VAL(params[1])?1:0);
01024 break;
01025 case T_DATETIME:
01026 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))==0?1:0);
01027 break;
01028 case T_STRING:
01029 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) ==0?1:0);
01030 break;
01031 default:
01032 break;
01033 }
01034 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
01035 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
01036 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
01037 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
01038 }
01039 Res *smsi_neq(Node **params, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01040 switch(TYPE(params[0])) {
01041 case T_BOOL:
01042 return newBoolRes(r, RES_BOOL_VAL(params[0]) != RES_BOOL_VAL(params[1])?1:0);
01043 break;
01044 case T_INT:
01045 return newBoolRes(r, RES_INT_VAL(params[0]) != RES_INT_VAL(params[1])?1:0);
01046 break;
01047 case T_DOUBLE:
01048 return newBoolRes(r, RES_DOUBLE_VAL(params[0]) != RES_DOUBLE_VAL(params[1])?1:0);
01049 break;
01050 case T_DATETIME:
01051 return newBoolRes(r, difftime(RES_TIME_VAL(params[0]), RES_TIME_VAL(params[1]))!=0?1:0);
01052 break;
01053 case T_STRING:
01054 return newBoolRes(r, strcmp(params[0]->text, params[1]->text) !=0?1:0);
01055 break;
01056 default:
01057 break;
01058 }
01059 char errbuf[ERR_MSG_LEN], type0[128], type1[128];
01060 snprintf(errbuf, ERR_MSG_LEN, "type error: comparing between %s and %s", typeToString(params[0]->exprType, NULL, type0, 128), typeToString(params[1]->exprType, NULL, type1, 128));
01061 generateAndAddErrMsg(errbuf, node, RE_DYNAMIC_TYPE_ERROR, errmsg);
01062 return newErrorRes(r, RE_DYNAMIC_TYPE_ERROR);
01063 }
01064 Res *smsi_like(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01065 Res **params = paramsr;
01066 char *pattern;
01067 char *bufstr;
01068 pattern = params[1]->text;
01069 Res *res;
01070 #if defined(_POSIX_VERSION) || defined(USE_BOOST)
01071 bufstr = strdup(params[0]->text);
01072
01073 char *buf2;
01074 buf2 = wildCardToRegex(pattern);
01075 regex_t regbuf;
01076 regcomp(®buf,buf2,REG_EXTENDED);
01077 res = newBoolRes(r, regexec(®buf,bufstr, 0,0,0)==0?1:0);
01078 regfree(®buf);
01079 free(buf2);
01080 free(bufstr);
01081 #else
01082 res = newBoolRes(r, match(pattern, param[0]->text)==TRUE?1:0);
01083 #endif
01084 return res;
01085 }
01086 Res *smsi_not_like(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01087 Res *res = smsi_like(paramsr, n, node, rei, reiSaveFlag, env, errmsg, r);
01088 if(TYPE(res) != N_ERROR) {
01089 return newBoolRes(r, RES_BOOL_VAL(res)?0:1);
01090 }
01091 return res;
01092 }
01093 Res *smsi_like_regex(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01094 Res **params = paramsr;
01095 char *pattern;
01096 char *bufstr;
01097 pattern = params[1]->text;
01098 Res *res;
01099 #if defined(_POSIX_VERSION) || defined(USE_BOOST)
01100 bufstr = strdup(params[0]->text);
01101
01102 pattern = matchWholeString(params[1]->text);
01103 regex_t regbuf;
01104 regcomp(®buf,pattern,REG_EXTENDED);
01105 res = newBoolRes(r, regexec(®buf,bufstr, 0,0,0)==0?1:0);
01106 regfree(®buf);
01107 free(bufstr);
01108 free(pattern);
01109 #else
01110 res = newBoolRes(r, match(pattern, param[0]->text)==TRUE?1:0);
01111 #endif
01112 return res;
01113 }
01114 Res *smsi_not_like_regex(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01115 Res *res = smsi_like_regex(paramsr, n, node, rei, reiSaveFlag, env, errmsg, r);
01116 if(TYPE(res) != N_ERROR) {
01117 return newBoolRes(r, RES_BOOL_VAL(res)?0:1);
01118 }
01119 return res;
01120 }
01121
01122 Res *smsi_eval(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01123 Res **params = (Res **)paramsr;
01124
01125 return eval(params[0]->text, env, rei, reiSaveFlag, errmsg, r);
01126 }
01127
01128 Res *smsi_evalrule(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01129 Res **params = (Res **)paramsr;
01130
01131 return newIntRes(r, parseAndComputeRule(params[0]->text, env, rei, reiSaveFlag, errmsg, r));
01132 }
01133
01134
01135
01136
01137 Res *smsi_errorcode(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01138 Res *res;
01139 switch(getNodeType(paramsr[0])) {
01140 case N_ACTIONS:
01141 res = evaluateActions((Node *)paramsr[0], (Node *)paramsr[1], 0, rei, reiSaveFlag, env, errmsg, r);
01142 break;
01143 default:
01144 res = evaluateExpression3((Node *)paramsr[0], 0,1, rei,reiSaveFlag,env,errmsg,r);
01145 break;
01146 }
01147 switch(getNodeType(res)) {
01148 case N_ERROR:
01149 return newIntRes(r, RES_ERR_CODE(res));
01150 default:
01151 return newIntRes(r, 0);
01152 }
01153 }
01154
01155
01156
01157
01158
01159 Res *smsi_errormsg(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01160 char *errbuf = (char *)malloc(ERR_MSG_LEN*1024*sizeof(char));
01161 Res *res;
01162 switch(getNodeType(paramsr[0])) {
01163 case N_ACTIONS:
01164 res = evaluateActions((Node *)paramsr[0], (Node *)paramsr[1], 0, rei, reiSaveFlag, env, errmsg, r);
01165 paramsr[2] = newStringRes(r, errMsgToString(errmsg, errbuf, ERR_MSG_LEN*1024));
01166 break;
01167 default:
01168 res = evaluateExpression3((Node *)paramsr[0], 0,1,rei,reiSaveFlag,env,errmsg,r);
01169 paramsr[1] = newStringRes(r, errMsgToString(errmsg, errbuf, ERR_MSG_LEN*1024));
01170 break;
01171 }
01172 freeRErrorContent(errmsg);
01173 free(errbuf);
01174 switch(getNodeType(res)) {
01175 case N_ERROR:
01176 return newIntRes(r, RES_ERR_CODE(res));
01177 default:
01178 return newIntRes(r, 0);
01179 }
01180 }
01181
01182 Res *smsi_delayExec(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01183 {
01184 int i;
01185 char actionCall[MAX_ACTION_SIZE];
01186 char recoveryActionCall[MAX_ACTION_SIZE];
01187 char delayCondition[MAX_ACTION_SIZE];
01188
01189 Res **params = (Res **)paramsr;
01190
01191 rstrcpy(delayCondition, params[0]->text, MAX_ACTION_SIZE);
01192 rstrcpy(actionCall, params[1]->text, MAX_ACTION_SIZE);
01193 rstrcpy(recoveryActionCall, params[2]->text, MAX_ACTION_SIZE);
01194
01195 msParamArray_t *tmp = rei->msParamArray;
01196 rei->msParamArray = newMsParamArray();
01197
01198 int ret = convertEnvToMsParamArray(rei->msParamArray, env, errmsg, r);
01199 if(ret!=0) {
01200 generateAndAddErrMsg("error converting Env to MsParamArray", node, ret, errmsg);
01201 return newErrorRes(r, ret);
01202 }
01203
01204 i = _delayExec(actionCall, recoveryActionCall, delayCondition, rei);
01205
01206 deleteMsParamArray(rei->msParamArray);
01207 rei->msParamArray = tmp;
01208
01209 if(i < 0) {
01210 return newErrorRes(r, i);
01211 } else {
01212 return newIntRes(r, i);
01213 }
01214 }
01215
01216 Res *smsi_remoteExec(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01217 {
01218 int i;
01219 execMyRuleInp_t execMyRuleInp;
01220 msParamArray_t *outParamArray = NULL;
01221 char tmpStr[LONG_NAME_LEN];
01222
01223 Res **params = (Res **)paramsr;
01224
01225 memset (&execMyRuleInp, 0, sizeof (execMyRuleInp));
01226 execMyRuleInp.condInput.len=0;
01227 rstrcpy (execMyRuleInp.outParamDesc, ALL_MS_PARAM_KW, LONG_NAME_LEN);
01228
01229 rstrcpy (tmpStr, params[0]->text, LONG_NAME_LEN);
01230 parseHostAddrStr (tmpStr, &execMyRuleInp.addr);
01231
01232 if(strlen(params[3]->text) == 0) {
01233 snprintf(execMyRuleInp.myRule, META_STR_LEN, "remExec{%s}", params[2]->text);
01234 } else {
01235 snprintf(execMyRuleInp.myRule, META_STR_LEN, "remExec||%s|%s", params[2]->text, params[3]->text);
01236 }
01237 addKeyVal(&execMyRuleInp.condInput,"execCondition",params[1]->text);
01238
01239 rei->msParamArray = newMsParamArray();
01240 int ret = convertEnvToMsParamArray(rei->msParamArray, env, errmsg, r);
01241 if(ret!=0) {
01242 generateAndAddErrMsg("error converting Env to MsParamArray", node, ret, errmsg);
01243 return newErrorRes(r, ret);
01244 }
01245 execMyRuleInp.inpParamArray = rei->msParamArray;
01246
01247 i = rsExecMyRule (rei->rsComm, &execMyRuleInp, &outParamArray);
01248
01249 if(outParamArray != NULL) {
01250 rei->msParamArray = outParamArray;
01251 }
01252 updateMsParamArrayToEnvAndFreeNonIRODSType(rei->msParamArray, env, errmsg, r);
01253 deleteMsParamArray(rei->msParamArray);
01254 rei->msParamArray = NULL;
01255 if(i<0) {
01256 return newErrorRes(r, i);
01257 } else {
01258 return newIntRes(r, i);
01259 }
01260 }
01261 int writeStringNew(char *writeId, char *writeStr, Env *env, Region *r, ruleExecInfo_t *rei ) {
01262 execCmdOut_t *myExecCmdOut;
01263 Res *execOutRes;
01264
01265
01266 #ifndef DEBUG // JMC - backport 4760
01267 dataObjInp_t dataObjInp;
01268 openedDataObjInp_t openedDataObjInp;
01269 bytesBuf_t tmpBBuf;
01270 fileLseekOut_t *dataObjLseekOut = NULL;
01271 int fd,i;
01272 #endif // JMC - backport 4760
01273
01274
01275 if (writeId != NULL && strcmp (writeId, "serverLog") == 0) {
01276 rodsLog (LOG_NOTICE, "writeString: inString = %s", writeStr);
01277 return 0;
01278 }
01279 #ifndef DEBUG // JMC - backport 4760
01280
01281
01282
01283 if (writeId != NULL && writeId[0] == '/') {
01284
01285
01286 if (rei == NULL || rei->rsComm == NULL) {
01287 rodsLog (LOG_ERROR, "_writeString: input rei or rsComm is NULL");
01288 return (SYS_INTERNAL_NULL_INPUT_ERR);
01289 }
01290
01291 bzero (&dataObjInp, sizeof (dataObjInp));
01292 dataObjInp.openFlags = O_RDWR;
01293 snprintf (dataObjInp.objPath, MAX_NAME_LEN, "%s",writeId);
01294 fd = rsDataObjOpen (rei->rsComm, &dataObjInp);
01295 if (fd < 0) {
01296 rodsLog (LOG_ERROR, "_writeString: rsDataObjOpen failed. status = %d", fd);
01297 return(fd);
01298 }
01299
01300 bzero(&openedDataObjInp, sizeof(openedDataObjInp));
01301 openedDataObjInp.l1descInx = fd;
01302 openedDataObjInp.offset = 0;
01303 openedDataObjInp.whence = SEEK_END;
01304 i = rsDataObjLseek (rei->rsComm, &openedDataObjInp, &dataObjLseekOut);
01305 if (i < 0) {
01306 rodsLog (LOG_ERROR, "_writeString: rsDataObjLseek failed. status = %d", i);
01307 return(i);
01308 }
01309
01310 bzero(&openedDataObjInp, sizeof(openedDataObjInp));
01311 openedDataObjInp.l1descInx = fd;
01312 tmpBBuf.len = openedDataObjInp.len = strlen(writeStr) + 1;
01313 tmpBBuf.buf = writeStr;
01314 i = rsDataObjWrite (rei->rsComm, &openedDataObjInp, &tmpBBuf);
01315 if (i < 0) {
01316 rodsLog (LOG_ERROR, "_writeString: rsDataObjWrite failed. status = %d", i);
01317 return(i);
01318 }
01319
01320 bzero(&openedDataObjInp, sizeof(openedDataObjInp));
01321 openedDataObjInp.l1descInx = fd;
01322 i = rsDataObjClose (rei->rsComm, &openedDataObjInp);
01323 return(i);
01324 }
01325
01326
01327
01328 #endif // JMC - backport 4760
01329 if ((execOutRes = (Res *)lookupFromEnv(env, "ruleExecOut")) != NULL) {
01330 myExecCmdOut = (execCmdOut_t *)RES_UNINTER_STRUCT(execOutRes);
01331 } else {
01332 Env *global = env;
01333 while(global->previous != NULL) {
01334 global = global->previous;
01335 }
01336 myExecCmdOut = (execCmdOut_t *)malloc (sizeof (execCmdOut_t));
01337 memset (myExecCmdOut, 0, sizeof (execCmdOut_t));
01338 execOutRes = newUninterpretedRes(r, ExecCmdOut_MS_T, myExecCmdOut, NULL);
01339 insertIntoHashTable(global->current, "ruleExecOut", execOutRes);
01340 }
01341
01342 if (!strcmp(writeId,"stdout"))
01343 appendToByteBufNew(&(myExecCmdOut->stdoutBuf),(char *) writeStr);
01344 else if (!strcmp(writeId,"stderr"))
01345 appendToByteBufNew(&(myExecCmdOut->stderrBuf),(char *) writeStr);
01346 return 0;
01347 }
01348
01349 Res *smsi_writeLine(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01350 char *inString = convertResToString(paramsr[1]);
01351 Res *where = (Res *)paramsr[0];
01352 char *whereId = where->text;
01353
01354 if (strcmp (whereId, "serverLog") == 0) {
01355 rodsLog (LOG_NOTICE, "writeLine: inString = %s\n", inString);
01356 free(inString);
01357 return newIntRes(r, 0);
01358 }
01359 int i = writeStringNew(whereId, inString, env, r, rei);
01360 #ifdef DEBUG
01361 printf("%s\n", inString);
01362 #endif
01363
01364 free(inString);
01365 if (i < 0) {
01366 return newErrorRes(r, i);
01367 }
01368 i = writeStringNew(whereId, "\n", env, r, rei);
01369
01370 if (i < 0)
01371 return newErrorRes(r, i);
01372 else
01373 return newIntRes(r, i);
01374 }
01375 Res *smsi_writeString(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01376
01377 char *inString = convertResToString(paramsr[1]);
01378 Res *where = (Res *)paramsr[0];
01379 char *whereId = where->text;
01380
01381 int i = writeStringNew(whereId, inString, env, r, rei);
01382
01383 free(inString);
01384 if (i < 0)
01385 return newErrorRes(r, i);
01386 else
01387 return newIntRes(r, i);
01388 }
01389
01390 Res *smsi_triml(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01391
01392 Res *strres = (Res *)paramsr[0];
01393 Res *delimres = (Res *)paramsr[1];
01394
01395 char *str = strres->text;
01396 char *delim = delimres->text;
01397
01398 char *p = strstr(str, delim);
01399 if(p!=NULL) {
01400
01401 return newStringRes(r, p+strlen(delim));
01402 } else {
01403
01404 return strres;
01405 }
01406
01407
01408
01409 }
01410 Res *smsi_strlen(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01411 Res *strres = (Res *)paramsr[0];
01412 return newIntRes(r, strlen(strres->text));
01413 }
01414
01415 Res *smsi_substr(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01416 Res *strres = (Res *)paramsr[0];
01417 Res *startres = (Res *)paramsr[1];
01418 Res *finishres = (Res *)paramsr[2];
01419
01420 char *buf = strdup(strres->text + RES_INT_VAL(startres));
01421 buf[RES_INT_VAL(finishres) - RES_INT_VAL(startres)] = '\0';
01422
01423 Res *retres = newStringRes(r, buf);
01424 free(buf);
01425 return retres;
01426 }
01427
01428 Res *smsi_split(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01429 Res *strres = (Res *)paramsr[0];
01430 Res *delimres = (Res *)paramsr[1];
01431
01432 char *buf = strdup(strres->text);
01433 int len = strlen(buf);
01434 int count = 0;
01435 int trim = 1;
01436 int i;
01437 for(i=0;i<len;i++) {
01438 if(strchr(delimres->text, buf[i]) != NULL) {
01439 i++;
01440 while(i<len && strchr(delimres->text, buf[i]) != NULL) {
01441 i++;
01442 }
01443 if(!trim && i<len) {
01444 count++;
01445 }
01446 } else {
01447 trim = 0;
01448 }
01449 }
01450 if(!trim) {
01451 count ++;
01452 }
01453
01454 Res *coll = newCollRes(count, newSimpType(T_STRING, r), r);
01455
01456 int j=0;
01457 trim = 1;
01458 char *bufStart = buf;
01459 for(i=0;i<len;i++) {
01460 if(strchr(delimres->text, buf[i]) != NULL) {
01461 buf[i] = '\0';
01462 if(!trim) {
01463 coll->subtrees[j++] = newStringRes(r, bufStart);
01464 }
01465 i++;
01466 while(i<len && strchr(delimres->text, buf[i]) != NULL) {
01467 i++;
01468 }
01469 bufStart = buf + i;
01470 } else {
01471 trim = 0;
01472 }
01473 }
01474 if(j!=count) {
01475 coll->subtrees[j++] = newStringRes(r, bufStart);
01476 }
01477
01478 return coll;
01479
01480 }
01481
01482 Res *smsi_undefined(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01483 return newUnspecifiedRes(r);
01484
01485 }
01486 Res *smsi_trimr(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01487 Res *strres = (Res *)paramsr[0];
01488 Res *delimres = (Res *)paramsr[1];
01489
01490 char *str = strres->text;
01491 char *delim = delimres->text;
01492
01493 if(strlen(delim)==0) {
01494 return strres;
01495 }
01496
01497 char *p = strstr(str, delim);
01498 char *newp = NULL;
01499 while(p!=NULL) {
01500 newp = p;
01501 p = strstr(p+1, delim);
01502 }
01503 if(newp == NULL) {
01504
01505 return strres;
01506 } else {
01507
01508 char temp = *newp;
01509 *newp = '\0';
01510
01511 Res *res = newStringRes(r, str);
01512
01513 *newp = temp;
01514 return res;
01515 }
01516
01517 }
01518
01519 Res *smsi_msiAdmShowIRB(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01520 char buf[1024*16];
01521 int i;
01522 if(isComponentInitialized(ruleEngineConfig.extRuleSetStatus)) {
01523 for(i=0;i<ruleEngineConfig.extRuleSet->len;i++) {
01524 ruleToString(buf, 1024*16, ruleEngineConfig.extRuleSet->rules[i]);
01525 #ifdef DEBUG_VERBOSE
01526 printf("%s", buf);
01527 #endif
01528 writeStringNew("stdout", buf, env, r, rei );
01529 }
01530 }
01531 if(isComponentInitialized(ruleEngineConfig.appRuleSetStatus)) {
01532 for(i=0;i<ruleEngineConfig.appRuleSet->len;i++) {
01533 ruleToString(buf, 1024*16, ruleEngineConfig.appRuleSet->rules[i]);
01534 #ifdef DEBUG_VERBOSE
01535 printf("%s", buf);
01536 #endif
01537 writeStringNew("stdout", buf, env, r, rei );
01538 }
01539 }
01540 if(isComponentInitialized(ruleEngineConfig.coreRuleSetStatus)) {
01541 for(i=0;i<ruleEngineConfig.coreRuleSet->len;i++) {
01542 ruleToString(buf, 1024*16, ruleEngineConfig.coreRuleSet->rules[i]);
01543 #ifdef DEBUG_VERBOSE
01544 printf("%s", buf);
01545 #endif
01546 writeStringNew("stdout", buf, env, r, rei );
01547 }
01548 }
01549 return newIntRes(r, 0);
01550 }
01551 Res *smsi_msiAdmShowCoreRE(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01552 char buf[1024];
01553 char *conDir = getConfigDir ();
01554 char file2[1024];
01555 snprintf(file2, 1024, "%s/reConfigs/core.re",
01556 conDir);
01557 FILE *f2 = fopen(file2, "r");
01558
01559 while(!feof(f2) && ferror(f2) == 0) {
01560 if(fgets(buf, 1024, f2)!=NULL) {
01561 #ifdef DEBUG_VERBOSE
01562 printf("%s", buf);
01563 #endif
01564 writeStringNew("stdout", buf, env, r, rei);
01565 }
01566 }
01567 fclose(f2);
01568 return newIntRes(r, 0);
01569 }
01570 Res *smsi_msiAdmClearAppRuleStruct(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01571
01572 int i;
01573 #ifndef DEBUG
01574 if ((i = isUserPrivileged(rei->rsComm)) != 0)
01575 return newErrorRes(r, i);
01576 i = unlinkFuncDescIndex();
01577 if (i < 0)
01578 return newErrorRes(r, i);
01579 i = clearResources(RESC_APP_RULE_SET | RESC_APP_FUNC_DESC_INDEX);
01580 if (i < 0)
01581 return newErrorRes(r, i);
01582 i = generateFunctionDescriptionTables();
01583 if (i < 0)
01584 return newErrorRes(r, i);
01585 i = clearDVarStruct(&appRuleVarDef);
01586 if (i < 0)
01587 return newErrorRes(r, i);
01588 i = clearFuncMapStruct(&appRuleFuncMapDef);
01589 return newIntRes(r, i);
01590 #else
01591 i = unlinkFuncDescIndex();
01592 i = clearResources(RESC_APP_RULE_SET | RESC_APP_FUNC_DESC_INDEX);
01593 i = generateFunctionDescriptionTables();
01594 return newIntRes(r, 0);
01595 #endif
01596
01597 }
01598 Res *smsi_msiAdmAddAppRuleStruct(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01599 int i;
01600
01601 #ifndef DEBUG
01602 if ((i = isUserPrivileged(rei->rsComm)) != 0)
01603 return newErrorRes(r, i);
01604
01605 if (strlen(paramsr[0]->text) > 0) {
01606 i = loadRuleFromCacheOrFile(RULE_ENGINE_TRY_CACHE, paramsr[0]->text, &appRuleStrct);
01607 if (i < 0)
01608 return newErrorRes(r, i);
01609 }
01610 if (strlen(paramsr[1]->text) > 0) {
01611 i = readDVarStructFromFile(paramsr[1]->text, &appRuleVarDef);
01612 if (i < 0)
01613 return newErrorRes(r, i);
01614 }
01615 if (strlen(paramsr[2]->text) > 0) {
01616 i = readFuncMapStructFromFile(paramsr[2]->text, &appRuleFuncMapDef);
01617 if (i < 0)
01618 return newErrorRes(r, i);
01619 }
01620 return newIntRes(r, 0);
01621 #else
01622 i = loadRuleFromCacheOrFile(RULE_ENGINE_TRY_CACHE, paramsr[0]->text, &appRuleStrct);
01623 if(i<0) {
01624 return newErrorRes(r, i);
01625 } else {
01626 return newIntRes(r, i);
01627 }
01628
01629 #endif
01630
01631 }
01632
01633 Res *smsi_msiAdmAppendToTopOfCoreRE(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01634 #ifndef DEBUG
01635 int i;
01636 if ((i = isUserPrivileged(rei->rsComm)) != 0)
01637 return newErrorRes(r, i);
01638 #endif
01639 char *conDir = getConfigDir ();
01640 char file1[1024];
01641 char file2[1024];
01642 char file3[1024];
01643 snprintf(file1, 1024, "%s/reConfigs/%s.re",
01644 conDir, paramsr[0]->text);
01645 snprintf(file2, 1024, "%s/reConfigs/core.re",
01646 conDir);
01647 snprintf(file3, 1024, "%s/reConfigs/core.tmp", conDir);
01648 int errcode;
01649 if((errcode = fileConcatenate(file1, file2, file3))!=0 || (errcode = remove(file2))!=0 || (errcode = rename(file3, file2))!=0) {
01650 generateAndAddErrMsg("error appending to top of core.re", node, errcode, errmsg);
01651 return newErrorRes(r, errcode);
01652 }
01653 return newIntRes(r, 0);
01654
01655 }
01656 Res *smsi_msiAdmChangeCoreRE(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01657 #ifndef DEBUG
01658 int i;
01659 if ((i = isUserPrivileged(rei->rsComm)) != 0)
01660 return newErrorRes(r, i);
01661 #endif
01662 char *conDir = getConfigDir ();
01663 char file1[1024];
01664 char file2[1024];
01665 snprintf(file1, 1024, "%s/reConfigs/%s.re",
01666 conDir, paramsr[0]->text);
01667 snprintf(file2, 1024, "%s/reConfigs/core.re",
01668 conDir);
01669 int errcode;
01670 if((errcode = fileConcatenate(file1, NULL, file2))!=0) {
01671 generateAndAddErrMsg("error changing core.re", node, errcode, errmsg);
01672 return newErrorRes(r, errcode);
01673 }
01674 return newIntRes(r, 0);
01675
01676 }
01677
01678 int insertRulesIntoDBNew(char * baseName, RuleSet *ruleSet, ruleExecInfo_t *rei);
01679
01680 Res * smsi_msiAdmInsertRulesFromStructIntoDB(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01681 {
01682
01683
01684 int i;
01685 #ifndef DEBUG
01686 if ((i = isUserPrivileged(rei->rsComm)) != 0) {
01687 generateAndAddErrMsg("error inserting rules into database", node, i, errmsg);
01688 return newErrorRes(r, i);
01689 }
01690 #endif
01691
01692 if (paramsr[0]->text == NULL ||
01693 strlen(paramsr[0]->text) == 0 ) {
01694 generateAndAddErrMsg("empty input struct", node, PARAOPR_EMPTY_IN_STRUCT_ERR, errmsg);
01695 return newErrorRes(r, PARAOPR_EMPTY_IN_STRUCT_ERR);
01696 }
01697
01698 RuleSet *rs = (RuleSet *)RES_UNINTER_STRUCT(paramsr[1]);
01699 i = insertRulesIntoDBNew(paramsr[0]->text, rs, rei);
01700 if(i<0) {
01701 generateAndAddErrMsg("error inserting rules into database", node, PARAOPR_EMPTY_IN_STRUCT_ERR, errmsg);
01702 return newErrorRes(r, i);
01703 } else {
01704 return newIntRes(r, i);
01705 }
01706
01707 }
01708 Res * smsi_msiAdmReadRulesFromFileIntoStruct(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01709 {
01710
01711 int i;
01712 RuleSet *ruleSet;
01713
01714 #ifndef DEBUG
01715 if ((i = isUserPrivileged(rei->rsComm)) != 0) {
01716 generateAndAddErrMsg("error inserting rules into database", node, i, errmsg);
01717 return newErrorRes(r, i);
01718 }
01719 #endif
01720
01721
01722
01723
01724 if (paramsr[0]->text == NULL ||
01725 strlen(paramsr[0]->text) == 0 ) {
01726 generateAndAddErrMsg("empty input struct", node, PARAOPR_EMPTY_IN_STRUCT_ERR, errmsg);
01727 return newErrorRes(r, PARAOPR_EMPTY_IN_STRUCT_ERR);
01728 }
01729 Region *rsr = make_region(0, NULL);
01730
01731 ruleSet = newRuleSet(rsr);
01732
01733 Env *rsEnv = newEnv(newHashTable2(100, rsr), NULL, NULL, rsr);
01734
01735 int errloc = 0;
01736 i = readRuleSetFromFile(paramsr[0]->text, ruleSet, rsEnv, &errloc, errmsg, rsr);
01737
01738 if (i != 0) {
01739 region_free(rsr);
01740 generateAndAddErrMsg("error reading rules from file.", node, i, errmsg);
01741 return newErrorRes(r, i);
01742 }
01743
01744 Hashtable *objectMap = newHashTable2(100, rsr);
01745 RuleSet *buf = memCpRuleSet(ruleSet, objectMap);
01746 if(buf == NULL) {
01747 return newErrorRes(r, RE_OUT_OF_MEMORY);
01748 }
01749
01750 paramsr[1] = newUninterpretedRes(r, RuleSet_MS_T, (void *) buf, NULL);
01751
01752 region_free(rsr);
01753 return newIntRes(r, 0);
01754 }
01755
01756 Res *smsi_msiAdmWriteRulesFromStructIntoFile(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01757 int i;
01758 FILE *file;
01759 char fileName[MAX_NAME_LEN];
01760 char *configDir;
01761
01762 char *inFileName = paramsr[0]->text;
01763 if (inFileName[0] == '/' || inFileName[0] == '\\' ||
01764 inFileName[1] == ':') {
01765 snprintf (fileName,MAX_NAME_LEN, "%s",inFileName);
01766 }
01767 else {
01768 configDir = getConfigDir ();
01769 snprintf (fileName,MAX_NAME_LEN, "%s/reConfigs/%s.re", configDir,inFileName);
01770 }
01771
01772
01773 file = fopen(fileName, "w");
01774 if (file == NULL) {
01775 rodsLog(LOG_NOTICE,
01776 "msiAdmWriteRulesFromStructToFile could not open rules file %s for writing\n",
01777 fileName);
01778 generateAndAddErrMsg("error opening file for writing.", node, FILE_OPEN_ERR, errmsg);
01779 return newErrorRes(r, FILE_OPEN_ERR);
01780 }
01781
01782 RuleSet *ruleSet = (RuleSet *) RES_UNINTER_STRUCT(paramsr[1]);
01783 char buf[1024*16];
01784 for(i=0;i<ruleSet->len;i++) {
01785 ruleToString(buf, 1024*16, ruleSet->rules[i]);
01786 fprintf(file, "%s", buf);
01787 }
01788 fclose (file);
01789 return newIntRes(r, 0);
01790 }
01791
01792
01793
01794
01795 int readRuleSetFromDB(char *ruleBaseName, char *versionStr, RuleSet *rs, ruleExecInfo_t *rei, rError_t *errmsg, Region *r);
01796
01797 Res * smsi_msiAdmRetrieveRulesFromDBIntoStruct(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01798 {
01799
01800 int i;
01801 RuleSet *ruleSet;
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812 if (paramsr[0]->text == NULL ||
01813 strlen(paramsr[0]->text) == 0 ) {
01814 generateAndAddErrMsg("empty input struct", node, PARAOPR_EMPTY_IN_STRUCT_ERR, errmsg);
01815 return newErrorRes(r, PARAOPR_EMPTY_IN_STRUCT_ERR);
01816 }
01817 if (paramsr[1]->text == NULL ||
01818 strlen(paramsr[1]->text) == 0 ) {
01819 generateAndAddErrMsg("empty input struct", node, PARAOPR_EMPTY_IN_STRUCT_ERR, errmsg);
01820 return newErrorRes(r, PARAOPR_EMPTY_IN_STRUCT_ERR);
01821 }
01822 Region *rsr = make_region(0, NULL);
01823
01824 ruleSet = newRuleSet(rsr);
01825
01826
01827
01828 i = readRuleSetFromDB(paramsr[0]->text, paramsr[1]->text, ruleSet, rei, errmsg, rsr);
01829
01830 if (i != 0) {
01831 region_free(rsr);
01832 generateAndAddErrMsg("error retrieving rules from database.", node, i, errmsg);
01833 return newErrorRes(r, i);
01834 }
01835
01836 Hashtable *objectMap = newHashTable2(100, rsr);
01837 RuleSet *buf = memCpRuleSet(ruleSet, objectMap);
01838 if(buf == NULL) {
01839 return newErrorRes(r, RE_OUT_OF_MEMORY);
01840 }
01841
01842 paramsr[2] = newUninterpretedRes(r, RuleSet_MS_T, (void *) buf, NULL);
01843
01844 region_free(rsr);
01845 return newIntRes(r, 0);
01846 }
01847
01848
01849 Res *smsi_getstdout(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01850 Res *res = (Res *)lookupFromEnv(env, "ruleExecOut");
01851 if(res == NULL) {
01852 generateAndAddErrMsg("ruleExecOut not set", node, RE_RUNTIME_ERROR, errmsg);
01853 return newErrorRes(r, RE_RUNTIME_ERROR);
01854 }
01855
01856 execCmdOut_t *out = (execCmdOut_t *)RES_UNINTER_STRUCT(res);
01857 int start = strlen((char *)out->stdoutBuf.buf);
01858 Res *ret = smsi_do(paramsr, 1, node, rei, reiSaveFlag, env, errmsg, r);
01859
01860 paramsr[1] = newStringRes(r, ((char *)out->stdoutBuf.buf + start));
01861 return ret;
01862 }
01863
01864 Res *smsi_getstderr(Node **paramsr, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01865 Res *res = (Res *)lookupFromEnv(env, "ruleExecOut");
01866 if(res == NULL) {
01867 generateAndAddErrMsg("ruleExecOut not set", node, RE_RUNTIME_ERROR, errmsg);
01868 return newErrorRes(r, RE_RUNTIME_ERROR);
01869 }
01870
01871 execCmdOut_t *out = (execCmdOut_t *)RES_UNINTER_STRUCT(res);
01872 int start = strlen((char *)out->stderrBuf.buf);
01873 Res *ret = smsi_do(paramsr, 1, node, rei, reiSaveFlag, env, errmsg, r);
01874 paramsr[1] = newStringRes(r, ((char *)out->stderrBuf.buf + start));
01875 return ret;
01876 }
01877
01878 Res *smsi_assignStr(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r) {
01879 Res *val = evaluateExpression3((Node *)subtrees[1], 0, 1, rei, reiSaveFlag, env, errmsg,r);
01880 if(getNodeType(val) == N_ERROR) {
01881 return val;
01882 }
01883 if(TYPE(val) == T_INT || TYPE(val) == T_DOUBLE || TYPE(val) == T_BOOL) {
01884 CASCADE_N_ERROR(val = smsi_str(&val, 1, node, rei, reiSaveFlag, env, errmsg, r));
01885 }
01886 Res *ret = matchPattern(subtrees[0], val, env, rei, reiSaveFlag, errmsg, r);
01887
01888 return ret;
01889
01890 }
01891
01892 extern int GlobalAllRuleExecFlag;
01893 Res *smsi_applyAllRules(Node **subtrees, int n, Node *node, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
01894 {
01895 Res *res;
01896 Node *action;
01897 int reiSaveFlag2;
01898 int allRuleExecFlag;
01899
01900 action = subtrees[0];
01901 reiSaveFlag2 = RES_INT_VAL(subtrees[1]);
01902 allRuleExecFlag = RES_INT_VAL(subtrees[2]);
01903
01904 res = evaluateExpression3(action, allRuleExecFlag == 1 ? 2 : 1, 1, rei, reiSaveFlag2, env, errmsg, r);
01905
01906 return res;
01907
01908 }
01909
01910
01911
01912 int fileConcatenate(char *file1, char *file2, char *file3) {
01913 char buf[1024];
01914 FILE *f1 = fopen(file1, "r");
01915 if(f1 == NULL) {
01916 return USER_FILE_DOES_NOT_EXIST;
01917 }
01918 FILE *f2;
01919 if(file2 == NULL) {
01920 f2 = NULL;
01921 } else {
01922 f2 = fopen(file2, "r");
01923 if(f2 == NULL) {
01924 fclose(f1);
01925 return USER_FILE_DOES_NOT_EXIST;
01926 }
01927 }
01928 FILE *f3 = fopen(file3, "w");
01929
01930 size_t len;
01931 int error = 0;
01932 while(!feof(f1) && ferror(f1) == 0) {
01933 len = fread(buf, 1, 1024, f1);
01934 fwrite(buf, 1, len, f3);
01935 }
01936 error = ferror(f1);
01937 if(error==0 && f2!=NULL) {
01938 while(!feof(f2) && ferror(f2) == 0) {
01939 len = fread(buf, 1, 1024, f2);
01940 fwrite(buf, 1, len, f3);
01941 }
01942 error = ferror(f2);
01943 }
01944
01945 fclose(f1);
01946 if(f2!=NULL) {
01947 fclose(f2);
01948 }
01949 fclose(f3);
01950 return error;
01951 }
01952
01953 Res* eval(char *expr, Env *env, ruleExecInfo_t *rei, int saveREI, rError_t *errmsg, Region *r) {
01954 Res *res = parseAndComputeExpression(expr, env, rei, saveREI, errmsg, r);
01955 return res;
01956 }
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975 Node *construct(char *fn, Node **args, int argc, Node *constype, Region *r) {
01976 Node *res = newRes(r);
01977 res->text = cpStringExt(fn, r);
01978 res->degree = argc;
01979 res->subtrees = (Node **)region_alloc(r, sizeof(Node *)*argc);
01980 memcpy(res->subtrees, args, sizeof(Node *)*argc);
01981 res->exprType = constype;
01982 return res;
01983 }
01984
01985 Node *deconstruct(char *fn, Node **args, int argc, int proj, rError_t*errmsg, Region *r) {
01986 Node *res = args[0]->subtrees[proj];
01987 return res;
01988 }
01989
01990 void getSystemFunctions(Hashtable *ft, Region *r) {
01991 insertIntoHashTable(ft, "do", newFunctionFD("e ?->?", smsi_do, r));
01992 insertIntoHashTable(ft, "eval", newFunctionFD("string->?", smsi_eval, r));
01993 insertIntoHashTable(ft, "evalrule", newFunctionFD("string->?", smsi_evalrule, r));
01994 insertIntoHashTable(ft, "applyAllRules", newFunctionFD("e ? * f 0{integer string } => integer * f 1{integer string} => integer->?", smsi_applyAllRules, r));
01995 insertIntoHashTable(ft, "errorcodea", newFunctionFD("a ? * a ?->integer", smsi_errorcode, r));
01996 insertIntoHashTable(ft, "errorcode", newFunctionFD("e ?->integer", smsi_errorcode, r));
01997 insertIntoHashTable(ft, "errormsga", newFunctionFD("a ? * a ? * o string->integer", smsi_errormsg, r));
01998 insertIntoHashTable(ft, "errormsg", newFunctionFD("e ? * o string->integer", smsi_errormsg, r));
01999 insertIntoHashTable(ft, "getstdout", newFunctionFD("e ? * o string ->integer", smsi_getstdout, r));
02000 insertIntoHashTable(ft, "getstderr", newFunctionFD("e ? * o string ->integer", smsi_getstderr, r));
02001 insertIntoHashTable(ft, "let", newFunctionFD("e 0 * e f 0 * e 1->1", smsi_letExec, r));
02002 insertIntoHashTable(ft, "match", newFunctionFD("e 0 * e (0 * 1)*->1", smsi_matchExec, r));
02003 insertIntoHashTable(ft, "if2", newFunctionFD("e boolean * e 0 * e 0 * e ? * e ?->0", smsi_if2Exec, r));
02004 insertIntoHashTable(ft, "if", newFunctionFD("e boolean * a ? * a ? * a ? * a ?->?", smsi_ifExec, r));
02005 insertIntoHashTable(ft, "for", newFunctionFD("e ? * e boolean * e ? * a ? * a ?->?",smsi_forExec, r));
02006 insertIntoHashTable(ft, "while", newFunctionFD("e boolean * a ? * a ?->?",smsi_whileExec, r));
02007 insertIntoHashTable(ft, "foreach", newFunctionFD("e list 0 * a ? * a ?->?", smsi_forEachExec, r));
02008 insertIntoHashTable(ft, "foreach2", newFunctionFD("forall X, e X * e list X * a ? * a ?->?", smsi_forEach2Exec, r));
02009 insertIntoHashTable(ft, "break", newFunctionFD("->integer", smsi_break, r));
02010 insertIntoHashTable(ft, "succeed", newFunctionFD("->integer", smsi_succeed, r));
02011 insertIntoHashTable(ft, "fail", newFunctionFD("integer ?->integer", smsi_fail, r));
02012 insertIntoHashTable(ft, "assign", newFunctionFD("e 0 * e f 0->integer", smsi_assign, r));
02013 insertIntoHashTable(ft, "lmsg", newFunctionFD("string->integer", smsi_lmsg, r));
02014 insertIntoHashTable(ft, "listvars", newFunctionFD("->string", smsi_listvars, r));
02015 insertIntoHashTable(ft, "listcorerules", newFunctionFD("->list string", smsi_listcorerules, r));
02016 insertIntoHashTable(ft, "listapprules", newFunctionFD("->list string", smsi_listapprules, r));
02017 insertIntoHashTable(ft, "listextrules", newFunctionFD("->list string", smsi_listextrules, r));
02018
02019
02020 insertIntoHashTable(ft, "time", newFunctionFD("->time", smsi_time, r));
02021 insertIntoHashTable(ft, "timestr", newFunctionFD("time->string", smsi_timestr, r));
02022 insertIntoHashTable(ft, "str", newFunctionFD("?->string", smsi_str, r));
02023 insertIntoHashTable(ft, "datetime", newFunctionFD("string->time", smsi_datetime, r));
02024 insertIntoHashTable(ft, "timestrf", newFunctionFD("time * string->string", smsi_timestr, r));
02025 insertIntoHashTable(ft, "datetimef", newFunctionFD("string * string->time", smsi_datetime, r));
02026 insertIntoHashTable(ft, "double", newFunctionFD("f 0{string double time}->double", smsi_double, r));
02027 insertIntoHashTable(ft, "int", newFunctionFD("0{integer string double}->integer", smsi_int, r));
02028 insertIntoHashTable(ft, "bool", newFunctionFD("0{boolean integer string double}->boolean", smsi_bool, r));
02029 insertIntoHashTable(ft, "list", newFunctionFD("forall X, X*->list X", smsi_list, r));
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042 insertIntoHashTable(ft, "elem", newFunctionFD("forall X, list X * integer->X", smsi_elem, r));
02043 insertIntoHashTable(ft, "setelem", newFunctionFD("forall X, list X * integer * X->list X", smsi_setelem, r));
02044 insertIntoHashTable(ft, "hd", newFunctionFD("forall X, list X->X", smsi_hd, r));
02045 insertIntoHashTable(ft, "tl", newFunctionFD("forall X, list X->list X", smsi_tl, r));
02046 insertIntoHashTable(ft, "cons", newFunctionFD("forall X, X * list X->list X", smsi_cons, r));
02047 insertIntoHashTable(ft, "size", newFunctionFD("forall X, list X->integer", smsi_size, r));
02048 insertIntoHashTable(ft, "type", newFunctionFD("forall X, X->string",smsi_type, r));
02049 insertIntoHashTable(ft, "arity", newFunctionFD("string->integer",smsi_arity, r));
02050 insertIntoHashTable(ft, "+", newFunctionFD("forall X in {integer double}, f X * f X->X",smsi_add, r));
02051 insertIntoHashTable(ft, "++", newFunctionFD("f string * f string->string",smsi_concat, r));
02052 insertIntoHashTable(ft, "-", newFunctionFD("forall X in {integer double}, f X * f X->X",smsi_subtract, r));
02053 insertIntoHashTable(ft, "neg", newFunctionFD("forall X in {integer double}, X-> X", smsi_negate, r));
02054 insertIntoHashTable(ft, "*", newFunctionFD("forall X in {integer double}, f X * f X->X",smsi_multiply, r));
02055 insertIntoHashTable(ft, "/", newFunctionFD("forall X in {integer double}, f X * f X->?",smsi_divide, r));
02056 insertIntoHashTable(ft, "%", newFunctionFD("integer * integer->integer",smsi_modulo, r));
02057 insertIntoHashTable(ft, "^", newFunctionFD("f double * f double->double",smsi_power, r));
02058 insertIntoHashTable(ft, "^^", newFunctionFD("f double * f double->double",smsi_root, r));
02059 insertIntoHashTable(ft, "log", newFunctionFD("f double->double",smsi_log, r));
02060 insertIntoHashTable(ft, "exp", newFunctionFD("f double->double",smsi_exp, r));
02061 insertIntoHashTable(ft, "!", newFunctionFD("boolean->boolean",smsi_not, r));
02062 insertIntoHashTable(ft, "&&", newFunctionFD("boolean * boolean->boolean",smsi_and, r));
02063 insertIntoHashTable(ft, "||", newFunctionFD("boolean * boolean->boolean",smsi_or, r));
02064 insertIntoHashTable(ft, "%%", newFunctionFD("boolean * boolean->boolean",smsi_or, r));
02065 insertIntoHashTable(ft, "==", newFunctionFD("forall X in {integer double boolean string time}, f X * f X->boolean",smsi_eq, r));
02066 insertIntoHashTable(ft, "!=", newFunctionFD("forall X in {integer double boolean string time}, f X * f X->boolean",smsi_neq, r));
02067 insertIntoHashTable(ft, ">", newFunctionFD("forall X in {integer double string time}, f X * f X->boolean", smsi_gt, r));
02068 insertIntoHashTable(ft, "<", newFunctionFD("forall X in {integer double string time}, f X * f X->boolean", smsi_lt, r));
02069 insertIntoHashTable(ft, ">=", newFunctionFD("forall X in {integer double string time}, f X * f X->boolean", smsi_ge, r));
02070 insertIntoHashTable(ft, "<=", newFunctionFD("forall X in {integer double string time}, f X * f X->boolean", smsi_le, r));
02071 insertIntoHashTable(ft, "floor", newFunctionFD("f double->double", smsi_floor, r));
02072 insertIntoHashTable(ft, "ceiling", newFunctionFD("f double->double", smsi_ceiling, r));
02073 insertIntoHashTable(ft, "abs", newFunctionFD("f double->double", smsi_abs, r));
02074 insertIntoHashTable(ft, "max", newFunctionFD("f double+->double", smsi_max, r));
02075 insertIntoHashTable(ft, "min", newFunctionFD("f double+->double", smsi_min, r));
02076 insertIntoHashTable(ft, "average", newFunctionFD("f double+->double", smsi_average, r));
02077 insertIntoHashTable(ft, "like", newFunctionFD("string * string->boolean", smsi_like, r));
02078 insertIntoHashTable(ft, "not like", newFunctionFD("string * string->boolean", smsi_not_like, r));
02079 insertIntoHashTable(ft, "like regex", newFunctionFD("string * string->boolean", smsi_like_regex, r));
02080 insertIntoHashTable(ft, "not like regex", newFunctionFD("string * string->boolean", smsi_not_like_regex, r));
02081 insertIntoHashTable(ft, "delayExec", newFunctionFD("string * string * string->integer", smsi_delayExec, r));
02082 insertIntoHashTable(ft, "remoteExec", newFunctionFD("string * string * string * string->integer", smsi_remoteExec,r));
02083 insertIntoHashTable(ft, "writeLine", newFunctionFD("string * ?->integer", smsi_writeLine,r));
02084 insertIntoHashTable(ft, "writeString", newFunctionFD("string * ?->integer", smsi_writeString,r));
02085 insertIntoHashTable(ft, "triml", newFunctionFD("string * string->string", smsi_triml, r));
02086 insertIntoHashTable(ft, "trimr", newFunctionFD("string * string->string", smsi_trimr, r));
02087 insertIntoHashTable(ft, "strlen", newFunctionFD("string->integer", smsi_strlen, r));
02088 insertIntoHashTable(ft, "substr", newFunctionFD("string * integer * integer->string", smsi_substr, r));
02089 insertIntoHashTable(ft, "split", newFunctionFD("string * string -> list string", smsi_split, r));
02090 insertIntoHashTable(ft, "unspeced", newFunctionFD("-> ?", smsi_undefined, r));
02091 insertIntoHashTable(ft, "msiAdmShowIRB", newFunctionFD("e ? ?->integer", smsi_msiAdmShowIRB, r));
02092 insertIntoHashTable(ft, "msiAdmShowCoreRE", newFunctionFD("e ? ?->integer", smsi_msiAdmShowCoreRE, r));
02093 #ifdef DEBUG
02094 insertIntoHashTable(ft, "msiAdmAddAppRuleStruct", newFunctionFD("string->integer", smsi_msiAdmAddAppRuleStruct, r));
02095 #else
02096 insertIntoHashTable(ft, "msiAdmAddAppRuleStruct", newFunctionFD("string * string * string->integer", smsi_msiAdmAddAppRuleStruct, r));
02097 #endif
02098 insertIntoHashTable(ft, "msiAdmClearAppRuleStruct", newFunctionFD("->integer", smsi_msiAdmClearAppRuleStruct, r));
02099 insertIntoHashTable(ft, "msiAdmAppendToTopOfCoreRE", newFunctionFD("string->integer", smsi_msiAdmAppendToTopOfCoreRE, r));
02100 insertIntoHashTable(ft, "msiAdmChangeCoreRE", newFunctionFD("string->integer", smsi_msiAdmChangeCoreRE, r));
02101 insertIntoHashTable(ft, "msiAdmInsertRulesFromStructIntoDB", newFunctionFD("string * `RuleSet_PI` -> integer", smsi_msiAdmInsertRulesFromStructIntoDB, r));
02102 insertIntoHashTable(ft, "msiAdmReadRulesFromFileIntoStruct", newFunctionFD("string * d `RuleSet_PI` -> integer", smsi_msiAdmReadRulesFromFileIntoStruct, r));
02103 insertIntoHashTable(ft, "msiAdmWriteRulesFromStructIntoFile", newFunctionFD("string * `RuleSet_PI` -> integer", smsi_msiAdmWriteRulesFromStructIntoFile, r));
02104 insertIntoHashTable(ft, "msiAdmRetrieveRulesFromDBIntoStruct", newFunctionFD("string * string * d `RuleSet_PI` -> integer", smsi_msiAdmRetrieveRulesFromDBIntoStruct, r));
02105 insertIntoHashTable(ft, "rei->doi->dataSize", newFunctionFD("double", (SmsiFuncTypePtr) NULL, r));
02106
02107 #ifdef RE_BACKWARD_COMPATIBLE // JMC - backport 4545
02108 insertIntoHashTable(ft, "assignStr", newFunctionFD("e ? * e ?->integer", smsi_assignStr, r));
02109 insertIntoHashTable(ft, "ifExec", newFunctionFD("e boolean * a ? * a ? * a ? * a ?->?", smsi_ifExec, r));
02110 insertIntoHashTable(ft, "forExec", newFunctionFD("e ? * e boolean * a ? * a ? * a ?->?", smsi_forExec, r));
02111 insertIntoHashTable(ft, "whileExec", newFunctionFD("e boolean * a ? * a ?->?", smsi_whileExec, r));
02112 insertIntoHashTable(ft, "forEachExec", newFunctionFD("e list 0 * a ? * a ?->?", smsi_forEachExec, r));
02113 insertIntoHashTable(ft, "msiGetRulesFromDBIntoStruct", newFunctionFD("string * string * d `RuleSet_PI` -> integer", smsi_msiAdmRetrieveRulesFromDBIntoStruct, r));
02114 #endif
02115
02116 }