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