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