Beispiel #1
0
enum command_control_type
execute_control_command (struct command_line *cmd)
{
  struct expression *expr;
  struct command_line *current;
  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
  struct value *val;
  struct value *val_mark;
  int loop;
  enum command_control_type ret;
  char *new_line;

  /* Start by assuming failure, if a problem is detected, the code
     below will simply "break" out of the switch.  */
  ret = invalid_control;

  switch (cmd->control_type)
    {
    case simple_control:
      /* A simple command, execute it and return.  */
      new_line = insert_args (cmd->line);
      if (!new_line)
	break;
      make_cleanup (free_current_contents, &new_line);
      execute_command (new_line, 0);
      ret = cmd->control_type;
      break;

    case continue_control:
      print_command_trace ("loop_continue");

      /* Return for "continue", and "break" so we can either
         continue the loop at the top, or break out.  */
      ret = cmd->control_type;
      break;

    case break_control:
      print_command_trace ("loop_break");

      /* Return for "continue", and "break" so we can either
         continue the loop at the top, or break out.  */
      ret = cmd->control_type;
      break;

    case while_control:
      {
	char *buffer = alloca (strlen (cmd->line) + 7);

	sprintf (buffer, "while %s", cmd->line);
	print_command_trace (buffer);

	/* Parse the loop control expression for the while statement.  */
	new_line = insert_args (cmd->line);
	if (!new_line)
	  break;
	make_cleanup (free_current_contents, &new_line);
	expr = parse_expression (new_line);
	make_cleanup (free_current_contents, &expr);

	ret = simple_control;
	loop = 1;

	/* Keep iterating so long as the expression is true.  */
	while (loop == 1)
	  {
	    int cond_result;

	    QUIT;

	    /* Evaluate the expression.  */
	    val_mark = value_mark ();
	    val = evaluate_expression (expr);
	    cond_result = value_true (val);
	    value_free_to_mark (val_mark);

	    /* If the value is false, then break out of the loop.  */
	    if (!cond_result)
	      break;

	    /* Execute the body of the while statement.  */
	    current = *cmd->body_list;
	    while (current)
	      {
		command_nest_depth++;
		ret = execute_control_command (current);
		command_nest_depth--;

		/* If we got an error, or a "break" command, then stop
		   looping.  */
		if (ret == invalid_control || ret == break_control)
		  {
		    loop = 0;
		    break;
		  }

		/* If we got a "continue" command, then restart the loop
		   at this point.  */
		if (ret == continue_control)
		  break;

		/* Get the next statement.  */
		current = current->next;
	      }
	  }

	/* Reset RET so that we don't recurse the break all the way down.  */
	if (ret == break_control)
	  ret = simple_control;

	break;
      }

    case if_control:
      {
	char *buffer = alloca (strlen (cmd->line) + 4);

	sprintf (buffer, "if %s", cmd->line);
	print_command_trace (buffer);

	new_line = insert_args (cmd->line);
	if (!new_line)
	  break;
	make_cleanup (free_current_contents, &new_line);
	/* Parse the conditional for the if statement.  */
	expr = parse_expression (new_line);
	make_cleanup (free_current_contents, &expr);

	current = NULL;
	ret = simple_control;

	/* Evaluate the conditional.  */
	val_mark = value_mark ();
	val = evaluate_expression (expr);

	/* Choose which arm to take commands from based on the value
	   of the conditional expression.  */
	if (value_true (val))
	  current = *cmd->body_list;
	else if (cmd->body_count == 2)
	  current = *(cmd->body_list + 1);
	value_free_to_mark (val_mark);

	/* Execute commands in the given arm.  */
	while (current)
	  {
	    command_nest_depth++;
	    ret = execute_control_command (current);
	    command_nest_depth--;

	    /* If we got an error, get out.  */
	    if (ret != simple_control)
	      break;

	    /* Get the next statement in the body.  */
	    current = current->next;
	  }

	break;
      }
    case commands_control:
      {
	/* Breakpoint commands list, record the commands in the
	   breakpoint's command list and return.  */
	new_line = insert_args (cmd->line);
	if (!new_line)
	  break;
	make_cleanup (free_current_contents, &new_line);
	ret = commands_from_control_command (new_line, cmd);
	break;
      }
    case python_control:
      {
	eval_python_from_control_command (cmd);
	ret = simple_control;
	break;
      }

    default:
      warning (_("Invalid control type in canned commands structure."));
      break;
    }

  do_cleanups (old_chain);

  return ret;
}
Beispiel #2
0
int perform_call_on_node (node *proc, node *arglist,
			  library *lib, exec_env *env)
{
	int res;
	block *last_block = env->block_stack;
	block *b = malloc(sizeof(block));

	if(!b) {

		env->error.code = ERROR_BAD_ALLOC;
		env->error.static_msg = "couldn't allocate block for proc call.";
		E_SET_ERROR(*env);
		return -1;
	}

	memset(b, 0, sizeof(*b));
	b->label = proc->sym;
	b->body_node = proc->right;
	b->stmt = proc->right->left;
	b->next = env->block_stack;
	env->block_stack = b;
	env->skip_advance = 1;

	if(arglist) {
		b->values = create_symbol_map();
		if(!b->values) {
			pop_block(env);
			env->error.code = ERROR_BAD_ALLOC;
			env->error.static_msg = "couldn't create value table "
				                "for new block in proc call";
			FIAL_set_error(env);
			return -1;
		}
		if((res = insert_args(proc->left, arglist,
				      b->values, last_block, env)) < 0) {
			pop_block(env);
			switch(res) {
			case -1:
				env->error.code = ERROR_BAD_ALLOC;
				env->error.static_msg = "bad alloc setting "
					"arguments";
				FIAL_set_error(env);
				return -1;
			case -2:
				assert(res == -2);
				env->error.code = ERROR_UNDECLARED_VAR;
				env->error.static_msg = "undeclared variable "
							"in arglist";
				FIAL_set_error(env);
				return -1;
			case -5:
				env->error.code = ERROR_UNDECLARED_VAR;
				env->error.static_msg = 
				"Map access error when generating arglist";
				FIAL_set_error(env);
				return -1;
			default:
				assert(res == -3 || res == -4);
				return -1;
			}
		}
	}
	if(lib) {
		b->last_lib = env->lib;
		env->lib = lib;
	}
	return 0;
}