Пример #1
0
/** 
 * Check input type, translate if matching 
 */
int		cmd_case()
{
  aspectype_t	*exprtype;
  revmexpr_t	*matchme;
  revmexpr_t	*candid;
  int		ret;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);
  if (!world.curjob->recur[world.curjob->curscope].rwrt.matchexpr)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Case is not in a match", -1);

  exprtype = aspect_type_get_by_id(ASPECT_TYPE_EXPR);
  if (!exprtype)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Expression type not found : lacking reflection ?", -1);

  /* If a previous case has already matched, simply end the transformation now :
     We must do that here because some "post" commands can be put after a matching 
     "case", so we only stop rewriting at the first case -following- a matching case */
  if (world.curjob->recur[world.curjob->curscope].rwrt.matched)
    {
      revm_move_pc(world.curjob->curcmd->endlabel);
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
    }

  /* Check if we match */
  matchme = (revmexpr_t *) world.curjob->recur[world.curjob->curscope].rwrt.matchexpr;
  if (!matchme->type)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Invalid type for matchme expression", -1);
  candid = revm_expr_create(matchme->type, "$candid", strdup(world.curjob->curcmd->param[0]));
  ret = (!candid ? 1 : revm_expr_match(candid, matchme));
  
  /* No match or bad match : nothing happens */
  if (ret)
    {
      world.curjob->recur[world.curjob->curscope].rwrt.matched = 0;
      PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
    }
  
  /* Matched : transform and execute post side effects if any */
  world.curjob->recur[world.curjob->curscope].rwrt.matched = 1;

  /* Sometimes the case command comes directly with appended post side-effects */
  if (!world.curjob->curcmd->param[1])
    PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);

  /* The rewrite output was directly specified in the case command */
  revm_case_transform(matchme, strdup(world.curjob->curcmd->param[1]));

  /* Additional side-effects were specified in the case command */
  if (world.curjob->curcmd->param[2] && 
      revm_case_execmd(world.curjob->curcmd->param[2]) < 0)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Post-side-effects commands failed", -1);
  
  /* Jump to end of the match construct */
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Пример #2
0
/** 
 * Perform the transformation (can be called from case or into commands) 
 * @param matchme
 * @param destvalue
 * @return
*/
static int	revm_case_transform(revmexpr_t *matchme, char *destvalue)
{
  u_int		dstnbr;
  char		*curptr;
  char		*foundptr;
  u_int		curidx;
  list_t	*exprlist;
  aspectype_t	*type;
  char		namebuf[BUFSIZ];
  char		*rname;
  revmexpr_t	*candid;
  list_t	*looplist;
  int		ret;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* We matched : first find how many elements there is in the target (list) type */
  exprlist = world.curjob->recur[world.curjob->curscope].rwrt.transformed;
  dstnbr = 1;

  for (curidx = world.curjob->iter[world.curjob->curloop].elmidx - 1, curptr = destvalue; 
       curptr && *curptr; 
       curptr = foundptr + 2, curidx++, dstnbr++)
    {
      foundptr = strstr(curptr, "::");
      if (!foundptr && dstnbr == 1)
	break;
      if (foundptr)
	*foundptr = 0x00;
      type   = revm_exprtype_get(curptr);
      snprintf(namebuf, BUFSIZ, "%s-%u", world.curjob->iter[world.curjob->curloop].curkey, curidx); 
      rname = strdup(namebuf);
      candid = revm_expr_create(type, rname, curptr);
      if (!candid || !candid->annot)
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Invalid target type(s) for transformation", -1);
      candid->annot->inhash = 1;
      elist_append(exprlist, rname, candid);
      if (!foundptr)
	break;
    }

  /* XXX: Case where the rewritten element is not part of an iterated list -- unsupported */
  looplist = (list_t *) world.curjob->iter[world.curjob->curloop].container;
  if (!looplist)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Rewriting of non-list element unimplemented", -1);
  else if (looplist->type != ASPECT_TYPE_EXPR)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Rewrite of non-expression variables unimplemented", -1);
  
  /* Simply replace the current list element now */
  /* The type of the list (list_t->type) does not change : it still is a list of revmexpr_t */

  /* Just one element to swap */
  else if (dstnbr == 1)
    {

      /* No transformation, keep the original expression */
      if (!strcmp(destvalue, "."))
	candid = matchme;
      else
	{

	  /* Case where we did not have a simple value here but a real expression */
	  rname = revm_tmpvar_create();	  
	  type   = revm_exprtype_get(destvalue);
	  candid = revm_expr_create(type, rname, destvalue);
	  if (!candid || !candid->annot)
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
			 "Malformed destination type", -1);
	  candid->annot->inhash = 1;

	  /** 
	   **
	   ** XXX: Disabled -- do not remove -- to enable when SSA transform is ready
	   ** if (revm_links_propagate(candid, matchme) < 0)
	   ** PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
	   ** "Error while propagating dataflow links", -1);
	   **
	   ** XXX: Also address the propagate for the case where dstnbr != 1
	   */

	  ret = elist_set(looplist, world.curjob->iter[world.curjob->curloop].curkey, candid);
	  if (ret < 0)
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
			 "Failed to store transformed expr in input list", -1);

	  /* 
	  ** We reuse the same key for transform list, so that any change in transform list
	  ** can be recorded back to the element of the original list. We also refresh the
	  ** induction variable of current loop context.
	  **
	  ** XXX: we should probably update context hashes too
	  */
	  elist_append(exprlist, strdup(world.curjob->iter[world.curjob->curloop].curkey), candid);
	  char *name = world.curjob->iter[world.curjob->curloop].curind->label;
	  world.curjob->iter[world.curjob->curloop].curind = candid;
	  world.curjob->iter[world.curjob->curloop].curind->label = name;
	}
    }

  /* Insert a list at a certain offset of the list and remove matched element */
  else
    {
      elist_replace(looplist, world.curjob->iter[world.curjob->curloop].curkey, 
		    elist_copy(exprlist, ELIST_DATA_NOCOPY));
      world.curjob->iter[world.curjob->curloop].elmidx += exprlist->elmnbr - 1;
    }

  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}
