/* GDB CLI command scripting.
- Copyright 1986-2000 Free Software Foundation, Inc.
+
+ Copyright (c) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "value.h"
#include "language.h" /* For value_true */
#include <ctype.h>
-#ifdef UI_OUT
#include "ui-out.h"
-#endif
-
+#include "gdb_string.h"
+#include "exceptions.h"
#include "top.h"
+#include "breakpoint.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-script.h"
-
-/* From gdb/top.c */
-
-extern void dont_repeat (void);
-
-extern void do_restore_instream_cleanup (void *stream);
+#include "gdb_assert.h"
/* Prototypes for local functions */
-static struct cleanup *
- make_cleanup_free_command_lines (struct command_line **arg);
-
static enum command_control_type
recurse_read_control_structure (struct command_line *current_cmd);
static void validate_comname (char *);
-/* Level of control structure. */
+/* Level of control structure when reading. */
static int control_level;
-/* Source command state variable. */
-static int source_error_allocated;
+/* Level of control structure when executing. */
+static int command_nest_depth = 1;
+
+/* This is to prevent certain commands being printed twice. */
+static int suppress_next_print_command_trace = 0;
/* Structure for arguments to user defined functions. */
#define MAXUSERARGS 10
struct user_args
{
struct user_args *next;
+ /* It is necessary to store a malloced copy of the command line to
+ ensure that the arguments are not overwritten before they are used. */
+ char *command;
struct
{
char *arg;
{
struct command_line *cmd;
- if (args == NULL)
- error ("if/while commands require arguments.\n");
+ if (args == NULL && (type == if_control || type == while_control))
+ error (_("if/while commands require arguments."));
+ gdb_assert (args != NULL);
cmd = (struct command_line *) xmalloc (sizeof (struct command_line));
cmd->next = NULL;
* cmd->body_count);
memset (cmd->body_list, 0, sizeof (struct command_line *) * cmd->body_count);
cmd->line = savestring (args, strlen (args));
+
return cmd;
}
/* Read in the body of this command. */
if (recurse_read_control_structure (cmd) == invalid_control)
{
- warning ("error reading in control structure\n");
+ warning (_("Error reading in canned sequence of commands."));
do_cleanups (old_chain);
return NULL;
}
}
/* Recursively print a command (including full control structures). */
-#ifdef UI_OUT
+
void
print_command_lines (struct ui_out *uiout, struct command_line *cmd,
unsigned int depth)
/* A while command. Recursively print its subcommands and continue. */
if (list->control_type == while_control)
{
- ui_out_text (uiout, "while ");
ui_out_field_fmt (uiout, NULL, "while %s", list->line);
ui_out_text (uiout, "\n");
print_command_lines (uiout, *list->body_list, depth + 1);
- ui_out_field_string (uiout, NULL, "end");
if (depth)
ui_out_spaces (uiout, 2 * depth);
- ui_out_text (uiout, "end\n");
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
list = list->next;
continue;
}
/* An if command. Recursively print both arms before continueing. */
if (list->control_type == if_control)
{
- ui_out_text (uiout, "if ");
ui_out_field_fmt (uiout, NULL, "if %s", list->line);
ui_out_text (uiout, "\n");
/* The true arm. */
if (depth)
ui_out_spaces (uiout, 2 * depth);
ui_out_field_string (uiout, NULL, "else");
- ui_out_text (uiout, "else\n");
+ ui_out_text (uiout, "\n");
print_command_lines (uiout, list->body_list[1], depth + 1);
}
+ if (depth)
+ ui_out_spaces (uiout, 2 * depth);
ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
+ list = list->next;
+ continue;
+ }
+
+ /* A commands command. Print the breakpoint commands and continue. */
+ if (list->control_type == commands_control)
+ {
+ if (*(list->line))
+ ui_out_field_fmt (uiout, NULL, "commands %s", list->line);
+ else
+ ui_out_field_string (uiout, NULL, "commands");
+ ui_out_text (uiout, "\n");
+ print_command_lines (uiout, *list->body_list, depth + 1);
if (depth)
ui_out_spaces (uiout, 2 * depth);
- ui_out_text (uiout, "end\n");
+ ui_out_field_string (uiout, NULL, "end");
+ ui_out_text (uiout, "\n");
list = list->next;
continue;
}
list = list->next;
} /* while (list) */
}
-#else
-void
-print_command_line (struct command_line *cmd, unsigned int depth,
- struct ui_file *stream)
-{
- unsigned int i;
-
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
- /* A simple command, print it and return. */
- if (cmd->control_type == simple_control)
- {
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- return;
- }
+/* Handle pre-post hooks. */
- /* loop_continue to jump to the start of a while loop, print it
- and return. */
- if (cmd->control_type == continue_control)
- {
- fputs_filtered ("loop_continue\n", stream);
- return;
- }
+static void
+clear_hook_in_cleanup (void *data)
+{
+ struct cmd_list_element *c = data;
+ c->hook_in = 0; /* Allow hook to work again once it is complete */
+}
- /* loop_break to break out of a while loop, print it and return. */
- if (cmd->control_type == break_control)
+void
+execute_cmd_pre_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_pre) && (!c->hook_in))
{
- fputs_filtered ("loop_break\n", stream);
- return;
- }
-
- /* A while command. Recursively print its subcommands before returning. */
- if (cmd->control_type == while_control)
- {
- struct command_line *list;
- fputs_filtered ("while ", stream);
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- list = *cmd->body_list;
- while (list)
- {
- print_command_line (list, depth + 1, stream);
- list = list->next;
- }
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_pre, (char *) 0);
+ do_cleanups (cleanups);
}
+}
- /* An if command. Recursively print both arms before returning. */
- if (cmd->control_type == if_control)
+void
+execute_cmd_post_hook (struct cmd_list_element *c)
+{
+ if ((c->hook_post) && (!c->hook_in))
{
- fputs_filtered ("if ", stream);
- fputs_filtered (cmd->line, stream);
- fputs_filtered ("\n", stream);
- /* The true arm. */
- print_command_line (cmd->body_list[0], depth + 1, stream);
-
- /* Show the false arm if it exists. */
- if (cmd->body_count == 2)
- {
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
- fputs_filtered ("else\n", stream);
- print_command_line (cmd->body_list[1], depth + 1, stream);
- }
- if (depth)
- {
- for (i = 0; i < depth; i++)
- fputs_filtered (" ", stream);
- }
- fputs_filtered ("end\n", stream);
+ struct cleanup *cleanups = make_cleanup (clear_hook_in_cleanup, c);
+ c->hook_in = 1; /* Prevent recursive hooking */
+ execute_user_command (c->hook_post, (char *) 0);
+ do_cleanups (cleanups);
}
}
-#endif
/* Execute the command in CMD. */
+static void
+do_restore_user_call_depth (void * call_depth)
+{
+ int * depth = call_depth;
+ (*depth)--;
+ if ((*depth) == 0)
+ in_user_command = 0;
+}
+
void
execute_user_command (struct cmd_list_element *c, char *args)
{
- register struct command_line *cmdlines;
+ 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;
old_chain = setup_user_args (args);
/* Null command */
return;
+ 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. */
- old_chain = make_cleanup (do_restore_instream_cleanup, instream);
+ 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;
+
+ command_nest_depth++;
while (cmdlines)
{
ret = execute_control_command (cmdlines);
if (ret != simple_control && ret != break_control)
{
- warning ("Error in control structure.\n");
+ warning (_("Error executing canned sequence of commands."));
break;
}
cmdlines = cmdlines->next;
}
+ command_nest_depth--;
do_cleanups (old_chain);
}
+/* This function is called every time GDB prints a prompt.
+ It ensures that errors and the like to not confuse the command tracing. */
+
+void
+reset_command_nest_depth (void)
+{
+ command_nest_depth = 1;
+
+ /* Just in case. */
+ suppress_next_print_command_trace = 0;
+}
+
+/* Print the command, prefixed with '+' to represent the call depth.
+ This is slightly complicated because this function may be called
+ from execute_command and execute_control_command. Unfortunately
+ execute_command also prints the top level control commands.
+ In these cases execute_command will call execute_control_command
+ via while_command or if_command. Inner levels of 'if' and 'while'
+ are dealt with directly. Therefore we can use these functions
+ to determine whether the command has been printed already or not. */
+void
+print_command_trace (const char *cmd)
+{
+ int i;
+
+ if (suppress_next_print_command_trace)
+ {
+ suppress_next_print_command_trace = 0;
+ return;
+ }
+
+ if (!source_verbose && !trace_commands)
+ return;
+
+ for (i=0; i < command_nest_depth; i++)
+ printf_filtered ("+");
+
+ printf_filtered ("%s\n", cmd);
+}
+
enum command_control_type
execute_control_command (struct command_line *cmd)
{
struct expression *expr;
struct command_line *current;
- struct cleanup *old_chain = 0;
- value_ptr val;
- value_ptr val_mark;
+ 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)
- return invalid_control;
- old_chain = make_cleanup (free_current_contents, &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;
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)
- return invalid_control;
- old_chain = make_cleanup (free_current_contents, &new_line);
+ break;
+ make_cleanup (free_current_contents, &new_line);
expr = parse_expression (new_line);
make_cleanup (free_current_contents, &expr);
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. */
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)
- return invalid_control;
- old_chain = make_cleanup (free_current_contents, &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);
/* 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;
}
+ 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;
+ }
default:
- warning ("Invalid control type in command structure.");
- return invalid_control;
+ warning (_("Invalid control type in canned commands structure."));
+ break;
}
- if (old_chain)
- do_cleanups (old_chain);
+ do_cleanups (old_chain);
return ret;
}
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
if (command == NULL)
return;
+ suppress_next_print_command_trace = 1;
execute_control_command (command);
free_command_lines (&command);
}
{
struct user_args *oargs = user_args;
if (!user_args)
- internal_error ("Internal error, arg_cleanup called with no user args.\n");
+ internal_error (__FILE__, __LINE__,
+ _("arg_cleanup called with no user args.\n"));
user_args = user_args->next;
- free (oargs);
+ xfree (oargs->command);
+ xfree (oargs);
}
/* Bind the incomming arguments for a user defined command to
if (p == NULL)
return old_chain;
+ user_args->command = p = xstrdup (p);
+
while (*p)
{
char *start_arg;
if (arg_count >= MAXUSERARGS)
{
- error ("user defined function may only have %d arguments.\n",
+ error (_("user defined function may only have %d arguments."),
MAXUSERARGS);
return old_chain;
}
{
while ((p = strchr (p, '$')))
{
- if (strncmp (p, "$arg", 4) == 0 && isdigit (p[4]))
+ if (strncmp (p, "$arg", 4) == 0
+ && (isdigit (p[4]) || p[4] == 'c'))
return p;
p++;
}
char *p, *save_line, *new_line;
unsigned len, i;
+ /* If we are not in a user-defined function, 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;
len += p - line;
i = p[4] - '0';
- if (i >= user_args->count)
+ if (p[4] == 'c')
{
- error ("Missing argument %d in user function.\n", i);
+ /* $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;
}
- len += user_args->a[i].len;
+ else
+ {
+ len += user_args->a[i].len;
+ }
line = p + 5;
}
memcpy (new_line, line, p - line);
new_line += p - line;
- i = p[4] - '0';
- len = user_args->a[i].len;
- if (len)
+ 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';
+ }
+ else
+ *(new_line++) = user_args->count + '0';
+ }
+ else
{
- memcpy (new_line, user_args->a[i].arg, len);
- new_line += len;
+ i = p[4] - '0';
+ len = user_args->a[i].len;
+ if (len)
+ {
+ memcpy (new_line, user_args->a[i].arg, len);
+ new_line += len;
+ }
}
line = p + 5;
}
xmalloc (sizeof (struct command_line *) * new_length);
memcpy (body_list, command->body_list, sizeof (struct command_line *) * n);
+ memset (body_list + n, 0, sizeof (struct command_line *) * (new_length - n));
- free (command->body_list);
+ xfree (command->body_list);
command->body_list = body_list;
command->body_count = new_length;
}
int i = 0;
if (control_level >= 254)
- error ("Control nesting too deep!\n");
+ error (_("Control nesting too deep!"));
/* Set a prompt based on the nesting of the control commands. */
- if (instream == stdin || (instream == 0 && readline_hook != NULL))
+ if (instream == stdin || (instream == 0 && deprecated_readline_hook != NULL))
{
for (i = 0; i < control_level; i++)
control_prompt[i] = ' ';
/* Check for while, if, break, continue, etc and build a new command
line structure for them. */
if (p1 - p > 5 && !strncmp (p, "while", 5))
- *command = build_command_line (while_control, p + 6);
+ {
+ char *first_arg;
+ first_arg = p + 5;
+ while (first_arg < p1 && isspace (*first_arg))
+ first_arg++;
+ *command = build_command_line (while_control, first_arg);
+ }
else if (p1 - p > 2 && !strncmp (p, "if", 2))
- *command = build_command_line (if_control, p + 3);
+ {
+ char *first_arg;
+ first_arg = p + 2;
+ while (first_arg < p1 && isspace (*first_arg))
+ first_arg++;
+ *command = build_command_line (if_control, first_arg);
+ }
+ else if (p1 - p >= 8 && !strncmp (p, "commands", 8))
+ {
+ char *first_arg;
+ first_arg = p + 8;
+ while (first_arg < p1 && isspace (*first_arg))
+ first_arg++;
+ *command = build_command_line (commands_control, first_arg);
+ }
else if (p1 - p == 10 && !strncmp (p, "loop_break", 10))
{
*command = (struct command_line *)
/* Sanity checks. */
if (current_cmd->control_type == simple_control)
- {
- error ("Recursed on a simple control type\n");
- return invalid_control;
- }
+ error (_("Recursed on a simple control type."));
if (current_body > current_cmd->body_count)
- {
- error ("Allocated body is smaller than this command type needs\n");
- return invalid_control;
- }
+ error (_("Allocated body is smaller than this command type needs."));
/* Read lines from the input stream and build control structures. */
while (1)
if (val == end_command)
{
if (current_cmd->control_type == while_control
- || current_cmd->control_type == if_control)
+ || current_cmd->control_type == if_control
+ || current_cmd->control_type == commands_control)
{
- /* Success reading an entire control structure. */
+ /* Success reading an entire canned sequence of commands. */
ret = simple_control;
break;
}
/* If the latest line is another control structure, then recurse
on it. */
if (next->control_type == while_control
- || next->control_type == if_control)
+ || next->control_type == if_control
+ || next->control_type == commands_control)
{
control_level++;
ret = recurse_read_control_structure (next);
enum misc_command_type val;
control_level = 0;
- if (readline_begin_hook)
- {
- /* Note - intentional to merge messages with no newline */
- (*readline_begin_hook) ("%s %s\n", prompt_arg, END_MESSAGE);
- }
- else if (from_tty && input_from_terminal_p ())
+
+ if (from_tty && input_from_terminal_p ())
{
- printf_unfiltered ("%s\n%s\n", prompt_arg, END_MESSAGE);
- gdb_flush (gdb_stdout);
+ if (deprecated_readline_begin_hook)
+ {
+ /* Note - intentional to merge messages with no newline */
+ (*deprecated_readline_begin_hook) ("%s %s\n", prompt_arg, END_MESSAGE);
+ }
+ else
+ {
+ printf_unfiltered ("%s\n%s\n", prompt_arg, END_MESSAGE);
+ gdb_flush (gdb_stdout);
+ }
}
head = tail = NULL;
while (1)
{
+ dont_repeat ();
val = read_next_line (&next);
/* Ignore blank lines or comments. */
}
if (next->control_type == while_control
- || next->control_type == if_control)
+ || next->control_type == if_control
+ || next->control_type == commands_control)
{
control_level++;
ret = recurse_read_control_structure (next);
do_cleanups (old_chain);
}
- if (readline_end_hook)
+ if (deprecated_readline_end_hook && from_tty && input_from_terminal_p ())
{
- (*readline_end_hook) ();
+ (*deprecated_readline_end_hook) ();
}
return (head);
}
void
free_command_lines (struct command_line **lptr)
{
- register struct command_line *l = *lptr;
- register struct command_line *next;
+ struct command_line *l = *lptr;
+ struct command_line *next;
struct command_line **blist;
int i;
free_command_lines (blist);
}
next = l->next;
- free (l->line);
- free ((PTR) l);
+ xfree (l->line);
+ xfree (l);
l = next;
}
+ *lptr = NULL;
}
static void
free_command_lines (arg);
}
-static struct cleanup *
+struct cleanup *
make_cleanup_free_command_lines (struct command_line **arg)
{
return make_cleanup (do_free_command_lines_cleanup, arg);
}
+
+struct command_line *
+copy_command_lines (struct command_line *cmds)
+{
+ struct command_line *result = NULL;
+
+ if (cmds)
+ {
+ result = (struct command_line *) xmalloc (sizeof (struct command_line));
+
+ result->next = copy_command_lines (cmds->next);
+ result->line = xstrdup (cmds->line);
+ result->control_type = cmds->control_type;
+ result->body_count = cmds->body_count;
+ if (cmds->body_count > 0)
+ {
+ int i;
+
+ result->body_list = (struct command_line **)
+ xmalloc (sizeof (struct command_line *) * cmds->body_count);
+
+ for (i = 0; i < cmds->body_count; i++)
+ result->body_list[i] = copy_command_lines (cmds->body_list[i]);
+ }
+ else
+ result->body_list = NULL;
+ }
+
+ return result;
+}
\f
static void
validate_comname (char *comname)
{
- register char *p;
+ char *p;
if (comname == 0)
- error_no_arg ("name of command to define");
+ error_no_arg (_("name of command to define"));
p = comname;
while (*p)
{
if (!isalnum (*p) && *p != '-' && *p != '_')
- error ("Junk in argument list: \"%s\"", p);
+ error (_("Junk in argument list: \"%s\""), p);
p++;
}
}
CMD_PRE_HOOK,
CMD_POST_HOOK
};
- register struct command_line *cmds;
- register struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
+ struct command_line *cmds;
+ struct cmd_list_element *c, *newc, *oldc, *hookc = 0;
char *tem = comname;
char *tem2;
char tmpbuf[MAX_TMPBUF];
/* Look it up, and verify that we got an exact match. */
c = lookup_cmd (&tem, cmdlist, "", -1, 1);
- if (c && !STREQ (comname, c->name))
+ if (c && strcmp (comname, c->name) != 0)
c = 0;
if (c)
{
+ int q;
if (c->class == class_user || c->class == class_alias)
- tem = "Redefine command \"%s\"? ";
+ q = query (_("Redefine command \"%s\"? "), c->name);
else
- tem = "Really redefine built-in command \"%s\"? ";
- if (!query (tem, c->name))
- error ("Command \"%s\" not redefined.", c->name);
+ q = query (_("Really redefine built-in command \"%s\"? "), c->name);
+ if (!q)
+ error (_("Command \"%s\" not redefined."), c->name);
}
/* If this new command is a hook, then mark the command which it
/* Look up cmd it hooks, and verify that we got an exact match. */
tem = comname + hook_name_size;
hookc = lookup_cmd (&tem, cmdlist, "", -1, 0);
- if (hookc && !STREQ (comname + hook_name_size, hookc->name))
+ if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0)
hookc = 0;
if (!hookc)
{
- warning ("Your new `%s' command does not hook any existing command.",
+ warning (_("Your new `%s' command does not hook any existing command."),
comname);
if (!query ("Proceed? "))
- error ("Not confirmed.");
+ error (_("Not confirmed."));
}
}
newc->hookee_pre = hookc; /* We are marked as hooking target cmd. */
break;
case CMD_POST_HOOK:
- hookc->hook_pre = newc; /* Target gets hooked. */
- newc->hookee_pre = hookc; /* We are marked as hooking target cmd. */
+ hookc->hook_post = newc; /* Target gets hooked. */
+ newc->hookee_post = hookc; /* We are marked as hooking target cmd. */
break;
default:
/* Should never come here as hookc would be 0. */
+ internal_error (__FILE__, __LINE__, _("bad switch"));
}
}
}
document_command (char *comname, int from_tty)
{
struct command_line *doclines;
- register struct cmd_list_element *c;
+ struct cmd_list_element *c;
char *tem = comname;
char tmpbuf[128];
c = lookup_cmd (&tem, cmdlist, "", 0, 1);
if (c->class != class_user)
- error ("Command \"%s\" is built-in.", comname);
+ error (_("Command \"%s\" is built-in."), comname);
sprintf (tmpbuf, "Type documentation for \"%s\".", comname);
doclines = read_command_lines (tmpbuf, from_tty);
if (c->doc)
- free (c->doc);
+ xfree (c->doc);
{
- register struct command_line *cl1;
- register int len = 0;
+ struct command_line *cl1;
+ int len = 0;
for (cl1 = doclines; cl1; cl1 = cl1->next)
len += strlen (cl1->line) + 1;
{
int old_line;
char *old_file;
- char *old_pre_error;
- char *old_error_pre_print;
};
static void
-source_cleanup_lines (PTR args)
+source_cleanup_lines (void *args)
{
struct source_cleanup_lines_args *p =
(struct source_cleanup_lines_args *) args;
source_line_number = p->old_line;
source_file_name = p->old_file;
- source_pre_error = p->old_pre_error;
- error_pre_print = p->old_error_pre_print;
}
-/* ARGSUSED */
static void
do_fclose_cleanup (void *stream)
{
fclose (stream);
}
+struct wrapped_read_command_file_args
+{
+ FILE *stream;
+};
+
+static void
+wrapped_read_command_file (struct ui_out *uiout, void *data)
+{
+ struct wrapped_read_command_file_args *args = data;
+ read_command_file (args->stream);
+}
+
/* Used to implement source_command */
void
int needed_length;
if (stream == NULL)
- {
- internal_error ("called with NULL file pointer!");
- }
+ internal_error (__FILE__, __LINE__, _("called with NULL file pointer!"));
old_cleanups = make_cleanup (do_fclose_cleanup, stream);
old_lines.old_line = source_line_number;
old_lines.old_file = source_file_name;
- old_lines.old_pre_error = source_pre_error;
- old_lines.old_error_pre_print = error_pre_print;
make_cleanup (source_cleanup_lines, &old_lines);
source_line_number = 0;
source_file_name = file;
- source_pre_error = error_pre_print == NULL ? "" : error_pre_print;
- source_pre_error = savestring (source_pre_error, strlen (source_pre_error));
- make_cleanup (free, source_pre_error);
/* This will get set every time we read a line. So it won't stay "" for
long. */
error_pre_print = "";
- needed_length = strlen (source_file_name) + strlen (source_pre_error) + 80;
- if (source_error_allocated < needed_length)
- {
- source_error_allocated *= 2;
- if (source_error_allocated < needed_length)
- source_error_allocated = needed_length;
- if (source_error == NULL)
- source_error = xmalloc (source_error_allocated);
- else
- source_error = xrealloc (source_error, source_error_allocated);
- }
-
- read_command_file (stream);
+ {
+ struct gdb_exception e;
+ struct wrapped_read_command_file_args args;
+ args.stream = stream;
+ e = catch_exception (uiout, wrapped_read_command_file, &args,
+ RETURN_MASK_ERROR);
+ switch (e.reason)
+ {
+ case 0:
+ break;
+ case RETURN_ERROR:
+ /* Re-throw the error, but with the file name information
+ prepended. */
+ throw_error (e.error,
+ _("%s:%d: Error in sourced command file:\n%s"),
+ source_file_name, source_line_number, e.message);
+ default:
+ internal_error (__FILE__, __LINE__, _("bad reason"));
+ }
+ }
do_cleanups (old_cleanups);
}
void
show_user_1 (struct cmd_list_element *c, struct ui_file *stream)
{
- register struct command_line *cmdlines;
+ struct command_line *cmdlines;
cmdlines = c->user_commands;
if (!cmdlines)
fputs_filtered (c->name, stream);
fputs_filtered (":\n", stream);
-#ifdef UI_OUT
print_command_lines (uiout, cmdlines, 1);
fputs_filtered ("\n", stream);
-#else
- while (cmdlines)
- {
- print_command_line (cmdlines, 4, stream);
- cmdlines = cmdlines->next;
- }
- fputs_filtered ("\n", stream);
-#endif
}