00001
00002
00003 #include "debug.h"
00004 #ifdef DEBUG
00005 #include "re.h"
00006 #else
00007 #include "reGlobalsExtern.h"
00008 #include "reHelpers1.h"
00009 #endif
00010 #include "rules.h"
00011 #include "index.h"
00012 #include "functions.h"
00013 #include "arithmetics.h"
00014 #include "configuration.h"
00015 #include "filesystem.h"
00016
00017
00018
00019 #define RE_ERROR(cond) if(cond) { goto error; }
00020
00021 extern int GlobalAllRuleExecFlag;
00022
00023
00024
00025
00026
00027
00028
00029 int readRuleSetFromFile(char *ruleBaseName, RuleSet *ruleSet, Env *funcDesc, int* errloc, rError_t *errmsg, Region *r) {
00030 char rulesFileName[MAX_NAME_LEN];
00031 getRuleBasePath(ruleBaseName, rulesFileName);
00032
00033 return readRuleSetFromLocalFile(ruleBaseName, rulesFileName, ruleSet, funcDesc, errloc, errmsg,r);
00034 }
00035 int readRuleSetFromLocalFile(char *ruleBaseName, char *rulesFileName, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r) {
00036
00037 FILE *file;
00038 char errbuf[ERR_MSG_LEN];
00039 file = fopen(rulesFileName, "r");
00040 if (file == NULL) {
00041 snprintf(errbuf, ERR_MSG_LEN,
00042 "readRuleSetFromFile() could not open rules file %s\n",
00043 rulesFileName);
00044 addRErrorMsg(errmsg, RULES_FILE_READ_ERROR, errbuf);
00045 return(RULES_FILE_READ_ERROR);
00046 }
00047 Pointer *e = newPointer(file, ruleBaseName);
00048 int ret = parseRuleSet(e, ruleSet, funcDesc, errloc, errmsg, r);
00049 deletePointer(e);
00050 if(ret < 0) {
00051 return ret;
00052 }
00053
00054 Node *errnode;
00055 ExprType *restype = typeRuleSet(ruleSet, errmsg, &errnode, r);
00056 if(getNodeType(restype) == T_ERROR) {
00057 *errloc = NODE_EXPR_POS(errnode);
00058 return RE_TYPE_ERROR;
00059 }
00060
00061 return 0;
00062 }
00063 execCmdOut_t *addCmdExecOutToEnv(Env *global, Region *r) {
00064 execCmdOut_t *ruleExecOut = (execCmdOut_t *)malloc (sizeof (execCmdOut_t));
00065 memset (ruleExecOut, 0, sizeof (execCmdOut_t));
00066 ruleExecOut->stdoutBuf.buf = strdup("");
00067 ruleExecOut->stdoutBuf.len = 0;
00068 ruleExecOut->stderrBuf.buf = strdup("");
00069 ruleExecOut->stderrBuf.len = 0;
00070 Res *execOutRes = newUninterpretedRes(r, ExecCmdOut_MS_T, ruleExecOut, NULL);
00071 insertIntoHashTable(global->current, "ruleExecOut", execOutRes);
00072 return ruleExecOut;
00073
00074 }
00075
00076 void freeCmdExecOut(execCmdOut_t *ruleExecOut) {
00077 if(ruleExecOut!=NULL) {
00078 if(ruleExecOut->stdoutBuf.buf!=0) {
00079 free(ruleExecOut->stdoutBuf.buf);
00080 }
00081 if(ruleExecOut->stderrBuf.buf!=0) {
00082 free(ruleExecOut->stderrBuf.buf);
00083 }
00084 free(ruleExecOut);
00085 }
00086
00087 }
00088
00089 int parseAndComputeMsParamArrayToEnv(msParamArray_t *var, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r) {
00090 int i;
00091 for(i=0;i<var->len;i++) {
00092 Res *res = newRes(r);
00093 int ret = convertMsParamToRes(var->msParam[i], res, errmsg, r);
00094 if(ret != 0) {
00095 return ret;
00096 }
00097 char *varName = var->msParam[i]->label;
00098 if(TYPE(res) == T_UNSPECED) {
00099 if(varName!=NULL) {
00100 updateInEnv(env, varName, res);
00101 }
00102 continue;
00103 }
00104 if(TYPE(res) != T_STRING) {
00105 return -1;
00106 }
00107
00108 char *expr = res->text;
00109 res = parseAndComputeExpression(expr, env, rei, reiSaveFlag, errmsg, r);
00110 if(getNodeType(res) == N_ERROR) {
00111 return RES_ERR_CODE(res);
00112 }
00113 if(varName!=NULL) {
00114 updateInEnv(env, varName, res);
00115 }
00116 }
00117 return 0;
00118
00119 }
00120 Env *defaultEnv(Region *r) {
00121 Env *global = newEnv(newHashTable2(10, r), NULL, NULL, r);
00122 Env *env = newEnv(newHashTable2(10, r), global, NULL, r);
00123
00124 return env;
00125 }
00126
00127 int parseAndComputeRuleAdapter(char *rule, msParamArray_t *msParamArray, ruleExecInfo_t *rei, int reiSaveFlag, Region *r) {
00128
00129 int recclearDelayed = ruleEngineConfig.clearDelayed;
00130 ruleEngineConfig.clearDelayed = 0;
00131
00132 rError_t errmsgBuf;
00133 errmsgBuf.errMsg = NULL;
00134 errmsgBuf.len = 0;
00135
00136 Env *env = defaultEnv(r);
00137
00138 rei->status = 0;
00139
00140 msParamArray_t *orig = NULL;
00141
00142 Res *execOutRes;
00143
00144 int rescode = 0;
00145 if(msParamArray!=NULL) {
00146 if(strncmp(rule, "@external\n", 10) == 0) {
00147 rescode = parseAndComputeMsParamArrayToEnv(msParamArray, globalEnv(env), rei, reiSaveFlag, &errmsgBuf, r);
00148 RE_ERROR(rescode < 0);
00149 rule = rule + 10;
00150 } else {
00151 rescode = convertMsParamArrayToEnv(msParamArray, globalEnv(env), &errmsgBuf, r);
00152 RE_ERROR(rescode < 0);
00153 }
00154 }
00155
00156 if((execOutRes = (Res *)lookupFromEnv(env, "ruleExecOut")) == NULL || TYPE(execOutRes) == T_UNSPECED) {
00157
00158 deleteFromHashTable(globalEnv(env)->current, "ruleExecOut");
00159 addCmdExecOutToEnv(globalEnv(env), r);
00160 }
00161
00162 orig = rei->msParamArray;
00163 rei->msParamArray = NULL;
00164
00165 rescode = parseAndComputeRule(rule, env, rei, reiSaveFlag, &errmsgBuf, r);
00166
00167 if(orig==NULL) {
00168 rei->msParamArray = newMsParamArray();
00169 } else {
00170 rei->msParamArray = orig;
00171 }
00172 convertEnvToMsParamArray(rei->msParamArray, env, &errmsgBuf, r);
00173
00174 RE_ERROR(rescode < 0);
00175 freeRErrorContent(&errmsgBuf);
00176
00177
00178 return rescode;
00179 error:
00180 logErrMsg(&errmsgBuf, &rei->rsComm->rError);
00181 rei->status = rescode;
00182 freeRErrorContent(&errmsgBuf);
00183
00184 if(recclearDelayed) {
00185 clearDelayed();
00186 }
00187 ruleEngineConfig.clearDelayed = recclearDelayed;
00188
00189 return rescode;
00190
00191
00192 }
00193
00194 int parseAndComputeRuleNewEnv( char *rule, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r) {
00195 Env *env = defaultEnv(r);
00196 addCmdExecOutToEnv(globalEnv(env), r);
00197
00198 int rescode = 0;
00199 msParamArray_t *orig = NULL;
00200
00201 if(msParamArray!=NULL) {
00202 rescode = convertMsParamArrayToEnv(msParamArray, env->previous, errmsg, r);
00203 RE_ERROR(rescode < 0);
00204 }
00205
00206 orig = rei->msParamArray;
00207 rei->msParamArray = NULL;
00208
00209 rescode = parseAndComputeRule(rule, env, rei, reiSaveFlag, errmsg, r);
00210 RE_ERROR(rescode < 0);
00211
00212 if(orig==NULL) {
00213 rei->msParamArray = newMsParamArray();
00214 } else {
00215 rei->msParamArray = orig;
00216 }
00217 rescode = convertEnvToMsParamArray(rei->msParamArray, env, errmsg, r);
00218 RE_ERROR(rescode < 0);
00219
00220 return rescode;
00221
00222 error:
00223
00224
00225 return rescode;
00226 }
00227
00228
00229 int parseAndComputeRule(char *rule, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r) {
00230 if(overflow(rule, MAX_RULE_LEN)) {
00231 addRErrorMsg(errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow");
00232 return RE_BUFFER_OVERFLOW;
00233 }
00234 Node *node;
00235 Pointer *e = newPointer2(rule);
00236 if(e == NULL) {
00237 addRErrorMsg(errmsg, RE_POINTER_ERROR, "error: can not create a Pointer.");
00238 return RE_POINTER_ERROR;
00239 }
00240
00241 int tempLen = ruleEngineConfig.extRuleSet->len;
00242
00243 int checkPoint=checkPointExtRuleSet(r);
00244
00245 int rescode;
00246
00247 int errloc;
00248
00249
00250 rescode = parseRuleSet(e, ruleEngineConfig.extRuleSet, ruleEngineConfig.extFuncDescIndex, &errloc, errmsg, r);
00251 deletePointer(e);
00252 if(rescode != 0) {
00253 return RE_PARSER_ERROR;
00254 }
00255
00256 RuleDesc *rd = NULL;
00257 Res *res = NULL;
00258
00259 int i;
00260 for(i=tempLen;i<ruleEngineConfig.extRuleSet->len;i++) {
00261 if(ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_FUNC || ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_REL) {
00262 appendRuleIntoExtIndex(ruleEngineConfig.extRuleSet->rules[i], i, r);
00263 }
00264 }
00265
00266 for(i=tempLen;i<ruleEngineConfig.extRuleSet->len;i++) {
00267 if(ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_FUNC || ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_REL) {
00268 Hashtable *varTypes = newHashTable2(10, r);
00269
00270 List *typingConstraints = newList(r);
00271 Node *errnode;
00272 ExprType *type = typeRule(ruleEngineConfig.extRuleSet->rules[i], ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, &errnode, r);
00273
00274 if(getNodeType(type)==T_ERROR) {
00275
00276 rescode = RE_TYPE_ERROR;
00277 RETURN;
00278 }
00279 }
00280 }
00281
00282
00283 rd = ruleEngineConfig.extRuleSet->rules[tempLen];
00284 node = rd->node;
00285
00286 res = execRuleNodeRes(node, NULL, 0, GlobalAllRuleExecFlag, env, rei, reiSaveFlag, errmsg,r);
00287 rescode = getNodeType(res) == N_ERROR? RES_ERR_CODE(res):0;
00288 ret:
00289
00290 popExtRuleSet(checkPoint);
00291
00292 return rescode;
00293 }
00294
00295
00296 Res *computeExpressionWithParams( char *actionName, char **params, int paramsCount, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r) {
00297 #ifdef DEBUG
00298 char buf[ERR_MSG_LEN>1024?ERR_MSG_LEN:1024];
00299 snprintf(buf, 1024, "computExpressionWithParams: %s\n", actionName);
00300 writeToTmp("entry.log", buf);
00301 #endif
00302
00303 int recclearDelayed = ruleEngineConfig.clearDelayed;
00304 ruleEngineConfig.clearDelayed = 0;
00305
00306 if(overflow(actionName, MAX_NAME_LEN)) {
00307 addRErrorMsg(errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow");
00308 return newErrorRes(r, RE_BUFFER_OVERFLOW);
00309 }
00310 int k;
00311 for(k=0;k<paramsCount;k++) {
00312 if(overflow(params[k], MAX_RULE_LEN)) {
00313 addRErrorMsg(errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow");
00314 return newErrorRes(r, RE_BUFFER_OVERFLOW);
00315 }
00316 }
00317
00318 Node** paramNodes = (Node **)region_alloc(r, sizeof(Node *)*paramsCount);
00319 int i;
00320 for(i=0;i<paramsCount;i++) {
00321
00322 Node *node;
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332 node = newNode(TK_STRING, params[i], 0, r);
00333
00334
00335
00336
00337
00338
00339
00340
00341 paramNodes[i] = node;
00342 }
00343
00344 Node *node = createFunctionNode(actionName, paramNodes, paramsCount, NULL, r);
00345 Env *global = newEnv(newHashTable2(10, r), NULL, NULL, r);
00346 Env *env = newEnv(newHashTable2(10, r), global, NULL, r);
00347 if(msParamArray!=NULL) {
00348 convertMsParamArrayToEnv(msParamArray, global, errmsg, r);
00349 }
00350 Res *res = computeNode(node, NULL, env, rei, reiSaveFlag, errmsg,r);
00351
00352 if(recclearDelayed) {
00353 clearDelayed();
00354 }
00355 ruleEngineConfig.clearDelayed = recclearDelayed;
00356 return res;
00357 }
00358 ExprType *typeRule(RuleDesc *rule, Env *funcDesc, Hashtable *varTypes, List *typingConstraints, rError_t *errmsg, Node **errnode, Region *r) {
00359
00360 addRErrorMsg(errmsg, -1, ERR_MSG_SEP);
00361 char buf[ERR_MSG_LEN];
00362 Node *node = rule->node;
00363 int dynamictyping = rule->dynamictyping;
00364 #if 0
00365 int arity = RULE_NODE_NUM_PARAMS(node);
00366 Node *type = node->subtrees[0]->subtrees[1];
00367 #endif
00368
00369 ExprType *resType = typeExpression3(node->subtrees[1], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r);
00370
00371 RE_ERROR(getNodeType(resType) == T_ERROR);
00372 if(getNodeType(resType) != T_BOOL && getNodeType(resType) != T_VAR && getNodeType(resType) != T_DYNAMIC) {
00373 char buf2[1024], buf3[ERR_MSG_LEN];
00374 typeToString(resType, varTypes, buf2, 1024);
00375 snprintf(buf3, ERR_MSG_LEN, "error: the type %s of the rule condition is not supported", buf2);
00376 generateErrMsg(buf3, NODE_EXPR_POS(node->subtrees[1]), node->subtrees[1]->base, buf);
00377 addRErrorMsg(errmsg, RE_TYPE_ERROR, buf);
00378 RE_ERROR(1);
00379 }
00380 resType = typeExpression3(node->subtrees[2], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r);
00381 RE_ERROR(getNodeType(resType) == T_ERROR);
00382 resType = typeExpression3(node->subtrees[3], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r);
00383 RE_ERROR(getNodeType(resType) == T_ERROR);
00384
00385 RE_ERROR(solveConstraints(typingConstraints, varTypes, errmsg, errnode, r) == ABSURDITY);
00386 int i;
00387 for(i =1;i<=3;i++) {
00388 postProcessCoercion(node->subtrees[i], varTypes, errmsg, errnode, r);
00389 postProcessActions(node->subtrees[i], funcDesc, errmsg, errnode, r);
00390 }
00391
00392 return newSimpType(T_INT, r);
00393
00394 error:
00395 snprintf(buf, ERR_MSG_LEN, "type error: in rule %s", node->subtrees[0]->text);
00396 addRErrorMsg(errmsg, RE_TYPE_ERROR, buf);
00397 return resType;
00398
00399 }
00400
00401 ExprType *typeRuleSet(RuleSet *ruleset, rError_t *errmsg, Node **errnode, Region *r) {
00402 Env *funcDesc = ruleEngineConfig.extFuncDescIndex;
00403 Hashtable *ruleType = newHashTable2(MAX_NUM_RULES * 2, r);
00404 ExprType *res;
00405 int i;
00406 for(i=0;i<ruleset->len;i++) {
00407 RuleDesc *rule = ruleset->rules[i];
00408 if(rule->ruleType == RK_REL || rule->ruleType == RK_FUNC) {
00409 List *typingConstraints = newList(r);
00410 Hashtable *varTypes = newHashTable2(100, r);
00411 ExprType *restype = typeRule(rule, funcDesc, varTypes, typingConstraints, errmsg, errnode, r);
00412
00413
00414
00415 if(getNodeType(restype) == T_ERROR) {
00416 res = restype;
00417 char *errbuf = (char *) malloc(ERR_MSG_LEN*1024*sizeof(char));
00418 errMsgToString(errmsg, errbuf, ERR_MSG_LEN*1024);
00419 #ifdef DEBUG
00420 writeToTmp("ruleerr.log", errbuf);
00421 writeToTmp("ruleerr.log", "\n");
00422 #endif
00423 rodsLog (LOG_ERROR, "%s", errbuf);
00424 free(errbuf);
00425 freeRErrorContent(errmsg);
00426 RETURN;
00427 }
00428
00429 char errbuf[ERR_MSG_LEN];
00430 char *ruleName = rule->node->subtrees[0]->text;
00431 FunctionDesc *fd;
00432 if((fd = (FunctionDesc *)lookupFromEnv(funcDesc, ruleName)) != NULL) {
00433 if(getNodeType(fd) != N_FD_EXTERNAL && getNodeType(fd) != N_FD_RULE_INDEX_LIST) {
00434 char *err;
00435 switch(getNodeType(fd)) {
00436 case N_FD_CONSTRUCTOR:
00437 err = "redefinition of constructor";
00438 break;
00439 case N_FD_DECONSTRUCTOR:
00440 err = "redefinition of deconstructor";
00441 break;
00442 case N_FD_FUNCTION:
00443 err = "redefinition of system microservice";
00444 break;
00445 default:
00446 err = "redefinition of system symbol";
00447 break;
00448 }
00449
00450 generateErrMsg(err, NODE_EXPR_POS(rule->node), rule->node->base, errbuf);
00451 addRErrorMsg(errmsg, RE_FUNCTION_REDEFINITION, errbuf);
00452 res = newErrorType(RE_FUNCTION_REDEFINITION, r);
00453 *errnode = rule->node;
00454 RETURN;
00455 }
00456 }
00457
00458 RuleDesc *rd = (RuleDesc *)lookupFromHashTable(ruleType, ruleName);
00459 if(rd!=NULL) {
00460 if(rule->ruleType == RK_FUNC || rd ->ruleType == RK_FUNC) {
00461 generateErrMsg("redefinition of function", NODE_EXPR_POS(rule->node), rule->node->base, errbuf);
00462 addRErrorMsg(errmsg, RE_FUNCTION_REDEFINITION, errbuf);
00463 generateErrMsg("previous definition", NODE_EXPR_POS(rd->node), rd->node->base, errbuf);
00464 addRErrorMsg(errmsg, RE_FUNCTION_REDEFINITION, errbuf);
00465 res = newErrorType(RE_FUNCTION_REDEFINITION, r);
00466 *errnode = rule->node;
00467 RETURN;
00468 }
00469 } else {
00470 insertIntoHashTable(ruleType, ruleName, rule);
00471 }
00472 }
00473 }
00474 res = newSimpType(T_INT, r);
00475
00476 ret:
00477 return res;
00478 }
00479
00480 int typeNode(Node *node, Hashtable *varTypes, rError_t *errmsg, Node **errnode, Region *r)
00481 {
00482 if((node->option & OPTION_TYPED) == 0) {
00483
00484 List *typingConstraints = newList(r);
00485 Res *resType = typeExpression3(node, 0, ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, errnode, r);
00486
00487 if(getNodeType(resType) == T_ERROR) {
00488 addRErrorMsg(errmsg, RE_TYPE_ERROR, "type error: in rule");
00489 return RE_TYPE_ERROR;
00490 }
00491 postProcessCoercion(node, varTypes, errmsg, errnode, r);
00492 postProcessActions(node, ruleEngineConfig.extFuncDescIndex, errmsg, errnode, r);
00493
00494 varTypes = NULL;
00495 node->option |= OPTION_TYPED;
00496 }
00497 return 0;
00498 }
00499
00500
00501 Res* computeNode(Node *node, Node *reco, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t* errmsg, Region *r) {
00502 Hashtable *varTypes = newHashTable2(10, r);
00503 Region *rNew = make_region(0, NULL);
00504 Node *en;
00505 Node **errnode = &en;
00506 Res* res;
00507 int errorcode;
00508 if((errorcode = typeNode(node, varTypes, errmsg, errnode, r))!=0) {
00509 res = newErrorRes(r,errorcode);
00510 RETURN;
00511 }
00512 if(reco != NULL && (errorcode = typeNode(reco, varTypes, errmsg, errnode, r))!=0) {
00513 res = newErrorRes(r,errorcode);
00514 RETURN;
00515 }
00516 if(getNodeType(node) == N_ACTIONS) {
00517 res = evaluateActions(node, NULL, GlobalAllRuleExecFlag, rei, reiSaveFlag, env, errmsg, rNew);
00518 } else {
00519 res = evaluateExpression3(node, GlobalAllRuleExecFlag, 0, rei, reiSaveFlag, env, errmsg, rNew);
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 ret:
00530 res = cpRes(res, r);
00531 cpEnv(env, r);
00532 region_free(rNew);
00533 return res;
00534 }
00535
00536
00537
00538
00539 Res *parseAndComputeExpression(char *expr, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r) {
00540 Res *res = NULL;
00541 char buf[ERR_MSG_LEN>1024?ERR_MSG_LEN:1024];
00542 int rulegen;
00543 Node *node = NULL, *recoNode = NULL;
00544
00545 #ifdef DEBUG
00546 snprintf(buf, 1024, "parseAndComputeExpression: %s\n", expr);
00547 writeToTmp("entry.log", buf);
00548 #endif
00549 if(overflow(expr, MAX_RULE_LEN)) {
00550 addRErrorMsg(errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow");
00551 return newErrorRes(r, RE_BUFFER_OVERFLOW);
00552 }
00553 Pointer *e = newPointer2(expr);
00554 ParserContext *pc = newParserContext(errmsg, r);
00555 if(e == NULL) {
00556 addRErrorMsg(errmsg, RE_POINTER_ERROR, "error: can not create pointer.");
00557 res = newErrorRes(r, RE_POINTER_ERROR);
00558 RETURN;
00559 }
00560 rulegen = isRuleGenSyntax(expr);
00561
00562 if(rulegen) {
00563 node = parseTermRuleGen(e, rulegen, pc);
00564 } else {
00565 node= parseActionsRuleGen(e, rulegen, 1, pc);
00566 }
00567 if(node==NULL) {
00568 addRErrorMsg(errmsg, RE_OUT_OF_MEMORY, "error: out of memory.");
00569 res = newErrorRes(r, RE_OUT_OF_MEMORY);
00570 RETURN;
00571 } else if (getNodeType(node) == N_ERROR) {
00572 generateErrMsg("error: syntax error",NODE_EXPR_POS(node), node->base, buf);
00573 addRErrorMsg(errmsg, RE_PARSER_ERROR, buf);
00574 res = newErrorRes(r, RE_PARSER_ERROR);
00575 RETURN;
00576 } else {
00577 Token *token;
00578 token = nextTokenRuleGen(e, pc, 0, 0);
00579 if(strcmp(token->text, "|")==0) {
00580 recoNode = parseActionsRuleGen(e, rulegen, 1, pc);
00581 if(recoNode==NULL) {
00582 addRErrorMsg(errmsg, RE_OUT_OF_MEMORY, "error: out of memory.");
00583 res = newErrorRes(r, RE_OUT_OF_MEMORY);
00584 RETURN;
00585 } else if (getNodeType(recoNode) == N_ERROR) {
00586 generateErrMsg("error: syntax error",NODE_EXPR_POS(recoNode), recoNode->base, buf);
00587 addRErrorMsg(errmsg, RE_PARSER_ERROR, buf);
00588 res = newErrorRes(r, RE_PARSER_ERROR);
00589 RETURN;
00590 }
00591 token = nextTokenRuleGen(e, pc, 0, 0);
00592 }
00593 if(token->type!=TK_EOS) {
00594 Label pos;
00595 getFPos(&pos, e, pc);
00596 generateErrMsg("error: unparsed suffix",pos.exprloc, pos.base, buf);
00597 addRErrorMsg(errmsg, RE_UNPARSED_SUFFIX, buf);
00598 res = newErrorRes(r, RE_UNPARSED_SUFFIX);
00599 RETURN;
00600 }
00601 }
00602 res = computeNode(node, NULL, env, rei, reiSaveFlag, errmsg,r);
00603 ret:
00604 deleteParserContext(pc);
00605 deletePointer(e);
00606 return res;
00607 }
00608
00609 int generateRuleTypes(RuleSet *inRuleSet, Hashtable *symbol_type_table, Region *r)
00610 {
00611 int i;
00612 for (i=0;i<inRuleSet->len;i++) {
00613 Node *ruleNode = inRuleSet->rules[i]->node;
00614 if(ruleNode == NULL)
00615 continue;
00616 char *key = ruleNode->subtrees[0]->text;
00617 int arity = RULE_NODE_NUM_PARAMS(ruleNode);
00618
00619 ExprType **paramTypes = (ExprType**) region_alloc(r, sizeof(ExprType *)*arity);
00620 int k;
00621 for(k=0;k<arity;k++) {
00622 paramTypes[k] = newTVar(r);
00623 }
00624 ExprType *ruleType = newFuncTypeVarArg(arity, OPTION_VARARG_ONCE, paramTypes, newSimpType(T_INT, r), r);
00625
00626 if (insertIntoHashTable(symbol_type_table, key,ruleType) == 0) {
00627 return 0;
00628 }
00629 }
00630 return 1;
00631 }
00632
00633 RuleDesc* getRuleDesc(int ri)
00634 {
00635
00636 if(ri< APP_RULE_INDEX_OFF) {
00637 return ruleEngineConfig.extRuleSet->rules[ri];
00638 } else
00639 if (ri < CORE_RULE_INDEX_OFF) {
00640 ri = ri - APP_RULE_INDEX_OFF;
00641 return ruleEngineConfig.appRuleSet->rules[ri];
00642 } else {
00643 ri = ri - CORE_RULE_INDEX_OFF;
00644 return ruleEngineConfig.coreRuleSet->rules[ri];
00645 }
00646 }
00647
00648 #ifdef USE_EIRODS
00649
00650
00651 int actionTableLookUp ( eirods::ms_table_entry& _entry, char* _action ) {
00652
00653 std::string str_act( _action );
00654
00655 if( str_act[0] == 'a' && str_act[1] == 'c' )
00656 return -1;
00657
00658
00659
00660
00661 if( !MicrosTable.has_entry( str_act ) ) {
00662 rodsLog( LOG_NOTICE, "actionTableLookUp - [%s] not found, load it.", _action );
00663 eirods::error ret = eirods::load_microservice_plugin( MicrosTable, str_act );
00664 if( !ret.ok() ) {
00665 return UNMATCHED_ACTION_ERR;
00666 } else {
00667 rodsLog( LOG_NOTICE, "actionTableLookUp - loaded [%s]", _action );
00668 }
00669 }
00670
00671 _entry = *MicrosTable[ str_act ];
00672
00673 return 0;
00674
00675 }
00676 #else
00677 int actionTableLookUp (char *action)
00678 {
00679
00680 int i;
00681
00682 for (i = 0; i < NumOfAction; i++) {
00683 if (!strcmp(MicrosTable[i].action,action))
00684 return (i);
00685 }
00686
00687 return (UNMATCHED_ACTION_ERR);
00688 }
00689 #endif
00690
00691
00692
00693
00694
00695 Res *parseAndComputeExpressionAdapter(char *inAction, msParamArray_t *inMsParamArray, int retOutParams, ruleExecInfo_t *rei, int reiSaveFlag, Region *r) {
00696
00697 int recclearDelayed = ruleEngineConfig.clearDelayed;
00698 ruleEngineConfig.clearDelayed = 0;
00699 int freeRei = 0;
00700 if(rei == NULL) {
00701 rei = (ruleExecInfo_t *) malloc(sizeof(ruleExecInfo_t));
00702 memset(rei, 0, sizeof(ruleExecInfo_t));
00703 freeRei = 1;
00704 }
00705 rei->status = 0;
00706 Env *env = defaultEnv(r);
00707
00708 execCmdOut_t *execOut = addCmdExecOutToEnv(globalEnv(env), r);
00709 Res *res;
00710 rError_t errmsgBuf;
00711 errmsgBuf.errMsg = NULL;
00712 errmsgBuf.len = 0;
00713
00714 msParamArray_t *orig = rei->msParamArray;
00715 rei->msParamArray = NULL;
00716
00717 if(inMsParamArray!=NULL) {
00718 convertMsParamArrayToEnv(inMsParamArray, env, &errmsgBuf, r);
00719 }
00720
00721 res = parseAndComputeExpression(inAction, env, rei, reiSaveFlag, &errmsgBuf, r);
00722 if(retOutParams) {
00723 if(inMsParamArray != NULL) {
00724 clearMsParamArray(inMsParamArray, 0);
00725 convertEnvToMsParamArray(inMsParamArray, env, &errmsgBuf, r);
00726 }
00727 }
00728 rei->msParamArray = orig;
00729
00730 freeCmdExecOut(execOut);
00731
00732 if(getNodeType(res) == N_ERROR && !freeRei) {
00733 logErrMsg(&errmsgBuf, &rei->rsComm->rError);
00734 rei->status = RES_ERR_CODE(res);
00735 }
00736 freeRErrorContent(&errmsgBuf);
00737 if(freeRei) {
00738 free(rei);
00739 }
00740 if(recclearDelayed) {
00741 clearDelayed();
00742 }
00743 ruleEngineConfig.clearDelayed = recclearDelayed;
00744 return res;
00745
00746 }
00747 int overflow(char* expr, int len) {
00748 int i;
00749 for(i = 0;i<len+1;i++) {
00750 if(expr[i]==0)
00751 return 0;
00752 }
00753 return 1;
00754 }
00755