Index: gdb/cli/cli-script.c |
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c |
index 4b6c416914584c45af803a6b489502029a37f2e7..387a11ee17a22055a4c5190d19fe10def402ea33 100644 |
--- a/gdb/cli/cli-script.c |
+++ b/gdb/cli/cli-script.c |
@@ -1,6 +1,6 @@ |
/* GDB CLI command scripting. |
- Copyright (c) 1986-2002, 2004-2012 Free Software Foundation, Inc. |
+ Copyright (C) 1986-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -23,7 +23,7 @@ |
#include <ctype.h> |
#include "ui-out.h" |
-#include "gdb_string.h" |
+#include <string.h> |
#include "exceptions.h" |
#include "top.h" |
#include "breakpoint.h" |
@@ -78,6 +78,25 @@ struct user_args |
*user_args; |
+/* Return non-zero if TYPE is a multi-line command (i.e., is terminated |
+ by "end"). */ |
+ |
+static int |
+multi_line_command_p (enum command_control_type type) |
+{ |
+ switch (type) |
+ { |
+ case if_control: |
+ case while_control: |
+ case while_stepping_control: |
+ case commands_control: |
+ case python_control: |
+ return 1; |
+ default: |
+ return 0; |
+ } |
+} |
+ |
/* Allocate, initialize a new command line structure for one of the |
control commands (if/while). */ |
@@ -314,7 +333,7 @@ execute_user_command (struct cmd_list_element *c, char *args) |
struct cleanup *old_chain; |
enum command_control_type ret; |
static int user_call_depth = 0; |
- extern int max_user_call_depth; |
+ extern unsigned int max_user_call_depth; |
cmdlines = c->user_commands; |
if (cmdlines == 0) |
@@ -441,9 +460,10 @@ execute_control_command (struct command_line *cmd) |
case while_control: |
{ |
- char *buffer = alloca (strlen (cmd->line) + 7); |
+ int len = strlen (cmd->line) + 7; |
+ char *buffer = alloca (len); |
- sprintf (buffer, "while %s", cmd->line); |
+ xsnprintf (buffer, len, "while %s", cmd->line); |
print_command_trace (buffer); |
/* Parse the loop control expression for the while statement. */ |
@@ -509,9 +529,10 @@ execute_control_command (struct command_line *cmd) |
case if_control: |
{ |
- char *buffer = alloca (strlen (cmd->line) + 4); |
+ int len = strlen (cmd->line) + 4; |
+ char *buffer = alloca (len); |
- sprintf (buffer, "if %s", cmd->line); |
+ xsnprintf (buffer, len, "if %s", cmd->line); |
print_command_trace (buffer); |
new_line = insert_args (cmd->line); |
@@ -554,6 +575,7 @@ execute_control_command (struct command_line *cmd) |
break; |
} |
+ |
case commands_control: |
{ |
/* Breakpoint commands list, record the commands in the |
@@ -565,6 +587,7 @@ execute_control_command (struct command_line *cmd) |
ret = commands_from_control_command (new_line, cmd); |
break; |
} |
+ |
case python_control: |
{ |
eval_python_from_control_command (cmd); |
@@ -596,7 +619,7 @@ execute_control_command_untraced (struct command_line *cmd) |
/* "while" command support. Executes a body of statements while the |
loop condition is nonzero. */ |
-void |
+static void |
while_command (char *arg, int from_tty) |
{ |
struct command_line *command = NULL; |
@@ -620,7 +643,7 @@ while_command (char *arg, int from_tty) |
/* "if" command support. Execute either the true or false arm depending |
on the value of the if conditional. */ |
-void |
+static void |
if_command (char *arg, int from_tty) |
{ |
struct command_line *command = NULL; |
@@ -687,11 +710,8 @@ setup_user_args (char *p) |
int bsquote = 0; |
if (arg_count >= MAXUSERARGS) |
- { |
- error (_("user defined function may only have %d arguments."), |
- MAXUSERARGS); |
- return old_chain; |
- } |
+ error (_("user defined function may only have %d arguments."), |
+ MAXUSERARGS); |
/* Strip whitespace. */ |
while (*p == ' ' || *p == '\t') |
@@ -1104,11 +1124,7 @@ recurse_read_control_structure (char * (*read_next_line_func) (void), |
if (val == end_command) |
{ |
- if (current_cmd->control_type == while_control |
- || current_cmd->control_type == while_stepping_control |
- || current_cmd->control_type == if_control |
- || current_cmd->control_type == python_control |
- || current_cmd->control_type == commands_control) |
+ if (multi_line_command_p (current_cmd->control_type)) |
{ |
/* Success reading an entire canned sequence of commands. */ |
ret = simple_control; |
@@ -1157,11 +1173,7 @@ recurse_read_control_structure (char * (*read_next_line_func) (void), |
/* If the latest line is another control structure, then recurse |
on it. */ |
- if (next->control_type == while_control |
- || next->control_type == while_stepping_control |
- || next->control_type == if_control |
- || next->control_type == python_control |
- || next->control_type == commands_control) |
+ if (multi_line_command_p (next->control_type)) |
{ |
control_level++; |
ret = recurse_read_control_structure (read_next_line_func, next, |
@@ -1247,13 +1259,12 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands, |
void (*validator)(char *, void *), void *closure) |
{ |
struct command_line *head, *tail, *next; |
- struct cleanup *old_chain; |
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); |
enum command_control_type ret; |
enum misc_command_type val; |
control_level = 0; |
head = tail = NULL; |
- old_chain = NULL; |
while (1) |
{ |
@@ -1277,11 +1288,7 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands, |
break; |
} |
- if (next->control_type == while_control |
- || next->control_type == if_control |
- || next->control_type == python_control |
- || next->control_type == commands_control |
- || next->control_type == while_stepping_control) |
+ if (multi_line_command_p (next->control_type)) |
{ |
control_level++; |
ret = recurse_read_control_structure (read_next_line_func, next, |
@@ -1299,22 +1306,17 @@ read_command_lines_1 (char * (*read_next_line_func) (void), int parse_commands, |
else |
{ |
head = next; |
- old_chain = make_cleanup_free_command_lines (&head); |
+ make_cleanup_free_command_lines (&head); |
} |
tail = next; |
} |
dont_repeat (); |
- if (head) |
- { |
- if (ret != invalid_control) |
- { |
- discard_cleanups (old_chain); |
- } |
- else |
- do_cleanups (old_chain); |
- } |
+ if (ret != invalid_control) |
+ discard_cleanups (old_chain); |
+ else |
+ do_cleanups (old_chain); |
return head; |
} |
@@ -1414,7 +1416,8 @@ validate_comname (char **comname) |
if (last_word != *comname) |
{ |
struct cmd_list_element *c; |
- char saved_char, *tem = *comname; |
+ char saved_char; |
+ const char *tem = *comname; |
/* Separate the prefix and the command. */ |
saved_char = last_word[-1]; |
@@ -1446,7 +1449,7 @@ user_defined_command (char *ignore, int from_tty) |
{ |
} |
-void |
+static void |
define_command (char *comname, int from_tty) |
{ |
#define MAX_TMPBUF 128 |
@@ -1459,6 +1462,7 @@ define_command (char *comname, int from_tty) |
struct command_line *cmds; |
struct cmd_list_element *c, *newc, *hookc = 0, **list; |
char *tem, *comfull; |
+ const char *tem_c; |
char tmpbuf[MAX_TMPBUF]; |
int hook_type = CMD_NO_HOOK; |
int hook_name_size = 0; |
@@ -1472,8 +1476,8 @@ define_command (char *comname, int from_tty) |
list = validate_comname (&comname); |
/* Look it up, and verify that we got an exact match. */ |
- tem = comname; |
- c = lookup_cmd (&tem, *list, "", -1, 1); |
+ tem_c = comname; |
+ c = lookup_cmd (&tem_c, *list, "", -1, 1); |
if (c && strcmp (comname, c->name) != 0) |
c = 0; |
@@ -1507,8 +1511,8 @@ define_command (char *comname, int from_tty) |
if (hook_type != CMD_NO_HOOK) |
{ |
/* Look up cmd it hooks, and verify that we got an exact match. */ |
- tem = comname + hook_name_size; |
- hookc = lookup_cmd (&tem, *list, "", -1, 0); |
+ tem_c = comname + hook_name_size; |
+ hookc = lookup_cmd (&tem_c, *list, "", -1, 0); |
if (hookc && strcmp (comname + hook_name_size, hookc->name) != 0) |
hookc = 0; |
if (!hookc) |
@@ -1529,7 +1533,8 @@ define_command (char *comname, int from_tty) |
if (isupper (*tem)) |
*tem = tolower (*tem); |
- sprintf (tmpbuf, "Type commands for definition of \"%s\".", comfull); |
+ xsnprintf (tmpbuf, sizeof (tmpbuf), |
+ "Type commands for definition of \"%s\".", comfull); |
cmds = read_command_lines (tmpbuf, from_tty, 1, 0, 0); |
if (c && c->class == class_user) |
@@ -1562,12 +1567,13 @@ define_command (char *comname, int from_tty) |
} |
} |
-void |
+static void |
document_command (char *comname, int from_tty) |
{ |
struct command_line *doclines; |
struct cmd_list_element *c, **list; |
- char *tem, *comfull; |
+ const char *tem; |
+ char *comfull; |
char tmpbuf[128]; |
comfull = comname; |
@@ -1579,7 +1585,8 @@ document_command (char *comname, int from_tty) |
if (c->class != class_user) |
error (_("Command \"%s\" is built-in."), comfull); |
- sprintf (tmpbuf, "Type documentation for \"%s\".", comfull); |
+ xsnprintf (tmpbuf, sizeof (tmpbuf), "Type documentation for \"%s\".", |
+ comfull); |
doclines = read_command_lines (tmpbuf, from_tty, 0, 0, 0); |
if (c->doc) |
@@ -1638,9 +1645,6 @@ script_from_file (FILE *stream, const char *file) |
old_cleanups = make_cleanup (source_cleanup_lines, &old_lines); |
source_line_number = 0; |
source_file_name = file; |
- /* This will get set every time we read a line. So it won't stay "" |
- for long. */ |
- error_pre_print = ""; |
{ |
volatile struct gdb_exception e; |
@@ -1672,7 +1676,7 @@ script_from_file (FILE *stream, const char *file) |
(recursively). PREFIX and NAME combined are the name of the |
current command. */ |
void |
-show_user_1 (struct cmd_list_element *c, char *prefix, char *name, |
+show_user_1 (struct cmd_list_element *c, const char *prefix, const char *name, |
struct ui_file *stream) |
{ |
struct command_line *cmdlines; |
@@ -1696,3 +1700,34 @@ show_user_1 (struct cmd_list_element *c, char *prefix, char *name, |
fputs_filtered ("\n", stream); |
} |
+ |
+ |
+initialize_file_ftype _initialize_cli_script; |
+ |
+void |
+_initialize_cli_script (void) |
+{ |
+ add_com ("document", class_support, document_command, _("\ |
+Document a user-defined command.\n\ |
+Give command name as argument. Give documentation on following lines.\n\ |
+End with a line of just \"end\".")); |
+ add_com ("define", class_support, define_command, _("\ |
+Define a new command name. Command name is argument.\n\ |
+Definition appears on following lines, one command per line.\n\ |
+End with a line of just \"end\".\n\ |
+Use the \"document\" command to give documentation for the new command.\n\ |
+Commands defined in this way may have up to ten arguments.")); |
+ |
+ add_com ("while", class_support, while_command, _("\ |
+Execute nested commands WHILE the conditional expression is non zero.\n\ |
+The conditional expression must follow the word `while' and must in turn be\n\ |
+followed by a new line. The nested commands must be entered one per line,\n\ |
+and should be terminated by the word `end'.")); |
+ |
+ add_com ("if", class_support, if_command, _("\ |
+Execute nested commands once IF the conditional expression is non zero.\n\ |
+The conditional expression must follow the word `if' and must in turn be\n\ |
+followed by a new line. The nested commands must be entered one per line,\n\ |
+and should be terminated by the word 'else' or `end'. If an else clause\n\ |
+is used, the same rules apply to its nested commands as to the first ones.")); |
+} |