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