/* call an action with actionName and string parameters */ Res *computeExpressionWithParams( const char *actionName, const char **params, int paramsCount, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r ) { #ifdef DEBUG char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024]; snprintf( buf, 1024, "computExpressionWithParams: %s\n", actionName ); writeToTmp( "entry.log", buf ); #endif /* set clearDelayed to 0 so that nested calls to this function do not call clearDelay() */ int recclearDelayed = ruleEngineConfig.clearDelayed; ruleEngineConfig.clearDelayed = 0; if ( overflow( actionName, MAX_NAME_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } int k; for ( k = 0; k < paramsCount; k++ ) { if ( overflow( params[k], MAX_RULE_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } } Node** paramNodes = ( Node ** )region_alloc( r, sizeof( Node * ) * paramsCount ); int i; for ( i = 0; i < paramsCount; i++ ) { Node *node; /*Pointer *e = newPointer2(params[i]); if(e == NULL) { addRErrorMsg(errmsg, -1, "error: can not create Pointer."); return newErrorRes(r, -1); } node = parseTermRuleGen(e, 1, errmsg, r);*/ node = newNode( TK_STRING, params[i], 0, r ); /*if(node==NULL) { addRErrorMsg(errmsg, OUT_OF_MEMORY, "error: out of memory."); return newErrorRes(r, OUT_OF_MEMORY); } else if (getNodeType(node) == N_ERROR) { return newErrorRes(r, RES_ERR_CODE(node)); }*/ paramNodes[i] = node; } Node *node = createFunctionNode( actionName, paramNodes, paramsCount, NULL, r ); Env *global = newEnv( newHashTable2( 10, r ), NULL, NULL, r ); Env *env = newEnv( newHashTable2( 10, r ), global, NULL, r ); if ( msParamArray != NULL ) { convertMsParamArrayToEnv( msParamArray, global, r ); deleteFromHashTable(global->current, "ruleExecOut"); } Res *res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r ); /* deleteEnv(env, 3); */ if ( recclearDelayed ) { clearDelayed(); } ruleEngineConfig.clearDelayed = recclearDelayed; return res; }
/* parse and compute an expression * */ Res *parseAndComputeExpression( char *expr, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) { Res *res = NULL; char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024]; int rulegen; Node *node = NULL, *recoNode = NULL; #ifdef DEBUG snprintf( buf, 1024, "parseAndComputeExpression: %s\n", expr ); writeToTmp( "entry.log", buf ); #endif if ( overflow( expr, MAX_RULE_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } Pointer *e = newPointer2( expr ); ParserContext *pc = newParserContext( errmsg, r ); if ( e == NULL ) { addRErrorMsg( errmsg, RE_POINTER_ERROR, "error: can not create pointer." ); res = newErrorRes( r, RE_POINTER_ERROR ); RETURN; } rulegen = isRuleGenSyntax( expr ); if ( rulegen ) { node = parseTermRuleGen( e, rulegen, pc ); } else { node = parseActionsRuleGen( e, rulegen, 1, pc ); } if ( node == NULL ) { addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." ); res = newErrorRes( r, RE_OUT_OF_MEMORY ); RETURN; } else if ( getNodeType( node ) == N_ERROR ) { generateErrMsg( "error: syntax error", NODE_EXPR_POS( node ), node->base, buf ); addRErrorMsg( errmsg, RE_PARSER_ERROR, buf ); res = newErrorRes( r, RE_PARSER_ERROR ); RETURN; } else { Token *token; token = nextTokenRuleGen( e, pc, 0, 0 ); if ( strcmp( token->text, "|" ) == 0 ) { recoNode = parseActionsRuleGen( e, rulegen, 1, pc ); if ( recoNode == NULL ) { addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." ); res = newErrorRes( r, RE_OUT_OF_MEMORY ); RETURN; } else if ( getNodeType( recoNode ) == N_ERROR ) { generateErrMsg( "error: syntax error", NODE_EXPR_POS( recoNode ), recoNode->base, buf ); addRErrorMsg( errmsg, RE_PARSER_ERROR, buf ); res = newErrorRes( r, RE_PARSER_ERROR ); RETURN; } token = nextTokenRuleGen( e, pc, 0, 0 ); } if ( token->type != TK_EOS ) { Label pos; getFPos( &pos, e, pc ); generateErrMsg( "error: unparsed suffix", pos.exprloc, pos.base, buf ); addRErrorMsg( errmsg, RE_UNPARSED_SUFFIX, buf ); res = newErrorRes( r, RE_UNPARSED_SUFFIX ); RETURN; } } res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r ); ret: deleteParserContext( pc ); deletePointer( e ); return res; }
int convertMsParamToResAndFreeNonIRODSType(msParam_t *mP, Res *res, rError_t *errmsg, Region *r) { #ifdef DEBUG writeToTmp("relog.txt", "type: "); writeToTmp("relog.txt", mP->type); writeToTmp("relog.txt", "\n"); #endif if(mP->type == NULL) { res->exprType = newSimpType(T_UNSPECED, r); return 0; } else if (strcmp(mP->type, DOUBLE_MS_T) == 0) { /* if the parameter is an integer */ convertDoubleValue(res, *(double *)mP->inOutStruct,r); free(mP->inOutStruct); mP->inOutStruct = NULL; return 0; } else if (strcmp(mP->type, INT_MS_T) == 0) { /* if the parameter is an integer */ /* this could be int, bool, or datatime */ if(res->exprType == NULL) { /* output parameter */ RES_INT_VAL_LVAL(res) = *(int *)mP->inOutStruct; res->exprType = newSimpType(T_INT, r); } else switch(TYPE(res)) { case T_INT: RES_INT_VAL_LVAL(res) = *(int *)mP->inOutStruct; break; case T_BOOL: RES_BOOL_VAL_LVAL(res) = *(int *)mP->inOutStruct; break; case T_DATETIME: RES_TIME_VAL(res) = *(rodsLong_t *)mP->inOutStruct; break; default: convertIntValue(res, *(int *)mP->inOutStruct,r); } free(mP->inOutStruct); mP->inOutStruct = NULL; return 0; } else if (strcmp(mP->type, STR_MS_T) == 0) { /* if the parameter is a string */ convertStrValue(res, (char *)mP->inOutStruct,r); free(mP->inOutStruct); mP->inOutStruct = NULL; return 0; } else if(strcmp(mP->type, DATETIME_MS_T) == 0) { RES_TIME_VAL(res) = *(rodsLong_t *)mP->inOutStruct; TYPE(res) = T_DATETIME; free(mP->inOutStruct); mP->inOutStruct = NULL; return 0; /* } else if(strcmp(mP->type, StrArray_MS_T) == 0) { convertCollectionToRes(mP, res); return 1; } else if(strcmp(mP->type, IntArray_MS_T) == 0) { convertCollectionToRes(mP, res); return 1; } else if(strcmp(mP->type, GenQueryOut_MS_T) == 0) { convertCollectionToRes(mP, res); return 1; */ } else { if(res->param==NULL) { res->param = newMsParam(mP->type, mP->inOutStruct, mP->inpOutBuf, r); } else { res->param->type = cpStringExt(mP->type, r); RES_UNINTER_STRUCT(res) = mP->inOutStruct; RES_UNINTER_BUFFER(res) = mP->inpOutBuf; } res->exprType = newIRODSType(mP->type,r); return 0; } }
ExprType *typeRuleSet( RuleSet *ruleset, rError_t *errmsg, Node **errnode, Region *r ) { Env *funcDesc = ruleEngineConfig.extFuncDescIndex; Hashtable *ruleType = newHashTable2( MAX_NUM_RULES * 2, r ); ExprType *res; int i; for ( i = 0; i < ruleset->len; i++ ) { RuleDesc *rule = ruleset->rules[i]; if ( rule->ruleType == RK_REL || rule->ruleType == RK_FUNC ) { List *typingConstraints = newList( r ); Hashtable *varTypes = newHashTable2( 100, r ); ExprType *restype = typeRule( rule, funcDesc, varTypes, typingConstraints, errmsg, errnode, r ); /*char buf[1024]; */ /*typingConstraintsToString(typingConstraints, buf, 1024); */ /*printf("rule %s, typing constraints: %s\n", ruleset->rules[i]->subtrees[0]->text, buf); */ if ( getNodeType( restype ) == T_ERROR ) { res = restype; char *errbuf = ( char * ) malloc( ERR_MSG_LEN * 1024 * sizeof( char ) ); errMsgToString( errmsg, errbuf, ERR_MSG_LEN * 1024 ); #ifdef DEBUG writeToTmp( "ruleerr.log", errbuf ); writeToTmp( "ruleerr.log", "\n" ); #endif rodsLog( LOG_ERROR, "%s", errbuf ); free( errbuf ); freeRErrorContent( errmsg ); RETURN; } /* check that function names are unique and do not conflict with system msis */ char errbuf[ERR_MSG_LEN]; char *ruleName = rule->node->subtrees[0]->text; FunctionDesc *fd; if ( ( fd = ( FunctionDesc * )lookupFromEnv( funcDesc, ruleName ) ) != NULL ) { if ( getNodeType( fd ) != N_FD_EXTERNAL && getNodeType( fd ) != N_FD_RULE_INDEX_LIST ) { char *err; switch ( getNodeType( fd ) ) { case N_FD_CONSTRUCTOR: err = "redefinition of constructor"; break; case N_FD_DECONSTRUCTOR: err = "redefinition of deconstructor"; break; case N_FD_FUNCTION: err = "redefinition of system microservice"; break; default: err = "redefinition of system symbol"; break; } generateErrMsg( err, NODE_EXPR_POS( rule->node ), rule->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); res = newErrorType( RE_FUNCTION_REDEFINITION, r ); *errnode = rule->node; RETURN; } } RuleDesc *rd = ( RuleDesc * )lookupFromHashTable( ruleType, ruleName ); if ( rd != NULL ) { if ( rule->ruleType == RK_FUNC || rd ->ruleType == RK_FUNC ) { generateErrMsg( "redefinition of function", NODE_EXPR_POS( rule->node ), rule->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); generateErrMsg( "previous definition", NODE_EXPR_POS( rd->node ), rd->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); res = newErrorType( RE_FUNCTION_REDEFINITION, r ); *errnode = rule->node; RETURN; } } else { insertIntoHashTable( ruleType, ruleName, rule ); } } } res = newSimpType( T_INT, r ); /* Although a rule set does not have type T_INT, return T_INT to indicate success. */ ret: return res; }