void execute_user_command (struct cmd_list_element *c, char *args) { struct command_line *cmdlines; struct cleanup *old_chain; enum command_control_type ret; static int user_call_depth = 0; extern int max_user_call_depth; cmdlines = c->user_commands; if (cmdlines == 0) /* Null command */ return; old_chain = setup_user_args (args); if (++user_call_depth > max_user_call_depth) error (_("Max user call depth exceeded -- command aborted.")); make_cleanup (do_restore_user_call_depth, &user_call_depth); /* Set the instream to 0, indicating execution of a user-defined function. */ make_cleanup (do_restore_instream_cleanup, instream); instream = (FILE *) 0; /* Also set the global in_user_command, so that NULL instream is not confused with Insight. */ in_user_command = 1; make_cleanup_restore_integer (&interpreter_async); interpreter_async = 0; command_nest_depth++; while (cmdlines) { ret = execute_control_command (cmdlines); if (ret != simple_control && ret != break_control) { warning (_("Error executing canned sequence of commands.")); break; } cmdlines = cmdlines->next; } command_nest_depth--; do_cleanups (old_chain); }
void execute_user_command (struct cmd_list_element *c, const char *args) { struct ui *ui = current_ui; struct command_line *cmdlines; enum command_control_type ret; extern unsigned int max_user_call_depth; cmdlines = c->user_commands; if (cmdlines == 0) /* Null command */ return; scoped_user_args_level push_user_args (args); if (user_args_stack.size () > max_user_call_depth) error (_("Max user call depth exceeded -- command aborted.")); /* Set the instream to 0, indicating execution of a user-defined function. */ scoped_restore restore_instream = make_scoped_restore (&ui->instream, nullptr); scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); scoped_restore save_nesting = make_scoped_restore (&command_nest_depth, command_nest_depth + 1); while (cmdlines) { ret = execute_control_command (cmdlines); if (ret != simple_control && ret != break_control) { warning (_("Error executing canned sequence of commands.")); break; } cmdlines = cmdlines->next; } }
enum command_control_type execute_control_command_untraced (struct command_line *cmd) { suppress_next_print_command_trace = 1; return execute_control_command (cmd); }
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; }