/* GDB CLI command scripting.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2016 Free Software Foundation, Inc.
This file is part of GDB.
void (*validator)(char *, void *),
void *closure);
-static char *insert_args (char *line);
-
static struct cleanup * setup_user_args (char *p);
static char *read_next_line (void);
static void
clear_hook_in_cleanup (void *data)
{
- struct cmd_list_element *c = data;
+ struct cmd_list_element *c = (struct cmd_list_element *) data;
c->hook_in = 0; /* Allow hook to work again once it is complete. */
}
static void
do_restore_user_call_depth (void * call_depth)
{
- int *depth = call_depth;
+ int *depth = (int *) call_depth;
(*depth)--;
if ((*depth) == 0)
void
execute_user_command (struct cmd_list_element *c, char *args)
{
+ struct ui *ui = current_ui;
struct command_line *cmdlines;
struct cleanup *old_chain;
enum command_control_type ret;
/* Set the instream to 0, indicating execution of a
user-defined function. */
- make_cleanup (do_restore_instream_cleanup, instream);
- instream = (FILE *) 0;
+ make_cleanup (do_restore_instream_cleanup, ui->instream);
+ ui->instream = NULL;
/* 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;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
command_nest_depth++;
while (cmdlines)
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. */
switch (cmd->control_type)
{
case simple_control:
- /* A simple command, execute it and return. */
- new_line = insert_args (cmd->line);
- if (!new_line)
+ {
+ /* A simple command, execute it and return. */
+ std::string new_line = insert_user_defined_cmd_args (cmd->line);
+ execute_command (&new_line[0], 0);
+ ret = cmd->control_type;
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");
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);
+ 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;
/* Evaluate the expression. */
val_mark = value_mark ();
- val = evaluate_expression (expr);
+ val = evaluate_expression (expr.get ());
cond_result = value_true (val);
value_free_to_mark (val_mark);
xsnprintf (buffer, len, "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);
+ 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);
+ val = evaluate_expression (expr.get ());
/* Choose which arm to take commands from based on the value
of the conditional expression. */
{
/* 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);
+ std::string new_line = insert_user_defined_cmd_args (cmd->line);
+ ret = commands_from_control_command (new_line.c_str (), cmd);
break;
}
break;
}
- do_cleanups (old_chain);
-
return ret;
}
while_command (char *arg, int from_tty)
{
struct command_line *command = NULL;
- struct cleanup *old_chain;
control_level = 1;
command = get_command_line (while_control, arg);
if (command == NULL)
return;
- old_chain = make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
execute_control_command_untraced (command);
free_command_lines (&command);
-
- do_cleanups (old_chain);
}
/* "if" command support. Execute either the true or false arm depending
if (command == NULL)
return;
- old_chain = make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
execute_control_command_untraced (command);
free_command_lines (&command);
-
- do_cleanups (old_chain);
}
/* Cleanup */
/* Given character string P, return a point to the first argument
($arg), or NULL if P contains no arguments. */
-static char *
-locate_arg (char *p)
+static const char *
+locate_arg (const char *p)
{
while ((p = strchr (p, '$')))
{
return NULL;
}
-/* Insert the user defined arguments stored in user_arg into the $arg
- arguments found in line, with the updated copy being placed into
- nline. */
+/* See cli-script.h. */
-static char *
-insert_args (char *line)
+std::string
+insert_user_defined_cmd_args (const char *line)
{
- char *p, *save_line, *new_line;
- unsigned len, i;
-
- /* If we are not in a user-defined function, treat $argc, $arg0, et
+ /* If we are not in a user-defined command, treat $argc, $arg0, et
cetera as normal convenience variables. */
if (user_args == NULL)
- return xstrdup (line);
-
- /* First we need to know how much memory to allocate for the new
- line. */
- save_line = line;
- len = 0;
- while ((p = locate_arg (line)))
- {
- len += p - line;
- i = p[4] - '0';
-
- if (p[4] == 'c')
- {
- /* $argc. Number will be <=10. */
- len += user_args->count == 10 ? 2 : 1;
- }
- else if (i >= user_args->count)
- {
- error (_("Missing argument %d in user function."), i);
- return NULL;
- }
- else
- {
- len += user_args->a[i].len;
- }
- line = p + 5;
- }
-
- /* Don't forget the tail. */
- len += strlen (line);
-
- /* Allocate space for the new line and fill it in. */
- new_line = (char *) xmalloc (len + 1);
- if (new_line == NULL)
- return NULL;
+ return line;
- /* Restore pointer to beginning of old line. */
- line = save_line;
-
- /* Save pointer to beginning of new line. */
- save_line = new_line;
+ std::string new_line;
+ const char *p;
while ((p = locate_arg (line)))
{
int i, len;
- memcpy (new_line, line, p - line);
- new_line += p - line;
+ new_line.append (line, p - line);
if (p[4] == 'c')
{
gdb_assert (user_args->count >= 0 && user_args->count <= 10);
if (user_args->count == 10)
{
- *(new_line++) = '1';
- *(new_line++) = '0';
+ new_line += '1';
+ new_line += '0';
}
else
- *(new_line++) = user_args->count + '0';
+ new_line += user_args->count + '0';
}
else
{
i = p[4] - '0';
+ if (i >= user_args->count)
+ error (_("Missing argument %d in user function."), i);
+
len = user_args->a[i].len;
- if (len)
- {
- memcpy (new_line, user_args->a[i].arg, len);
- new_line += len;
- }
+ if (len > 0)
+ new_line.append (user_args->a[i].arg, len);
}
line = p + 5;
}
/* Don't forget the tail. */
- strcpy (new_line, line);
+ new_line.append (line);
- /* Return a pointer to the beginning of the new line. */
- return save_line;
+ return new_line;
}
\f
command->body_count = new_length;
}
-/* Read next line from stdout. Passed to read_command_line_1 and
+/* Read next line from stdin. Passed to read_command_line_1 and
recurse_read_control_structure whenever we need to read commands
- from stdout. */
+ from stdin. */
static char *
read_next_line (void)
{
+ struct ui *ui = current_ui;
char *prompt_ptr, control_prompt[256];
int i = 0;
+ int from_tty = ui->instream == ui->stdin_stream;
if (control_level >= 254)
error (_("Control nesting too deep!"));
/* Set a prompt based on the nesting of the control commands. */
- if (instream == stdin || (instream == 0 && deprecated_readline_hook != NULL))
+ if (from_tty
+ || (ui->instream == 0 && deprecated_readline_hook != NULL))
{
for (i = 0; i < control_level; i++)
control_prompt[i] = ' ';
else
prompt_ptr = NULL;
- return command_line_input (prompt_ptr, instream == stdin, "commands");
+ return command_line_input (prompt_ptr, from_tty, "commands");
}
/* Process one input line. If the command is an "end", return such an
{
struct command_line *head;
- if (from_tty && input_from_terminal_p ())
+ if (from_tty && input_interactive_p (current_ui))
{
if (deprecated_readline_begin_hook)
{
do_cleanups (old_chain);
}
- if (deprecated_readline_end_hook && from_tty && input_from_terminal_p ())
+ if (from_tty && input_interactive_p (current_ui)
+ && deprecated_readline_end_hook)
{
(*deprecated_readline_end_hook) ();
}
static void
do_free_command_lines_cleanup (void *arg)
{
- free_command_lines (arg);
+ free_command_lines ((struct command_line **) arg);
}
struct cleanup *
source_line_number = 0;
source_file_name = file;
- make_cleanup_restore_integer (&interpreter_async);
- interpreter_async = 0;
-
{
+ scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
TRY
{