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; }
static enum command_control_type execute_control_command_1 (struct command_line *cmd) { struct command_line *current; struct value *val; struct value *val_mark; int loop; enum command_control_type ret; /* 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. */ std::string new_line = insert_user_defined_cmd_args (cmd->line); execute_command (new_line.c_str (), 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: { int len = strlen (cmd->line) + 7; char *buffer = (char *) alloca (len); xsnprintf (buffer, len, "while %s", cmd->line); print_command_trace (buffer); /* Parse the loop control expression for the while statement. */ std::string new_line = insert_user_defined_cmd_args (cmd->line); expression_up expr = parse_expression (new_line.c_str ()); 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.get ()); 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) { scoped_restore save_nesting = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); ret = execute_control_command_1 (current); /* 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: { int len = strlen (cmd->line) + 4; char *buffer = (char *) alloca (len); xsnprintf (buffer, len, "if %s", cmd->line); print_command_trace (buffer); /* Parse the conditional for the if statement. */ std::string new_line = insert_user_defined_cmd_args (cmd->line); expression_up expr = parse_expression (new_line.c_str ()); current = NULL; ret = simple_control; /* Evaluate the conditional. */ val_mark = value_mark (); val = evaluate_expression (expr.get ()); /* 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) { scoped_restore save_nesting = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); ret = execute_control_command_1 (current); /* 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. */ std::string new_line = insert_user_defined_cmd_args (cmd->line); ret = commands_from_control_command (new_line.c_str (), cmd); break; } case compile_control: eval_compile_command (cmd, NULL, cmd->control_u.compile.scope, cmd->control_u.compile.scope_data); ret = simple_control; break; case python_control: case guile_control: { eval_ext_lang_from_control_command (cmd); ret = simple_control; break; } default: warning (_("Invalid control type in canned commands structure.")); break; } return ret; }