Пример #3
0
/* Declare a new typed variable */ 
int		cmd_declare()
{
  aspectype_t	*type;
  char		*varname;
  char		buf[BUFSIZ];
  u_int		curlen;
  u_int		curidx;
  u_int		curpidx;
  u_int		openbrace;
  u_int		closebrace;

  PROFILER_IN(__FILE__, __FUNCTION__, __LINE__);

  /* Preliminary checks */
  if (world.curjob->curcmd->argc < 3 ||
      strcmp(world.curjob->curcmd->param[1], "="))
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Invalid syntax for command", -1);

  /* Preliminary checks */
  type = aspect_type_get_by_name(world.curjob->curcmd->name);
  if (!type)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Unknown type for new variable", -1);

  /* Create the new data structure */
  bzero(buf, BUFSIZ);

  /* Create a unique string for the value of the object */
  for (openbrace = closebrace = curlen = 0, curidx = 2; 
       world.curjob->curcmd->param[curidx]; 
       curidx++, curlen += curpidx)
    for (curpidx = 0; world.curjob->curcmd->param[curidx][curpidx]; 
	 curpidx++)
      switch (world.curjob->curcmd->param[curidx][curpidx])
	{
	case '(':
	  *(buf + curlen + curpidx) = '(';
	  openbrace++;
	  break;
	case ')':
	  *(buf + curlen + curpidx) = ')';
	  closebrace++;
	  if (closebrace > openbrace)
	    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
			 "Invalid closing structure for variable", -1);
	  break;
	case ' ':
	  *(buf + curlen + curpidx) = ',';
	  break;
	default:
	  *(buf + curlen + curpidx) = world.curjob->curcmd->param[curidx][curpidx];
	  break;
	}

  /* Some first checks on the value */
  if (closebrace != openbrace)
    PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		 "Invalid nesting structure for variable", -1);

#if __DEBUG_EXPRS__
  fprintf(stderr, "Expression to write in variable: %s \n", buf);
#endif

  curlen = strlen(world.curjob->curcmd->param[0]);
  varname = alloca(curlen + 2);
  snprintf(varname, curlen + 2, "$%s", world.curjob->curcmd->param[0]);

  /* Perform the real operation now */
  if (type->childs)
    {
      if (!revm_expr_create(type, varname, buf))
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Invalid value for variable", -1);
    }
  else
    {
      if (!revm_simple_expr_create(type, varname, buf))
	PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__,
		     "Invalid value for variable", -1);
    }

  /* Print success */
  if (!world.state.revm_quiet)
    {
      snprintf(buf, sizeof(buf), 
	       " [*] Variable %s succesfully initialized \n\n", 
	       world.curjob->curcmd->param[0]);
      revm_output(buf);
    }
  
  PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0);
}