irods  4.2.8
About: iRODS (the integrated Rule Oriented Data System) is a distributed data-management system for creating data grids, digital libraries, persistent archives, and real-time data systems.
  Fossies Dox: irods-4.2.8.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

rules.cpp
Go to the documentation of this file.
1 /* For copyright information please refer to files in the COPYRIGHT directory
2  */
3 #include "debug.hpp"
4 #include "reGlobalsExtern.hpp"
5 #include "reHelpers1.hpp"
6 #include "rules.hpp"
7 #include "index.hpp"
8 #include "functions.hpp"
9 #include "arithmetics.hpp"
10 #include "configuration.hpp"
11 #include "filesystem.hpp"
12 #include "rcMisc.h"
13 #include "irods_log.hpp"
14 #include "irods_re_plugin.hpp"
15 #include "irods_error.hpp"
16 
17 #define RE_ERROR(cond) if(cond) { goto error; }
18 
19 extern int GlobalAllRuleExecFlag;
20 
21 
28 int readRuleSetFromFile( const char *ruleBaseName, RuleSet *ruleSet, Env *funcDesc, int* errloc, rError_t *errmsg, Region *r ) {
29  char rulesFileName[MAX_NAME_LEN];
30  getRuleBasePath( ruleBaseName, rulesFileName );
31 
32  return readRuleSetFromLocalFile( ruleBaseName, rulesFileName, ruleSet, funcDesc, errloc, errmsg, r );
33 }
34 int readRuleSetFromLocalFile( const char *ruleBaseName, const char *rulesFileName, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r ) {
35 
36  FILE *file;
37  char errbuf[ERR_MSG_LEN];
38  file = fopen( rulesFileName, "r" );
39  if ( file == NULL ) {
40  snprintf( errbuf, ERR_MSG_LEN,
41  "readRuleSetFromFile() could not open rules file %s\n",
42  rulesFileName );
43  addRErrorMsg( errmsg, RULES_FILE_READ_ERROR, errbuf );
44  return RULES_FILE_READ_ERROR;
45  }
46  Pointer *e = newPointer( file, ruleBaseName );
47  int ret = parseRuleSet( e, ruleSet, funcDesc, errloc, errmsg, r );
48  deletePointer( e );
49  if ( ret < 0 ) {
50  return ret;
51  }
52 
53  Node *errnode{};
54  ExprType *restype = typeRuleSet( ruleSet, errmsg, &errnode, r );
55  if ( getNodeType( restype ) == T_ERROR ) {
56  if ( NULL != errnode ) {
57  *errloc = NODE_EXPR_POS( errnode );
58  }
59  return RE_TYPE_ERROR;
60  }
61 
62  return 0;
63 }
64 
65 int parseAndComputeMsParamArrayToEnv( msParamArray_t *var, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) {
66  int i;
67  for ( i = 0; i < var->len; i++ ) {
68  Res *res = newRes( r );
69  int ret = convertMsParamToRes( var->msParam[i], res, r );
70  if ( ret != 0 ) {
71  return ret;
72  }
73  char *varName = var->msParam[i]->label;
74  if ( TYPE( res ) == T_UNSPECED ) {
75  if ( varName != NULL ) {
76  updateInEnv( env, varName, res );
77  }
78  continue;
79  }
80  if ( TYPE( res ) != T_STRING ) {
81  return -1;
82  }
83 
84  char *expr = res->text;
85  res = parseAndComputeExpression( expr, env, rei, reiSaveFlag, errmsg, r );
86  if ( getNodeType( res ) == N_ERROR ) {
87  return RES_ERR_CODE( res );
88  }
89  if ( varName != NULL ) {
90  updateInEnv( env, varName, res );
91  }
92  }
93  return 0;
94 
95 }
97  Env *global = newEnv( newHashTable2( 10, r ), NULL, NULL, r );
98  Env *env = newEnv( newHashTable2( 10, r ), global, NULL, r );
99 
100  return env;
101 }
102 
103 int parseAndComputeRuleAdapter( char *rule, msParamArray_t *msParamArray, ruleExecInfo_t *rei, int reiSaveFlag, Region *r ) {
104  /* set clearDelayed to 0 so that nested calls to this function do not call clearDelay() */
105  int recclearDelayed = ruleEngineConfig.clearDelayed;
107 
108  rError_t errmsgBuf;
109  errmsgBuf.errMsg = NULL;
110  errmsgBuf.len = 0;
111 
112  Env *env = defaultEnv( r );
113 
114  rei->status = 0;
115 
116  int rescode = 0;
117  if ( msParamArray != NULL ) {
118  if ( strncmp( rule, "@external\n", 10 ) == 0 ) {
119  rescode = parseAndComputeMsParamArrayToEnv( msParamArray, globalEnv( env ), rei, reiSaveFlag, &errmsgBuf, r );
120  RE_ERROR( rescode < 0 );
121  rule = rule + 10;
122  }
123  else {
124  rescode = convertMsParamArrayToEnv( msParamArray, globalEnv( env ), r );
125  RE_ERROR( rescode < 0 );
126  }
127  }
128 
129  deleteFromHashTable(globalEnv(env)->current, "ruleExecOut");
130 
131  rei->msParamArray = msParamArray;
132 
133  rescode = parseAndComputeRule( rule, env, rei, reiSaveFlag, &errmsgBuf, r );
134  RE_ERROR( rescode < 0 );
135 
136  if ( NULL == rei->msParamArray ) {
137  rei->msParamArray = newMsParamArray();
138  }
139  rescode = convertEnvToMsParamArray( rei->msParamArray, env, &errmsgBuf, r );
140  RE_ERROR( rescode < 0 );
141 
142  freeRErrorContent( &errmsgBuf );
143  /* deleteEnv(env, 3); */
144 
145  return rescode;
146 error:
147  logErrMsg( &errmsgBuf, &rei->rsComm->rError );
148  rei->status = rescode;
149  freeRErrorContent( &errmsgBuf );
150  /* deleteEnv(env, 3); */
151  if ( recclearDelayed ) {
152  clearDelayed();
153  }
154  ruleEngineConfig.clearDelayed = recclearDelayed;
155 
156  return rescode;
157 
158 
159 }
160 
161 int parseAndComputeRuleNewEnv( char *rule, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r ) {
162  Env *env = defaultEnv( r );
163 
164  int rescode = 0;
165 
166  if ( msParamArray != NULL ) {
167  rescode = convertMsParamArrayToEnv( msParamArray, env->previous, r );
168  RE_ERROR( rescode < 0 );
169  deleteFromHashTable(env->previous->current, "ruleExecOut");
170  }
171 
172  rescode = parseAndComputeRule( rule, env, rei, reiSaveFlag, errmsg, r );
173  RE_ERROR( rescode < 0 );
174 
175  rescode = convertEnvToMsParamArray( rei->msParamArray, env, errmsg, r );
176  RE_ERROR( rescode < 0 );
177  /* deleteEnv(env, 3); */
178  return rescode;
179 
180 error:
181 
182  /* deleteEnv(env, 3); */
183  return rescode;
184 }
185 
186 /* parse and compute a rule */
187 int parseAndComputeRule( char *rule, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) {
188  if ( overflow( rule, MAX_RULE_LEN ) ) {
189  addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" );
190  return RE_BUFFER_OVERFLOW;
191  }
192  Node *node;
193  Pointer *e = newPointer2( rule );
194  if ( e == NULL ) {
195  addRErrorMsg( errmsg, RE_POINTER_ERROR, "error: can not create a Pointer." );
196  return RE_POINTER_ERROR;
197  }
198 
199  int tempLen = ruleEngineConfig.extRuleSet->len;
200 
201  int checkPoint = checkPointExtRuleSet( r );
202 
203  int rescode;
204 
205  int errloc;
206 
207  RuleDesc *rd = NULL;
208  Res *res = NULL;
209 
210  /* add rules into ext rule set */
211  rescode = parseRuleSet( e, ruleEngineConfig.extRuleSet, ruleEngineConfig.extFuncDescIndex, &errloc, errmsg, r );
212  deletePointer( e );
213  if ( rescode != 0 ) {
214  rescode = RE_PARSER_ERROR;
215  RETURN;
216  }
217 
218  /* add rules into rule index */
219  int i;
220  for ( i = tempLen; i < ruleEngineConfig.extRuleSet->len; i++ ) {
223  }
224  }
225 
226  for ( i = tempLen; i < ruleEngineConfig.extRuleSet->len; i++ ) {
228  Hashtable *varTypes = newHashTable2( 10, r );
229 
230  List *typingConstraints = newList( r );
231  Node *errnode;
232  ExprType *type = typeRule( ruleEngineConfig.extRuleSet->rules[i], ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, &errnode, r );
233 
234  if ( getNodeType( type ) == T_ERROR ) {
235  /* rescode = TYPE_ERROR; # TGR, since renamed to RE_TYPE_ERROR */
236  rescode = RE_TYPE_ERROR;
237  RETURN;
238  }
239  }
240  }
241 
242  /* exec the first rule */
243  rd = ruleEngineConfig.extRuleSet->rules[tempLen];
244  node = rd->node;
245 
246  res = execRuleNodeRes( node, NULL, 0, GlobalAllRuleExecFlag, env, rei, reiSaveFlag, errmsg, r );
247  rescode = getNodeType( res ) == N_ERROR ? RES_ERR_CODE( res ) : 0;
248 ret:
249  /* remove rules from ext rule set */
250  popExtRuleSet( checkPoint );
251 
252  return rescode;
253 }
254 
255 /* call an action with actionName and string parameters */
256 Res *computeExpressionWithParams( const char *actionName, const char **params, int paramsCount, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r ) {
257 #ifdef DEBUG
258  char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024];
259  snprintf( buf, 1024, "computExpressionWithParams: %s\n", actionName );
260  writeToTmp( "entry.log", buf );
261 #endif
262  /* set clearDelayed to 0 so that nested calls to this function do not call clearDelay() */
263  int recclearDelayed = ruleEngineConfig.clearDelayed;
265 
266  if ( overflow( actionName, MAX_NAME_LEN ) ) {
267  addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" );
268  return newErrorRes( r, RE_BUFFER_OVERFLOW );
269  }
270  int k;
271  for ( k = 0; k < paramsCount; k++ ) {
272  if ( overflow( params[k], MAX_RULE_LEN ) ) {
273  addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" );
274  return newErrorRes( r, RE_BUFFER_OVERFLOW );
275  }
276  }
277 
278  Node** paramNodes = ( Node ** )region_alloc( r, sizeof( Node * ) * paramsCount );
279  int i;
280  for ( i = 0; i < paramsCount; i++ ) {
281 
282  Node *node;
283 
284  /*Pointer *e = newPointer2(params[i]);
285 
286  if(e == NULL) {
287  addRErrorMsg(errmsg, -1, "error: can not create Pointer.");
288  return newErrorRes(r, -1);
289  }
290 
291  node = parseTermRuleGen(e, 1, errmsg, r);*/
292  node = newNode( TK_STRING, params[i], 0, r );
293  /*if(node==NULL) {
294  addRErrorMsg(errmsg, OUT_OF_MEMORY, "error: out of memory.");
295  return newErrorRes(r, OUT_OF_MEMORY);
296  } else if (getNodeType(node) == N_ERROR) {
297  return newErrorRes(r, RES_ERR_CODE(node));
298 
299  }*/
300 
301  paramNodes[i] = node;
302  }
303 
304  Node *node = createFunctionNode( actionName, paramNodes, paramsCount, NULL, r );
305  Env *global = newEnv( newHashTable2( 10, r ), NULL, NULL, r );
306  Env *env = newEnv( newHashTable2( 10, r ), global, NULL, r );
307  if ( msParamArray != NULL ) {
308  convertMsParamArrayToEnv( msParamArray, global, r );
309  deleteFromHashTable(global->current, "ruleExecOut");
310  }
311  Res *res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r );
312  /* deleteEnv(env, 3); */
313  if ( recclearDelayed ) {
314  clearDelayed();
315  }
316  ruleEngineConfig.clearDelayed = recclearDelayed;
317  return res;
318 }
319 ExprType *typeRule( RuleDesc *rule, Env *funcDesc, Hashtable *varTypes, List *typingConstraints, rError_t *errmsg, Node **errnode, Region *r ) {
320  /* printf("%s\n", node->subtrees[0]->text); */
321  addRErrorMsg( errmsg, -1, ERR_MSG_SEP );
322  char buf[ERR_MSG_LEN];
323  Node *node = rule->node;
324  int dynamictyping = rule->dynamictyping;
325 
326  ExprType *resType = typeExpression3( node->subtrees[1], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r );
327  /*printf("Type %d\n",resType->t); */
328  RE_ERROR( getNodeType( resType ) == T_ERROR );
329  if ( getNodeType( resType ) != T_BOOL && getNodeType( resType ) != T_VAR && getNodeType( resType ) != T_DYNAMIC ) {
330  char buf2[1024], buf3[ERR_MSG_LEN];
331  typeToString( resType, varTypes, buf2, 1024 );
332  snprintf( buf3, ERR_MSG_LEN, "error: the type %s of the rule condition is not supported", buf2 );
334  addRErrorMsg( errmsg, RE_TYPE_ERROR, buf );
335  RE_ERROR( 1 );
336  }
337  resType = typeExpression3( node->subtrees[2], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r );
338  RE_ERROR( getNodeType( resType ) == T_ERROR );
339  resType = typeExpression3( node->subtrees[3], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r );
340  RE_ERROR( getNodeType( resType ) == T_ERROR );
341  /* printVarTypeEnvToStdOut(varTypes); */
342  RE_ERROR( solveConstraints( typingConstraints, varTypes, errmsg, errnode, r ) == ABSURDITY );
343  int i;
344  for ( i = 1; i <= 3; i++ ) { // 1 = cond, 2 = actions, 3 = recovery
345  postProcessCoercion( node->subtrees[i], varTypes, errmsg, errnode, r );
346  postProcessActions( node->subtrees[i], funcDesc, errmsg, errnode, r );
347  }
348  /*printTree(node, 0); */
349  return newSimpType( T_INT, r );
350 
351 error:
352  snprintf( buf, ERR_MSG_LEN, "type error: in rule %s", node->subtrees[0]->text );
353  addRErrorMsg( errmsg, RE_TYPE_ERROR, buf );
354  return resType;
355 
356 }
357 
358 ExprType *typeRuleSet( RuleSet *ruleset, rError_t *errmsg, Node **errnode, Region *r ) {
361  ExprType *res;
362  int i;
363  for ( i = 0; i < ruleset->len; i++ ) {
364  RuleDesc *rule = ruleset->rules[i];
365  if ( rule->ruleType == RK_REL || rule->ruleType == RK_FUNC ) {
366  List *typingConstraints = newList( r );
367  Hashtable *varTypes = newHashTable2( 100, r );
368  ExprType *restype = typeRule( rule, funcDesc, varTypes, typingConstraints, errmsg, errnode, r );
369  /*char buf[1024]; */
370  /*typingConstraintsToString(typingConstraints, buf, 1024); */
371  /*printf("rule %s, typing constraints: %s\n", ruleset->rules[i]->subtrees[0]->text, buf); */
372  if ( getNodeType( restype ) == T_ERROR ) {
373  res = restype;
374  char *errbuf = ( char * ) malloc( ERR_MSG_LEN * 1024 * sizeof( char ) );
375  errMsgToString( errmsg, errbuf, ERR_MSG_LEN * 1024 );
376 #ifdef DEBUG
377  writeToTmp( "ruleerr.log", errbuf );
378  writeToTmp( "ruleerr.log", "\n" );
379 #endif
380  rodsLog( LOG_ERROR, "%s", errbuf );
381  free( errbuf );
382  freeRErrorContent( errmsg );
383  RETURN;
384  }
385  /* check that function names are unique and do not conflict with system msis */
386  char errbuf[ERR_MSG_LEN];
387  char *ruleName = rule->node->subtrees[0]->text;
388  FunctionDesc *fd;
389  if ( ( fd = ( FunctionDesc * )lookupFromEnv( funcDesc, ruleName ) ) != NULL ) {
390  if ( getNodeType( fd ) != N_FD_EXTERNAL && getNodeType( fd ) != N_FD_RULE_INDEX_LIST ) {
391  char *err;
392  switch ( getNodeType( fd ) ) {
393  case N_FD_CONSTRUCTOR:
394  err = "redefinition of constructor";
395  break;
396  case N_FD_DECONSTRUCTOR:
397  err = "redefinition of deconstructor";
398  break;
399  case N_FD_FUNCTION:
400  err = "redefinition of system microservice";
401  break;
402  default:
403  err = "redefinition of system symbol";
404  break;
405  }
406 
407  generateErrMsg( err, NODE_EXPR_POS( rule->node ), rule->node->base, errbuf );
408  addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf );
410  *errnode = rule->node;
411  RETURN;
412  }
413  }
414 
415  RuleDesc *rd = ( RuleDesc * )lookupFromHashTable( ruleType, ruleName );
416  if ( rd != NULL ) {
417  if ( rule->ruleType == RK_FUNC || rd ->ruleType == RK_FUNC ) {
418  generateErrMsg( "redefinition of function", NODE_EXPR_POS( rule->node ), rule->node->base, errbuf );
419  addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf );
420  generateErrMsg( "previous definition", NODE_EXPR_POS( rd->node ), rd->node->base, errbuf );
421  addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf );
423  *errnode = rule->node;
424  RETURN;
425  }
426  }
427  else {
428  insertIntoHashTable( ruleType, ruleName, rule );
429  }
430  }
431  }
432  res = newSimpType( T_INT, r ); /* Although a rule set does not have type T_INT, return T_INT to indicate success. */
433 
434 ret:
435  return res;
436 }
437 
438 int typeNode( Node *node, Hashtable *varTypes, rError_t *errmsg, Node **errnode, Region *r ) {
439  if ( ( node->option & OPTION_TYPED ) == 0 ) {
440  /*printTree(node, 0); */
441  List *typingConstraints = newList( r );
442  Res *resType = typeExpression3( node, 0, ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, errnode, r );
443  /*printf("Type %d\n",resType->t); */
444  if ( getNodeType( resType ) == T_ERROR ) {
445  addRErrorMsg( errmsg, RE_TYPE_ERROR, "type error: in rule" );
446  return RE_TYPE_ERROR;
447  }
448  postProcessCoercion( node, varTypes, errmsg, errnode, r );
450  /* printTree(node, 0); */
451  varTypes = NULL;
453  }
454  return 0;
455 }
456 
457 /* compute an expression or action given by an AST node */
458 Res* computeNode( Node *node, Node *reco, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t* errmsg, Region *r ) {
459  Hashtable *varTypes = newHashTable2( 10, r );
460  Region *rNew = make_region( 0, NULL );
461  Node *en;
462  Node **errnode = &en;
463  Res* res;
464  int errorcode;
465  if ( ( errorcode = typeNode( node, varTypes, errmsg, errnode, r ) ) != 0 ) {
466  res = newErrorRes( r, errorcode );
467  RETURN;
468  }
469  if ( reco != NULL && ( errorcode = typeNode( reco, varTypes, errmsg, errnode, r ) ) != 0 ) {
470  res = newErrorRes( r, errorcode );
471  RETURN;
472  }
473  if ( getNodeType( node ) == N_ACTIONS ) {
474  res = evaluateActions( node, NULL, GlobalAllRuleExecFlag, rei, reiSaveFlag, env, errmsg, rNew );
475  }
476  else {
477  res = evaluateExpression3( node, GlobalAllRuleExecFlag, 0, rei, reiSaveFlag, env, errmsg, rNew );
478  }
479 
480  /* switch (TYPE(res)) {
481  case T_ERROR:
482  addRErrorMsg(errmsg, -1, "error: in rule");
483  break;
484  default:
485  break;
486  }*/
487 ret:
488  res = cpRes( res, r );
489  cpEnv( env, r );
490  region_free( rNew );
491  return res;
492 }
493 
494 /* parse and compute an expression
495  *
496  */
497 Res *parseAndComputeExpression( char *expr, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) {
498  Res *res = NULL;
499  char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024];
500  int rulegen;
501  Node *node = NULL, *recoNode = NULL;
502 
503 #ifdef DEBUG
504  snprintf( buf, 1024, "parseAndComputeExpression: %s\n", expr );
505  writeToTmp( "entry.log", buf );
506 #endif
507  if ( overflow( expr, MAX_RULE_LEN ) ) {
508  addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" );
509  return newErrorRes( r, RE_BUFFER_OVERFLOW );
510  }
511  Pointer *e = newPointer2( expr );
512  ParserContext *pc = newParserContext( errmsg, r );
513  if ( e == NULL ) {
514  addRErrorMsg( errmsg, RE_POINTER_ERROR, "error: can not create pointer." );
515  res = newErrorRes( r, RE_POINTER_ERROR );
516  RETURN;
517  }
518  rulegen = isRuleGenSyntax( expr );
519 
520  if ( rulegen ) {
521  node = parseTermRuleGen( e, rulegen, pc );
522  }
523  else {
524  node = parseActionsRuleGen( e, rulegen, 1, pc );
525  }
526  if ( node == NULL ) {
527  addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." );
528  res = newErrorRes( r, RE_OUT_OF_MEMORY );
529  RETURN;
530  }
531  else if ( getNodeType( node ) == N_ERROR ) {
532  generateErrMsg( "error: syntax error", NODE_EXPR_POS( node ), node->base, buf );
533  addRErrorMsg( errmsg, RE_PARSER_ERROR, buf );
534  res = newErrorRes( r, RE_PARSER_ERROR );
535  RETURN;
536  }
537  else {
538  Token *token;
539  token = nextTokenRuleGen( e, pc, 0, 0 );
540  if ( strcmp( token->text, "|" ) == 0 ) {
541  recoNode = parseActionsRuleGen( e, rulegen, 1, pc );
542  if ( recoNode == NULL ) {
543  addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." );
544  res = newErrorRes( r, RE_OUT_OF_MEMORY );
545  RETURN;
546  }
547  else if ( getNodeType( recoNode ) == N_ERROR ) {
548  generateErrMsg( "error: syntax error", NODE_EXPR_POS( recoNode ), recoNode->base, buf );
549  addRErrorMsg( errmsg, RE_PARSER_ERROR, buf );
550  res = newErrorRes( r, RE_PARSER_ERROR );
551  RETURN;
552  }
553  token = nextTokenRuleGen( e, pc, 0, 0 );
554  }
555  if ( token->type != TK_EOS ) {
556  Label pos;
557  getFPos( &pos, e, pc );
558  generateErrMsg( "error: unparsed suffix", pos.exprloc, pos.base, buf );
559  addRErrorMsg( errmsg, RE_UNPARSED_SUFFIX, buf );
560  res = newErrorRes( r, RE_UNPARSED_SUFFIX );
561  RETURN;
562  }
563  }
564  res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r );
565 ret:
566  deleteParserContext( pc );
567  deletePointer( e );
568  return res;
569 }
570 
571 int generateRuleTypes( RuleSet *inRuleSet, Hashtable *symbol_type_table, Region *r ) {
572  int i;
573  for ( i = 0; i < inRuleSet->len; i++ ) {
574  Node *ruleNode = inRuleSet->rules[i]->node;
575  if ( ruleNode == NULL ) {
576  continue;
577  }
578  char *key = ruleNode->subtrees[0]->text;
579  int arity = RULE_NODE_NUM_PARAMS( ruleNode );
580 
581  ExprType **paramTypes = ( ExprType** ) region_alloc( r, sizeof( ExprType * ) * arity );
582  int k;
583  for ( k = 0; k < arity; k++ ) {
584  paramTypes[k] = newTVar( r );
585  }
586  ExprType *ruleType = newFuncTypeVarArg( arity, OPTION_VARARG_ONCE, paramTypes, newSimpType( T_INT, r ), r );
587 
588  if ( insertIntoHashTable( symbol_type_table, key, ruleType ) == 0 ) {
589  return 0;
590  }
591  }
592  return 1;
593 }
594 
595 RuleDesc* getRuleDesc( int ri ) {
596 
597  if ( ri < APP_RULE_INDEX_OFF ) {
598  return ruleEngineConfig.extRuleSet->rules[ri];
599  }
600  else if ( ri < CORE_RULE_INDEX_OFF ) {
601  ri = ri - APP_RULE_INDEX_OFF;
602  return ruleEngineConfig.appRuleSet->rules[ri];
603  }
604  else {
605  ri = ri - CORE_RULE_INDEX_OFF;
606  return ruleEngineConfig.coreRuleSet->rules[ri];
607  }
608 }
609 
610 /*
611  * Set retOutParam to 1 if you need to retrieve the output parameters from inMsParamArray and 0 if not
612  */
613 Res *parseAndComputeExpressionAdapter( char *inAction, msParamArray_t *inMsParamArray, int retOutParams, ruleExecInfo_t *rei, int reiSaveFlag, Region *r ) { // JMC - backport 4540
614  /* set clearDelayed to 0 so that nested calls to this function do not call clearDelay() */
615  int recclearDelayed = ruleEngineConfig.clearDelayed;
617  int freeRei = 0;
618 
619  if ( rei == NULL ) {
620  rei = ( ruleExecInfo_t * ) malloc( sizeof( ruleExecInfo_t ) );
621  memset( rei, 0, sizeof( ruleExecInfo_t ) );
622  freeRei = 1;
623  }
624 
625  rei->status = 0;
626  Env *env = defaultEnv( r );
627 
628  /* retrieve generated data here as it may be overridden by convertMsParamArrayToEnv */
629  Res *res;
630  rError_t errmsgBuf;
631  errmsgBuf.errMsg = NULL;
632  errmsgBuf.len = 0;
633 
634  if ( inMsParamArray != NULL ) {
635  convertMsParamArrayToEnv( inMsParamArray, env, r );
636  deleteFromHashTable(env->current, "ruleExecOut");
637  }
638 
639  res = parseAndComputeExpression( inAction, env, rei, reiSaveFlag, &errmsgBuf, r );
640  if ( retOutParams ) { // JMC - backport 4540
641  if ( inMsParamArray != NULL ) {
642  clearMsParamArray( inMsParamArray, 0 );
643  convertEnvToMsParamArray( inMsParamArray, env, &errmsgBuf, r );
644  }
645  }
646 
647  /* deleteEnv(env, 3); */
648  if ( getNodeType( res ) == N_ERROR && !freeRei ) {
649  logErrMsg( &errmsgBuf, &rei->rsComm->rError );
650  rei->status = RES_ERR_CODE( res );
651  }
652 
653  freeRErrorContent( &errmsgBuf );
654 
655  if ( freeRei ) {
656  free( rei );
657  }
658 
659  if ( recclearDelayed ) {
660  clearDelayed();
661  }
662 
663  ruleEngineConfig.clearDelayed = recclearDelayed;
664 
665  return res;
666 
667 }
668 int overflow( const char* expr, int len ) {
669  int i;
670  for ( i = 0; i < len + 1; i++ ) {
671  if ( expr[i] == 0 ) {
672  return 0;
673  }
674  }
675  return 1;
676 }
rodsLog
void rodsLog(int level, const char *formatStr,...)
Definition: rodsLog.cpp:86
ruleSet::rules
RuleDesc * rules[50000]
Definition: restructs.hpp:284
NULL
#define NULL
Definition: rodsDef.h:70
irods.pypyodbc.restype
restype
Definition: pypyodbc.py:705
rError_t::len
int len
Definition: rodsError.h:25
Cache::clearDelayed
int clearDelayed
Definition: configuration.hpp:65
overflow
int overflow(const char *expr, int len)
Definition: rules.cpp:668
typeNode
int typeNode(Node *node, Hashtable *varTypes, rError_t *errmsg, Node **errnode, Region *r)
Definition: rules.cpp:438
lookupFromEnv
const void * lookupFromEnv(Env *env, const char *key)
Definition: utils.cpp:813
solveConstraints
Satisfiability solveConstraints(List *typingConstraints, Hashtable *typingEnv, rError_t *errmsg, Node **errnode, Region *r)
Definition: typing.cpp:550
N_FD_DECONSTRUCTOR
@ N_FD_DECONSTRUCTOR
Definition: restructs.hpp:145
RK_FUNC
@ RK_FUNC
Definition: restructs.hpp:265
reHelpers1.hpp
token::type
NodeType type
Definition: restructs.hpp:294
nextTokenRuleGen
Token * nextTokenRuleGen(Pointer *expr, ParserContext *pc, int rulegen, int ext)
Definition: parser.cpp:160
index.hpp
parseRuleSet
int parseRuleSet(Pointer *e, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r)
Definition: parser.cpp:3179
RuleExecInfo::status
int status
Definition: irods_re_structs.hpp:19
region_alloc
void * region_alloc(Region *r, size_t s)
Definition: region.cpp:138
createFunctionNode
Node * createFunctionNode(const char *fn, Node **params, int paramsLen, Label *exprloc, Region *r)
Definition: restructs.cpp:429
env::previous
Env * previous
Definition: restructs.hpp:228
postProcessCoercion
void postProcessCoercion(Node *expr, Hashtable *varTypes, rError_t *errmsg, Node **errnode, Region *r)
Definition: typing.cpp:1176
T_UNSPECED
@ T_UNSPECED
Definition: restructs.hpp:156
getNodeType
#define getNodeType(x)
Definition: restructs.hpp:69
popExtRuleSet
void popExtRuleSet(int checkPoint)
Definition: configuration.cpp:144
env
Definition: restructs.hpp:226
parseAndComputeRule
int parseAndComputeRule(char *rule, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r)
Definition: rules.cpp:187
configuration.hpp
convertEnvToMsParamArray
int convertEnvToMsParamArray(msParamArray_t *var, Env *env, rError_t *errmsg, Region *r)
Definition: conversion.cpp:460
typeToString
char * typeToString(ExprType *type, Hashtable *var_types, char *buf, int bufsize)
Definition: utils.cpp:522
rcMisc.h
RuleDesc::ruleType
RuleType ruleType
Definition: restructs.hpp:276
ruleSet::len
int len
Definition: restructs.hpp:283
RULE_NODE_NUM_PARAMS
#define RULE_NODE_NUM_PARAMS(r)
Definition: restructs.hpp:45
ParserContext
Definition: parser.hpp:50
token::text
char text[1023+1]
Definition: restructs.hpp:295
filesystem.hpp
make_region
Region * make_region(size_t is, jmp_buf *label)
Definition: region.cpp:85
node
Definition: restructs.hpp:244
typeExpression3
ExprType * typeExpression3(Node *expr, int notyping, Env *funcDesc, Hashtable *varTypes, List *typingConstraints, rError_t *errmsg, Node **errnode, Region *r)
Definition: typing.cpp:1035
getRuleBasePath
char * getRuleBasePath(const char *ruleBaseName, char rulesFileName[(1024+64)])
Definition: filesystem.cpp:14
CORE_RULE_INDEX_OFF
#define CORE_RULE_INDEX_OFF
Definition: reconstants.hpp:28
defaultEnv
Env * defaultEnv(Region *r)
Definition: rules.cpp:96
Cache::coreRuleSet
RuleSet * coreRuleSet
Definition: configuration.hpp:53
reGlobalsExtern.hpp
generateRuleTypes
int generateRuleTypes(RuleSet *inRuleSet, Hashtable *symbol_type_table, Region *r)
Definition: rules.cpp:571
N_FD_RULE_INDEX_LIST
@ N_FD_RULE_INDEX_LIST
Definition: restructs.hpp:147
TYPE
#define TYPE(x)
Definition: restructs.hpp:23
token
Definition: restructs.hpp:293
LOG_ERROR
#define LOG_ERROR
Definition: rodsLog.h:43
parseActionsRuleGen
Node * parseActionsRuleGen(Pointer *expr, int rulegn, int backwardCompatible, ParserContext *pc)
Definition: parser.cpp:3400
pointer
Definition: parser.hpp:34
label::exprloc
long exprloc
Definition: restructs.hpp:289
APP_RULE_INDEX_OFF
#define APP_RULE_INDEX_OFF
Definition: reconstants.hpp:29
newTVar
ExprType * newTVar(Region *r)
Definition: restructs.cpp:62
newParserContext
ParserContext * newParserContext(rError_t *errmsg, Region *r)
Definition: parser.cpp:70
newPointer2
Pointer * newPointer2(char *buf)
Definition: parser.cpp:2435
parseAndComputeExpression
Res * parseAndComputeExpression(char *expr, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r)
Definition: rules.cpp:497
Cache::appRuleSet
RuleSet * appRuleSet
Definition: configuration.hpp:54
irods_re_plugin.hpp
logErrMsg
void logErrMsg(rError_t *errmsg, rError_t *system)
Definition: utils.cpp:762
newPointer
Pointer * newPointer(FILE *buf, const char *ruleBaseName)
Definition: parser.cpp:2430
parseAndComputeExpressionAdapter
Res * parseAndComputeExpressionAdapter(char *inAction, msParamArray_t *inMsParamArray, int retOutParams, ruleExecInfo_t *rei, int reiSaveFlag, Region *r)
Definition: rules.cpp:613
deleteFromHashTable
const void * deleteFromHashTable(Hashtable *h, const char *key)
Definition: hashtable.cpp:184
errMsgToString
char * errMsgToString(rError_t *errmsg, char *buf, int buflen)
Definition: utils.cpp:778
RuleExecInfo::rsComm
rsComm_t * rsComm
Definition: irods_re_structs.hpp:22
node::text
char * text
Definition: restructs.hpp:252
functions.hpp
postProcessActions
void postProcessActions(Node *expr, Env *systemFunctionTables, rError_t *errmsg, Node **errnode, Region *r)
Definition: typing.cpp:1204
parseAndComputeRuleNewEnv
int parseAndComputeRuleNewEnv(char *rule, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r)
Definition: rules.cpp:161
clearMsParamArray
int clearMsParamArray(msParamArray_t *msParamArray, int freeStruct)
Definition: msParam.cpp:447
TK_EOS
@ TK_EOS
Definition: restructs.hpp:110
newHashTable2
Hashtable * newHashTable2(int size, Region *r)
Definition: hashtable.cpp:72
rsComm_t::rError
rError_t rError
Definition: rcConnect.h:158
rError_t
Definition: rodsError.h:24
newErrorRes
Res * newErrorRes(Region *r, int errcode)
Definition: restructs.cpp:259
ruleType
ruleType
Definition: restructs.hpp:263
N_ACTIONS
@ N_ACTIONS
Definition: restructs.hpp:134
parseTermRuleGen
Node * parseTermRuleGen(Pointer *expr, int rulegn, ParserContext *pc)
Definition: parser.cpp:3385
node::subtrees
struct node ** subtrees
Definition: restructs.hpp:254
MAX_NUM_RULES
#define MAX_NUM_RULES
Definition: reconstants.hpp:27
N_FD_EXTERNAL
@ N_FD_EXTERNAL
Definition: restructs.hpp:146
RE_TYPE_ERROR
@ RE_TYPE_ERROR
Definition: rodsErrorTable.h:720
MsParamArray::msParam
msParam_t ** msParam
Definition: msParam.h:87
rules.hpp
evaluateExpression3
Res * evaluateExpression3(Node *expr, int applyAll, int force, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
Definition: arithmetics.cpp:50
isRuleGenSyntax
int isRuleGenSyntax(char *expr)
Definition: utils.cpp:922
RE_UNPARSED_SUFFIX
@ RE_UNPARSED_SUFFIX
Definition: rodsErrorTable.h:696
RE_OUT_OF_MEMORY
@ RE_OUT_OF_MEMORY
Definition: rodsErrorTable.h:714
execRuleNodeRes
Res * execRuleNodeRes(Node *rule, Res **args, unsigned int argc, int applyAll, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r)
Definition: arithmetics.cpp:1416
typeRule
ExprType * typeRule(RuleDesc *rule, Env *funcDesc, Hashtable *varTypes, List *typingConstraints, rError_t *errmsg, Node **errnode, Region *r)
Definition: rules.cpp:319
updateInEnv
void updateInEnv(Env *env, char *varname, Res *res)
Definition: utils.cpp:821
newNode
Node * newNode(NodeType type, const char *text, Label *exprloc, Region *r)
Definition: restructs.cpp:10
T_STRING
@ T_STRING
Definition: restructs.hpp:161
MAX_NAME_LEN
#define MAX_NAME_LEN
Definition: rodsDef.h:61
terminate_irods_processes.e
e
Definition: terminate_irods_processes.py:19
NODE_EXPR_POS
#define NODE_EXPR_POS(x)
Definition: restructs.hpp:68
globalEnv
Env * globalEnv(Env *env)
Definition: utils.cpp:754
RE_ERROR
#define RE_ERROR(cond)
Definition: rules.cpp:17
cpRes
#define cpRes(p, r)
Definition: utils.hpp:48
newSimpType
ExprType * newSimpType(NodeType t, Region *r)
Definition: restructs.cpp:70
insertIntoHashTable
int insertIntoHashTable(Hashtable *h, const char *key, const void *value)
Definition: hashtable.cpp:99
getFPos
Label * getFPos(Label *label, Pointer *p, ParserContext *context)
Definition: parser.cpp:2635
GlobalAllRuleExecFlag
int GlobalAllRuleExecFlag
Definition: libirods_rule_engine_plugin-irods_rule_language.cpp:57
label::base
char * base
Definition: restructs.hpp:290
addRErrorMsg
int addRErrorMsg(rError_t *myError, int status, const char *msg)
Definition: rcMisc.cpp:121
N_FD_CONSTRUCTOR
@ N_FD_CONSTRUCTOR
Definition: restructs.hpp:144
RETURN
#define RETURN(status)
Definition: microservice.hpp:351
N_FD_FUNCTION
@ N_FD_FUNCTION
Definition: restructs.hpp:143
parseAndComputeMsParamArrayToEnv
int parseAndComputeMsParamArrayToEnv(msParamArray_t *var, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r)
Definition: rules.cpp:65
parseAndComputeRuleAdapter
int parseAndComputeRuleAdapter(char *rule, msParamArray_t *msParamArray, ruleExecInfo_t *rei, int reiSaveFlag, Region *r)
Definition: rules.cpp:103
debug.hpp
lookupFromHashTable
const void * lookupFromHashTable(Hashtable *h, const char *key)
Definition: hashtable.cpp:222
node::base
char * base
Definition: restructs.hpp:255
OPTION_VARARG_ONCE
#define OPTION_VARARG_ONCE
Definition: restructs.hpp:72
cpEnv
void cpEnv(Env *env, Region *r)
Definition: utils.cpp:396
region
Definition: region.h:45
T_BOOL
@ T_BOOL
Definition: restructs.hpp:163
MsParamArray::len
int len
Definition: msParam.h:85
arithmetics.hpp
MsParam::label
char * label
Definition: msParam.h:77
typeRuleSet
ExprType * typeRuleSet(RuleSet *ruleset, rError_t *errmsg, Node **errnode, Region *r)
Definition: rules.cpp:358
RuleDesc
Definition: restructs.hpp:272
newList
List * newList(Region *r)
Definition: list.cpp:6
newEnv
Env * newEnv(Hashtable *current, Env *previous, Env *lower, Region *r)
Definition: restructs.cpp:281
readRuleSetFromFile
int readRuleSetFromFile(const char *ruleBaseName, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r)
Definition: rules.cpp:28
newRes
Res * newRes(Region *r)
Definition: restructs.cpp:176
evaluateActions
Res * evaluateActions(Node *expr, Node *reco, int applyAll, ruleExecInfo_t *rei, int reiSaveFlag, Env *env, rError_t *errmsg, Region *r)
Definition: arithmetics.cpp:473
getRuleDesc
RuleDesc * getRuleDesc(int ri)
Definition: rules.cpp:595
MAX_RULE_LEN
#define MAX_RULE_LEN
Definition: reconstants.hpp:9
RuleExecInfo::msParamArray
msParamArray_t * msParamArray
Definition: irods_re_structs.hpp:24
update_schema_ids_for_cmake.file
file
Definition: update_schema_ids_for_cmake.py:21
T_VAR
@ T_VAR
Definition: restructs.hpp:171
error
int error
Definition: filesystem.cpp:101
RuleDesc::node
Node * node
Definition: restructs.hpp:275
RuleExecInfo
Definition: irods_re_structs.hpp:18
deletePointer
void deletePointer(Pointer *buf)
Definition: parser.cpp:2441
T_INT
@ T_INT
Definition: restructs.hpp:160
RE_BUFFER_OVERFLOW
@ RE_BUFFER_OVERFLOW
Definition: rodsErrorTable.h:701
Cache::extFuncDescIndex
Env * extFuncDescIndex
Definition: configuration.hpp:59
N_ERROR
@ N_ERROR
Definition: restructs.hpp:111
RuleDesc::dynamictyping
int dynamictyping
Definition: restructs.hpp:277
generateErrMsg
char * generateErrMsg(char *msg, long errloc, char *ruleBaseName, char errbuf[1024])
Definition: parser.cpp:3555
ABSURDITY
@ ABSURDITY
Definition: typing.hpp:13
env::current
Hashtable * current
Definition: restructs.hpp:227
TK_STRING
@ TK_STRING
Definition: restructs.hpp:115
computeExpressionWithParams
Res * computeExpressionWithParams(const char *actionName, const char **params, int paramsCount, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r)
Definition: rules.cpp:256
region_free
void region_free(Region *r)
Definition: region.cpp:146
RULES_FILE_READ_ERROR
@ RULES_FILE_READ_ERROR
Definition: rodsErrorTable.h:596
node::option
int option
Definition: restructs.hpp:247
T_DYNAMIC
@ T_DYNAMIC
Definition: restructs.hpp:158
appendRuleIntoExtIndex
void appendRuleIntoExtIndex(RuleDesc *rule, int i, Region *r)
Definition: configuration.cpp:93
newErrorType
ExprType * newErrorType(int errcode, Region *r)
Definition: restructs.cpp:73
ruleEngineConfig
Cache ruleEngineConfig
Definition: configuration.cpp:68
deleteParserContext
void deleteParserContext(ParserContext *t)
Definition: parser.cpp:85
readRuleSetFromLocalFile
int readRuleSetFromLocalFile(const char *ruleBaseName, const char *rulesFileName, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r)
Definition: rules.cpp:34
clearDelayed
void clearDelayed()
Definition: configuration.cpp:221
hashtable
Definition: irods_hashtable.h:16
convertMsParamArrayToEnv
int convertMsParamArrayToEnv(msParamArray_t *var, Env *env, Region *r)
Definition: conversion.cpp:517
irods_error.hpp
writeToTmp
int writeToTmp(char *fileName, char *text)
Definition: utils.cpp:681
RE_PARSER_ERROR
@ RE_PARSER_ERROR
Definition: rodsErrorTable.h:695
RES_ERR_CODE
#define RES_ERR_CODE(x)
Definition: restructs.hpp:50
RE_FUNCTION_REDEFINITION
@ RE_FUNCTION_REDEFINITION
Definition: rodsErrorTable.h:721
label
Definition: restructs.hpp:288
MsParamArray
Definition: msParam.h:84
computeNode
Res * computeNode(Node *node, Node *reco, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r)
Definition: rules.cpp:458
T_ERROR
@ T_ERROR
Definition: restructs.hpp:157
newMsParamArray
msParamArray_t * newMsParamArray()
Definition: restructs.cpp:266
rError_t::errMsg
rErrMsg_t ** errMsg
Definition: rodsError.h:26
buf
static char buf[64+50+1]
Definition: rsAuthRequest.cpp:21
type
int type
Definition: filesystem.cpp:103
ERR_MSG_SEP
#define ERR_MSG_SEP
Definition: reconstants.hpp:21
OPTION_TYPED
#define OPTION_TYPED
Definition: restructs.hpp:78
newFuncTypeVarArg
ExprType * newFuncTypeVarArg(int arity, int vararg, ExprType **paramTypes, ExprType *elemType, Region *r)
Definition: restructs.cpp:85
irods_log.hpp
list
Definition: irods_list.h:13
freeRErrorContent
int freeRErrorContent(rError_t *myError)
Definition: rcMisc.cpp:182
checkPointExtRuleSet
int checkPointExtRuleSet(Region *r)
Definition: configuration.cpp:130
RE_POINTER_ERROR
@ RE_POINTER_ERROR
Definition: rodsErrorTable.h:697
ERR_MSG_LEN
#define ERR_MSG_LEN
Definition: rodsError.h:16
convertMsParamToRes
int convertMsParamToRes(msParam_t *mP, Res *res, Region *r)
Definition: conversion.cpp:142
Cache::extRuleSet
RuleSet * extRuleSet
Definition: configuration.hpp:55
RK_REL
@ RK_REL
Definition: restructs.hpp:264
ruleSet
Definition: restructs.hpp:282