summaryrefslogtreecommitdiff
path: root/gdb/mi
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2000-02-23 00:25:43 +0000
committerAndrew Cagney <cagney@redhat.com>2000-02-23 00:25:43 +0000
commit878d2171da6c4e602c22f4fcc32cbd83c17f3785 (patch)
treefbc1fee48f927bb7a1939e4245020e3f71d2eb27 /gdb/mi
parent2304a2f886be1bb386a1f91a075b758ab84d1774 (diff)
downloadgdb-878d2171da6c4e602c22f4fcc32cbd83c17f3785.tar.gz
Add mi/ and testsuite/gdb.mi/ subdirectories.
Add --enable-gdbmi option to configury. Add mi rules to Makefile.in Add mi conditional output to event-top.c infrun.c main.c top.c. Add -i=mi option.
Diffstat (limited to 'gdb/mi')
-rw-r--r--gdb/mi/ChangeLog-mi1346
-rw-r--r--gdb/mi/gdbmi.texinfo2513
-rw-r--r--gdb/mi/mi-cmd-break.c253
-rw-r--r--gdb/mi/mi-cmd-disas.c499
-rw-r--r--gdb/mi/mi-cmd-stack.c317
-rw-r--r--gdb/mi/mi-cmd-var.c474
-rw-r--r--gdb/mi/mi-cmds.c263
-rw-r--r--gdb/mi/mi-cmds.h128
-rw-r--r--gdb/mi/mi-console.c118
-rw-r--r--gdb/mi/mi-console.h31
-rw-r--r--gdb/mi/mi-getopt.c80
-rw-r--r--gdb/mi/mi-getopt.h64
-rw-r--r--gdb/mi/mi-main.c1446
-rw-r--r--gdb/mi/mi-out.c401
-rw-r--r--gdb/mi/mi-out.h39
-rw-r--r--gdb/mi/mi-parse.c243
-rw-r--r--gdb/mi/mi-parse.h59
17 files changed, 8274 insertions, 0 deletions
diff --git a/gdb/mi/ChangeLog-mi b/gdb/mi/ChangeLog-mi
new file mode 100644
index 00000000000..6e22c2654e7
--- /dev/null
+++ b/gdb/mi/ChangeLog-mi
@@ -0,0 +1,1346 @@
+Wed Feb 23 10:30:55 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Update copyright - FSF. Update version
+ information.
+
+ mi-cmd-break.c, mi-cmd-disas.c, mi-cmd-stack.c, mi-cmd-var.c,
+ mi-cmds.h, mi-main.c, mi-parse.c, mi-parse.h: Re-format using GNU
+ indent.
+
+2000-02-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Add include of gdbcore.h for write_memory()
+ prototype.
+
+2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble): Change syntax of
+ command. Now use options.
+ Instead of printing the symbolic address of instructions via
+ print_address_symbolic(), use build_address_symbolic() and format
+ properly for output.
+ (gdb_do_disassmble): Delete.
+
+2000-02-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-disas.c (mi_cmd_disassemble):
+
+2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_write_memory): New function. Write a
+ value into target memory.
+
+ * mi-cmds.h (mi_cmd_data_write_memory): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up data-write-memory to
+ mi_cmd_data_write_memory().
+
+2000-02-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_download): Correct error message to
+ report right function name.
+ (mi_cmd_target_select): Add doing exec cleanups at end.
+ (mi_cmd_data_read_memory): Correct typo.
+ (mi_cmd_execute): Do not simply free last_async_command, but reset
+ it to NULL as well.
+ (free_and_reset): New function, free the argument and set it to
+ NULL.
+ (mi_cmd_target_select_continuation): Delete prototype.
+
+Tue Feb 1 00:17:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-disas.c, mi-cmds.h, mi-console.c, mi-console.h,
+ mi-main.c, mi-out.c, mi-out.h: Update to reflect rename of
+ gdb-file / GDB_FILE to ui-file / ``struct ui_file''.
+
+Mon Jan 31 18:33:28 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Delete reference to
+ fputs_unfiltered_hook.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Update entries for
+ mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values.
+
+ * mi-cmds.h (mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values): Update to mi_cmd_argv_ftype.
+
+ * mi-main.c (mi_cmd_data_list_register_names,
+ mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_values): Update to use argc, argv
+ parameters.
+
+2000-01-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Correct the computation of
+ next-row.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_create): Test for NULL type.
+ (mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update): Prevent possibility of memory
+ leak on error.
+
+2000-01-27 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_field_string): Test for NULL string pointer.
+
+2000-01-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-stack.c (mi_cmd_stack_list_frames): Call
+ print_frmae_info() with the correct arguments.
+
+ * mi-main.c (mi_cmd_exec_return): Call
+ show_and_print_stack_frame() with LOC_AND_ADDRESS, so it does the
+ right thing. Update Copyright.
+
+2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Move disassemble commands from here.
+
+ * mi-cmd-disas.c: To here. New file.
+
+2000-01-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-stack.c: Remove include of mi-out.h.
+
+ * mi-main.c (mi_cmd_disassemble): Update function to use argc/argv
+ interface.
+
+ * mi-cmds.h: Ditto.
+
+ * mi-cmds.c: Ditto.
+
+2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update stack commands descriptions.
+ Add thread commands descriptions and examples.
+
+ * mi-main.c (mi_cmd_thread_list_ids): Fix typo.
+
+2000-01-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_thread_list_ids): New function, print a list
+ of currently known threads ids, and the total number of threads.
+ (mi_cmd_thread_select): New function. Switch current thread.
+
+ * mi-cmds.c (mi_cmds): Implement thread-list-ids by
+ mi_cmd_thread_list_ids, and thread-select by mi_cmd_thread_select.
+
+ * mi-cmds.h (mi_cmd_thread_select, mi_cmd_thread_list_ids): Export.
+
+2000-01-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Move stack commands from here.
+
+ * mi-cmd-stack.c: To here. New file.
+
+2000-01-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (list_args_or_locals): Add a new paramter, the frame
+ for which to display args or locals. Don't use selected_frame
+ anymore, use the new parameter instead. Return void instead of
+ mi_cmd_result, let callers do so.
+ (mi_cmd_stack_list_args): Change interface. Now accept low and
+ high frame numbers to display args for a range of frames. Without
+ these two, display args for the whole stack.
+ (mi_cmd_stack_list_locals): Adapt to new interface for
+ list_args_or_locals.
+
+2000-01-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+ mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+ mi_cmd_stack_select_frame): Change to use argv type of parameters.
+
+ * mi-cmds.c (mi_cmds): Change stack-info-depth,
+ stack-list-arguments, stack-list-frames, stack-list-locals,
+ stack-select-frame to use argv parameters.
+
+ * mi-cmds.h (mi_cmd_stack_info_depth, mi_cmd_stack_list_args,
+ mi_cmd_stack_list_frames, mi_cmd_stack_list_locals,
+ mi_cmd_stack_select_frame): Update definitions.
+
+Tue Jan 4 12:38:54 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Force the MI interface to use seven
+ bit strings.
+ * gdbmi.texinfo: Make it clear that a quoted C string is seven
+ bit.
+
+Thu Dec 30 14:15:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.c (mi_getopt): Rewrite. Allow long options.
+ * mi-getopt.h (struct mi_opt): Declare.
+ (mi_getopt): Update.
+
+ * mi-main.c (mi_cmd_data_read_memory), mi-cmd-break.c
+ (mi_cmd_break_insert, mi_cmd_break_watch): Update.
+
+Wed Dec 29 23:38:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Add support for -c
+ <condition>, -i <ignore-count> and -p <thread>.
+ (breakpoint_notify): New function.
+ (mi_cmd_break_insert): Wrap GDB call with callback hooks so that
+ MI is notified when ever a breakpoint is created.
+
+ * gdbmi.texinfo: Update.
+
+Fri Dec 24 11:23:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Strip out more useless #ifdef
+ UI_OUTs.
+
+1999-12-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Fix output. Lines that have no
+ assembly instructions must still be outputted, to keep the source
+ line numbering correct.
+ Remove #ifdef UI_OUT's, they are useless.
+
+1999-12-17 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Don't print a new list in mixed
+ mode, every time. Just do it when we actually encounter a new
+ source line.
+
+1999-12-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_list_children): Add test for C++ pseudo
+ variable objects (private, public, protected) as these do not have
+ a type and the -var-list-children operation was dumping core.
+
+Fri Dec 17 20:23:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Document recommended syntax for options.
+
+ * mi-main.c (mi_cmd_data_read_memory): Add support for ``-o
+ <offset>''.
+ * gdbmi.texinfo: Document.
+
+Wed Dec 15 17:43:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.h (mi_getopt): Change optarg to a char pointer. Check
+ optind.
+ * mi-cmd-break.c (mi_cmd_break_insert): Update.
+
+ * mi-main.c (mi_cmd_data_read_memory): Add fields "next-row-addr",
+ "prev-row-addr", "next-page-addr", "prev-page-addr" and a per row
+ "addr".
+ * gdbmi.texinfo: Update.
+
+Wed Dec 15 01:05:40 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_result): Add MI_CMD_CAUGHT_ERROR for when the
+ error is caught.
+
+ * mi-main.c (captured_mi_execute_command): When
+ MI_CMD_CAUGHT_ERROR return 0 rethrowing the eror.
+
+1999-12-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Remove unused var.
+
+ * mi-cmd-var.c (mi_cmd_var_update): Remove unused variables.
+
+Mon Dec 13 18:43:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): Quote the command when printing it.
+ (mi_parse_argv): Fix handling of quoted strings. Was not
+ de-quoting them.
+ (mi_parse_argv): Make static.
+
+Mon Dec 13 18:30:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_break_insert, mi_cmd_break_watch): Change type
+ to mi_cmd_argv_ftype.
+ * mi-cmds.c (mi_cmds): Update.
+ * mi-cmd-break.c (mi_cmd_break_insert, mi_cmd_break_watch): Change
+ to new style of arguments with argc and argv. Parse arguments
+ using mi_getopt.
+
+ * mi-cmd-break.c (mi_cmd_break_insert): Wrap body in #ifdef UI_OUT
+ to avoid non-ui compile problems.
+
+Mon Dec 13 15:08:36 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-getopt.h, mi-getopt.c: New files. Similar to getopt but with
+ well defined semantics.
+
+Mon Dec 13 14:22:21 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_break_insert, mi_cmd_break_watch, enum
+ wp_type, enum bp_type): Move from here.
+ * mi-cmd-break.c: To here. New file.
+ (mi_cmd_break_insert, mi_cmd_break_insert, mi_cmd_break_watch):
+ Use error to report problems.
+
+1999-12-09 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update description of exec-interrupt.
+
+ * mi-main.c (mi_cmd_exec_interrupt): If the program is not
+ executing, don't try to interrupt it, but error out instead. Make
+ sure previous_async_command is not null before duplicating it into
+ last_async_command.
+
+ * gdbmi.texinfo: Add examples for data-evaluate-expression.
+
+1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_assign, mi_cmd_var_create,
+ mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+ mi_cmd_var_info_type, mi_cmd_var_list_children,
+ mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+ mi_cmd_var_show_format, mi_cmd_var_update): Change to use new
+ style of arguments with argc and argv.
+ (next_arg): Delete.
+ (which_var): Delete.
+
+ * mi-cmds.c (mi_cmds): Update entries for mi_cmd_var_assign,
+ mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_evaluate_expression, mi_cmd_var_info_expression,
+ mi_cmd_var_info_num_children, mi_cmd_var_info_type,
+ mi_cmd_var_list_children, mi_cmd_var_set_format,
+ mi_cmd_var_show_attributes, mi_cmd_var_show_format,
+ mi_cmd_var_update.
+
+ * mi-cmds.h (mi_cmd_var_assign, mi_cmd_var_create,
+ mi_cmd_var_delete, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_info_expression, mi_cmd_var_info_num_children,
+ mi_cmd_var_info_type, mi_cmd_var_list_children,
+ mi_cmd_var_set_format, mi_cmd_var_show_attributes,
+ mi_cmd_var_show_format, mi_cmd_var_update): Update declarations.
+
+1999-12-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Comment out -data-assign command. * mi-main.c
+ (mi_cmd_data_assign): Do not use, comment out. * mi-cmds.h
+ (mi_cmd_data_assign): Remove. * mi-cmds.c: Remove -data-assign
+ command from MI interface.
+
+1999-12-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-parse.c (mi_parse): Add '\n' at end of error messages, so
+ that prompt comes out on new line.
+
+ * gdbmi.texinfo: Update disassembly command output.
+
+1999-12-06 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): Update output for UI_OUT case.
+
+1999-12-02 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update exec-until output, including the reason
+ for stopping.
+
+Thu Dec 2 17:17:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.c: Include <string.h> for memset.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_return): ifdef the references to
+ return_command_wrapper().
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_interrupt,
+ mi_cmd_target_select, mi_execute_async_cli_command,
+ mi_exec_async_cli_cmd_continuation, mi_load_progress): Don't print
+ last_async_command if it is NULL.
+ (mi_cmd_exec_return):
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_return): Reimplement using
+ return_command() instead of mi_execute_async_cli_command().
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h: Export mi_cmd_data_assign and
+ mi_cmd_data_evaluate_expression.
+
+ * mi-cmds.c (mi_cmds): Hook data-assign to mi_cmd_data_assign and
+ data-evaluate-expression to mi_cmd_data_evaluate_expression.
+
+ * mi-main.c (mi_cmd_data_assign): New function. Implement
+ data-assign command.
+ (mi_cmd_data_evaluate_expression): New function. Implement
+ data-evaluate-expression command.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Fix some texinfo formatting errors.
+
+1999-12-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Update data-list-register-values description.
+
+ * mi-cmds.h: Export mi_cmd_data_list_register_values.
+
+ * mi-cmds.c (mi_cmds): Hook data-list-register-values to
+ mi_cmd_data_list_register_values.
+
+ * mi-main.c (mi_cmd_data_list_register_values): New
+ function. Implements the -data-list-register-values command.
+ (get_register): New function. Output the contents of a given
+ register.
+
+Wed Dec 1 20:27:22 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Append missing "\n"
+ for synchronous stopped message.
+
+1999-11-30 James Ingham <jingham@leda.cygnus.com>
+
+ * gdbmi.texinfo: Fix obvious typo in @end statement.
+
+Wed Dec 1 12:36:27 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-var.c: Include "value.h".
+ * mi-console.c: Include <string.h>.
+
+Wed Dec 1 00:21:03 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): For a CLI command, pass
+ "%s" to mi_execute_cli_command to stop core dumps.
+ (captured_mi_execute_command): Echo CLI commands on gdb_stdlog.
+
+Wed Dec 1 00:10:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo: Explain NR-BYTES and ADDR.
+
+Tue Nov 30 23:31:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmd-var.c (mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one, next_arg,
+ which_var): New file. Move varobj commands to here from
+ mi-main.c.
+
+ * mi-console.h, mi-console.c (mi_console_file_new,
+ mi_console_file_delete, mi_console_file_fputs,
+ mi_console_raw_packet, mi_console_file_flush): New files. Move
+ mi_console_file to here from mi-main.c.
+
+Tue Nov 30 19:37:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): Use fputstr_unfiltered
+ when printing error messages.
+ (mi_cmd_execute): Ditto.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Describe -data-list-changed-registers,
+ -data-list-register-names. Add examples for
+ -exec-next-instruction, exec-step-instruction, -exec-run,
+ -exec-until. Format examples for -data-read-memory.
+ update example for -target-download.
+
+1999-11-29 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Remove mentioning of inaccurate watchpoint hit
+ count.
+
+Mon Nov 29 19:28:55 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Return ``enum
+ mi_cmd_cmd_result''. mi_cmd_exec_run, mi_cmd_exec_next,
+ mi_cmd_exec_step, mi_cmd_exec_step_instruction,
+ mi_cmd_exec_finish, mi_cmd_exec_until, mi_cmd_exec_return,
+ mi_cmd_exec_continue): Update call.
+ (mi_execute_async_cli_command): When target is synchronous, fake
+ asynchronous behavour (ulgh). Allows tests to be run on built-in
+ simulator and native targets.
+
+Mon Nov 29 15:15:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_gdb_exit), mi-cmds.c (mi_cmds), mi-main.c
+ (mi_cmd_gdb_exit): Change function signature to mi_cmd_argv_ftype.
+
+1999-11-28 Andew Cagney <cagney@rat-in-a-hat.cygnus.com>
+
+ * mi-parse.c: Include <ctype.h> and <string.h>
+
+1999-11-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * gdbmi.texinfo: Added watchpoint command descriptions and
+ examples.
+
+ * mi-main.c (mi_load_progress): Add parameter for total sent so far.
+ Print it as well.
+
+Fri Nov 26 10:17:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbmi.texinfo (section Output Syntax): For lists, the <string>
+ part of a <result> is optional. Clarify syntax.
+ (appendix Proposed v2.0 Output Syntax): New section. Provide
+ record of discussion of possible changes to syntax.
+
+Wed Nov 24 19:41:35 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): Simplify. Fix coredump
+ when arguments were bad.
+ (mi_cmd_execute): Change parameter to ``struct mi_parse''. Handle
+ case of argv_func as well as args_func.
+ (captured_mi_execute_command): Update.
+
+ * mi-cmds.c (struct mi_cmd): Add field for mi_cmd_argv_ftype.
+ (mi_cmds): Update mi_cmd_data_read_memory.
+ (mi_lookup): Return
+
+ * mi-cmds.h (mi_cmd_args_ftype): Rename mi_cmd_ftype. Make all
+ functions of type this type.
+ (mi_cmd_argv_ftype): Declare.
+ (mi_cmd_data_read_memory): Change type to mi_cmd_argv_fytpe.
+ (struct mi_cmd): Move declaration to here from mi-cmds.c.
+ (mi_lookup): Return a pointer to ``struct mi_cmd''.
+
+Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): Initialize TOKEN when a CLI command.
+
+ * gdbmi.texinfo: Allow a <token> before a CLI command.
+
+ * mi-parse.h (struct mi_parse): Declare.
+ (mi_parse): Change to return a ``struct mi_parse''.
+ (enum mi_command_type): Delete PARSE_ERROR.
+
+ * mi-main.c (struct mi_execute_command_context): Delete.
+ (captured_mi_execute_command): Update
+ (mi_execute_command): Update. Check for mi_parse returning NULL.
+
+Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.h: Remove const, from cmd parameter. Causes cascading
+ warnings.
+
+Wed Nov 24 15:03:34 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c (mi_parse): New function. Move parse code to here.
+ * mi-main.c (parse): From here. Delete.
+
+Wed Nov 24 12:57:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-parse.c, mi-parse.h: New files. Implement mi_parse_env.
+
+Wed Nov 24 11:24:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_field_string): Make string parameter constant.
+
+1999-11-23 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_target_download): Export.
+
+ * mi-cmds.c (mi_cmds): Add mi_cmd_target_download.
+
+ * mi-main.c: Include <sys/time.h>.
+ (mi_cmd_target_download): New function, implement the
+ target-download command.
+ (mi_load_progress): New function. Called via the
+ show_load_progress hook. Prints updates every 0.5 secs.
+ (mi_command_loop): Initialize the show_load_progress hook.
+
+1999-11-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_until): New function. Implement until
+ command.
+ (mi_cmd_exec_step_instruction): New function. Implement stepi
+ command.
+ (mi_cmd_exec_next_instruction): New function. Implement nexti
+ command.
+
+ * mi-cmds.c (mi_cmds): Add mi_cmd_exec_step_instruction,
+ mi_cmd_exec_next_instruction, mi_cmd_exec_until.
+
+ * mi-cmds.h (mi_cmd_exec_step_instruction,
+ mi_cmd_exec_next_instruction, mi_cmd_exec_until): Export.
+
+Tue Nov 23 00:30:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi/gdbmi.texinfo: Document -data-read-memory.
+
+ * mi-main.c (mi_cmd_data_read_memory): Fix off-by-one check of
+ argc.
+ (mi_cmd_data_read_memory): Label the output table with "memory".
+
+Thu Nov 18 18:15:53 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_exec_interrupt, mi_cmd_break_insert,
+ mi_cmd_break_watch, mi_cmd_disassemble, mi_cmd_execute): Replace
+ strdup with xstrdup.
+
+Thu Nov 18 20:50:09 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_data_read_memory): New function. Implement
+ data-read-memory.
+
+ * mi-cmds.h, mi-cmds.c: Add mi_cmd_data_read_memory.
+ * mi-cmds.c (mi_cmds): Ditto.
+
+1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_break_watch): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up break-watch to function
+ mi_cmd_break_watch.
+
+ * mi-main.c (wp_type): New enumeration for the possible types of
+ watchpoints.
+ (mi_cmd_break_watch): New function, implements the break-watch
+ command.
+
+1999-11-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_break_insert): Handle case in which the command is
+ just a -break-insert w/o args.
+
+Fri Nov 12 00:01:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_field_string): Always quote the string.
+
+1999-11-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.h(mi_cmd_data_list_changed_registers,
+ mi_cmd_data_list_register_names): Export.
+
+ * mi-cmds.c (mi_cmds): Hook up data-list-changed-registers to
+ mi_cmd_data_list_changed_registers and data-list-register-names to
+ mi_cmd_data_list_register_names.
+
+ * mi-main.c (mi_cmd_data_list_changed_registers): New function,
+ implements the data-list-changed-registers command.
+ (mi_cmd_data_list_register_names): New function, implements the
+ data-list-register-names command.
+ (register_changed_p): New function. Decide whether the register
+ contents have changed.
+ (setup_architecture_data): New function. Initialize registers
+ memory.
+ (_initialize_mi_main): Call setup_architecture_data(), and
+ register_gdbarch_swap().
+
+Wed Nov 10 18:35:08 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Correctly quote error messages.
+
+Wed Nov 10 11:05:14 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi/gdbmi.texinfo: Delete <stream-output>. Replaced by
+ <c-string>.
+
+ * mi-main.c (mi_console_raw_packet): Always quote console output.
+
+Tue Nov 9 17:53:05 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_new), mi-out.c (mi_out_new): Replace
+ the tui_file with a mem_file. Ya!
+
+ * mi-out.c (do_write): New function, wrapper to gdb_file_write.
+ (mi_out_put): Pass do_write to gdb_file_put.
+
+ * mi-main.c (mi_console_file_flush): Rewrite. Use
+ mi_console_raw_packet to send data to the console.
+ (mi_console_raw_packet): New function. Correctly
+ create quoted C string packets.
+
+1999-11-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Break-insert is now implemented by
+ mi_cmd_break_insert.
+ * mi-cmds.h (mi_cmd_break_insert): Export.
+ * mi-main.c (bp_type): New enumeration.
+ (mi_cmd_break_insert): New function. Implements all flavors of
+ breakpoint insertion.
+
+Mon Nov 8 17:49:17 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_flush): Replace gdb_file_get_strbuf
+ with tui_file_get_strbuf.
+
+Fri Nov 5 17:06:07 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_delete, mi_console_file_fputs,
+ mi_console_file_flush): Call internal_error instead of error.
+
+Thu Nov 4 19:53:32 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (captured_mi_execute_command): New function.
+ (mi_execute_command): Rewrite. Replace SET_TOP_LEVEL() with call
+ to captured_mi_execute_command via catch_errors.
+
+Thu Nov 4 20:33:58 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (clean): Delete.
+ (mi_command_loop): Delete extern declaration of
+ mi_execute_command.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_stack_select_frame): Conditionalize the body
+ on UI_OUT, because select_frame_command_wrapper is only defined if
+ UI_OUT is.
+ (mi_cmd_exec_interrupt): Conditionalize the body on UI_OUT,
+ because interrupt_target_command_wrapper is only defined if UI_OUT is.
+
+ * mi-cmds.c (mi_cmds): Implement command exec-interrupt by
+ mi_cmd_exec_interrupt.
+
+ * mi-main.c (mi_cmd_exec_interrupt): New function. Implements
+ exec-interrupt command.
+ (mi_cmd_execute): If the target is running save execution command
+ token in previous_async_command. If the command is not 'interrupt'
+ and the target is running, reject it.
+ (clean): New function. Free the arg and reset it to NULL.
+
+ * mi-cmds.h (mi_cmd_exec_interrupt):Export.
+
+1999-10-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Implement command stack-select-frame by
+ mi_cmd_stack_select_frame.
+
+ * mi-main.c (mi_cmd_stack_select_frame): New function. Implements
+ stack-select-frame command.
+
+ * mi-cmds.h (mi_cmd_select_frame):Export.
+
+1999-10-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Implement commands stack-list-locals and
+ stack-list-arguments by mi_cmd_stack_list_locals and
+ mi_cmd_stack_list_args.
+
+ * mi-main.c (mi_cmd_stack_list_locals): New function. Implements
+ stack-list-locals command.
+ (mi_cmd_stack_list_args): New function. Implements
+ stack-list-arguments command.
+ (list_args_or_locals): New function. Do all the work for the
+ listing of locals or arguments.
+
+ * mi-cmds.h (mi_cmd_stack_list_args,mi_cmd_stack_list_locals) :
+ Export.
+
+1999-10-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add new command stack-info-depth.
+
+ * mi-main.c (mi_cmd_stack_info_depth): New function. Implements
+ the stack-info-depth command.
+ * mi-cmds.h (mi_cmd_stack_info_depth): Export.
+
+
+1999-10-22 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Handle MI_CMD_ERROR case
+ properly, for command that return error code and don't set
+ mi_error_message.
+
+ * mi-cmds.c (mi_cmds): Hook stack-list-frames command to
+ mi_cmd_stack_list_frames function.
+ * mi-cmds.h (mi_cmd_stack_list_frames): Export.
+
+ * mi-main.c (mi_execute_command): Deal with a return code of
+ MI_CMD_ERROR from the execution of mi commands.
+ (mi_error_message): Static string variable, to contain the error
+ message from mi commands.
+ (mi_cmd_stack_list_frames): New function. Prints a backtrace.
+
+1999-10-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Handle the new command line
+ parameter that specifies the number of disassembly lines to be
+ displayed.
+ (gdb_do_disassemble): Add new parameter. Count the number of lines
+ that have been displayed, and stop when limit is reached.
+
+Wed Oct 13 18:04:13 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Don't initialize ``flush_hook''.
+
+1999-10-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: More reformatting of the grammars.
+
+1999-10-12 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: More TeX formatting.
+
+1999-10-11 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: First pass completed. All commands should have
+ some comments/info.
+ Escape '@' output special char.
+ Reformat for TeX.
+
+1999-10-08 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: Filled in part of file command section, and
+ stack section.
+
+1999-10-07 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi/gdbmi.texinfo: Filled in some sections about execution
+ commands.
+
+Tue Oct 5 15:27:28 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h: Sort table
+ * mi-cmds.c: Ditto.
+ (MI_TABLE_SIZE): Increase to 251.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete): Add missing
+ cleanups.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (next_arg): Returns lenght as well.
+ (which_var, mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_update): Do not modify the input
+ string, use allocated storage instead.
+ (mi_cmd_var_assign): Adjust call to next_arg() to include new
+ argument.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Fix handling of errors.
+
+1999-10-04 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_out_new): Call tui_sfileopen() instead of
+ deprecated gdb_file_init_astream().
+ * mi-main.c (mi_console_file_new): Ditto.
+
+Mon Oct 4 15:17:29 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h: Sort function declarations.
+ (mi_lookup): Add extern.
+
+ * mi-cmds.c (mi_lookup): Delete dead code.
+ (build_table): Call internal_error instead of error.
+ (build_table): Send trace output to gdb_stdlog.
+
+1999-10-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Don't do the cleanups
+ if target_executing is null.
+
+1999-09-28 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (async_p): Change var name to event_loop_p.
+
+Mon Sep 27 15:11:00 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command, mi_execute_command):
+ Replace target_has_async with function target_can_async_p.
+
+Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select_continuation): Delete function.
+ (mi_cmd_target_select): Simplify. target-connect is guarenteed to
+ be synchronous.
+
+Sun Sep 26 00:12:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (mi_cmd_ftype): Replace mi_impl_ftype.
+ (enum mi_cmd_result): Define.
+ * mi-cmds.c (struct mi_cmd): Update.
+ (mi_lookup): Update.
+ * mi-main.c (mi_cmd_execute): Update.
+
+ * mi-main.c (mi_cmd_gdb_exit, mi_cmd_exec_run, mi_cmd_exec_next,
+ mi_cmd_exec_step, mi_cmd_target_select, mi_cmd_exec_continue,
+ mi_cmd_exec_return, mi_cmd_exec_finish, mi_cmd_disassemble,
+ mi_cmd_var_create, mi_cmd_var_delete, mi_cmd_var_set_format,
+ mi_cmd_var_show_format, mi_cmd_var_info_num_children,
+ mi_cmd_var_list_children, mi_cmd_var_info_type,
+ mi_cmd_var_info_expression, mi_cmd_var_show_attributes,
+ mi_cmd_var_evaluate_expression, mi_cmd_var_update): Update.
+ Return MI_CMD_DONE.
+
+1999-09-22 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create): Use paddr() to format address
+ on trace output.
+
+1999-09-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create): Test for varobjdebug before
+ printing trace and send it to gdb_stdlog.
+
+Mon Sep 20 13:41:04 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * Makefile.in (mi-out.o): Add dependency list.
+ * mi-out.c: Include "mi-out.h".
+
+1999-09-18 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (_initialize_mi_main): Events on stadin are now
+ handled by stdin_event_handler.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add var-* commands.
+
+1999-09-17 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_var_create, mi_cmd_var_delete,
+ mi_cmd_var_set_format, mi_cmd_var_show_format,
+ mi_cmd_var_info_num_children, mi_cmd_var_list_children,
+ mi_cmd_var_info_type, mi_cmd_var_info_expression,
+ mi_cmd_var_show_attributes, mi_cmd_var_evaluate_expression,
+ mi_cmd_var_assign, mi_cmd_var_update, varobj_update_one,
+ which_var, next_arg): New functions. Implement the -var-*
+ commands.
+ * mi-cmds.h: Add prototypes for the above.
+
+1999-09-14 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Add detach command.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (lookup_table): Fix typo.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds): Fix typo and missing command.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Properly align function prototypes.
+ (mi_cmd_target_select): Proper check for NULL value.
+
+1999-09-09 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_execute_async_cli_command): Fix for native targets
+ that do not have async yet.
+
+1999-09-01 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Remove unused var.
+ (gdb_do_disassemble): Ditto.
+
+1999-08-30 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Replace all the occurrences of 'asynch' in variable
+ or function names with 'async' to make it consistent with the rest
+ of gdb.
+
+Mon Aug 30 18:16:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c: #include <ctype.h> for isspace().
+
+1999-08-27 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (gdb_do_disassemble): This function returns void, not
+ int.
+
+1999-08-26 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): Don't use atoi() on the high
+ address string, just treat it same as address low.
+ (gdb_do_disassemble): Parse high_address string before seeing if
+ it is zero.
+
+1999-08-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_disassemble): New function to produce
+ disassembly output for mi.
+ (gdb_dis_asm_read_memory): New function. Read the disassembly from
+ the executable file, instead of target memory.
+ (compare_lines): New function. Compare order of disassembly lines.
+ (gdb_do_disassemble): New function. Do the real job of getting the
+ assembly code out.
+
+ * mi-cmds.c (mi_cmds): Do data-disassemble mi command via the
+ mi_cmd_disassemble function.
+
+ * mi-cmds.h: Export new function mi_cmd_disassemble.
+
+Wed Aug 25 15:58:31 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Remove references to ui-hooks.
+
+1999-08-21 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_execute_asynch_cli_command): Fix the incorrect
+ usage of strcat(): allocate enough space for the string.
+
+1999-08-13 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ From Christopher Faylor <cgf@cygnus.com>
+ * mi-main.c (mi_execute_command): Make sure we flush all the
+ output after each command.
+
+1999-08-10 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (_initialize_mi_main): Remove casting in call to
+ add_file_handler.
+
+Sun Aug 8 17:20:57 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select, mi_execute_asynch_cli_command):
+ Replace call to fatal with call to internal_error.
+
+1999-07-26 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_execute): Add return code.
+ (mi_execute_command): Make appropriate changes when calling the
+ function mentioned above.
+ (mi_cmd_gdb_exit, mi_cmd_target_select,
+ mi_cmd_target_select_continuation, mi_execute_command,
+ mi_exec_asynch_cli_cmd, mi_exec_asynch_cli_cmd_continuation):
+ Print token, prefix, class and output (if any) in one single group
+ of statements.
+ (mi_execute_command, mi_cmd_execute): Fix error prefix.
+ (mi_cmd_execute): Use exec cleanup for token.
+ * mi-out.c (mi_out_rewind): New function.
+ * mi-out.h: Prototype for the above.
+
+1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_gdb_exit): Use buffer for exit message.
+ (mi_cmd_execute): Route error messages to correct file.
+ (mi_execute_asynch_cli_command): Insert line feed after running
+ message.
+
+1999-07-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.h (mi_out_buffered): Add extern declaration.
+ * mi-out.c (mi_out_buffered): New function. Insert a string at the
+ current buffer position.
+ * mi-main.c (mi_cmd_target_select, mi_execute_command,
+ mi_cmd_execute, mi_execute_asynch_cli_command): Use the above
+ function instead of printing to raw_stdout.
+ (mi_cmd_target_select, mi_cmd_target_select_continuation,
+ mi_execute_command, mi_cmd_execute, mi_execute_cli_command,
+ mi_exec_asynch_cli_cmd_continuation): Fix handling of token and
+ prefix.
+ (mi_execute_cli_command): Remove parameter no longer needed.
+
+1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c (mi_cmd_target_select_continuation): Print the numeric
+ token when we are connected.
+ (mi_execute_command): Don't print the token now, do it later.
+ (mi_execute_cli_command): Add a new parameter for the numeric
+ token. Print the token, the prefix and the class after the
+ command has executed, not before.
+ (mi_execute_asynch_cli_command): Don't print an extra blank line.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_gdb_exit): Add \n at the end.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_cmd_execute): New function. Dispatch a mi operation.
+ (mi_execute_command): Use the above.
+
+1999-07-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Fix identation.
+
+1999-07-15 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * mi-main.c: Include target.h and inferior.h.
+ (mi_cmd_target_select): New function to execute the target-select
+ mi operation.
+ (mi_cmd_target_select_continuation): New function. Continuation
+ for the target-select operation.
+ (mi_execute_command): In case of an MI command which requires
+ asynchronous execution, do not try to display the result now. If
+ the execution has to look synchronous don't display the "(gdb)"
+ prompt.
+ (mi_execute_asynch_cli_command): Invoke real asynchronous
+ commands, set up exec_cleanups, and continuations.
+ (mi_exec_asynch_cli_cmd_continuation): New function. Continuation
+ for all the MI execution commands except 'target-select'.
+ (mi_execute_command): Handle null commands by exiting gdb, instead
+ of core dumping.
+
+ * mi-cmds.c (mi_cmds): Hook up -target-select operation to new mi
+ function.
+
+ * mi-cmds.h (mi_cmd_target_select): Add extern declaration.
+
+Thu Jul 15 10:31:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (struct mi_console_file): Add field ``prefix''.
+ (mi_console_file_new): Add argument prefix. Initialize prefix
+ field.
+ (mi_console_file_flush): Use ``prefix'' instead of "~" as the
+ prefix string.
+ (mi_command_loop): Update stream output prefixes. gdb_stdout ==
+ "~", gdb_stderr / gdb_stdlog == "&", gdb_stdtarg == "@".
+
+1999-07-13 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (ui_out_data): New field first_header. Fix output when
+ no breakpoints are found.
+ (mi_table_begin, mi_table_body, mi_table_header): Test for
+ first_header.
+ (mi_table_end): Test for supress_field_separator.
+ (mi_message): Remove messages from MI output.
+
+1999-06-30 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_cmds[]): Delete gdb-cli operation.
+ * mi-main.c (parse): Remove ifdefs for cli commands parsing.
+ (mi-execute-command): Ditto.
+
+Mon Jun 28 13:06:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.h: New file.
+ (mi_out_new, mi_out_put): Move mi specific delcarations to here.
+ * ui-out.h: From here.
+
+ * mi-main.c: Include "mi-out.h".
+
+1999-06-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * top.c (print_gdb_version): Add the word HEADLESS when output
+ follows headless format.
+ (print_command_lines): Fix typo.
+
+1999-06-25 Elena Zannoni <ezannoni@kwikemart.cygnus.com>
+
+ * event-loop.h: Export input_fd.
+ * mi-main.c (mi_command_loop): Use the event loop if running
+ asynchronously.
+ (mi_execute_command_wrapper): New function.
+ (_initialize_mi-main): Set things up for running asynchronously.
+
+1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (mi_lookup): Deleted.
+ (lookup_table): New function. Replaces old mi_lookup() for local
+ use.
+ (mi_lookup): New function. External interface for command table
+ searchs.
+ (build_table): New definition.
+ (mi_cmds[]): Add several command implementations and the gdb-cli
+ special operation.
+ (mi_cmd_execute): Deleted.
+ * mi-cmds.h: Add type definition for command implementation
+ function pointers, add declaration for new implementation
+ functions and a declaration for mi_lookup().
+ * mi-main.c (mi_execute_asynch_cli_command): New
+ function. Captures code that was repeated for all asynch
+ operations.
+ (mi_cmd_exec_*): Use the above new function.
+ (mi_gdb_cmd_exit): Fix the output, printing something appropriate.
+ (mi_cmd_exec_finish): New operation implementation function.
+ (mi_cmd_exec_return): Ditto.
+ (parse): Prepare to remove cli commands.
+ (mi_execute_command): Fix the output and change the way mi-cmds is
+ used.
+
+1999-06-18 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_begin): Add missing field separator call.
+
+Thu Jun 17 21:05:40 1999 Fernando Nasser <fnasser@tofu.to.cygnus.com>
+
+ * breakpoint.c (breakpoint_1): Remove space in breakpoint table
+ id.
+ (mention): Use ui_out for last new line (forgotten).
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c (mi_console_file_flush): Prevent prefix printing when
+ buffer empty; change prefix to '~'.
+ (mi_cmd_exec_*): Prefix normal output with '^' instead of
+ ','; remove unwanted new lines before "stopped".
+
+1999-06-16 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-cmds.c (struct mi_cmds): Updated entries for -exec-continue
+ and exec-next operations.
+ (mi_cmd_execute): New text for error messages.
+ * mi-cmds.h: Add declaration for mi_cmd_exec_next and
+ mi_cmd_exec_continue.
+ * mi-main.c (mi_cmd_exec_next): New function. Implements exec-next
+ operation.
+ (mi_cmd_exec_continue): New function. Implements exec-continue
+ operation.
+ (mi_execute_comand): Add missing space to prompt.
+ (mi_cmd_exec_run): Ditto.
+ (mi_cmd_exec_step): Ditto.
+ * mi-out.c (mi_out_new): Add flags argument to ui_out_new call.
+ (ui_list_end): Reset supress_field_separator flag.
+
+Sat Jun 12 11:49:10 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h. mi-cmds.c (exec step): Command implemented by
+ mi_cmd_exec_step instead of cli call.
+ * mi-main.c (mi_cmd_exec_step): New function.
+
+ * mi-cmds.h. mi-cmds.c (exec run): Command implemented by
+ mi_cmd_exec_run instead of cli call.
+ * mi-main.c (mi_cmd_exec_run): New function.
+
+ * mi-cmds.h. mi-cmds.c (gdb exit): Command implemented by
+ mi_cmd_gdb_exit instead of quit_force.
+ * mi-main.c (mi_cmd_gdb_exit): New function.
+
+Sat Jun 12 11:33:23 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_command_loop): Pass mi_input to
+ simplified_command_loop.
+ (mi_input): New function. Calls gdb_readline with no prompt.
+
+Sat Jun 12 11:19:02 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_console_file_fputs): Re-implement. Use a buffer
+ to accumulate output.
+
+ * mi-main.c (struct mi_console_file): Add a buffer.
+ (mi_console_file_new): Create a buffer.
+ (mi_console_file_flush): New function.
+
+Sat Jun 12 10:59:39 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-cmds.h (raw_stdout): Declare. Will be moved later.
+ * mi-cmds.c (mi_cmd_execute): Send error messages to RAW stdout.
+ (mi_cmds): Sort by class.
+
+ * mi-main.c (raw_stdout): Make global.
+ * mi-main.c: Remove #ifdef UI_OUT. File assumes UI_OUT is
+ present.
+ * mi-main.c: Include "gdb_string.h".
+ (mi_out_put): Delete declaration.
+
+1999-06-11 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-main.c: Add pre-processor test for UI_OUT.
+ (mi_execute_command): Add pre-processor test for UI_OUT.
+
+Fri Jun 11 23:11:41 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (raw_stdout): New variable.
+ (mi_execute_command): Write mi-out direct to raw_stdout.
+ (mi_command_loop): Create raw_stdout. Attach gdb_stdout to the
+ console.
+ (mi_console_file_fputs, mi_console_file_delete,
+ mi_console_file_new): New functions.
+ (struct mi_console_file): Declare.
+
+Fri Jun 11 18:34:33 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c (mi_execute_command): Call mi_out_put to display the
+ result.
+ * mi-out.c (mi_out_put): New function.
+ * ui-out.h (mi_out_put): Add declare. Will move later.
+ * Makefile.in (mi-cmds.o, mi-main.o): Add dependency on ui-out.h.
+
+ * mi-out.c (mi_field_string, mi_field_fmt, mi_message, mi_flush,
+ out_field_fmt, list_open, list_close): Replace gdb_stdout with
+ data->buffer.
+ (field_separator, list_open, list_close): Add uiout parameter.
+ (mi_table_begin, mi_table_body, mi_table_end, mi_list_begin,
+ mi_list_end, mi_field_string, mi_field_fmt, out_field_fmt,
+ out_field_fmt): Update.
+
+ * mi-out.c (mi_out_new): Initialize supress_field_separator.
+ (supress_field_separator): Move into mi-out local data object.
+ (mi_table_begin, mi_list_begin, field_separator): Update.
+
+Fri Jun 11 16:08:37 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-out.c (mi_out_new): New function, replace init_mi_out.
+ * mi-main.c (mi_command_loop): Call mi_out_new().
+
+ * ui-out.h (mi_out_new): Add declaration. Will move later.
+ (mi_ui_out_impl): Delete.
+
+Wed Jun 9 16:42:16 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * mi-main.c: Include "ui-hooks.h".
+ (mi_init_ui, mi_command_loop): New functions.
+ (_initialize_mi_main): Install ``mi'' as the interpreter when
+ selected.
+
+Mon Jun 7 18:43:43 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fernando Nasser <fnasser@totem.to.cygnus.com>
+ * mi-cmds.c (build_table): Clean up error message.
+ * mi-cmds.c (mi_cmd_execute), mi-main.c (mi_execute_command): Only
+ print debug information when mi_debug_p.
+ * mi-cmds.h (mi_debug_p), mi-main.c: Global, control debug messages.
+
+Thu Jun 3 00:44:52 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ From Fernando Nasser <fnasser@totem.to.cygnus.com>:
+ * mi-cmds.c: Add CLI definitions for "exec-arguments",
+ "exec-next", "gdb-exit", "break-list", "break-info", "exec-step"
+ and "stack-list-frames" to mi_cmds.
+ (struct mi_command): Add ``from_tty'' argument to func.
+ * mi-cmds.h (quit_force): Declare.
+
+1999-05-31 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_end): Remove unwanted "\n".
+
+Thu May 27 14:59:06 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c: Include "ui-hooks.h".
+ (call_interp_loop): Tempoary. Pass mi_execute_command to
+ simplified_command_loop. Initialize gdb_stdout & gdb_stderr to
+ stdio gdb_file streams. Force all hooks to null.
+
+ * mi-cmds.h, mi-main.c, mi-cmds.c: New files.
+ * Makefile.in (SFILES): Add mi-main.c, mi-cmds.c
+ (COMMON_OBS): Add mi-main.o, mi-cmds.o.
+ (mi_cmds_h): Define.
+
+Wed May 26 12:39:49 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * top.c (call_interp_loop): Hack. Add extern declaration for
+ mi_ui_out_impl.
+
+1999-05-25 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: New table syntax.
+
+Mon May 24 16:16:29 1999 Andrew Cagney <cagney@amy.cygnus.com>
+
+ mi-out.c (_initialize_mi_out): Add external declaration.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c (mi_table_begin): Added missing parameter.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: Changed table markers and added table id.
+
+1999-05-21 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ * mi-out.c: New file. Implements low-level ui-out primitives for
+ CLI-based interaction.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/gdb/mi/gdbmi.texinfo b/gdb/mi/gdbmi.texinfo
new file mode 100644
index 00000000000..ec2590e907b
--- /dev/null
+++ b/gdb/mi/gdbmi.texinfo
@@ -0,0 +1,2513 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename gdbmi.info
+@settitle GDB/MI Machine Interface
+@setchapternewpage off
+@c %**end of header
+
+@ifinfo
+This file documents GDB/MI, a Machine Interface to GDB.
+
+Copyright (C) 2000, Free Software Foundation, Inc.
+Contributed by Cygnus Solutions.
+
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission notice
+identical to this one except for the removal of this paragraph (this
+paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that the
+entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@c This title page illustrates only one of the
+@c two methods of forming a title page.
+
+@titlepage
+@title GDB/MI
+@subtitle Version 0.2
+@subtitle Feb 2000
+@author Andrew Cagney, Fernando Nasser and Elena Zannoni
+
+@c The following two commands
+@c start the copyright page.
+@page
+@vskip 0pt plus 1filll
+Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+Copyright @copyright{} 2000, Free Software Foundation, Inc.
+@end titlepage
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Overview
+
+@heading Function and Purpose
+
+GDB/MI is a line based machine oriented text interface to GDB. It is
+specifically intended to support the development of systems which use
+the debugger as just one small component of a larger system.
+
+@heading This Document
+
+This document is a specification of the GDB/MI interface. It is written
+in the form of a reference manual.
+
+@heading Terminology
+
+@heading Dependencies
+
+@heading Acknowledgments
+
+In alphabetic order: Fernando Nasser, Stan Shebs and Elena Zannoni.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Command Syntax
+
+@section Input Syntax
+
+@table @code
+
+@item <command> @expansion{}
+<cli-command> | <mi-command>
+
+@item <cli-command> @expansion{}
+[ <token> ] "any existing GDB CLI command" <nl>
+
+@item <mi-command> @expansion{}
+[ <token> ] ``-'' <operation> ( `` '' <option> )* [ `` --'' ] ( `` '' <parameter> )* <nl>
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@item <option> @expansion{}
+``-'' <parameter> [ `` '' <parameter> ]
+
+@item <parameter> @expansion{}
+<non-blank-sequence> | <c-string>
+
+@item <operation> @expansion{}
+any of the operations described in this document.
+
+@item <non-blank-sequence> @expansion{}
+anything provided it doesn't contain special characters such as ``-''
+ <nl>, ``"'' and of course `` ''.
+
+@item <c-string> @expansion{}
+``"'' <seven-bit-iso-c-string-content> ``"''
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+The CLI commands are still handled by the MI interpreter; their output
+is described below
+
+@item
+The @code{<token>}, when present, is passed back when the command
+finishes.
+
+@item
+Some mi commands accept optional arguments as part of the parameter
+list. Each option is identified by a leading @code{-} (dash) and may be
+followed by an option argument parameter. Options occure first in the
+parameter list and can be delimiated from normal parameters using
+@code{--}.
+
+@end itemize
+
+Pragmatics:
+
+@itemize @bullet
+
+@item
+We want easy access to the existing CLI syntax (for debugging).
+
+@item
+We want it easy to spot a MI operation
+
+@end itemize
+
+@section Output Syntax
+
+The output from GDB/MI consists of zero or more out-of-band records
+followed, optionally, by a single result record. The result record
+being for the most recent command. The sequence of output records is
+terminated by ``(gdb)''.
+
+If an input command was prefixed with a @code{<token>} then the
+corresponding output for that command will also be prefixed by that same
+token.
+
+@table @code
+@item <output> @expansion{}
+( <out-of-band-record> )* [ <result-record> ] ``(gdb)'' <nl>
+
+@item <result-record> @expansion{}
+[ <token> ] ``^'' <result-class> ( ``,'' <result> )* <nl>
+
+@item <out-of-band-record> @expansion{}
+<async-record> | <stream-record>
+
+@item <async-record> @expansion{}
+<exec-async-output> | <status-async-output> | <notify-async-output>
+
+@item <exec-async-output> @expansion{}
+[ <token> ] ``*'' <async-output>
+
+@item <status-async-output> @expansion{}
+[ <token> ] ``+'' <async-output>
+
+@item <notify-async-output> @expansion{}
+[ <token> ] ``='' <async-output>
+
+@item <async-output> @expansion{}
+<async-class> ( ``,'' <result> )* <nl>
+
+@item <result-class> @expansion{}
+``done'' | ``running'' | ``connected'' | ``error'' | ``exit''
+
+@item <async-class> @expansion{}
+``stopped'' | others (depending on needs, still in development)
+
+@item <result> @expansion{}
+[ <string> ``='' ] <value>
+
+@item <value> @expansion{}
+<const> | ``@{'' <result> ( ``,'' <result> )* ``@}''
+
+@item <const> @expansion{}
+<c-string>
+
+@item <stream-record> @expansion{}
+<console-stream-output> | <target-stream-output> | <log-stream-output>
+
+@item <console-stream-output> @expansion{}
+``~'' <c-string>
+
+@item <target-stream-output> @expansion{}
+``@@'' <c-string>
+
+@item <log-stream-output> @expansion{}
+``&'' <c-string>
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@end table
+
+In addition, the following are still being developed.
+
+@table @code
+
+@item <query>
+This action is currently undefined.
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{<token>} is from the corresponding request. If an execution
+command is interrupted by the -exec-interrupt command, the token
+associated with the `*stopped' message is the one of the original
+execution command, not the one of the interrupt-command.
+
+@item
+<status-async-output> contains on-going status information about the progress
+of a slow operation. It can be discarded. All status output is prefixed by
+the prefix `+'.
+
+@item
+<exec-async-output> contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+the prefix `*'.
+
+@item
+<notify-async-output> contains supplementary information that the client should
+handle (new breakpoint information). All notify output is prefixed by
+the prefix `='.
+
+@item
+<console-stream-output> is output that should be displayed as is in the
+console. It is the textual response to a CLI command. All the console
+output is prefixed by the prefix ``~''.
+
+@item
+<target-stream-output> is the output produced by the target program.
+All the target output is prefixed by the prefix ``@@''.
+
+@item
+<log-stream-output> is output text coming from GDB's internals, for
+instance messages that should be displayed as part of an error log. All
+the log output is prefixed by the prefix ``&''.
+
+@end itemize
+
+@section Simple Examples
+
+@subheading Target stop:
+
+@example
+-> -stop
+<- (gdb)
+@end example
+
+(later)
+
+@example
+<- *stop,reason="stop",address="0x123",source="a.c:123"
+<- (gdb)
+@end example
+
+
+@subheading Simple CLI command being passed through the MI and on to the CLI.
+
+@example
+-> print 1+2
+<- ~3\n
+<- (gdb)
+@end example
+
+
+@subheading Command with side effects:
+
+@example
+-> -symbol-file xyz.exe
+<- *breakpoint,nr="3",address="0x123",source="a.c:123"
+<- (gdb)
+@end example
+
+
+@subheading A bad command:
+
+@example
+-> -rubbish
+<- error,"Rubbish not found"
+<- (gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter CLI compatibility
+
+To help users familiar with the GDB's existing CLI interface, the GDB/MI
+will accept existing CLI commands. As specified by the syntax, such
+commands can be directly entered into the MI interface and GDB will
+respond.
+
+The mechanism is provided as an aid to developers of MI clients and not
+as a reliable interface into the CLI. Since the command is being
+interpreteted in an environment that assumes MI behaviour the exact
+output of such commands is likely to end up being an un-supported hybrid
+of MI and CLI output.
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Output Records
+
+@section Result Records
+
+In addition to a number of out-of-band notifications the response to an
+MI command includes one of the following result indications.
+
+@table @code
+
+@item ``^done'' [ ``,'' <results> ]
+The synchronous operation was successful, @code{<results>} is the return
+value.
+
+@item ``^running''
+The asynchronous operation was successfully started. The target is
+running. @emph{Is this one correct should it be an out-of-band
+notification?}
+
+@item ``^error'' ``,'' <c-string>
+The operation failed. The @code{<c-string>} contains the corresponding
+error message.
+
+@end table
+
+@section Stream Records
+
+GDB internally maintains a number of output streams: the console, the
+target, and the log. The output intended for each of these streams is
+tunneled through the MI interface using stream records.
+
+In addition to the prefix each stream record contains a
+@code{<string-output>}. This is either raw text (with an implicit new
+line) or a quoted C string (which does not contain an implicit newline).
+
+@table @code
+
+@item ``~'' <string-output>
+The console output stream contains text that should be displayed in the
+CLI console window. It contains the textual responses to CLI commands.
+
+@item ``@@'' <string-output>
+The target output stream contains any textual output from the running
+target.
+
+@item ``&'' <string-output>
+The LOG stream contains debugging messages being produced by GDB's
+internals.
+
+@end table
+
+@section Out-of-band Records.
+
+Out-of-band records are used to notify the MI client of additional
+changes that have occurred. Those changes can either be a consequence of
+an MI (breakpoint modified) or as a result of target activity (target
+stopped).
+
+The following is a preliminary list of possible out-of-band records.
+
+@table @code
+
+@item ``*'' ``stop''
+
+@end table
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Command Description Format
+
+The remaining chapters describe blocks of commands. Each block of
+commands is laid out in a fashion similar to this chapter.
+
+Note the the line breaks shown in the examples are here only for
+readability. They don't appear in the real output.
+Note that the commands with a non available example (N.A.) are not yet
+implemented.
+
+@section Motivation
+
+What motivates the collection of commands
+
+@section Introduction
+
+Brief introduction to the commands as a whole.
+
+@section Operations
+
+@subsection -command <args>...
+
+@subsubsection Result
+
+@subsubsection Out-of-band
+
+@subsubsection Notes
+
+@subsubsection Example
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Breakpoint table commands
+
+@section -break-after <number> <count>
+The breakpoint number <number> is not in effect until it has been hit <count> times.
+Note how this is reflected in the output of the -break-list command.
+
+@subsection GDB command
+ignore
+
+@subsection Example
+@example
+(gdb)
+-break-insert main
+^done,bkpt=@{number="1",addr="0x000100d0",file="hello.c",line="5"@}
+(gdb)
+-break-after 1 3
+~
+^done
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0",ignore="3"@}@}
+(gdb)
+@end example
+
+@c @section -break-catch
+
+@c @section -break-commands
+
+@section -break-condition <number> <expr>
+Breakpoint <number> will stop the program only if the condition in <expr> is true.
+The condition becomes part of the -break-list output.
+@subsection GDB command
+condition
+@subsection Example
+@example
+(gdb)
+-break-condition 1 1
+^done
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",cond="1",times="0",ignore="3"@}@}
+(gdb)
+@end example
+
+@section -break-delete @{ <breakpoint> @}+
+Delete the breakpoint(s) specified in the argument list. This is
+obviously reflected in the breakpoint list.
+@subsection GDB command
+delete
+@subsection Example
+@example
+(gdb)
+-break-delete 1
+^done
+(gdb)
+-break-list
+^done,BreakpointTable=@{@}
+(gdb)
+@end example
+
+@section -break-disable @{ <breakpoint> @}+
+Disable the breakpoint(s). Note how the field 'enabled' in the break
+list is now set to 'n'.
+@subsection GDB command
+disable
+@subsection Example
+@example
+(gdb)
+-break-disable 2
+^done
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="n",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@}
+(gdb)
+@end example
+
+@section -break-enable @{ <breakpoint> @}+
+Enable a previously disabled breakpoint(s).
+@subsection GDB command
+enable
+@subsection Example
+@example
+(gdb)
+enable 2
+^done
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@}@}
+(gdb)
+@end example
+
+@section -break-info <breakpoint>
+REDUNDANT??? Get information about a single breakpoint.
+@subsection GDB command
+@subsection Example
+N.A.
+
+@section -break-insert [ "-t" ] [ "-h" ] [ "-r" ] [ "-c" <condition> ] [ "-i" <ignore-count> ] [ "-p" <thread> ] [ <line> | <addr> ]
+
+<line>, if specified, accordingly to the gdb manual can be one of:
+@itemize @bullet
+@item function
+@c @item +offset
+@c @item -offset
+@c @item linenum
+@item filename:linenum
+@item filename:function
+@item *address
+@end itemize
+
+The possible forms of this command are:
+
+@table @samp
+@item -t
+Insert a tempoary breakpoint.
+@item -h
+Insert a hardware breakpoint.
+@item -c <condition>
+Make the breakpoint conditional on <condition>
+@item -i <ignore-count>
+Initialize the <ignore-count>
+@item -r
+Insert a regular breakpoint in all the functions whose names match the
+given regular expression. Other flags are not applicable to regular
+expresson.
+@end table
+
+
+The result is in the form:
+
+^done,bkptno="<gdb number for this breakpoint>",func="<name of the
+function where the breakpoint was inserted>",file="<source file which
+contains this function>",line="<source line number within the file>"
+
+Note: this is open to change. An out-of-band breakpoint instead of part
+of the result?
+@subsection GDB command
+break, tbreak, hbreak, thbreak, rbreak.
+@subsection Example
+@example
+(gdb)
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(gdb)
+-break-insert -t foo
+^done,bkpt=@{number="2",addr="0x00010774",file="recursive2.c",line="11"@}
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x0001072c",
+func="main",file="recursive2.c",line="4",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="del",enabled="y",addr="0x00010774",
+func="foo",file="recursive2.c",line="11",times="0"@}@}
+(gdb)
+-break-insert -r foo.*
+~int foo(int, int);
+^done,bkpt=@{number="3",addr="0x00010774",file="recursive2.c",line="11"@}
+(gdb)
+@end example
+
+@section -break-list
+Displays the list of inserted breakpoints, showing the following fields:
+@table @samp
+@item Number
+Number of the breakpoint
+@item Type
+Type of the breakpoint: breakpoint or watchpoint
+@item Disposition
+Should the breakpoint be deleted or disabled when it is hit: keep or nokeep
+@item Enabled
+Is the breakpoint enabled or no: y or n
+@item Address
+Memory location at which the breakpoint is set.
+@item What
+Logical location of the breakpoint, expressed by function name, file name, line number.
+@item times
+Number of times the breakpoint has been hit.
+@end table
+
+If there are no breakpoints or watchpoints, the BreakpointTable field is
+an empty list.
+@subsection GDB command
+info break
+
+@subsection Example 1
+@example
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",
+addr="0x000100d0",func="main",file="hello.c",line="5",times="0"@},
+bkpt=@{number="2",type="breakpoint",disp="keep",enabled="y",
+addr="0x00010114",func="foo",file="hello.c",line="13",times="0"@}@}
+(gdb)
+@end example
+@subsection Example 2
+@example
+(gdb)
+-break-list
+^done,BreakpointTable=@{@}
+(gdb)
+@end example
+
+@section -break-watch [ "-a" | "-r" ]
+Create a watchpoint. With the ``-a'' option it will create an access
+watchpoint, i.e. a watchpoints that triggers either on a read or on a
+write on the memory location. With the ``-r'' option, the watchoint
+created is a read watchpoint, i.e. it will trigger only when the memory
+location os accessed for reading. Without either of the options, the
+watchpoint created is a regular watchpoint, i.e. it will trigger whe the
+memory location is accessed for writing.
+
+Note that ``-break-list'' will report a single list of watchpoints and
+breakpoints inserted.
+
+@subsection GDB command
+watch, awatch, rwatch
+
+@subsection Example 1
+Watchpoint on a variable in main().
+@example
+(gdb)
+-break-watch x
+^done,wpt=@{number="2",exp="x"@}
+(gdb)
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="x"@},
+value=@{old="-268439212",new="55"@},
+frame=@{func="main",args=@{@},file="recursive2.c",line="5"@}
+(gdb)
+@end example
+@subsection Example 2
+Watchpoint on a variable local to a function. Gdb will stop the program execution
+twice: first for the variable changing value, then for the watchpoint going out of scope.
+@example
+(gdb)
+-break-watch C
+^done,wpt=@{number="5",exp="C"@}
+(gdb)
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",
+wpt=@{number="5",exp="C"@},value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=@{@},file="../../../devo/gdb/testsuite/gdb.mi/basics.c",
+line="13"@}
+(gdb)
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="5",
+frame=@{func="callee3",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb)
+@end example
+
+@subsection Example 3
+Listing breakpoints and watchpoints, at different points in the program execution.
+Note that once the watchpoint goes out of scope, it is deleted.
+@example
+(gdb)
+-break-watch C
+^done,wpt=@{number="2",exp="C"@}
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="0"@}@}
+(gdb)
+-exec-continue
+^running
+^done,reason="watchpoint-trigger",wpt=@{number="2",exp="C"@},
+value=@{old="-276895068",new="3"@},
+frame=@{func="callee4",args=@{@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="13"@}
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@},
+bkpt=@{number="2",type="watchpoint",disp="keep",
+enabled="y",addr="",what="C",times="-5"@}@}
+(gdb)
+-exec-continue
+^running
+^done,reason="watchpoint-scope",wpnum="2",
+frame=@{func="callee3",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb)
+-break-list
+^done,BreakpointTable=@{hdr=@{"Num","Type","Disp","Enb","Address","What"@},
+bkpt=@{number="1",type="breakpoint",disp="keep",enabled="y",addr="0x00010734",
+func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8",times="1"@}@}
+(gdb)
+@end example
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Data manipulation
+
+@c REMOVED FROM THE ITNERFACE.
+@c @section -data-assign
+@c Change the value of a program variable. Plenty of side effects.
+@c @subsection GDB command
+@c set variable
+@c @subsection Example
+@c N.A.
+
+@section -data-disassemble <begin> <end> <mode> <number-of-lines>
+Where
+@table @samp
+@item <begin>
+Is a function name or an address (or $pc)
+@item <end>
+can be 0 (in which case the enclosing function will be disassembled), or
+an address.
+@item <mode>
+can be 0 (only disassembly) or 1 (mixed source and disassembly).
+@item <number-of-lines>
+specifies the number of disassembly lines to be produced. If it is -1
+the whole function will be disassembled, in case no <end> address is
+specified. If <end> is specified as a non-zero value, and
+<number-of-lines> is lower that the number of disassembly lines between
+<begin> and <end>, we'll display only <number-of-lines> lines, vice
+versa if <number-of-lines> is higher than the number of lines between
+<begin> and <end>, we'll display only the lines up to <end>.
+@end table
+
+The output for each instruction is composed of two fields:
+@itemize @bullet
+@item Address
+@item Instruction
+@end itemize
+Note that whatever included in those fields, is not manipulated
+directely by Flathead, i.e. it is not possible to adjust their format.
+@subsection GDB command
+N.A. No direct mapping.
+
+@subsection Example 1
+@example
+(gdb)
+-data-disassemble main 0 0 -1
+^done,asm_insns=@{
+@{address="0x100b8 <main>",inst=" stwu r1,-16(r1)"@},
+@{address="0x100bc <main+4>",inst="mflr r0"@},
+@{address="0x100c0 <main+8>",inst=" stw r31,12(r1)"@},
+@{address="0x100c4 <main+12>",inst=" stw r0,20(r1)"@},
+@{address="0x100c8 <main+16>",inst=" mr r31,r1"@},
+@{address="0x100cc <main+20>",inst=" bl0x1013c <__eabi>"@},
+@{address="0x100d0 <main+24>",inst=" lis r9,2"@},
+@{address="0x100d4 <main+28>",inst=" addi r3,r9,-25680"@},
+@{address="0x100d8 <main+32>",inst=" bl 0x10fc8 <printf>"@},
+@{address="0x100dc <main+36>",inst=" bl 0x10100 <foo>"@},
+@{address="0x100e0 <main+40>",inst=" li r3,0"@},
+@{address="0x100e4 <main+44>",inst=" b 0x100e8 <main+48>"@},
+@{address="0x100e8 <main+48>",inst=" lwz r11,0(r1)"@},
+@{address="0x100ec <main+52>",inst=" lwz r0,4(r11)"@},
+@{address="0x100f0 <main+56>",inst=" mtlr r0"@},
+@{address="0x100f4 <main+60>",inst=" lwz r31,-4(r11)"@},
+@{address="0x100f8 <main+64>",inst=" mr r1,r11"@},
+@{address="0x100fc <main+68>",inst=" blr"@}
+(gdb)
+@end example
+
+@subsection Example 2
+@example
+(gdb)
+-data-disassemble main 0 0 3
+^done,asm_insns=@{
+@{address=" 0x100b8 <main>",inst=" stwu r1,-16(r1)"@},
+@{address=" 0x100bc <main+4>",inst="mflr r0"@},
+@{address=" 0x100c0 <main+8>",inst=" stw r31,12(r1)"@}
+(gdb)
+@end example
+
+@subsection Example 3
+@example
+(gdb)
+-data-disassemble foo 0 1 -1
+^done,asm_insns=@{src_and_asm_line=@{line="11",file="hello.c",
+line_asm_insn=@{
+@{address=" 0x10100 <foo>",inst=" stwu r1,-16(r1)"@},
+@{address=" 0x10104 <foo+4>",inst=" mflrr0"@},
+@{address=" 0x10108 <foo+8>",inst=" stw r31,12(r1)"@},
+@{address=" 0x1010c <foo+12>",inst=" stw r0,20(r1)"@},
+@{address=" 0x10110 <foo+16>",inst=" mr r31,r1"@}@}@},
+src_and_asm_line=@{line="12",file="hello.c",
+line_asm_insn=@{
+@{address=" 0x10114 <foo+20>",inst=" lisr9,2"@},
+@{address=" 0x10118 <foo+24>",inst=" addi r3,r9,-25664"@},
+@{address=" 0x1011c <foo+28>",inst=" bl 0x10fc8 <printf>"@}@}@},
+src_and_asm_line=@{line="14",file="hello.c",
+line_asm_insn=@{
+@{address=" 0x10120 <foo+32>",inst=" lwz r11,0(r1)"@},
+@{address=" 0x10124 <foo+36>",inst=" lwz r0,4(r11)"@},
+@{address=" 0x10128 <foo+40>",inst=" mtlr r0"@},
+@{address=" 0x1012c <foo+44>",inst=" lwz r31,-4(r11)"@},
+@{address=" 0x10130 <foo+48>",inst=" mr r1,r11"@},
+@{address=" 0x10134 <foo+52>",inst=" blr"@}@}@}@}
+(gdb)
+@end example
+
+@section -data-evaluate-expression
+Evaluate an expression. The expression could contain an inferior
+function call. The function call will execute synchronously.
+If the expression contains spaces, it must be enclosed in double quotes.
+@subsection GDB command
+print, output, gdb_eval
+@subsection Example
+@example
+211-data-evaluate-expression A
+211^done,value="1"
+(gdb)
+311-data-evaluate-expression &A
+311^done,value="0xefffeb7c"
+(gdb)
+411-data-evaluate-expression A+3
+411^done,value="4"
+(gdb)
+511-data-evaluate-expression "A + 3"
+511^done,value="4"
+(gdb)
+@end example
+
+@section -data-list-changed-registers
+Display a list of the registers that have changed.
+@subsection GDB command
+gdb_changed_register_list. This is in gdbtk only.
+@subsection Example
+On a PPC MBX board.
+@example
+(gdb)
+-exec-continue
+^running
+
+(gdb)
+*stopped,reason="breakpoint-hit",bkptno="1",frame=@{func="main",
+args=@{@},file="try.c",line="5"@}
+(gdb)
+-data-list-changed-registers
+^done,changed-registers=@{"0","1","2","4","5","6","7","8","9",
+"10","11","13","14","15","16","17","18","19","20","21","22","23",
+"24","25","26","27","28","30","31","64","65","66","67","69"@}
+(gdb)
+@end example
+
+@section -data-list-register-names
+Show a list of register names for the current target. If no arguments
+are given, it shows a list of the names of all the registers. If
+integer numbers are given as arguments, it will print a list of the
+names corresponding to the arguments.
+@subsection GDB command
+gdb_regnames
+@subsection Example
+For the PPC MBX board:
+@example
+(gdb)
+-data-list-register-names
+^done,register-names=@{"r0","r1","r2","r3","r4","r5","r6","r7",
+"r8","r9","r10","r11","r12","r13","r14","r15","r16","r17","r18",
+"r19","r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
+"r30","r31","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
+"f10","f11","f12","f13","f14","f15","f16","f17","f18","f19","f20",
+"f21","f22","f23","f24","f25","f26","f27","f28","f29","f30","f31",
+"pc","ps","cr","lr","ctr","xer"@}
+(gdb)
+-data-list-register-names 1 2 3
+^done,register-names=@{"r1","r2","r3"@}
+(gdb)
+@end example
+
+@section -data-list-register-values
+Display the registers contents. Arguments are the format according to
+which the registers contents are to be returned, and a list of numbers
+specifying the registers to display. A missing list of number indicates
+that the contents of all the registers must be returned.
+Allowed formats are:
+@itemize @bullet
+@item 'x': Hexadecimal
+@item 'o': Octal
+@item 't': Binary
+@item 'd': Decimal
+@item 'r': Raw
+@item 'N': Natural
+@end itemize
+
+@subsection GDB command
+info reg, info all-reg AND/OR gdb_fetch_registers
+@subsection Example
+For a PPC MBX board. Note, line breaks are for readability only, they
+don't appear in the actual output.
+@example
+(gdb)
+-data-list-register-values r 64 65
+^done,register-values=@{@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x00029002"@}@}
+(gdb)
+-data-list-register-values x
+^done,register-values=@{@{number="0",value="0xfe0043c8"@},
+@{number="1",value="0x3fff88"@},@{number="2",value="0xfffffffe"@},
+@{number="3",value="0x0"@},@{number="4",value="0xa"@},
+@{number="5",value="0x3fff68"@},@{number="6",value="0x3fff58"@},
+@{number="7",value="0xfe011e98"@},@{number="8",value="0x2"@},
+@{number="9",value="0xfa202820"@},@{number="10",value="0xfa202808"@},
+@{number="11",value="0x1"@},@{number="12",value="0x0"@},
+@{number="13",value="0x4544"@},@{number="14",value="0xffdfffff"@},
+@{number="15",value="0xffffffff"@},@{number="16",value="0xfffffeff"@},
+@{number="17",value="0xefffffed"@},@{number="18",value="0xfffffffe"@},
+@{number="19",value="0xffffffff"@},@{number="20",value="0xffffffff"@},
+@{number="21",value="0xffffffff"@},@{number="22",value="0xfffffff7"@},
+@{number="23",value="0xffffffff"@},@{number="24",value="0xffffffff"@},
+@{number="25",value="0xffffffff"@},@{number="26",value="0xfffffffb"@},
+@{number="27",value="0xffffffff"@},@{number="28",value="0xf7bfffff"@},
+@{number="29",value="0x0"@},@{number="30",value="0xfe010000"@},
+@{number="31",value="0x0"@},@{number="32",value="0x0"@},
+@{number="33",value="0x0"@},@{number="34",value="0x0"@},
+@{number="35",value="0x0"@},@{number="36",value="0x0"@},
+@{number="37",value="0x0"@},@{number="38",value="0x0"@},
+@{number="39",value="0x0"@},@{number="40",value="0x0"@},
+@{number="41",value="0x0"@},@{number="42",value="0x0"@},
+@{number="43",value="0x0"@},@{number="44",value="0x0"@},
+@{number="45",value="0x0"@},@{number="46",value="0x0"@},
+@{number="47",value="0x0"@},@{number="48",value="0x0"@},
+@{number="49",value="0x0"@},@{number="50",value="0x0"@},
+@{number="51",value="0x0"@},@{number="52",value="0x0"@},
+@{number="53",value="0x0"@},@{number="54",value="0x0"@},
+@{number="55",value="0x0"@},@{number="56",value="0x0"@},
+@{number="57",value="0x0"@},@{number="58",value="0x0"@},
+@{number="59",value="0x0"@},@{number="60",value="0x0"@},
+@{number="61",value="0x0"@},@{number="62",value="0x0"@},
+@{number="63",value="0x0"@},@{number="64",value="0xfe00a300"@},
+@{number="65",value="0x29002"@},@{number="66",value="0x202f04b5"@},
+@{number="67",value="0xfe0043b0"@},@{number="68",value="0xfe00b3e4"@},
+@{number="69",value="0x20002b03"@}@}
+(gdb)
+@end example
+
+@section -data-read-memory [ -o <byte-offset> ] [ -- ] <address> <word-format> <word-size> <nr-rows> <nr-cols> [ <aschar> ]
+Where
+@table @samp
+@item <address>
+An expression specifying the address of the first memory word to be
+read. Complex expressions containing embedded white space should be
+quoted using the C convention.
+@item <word-format>
+The format to be used to print the memory words. The notation is the
+same as for GDB's @code{print} command.
+@item <word-size>
+The size of each memory word in bytes.
+@item <nr-rows>
+The number of rows in the output table.
+@item <nr-cols>
+The number of columns in the output table.
+@item <aschar>
+If present, indicates that each row should include an ascii dump. The
+value of <aschar> is used as a padding character when a byte is not a
+member of the printable ascii character set (@code{<32} or @code{>126}).
+@item <byte-offset>
+An offset to add to the <address> before fetching memory.
+@end table
+Display memory contents as a table of <nr-rows> by <nr-cols> words.
+Each word being <word-size> bytes. In total @code{<nr-rows> * <nr-cols>
+* <word-size>} bytes are read (returned as @code{total-bytes}. Should
+less then the requested number of bytes be returned by the target, the
+missing words are identified using @code{N/A}. The number of bytes read
+from the target is returned in @code{nr-bytes} and the starting address
+used to read memory by @code{addr}.
+
+The address of the next/previous page or row is available in
+@code{next-row} and @code{prev-row}, @code{next-page} and
+@code{prev-page}.
+@subsection GDB command
+x AND/OR gdb_get_mem AND/OR GDBtk's memory read.
+@subsection Example 1
+Read six bytes of memory starting at @code{bytes+6} but then offset by
+@code{-6} bytes. Format as three rows of two columns. One byte per
+word. Display each word in hex.
+@example
+(gdb)
+9-data-read-memory -o -6 -- bytes+6 x 1 3 2
+9^done,addr="0x00001390",nr-bytes="6",total-bytes="6",
+next-row="0x00001396",prev-row="0x0000138e",next-page="0x00001396",
+prev-page="0x0000138a",memory=@{
+@{addr="0x00001390",data=@{"0x00","0x01"@}@},
+@{addr="0x00001392",data=@{"0x02","0x03"@}@},
+@{addr="0x00001394",data=@{"0x04","0x05"@}@}@}
+(gdb)
+@end example
+@subsection Example 2
+Read two bytes of memory starting at address @code{shorts + 64} and
+display as a single word formatted in decimal.
+@example
+(gdb)
+5-data-read-memory shorts+64 d 2 1 1
+5^done,addr="0x00001510",nr-bytes="2",total-bytes="2",
+next-row="0x00001512",prev-row="0x0000150e",
+next-page="0x00001512",prev-page="0x0000150e",memory=@{
+@{addr="0x00001510",data=@{"128"@}@}@}
+(gdb)
+@end example
+@subsection Example 3
+Read thirty two bytes of memory starting at @code{bytes+16} and format
+as eight rows of four columns. Include a string encoding with @code{x}
+used as the non-printable character.
+@example
+(gdb)
+4-data-read-memory bytes+16 x 1 8 4 x
+4^done,addr="0x000013a0",nr-bytes="32",total-bytes="32",
+next-row="0x000013c0",prev-row="0x0000139c",
+next-page="0x000013c0",prev-page="0x00001380",memory=@{
+@{addr="0x000013a0",data=@{"0x10","0x11","0x12","0x13"@},ascii="xxxx"@},
+@{addr="0x000013a4",data=@{"0x14","0x15","0x16","0x17"@},ascii="xxxx"@},
+@{addr="0x000013a8",data=@{"0x18","0x19","0x1a","0x1b"@},ascii="xxxx"@},
+@{addr="0x000013ac",data=@{"0x1c","0x1d","0x1e","0x1f"@},ascii="xxxx"@},
+@{addr="0x000013b0",data=@{"0x20","0x21","0x22","0x23"@},ascii=" !\"#"@},
+@{addr="0x000013b4",data=@{"0x24","0x25","0x26","0x27"@},ascii="$%&'"@},
+@{addr="0x000013b8",data=@{"0x28","0x29","0x2a","0x2b"@},ascii="()*+"@},
+@{addr="0x000013bc",data=@{"0x2c","0x2d","0x2e","0x2f"@},ascii=",-./"@}@}
+(gdb)
+@end example
+
+@section -display-delete <number>
+Delete the display <number>.
+@subsection GDB command
+delete display
+@subsection Example
+N.A.
+
+@section -display-disable <number>
+Disable display <number>
+@subsection GDB command
+disable display
+@subsection Example
+N.A.
+
+@section -display-enable <number>
+Enable display <number>
+@subsection GDB command
+enable display
+@subsection Example
+N.A.
+
+@section -display-insert <expression>
+Display <expression> every time the program stops.
+@subsection GDB command
+display
+@subsection Example
+N.A.
+
+@section -display-list
+List the displays. Do not show the current values.
+@subsection GDB command
+info display
+@subsection Example
+N.A.
+
+@section -environment-cd <pathdir>
+Set GDB's working directory.
+@subsection GDB command
+cd
+@subsection Example
+@example
+(gdb)
+-environment-cd /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(gdb)
+@end example
+
+@section -environment-directory <pathdir>
+Add directory <pathdir> to beginning of search path for source files.
+@subsection GDB command
+dir
+@subsection Example
+@example
+(gdb)
+-environment-directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb
+^done
+(gdb)
+@end example
+
+@section -environment-path @{ <pathdir> @}+
+Add directories to beginning of search path for object files.
+@subsection GDB command
+path
+@subsection Example
+@example
+(gdb)
+-environment-path /kwikemart/marge/ezannoni/flathead-dev/ppc-eabi/gdb
+^done
+(gdb)
+@end example
+
+@section -environment-pwd
+Show the current working directory
+@subsection GDB command
+pwd
+@subsection Example
+@example
+(gdb)
+-environment-pwd
+~Working directory /kwikemart/marge/ezannoni/flathead-dev/devo/gdb.
+^done
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Program control
+
+@section Program termination
+As a result of execution, the inferior program can run to completion, if
+it doesn't encouter any breakpoints. In this case the ouput will
+include an exit code, if the program has exited exceptionally.
+@subsection Example 1
+Program exited normally:
+@example
+(gdb)
+-exec-run
+^running
+(gdb)
+x = 55
+*stopped,reason="exited-normally"
+(gdb)
+@end example
+
+@subsection Example 2
+Program exited exceptionally:
+@example
+(gdb)
+-exec-run
+^running
+(gdb)
+x = 55
+*stopped,reason="exited",exit-code="01"
+(gdb)
+@end example
+
+Another way the program can terminate is if it receives a signal like SIGINT.
+@subsection Example
+Program exited with signal (for a more complete example, see the exec-interrupt command).
+@example
+(gdb)
+*stopped,reason="exited-signalled",signal-name="SIGINT",signal-meaning="Interrupt"
+@end example
+
+
+@section -exec-abort
+Kill the inferior running program.
+
+@subsection GDB command
+kill
+
+@subsection Example
+N.A.
+
+@section -exec-arguments
+Set the inferior program arguments, to be used in the next -exec-run.
+
+@subsection GDB command
+set args
+
+@subsection Example
+Don't have it around.
+
+@section -exec-continue
+Asynchronous command. Resumes the execution of the inferior program until
+a breakpoint is encountered, or the inferior exits.
+
+@subsection GDB command
+continue
+
+@subsection Example
+@example
+-exec-continue
+^running
+(gdb)
+@@Hello world
+*stopped,reason="breakpoint-hit",bkptno="2",frame=@{func="foo",args=@{@},
+file="hello.c",line="13"@}
+(gdb)
+@end example
+
+@section -exec-finish
+Asynchronous command. Resumes the execution of the inferior program until the
+current function is exited. Displays the results returned by the function (???).
+
+@subsection GDB command
+finish
+
+@subsection Example 1
+Function returning 'void'.
+@example
+-exec-finish
+^running
+(gdb)
+@@hello from foo
+*stopped,reason="function-finished",frame=@{func="main",args=@{@},
+file="hello.c",line="7"@}
+(gdb)
+@end example
+@subsection Example 2
+Function returning other than 'void'. The name of the internal gdb variable storing the
+result is printed, and the value itself.
+@example
+-exec-finish
+^running
+(gdb)
+*stopped,reason="function-finished",frame=@{addr="0x000107b0",func="foo",
+args=@{@{name="a",value="1"@},@{name="b",value="9"@}@},file="recursive2.c",line="14"@},
+gdb-result-var="$1",return-value="0"
+(gdb)
+
+@end example
+@section -exec-interrupt
+Asynchronous command. Interrupts the background execution of the target.
+Note how the token associated with the stop message is the one for the
+execution command that has been interrupted. The token for the interrupt
+itself only appears in the '^done' output. If the user is trying to
+interrupt a non running program, an error message will be printed.
+@subsection GDB command
+interrupt
+
+@subsection Example
+@example
+(gdb)
+111-exec-continue
+111^running
+
+(gdb)
+222-exec-interrupt
+222^done
+(gdb)
+111*stopped,signal-name="SIGINT",signal-meaning="Interrupt",
+frame=@{addr="0x00010140",func="foo",args=@{@},file="try.c",line="13"@}
+(gdb)
+
+(gdb)
+-exec-interrupt
+^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
+(gdb)
+
+@end example
+
+@section -exec-next
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached.
+
+@subsection GDB command
+next
+
+@subsection Example
+@example
+-exec-next
+^running
+(gdb)
+*stopped,reason="end-stepping-range",line="8",file="hello.c"
+(gdb)
+@end example
+
+@section -exec-next-instruction
+Asynchronous command. Executes one machine instruction. If the
+instruction is a function call continues until the function returns. If
+the program stops at an instruction in the middle of a source line, the
+address will be printed as well.
+@subsection GDB command
+nexti
+
+@subsection Example
+@example
+(gdb)
+-exec-next-instruction
+^running
+
+(gdb)
+*stopped,reason="end-stepping-range",
+addr="0x000100d4",line="5",file="hello.c"
+(gdb)
+@end example
+
+@section -exec-return
+Makes current function return immediately. Doesn't execute the inferior.
+It displays the new current frame.
+
+@subsection GDB command
+return
+
+@subsection Example
+@example
+(gdb)
+200-break-insert callee4
+200^done,bkpt=@{number="1",addr="0x00010734",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(gdb)
+000-exec-run
+000^running
+(gdb)
+000*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="callee4",args=@{@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@}
+(gdb)
+205-break-delete
+205^done
+(gdb)
+111-exec-return
+111^done,frame=@{level="0 ",func="callee3",
+args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@},
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="18"@}
+(gdb)
+@end example
+
+@section -exec-run
+Asynchronous command. Starts execution of the inferior from the
+beginning. The inferior executes until either a breakpoint is
+encountered or the program exits.
+
+@subsection GDB command
+run
+
+@subsection Example
+@example
+(gdb)
+-break-insert main
+^done,bkpt=@{number="1",addr="0x0001072c",file="recursive2.c",line="4"@}
+(gdb)
+-exec-run
+^running
+(gdb)
+*stopped,reason="breakpoint-hit",bkptno="1",
+frame=@{func="main",args=@{@},file="recursive2.c",line="4"@}
+(gdb)
+@end example
+
+
+@section -exec-show-arguments
+Print the arguments of the program.
+@subsection GDB command
+show args
+@subsection Example
+N.A.
+
+@c @section -exec-signal
+
+@section -exec-step
+Asynchronous command. Resumes execution of the inferior program, stopping
+when the beginning of the next source line is reached, if the next
+source line is not a function call. If it is, stop at the first
+instruction of the called function.
+
+@subsection GDB command
+step
+
+@subsection Example 1
+Stepping into a function:
+@example
+-exec-step
+^running
+(gdb)
+*stopped,reason="end-stepping-range",frame=@{func="foo",args=@{@{name="a",value="10"@},
+@{name="b",value="0"@}@},file="recursive2.c",line="11"@}
+(gdb)
+@end example
+@subsection Example 2
+Regular stepping
+@example
+-exec-step
+^running
+(gdb)
+*stopped,reason="end-stepping-range",line="14",file="recursive2.c"
+(gdb)
+@end example
+
+@section -exec-step-instruction
+Asynchronous command. Resumes the inferior which executes one machine
+instruction. The output, once stop, will vary depend on whether we have
+stopped in the middle of a source line or not. In the former case, the
+address at which the program stopped will be printed as well.
+
+@subsection GDB command
+stepi
+
+@subsection Example
+@example
+(gdb)
+-exec-step-instruction
+^running
+
+(gdb)
+*stopped,reason="end-stepping-range",
+frame=@{func="foo",args=@{@},file="try.c",line="10"@}
+(gdb)
+-exec-step-instruction
+^running
+
+(gdb)
+*stopped,reason="end-stepping-range",
+frame=@{addr="0x000100f4",func="foo",args=@{@},file="try.c",line="10"@}
+(gdb)
+@end example
+
+@section -exec-until
+Asynchronous command. Executes the inferior until the location specified
+in the argument is reached. If there is no argument, the inferior
+executes until a source line greater than the current one is reached.
+The reason for stopping in this case will be ``location-reached''.
+@subsection GDB command
+until
+
+@subsection Example
+@example
+(gdb)
+-exec-until recursive2.c:6
+^running
+(gdb)
+x = 55
+*stopped,reason="location-reached",frame=@{func="main",args=@{@},
+file="recursive2.c",line="6"@}
+(gdb)
+@end example
+
+@section -file-clear
+Is this going away????
+
+@section -file-exec-and-symbols <file>
+Specify the executable file to be debugged. This file is the one from
+which the symbol table is also read. If no file is specified, it clears
+the executable and symbol information. If breakpoints are set when
+using this command with no arguments, gdb will produce errors. No output
+is produced, except a completion notification.
+@subsection GDB command
+file <file>
+
+@subsection Example
+@example
+(gdb)
+-file-exec-and-symbols /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb)
+@end example
+
+@section -file-exec-file <file>
+Specify the executable file to be debugged. The symbol table is not read
+from this file. If used without argument gdb clears the information
+about the executable file. No output is produced, except a completion
+notification.
+@subsection GDB command
+exec-file <file>
+
+@subsection Example
+@example
+(gdb)
+-file-exec-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb)
+@end example
+
+@section -file-list-exec-sections
+List the sections of the current executable file.
+@subsection GDB command
+info file (only part of it), gdb_load_info
+@subsection Example
+N.A.
+
+@section -file-list-exec-source-files
+List the source files for the current executable.
+@subsection GDB command
+gdb_listfiles (gdbtk).
+@subsection Example
+N.A.
+
+@section -file-list-shared-libraries
+List the shared libraries in the program.
+@subsection GDB command
+info shared
+@subsection Example
+N.A.
+
+@section -file-list-symbol-files
+List symbol files.
+@subsection GDB command
+info file (part of it).
+@subsection Example
+N.A.
+
+@section -file-symbol-file <file>
+Read symbol table info from the file specified as argument. Used
+without arguments clears gdb's symbol table info. No output is
+produced, except a completion notification.
+@subsection GDB command
+symbol-file <file>
+
+@subsection Example
+@example
+(gdb)
+-file-symbol-file /kwikemart/marge/ezannoni/TRUNK/mbx/hello.mbx
+^done
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Misc GDB commands
+
+@c @section -gdb-complete
+
+@section -gdb-exit
+
+Exit GDB immediately.
+@subsection GDB command
+Approximately corresponds to 'quit'.
+
+@subsection Example
+@example
+(gdb)
+-gdb-exit
+@end example
+
+@section -gdb-set
+Set an internal GDB variable.
+IS THIS A DOLLAR VARIABLE? OR SOMETHING LIKE ANNOTATE ?????
+
+@subsection GDB command
+set
+
+@subsection Example
+@example
+(gdb)
+-gdb-set $foo=3
+^done
+(gdb)
+@end example
+
+@section -gdb-show
+Show the current value of a GDB variable.
+
+@subsection GDB command
+show
+
+@subsection Example
+@example
+(gdb)
+-gdb-show annotate
+^done,value="0"
+(gdb)
+@end example
+
+@c @section -gdb-source
+
+@section -gdb-version
+Show version information for gdb. Used in testing mostly.
+
+@subsection GDB command
+No equivalent.
+
+@subsection Example
+@example
+(gdb)
+-gdb-version
+~GNU gdb 4.18.1 HEADLESS
+~Copyright 1998 Free Software Foundation, Inc.
+~GDB is free software, covered by the GNU General Public License, and you are
+~welcome to change it and/or distribute copies of it under certain conditions.
+~Type "show copying" to see the conditions.
+~There is absolutely no warranty for GDB. Type "show warranty" for details.
+~This GDB was configured as "--host=sparc-sun-solaris2.5.1 --target=ppc-eabi".
+^done
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Kod Commands
+
+The Kod commands are not implemented.
+
+@c @section -kod-info
+
+@c @section -kod-list
+
+@c @section -kod-list-object-types
+
+@c @section -kod-show
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Memory Overlay Commands
+
+the memory overlay commands not implemented.
+
+@c @section -overlay-auto
+
+@c @section -overlay-list-mapping-state
+
+@c @section -overlay-list-overlays
+
+@c @section -overlay-map
+
+@c @section -overlay-off
+
+@c @section -overlay-on
+
+@c @section -overlay-unmap
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Signal Handling Commands
+
+Signal handling commands are not implemented.
+
+@c @section -signal-handle
+
+@c @section -signal-list-handle-actions
+
+@c @section -signal-list-signal-types
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Stack manipulation commands
+
+@section -stack-info-frame
+Get info on the current frame.
+@subsection GDB command
+info frame or frame (w/o args).
+@subsection Example
+N.A.
+
+@section -stack-info-depth [max-depth]
+Return the depth of the stack. If the integer argument <max-depth> is specified, do not
+count beyond max-depth frames.
+@subsection GDB command
+No equivalent.
+@subsection Example
+For a stack with frame levels 0 through 11:
+@example
+(gdb)
+-stack-info-depth
+^done,depth="12"
+(gdb)
+-stack-info-depth 4
+^done,depth="4"
+(gdb)
+-stack-info-depth 12
+^done,depth="12"
+(gdb)
+-stack-info-depth 11
+^done,depth="11"
+(gdb)
+-stack-info-depth 13
+^done,depth="12"
+(gdb)
+@end example
+
+@section -stack-list-arguments <show-values> [ <low-frame> <high-frame> ]
+Display a list of the arguments for the frames between low-frame and
+high-frame (inclusive). If low-frame and high-frame are not provided, it
+will list the arguments for the whole stack. The show-values argument
+must have a value of 0 or 1. A value of 0 means that only the names of
+the arguments are listed, a value of 1 means that both names and values
+of the argumetns are printed.
+@subsection GDB command
+gdb_get_args (partially).
+@subsection Example
+@example
+(gdb)
+-stack-list-frames
+^done,
+stack=@{
+frame=@{level="0 ",addr="0x00010734",func="callee4",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="8"@},
+frame=@{level="1 ",addr="0x0001076c",func="callee3",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="17"@},
+frame=@{level="2 ",addr="0x0001078c",func="callee2",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="22"@},
+frame=@{level="3 ",addr="0x000107b4",func="callee1",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="27"@},
+frame=@{level="4 ",addr="0x000107e0",func="main",
+file="../../../devo/gdb/testsuite/gdb.mi/basics.c",line="32"@}@}
+(gdb)
+-stack-list-arguments 0
+^done,
+stack-args=@{
+frame=@{level="0",args=@{@}@},
+frame=@{level="1",args=@{name="strarg"@}@},
+frame=@{level="2",args=@{name="intarg",name="strarg"@}@},
+frame=@{level="3",args=@{name="intarg",name="strarg",name="fltarg"@}@},
+frame=@{level="4",args=@{@}@}@}
+(gdb)
+-stack-list-arguments 1
+^done,
+stack-args=@{
+frame=@{level="0",args=@{@}@},
+frame=@{level="1",args=@{@{name="strarg",value="0x11940 \"A string argument.\""@}@}@},
+frame=@{level="2",args=@{
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}@}@},
+@{frame=@{level="3",args=@{
+@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@},
+@{name="fltarg",value="3.5"@}@}@},
+frame=@{level="4",args=@{@}@}@}
+(gdb)
+-stack-list-arguments 0 2 2
+^done,stack-args=@{frame=@{level="2",args=@{name="intarg",name="strarg"@}@}@}
+(gdb)
+-stack-list-arguments 1 2 2
+^done,stack-args=@{frame=@{level="2",
+args=@{@{name="intarg",value="2"@},
+@{name="strarg",value="0x11940 \"A string argument.\""@}@}@}@}
+(gdb)
+@end example
+
+@c @section -stack-list-exception-handlers
+
+@section -stack-list-frames [ <low-frame> <high-frame> ]
+List the frames currently on the stack. For each frame it displays the following info:
+@table @samp
+@item <level>
+The frame number, 0 being the topmost frame, i.e. the innermost function.
+@item <addr>
+Pc value for that frame.
+@item <func>
+Function name
+@item <file>
+File name of the source fle where the function lives.
+@item <line>
+Line number corresponding to the pc.
+@end table
+
+If invoked without arguments, it prints a backtrace for the whole stack.
+If given two integer arguments it shows the frames whose levels are
+between the two arguments (inclusive). If the two arguments are equal,
+it shows the single frame at the corresponding level.
+
+@subsection GDB command
+backtrace or where
+
+@subsection Example 1
+Whole stack backtrace.
+
+@example
+(gdb)
+-stack-list-frames
+^done,stack=
+@{frame=@{level="0 ",addr="0x0001076c",func="foo",file="recursive2.c",line="11"@},
+frame=@{level="1 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="2 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="6 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="7 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="8 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="9 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="10",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="11",addr="0x00010738",func="main",file="recursive2.c",line="4"@}@}
+
+(gdb)
+@end example
+
+@subsection Example 2
+Show frames between low_frame and high_frame.
+@example
+(gdb)
+-stack-list-frames 3 5
+^done,stack=
+@{frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="4 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@},
+frame=@{level="5 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@}@}
+(gdb)
+@end example
+@subsection Example 3
+Show one single frame.
+@example
+(gdb)
+-stack-list-frames 3 3
+^done,stack=
+@{frame=@{level="3 ",addr="0x000107a4",func="foo",file="recursive2.c",line="14"@}@}
+(gdb)
+@end example
+
+@section -stack-list-locals <print-values>
+Display the local variables names for the current frame. With an
+argument of 0 prints only the names of the variables, with argument of 1
+prints also the values.
+@subsection GDB command
+gdb_get_locals
+
+@subsection Example
+@example
+(gdb)
+-stack-list-locals 0
+^done,locals=@{name="A",name="B",name="C"@}
+(gdb)
+-stack-list-locals 1
+^done,locals=@{@{name="A",value="1"@},@{name="B",value="2"@},@{name="C",value="3"@}@}
+(gdb)
+@end example
+
+@section -stack-select-frame <framenum>
+Change the current frame. Select a different frame on the stack.
+@subsection GDB command
+frame (part), up, down
+AND/OR select-frame,
+up-silent, down-silent
+@subsection Example
+@example
+(gdb)
+-stack-select-frame 2
+^done
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Symbol query commands
+
+@section -symbol-info-address <symbol>
+Describe where <symbol> is stored.
+@subsection GDB command
+Info address
+@subsection Example
+N.A.
+
+@section -symbol-info-file
+Show the file for the symbol [NOT SURE]
+@subsection GDB command
+gdb_filnd_file (gdbtk).
+@subsection Example
+N.A.
+
+@section -symbol-info-function
+Show which function the symbol lives in. [NOT SURE]
+@subsection GDB command
+gdb_get_function (gdbtk)
+@subsection Example
+N.A.
+
+@section -symbol-info-line
+Core addresses of the code for a source line.
+@subsection GDB command
+info line , gdb_get_line, gdb_get_file
+@subsection Example
+N.A.
+
+@section -symbol-info-symbol
+Describe what symbol is at location ADDR [NOT SURE]
+@subsection GDB command
+info symbol
+@subsection Example
+N.A.
+
+@section -symbol-list-functions
+List the functions in the executable.
+@subsection GDB command
+info functions, gdb_listfunc, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-list-types
+List all the type names.
+@subsection GDB command
+info types, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-list-variables
+List all global and static variable names.
+@subsection GDB command
+Info variables, gdb_search
+@subsection Example
+N.A.
+
+@section -symbol-locate
+@subsection GDB command
+gdb_loc (gdbtk)
+@subsection Example
+N.A.
+
+@section -symbol-type
+Show type of a variable.
+@subsection GDB command
+ptype, gdb_obj_variable
+@subsection Example
+N.A.
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Target manipulation commands
+
+@section -target-attach
+Attach to a process or file outside of GDB.
+@subsection GDB command
+attach
+@subsection Example
+N.A.
+
+@section -target-compare-sections
+Compare section data on target to the exec file.
+@subsection GDB command
+compare-sections
+@subsection Example
+N.A.
+
+@section -target-detach
+Disconnect from the remote target.
+No output.
+
+@subsection GDB command
+detach
+
+@subsection Example
+@example
+(gdb)
+-target-detach
+^done
+(gdb)
+@end example
+
+@section -target-download
+Loads the executable onto the remote target.
+It prints out an update message every half second, which includes the fields:
+@itemize @bullet
+@item section: The name of the section.
+@item section-sent: The size of what has been sent so far for that section.
+@item section-size: The size of the section.
+@item total-sent: The total size of what was sent so far (the current and the previous sections).
+@item total-size: The size of the overall executable to download.
+@end itemize
+Each message is sent as status record.
+
+In addition it prints the name and size of the sections, as they are
+downloaded. These messages include the fields:
+@itemize @bullet
+@item section: The name of the section.
+@item section-size: The size of the section.
+@item total-size: The size of the overall executable to download.
+@end itemize
+At the end a summary is printed.
+@subsection GDB command
+load
+
+@subsection Example
+Note: Each status message appears on a single line. Here the messages
+have been broken down, so they can fit into a page.
+@example
+(gdb)
+-target-download
++download,@{section=".text",section-size="6668",total-size="9880"@}
++download,@{section=".text",section-sent="512",section-size="6668",
+total-sent="512",total-size="9880"@}
++download,@{section=".text",section-sent="1024",section-size="6668",
+total-sent="1024",total-size="9880"@}
++download,@{section=".text",section-sent="1536",section-size="6668",
+total-sent="1536",total-size="9880"@}
++download,@{section=".text",section-sent="2048",section-size="6668",
+total-sent="2048",total-size="9880"@}
++download,@{section=".text",section-sent="2560",section-size="6668",
+total-sent="2560",total-size="9880"@}
++download,@{section=".text",section-sent="3072",section-size="6668",
+total-sent="3072",total-size="9880"@}
++download,@{section=".text",section-sent="3584",section-size="6668",
+total-sent="3584",total-size="9880"@}
++download,@{section=".text",section-sent="4096",section-size="6668",
+total-sent="4096",total-size="9880"@}
++download,@{section=".text",section-sent="4608",section-size="6668",
+total-sent="4608",total-size="9880"@}
++download,@{section=".text",section-sent="5120",section-size="6668",
+total-sent="5120",total-size="9880"@}
++download,@{section=".text",section-sent="5632",section-size="6668",
+total-sent="5632",total-size="9880"@}
++download,@{section=".text",section-sent="6144",section-size="6668",
+total-sent="6144",total-size="9880"@}
++download,@{section=".text",section-sent="6656",section-size="6668",
+total-sent="6656",total-size="9880"@}
++download,@{section=".init",section-size="28",total-size="9880"@}
++download,@{section=".fini",section-size="28",total-size="9880"@}
++download,@{section=".data",section-size="3156",total-size="9880"@}
++download,@{section=".data",section-sent="512",section-size="3156",
+total-sent="7236",total-size="9880"@}
++download,@{section=".data",section-sent="1024",section-size="3156",
+total-sent="7748",total-size="9880"@}
++download,@{section=".data",section-sent="1536",section-size="3156",
+total-sent="8260",total-size="9880"@}
++download,@{section=".data",section-sent="2048",section-size="3156",
+total-sent="8772",total-size="9880"@}
++download,@{section=".data",section-sent="2560",section-size="3156",
+total-sent="9284",total-size="9880"@}
++download,@{section=".data",section-sent="3072",section-size="3156",
+total-sent="9796",total-size="9880"@}
+^done,address="0x10004",load-size="9880",transfer-rate="6586",write-rate="429"
+(gdb)
+@end example
+
+@section -target-exec-status
+Provide information on the state of the target. Whether it is running or not, for instance.
+@subsection GDB command
+No equivalent
+@subsection Example
+N.A.
+
+@section -target-list-available-targets
+List the possible targets to connect to.
+@subsection GDB command
+help target
+@subsection Example
+N.A.
+
+@section -target-list-current-targets
+What the current target is.
+@subsection GDB command
+info file (part of it).
+@subsection Example
+N.A.
+
+@section -target-list-parameters
+????
+@subsection GDB command
+No equivalent
+@subsection Example
+N.A.
+
+@section -target-select
+Connect GDB to the remote target.
+It takes two args:
+
+-target-select <type> <parameters>.
+
+Where:
+
+@table @samp
+@item <type>
+The type of target, for instance async, remote, etc.
+@item <parameters>
+Device names, host names and the like.
+@end table
+The output is a connection notification, followed by the address at
+which the target program is, in the following form:
+^connected,addr="<address>",func="<function name>",args=@{<arg list>@}
+
+@subsection GDB command
+target
+
+@subsection Example
+@example
+(gdb)
+-target-select async /dev/ttya
+^connected,addr="0xfe00a300",func="??",args=@{@}
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Thread commands
+
+@section -thread-info
+@subsection GDB command
+@subsection Example
+
+@section -thread-list-all-threads
+@subsection GDB command
+@subsection Example
+
+@section -thread-list-ids
+Produces a list of the currently known gdb thread ids. At the end of the
+list it also prints the toal number of such threads.
+@subsection GDB command
+None equivalent. (Maybe part of info threads).
+@subsection Example 1
+No threads present, besides the main process.
+@example
+(gdb)
+-thread-list-ids
+^done,thread-ids=@{@},number-of-threads="0"
+(gdb)
+@end example
+@subsection Example 2
+Several threads.
+@example
+(gdb)
+-thread-list-ids
+^done,thread-ids=@{thread-id="3",thread-id="2",thread-id="1"@},
+number-of-threads="3"
+(gdb)
+@end example
+
+@section -thread-select <threadnum>
+Make <threadnum> the current thread. It prints the number of the new
+current thread, and the topmost frame for that thread.
+@subsection GDB command
+thread
+@subsection Example
+@example
+(gdb)
+-exec-next
+^running
+(gdb)
+*stopped,reason="end-stepping-range",thread-id="2",line="187",
+file="../../../devo/gdb/testsuite/gdb.threads/linux-dp.c"
+(gdb)
+-thread-list-ids
+^done,
+thread-ids={thread-id="3",thread-id="2",thread-id="1"},
+number-of-threads="3"
+(gdb)
+-thread-select 3
+^done,new-thread-id="3",
+frame=@{level="0 ",func="vprintf",
+args=@{@{name="format",value="0x8048e9c \"%*s%c %d %c\\n\""@},
+@{name="arg",value="0x2"@}@},file="vprintf.c",line="31"@}
+(gdb)
+@end example
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Tracepoint Commands
+
+The tracepoint commands are not implemented.
+
+@c @section -trace-actions
+
+@c @section -trace-delete
+
+@c @section -trace-disable
+
+@c @section -trace-dump
+
+@c @section -trace-enable
+
+@c @section -trace-exists
+
+@c @section -trace-find
+
+@c @section -trace-frame-number
+
+@c @section -trace-info
+
+@c @section -trace-insert
+
+@c @section -trace-list
+
+@c @section -trace-pass-count
+
+@c @section -trace-save
+
+@c @section -trace-start
+
+@c @section -trace-stop
+
+
+@c %%%%%%%%%%%%%%%%%%%%%%%%%%%% CHAPTER %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@chapter Variable Objects
+
+@section Motivation
+
+For the implementation of a variable debugger window (locals, watched
+expressions, etc.), we are proposing the adaptation of the existent code
+used by Insight.
+
+The two main reason for that are:
+
+@enumerate 1
+@item
+It has been proven in practice (it is already on it's second generation)
+@item
+It will shorten development time (needless to say how important it is
+now)
+@end enumerate
+
+The original interface was designed to be used by Tcl code, so it was
+slightly changed so it can be used through flathead. This document
+describes the flathead operations that will be available and gives some
+hints about its use.
+
+@emph{Note}: In addition to the set of operations described here, we
+expect the GUI implementation of a variable window to require, at least,
+the following operations:
+@itemize bullet
+@item -gdb-show output-radix
+@item -stack-list-arguments
+@item -stack-list-locals
+@item -stack-select-frame
+@end itemize
+
+@section Introduction
+
+The basic idea behind variable objects is the creation of a named object
+to represent a variable, an expression, a memory location or even a CPU
+register. For each object created, a set of operations is available for
+examining or changing its properties.
+
+Furthermore, complex data types, such as C structures, are represented
+in a tree format. For instance, the struct type variable is the root
+and the children will represent the struct members. If a children is
+itself of a complex type, it will also have children of its own.
+Appropriate language differences are handled for C, C++ and Java.
+
+When returning the actual values of the objects, this facility allows
+for the individual selection of the display format used in the result
+creation. It can be chosen among: binary, decimal, hexadecimal, octal
+and natural. Natural refers to the a default format automatically chosen
+based on the variable type (like decimal for int, hex for pointers,
+etc.).
+
+The following is the complete set of flathead operations defined to
+access this functionality:
+
+@multitable @columnfractions .3 .6
+@item @strong{Operation}
+@tab @strong{Description}
+
+@item -var-create
+@tab create a variable object
+@item -var-delete
+@tab delete the variable object and its children
+@item -var-set-format
+@tab set the display format of this variable
+@item -var-show-format
+@tab show the display format of this variable
+@item -var-info-num-children
+@tab tells how many children this object has
+@item -var-list-children
+@tab return a list of the object's children
+@item -var-info-type
+@tab show the type of this variable object
+@item -var-info-expression
+@tab print what this variable object represents
+@item -var-show-attributes
+@tab is this variable editable? does it exist here?
+@item -var-evaluate-expression
+@tab get the value of this variable
+@item -var-assign
+@tab set the value of this variable
+@item -var-update
+@tab update the variable and its children
+@end multitable
+
+In the next section we describe each operation in detail and suggest how
+it can be used.
+
+
+@section Operations Description And Use
+
+@subsection -var-create @{<name> | '-'@} @{<frame-addr> | '*'@} <expression>
+
+This operation creates a variable object, which allows the monitoring of
+a variable, the result of an expression, a memory cell or a CPU
+register.
+
+The <name> parameter is the string by which the object can be
+referenced. It must be unique. If '-' is specified, the varobj system
+will generate a string "varNNNNNN" automatically. It will be unique
+provided that one does not specify <name> on that format. The command
+fails if a duplicate name is found.
+
+The frame under which the expression should be evaluated can be
+specified. A '*' indicates that the current frame should be used.
+
+Expression is any expression valid on the current language set (must not
+begin with '*') or: *<addr> - The address of a memory cell
+*<addr>-<addr> - An memory address range (TBD) $<regname> - A CPU
+register
+
+This operation returns the name, number of children and the type of the
+object created. Type is returned as a string as the ones generated by
+gdb CLI.
+
+name="<name>",numchild="N",type="<type>"
+
+@subsection -var-delete <name>
+
+Deletes a previously created variable object and all of it's children.
+
+Returns an error if the object <name> is not found.
+
+@subsection -var-set-format <name> <format-spec>
+
+Sets the output format for the value of the object.
+
+<format-spec> = @{binary | decimal | hexadecimal | octal | natural@}
+
+@subsection -var-show-format <name>
+
+Returns the format used to display the value of the object.
+
+format="<format-spec>"
+
+@subsection -var-info-num-children <name>
+
+Returns the number of children of a variable object.
+
+numchild="N"
+
+@subsection -var-list-children <name>
+
+Returns a list of the children of the specified variable object.
+
+numchild="N",children=@{@{name="<name>",numchild="N",type="<type>"@},(repeats N times)@}
+
+@subsection -var-info-type <name>
+
+Returns the type of the specified variable. The type is returned as a
+string in the same format as it is output by gdb's CLI.
+
+type="<type>"
+
+@subsection -var-info-expression <name>
+
+Returns what is represented by the specified variable object.
+
+lang="<lang-spec>",exp="<expression>"
+
+where <lang-spec> = @{"C" | "C++" | "Java"@}
+
+@subsection -var-show-attributes <name>
+
+List attributes of the specified variable object.
+
+status="<attr>[,<attr>]*"
+
+where <attr> = @{ @{ editable | noneditable @} | TBD @}
+
+@subsection -var-evaluate-expression <name>
+
+Evaluates the expression that is represented by the specified variable
+object and returns its value as a string in the current format specified
+for the object.
+
+value="<value>"
+
+@subsection -var-assign <name> <expression>
+
+Assigns a new value for the variable object specified. The object must
+be "editable".
+
+@subsection -var-update @{<name> | '*'@}
+
+Update the value of the variable object by evaluating its expression
+after fetching all the new values from memory or registers. A '*'
+causes all existing variable objects to be updated.
+
+
+@c%%%%%%%%%%%%%%%%%%%%%%%%%%%% APPENDIX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@appendix Proposed v2.0 Output Syntax
+
+This appendix is not part of the MI specification. It is provided as a
+discussion point.
+
+The output from GDB/MI consists of zero or more out-of-band records
+optionally followed by a single result record. The result record being
+for the most recent command input. The sequence being terminated by
+``(gdb)''.
+
+Asynchronous GDB/MI output is similar.
+
+Each output record directly associated with an input command is prefixed
+by the input commands @code{<token>}.
+
+@table @code
+@item <output> @expansion{}
+@{ <out-of-band-record> @} [ <result-record> ] ``(gdb)'' <nl>
+
+@item <result-record> @expansion{}
+[ <token> ] ``^'' <result-class> @{ ``,'' <result> @} <nl>
+
+@item <out-of-band-record> @expansion{}
+<async-record> | <stream-record>
+
+@item <async-record> @expansion{}
+<exec-async-output> | <status-async-output> | <notify-async-output>
+
+@item <exec-async-output> @expansion{}
+[ <token> ] ``*'' <async-output>
+
+@item <status-async-output> @expansion{}
+[ <token> ] ``+'' <async-output>
+
+@item <notify-async-output> @expansion{}
+[ <token> ] ``='' <async-output>
+
+@item <async-output> @expansion{}
+<async-class> @{ ``,'' <result> @} <nl>
+
+@item <result-class> @expansion{}
+``done'' | ``running'' | ``connected'' | ``error'' | ``exit''
+
+@item <async-class> @expansion{}
+``stopped'' | @emph{others depending on need as still in development}
+
+@item <result> @expansion{}
+<string> ``='' <value>
+
+@item <value> @expansion{}
+<c-string> | <tupple> | <list>
+
+@item <tupple> @expansion{}
+``@{@}'' | ``@{'' <result> @{ ``,'' <result> @} ``@}''
+
+@item <list> @expansion{}
+``[]'' | ``['' <value> @{ ``,'' <value> @} ``]''
+
+@item <string> @expansion{}
+@emph{[-A-Za-z\.0-9_]*}
+
+@item <c-string> @expansion{}
+@emph{See the input specification}
+
+@item <stream-record> @expansion{}
+<console-stream-output> | <target-stream-output> | <log-stream-output>
+
+@item <console-stream-output> @expansion{}
+``~'' <c-string>
+
+@item <target-stream-output> @expansion{}
+``@@'' <c-string>
+
+@item <log-stream-output> @expansion{}
+``&'' <c-string>
+
+@item <nl> @expansion{}
+CR | CR-LF
+
+@item <token> @expansion{}
+``any sequence of digits''
+
+@end table
+
+In addition, the following are still being developed.
+
+@table @code
+
+@item <query>
+This action is currently undefined.
+
+@end table
+
+Notes:
+
+@itemize @bullet
+
+@item
+All output sequences end in a single line containing a period.
+
+@item
+The @code{<token>} is from the corresponding request. If an execution
+command is interrupted by the -exec-interrupt command, the token
+associated with the `*stopped' message is the one of the original
+execution command, not the one of the interrupt-command.
+
+@item
+<status-async-output> contains on-going status information about the progress
+of a slow operation. It can be discarded. All status output is prefixed by
+the prefix `+'.
+
+@item
+<exec-async-output> contains asynchronous state change on the target
+(stopped, started, disappeared). All async output is prefixed by
+the prefix `*'.
+
+@item
+<notify-async-output> contains supplementary information that the client should
+handle (new breakpoint information). All notify output is prefixed by
+the prefix `='.
+
+@item
+<console-stream-output> is output that should be displayed as is in the
+console. It is the textual response to a CLI command. All the console
+output is prefixed by the prefix ``~''.
+
+@item
+<target-stream-output> is the output produced by the target program.
+All the target output is prefixed by the prefix ``@@''.
+
+@item
+<log-stream-output> is output text coming from GDB's internals, for
+instance messages that should be displayed as part of an error log. All
+the log output is prefixed by the prefix ``&''.
+
+@end itemize
+
+
+@c Local variables:
+@c change-log-default-name: "ChangeLog-mi"
+@c End:
+@bye
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
new file mode 100644
index 00000000000..d366531bf56
--- /dev/null
+++ b/gdb/mi/mi-cmd-break.c
@@ -0,0 +1,253 @@
+/* MI Command Set - breakpoint and watchpoint commands.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "breakpoint.h"
+#include "gdb_string.h"
+#include "mi-getopt.h"
+#include "gdb-events.h"
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+enum
+ {
+ FROM_TTY = 0
+ };
+
+/* Output a single breakpoint. */
+
+static void
+breakpoint_notify (int b)
+{
+ gdb_breakpoint_query (b);
+}
+
+
+struct gdb_events breakpoint_hooks =
+{
+ breakpoint_notify,
+ breakpoint_notify,
+ breakpoint_notify,
+};
+
+
+enum bp_type
+ {
+ REG_BP,
+ HW_BP,
+ REGEXP_BP
+ };
+
+/* Insert a breakpoint. The type of breakpoint is specified by the
+ first argument: -break-insert <location> --> insert a regular
+ breakpoint. -break-insert -t <location> --> insert a temporary
+ breakpoint. -break-insert -h <location> --> insert an hardware
+ breakpoint. -break-insert -t -h <location> --> insert a temporary
+ hw bp.
+ -break-insert -r <regexp> --> insert a bp at functions matching
+ <regexp> */
+
+enum mi_cmd_result
+mi_cmd_break_insert (char *command, char **argv, int argc)
+{
+ char *address = NULL;
+ enum bp_type type = REG_BP;
+ int temp_p = 0;
+ int thread = -1;
+ int ignore_count = 0;
+ char *condition = NULL;
+ enum gdb_rc rc;
+ struct gdb_events *old_hooks;
+ enum opt
+ {
+ HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
+ IGNORE_COUNT_OPT, THREAD_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"h", HARDWARE_OPT, 0},
+ {"t", TEMP_OPT, 0},
+ {"c", CONDITION_OPT, 1},
+ {"i", IGNORE_COUNT_OPT, 1},
+ {"p", THREAD_OPT, 1},
+ 0
+ };
+
+ /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
+ to denote the end of the option list. */
+ int optind = 0;
+ char *optarg;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_break_insert", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case TEMP_OPT:
+ temp_p = 1;
+ break;
+ case HARDWARE_OPT:
+ type = HW_BP;
+ break;
+#if 0
+ case REGEXP_OPT:
+ type = REGEXP_BP;
+ break;
+#endif
+ case CONDITION_OPT:
+ condition = optarg;
+ break;
+ case IGNORE_COUNT_OPT:
+ ignore_count = atol (optarg);
+ break;
+ case THREAD_OPT:
+ thread = atol (optarg);
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ error ("mi_cmd_break_insert: Missing <location>");
+ if (optind < argc - 1)
+ error ("mi_cmd_break_insert: Garbage following <location>");
+ address = argv[optind];
+
+ /* Now we have what we need, let's insert the breakpoint! */
+ old_hooks = set_gdb_event_hooks (&breakpoint_hooks);
+ switch (type)
+ {
+ case REG_BP:
+ rc = gdb_breakpoint (address, condition,
+ 0 /*hardwareflag */ , temp_p,
+ thread, ignore_count);
+ break;
+ case HW_BP:
+ rc = gdb_breakpoint (address, condition,
+ 1 /*hardwareflag */ , temp_p,
+ thread, ignore_count);
+ break;
+#if 0
+ case REGEXP_BP:
+ if (temp_p)
+ error ("mi_cmd_break_insert: Unsupported tempoary regexp breakpoint");
+ else
+ rbreak_command_wrapper (address, FROM_TTY);
+ return MI_CMD_DONE;
+ break;
+#endif
+ default:
+ internal_error ("mi_cmd_break_insert: Bad switch.");
+ }
+ set_gdb_event_hooks (old_hooks);
+
+ if (rc == GDB_RC_FAIL)
+ return MI_CMD_CAUGHT_ERROR;
+ else
+ return MI_CMD_DONE;
+}
+
+enum wp_type
+{
+ REG_WP,
+ READ_WP,
+ ACCESS_WP
+};
+
+/* Insert a watchpoint. The type of watchpoint is specified by the
+ first argument:
+ -break-watch <expr> --> insert a regular wp.
+ -break-watch -r <expr> --> insert a read watchpoint.
+ -break-watch -a <expr> --> insert an access wp. */
+
+enum mi_cmd_result
+mi_cmd_break_watch (char *command, char **argv, int argc)
+{
+ char *expr = NULL;
+ enum wp_type type = REG_WP;
+ enum opt
+ {
+ READ_OPT, ACCESS_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"r", READ_OPT, 0},
+ {"a", ACCESS_OPT, 0},
+ 0
+ };
+
+ /* Parse arguments. */
+ int optind = 0;
+ char *optarg;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_break_watch", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case READ_OPT:
+ type = READ_WP;
+ break;
+ case ACCESS_OPT:
+ type = ACCESS_WP;
+ break;
+ }
+ }
+ if (optind >= argc)
+ error ("mi_cmd_break_watch: Missing <expression>");
+ if (optind < argc - 1)
+ error ("mi_cmd_break_watch: Garbage following <expression>");
+ expr = argv[optind];
+
+ /* Now we have what we need, let's insert the watchpoint! */
+ switch (type)
+ {
+ case REG_WP:
+#ifdef UI_OUT
+ watch_command_wrapper (expr, FROM_TTY);
+#endif
+ break;
+ case READ_WP:
+#ifdef UI_OUT
+ rwatch_command_wrapper (expr, FROM_TTY);
+#endif
+ break;
+ case ACCESS_WP:
+#ifdef UI_OUT
+ awatch_command_wrapper (expr, FROM_TTY);
+#endif
+ break;
+ default:
+ error ("mi_cmd_break_watch: Unknown watchpoint type.");
+ }
+ return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-disas.c b/gdb/mi/mi-cmd-disas.c
new file mode 100644
index 00000000000..9bbc9ef0c38
--- /dev/null
+++ b/gdb/mi/mi-cmd-disas.c
@@ -0,0 +1,499 @@
+/* MI Command Set - disassemble commands.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "target.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "mi-getopt.h"
+#include "ui-out.h"
+
+static int gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, int len,
+ disassemble_info * info);
+static int compare_lines (const PTR mle1p, const PTR mle2p);
+
+/* Disassemble functions. FIXME: these do not really belong here. We
+ should get rid of all the duplicate code in gdb that does the same
+ thing: disassemble_command() and the gdbtk variation. */
+
+/* This Structure is used in mi_cmd_disassemble.
+ We need a different sort of line table from the normal one cuz we can't
+ depend upon implicit line-end pc's for lines to do the
+ reordering in this function. */
+
+struct dis_line_entry
+ {
+ int line;
+ CORE_ADDR start_pc;
+ CORE_ADDR end_pc;
+ };
+
+/* This variable determines where memory used for disassembly is read from. */
+int gdb_disassemble_from_exec = -1;
+
+/* This is the memory_read_func for gdb_disassemble when we are
+ disassembling from the exec file. */
+static int
+gdb_dis_asm_read_memory (bfd_vma memaddr, bfd_byte * myaddr, int len, disassemble_info * info)
+{
+ extern struct target_ops exec_ops;
+ int res;
+
+ errno = 0;
+ res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
+
+ if (res == len)
+ return 0;
+ else if (errno == 0)
+ return EIO;
+ else
+ return errno;
+}
+
+static int
+compare_lines (const PTR mle1p, const PTR mle2p)
+{
+ struct dis_line_entry *mle1, *mle2;
+ int val;
+
+ mle1 = (struct dis_line_entry *) mle1p;
+ mle2 = (struct dis_line_entry *) mle2p;
+
+ val = mle1->line - mle2->line;
+
+ if (val != 0)
+ return val;
+
+ return mle1->start_pc - mle2->start_pc;
+}
+
+/* The arguments to be passed on the command line and parsed here are:
+
+ either:
+
+ START-ADDRESS: address to start the disassembly at.
+ END-ADDRESS: address to end the disassembly at.
+
+ or:
+
+ FILENAME: The name of the file where we want disassemble from.
+ LINE: The line around which we want to disassemble. It will
+ disassemble the function that contins that line.
+ HOW_MANY: Number of disassembly lines to display. In mixed mode, it
+ is the number of disassembly lines only, not counting the source
+ lines.
+
+ always required:
+
+ MODE: 0 or 1 for disassembly only, or mixed source and disassembly,
+ respectively. */
+
+enum mi_cmd_result
+mi_cmd_disassemble (char *command, char **argv, int argc)
+{
+ CORE_ADDR pc;
+ CORE_ADDR start;
+ CORE_ADDR low = 0;
+ CORE_ADDR high = 0;
+
+ int how_many = -1;
+ int mixed_source_and_assembly;
+ int num_displayed;
+ int line_num;
+
+ char *file_string;
+ static disassemble_info di;
+ static int di_initialized;
+
+ struct symtab *s;
+
+ /* To collect the instruction outputted from opcodes. */
+ static struct ui_stream *stb = NULL;
+
+ /* parts of the symbolic representation of the address */
+ int line;
+ int offset;
+ int unmapped;
+ char *filename = NULL;
+ char *name = NULL;
+
+ /* Which options have we processed? */
+ int file_seen = 0;
+ int line_seen = 0;
+ int num_seen = 0;
+ int start_seen = 0;
+ int end_seen = 0;
+
+ /* Options processing stuff. */
+ int optind = 0;
+ char *optarg;
+ enum opt
+ {
+ FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"f", FILE_OPT, 1},
+ {"l", LINE_OPT, 1},
+ {"n", NUM_OPT, 1},
+ {"s", START_OPT, 1},
+ {"e", END_OPT, 1},
+ 0
+ };
+
+ /* Get the options with their arguments. Keep track of what we
+ encountered. */
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_disassemble", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case FILE_OPT:
+ file_string = xstrdup (optarg);
+ file_seen = 1;
+ break;
+ case LINE_OPT:
+ line_num = atoi (optarg);
+ line_seen = 1;
+ break;
+ case NUM_OPT:
+ how_many = atoi (optarg);
+ num_seen = 1;
+ break;
+ case START_OPT:
+ low = parse_and_eval_address (optarg);
+ start_seen = 1;
+ break;
+ case END_OPT:
+ high = parse_and_eval_address (optarg);
+ end_seen = 1;
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ /* Allow only filename + linenum (with how_many which is not
+ required) OR start_addr + and_addr */
+
+ if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
+ || (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
+ || (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
+ error ("mi_cmd_disassemble: Usage: ( [-f filename -l linenum [-n howmany]] | [-s startaddr -e endaddr]) [--] mixed_mode.");
+
+ if (argc != 1)
+ error ("mi_cmd_disassemble: Usage: [-f filename -l linenum [-n howmany]] [-s startaddr -e endaddr] [--] mixed_mode.");
+
+ mixed_source_and_assembly = atoi (argv[0]);
+ if ((mixed_source_and_assembly != 0) && (mixed_source_and_assembly != 1))
+ error ("mi_cmd_disassemble: Mixed_mode argument must be 0 or 1.");
+
+ /* We must get the function beginning and end where line_num is
+ contained. */
+
+ if (line_seen && file_seen)
+ {
+ s = lookup_symtab (file_string);
+ if (s == NULL)
+ error ("mi_cmd_disassemble: Invalid filename.");
+ if (!find_line_pc (s, line_num, &start))
+ error ("mi_cmd_disassemble: Invalid line number");
+ if (find_pc_partial_function (start, NULL, &low, &high) == 0)
+ error ("mi_cmd_disassemble: No function contains specified address");
+ }
+
+ if (!di_initialized)
+ {
+ /* We don't add a cleanup for this, because the allocation of
+ the stream is done once only for each gdb run, and we need to
+ keep it around until the end. Hopefully there won't be any
+ errors in the init code below, that make this function bail
+ out. */
+ stb = ui_out_stream_new (uiout);
+ INIT_DISASSEMBLE_INFO_NO_ARCH (di, stb->stream,
+ (fprintf_ftype) fprintf_unfiltered);
+ di.flavour = bfd_target_unknown_flavour;
+ di.memory_error_func = dis_asm_memory_error;
+ di.print_address_func = dis_asm_print_address;
+ di_initialized = 1;
+ }
+
+ di.mach = TARGET_PRINT_INSN_INFO->mach;
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ di.endian = BFD_ENDIAN_BIG;
+ else
+ di.endian = BFD_ENDIAN_LITTLE;
+
+ /* If gdb_disassemble_from_exec == -1, then we use the following heuristic to
+ determine whether or not to do disassembly from target memory or from the
+ exec file:
+
+ If we're debugging a local process, read target memory, instead of the
+ exec file. This makes disassembly of functions in shared libs work
+ correctly. Also, read target memory if we are debugging native threads.
+
+ Else, we're debugging a remote process, and should disassemble from the
+ exec file for speed. However, this is no good if the target modifies its
+ code (for relocation, or whatever).
+ */
+
+ if (gdb_disassemble_from_exec == -1)
+ {
+ if (strcmp (target_shortname, "child") == 0
+ || strcmp (target_shortname, "procfs") == 0
+ || strcmp (target_shortname, "vxprocess") == 0
+ || strstr (target_shortname, "-threads") != NULL)
+ gdb_disassemble_from_exec = 0; /* It's a child process, read inferior mem */
+ else
+ gdb_disassemble_from_exec = 1; /* It's remote, read the exec file */
+ }
+
+ if (gdb_disassemble_from_exec)
+ di.read_memory_func = gdb_dis_asm_read_memory;
+ else
+ di.read_memory_func = dis_asm_read_memory;
+
+ /* If just doing straight assembly, all we need to do is disassemble
+ everything between low and high. If doing mixed source/assembly,
+ we've got a totally different path to follow. */
+
+ if (mixed_source_and_assembly)
+ {
+ /* Come here for mixed source/assembly */
+ /* The idea here is to present a source-O-centric view of a
+ function to the user. This means that things are presented
+ in source order, with (possibly) out of order assembly
+ immediately following. */
+ struct symtab *symtab;
+ struct linetable_entry *le;
+ int nlines;
+ int newlines;
+ struct dis_line_entry *mle;
+ struct symtab_and_line sal;
+ int i;
+ int out_of_order;
+ int next_line;
+
+ /* Assume symtab is valid for whole PC range */
+ symtab = find_pc_symtab (low);
+
+ if (!symtab || !symtab->linetable)
+ goto assembly_only;
+
+ /* First, convert the linetable to a bunch of my_line_entry's. */
+
+ le = symtab->linetable->item;
+ nlines = symtab->linetable->nitems;
+
+ if (nlines <= 0)
+ goto assembly_only;
+
+ mle = (struct dis_line_entry *) alloca (nlines * sizeof (struct dis_line_entry));
+
+ out_of_order = 0;
+
+ /* Copy linetable entries for this function into our data
+ structure, creating end_pc's and setting out_of_order as
+ appropriate. */
+
+ /* First, skip all the preceding functions. */
+
+ for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
+
+ /* Now, copy all entries before the end of this function. */
+
+ newlines = 0;
+ for (; i < nlines - 1 && le[i].pc < high; i++)
+ {
+ if (le[i].line == le[i + 1].line
+ && le[i].pc == le[i + 1].pc)
+ continue; /* Ignore duplicates */
+
+ mle[newlines].line = le[i].line;
+ if (le[i].line > le[i + 1].line)
+ out_of_order = 1;
+ mle[newlines].start_pc = le[i].pc;
+ mle[newlines].end_pc = le[i + 1].pc;
+ newlines++;
+ }
+
+ /* If we're on the last line, and it's part of the function,
+ then we need to get the end pc in a special way. */
+
+ if (i == nlines - 1
+ && le[i].pc < high)
+ {
+ mle[newlines].line = le[i].line;
+ mle[newlines].start_pc = le[i].pc;
+ sal = find_pc_line (le[i].pc, 0);
+ mle[newlines].end_pc = sal.end;
+ newlines++;
+ }
+
+ /* Now, sort mle by line #s (and, then by addresses within
+ lines). */
+
+ if (out_of_order)
+ qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
+
+ /* Now, for each line entry, emit the specified lines (unless
+ they have been emitted before), followed by the assembly code
+ for that line. */
+
+ next_line = 0; /* Force out first line */
+ ui_out_list_begin (uiout, "asm_insns");
+ num_displayed = 0;
+ for (i = 0; i < newlines; i++)
+ {
+ int close_list = 1;
+ /* Print out everything from next_line to the current line. */
+ if (mle[i].line >= next_line)
+ {
+ if (next_line != 0)
+ {
+ /* Just one line to print. */
+ if (next_line == mle[i].line)
+ {
+ ui_out_list_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ else
+ {
+ /* Several source lines w/o asm instructions associated. */
+ for (; next_line < mle[i].line; next_line++)
+ {
+ ui_out_list_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ ui_out_list_begin (uiout, "line_asm_insn");
+ ui_out_list_end (uiout);
+ ui_out_list_end (uiout);
+ }
+ /* Print the last line and leave list open for
+ asm instructions to be added. */
+ ui_out_list_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, next_line, mle[i].line + 1, 0);
+ }
+ }
+ else
+ {
+ ui_out_list_begin (uiout, "src_and_asm_line");
+ print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
+ }
+
+ next_line = mle[i].line + 1;
+ ui_out_list_begin (uiout, "line_asm_insn");
+ if (i + 1 < newlines && mle[i + 1].line <= mle[i].line)
+ close_list = 0;
+ }
+ for (pc = mle[i].start_pc; pc < mle[i].end_pc;)
+ {
+ QUIT;
+ if (how_many >= 0)
+ {
+ if (num_displayed >= how_many)
+ break;
+ else
+ num_displayed++;
+ }
+ ui_out_list_begin (uiout, NULL);
+ print_address_numeric (pc, 1, stb->stream);
+ ui_out_field_stream (uiout, "address", stb);
+
+ if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
+ {
+ /* We don't care now about line, filename and
+ unmapped, but we might in the future. */
+ ui_out_field_string (uiout, "func-name", name);
+ ui_out_field_int (uiout, "offset", offset);
+ }
+ if (filename != NULL)
+ free (filename);
+ if (name != NULL)
+ free (name);
+
+ ui_file_rewind (stb->stream);
+ pc += (*tm_print_insn) (pc, &di);
+ ui_out_field_stream (uiout, "inst", stb);
+ ui_file_rewind (stb->stream);
+ ui_out_list_end (uiout);
+ }
+ if (close_list)
+ {
+ ui_out_list_end (uiout);
+ ui_out_list_end (uiout);
+ close_list = 0;
+ }
+ if (how_many >= 0)
+ if (num_displayed >= how_many)
+ break;
+ }
+ ui_out_list_end (uiout);
+ }
+ else
+ {
+ assembly_only:
+ ui_out_list_begin (uiout, "asm_insns");
+ num_displayed = 0;
+ for (pc = low; pc < high;)
+ {
+ QUIT;
+ if (how_many >= 0)
+ {
+ if (num_displayed >= how_many)
+ break;
+ else
+ num_displayed++;
+ }
+ ui_out_list_begin (uiout, NULL);
+ print_address_numeric (pc, 1, stb->stream);
+ ui_out_field_stream (uiout, "address", stb);
+
+ if (!build_address_symbolic (pc, 0, &name, &offset, &filename, &line, &unmapped))
+ {
+ /* We don't care now about line, filename and
+ unmapped. But we might in the future. */
+ ui_out_field_string (uiout, "func-name", name);
+ ui_out_field_int (uiout, "offset", offset);
+ }
+ if (filename != NULL)
+ free (filename);
+ if (name != NULL)
+ free (name);
+
+ ui_file_rewind (stb->stream);
+ pc += (*tm_print_insn) (pc, &di);
+ ui_out_field_stream (uiout, "inst", stb);
+ ui_file_rewind (stb->stream);
+ ui_out_list_end (uiout);
+ }
+ ui_out_list_end (uiout);
+ }
+ gdb_flush (gdb_stdout);
+
+ return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
new file mode 100644
index 00000000000..143054c66c9
--- /dev/null
+++ b/gdb/mi/mi-cmd-stack.c
@@ -0,0 +1,317 @@
+/* MI Command Set - stack commands.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "target.h"
+#include "frame.h"
+#include "value.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+
+#ifdef UI_OUT
+/* FIXME: these should go in some .h file but stack.c doesn't have a
+ corresponding .h file. These wrappers will be obsolete anyway, once
+ we pull the plug on the sanitization. */
+extern void select_frame_command_wrapper (char *, int);
+#endif
+
+static void list_args_or_locals (int locals, int values, struct frame_info *fi);
+
+/* Print a list of the stack frames. Args can be none, in which case
+ we want to print the whole backtrace, or a pair of numbers
+ specifying the frame numbers at which to start and stop the
+ display. If the two numbers are equal, a single frame will be
+ displayed. */
+enum mi_cmd_result
+mi_cmd_stack_list_frames (char *command, char **argv, int argc)
+{
+ int frame_low;
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (!target_has_stack)
+ error ("mi_cmd_stack_list_frames: No stack.");
+
+ if (argc > 2 || argc == 1)
+ error ("mi_cmd_stack_list_frames: Usage: [FRAME_LOW FRAME_HIGH]");
+
+ if (argc == 2)
+ {
+ frame_low = atoi (argv[0]);
+ frame_high = atoi (argv[1]);
+ }
+ else
+ {
+ /* Called with no arguments, it means we want the whole
+ backtrace. */
+ frame_low = -1;
+ frame_high = -1;
+ }
+
+ /* Let's position fi on the frame at which to start the
+ display. Could be the innermost frame if the whole stack needs
+ displaying, or if frame_low is 0. */
+ for (i = 0, fi = get_current_frame ();
+ fi && i < frame_low;
+ i++, fi = get_prev_frame (fi));
+
+ if (fi == NULL)
+ error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+ ui_out_list_begin (uiout, "stack");
+
+ /* Now let;s print the frames up to frame_high, or until there are
+ frames in the stack. */
+ for (;
+ fi && (i <= frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ {
+ QUIT;
+ /* level == i: always print the level 'i'
+ source == LOC_AND_ADDRESS: print the location and the address
+ always, even for level 0.
+ args == 0: don't print the arguments. */
+ print_frame_info (fi /* frame info */ ,
+ i /* level */ ,
+ LOC_AND_ADDRESS /* source */ ,
+ 0 /* args */ );
+ }
+
+ ui_out_list_end (uiout);
+ if (i < frame_high)
+ error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
+
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_stack_info_depth (char *command, char **argv, int argc)
+{
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (!target_has_stack)
+ error ("mi_cmd_stack_info_depth: No stack.");
+
+ if (argc > 1)
+ error ("mi_cmd_stack_info_depth: Usage: [MAX_DEPTH]");
+
+ if (argc == 1)
+ frame_high = atoi (argv[0]);
+ else
+ /* Called with no arguments, it means we want the real depth of
+ the stack. */
+ frame_high = -1;
+
+ for (i = 0, fi = get_current_frame ();
+ fi && (i < frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ QUIT;
+
+ ui_out_field_int (uiout, "depth", i);
+
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the locals for the current frame. With argument of
+ 0, print only the names, with argument of 1 print also the
+ values. */
+enum mi_cmd_result
+mi_cmd_stack_list_locals (char *command, char **argv, int argc)
+{
+ if (argc != 1)
+ error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES");
+
+ list_args_or_locals (1, atoi (argv[0]), selected_frame);
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the arguments for the current frame. With argument
+ of 0, print only the names, with argument of 1 print also the
+ values. */
+enum mi_cmd_result
+mi_cmd_stack_list_args (char *command, char **argv, int argc)
+{
+ int frame_low;
+ int frame_high;
+ int i;
+ struct frame_info *fi;
+
+ if (argc < 1 || argc > 3 || argc == 2)
+ error ("mi_cmd_stack_list_args: Usage: PRINT_VALUES [FRAME_LOW FRAME_HIGH]");
+
+ if (argc == 3)
+ {
+ frame_low = atoi (argv[1]);
+ frame_high = atoi (argv[2]);
+ }
+ else
+ {
+ /* Called with no arguments, it means we want args for the whole
+ backtrace. */
+ frame_low = -1;
+ frame_high = -1;
+ }
+
+ /* Let's position fi on the frame at which to start the
+ display. Could be the innermost frame if the whole stack needs
+ displaying, or if frame_low is 0. */
+ for (i = 0, fi = get_current_frame ();
+ fi && i < frame_low;
+ i++, fi = get_prev_frame (fi));
+
+ if (fi == NULL)
+ error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+ ui_out_list_begin (uiout, "stack-args");
+
+ /* Now let's print the frames up to frame_high, or until there are
+ frames in the stack. */
+ for (;
+ fi && (i <= frame_high || frame_high == -1);
+ i++, fi = get_prev_frame (fi))
+ {
+ QUIT;
+ ui_out_list_begin (uiout, "frame");
+ ui_out_field_int (uiout, "level", i);
+ list_args_or_locals (0, atoi (argv[0]), fi);
+ ui_out_list_end (uiout);
+ }
+
+ ui_out_list_end (uiout);
+ if (i < frame_high)
+ error ("mi_cmd_stack_list_args: Not enough frames in stack.");
+
+ return MI_CMD_DONE;
+}
+
+/* Print a list of the locals or the arguments for the currently
+ selected frame. If the argument passed is 0, printonly the names
+ of the variables, if an argument of 1 is passed, print the values
+ as well. */
+static void
+list_args_or_locals (int locals, int values, struct frame_info *fi)
+{
+ struct block *block;
+ struct symbol *sym;
+ int i, nsyms;
+ int print_me = 0;
+ static struct ui_stream *stb = NULL;
+
+ stb = ui_out_stream_new (uiout);
+
+ block = get_frame_block (fi);
+
+ ui_out_list_begin (uiout, locals ? "locals" : "args");
+
+ while (block != 0)
+ {
+ nsyms = BLOCK_NSYMS (block);
+ for (i = 0; i < nsyms; i++)
+ {
+ sym = BLOCK_SYM (block, i);
+ switch (SYMBOL_CLASS (sym))
+ {
+ default:
+ case LOC_UNDEF: /* catches errors */
+ case LOC_CONST: /* constant */
+ case LOC_TYPEDEF: /* local typedef */
+ case LOC_LABEL: /* local label */
+ case LOC_BLOCK: /* local function */
+ case LOC_CONST_BYTES: /* loc. byte seq. */
+ case LOC_UNRESOLVED: /* unresolved static */
+ case LOC_OPTIMIZED_OUT: /* optimized out */
+ print_me = 0;
+ break;
+
+ case LOC_ARG: /* argument */
+ case LOC_REF_ARG: /* reference arg */
+ case LOC_REGPARM: /* register arg */
+ case LOC_REGPARM_ADDR: /* indirect register arg */
+ case LOC_LOCAL_ARG: /* stack arg */
+ case LOC_BASEREG_ARG: /* basereg arg */
+ if (!locals)
+ print_me = 1;
+ break;
+
+ case LOC_LOCAL: /* stack local */
+ case LOC_BASEREG: /* basereg local */
+ case LOC_STATIC: /* static */
+ case LOC_REGISTER: /* register */
+ if (locals)
+ print_me = 1;
+ break;
+ }
+ if (print_me)
+ {
+ if (values)
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_string (uiout, "name", SYMBOL_NAME (sym));
+
+ if (values)
+ {
+ struct symbol *sym2;
+ if (!locals)
+ sym2 = lookup_symbol (SYMBOL_NAME (sym),
+ block, VAR_NAMESPACE,
+ (int *) NULL,
+ (struct symtab **) NULL);
+ else
+ sym2 = sym;
+ print_variable_value (sym2, fi, stb->stream);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_list_end (uiout);
+ }
+ }
+ }
+ if (BLOCK_FUNCTION (block))
+ break;
+ else
+ block = BLOCK_SUPERBLOCK (block);
+ }
+ ui_out_list_end (uiout);
+ ui_out_stream_delete (stb);
+}
+
+enum mi_cmd_result
+mi_cmd_stack_select_frame (char *command, char **argv, int argc)
+{
+#ifdef UI_OUT
+ if (!target_has_stack)
+ error ("mi_cmd_stack_select_frame: No stack.");
+
+ if (argc > 1)
+ error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
+
+ /* with no args, don't change frame */
+ if (argc == 0)
+ select_frame_command_wrapper (0, 1 /* not used */ );
+ else
+ select_frame_command_wrapper (argv[0], 1 /* not used */ );
+#endif
+ return MI_CMD_DONE;
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
new file mode 100644
index 00000000000..cf94496212c
--- /dev/null
+++ b/gdb/mi/mi-cmd-var.c
@@ -0,0 +1,474 @@
+/* MI Command Set - varobj commands.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "mi-cmds.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "varobj.h"
+#include "value.h"
+#include <ctype.h>
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+extern int varobjdebug; /* defined in varobj.c */
+
+static void varobj_update_one (struct varobj *var);
+
+/* VAROBJ operations */
+
+enum mi_cmd_result
+mi_cmd_var_create (char *command, char **argv, int argc)
+{
+ CORE_ADDR frameaddr;
+ struct varobj *var;
+ char *name;
+ char *frame;
+ char *expr;
+ char *type;
+ struct cleanup *old_cleanups;
+
+ if (argc != 3)
+ {
+ /* asprintf (&mi_error_message,
+ "mi_cmd_var_create: Usage: .");
+ return MI_CMD_ERROR; */
+ error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION.");
+ }
+
+ name = xstrdup (argv[0]);
+ /* Add cleanup for name. Must be free_current_contents as
+ name can be reallocated */
+ old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents,
+ &name);
+
+ frame = xstrdup (argv[1]);
+ old_cleanups = make_cleanup (free, frame);
+
+ expr = xstrdup (argv[2]);
+
+ if (strcmp (name, "-") == 0)
+ {
+ free (name);
+ name = varobj_gen_name ();
+ }
+ else if (!isalpha (*name))
+ error ("mi_cmd_var_create: name of object must begin with a letter");
+
+ if (strcmp (frame, "*") == 0)
+ frameaddr = -1;
+ else
+ frameaddr = parse_and_eval_address (frame);
+
+ if (varobjdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n",
+ name, frame, paddr (frameaddr), expr);
+
+ var = varobj_create (name, expr, frameaddr);
+
+ if (var == NULL)
+ error ("mi_cmd_var_create: unable to create variable object");
+
+ ui_out_field_string (uiout, "name", name);
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+ type = varobj_get_type (var);
+ if (type == NULL)
+ ui_out_field_string (uiout, "type", "");
+ else
+ {
+ ui_out_field_string (uiout, "type", type);
+ free (type);
+ }
+
+ do_cleanups (old_cleanups);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_delete (char *command, char **argv, int argc)
+{
+ char *name;
+ char *expr;
+ struct varobj *var;
+ int numdel;
+ int children_only_p = 0;
+ struct cleanup *old_cleanups;
+
+ if (argc < 1 || argc > 2)
+ error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION.");
+
+ name = xstrdup (argv[0]);
+ /* Add cleanup for name. Must be free_current_contents as
+ name can be reallocated */
+ old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents,
+ &name);
+
+ /* If we have one single argument it cannot be '-c' or any string
+ starting with '-'. */
+ if (argc == 1)
+ {
+ if (strcmp (name, "-c") == 0)
+ error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name");
+ if (*name == '-')
+ error ("mi_cmd_var_delete: Illegal variable object name");
+ }
+
+ /* If we have 2 arguments they must be '-c' followed by a string
+ which would be the variable name. */
+ if (argc == 2)
+ {
+ expr = xstrdup (argv[1]);
+ if (strcmp (name, "-c") != 0)
+ error ("mi_cmd_var_delete: Invalid option.");
+ children_only_p = 1;
+ free (name);
+ name = xstrdup (expr);
+ free (expr);
+ }
+
+ /* If we didn't error out, now NAME contains the name of the
+ variable. */
+
+ var = varobj_get_handle (name);
+
+ if (var == NULL)
+ error ("mi_cmd_var_delete: Variable object not found.");
+
+ numdel = varobj_delete (var, NULL, children_only_p);
+
+ ui_out_field_int (uiout, "ndeleted", numdel);
+
+ do_cleanups (old_cleanups);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_set_format (char *command, char **argv, int argc)
+{
+ enum varobj_display_formats format;
+ int len;
+ struct varobj *var;
+ char *formspec;
+
+ if (argc != 2)
+ error ("mi_cmd_var_set_format: Usage: NAME FORMAT.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+
+ if (var == NULL)
+ error ("mi_cmd_var_set_format: Variable object not found");
+
+ formspec = xstrdup (argv[1]);
+ if (formspec == NULL)
+ error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+ len = strlen (formspec);
+
+ if (STREQN (formspec, "natural", len))
+ format = FORMAT_NATURAL;
+ else if (STREQN (formspec, "binary", len))
+ format = FORMAT_BINARY;
+ else if (STREQN (formspec, "decimal", len))
+ format = FORMAT_DECIMAL;
+ else if (STREQN (formspec, "hexadecimal", len))
+ format = FORMAT_HEXADECIMAL;
+ else if (STREQN (formspec, "octal", len))
+ format = FORMAT_OCTAL;
+ else
+ error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\"");
+
+ /* Set the format of VAR to given format */
+ varobj_set_display_format (var, format);
+
+ /* Report the new current format */
+ ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_format (char *command, char **argv, int argc)
+{
+ enum varobj_display_formats format;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_show_format: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_show_format: Variable object not found");
+
+ format = varobj_get_display_format (var);
+
+ /* Report the current format */
+ ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_num_children (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_num_children: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_num_children: Variable object not found");
+
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_list_children (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ struct varobj **childlist;
+ struct varobj **cc;
+ int numchild;
+ char *type;
+
+ if (argc != 1)
+ error ("mi_cmd_var_list_children: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_list_children: Variable object not found");
+
+ numchild = varobj_list_children (var, &childlist);
+ ui_out_field_int (uiout, "numchild", numchild);
+
+ if (numchild <= 0)
+ return MI_CMD_DONE;
+
+ ui_out_list_begin (uiout, "children");
+ cc = childlist;
+ while (*cc != NULL)
+ {
+ ui_out_list_begin (uiout, "child");
+ ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
+ ui_out_field_string (uiout, "exp", varobj_get_expression (*cc));
+ ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc));
+ type = varobj_get_type (*cc);
+ /* C++ pseudo-variables (public, private, protected) do not have a type */
+ if (type)
+ ui_out_field_string (uiout, "type", varobj_get_type (*cc));
+ ui_out_list_end (uiout);
+ cc++;
+ }
+ ui_out_list_end (uiout);
+ free (childlist);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_type (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_type: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_type: Variable object not found");
+
+ ui_out_field_string (uiout, "type", varobj_get_type (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_info_expression (char *command, char **argv, int argc)
+{
+ enum varobj_languages lang;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_info_expression: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_info_expression: Variable object not found");
+
+ lang = varobj_get_language (var);
+
+ ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]);
+ ui_out_field_string (uiout, "exp", varobj_get_expression (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_show_attributes (char *command, char **argv, int argc)
+{
+ int attr;
+ char *attstr;
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_show_attributes: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_show_attributes: Variable object not found");
+
+ attr = varobj_get_attributes (var);
+ /* FIXME: define masks for attributes */
+ if (attr & 0x00000001)
+ attstr = "editable";
+ else
+ attstr = "noneditable";
+
+ ui_out_field_string (uiout, "attr", attstr);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+
+ if (argc != 1)
+ error ("mi_cmd_var_evaluate_expression: Usage: NAME.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_evaluate_expression: Variable object not found");
+
+ ui_out_field_string (uiout, "value", varobj_get_value (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_assign (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ char *expression;
+
+ if (argc != 2)
+ error ("mi_cmd_var_assign: Usage: NAME EXPRESSION.");
+
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (argv[0]);
+ if (var == NULL)
+ error ("mi_cmd_var_assign: Variable object not found");
+
+ /* FIXME: define masks for attributes */
+ if (!(varobj_get_attributes (var) & 0x00000001))
+ error ("mi_cmd_var_assign: Variable object is not editable");
+
+ expression = xstrdup (argv[1]);
+
+ if (!varobj_set_value (var, expression))
+ error ("mi_cmd_var_assign: Could not assign expression to varible object");
+
+ ui_out_field_string (uiout, "value", varobj_get_value (var));
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_var_update (char *command, char **argv, int argc)
+{
+ struct varobj *var;
+ struct varobj **rootlist;
+ struct varobj **cr;
+ char *name;
+ int nv;
+
+ if (argc != 1)
+ error ("mi_cmd_var_update: Usage: NAME.");
+
+ name = argv[0];
+
+ /* Check if the parameter is a "*" which means that we want
+ to update all variables */
+
+ if ((*name == '*') && (*(name + 1) == '\0'))
+ {
+ nv = varobj_list (&rootlist);
+ ui_out_list_begin (uiout, "changelist");
+ if (nv <= 0)
+ {
+ ui_out_list_end (uiout);
+ return MI_CMD_DONE;
+ }
+ cr = rootlist;
+ while (*cr != NULL)
+ {
+ varobj_update_one (*cr);
+ cr++;
+ }
+ free (rootlist);
+ ui_out_list_end (uiout);
+ }
+ else
+ {
+ /* Get varobj handle, if a valid var obj name was specified */
+ var = varobj_get_handle (name);
+ if (var == NULL)
+ error ("mi_cmd_var_update: Variable object not found");
+
+ ui_out_list_begin (uiout, "changelist");
+ varobj_update_one (var);
+ ui_out_list_end (uiout);
+ }
+ return MI_CMD_DONE;
+}
+
+/* Helper for mi_cmd_var_update() */
+
+static void
+varobj_update_one (struct varobj *var)
+{
+ struct varobj **changelist;
+ struct varobj **cc;
+ int nc;
+
+ nc = varobj_update (var, &changelist);
+
+ if (nc <= 0)
+ return;
+
+ cc = changelist;
+ while (*cc != NULL)
+ {
+ ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
+ cc++;
+ }
+ free (changelist);
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
new file mode 100644
index 00000000000..f0d4fc85d73
--- /dev/null
+++ b/gdb/mi/mi-cmds.c
@@ -0,0 +1,263 @@
+/* MI Command Set.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "top.h"
+#include "mi-cmds.h"
+#include <string.h>
+
+extern void _initialize_mi_cmds (void);
+struct mi_cmd;
+static struct mi_cmd **lookup_table (const char *command);
+static void build_table (struct mi_cmd *commands);
+
+
+struct mi_cmd mi_cmds[] =
+{
+ {"break-after", "ignore %s", 0},
+ {"break-catch", 0, 0},
+ {"break-commands", 0, 0},
+ {"break-condition", "cond %s", 0},
+ {"break-delete", "delete breakpoint %s", 0},
+ {"break-disable", "disable breakpoint %s", 0},
+ {"break-enable", "enable breakpoint %s", 0},
+ {"break-info", "info break %s", 0},
+ {"break-insert", 0, 0, mi_cmd_break_insert},
+ {"break-list", "info break", 0},
+ {"break-watch", 0, 0, mi_cmd_break_watch},
+ {"data-disassemble", 0, 0, mi_cmd_disassemble},
+ {"data-evaluate-expression", 0, 0, mi_cmd_data_evaluate_expression},
+ {"data-list-changed-registers", 0, 0, mi_cmd_data_list_changed_registers},
+ {"data-list-register-names", 0, 0, mi_cmd_data_list_register_names},
+ {"data-list-register-values", 0, 0, mi_cmd_data_list_register_values},
+ {"data-read-memory", 0, 0, mi_cmd_data_read_memory},
+ {"data-write-memory", 0, 0, mi_cmd_data_write_memory},
+ {"display-delete", 0, 0},
+ {"display-disable", 0, 0},
+ {"display-enable", 0, 0},
+ {"display-insert", 0, 0},
+ {"display-list", 0, 0},
+ {"environment-cd", "cd %s", 0},
+ {"environment-directory", "dir %s", 0},
+ {"environment-path", "path %s", 0},
+ {"environment-pwd", "pwd", 0},
+ {"exec-abort", 0, 0},
+ {"exec-arguments", "set args %s", 0},
+ {"exec-continue", 0, mi_cmd_exec_continue},
+ {"exec-finish", 0, mi_cmd_exec_finish},
+ {"exec-interrupt", 0, mi_cmd_exec_interrupt},
+ {"exec-next", 0, mi_cmd_exec_next},
+ {"exec-next-instruction", 0, mi_cmd_exec_next_instruction},
+ {"exec-return", 0, mi_cmd_exec_return},
+ {"exec-run", 0, mi_cmd_exec_run},
+ {"exec-show-arguments", 0, 0},
+ {"exec-signal", 0, 0},
+ {"exec-step", 0, mi_cmd_exec_step},
+ {"exec-step-instruction", 0, mi_cmd_exec_step_instruction},
+ {"exec-until", 0, mi_cmd_exec_until},
+ {"file-clear", 0, 0},
+ {"file-exec-and-symbols", "file %s", 0},
+ {"file-exec-file", "exec-file %s", 0},
+ {"file-list-exec-sections", 0, 0},
+ {"file-list-exec-source-files", 0, 0},
+ {"file-list-shared-libraries", 0, 0},
+ {"file-list-symbol-files", 0, 0},
+ {"file-symbol-file", "symbol-file %s", 0},
+ {"gdb-complete", 0, 0},
+ {"gdb-exit", 0, 0, mi_cmd_gdb_exit},
+ {"gdb-set", "set %s", 0},
+ {"gdb-show", "show %s", 0},
+ {"gdb-source", 0, 0},
+ {"gdb-version", "show version", 0},
+ {"kod-info", 0, 0},
+ {"kod-list", 0, 0},
+ {"kod-list-object-types", 0, 0},
+ {"kod-show", 0, 0},
+ {"overlay-auto", 0, 0},
+ {"overlay-list-mapping-state", 0, 0},
+ {"overlay-list-overlays", 0, 0},
+ {"overlay-map", 0, 0},
+ {"overlay-off", 0, 0},
+ {"overlay-on", 0, 0},
+ {"overlay-unmap", 0, 0},
+ {"signal-handle", 0, 0},
+ {"signal-list-handle-actions", 0, 0},
+ {"signal-list-signal-types", 0, 0},
+ {"stack-info-depth", 0, 0, mi_cmd_stack_info_depth},
+ {"stack-info-frame", 0, 0},
+ {"stack-list-arguments", 0, 0, mi_cmd_stack_list_args},
+ {"stack-list-exception-handlers", 0, 0},
+ {"stack-list-frames", 0, 0, mi_cmd_stack_list_frames},
+ {"stack-list-locals", 0, 0, mi_cmd_stack_list_locals},
+ {"stack-select-frame", 0, 0, mi_cmd_stack_select_frame},
+ {"symbol-info-address", 0, 0},
+ {"symbol-info-file", 0, 0},
+ {"symbol-info-function", 0, 0},
+ {"symbol-info-line", 0, 0},
+ {"symbol-info-symbol", 0, 0},
+ {"symbol-list-functions", 0, 0},
+ {"symbol-list-types", 0, 0},
+ {"symbol-list-variables", 0, 0},
+ {"symbol-locate", 0, 0},
+ {"symbol-type", 0, 0},
+ {"target-attach", 0, 0},
+ {"target-compare-sections", 0, 0},
+ {"target-detach", "detach", 0},
+ {"target-download", 0, mi_cmd_target_download},
+ {"target-exec-status", 0, 0},
+ {"target-list-available-targets", 0, 0},
+ {"target-list-current-targets", 0, 0},
+ {"target-list-parameters", 0, 0},
+ {"target-select", 0, mi_cmd_target_select},
+ {"thread-info", 0, 0},
+ {"thread-list-all-threads", 0, 0},
+ {"thread-list-ids", 0, 0, mi_cmd_thread_list_ids},
+ {"thread-select", 0, 0, mi_cmd_thread_select},
+ {"trace-actions", 0, 0},
+ {"trace-delete", 0, 0},
+ {"trace-disable", 0, 0},
+ {"trace-dump", 0, 0},
+ {"trace-enable", 0, 0},
+ {"trace-exists", 0, 0},
+ {"trace-find", 0, 0},
+ {"trace-frame-number", 0, 0},
+ {"trace-info", 0, 0},
+ {"trace-insert", 0, 0},
+ {"trace-list", 0, 0},
+ {"trace-pass-count", 0, 0},
+ {"trace-save", 0, 0},
+ {"trace-start", 0, 0},
+ {"trace-stop", 0, 0},
+ {"var-assign", 0, 0, mi_cmd_var_assign},
+ {"var-create", 0, 0, mi_cmd_var_create},
+ {"var-delete", 0, 0, mi_cmd_var_delete},
+ {"var-evaluate-expression", 0, 0, mi_cmd_var_evaluate_expression},
+ {"var-info-expression", 0, 0, mi_cmd_var_info_expression},
+ {"var-info-num-children", 0, 0, mi_cmd_var_info_num_children},
+ {"var-info-type", 0, 0, mi_cmd_var_info_type},
+ {"var-list-children", 0, 0, mi_cmd_var_list_children},
+ {"var-set-format", 0, 0, mi_cmd_var_set_format},
+ {"var-show-attributes", 0, 0, mi_cmd_var_show_attributes},
+ {"var-show-format", 0, 0, mi_cmd_var_show_format},
+ {"var-update", 0, 0, mi_cmd_var_update},
+ {0,}
+};
+
+/* Pointer to the mi command table (built at run time) */
+
+static struct mi_cmd **mi_table;
+
+/* A prime large enough to accomodate the entire command table */
+enum
+ {
+ MI_TABLE_SIZE = 227
+ };
+
+/* Exported function used to obtain info from the table */
+struct mi_cmd *
+mi_lookup (const char *command)
+{
+ return *lookup_table (command);
+}
+
+/* stat collecting */
+struct mi_cmd_stats
+{
+ int hit;
+ int miss;
+ int rehash;
+};
+struct mi_cmd_stats stats;
+
+/* our lookup function */
+static struct mi_cmd **
+lookup_table (const char *command)
+{
+ const char *chp;
+ unsigned int index = 0;
+ /* compute our hash */
+ for (chp = command; *chp; chp++)
+ {
+ /* some what arbitrary */
+ index = ((index << 6) + (unsigned int) *chp) % MI_TABLE_SIZE;
+ }
+ /* look it up */
+ while (1)
+ {
+ struct mi_cmd **entry = &mi_table[index];
+ if ((*entry) == 0)
+ {
+ /* not found, return pointer to next free. */
+ stats.miss++;
+ return entry;
+ }
+ if (strcmp (command, (*entry)->name) == 0)
+ {
+ stats.hit++;
+ return entry; /* found */
+ }
+ index = (index + 1) % MI_TABLE_SIZE;
+ stats.rehash++;
+ }
+}
+
+static void
+build_table (struct mi_cmd *commands)
+{
+ int nr_rehash = 0;
+ int nr_entries = 0;
+ struct mi_cmd *command;
+ int sizeof_table = sizeof (struct mi_cmd **) * MI_TABLE_SIZE;
+
+ mi_table = xmalloc (sizeof_table);
+ memset (mi_table, 0, sizeof_table);
+ for (command = commands; command->name != 0; command++)
+ {
+ struct mi_cmd **entry = lookup_table (command->name);
+ if (*entry)
+ internal_error ("command `%s' appears to be duplicated",
+ command->name);
+ *entry = command;
+ if (0)
+ {
+ fprintf_unfiltered (gdb_stdlog, "%-30s %2d\n",
+ command->name, stats.rehash - nr_rehash);
+ }
+ nr_entries++;
+ nr_rehash = stats.rehash;
+ }
+ if (0)
+ {
+ fprintf_filtered (gdb_stdlog, "Average %3.1f\n",
+ (double) nr_rehash / (double) nr_entries);
+ }
+}
+
+void
+_initialize_mi_cmds ()
+{
+ build_table (mi_cmds);
+ memset (&stats, 0, sizeof (stats));
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
new file mode 100644
index 00000000000..3b4f73e7995
--- /dev/null
+++ b/gdb/mi/mi-cmds.h
@@ -0,0 +1,128 @@
+/* MI Command Set.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#ifndef MI_CMDS_H
+#define MI_CMDS_H
+
+/* An MI command can return any of the following. */
+
+enum mi_cmd_result
+ {
+ /* Report the command as ``done''. Display both the ``NNN^done''
+ message and the completion prompt. */
+ MI_CMD_DONE = 0,
+ /* The command is still running in the forground. Main loop should
+ display the completion prompt. */
+ MI_CMD_FORGROUND,
+ /* An error condition was detected and an error message was
+ asprintf'd into the mi_error_message buffer. The main loop will
+ display the error message and the completion prompt. */
+ MI_CMD_ERROR,
+ /* An error condition was detected and caught. The error message is
+ in the global error message buffer. The main loop will display
+ the error message and the completion prompt. */
+ MI_CMD_CAUGHT_ERROR,
+ /* The MI command has already displayed its completion message.
+ Main loop will not display a completion message but will display
+ the completion prompt. */
+ MI_CMD_QUIET
+ };
+
+typedef enum mi_cmd_result (mi_cmd_argv_ftype) (char *command, char **argv, int argc);
+
+/* Older MI commands have this interface. Retained until all old
+ commands are flushed. */
+
+typedef enum mi_cmd_result (mi_cmd_args_ftype) ( /*ui */ char *args, int from_tty);
+
+/* Function implementing each command */
+extern mi_cmd_argv_ftype mi_cmd_break_insert;
+extern mi_cmd_argv_ftype mi_cmd_break_watch;
+extern mi_cmd_argv_ftype mi_cmd_disassemble;
+extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression;
+extern mi_cmd_argv_ftype mi_cmd_data_list_register_names;
+extern mi_cmd_argv_ftype mi_cmd_data_list_register_values;
+extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers;
+extern mi_cmd_argv_ftype mi_cmd_data_read_memory;
+extern mi_cmd_argv_ftype mi_cmd_data_write_memory;
+extern mi_cmd_args_ftype mi_cmd_exec_continue;
+extern mi_cmd_args_ftype mi_cmd_exec_finish;
+extern mi_cmd_args_ftype mi_cmd_exec_next;
+extern mi_cmd_args_ftype mi_cmd_exec_next_instruction;
+extern mi_cmd_args_ftype mi_cmd_exec_return;
+extern mi_cmd_args_ftype mi_cmd_exec_run;
+extern mi_cmd_args_ftype mi_cmd_exec_step;
+extern mi_cmd_args_ftype mi_cmd_exec_step_instruction;
+extern mi_cmd_args_ftype mi_cmd_exec_until;
+extern mi_cmd_args_ftype mi_cmd_exec_interrupt;
+extern mi_cmd_argv_ftype mi_cmd_gdb_exit;
+extern mi_cmd_argv_ftype mi_cmd_stack_info_depth;
+extern mi_cmd_argv_ftype mi_cmd_stack_list_args;
+extern mi_cmd_argv_ftype mi_cmd_stack_list_frames;
+extern mi_cmd_argv_ftype mi_cmd_stack_list_locals;
+extern mi_cmd_argv_ftype mi_cmd_stack_select_frame;
+extern mi_cmd_args_ftype mi_cmd_target_download;
+extern mi_cmd_args_ftype mi_cmd_target_select;
+extern mi_cmd_argv_ftype mi_cmd_thread_list_ids;
+extern mi_cmd_argv_ftype mi_cmd_thread_select;
+extern mi_cmd_argv_ftype mi_cmd_var_assign;
+extern mi_cmd_argv_ftype mi_cmd_var_create;
+extern mi_cmd_argv_ftype mi_cmd_var_delete;
+extern mi_cmd_argv_ftype mi_cmd_var_evaluate_expression;
+extern mi_cmd_argv_ftype mi_cmd_var_info_expression;
+extern mi_cmd_argv_ftype mi_cmd_var_info_num_children;
+extern mi_cmd_argv_ftype mi_cmd_var_info_type;
+extern mi_cmd_argv_ftype mi_cmd_var_list_children;
+extern mi_cmd_argv_ftype mi_cmd_var_set_format;
+extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
+extern mi_cmd_argv_ftype mi_cmd_var_show_format;
+extern mi_cmd_argv_ftype mi_cmd_var_update;
+
+/* Description of a single command. */
+
+struct mi_cmd
+ {
+ /* official name of the command */
+ const char *name;
+ /* If non-null, the corresponding CLI command that can be used to
+ implement this MI command */
+ const char *cli;
+ /* If non-null, the function implementing the MI command */
+ mi_cmd_args_ftype *args_func;
+ /* If non-null, the function implementing the MI command */
+ mi_cmd_argv_ftype *argv_func;
+ };
+
+/* Lookup a command in the mi comand table */
+
+extern struct mi_cmd *mi_lookup (const char *command);
+
+/* Debug flag */
+extern int mi_debug_p;
+
+/* Raw console output - FIXME: should this be a parameter? */
+extern struct ui_file *raw_stdout;
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-console.c b/gdb/mi/mi-console.c
new file mode 100644
index 00000000000..3bf6a73ede9
--- /dev/null
+++ b/gdb/mi/mi-console.c
@@ -0,0 +1,118 @@
+/* MI Console code.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "mi-console.h"
+#include <string.h>
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+/* MI-console: send output to std-out but correcty encapsulated */
+
+static ui_file_fputs_ftype mi_console_file_fputs;
+static ui_file_flush_ftype mi_console_file_flush;
+static ui_file_delete_ftype mi_console_file_delete;
+
+struct mi_console_file
+ {
+ int *magic;
+ struct ui_file *raw;
+ struct ui_file *buffer;
+ const char *prefix;
+ };
+
+int mi_console_file_magic;
+
+struct ui_file *
+mi_console_file_new (struct ui_file *raw,
+ const char *prefix)
+{
+ struct ui_file *ui_file = ui_file_new ();
+ struct mi_console_file *mi_console = XMALLOC (struct mi_console_file);
+ mi_console->magic = &mi_console_file_magic;
+ mi_console->raw = raw;
+ mi_console->buffer = mem_fileopen ();
+ mi_console->prefix = prefix;
+ set_ui_file_fputs (ui_file, mi_console_file_fputs);
+ set_ui_file_flush (ui_file, mi_console_file_flush);
+ set_ui_file_data (ui_file, mi_console, mi_console_file_delete);
+ return ui_file;
+}
+
+static void
+mi_console_file_delete (struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error ("mi_console_file_delete: bad magic number");
+ free (mi_console);
+}
+
+static void
+mi_console_file_fputs (const char *buf,
+ struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error ("mi_console_file_fputs: bad magic number");
+ /* Append the text to our internal buffer */
+ fputs_unfiltered (buf, mi_console->buffer);
+ /* Flush when an embedded \n */
+ if (strchr (buf, '\n') != NULL)
+ gdb_flush (file);
+}
+
+/* Transform a byte sequence into a console output packet. */
+static void
+mi_console_raw_packet (void *data,
+ const char *buf,
+ long length_buf)
+{
+ struct mi_console_file *mi_console = data;
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error ("mi_console_file_transform: bad magic number");
+
+ if (length_buf > 0)
+ {
+ fputs_unfiltered (mi_console->prefix, mi_console->raw);
+ fputs_unfiltered ("\"", mi_console->raw);
+ fputstrn_unfiltered (buf, length_buf, '"', mi_console->raw);
+ fputs_unfiltered ("\"\n", mi_console->raw);
+ gdb_flush (mi_console->raw);
+ }
+}
+
+static void
+mi_console_file_flush (struct ui_file *file)
+{
+ struct mi_console_file *mi_console = ui_file_data (file);
+ if (mi_console->magic != &mi_console_file_magic)
+ internal_error ("mi_console_file_flush: bad magic number");
+ ui_file_put (mi_console->buffer, mi_console_raw_packet, mi_console);
+ ui_file_rewind (mi_console->buffer);
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-console.h b/gdb/mi/mi-console.h
new file mode 100644
index 00000000000..80cfec9aeb1
--- /dev/null
+++ b/gdb/mi/mi-console.h
@@ -0,0 +1,31 @@
+/* MI Command Set - MI Console.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#ifndef MI_CONSOLE_H
+#define MI_CONSOLE_H
+
+extern struct ui_file *mi_console_file_new (struct ui_file *raw, const char *prefix);
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c
new file mode 100644
index 00000000000..4a3758a4a6c
--- /dev/null
+++ b/gdb/mi/mi-getopt.c
@@ -0,0 +1,80 @@
+/* MI Command Set - MI Option Parser.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "mi-getopt.h"
+#include "string.h"
+
+int
+mi_getopt (const char *prefix,
+ int argc, char **argv,
+ struct mi_opt *opts,
+ int *optind, char **optarg)
+{
+ char *arg;
+ struct mi_opt *opt;
+ /* We assume that argv/argc are ok. */
+ if (*optind > argc || *optind < 0)
+ internal_error ("mi_getopt_long: optind out of bounds");
+ if (*optind == argc)
+ return -1;
+ arg = argv[*optind];
+ /* ``--''? */
+ if (strcmp (arg, "--") == 0)
+ {
+ *optind += 1;
+ *optarg = NULL;
+ return -1;
+ }
+ /* End of option list. */
+ if (arg[0] != '-')
+ {
+ *optarg = NULL;
+ return -1;
+ }
+ /* Look the option up. */
+ for (opt = opts; opt->name != NULL; opt++)
+ {
+ if (strcmp (opt->name, arg + 1) != 0)
+ continue;
+ if (opt->arg_p)
+ {
+ /* A non-simple optarg option. */
+ if (argc < *optind + 2)
+ error ("%s: Option %s requires an argument", prefix, arg);
+ *optarg = argv[(*optind) + 1];
+ *optind = (*optind) + 2;
+ return opt->index;
+ }
+ else
+ {
+ *optarg = NULL;
+ *optind = (*optind) + 1;
+ return opt->index;
+ }
+ }
+ error ("%s: Unknown option ``%s''", prefix, arg + 1);
+}
+
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-getopt.h b/gdb/mi/mi-getopt.h
new file mode 100644
index 00000000000..d633d43b3fc
--- /dev/null
+++ b/gdb/mi/mi-getopt.h
@@ -0,0 +1,64 @@
+/* MI Option Parser.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#ifndef MI_GETOPT_H
+#define MI_GETOPT_H
+
+/* Like getopt() but with simpler semantics.
+
+ An option has the form ``-<name>''. The special option ``--''
+ denotes the end of the option list. An option can be followed by a
+ separate argument (on a per option basis).
+
+ On entry OPTIND contains the index of the next element of ARGV that
+ needs parsing. OPTIND is updated to indicate the index of the next
+ argument before mi_getopt() returns.
+
+ If ARGV[OPTIND] is an option, that options INDEX is returned.
+ OPTARG is set to the options argument or NULL. OPTIND is updated.
+
+ If ARGV[OPTIND] is not an option, -1 is returned and OPTIND updated
+ to specify the non-option argument. OPTARG is set to NULL.
+
+ mi_getopt() calls ``error("%s: Unknown option %c", prefix,
+ option)'' if an unknown option is encountered. */
+
+struct mi_opt;
+extern int mi_getopt (const char *prefix, int argc, char **argv,
+ struct mi_opt *opt, int *optind, char **optarg);
+
+/* The option list. Terminated by NAME==NULL. ARG_P that the option
+ requires an argument. INDEX is returned to identify th option. */
+
+struct mi_opt
+ {
+ const char *name;
+ int index;
+ int arg_p;
+ };
+
+struct mi_opt;
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
new file mode 100644
index 00000000000..ec7f05edbd3
--- /dev/null
+++ b/gdb/mi/mi-main.c
@@ -0,0 +1,1446 @@
+/* MI Command Set.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+/* Work in progress */
+
+#include "defs.h"
+#include "target.h"
+#include "inferior.h"
+#include "gdb_string.h"
+#include "top.h"
+#include "gdbthread.h"
+#include "mi-cmds.h"
+#include "mi-parse.h"
+#include "mi-getopt.h"
+#include "mi-console.h"
+#include "ui-out.h"
+#include "mi-out.h"
+#include "event-loop.h"
+#include "event-top.h"
+#include "gdbcore.h" /* for write_memory() */
+#include <ctype.h>
+#include <sys/time.h>
+
+/* Convenience macro for allocting typesafe memory. */
+
+#undef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+
+enum
+ {
+ FROM_TTY = 0
+ };
+
+
+int mi_debug_p;
+struct ui_file *raw_stdout;
+
+/* The token of the last asynchronous command */
+static char *last_async_command;
+static char *previous_async_command;
+static char *mi_error_message;
+static char *old_regs;
+
+extern void _initialize_mi_main (void);
+static char *mi_input (char *);
+static void mi_execute_command (char *cmd, int from_tty);
+static enum mi_cmd_result mi_cmd_execute (struct mi_parse *parse);
+
+static void mi_execute_cli_command (const char *cli, char *args);
+static enum mi_cmd_result mi_execute_async_cli_command (char *mi, char *args, int from_tty);
+static void mi_execute_command_wrapper (char *cmd);
+
+void mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg);
+static void free_and_reset (char **arg);
+
+static int register_changed_p (int regnum);
+static int get_register (int regnum, int format);
+static void mi_load_progress (const char *section_name,
+ unsigned long sent_so_far,
+ unsigned long total_section,
+ unsigned long total_sent,
+ unsigned long grand_total);
+
+#ifdef UI_OUT
+/* FIXME: these should go in some .h file, but infcmd.c doesn't have a
+ corresponding .h file. These wrappers will be obsolete anyway, once
+ we pull the plug on the sanitization. */
+extern void interrupt_target_command_wrapper (char *, int);
+extern void return_command_wrapper (char *, int);
+#endif
+
+/* Command implementations. FIXME: Is this libgdb? No. This is the MI
+ layer that calls libgdb. Any operation used in the below should be
+ formalized. */
+
+enum mi_cmd_result
+mi_cmd_gdb_exit (char *command, char **argv, int argc)
+{
+ /* We have to print everything right here because we never return */
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("^exit\n", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ /* FIXME: The function called is not yet a formal libgdb function */
+ quit_force (NULL, FROM_TTY);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_exec_run (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("run", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_next (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("next", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_next_instruction (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("nexti", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_step (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("step", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_step_instruction (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("stepi", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_finish (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("finish", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_until (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("until", args, from_tty);
+}
+
+enum mi_cmd_result
+mi_cmd_exec_return (char *args, int from_tty)
+{
+#ifdef UI_OUT
+ /* This command doesn't really execute the target, it just pops the
+ specified number of frames. */
+ if (*args)
+ /* Call return_command with from_tty argument equal to 0 so as to
+ avoid being queried. */
+ return_command_wrapper (args, 0);
+ else
+ /* Call return_command with from_tty argument equal to 0 so as to
+ avoid being queried. */
+ return_command_wrapper (NULL, 0);
+
+ /* Because we have called return_command with from_tty = 0, we need
+ to print the frame here. */
+ show_and_print_stack_frame (selected_frame,
+ selected_frame_level,
+ LOC_AND_ADDRESS);
+#endif
+
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_exec_continue (char *args, int from_tty)
+{
+ /* FIXME: Should call a libgdb function, not a cli wrapper */
+ return mi_execute_async_cli_command ("continue", args, from_tty);
+}
+
+/* Interrupt the execution of the target. Note how we must play around
+ with the token varialbes, in order to display the current token in
+ the result of the interrupt command, and the previous execution
+ token when the target finally stops. See comments in
+ mi_cmd_execute. */
+enum mi_cmd_result
+mi_cmd_exec_interrupt (char *args, int from_tty)
+{
+#ifdef UI_OUT
+ if (!target_executing)
+ {
+ asprintf (&mi_error_message, "mi_cmd_exec_interrupt: Inferior not executing.");
+ return MI_CMD_ERROR;
+ }
+ interrupt_target_command_wrapper (args, from_tty);
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("^done", raw_stdout);
+ free (last_async_command);
+ if (previous_async_command)
+ last_async_command = xstrdup (previous_async_command);
+ free (previous_async_command);
+ previous_async_command = NULL;
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+#endif
+ return MI_CMD_QUIET;
+}
+
+enum mi_cmd_result
+mi_cmd_thread_select (char *command, char **argv, int argc)
+{
+ enum gdb_rc rc;
+
+ if (argc != 1)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_thread_select: USAGE: threadnum.");
+ return MI_CMD_ERROR;
+ }
+ else
+ rc = gdb_thread_select (argv[0]);
+
+ if (rc == GDB_RC_FAIL)
+ return MI_CMD_CAUGHT_ERROR;
+ else
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_thread_list_ids (char *command, char **argv, int argc)
+{
+ enum gdb_rc rc = MI_CMD_DONE;
+
+ if (argc != 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_thread_list_ids: No arguments required.");
+ return MI_CMD_ERROR;
+ }
+ else
+#ifdef UI_OUT
+ rc = gdb_list_thread_ids ();
+#endif
+
+ if (rc == GDB_RC_FAIL)
+ return MI_CMD_CAUGHT_ERROR;
+ else
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_data_list_register_names (char *command, char **argv, int argc)
+{
+ int regnum, numregs;
+ int i;
+
+ /* Note that the test for a valid register must include checking the
+ REGISTER_NAME because NUM_REGS may be allocated for the union of
+ the register sets within a family of related processors. In this
+ case, some entries of REGISTER_NAME will change depending upon
+ the particular processor being debugged. */
+
+ numregs = ARCH_NUM_REGS;
+
+ ui_out_list_begin (uiout, "register-names");
+
+ if (argc == 0) /* No args, just do all the regs */
+ {
+ for (regnum = 0;
+ regnum < numregs;
+ regnum++)
+ {
+ if (REGISTER_NAME (regnum) == NULL
+ || *(REGISTER_NAME (regnum)) == '\0')
+ continue;
+
+ ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
+ }
+ }
+
+ /* Else, list of register #s, just do listed regs */
+ for (i = 0; i < argc; i++)
+ {
+ regnum = atoi (argv[i]);
+
+ if (regnum >= 0
+ && regnum < numregs
+ && REGISTER_NAME (regnum) != NULL
+ && *REGISTER_NAME (regnum) != '\000')
+ ui_out_field_string (uiout, NULL, REGISTER_NAME (regnum));
+ else
+ {
+ asprintf (&mi_error_message, "bad register number");
+ return MI_CMD_ERROR;
+ }
+ }
+ ui_out_list_end (uiout);
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
+{
+ int regnum, numregs, changed;
+ int i;
+
+ /* Note that the test for a valid register must include checking the
+ REGISTER_NAME because NUM_REGS may be allocated for the union of
+ the register sets within a family of related processors. In this
+ case, some entries of REGISTER_NAME will change depending upon
+ the particular processor being debugged. */
+
+ numregs = ARCH_NUM_REGS;
+
+ ui_out_list_begin (uiout, "changed-registers");
+
+ if (argc == 0) /* No args, just do all the regs */
+ {
+ for (regnum = 0;
+ regnum < numregs;
+ regnum++)
+ {
+ if (REGISTER_NAME (regnum) == NULL
+ || *(REGISTER_NAME (regnum)) == '\0')
+ continue;
+ changed = register_changed_p (regnum);
+ if (changed < 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_list_changed_registers: Unable to read register contents.");
+ return MI_CMD_ERROR;
+ }
+ else if (changed)
+ ui_out_field_int (uiout, NULL, regnum);
+ }
+ }
+
+ /* Else, list of register #s, just do listed regs */
+ for (i = 0; i < argc; i++)
+ {
+ regnum = atoi (argv[i]);
+
+ if (regnum >= 0
+ && regnum < numregs
+ && REGISTER_NAME (regnum) != NULL
+ && *REGISTER_NAME (regnum) != '\000')
+ {
+ changed = register_changed_p (regnum);
+ if (changed < 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_list_register_change: Unable to read register contents.");
+ return MI_CMD_ERROR;
+ }
+ else if (changed)
+ ui_out_field_int (uiout, NULL, regnum);
+ }
+ else
+ {
+ asprintf (&mi_error_message, "bad register number");
+ return MI_CMD_ERROR;
+ }
+ }
+ ui_out_list_end (uiout);
+ return MI_CMD_DONE;
+}
+
+static int
+register_changed_p (int regnum)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+
+ if (read_relative_register_raw_bytes (regnum, raw_buffer))
+ return -1;
+
+ if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
+ REGISTER_RAW_SIZE (regnum)) == 0)
+ return 0;
+
+ /* Found a changed register. Return 1. */
+
+ memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
+ REGISTER_RAW_SIZE (regnum));
+
+ return 1;
+}
+
+/* Return a list of register number and value pairs. The valid
+ arguments expected are: a letter indicating the format in which to
+ display the registers contents. This can be one of: x (hexadecimal), d
+ (decimal), N (natural), t (binary), o (octal), r (raw). After the
+ format argumetn there can be a sequence of numbers, indicating which
+ registers to fetch the content of. If the format is the only argument,
+ a list of all the registers with their values is returned. */
+enum mi_cmd_result
+mi_cmd_data_list_register_values (char *command, char **argv, int argc)
+{
+ int regnum, numregs, format, result;
+ int i;
+
+ /* Note that the test for a valid register must include checking the
+ REGISTER_NAME because NUM_REGS may be allocated for the union of
+ the register sets within a family of related processors. In this
+ case, some entries of REGISTER_NAME will change depending upon
+ the particular processor being debugged. */
+
+ numregs = ARCH_NUM_REGS;
+
+ if (argc == 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_list_register_values: Usage: -data-list-register-values <format> [<regnum1>...<regnumN>]");
+ return MI_CMD_ERROR;
+ }
+
+ format = (int) argv[0][0];
+
+ if (!target_has_registers)
+ {
+ asprintf (&mi_error_message, "mi_cmd_data_list_register_values: No registers.");
+ return MI_CMD_ERROR;
+ }
+
+ ui_out_list_begin (uiout, "register-values");
+
+ if (argc == 1) /* No args, beside the format: do all the regs */
+ {
+ for (regnum = 0;
+ regnum < numregs;
+ regnum++)
+ {
+ if (REGISTER_NAME (regnum) == NULL
+ || *(REGISTER_NAME (regnum)) == '\0')
+ continue;
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_int (uiout, "number", regnum);
+ result = get_register (regnum, format);
+ if (result == -1)
+ return MI_CMD_ERROR;
+ ui_out_list_end (uiout);
+ }
+ }
+
+ /* Else, list of register #s, just do listed regs */
+ for (i = 1; i < argc; i++)
+ {
+ regnum = atoi (argv[i]);
+
+ if (regnum >= 0
+ && regnum < numregs
+ && REGISTER_NAME (regnum) != NULL
+ && *REGISTER_NAME (regnum) != '\000')
+ {
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_int (uiout, "number", regnum);
+ result = get_register (regnum, format);
+ if (result == -1)
+ return MI_CMD_ERROR;
+ ui_out_list_end (uiout);
+ }
+ else
+ {
+ asprintf (&mi_error_message, "bad register number");
+ return MI_CMD_ERROR;
+ }
+ }
+ ui_out_list_end (uiout);
+ return MI_CMD_DONE;
+}
+
+/* Output one register's contents in the desired format. */
+static int
+get_register (int regnum, int format)
+{
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+ char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+ int optim;
+ static struct ui_stream *stb = NULL;
+
+ stb = ui_out_stream_new (uiout);
+
+ if (format == 'N')
+ format = 0;
+
+ /* read_relative_register_raw_bytes returns a virtual frame pointer
+ (FRAME_FP (selected_frame)) if regnum == FP_REGNUM instead
+ of the real contents of the register. To get around this,
+ use get_saved_register instead. */
+ get_saved_register (raw_buffer, &optim, (CORE_ADDR *) NULL, selected_frame,
+ regnum, (enum lval_type *) NULL);
+ if (optim)
+ {
+ asprintf (&mi_error_message, "Optimized out");
+ return -1;
+ }
+
+ /* Convert raw data to virtual format if necessary. */
+
+ if (REGISTER_CONVERTIBLE (regnum))
+ {
+ REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
+ raw_buffer, virtual_buffer);
+ }
+ else
+ memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
+
+ if (format == 'r')
+ {
+ int j;
+ char *ptr, buf[1024];
+
+ strcpy (buf, "0x");
+ ptr = buf + 2;
+ for (j = 0; j < REGISTER_RAW_SIZE (regnum); j++)
+ {
+ register int idx = TARGET_BYTE_ORDER == BIG_ENDIAN ? j
+ : REGISTER_RAW_SIZE (regnum) - 1 - j;
+ sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]);
+ ptr += 2;
+ }
+ ui_out_field_string (uiout, "value", buf);
+ /*fputs_filtered (buf, gdb_stdout); */
+ }
+ else
+ {
+ val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0, 0,
+ stb->stream, format, 1, 0, Val_pretty_default);
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_stream_delete (stb);
+ }
+ return 1;
+}
+
+#if 0
+/*This is commented out because we decided it was not useful. I leave
+ it, just in case. ezannoni:1999-12-08 */
+
+/* Assign a value to a variable. The expression argument must be in
+ the form A=2 or "A = 2" (I.e. if there are spaces it needs to be
+ quoted. */
+enum mi_cmd_result
+mi_cmd_data_assign (char *command, char **argv, int argc)
+{
+ struct expression *expr;
+ struct cleanup *old_chain;
+
+ if (argc != 1)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_assign: Usage: -data-assign expression");
+ return MI_CMD_ERROR;
+ }
+
+ /* NOTE what follows is a clone of set_command(). FIXME: ezannoni
+ 01-12-1999: Need to decide what to do with this for libgdb purposes. */
+
+ expr = parse_expression (argv[0]);
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+ evaluate_expression (expr);
+ do_cleanups (old_chain);
+ return MI_CMD_DONE;
+}
+#endif
+
+/* Evaluate the value of the argument. The argument is an
+ expression. If the expression contains spaces it needs to be
+ included in double quotes. */
+enum mi_cmd_result
+mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
+{
+ struct expression *expr;
+ struct cleanup *old_chain = NULL;
+ value_ptr val;
+ struct ui_stream *stb = NULL;
+
+ stb = ui_out_stream_new (uiout);
+
+ if (argc != 1)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_evaluate_expression: Usage: -data-evaluate-expression expression");
+ return MI_CMD_ERROR;
+ }
+
+ expr = parse_expression (argv[0]);
+
+ old_chain = make_cleanup ((make_cleanup_func) free_current_contents, &expr);
+
+ val = evaluate_expression (expr);
+
+ /* Print the result of the expression evaluation. */
+ val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
+ VALUE_EMBEDDED_OFFSET (val), VALUE_ADDRESS (val),
+ stb->stream, 0, 0, 0, 0);
+
+ ui_out_field_stream (uiout, "value", stb);
+ ui_out_stream_delete (stb);
+
+ do_cleanups (old_chain);
+
+ return MI_CMD_DONE;
+}
+
+enum mi_cmd_result
+mi_cmd_target_download (char *args, int from_tty)
+{
+ char *run;
+ struct cleanup *old_cleanups = NULL;
+
+ asprintf (&run, "load %s", args);
+ if (run == 0)
+ internal_error ("mi_cmd_target_download: no memory");
+ old_cleanups = make_cleanup (free, run);
+ execute_command (run, from_tty);
+
+ do_cleanups (old_cleanups);
+ return MI_CMD_DONE;
+}
+
+/* Connect to the remote target. */
+enum mi_cmd_result
+mi_cmd_target_select (char *args, int from_tty)
+{
+ char *run;
+ struct cleanup *old_cleanups = NULL;
+
+ asprintf (&run, "target %s", args);
+ if (run == 0)
+ internal_error ("mi_cmd_target_select: no memory");
+ old_cleanups = make_cleanup (free, run);
+
+ /* target-select is always synchronous. once the call has returned
+ we know that we are connected. */
+ /* NOTE: At present all targets that are connected are also
+ (implicitly) talking to a halted target. In the future this may
+ change. */
+ execute_command (run, from_tty);
+
+ do_cleanups (old_cleanups);
+
+ /* Issue the completion message here. */
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("^connected", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+ do_exec_cleanups (ALL_CLEANUPS);
+ return MI_CMD_QUIET;
+}
+
+/* DATA-MEMORY-READ:
+
+ ADDR: start address of data to be dumped.
+ WORD-FORMAT: a char indicating format for the ``word''. See
+ the ``x'' command.
+ WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes
+ NR_ROW: Number of rows.
+ NR_COL: The number of colums (words per row).
+ ASCHAR: (OPTIONAL) Append an ascii character dump to each row. Use
+ ASCHAR for unprintable characters.
+
+ Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and
+ displayes them. Returns:
+
+ {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
+
+ Returns:
+ The number of bytes read is SIZE*ROW*COL. */
+
+enum mi_cmd_result
+mi_cmd_data_read_memory (char *command, char **argv, int argc)
+{
+ struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+ CORE_ADDR addr;
+ long total_bytes;
+ long nr_cols;
+ long nr_rows;
+ char word_format;
+ struct type *word_type;
+ long word_size;
+ char word_asize;
+ char aschar;
+ char *mbuf;
+ int nr_bytes;
+ long offset = 0;
+ int optind = 0;
+ char *optarg;
+ enum opt
+ {
+ OFFSET_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"o", OFFSET_OPT, 1},
+ 0
+ };
+
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case OFFSET_OPT:
+ offset = atol (optarg);
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (argc < 5 || argc > 6)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
+ return MI_CMD_ERROR;
+ }
+
+ /* Extract all the arguments. */
+
+ /* Start address of the memory dump. */
+ addr = parse_and_eval_address (argv[0]) + offset;
+ /* The format character to use when displaying a memory word. See
+ the ``x'' command. */
+ word_format = argv[1][0];
+ /* The size of the memory word. */
+ word_size = atol (argv[2]);
+ switch (word_size)
+ {
+ case 1:
+ word_type = builtin_type_int8;
+ word_asize = 'b';
+ break;
+ case 2:
+ word_type = builtin_type_int16;
+ word_asize = 'h';
+ break;
+ case 4:
+ word_type = builtin_type_int32;
+ word_asize = 'w';
+ break;
+ case 8:
+ word_type = builtin_type_int64;
+ word_asize = 'g';
+ break;
+ default:
+ word_type = builtin_type_int8;
+ word_asize = 'b';
+ }
+ /* The number of rows */
+ nr_rows = atol (argv[3]);
+ if (nr_rows <= 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_read_memory: invalid number of rows.");
+ return MI_CMD_ERROR;
+ }
+ /* number of bytes per row. */
+ nr_cols = atol (argv[4]);
+ if (nr_cols <= 0)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_read_memory: invalid number of columns.");
+ }
+ /* The un-printable character when printing ascii. */
+ if (argc == 6)
+ aschar = *argv[5];
+ else
+ aschar = 0;
+
+ /* create a buffer and read it in. */
+ total_bytes = word_size * nr_rows * nr_cols;
+ mbuf = calloc (total_bytes, 1);
+ make_cleanup (free, mbuf);
+ if (mbuf == NULL)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_read_memory: out of memory.");
+ return MI_CMD_ERROR;
+ }
+ nr_bytes = 0;
+ while (nr_bytes < total_bytes)
+ {
+ int error;
+ long num = target_read_memory_partial (addr + nr_bytes, mbuf + nr_bytes,
+ total_bytes - nr_bytes,
+ &error);
+ if (num <= 0)
+ break;
+ nr_bytes += num;
+ }
+
+ /* output the header information. */
+ ui_out_field_core_addr (uiout, "addr", addr);
+ ui_out_field_int (uiout, "nr-bytes", nr_bytes);
+ ui_out_field_int (uiout, "total-bytes", total_bytes);
+ ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols);
+ ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols);
+ ui_out_field_core_addr (uiout, "next-page", addr + total_bytes);
+ ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes);
+
+ /* Build the result as a two dimentional table. */
+ {
+ struct ui_stream *stream = ui_out_stream_new (uiout);
+ int row;
+ int row_byte;
+ ui_out_list_begin (uiout, "memory");
+ for (row = 0, row_byte = 0;
+ row < nr_rows;
+ row++, row_byte += nr_cols * word_size)
+ {
+ int col;
+ int col_byte;
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_core_addr (uiout, "addr", addr + row_byte);
+ /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */
+ ui_out_list_begin (uiout, "data");
+ for (col = 0, col_byte = row_byte;
+ col < nr_cols;
+ col++, col_byte += word_size)
+ {
+ if (col_byte + word_size > nr_bytes)
+ {
+ ui_out_field_string (uiout, NULL, "N/A");
+ }
+ else
+ {
+ ui_file_rewind (stream->stream);
+ print_scalar_formatted (mbuf + col_byte, word_type, word_format,
+ word_asize, stream->stream);
+ ui_out_field_stream (uiout, NULL, stream);
+ }
+ }
+ ui_out_list_end (uiout);
+ if (aschar)
+ {
+ int byte;
+ ui_file_rewind (stream->stream);
+ for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++)
+ {
+ if (byte >= nr_bytes)
+ {
+ fputc_unfiltered ('X', stream->stream);
+ }
+ else if (mbuf[byte] < 32 || mbuf[byte] > 126)
+ {
+ fputc_unfiltered (aschar, stream->stream);
+ }
+ else
+ fputc_unfiltered (mbuf[byte], stream->stream);
+ }
+ ui_out_field_stream (uiout, "ascii", stream);
+ }
+ ui_out_list_end (uiout);
+ }
+ ui_out_stream_delete (stream);
+ ui_out_list_end (uiout);
+ }
+ do_cleanups (cleanups);
+ return MI_CMD_DONE;
+}
+
+/* DATA-MEMORY-WRITE:
+
+ COLUMN_OFFSET: optional argument. Must be preceeded by '-o'. The
+ offset from the beginning of the memory grid row where the cell to
+ be written is.
+ ADDR: start address of the row in the memory grid where the memory
+ cell is, if OFFSET_COLUMN is specified. Otherwise, the address of
+ the location to write to.
+ FORMAT: a char indicating format for the ``word''. See
+ the ``x'' command.
+ WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
+ VALUE: value to be written into the memory address.
+
+ Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE).
+
+ Prints nothing. */
+enum mi_cmd_result
+mi_cmd_data_write_memory (char *command, char **argv, int argc)
+{
+ CORE_ADDR addr;
+ char word_format;
+ long word_size;
+ /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big
+ enough when using a compiler other than GCC. */
+ LONGEST value;
+ unsigned char *buffer;
+ long offset = 0;
+ int optind = 0;
+ char *optarg;
+ enum opt
+ {
+ OFFSET_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"o", OFFSET_OPT, 1},
+ 0
+ };
+
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_data_write_memory", argc, argv, opts,
+ &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case OFFSET_OPT:
+ offset = atol (optarg);
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 4)
+ {
+ asprintf (&mi_error_message,
+ "mi_cmd_data_write_memory: Usage: [-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE.");
+ return MI_CMD_ERROR;
+ }
+
+ /* Extract all the arguments. */
+ /* Start address of the memory dump. */
+ addr = parse_and_eval_address (argv[0]);
+ /* The format character to use when displaying a memory word. See
+ the ``x'' command. */
+ word_format = argv[1][0];
+ /* The size of the memory word. */
+ word_size = atol (argv[2]);
+
+ /* Calculate the real address of the write destination. */
+ addr += (offset * word_size);
+
+ /* Get the value as a number */
+ value = parse_and_eval_address (argv[3]);
+ /* Get the value into an array */
+ buffer = (unsigned char *) xmalloc (word_size);
+ store_signed_integer (buffer, word_size, value);
+ /* Write it down to memory */
+ write_memory (addr, buffer, word_size);
+
+ return MI_CMD_DONE;
+}
+
+/* Execute a command within a safe environment. Return >0 for
+ ok. Return <0 for supress prompt. Return 0 to have the error
+ extracted from error_last_message(). */
+
+static int
+captured_mi_execute_command (void *data)
+{
+ struct mi_parse *context = data;
+ enum mi_cmd_result rc;
+
+ switch (context->op)
+ {
+
+ case MI_COMMAND:
+ /* A MI command was read from the input stream */
+ if (mi_debug_p)
+ /* FIXME: gdb_???? */
+ fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
+ context->token, context->command, context->args);
+ /* FIXME: cagney/1999-09-25: Rather than this convoluted
+ condition expression, each function should return an
+ indication of what action is required and then switch on
+ that. */
+ rc = mi_cmd_execute (context);
+ if (!target_can_async_p () || !target_executing)
+ {
+ /* print the result if there were no errors */
+ if (rc == MI_CMD_DONE)
+ {
+ fputs_unfiltered (context->token, raw_stdout);
+ fputs_unfiltered ("^done", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+ }
+ else if (rc == MI_CMD_ERROR)
+ {
+ if (mi_error_message)
+ {
+ fputs_unfiltered (context->token, raw_stdout);
+ fputs_unfiltered ("^error,msg=\"", raw_stdout);
+ fputstr_unfiltered (mi_error_message, '"', raw_stdout);
+ free (mi_error_message);
+ fputs_unfiltered ("\"\n", raw_stdout);
+ }
+ mi_out_rewind (uiout);
+ }
+ else if (rc == MI_CMD_CAUGHT_ERROR)
+ {
+ mi_out_rewind (uiout);
+ return 0;
+ }
+ else
+ mi_out_rewind (uiout);
+ }
+ else if (sync_execution)
+ /* Don't print the prompt. We are executing the target in
+ synchronous mode. */
+ return -1;
+ break;
+
+ case CLI_COMMAND:
+ /* A CLI command was read from the input stream */
+ /* This will be removed as soon as we have a complete set of
+ mi commands */
+ /* echo the command on the console. */
+ fprintf_unfiltered (gdb_stdlog, "%s\n", context->command);
+ /* FIXME: If the command string has something that looks like
+ a format spec (e.g. %s) we will get a core dump */
+ mi_execute_cli_command ("%s", context->command);
+ /* print the result */
+ /* FIXME: Check for errors here. */
+ fputs_unfiltered (context->token, raw_stdout);
+ fputs_unfiltered ("^done", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+ break;
+
+ }
+ return 1;
+}
+
+
+void
+mi_execute_command (char *cmd, int from_tty)
+{
+ struct mi_parse *command;
+
+ /* This is to handle EOF (^D). We just quit gdb. */
+ /* FIXME: we should call some API function here. */
+ if (cmd == 0)
+ quit_force (NULL, from_tty);
+
+ command = mi_parse (cmd);
+
+ if (command != NULL)
+ {
+ /* FIXME: cagney/1999-11-04: Can this use of catch_errors either
+ be pushed even further down or even eliminated? */
+ int rc = catch_errors (captured_mi_execute_command, command, "",
+ RETURN_MASK_ALL);
+ if (rc < 0)
+ {
+ /* The command is executing synchronously. Bail out early
+ suppressing the finished prompt. */
+ mi_parse_free (command);
+ return;
+ }
+ if (rc == 0)
+ {
+ char *msg = error_last_message ();
+ struct cleanup *cleanup = make_cleanup (free, msg);
+ /* The command execution failed and error() was called
+ somewhere */
+ fputs_unfiltered (command->token, raw_stdout);
+ fputs_unfiltered ("^error,msg=\"", raw_stdout);
+ fputstr_unfiltered (msg, '"', raw_stdout);
+ fputs_unfiltered ("\"\n", raw_stdout);
+ }
+ mi_parse_free (command);
+ }
+
+ gdb_flush (raw_stdout);
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ /* print any buffered hook code */
+ /* ..... */
+}
+
+static enum mi_cmd_result
+mi_cmd_execute (struct mi_parse *parse)
+{
+ if (parse->cmd->argv_func != NULL
+ || parse->cmd->args_func != NULL)
+ {
+ /* FIXME: We need to save the token because the command executed
+ may be asynchronous and need to print the token again.
+ In the future we can pass the token down to the func
+ and get rid of the last_async_command */
+ /* The problem here is to keep the token around when we launch
+ the target, and we want to interrupt it later on. The
+ interrupt command will have its own token, but when the
+ target stops, we must display the token corresponding to the
+ last execution command given. So we have another string where
+ we copy the token (previous_async_command), if this was
+ indeed the token of an execution command, and when we stop we
+ print that one. This is possible because the interrupt
+ command, when over, will copy that token back into the
+ default token string (last_async_command). */
+
+ if (target_executing)
+ {
+ if (!previous_async_command)
+ previous_async_command = xstrdup (last_async_command);
+ if (strcmp (parse->command, "exec-interrupt"))
+ {
+ fputs_unfiltered (parse->token, raw_stdout);
+ fputs_unfiltered ("^error,msg=\"", raw_stdout);
+ fputs_unfiltered ("Cannot execute command ", raw_stdout);
+ fputstr_unfiltered (parse->command, '"', raw_stdout);
+ fputs_unfiltered (" while target running", raw_stdout);
+ fputs_unfiltered ("\"\n", raw_stdout);
+ return MI_CMD_ERROR;
+ }
+ }
+ last_async_command = xstrdup (parse->token);
+ make_exec_cleanup ((make_cleanup_func) free_and_reset, &last_async_command);
+ /* FIXME: DELETE THIS! */
+ if (parse->cmd->args_func != NULL)
+ return parse->cmd->args_func (parse->args, 0 /*from_tty */ );
+ return parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
+ }
+ else if (parse->cmd->cli != 0)
+ {
+ /* FIXME: DELETE THIS. */
+ /* The operation is still implemented by a cli command */
+ /* Must be a synchronous one */
+ mi_execute_cli_command (parse->cmd->cli, parse->args);
+ return MI_CMD_DONE;
+ }
+ else
+ {
+ /* FIXME: DELETE THIS. */
+ fputs_unfiltered (parse->token, raw_stdout);
+ fputs_unfiltered ("^error,msg=\"", raw_stdout);
+ fputs_unfiltered ("Undefined mi command: ", raw_stdout);
+ fputstr_unfiltered (parse->command, '"', raw_stdout);
+ fputs_unfiltered (" (missing implementation)", raw_stdout);
+ fputs_unfiltered ("\"\n", raw_stdout);
+ return MI_CMD_ERROR;
+ }
+}
+
+void
+free_and_reset (char **arg)
+{
+ free (*arg);
+ *arg = NULL;
+}
+
+static void
+mi_execute_command_wrapper (char *cmd)
+{
+ mi_execute_command (cmd, stdin == instream);
+}
+
+/* FIXME: This is just a hack so we can get some extra commands going.
+ We don't want to channel things through the CLI, but call libgdb directly */
+/* Use only for synchronous commands */
+
+void
+mi_execute_cli_command (const char *cli, char *args)
+{
+ if (cli != 0)
+ {
+ struct cleanup *old_cleanups;
+ char *run;
+ asprintf (&run, cli, args);
+ if (mi_debug_p)
+ /* FIXME: gdb_???? */
+ fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n",
+ cli, run);
+ if (run == 0)
+ abort ();
+ old_cleanups = make_cleanup (free, run);
+ execute_command ( /*ui */ run, 0 /*from_tty */ );
+ do_cleanups (old_cleanups);
+ return;
+ }
+}
+
+enum mi_cmd_result
+mi_execute_async_cli_command (char *mi, char *args, int from_tty)
+{
+ struct cleanup *old_cleanups;
+ char *run;
+ char *async_args;
+
+ if (target_can_async_p ())
+ {
+ async_args = (char *) xmalloc (strlen (args) + 2);
+ make_exec_cleanup (free, async_args);
+ strcpy (async_args, args);
+ strcat (async_args, "&");
+ asprintf (&run, "%s %s", mi, async_args);
+ if (run == 0)
+ internal_error ("mi_execute_async_cli_command: no memory");
+ make_exec_cleanup (free, run);
+ add_continuation (mi_exec_async_cli_cmd_continuation, NULL);
+ }
+ else
+ {
+ asprintf (&run, "%s %s", mi, args);
+ if (run == 0)
+ internal_error ("mi_execute_async_cli_command: no memory");
+ old_cleanups = make_cleanup (free, run);
+ }
+
+ if (!target_can_async_p ())
+ {
+ /* NOTE: For synchronous targets asynchronous behavour is faked by
+ printing out the GDB prompt before we even try to execute the
+ command. */
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("^running\n", raw_stdout);
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ }
+ else
+ {
+ /* FIXME: cagney/1999-11-29: Printing this message before
+ calling execute_command is wrong. It should only be printed
+ once gdb has confirmed that it really has managed to send a
+ run command to the target. */
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("^running\n", raw_stdout);
+ }
+
+ execute_command ( /*ui */ run, 0 /*from_tty */ );
+
+ if (!target_can_async_p ())
+ {
+ /* Do this before doing any printing. It would appear that some
+ print code leaves garbage around in the buffer. */
+ do_cleanups (old_cleanups);
+ /* If the target was doing the operation synchronously we fake
+ the stopped message. */
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("*stopped", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ mi_out_rewind (uiout);
+ fputs_unfiltered ("\n", raw_stdout);
+ return MI_CMD_QUIET;
+ }
+ return MI_CMD_DONE;
+}
+
+void
+mi_exec_async_cli_cmd_continuation (struct continuation_arg *arg)
+{
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("*stopped", raw_stdout);
+ mi_out_put (uiout, raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+ do_exec_cleanups (ALL_CLEANUPS);
+}
+
+static char *
+mi_input (char *buf)
+{
+ return gdb_readline (NULL);
+}
+
+static void
+mi_load_progress (const char *section_name,
+ unsigned long sent_so_far,
+ unsigned long total_section,
+ unsigned long total_sent,
+ unsigned long grand_total)
+{
+ struct timeval time_now, delta, update_threshold;
+ static struct timeval last_update;
+ static char *previous_sect_name = NULL;
+ int new_section;
+
+ if (!interpreter_p || strcmp (interpreter_p, "mi") != 0)
+ return;
+
+ update_threshold.tv_sec = 0;
+ update_threshold.tv_usec = 500000;
+ gettimeofday (&time_now, NULL);
+
+ delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
+ delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
+
+ if (delta.tv_usec < 0)
+ {
+ delta.tv_sec -= 1;
+ delta.tv_usec += 1000000;
+ }
+
+ new_section = (previous_sect_name ?
+ strcmp (previous_sect_name, section_name) : 1);
+ if (new_section)
+ {
+ free (previous_sect_name);
+ previous_sect_name = xstrdup (section_name);
+
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("+download", raw_stdout);
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_string (uiout, "section", section_name);
+ ui_out_field_int (uiout, "section-size", total_section);
+ ui_out_field_int (uiout, "total-size", grand_total);
+ ui_out_list_end (uiout);
+ mi_out_put (uiout, raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
+ gdb_flush (raw_stdout);
+ }
+
+ if (delta.tv_sec >= update_threshold.tv_sec &&
+ delta.tv_usec >= update_threshold.tv_usec)
+ {
+ last_update.tv_sec = time_now.tv_sec;
+ last_update.tv_usec = time_now.tv_usec;
+ if (last_async_command)
+ fputs_unfiltered (last_async_command, raw_stdout);
+ fputs_unfiltered ("+download", raw_stdout);
+ ui_out_list_begin (uiout, NULL);
+ ui_out_field_string (uiout, "section", section_name);
+ ui_out_field_int (uiout, "section-sent", sent_so_far);
+ ui_out_field_int (uiout, "section-size", total_section);
+ ui_out_field_int (uiout, "total-sent", total_sent);
+ ui_out_field_int (uiout, "total-size", grand_total);
+ ui_out_list_end (uiout);
+ mi_out_put (uiout, raw_stdout);
+ fputs_unfiltered ("\n", raw_stdout);
+ gdb_flush (raw_stdout);
+ }
+}
+
+static void
+mi_command_loop ()
+{
+ /* HACK: Force stdout/stderr to point at the console. This avoids
+ any potential side effects caused by legacy code that is still
+ using the TUI / fputs_unfiltered_hook */
+ raw_stdout = stdio_fileopen (stdout);
+ /* Route normal output through the MIx */
+ gdb_stdout = mi_console_file_new (raw_stdout, "~");
+ /* Route error and log output through the MI */
+ gdb_stderr = mi_console_file_new (raw_stdout, "&");
+ gdb_stdlog = gdb_stderr;
+ /* Route target output through the MI. */
+ gdb_stdtarg = mi_console_file_new (raw_stdout, "@");
+
+ /* HACK: Poke the ui_out table directly. Should we be creating a
+ mi_out object wired up to the above gdb_stdout / gdb_stderr? */
+ uiout = mi_out_new ();
+
+ /* HACK: Override any other interpreter hooks. We need to create a
+ real event table and pass in that. */
+ init_ui_hook = 0;
+ /* command_loop_hook = 0; */
+ print_frame_info_listing_hook = 0;
+ query_hook = 0;
+ warning_hook = 0;
+ create_breakpoint_hook = 0;
+ delete_breakpoint_hook = 0;
+ modify_breakpoint_hook = 0;
+ interactive_hook = 0;
+ registers_changed_hook = 0;
+ readline_begin_hook = 0;
+ readline_hook = 0;
+ readline_end_hook = 0;
+ register_changed_hook = 0;
+ memory_changed_hook = 0;
+ context_hook = 0;
+ target_wait_hook = 0;
+ call_command_hook = 0;
+ error_hook = 0;
+ error_begin_hook = 0;
+ show_load_progress = mi_load_progress;
+
+ /* Turn off 8 bit strings in quoted output. Any character with the
+ high bit set is printed using C's octal format. */
+ sevenbit_strings = 1;
+
+ /* Tell the world that we're alive */
+ fputs_unfiltered ("(gdb) \n", raw_stdout);
+
+ if (!event_loop_p)
+ simplified_command_loop (mi_input, mi_execute_command);
+ else
+ start_event_loop ();
+}
+
+static void
+setup_architecture_data ()
+{
+ /* don't trust REGISTER_BYTES to be zero. */
+ old_regs = xmalloc (REGISTER_BYTES + 1);
+ memset (old_regs, 0, REGISTER_BYTES + 1);
+}
+
+static void
+mi_init_ui (arg0)
+ char *arg0;
+{
+ /* Eventually this will contain code that takes control of the
+ console. */
+}
+
+void
+_initialize_mi_main ()
+{
+ /* If we're _the_ interpreter, take control. */
+ if (interpreter_p
+ && strcmp (interpreter_p, "mi") == 0)
+ {
+ init_ui_hook = mi_init_ui;
+ command_loop_hook = mi_command_loop;
+ setup_architecture_data ();
+ register_gdbarch_swap (&old_regs, sizeof (old_regs), NULL);
+ register_gdbarch_swap (NULL, 0, setup_architecture_data);
+ if (event_loop_p)
+ {
+ /* These overwrite some of the initialization done in
+ _intialize_event_loop. */
+ call_readline = gdb_readline2;
+ input_handler = mi_execute_command_wrapper;
+ add_file_handler (input_fd, stdin_event_handler, 0);
+ async_command_editing_p = 0;
+ }
+ }
+ /* FIXME: Should we notify main that we are here as a possible
+ interpreter? */
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
new file mode 100644
index 00000000000..c389097cf6c
--- /dev/null
+++ b/gdb/mi/mi-out.c
@@ -0,0 +1,401 @@
+/* MI Command Set - output generating routines.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "ui-out.h"
+#include "mi-out.h"
+
+/* Convenience macro for allocting typesafe memory. */
+
+#ifndef XMALLOC
+#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE))
+#endif
+
+struct ui_out_data
+ {
+ int supress_field_separator;
+ int first_header;
+ struct ui_file *buffer;
+ };
+
+/* These are the MI output functions */
+
+static void mi_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid);
+static void mi_table_body (struct ui_out *uiout);
+static void mi_table_end (struct ui_out *uiout);
+static void mi_table_header (struct ui_out *uiout, int width,
+ enum ui_align alig, char *colhdr);
+static void mi_list_begin (struct ui_out *uiout, int list_flag, char *lstid);
+static void mi_list_end (struct ui_out *uiout, int list_flag);
+static void mi_field_int (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, char *fldname, int value);
+static void mi_field_skip (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, char *fldname);
+static void mi_field_string (struct ui_out *uiout, int fldno, int width,
+ enum ui_align alig, char *fldname,
+ const char *string);
+static void mi_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ char *fldname, char *format, va_list args);
+static void mi_spaces (struct ui_out *uiout, int numspaces);
+static void mi_text (struct ui_out *uiout, char *string);
+static void mi_message (struct ui_out *uiout, int verbosity, char *format,
+ va_list args);
+static void mi_wrap_hint (struct ui_out *uiout, char *identstring);
+static void mi_flush (struct ui_out *uiout);
+
+/* This is the MI ui-out implementation functions vector */
+
+/* FIXME: This can be initialized dynamically after default is set to
+ handle initial output in main.c */
+
+struct ui_out_impl mi_ui_out_impl =
+{
+ mi_table_begin,
+ mi_table_body,
+ mi_table_end,
+ mi_table_header,
+ mi_list_begin,
+ mi_list_end,
+ mi_field_int,
+ mi_field_skip,
+ mi_field_string,
+ mi_field_fmt,
+ mi_spaces,
+ mi_text,
+ mi_message,
+ mi_wrap_hint,
+ mi_flush
+};
+
+/* Prototypes for local functions */
+
+extern void _initialize_mi_out PARAMS ((void));
+static void field_separator (struct ui_out *uiout);
+static void list_open (struct ui_out *uiout);
+static void list_close (struct ui_out *uiout);
+
+static void out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
+ char *format,...);
+
+/* Mark beginning of a table */
+
+void
+mi_table_begin (uiout, nbrofcols, tblid)
+ struct ui_out *uiout;
+ int nbrofcols;
+ char *tblid;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ field_separator (uiout);
+ if (tblid)
+ fprintf_unfiltered (data->buffer, "%s=", tblid);
+ list_open (uiout);
+ data->first_header = 0;
+ data->supress_field_separator = 1;
+}
+
+/* Mark beginning of a table body */
+
+void
+mi_table_body (uiout)
+ struct ui_out *uiout;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ /* close the table header line if there were any headers */
+ if (data->first_header)
+ list_close (uiout);
+}
+
+/* Mark end of a table */
+
+void
+mi_table_end (uiout)
+ struct ui_out *uiout;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ list_close (uiout);
+ /* If table was empty this flag did not get reset yet */
+ data->supress_field_separator = 0;
+}
+
+/* Specify table header */
+
+void
+mi_table_header (uiout, width, alignment, colhdr)
+ struct ui_out *uiout;
+ int width;
+ int alignment;
+ char *colhdr;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (!data->first_header++)
+ {
+ fputs_unfiltered ("hdr=", data->buffer);
+ list_open (uiout);
+ }
+ mi_field_string (uiout, 0, width, alignment, 0, colhdr);
+}
+
+/* Mark beginning of a list */
+
+void
+mi_list_begin (uiout, list_flag, lstid)
+ struct ui_out *uiout;
+ int list_flag;
+ char *lstid;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ field_separator (uiout);
+ data->supress_field_separator = 1;
+ if (lstid)
+ fprintf_unfiltered (data->buffer, "%s=", lstid);
+ list_open (uiout);
+}
+
+/* Mark end of a list */
+
+void
+mi_list_end (uiout, list_flag)
+ struct ui_out *uiout;
+ int list_flag;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ list_close (uiout);
+ /* If list was empty this flag did not get reset yet */
+ data->supress_field_separator = 0;
+}
+
+/* output an int field */
+
+void
+mi_field_int (uiout, fldno, width, alignment, fldname, value)
+ struct ui_out *uiout;
+ int fldno;
+ int width;
+ int alignment;
+ char *fldname;
+ int value;
+{
+ char buffer[20]; /* FIXME: how many chars long a %d can become? */
+
+ sprintf (buffer, "%d", value);
+ mi_field_string (uiout, fldno, width, alignment, fldname, buffer);
+}
+
+/* used to ommit a field */
+
+void
+mi_field_skip (uiout, fldno, width, alignment, fldname)
+ struct ui_out *uiout;
+ int fldno;
+ int width;
+ int alignment;
+ char *fldname;
+{
+ mi_field_string (uiout, fldno, width, alignment, fldname, "");
+}
+
+/* other specific mi_field_* end up here so alignment and field
+ separators are both handled by mi_field_string */
+
+void
+mi_field_string (struct ui_out *uiout,
+ int fldno,
+ int width,
+ int align,
+ char *fldname,
+ const char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=", fldname);
+ fprintf_unfiltered (data->buffer, "\"");
+ if (string)
+ fputstr_unfiltered (string, '"', data->buffer);
+ fprintf_unfiltered (data->buffer, "\"");
+}
+
+/* This is the only field function that does not align */
+
+void
+mi_field_fmt (struct ui_out *uiout, int fldno,
+ int width, enum ui_align align,
+ char *fldname, char *format, va_list args)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=\"", fldname);
+ else
+ fputs_unfiltered ("\"", data->buffer);
+ vfprintf_unfiltered (data->buffer, format, args);
+ fputs_unfiltered ("\"", data->buffer);
+}
+
+void
+mi_spaces (uiout, numspaces)
+ struct ui_out *uiout;
+ int numspaces;
+{
+}
+
+void
+mi_text (uiout, string)
+ struct ui_out *uiout;
+ char *string;
+{
+}
+
+void
+mi_message (struct ui_out *uiout, int verbosity, char *format, va_list args)
+{
+}
+
+void
+mi_wrap_hint (uiout, identstring)
+ struct ui_out *uiout;
+ char *identstring;
+{
+ wrap_here (identstring);
+}
+
+void
+mi_flush (uiout)
+ struct ui_out *uiout;
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ gdb_flush (data->buffer);
+}
+
+/* local functions */
+
+/* Like mi_field_fmt, but takes a variable number of args
+ and makes a va_list and does not insert a separator */
+
+/* VARARGS */
+static void
+out_field_fmt (struct ui_out *uiout, int fldno, char *fldname,
+ char *format,...)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ va_list args;
+
+ field_separator (uiout);
+ if (fldname)
+ fprintf_unfiltered (data->buffer, "%s=\"", fldname);
+ else
+ fputs_unfiltered ("\"", data->buffer);
+
+ va_start (args, format);
+ vfprintf_unfiltered (data->buffer, format, args);
+
+ fputs_unfiltered ("\"", data->buffer);
+
+ va_end (args);
+}
+
+/* access to ui_out format private members */
+
+static void
+field_separator (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ if (data->supress_field_separator)
+ data->supress_field_separator = 0;
+ else
+ fputc_unfiltered (',', data->buffer);
+}
+
+static void
+list_open (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fputc_unfiltered ('{', data->buffer);
+}
+
+static void
+list_close (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fputc_unfiltered ('}', data->buffer);
+}
+
+/* add a string to the buffer */
+
+void
+mi_out_buffered (struct ui_out *uiout, char *string)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ fprintf_unfiltered (data->buffer, "%s", string);
+}
+
+/* clear the buffer */
+
+void
+mi_out_rewind (struct ui_out *uiout)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ ui_file_rewind (data->buffer);
+}
+
+/* dump the buffer onto the specified stream */
+
+static void
+do_write (void *data, const char *buffer, long length_buffer)
+{
+ ui_file_write (data, buffer, length_buffer);
+}
+
+void
+mi_out_put (struct ui_out *uiout,
+ struct ui_file *stream)
+{
+ struct ui_out_data *data = ui_out_data (uiout);
+ ui_file_put (data->buffer, do_write, stream);
+ ui_file_rewind (data->buffer);
+}
+
+/* initalize private members at startup */
+
+struct ui_out *
+mi_out_new (void)
+{
+ int flags = 0;
+ struct ui_out_data *data = XMALLOC (struct ui_out_data);
+ data->supress_field_separator = 0;
+ /* FIXME: This code should be using a ``string_file'' and not the
+ TUI buffer hack. */
+ data->buffer = mem_fileopen ();
+ return ui_out_new (&mi_ui_out_impl, data, flags);
+}
+
+/* standard gdb initialization hook */
+void
+_initialize_mi_out ()
+{
+ /* nothing happens here */
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
new file mode 100644
index 00000000000..ea2a2c62130
--- /dev/null
+++ b/gdb/mi/mi-out.h
@@ -0,0 +1,39 @@
+/* MI Command Set - MI output generating routines for GDB.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#ifndef MI_OUT_H
+#define MI_OUT_H 1
+
+#if __STDC__
+struct ui_out;
+struct ui_file;
+#endif
+
+extern struct ui_out *mi_out_new (void);
+extern void mi_out_put (struct ui_out *uiout, struct ui_file *stream);
+extern void mi_out_rewind (struct ui_out *uiout);
+extern void mi_out_buffered (struct ui_out *uiout, char *string);
+
+#endif /* MI_OUT_H */
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-parse.c b/gdb/mi/mi-parse.c
new file mode 100644
index 00000000000..d86f2eebec3
--- /dev/null
+++ b/gdb/mi/mi-parse.c
@@ -0,0 +1,243 @@
+/* MI Command Set - MI parser.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#include "defs.h"
+#include "mi-cmds.h"
+#include "mi-parse.h"
+
+#include <ctype.h>
+#include <string.h>
+
+#undef XMALLOC
+#define XMALLOC(TYPE) ((TYPE*) xmalloc (sizeof (TYPE)))
+
+static void
+mi_parse_argv (char *args, struct mi_parse *parse)
+{
+ char *chp = args;
+ int argc = 0;
+ char **argv = xmalloc ((argc + 1) * sizeof (char *));
+ argv[argc] = NULL;
+ while (1)
+ {
+ char *arg;
+ /* skip leading white space */
+ while (isspace (*chp))
+ chp++;
+ /* Three possibilities: EOF, quoted string, or other text. */
+ switch (*chp)
+ {
+ case '\0':
+ parse->argv = argv;
+ parse->argc = argc;
+ return;
+ case '"':
+ {
+ /* A quoted string. */
+ int len;
+ char *start = chp + 1;
+ /* Determine the buffer size. */
+ chp = start;
+ len = 0;
+ while (*chp != '\0' && *chp != '"')
+ {
+ if (*chp == '\\')
+ {
+ chp++;
+ if (parse_escape (&chp) <= 0)
+ {
+ /* Do not allow split lines or "\000" */
+ freeargv (argv);
+ return;
+ }
+ }
+ else
+ chp++;
+ len++;
+ }
+ /* Insist on a closing quote. */
+ if (*chp != '"')
+ {
+ freeargv (argv);
+ return;
+ }
+ /* Insist on trailing white space. */
+ if (chp[1] != '\0' && !isspace (chp[1]))
+ {
+ freeargv (argv);
+ return;
+ }
+ /* create the buffer. */
+ arg = xmalloc ((len + 1) * sizeof (char));
+ /* And copy the characters in. */
+ chp = start;
+ len = 0;
+ while (*chp != '\0' && *chp != '"')
+ {
+ if (*chp == '\\')
+ {
+ chp++;
+ arg[len] = parse_escape (&chp);
+ }
+ else
+ arg[len] = *chp++;
+ len++;
+ }
+ arg[len] = '\0';
+ chp++; /* that closing quote. */
+ break;
+ }
+ default:
+ {
+ /* An unquoted string. Accumulate all non blank
+ characters into a buffer. */
+ int len;
+ char *start = chp;
+ while (*chp != '\0' && !isspace (*chp))
+ {
+ chp++;
+ }
+ len = chp - start;
+ arg = xmalloc ((len + 1) * sizeof (char));
+ strncpy (arg, start, len);
+ arg[len] = '\0';
+ break;
+ }
+ }
+ /* Append arg to argv. */
+ argv = xrealloc (argv, (argc + 2) * sizeof (char *));
+ argv[argc++] = arg;
+ argv[argc] = NULL;
+ }
+}
+
+
+void
+mi_parse_free (struct mi_parse *parse)
+{
+ if (parse == NULL)
+ return;
+ if (parse->command != NULL)
+ free (parse->command);
+ if (parse->token != NULL)
+ free (parse->token);
+ if (parse->args != NULL)
+ free (parse->args);
+ if (parse->argv != NULL)
+ freeargv (parse->argv);
+ free (parse);
+}
+
+
+struct mi_parse *
+mi_parse (char *cmd)
+{
+ char *chp;
+ struct mi_parse *parse = XMALLOC (struct mi_parse);
+ memset (parse, 0, sizeof (*parse));
+
+ /* Before starting, skip leading white space. */
+ while (isspace (*cmd))
+ cmd++;
+
+ /* Find/skip any token and then extract it. */
+ for (chp = cmd; *chp >= '0' && *chp <= '9'; chp++)
+ ;
+ parse->token = xmalloc ((chp - cmd + 1) * sizeof (char *));
+ memcpy (parse->token, cmd, (chp - cmd));
+ parse->token[chp - cmd] = '\0';
+
+ /* This wasn't a real MI command. Return it as a CLI_COMMAND. */
+ if (*chp != '-')
+ {
+ while (isspace (*chp))
+ chp++;
+ parse->command = xstrdup (chp);
+ parse->op = CLI_COMMAND;
+ return parse;
+ }
+
+ /* Extract the command. */
+ {
+ char *tmp = chp + 1; /* discard ``-'' */
+ for (; *chp && !isspace (*chp); chp++)
+ ;
+ parse->command = xmalloc ((chp - tmp + 1) * sizeof (char *));
+ memcpy (parse->command, tmp, chp - tmp);
+ parse->command[chp - tmp] = '\0';
+ }
+
+ /* Find the command in the MI table. */
+ parse->cmd = mi_lookup (parse->command);
+ if (parse->cmd == NULL)
+ {
+ /* FIXME: This should be a function call. */
+ fprintf_unfiltered
+ (raw_stdout,
+ "%s^error,msg=\"Undefined MI command: %s\"\n",
+ parse->token, parse->command);
+ mi_parse_free (parse);
+ return NULL;
+ }
+
+ /* Skip white space following the command. */
+ while (isspace (*chp))
+ chp++;
+
+ /* For new argv commands, attempt to return the parsed argument
+ list. */
+ if (parse->cmd->argv_func != NULL)
+ {
+ mi_parse_argv (chp, parse);
+ if (parse->argv == NULL)
+ {
+ /* FIXME: This should be a function call. */
+ fprintf_unfiltered
+ (raw_stdout,
+ "%s^error,msg=\"Problem parsing arguments: %s %s\"\n",
+ parse->token, parse->command, chp);
+ mi_parse_free (parse);
+ return NULL;
+ }
+ }
+
+ /* FIXME: DELETE THIS */
+ /* For CLI and old ARGS commands, also return the remainder of the
+ command line as a single string. */
+ if (parse->cmd->args_func != NULL
+ || parse->cmd->cli != NULL)
+ {
+ parse->args = xstrdup (chp);
+ }
+
+ /* Fully parsed. */
+ parse->op = MI_COMMAND;
+ return parse;
+}
+
+void
+_initialize_mi_parse ()
+{
+}
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */
diff --git a/gdb/mi/mi-parse.h b/gdb/mi/mi-parse.h
new file mode 100644
index 00000000000..8206003ff1c
--- /dev/null
+++ b/gdb/mi/mi-parse.h
@@ -0,0 +1,59 @@
+/* MI Command Set - MI Command Parser.
+ Copyright (C) 2000, Free Software Foundation, Inc.
+ Contributed by Cygnus Solutions.
+
+ 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
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+
+#ifndef MI_PARSE_H
+#define MI_PARSE_H
+
+/* MI parser */
+
+enum mi_command_type
+ {
+ MI_COMMAND, CLI_COMMAND
+ };
+
+struct mi_parse
+ {
+ enum mi_command_type op;
+ char *command;
+ char *token;
+ const struct mi_cmd *cmd;
+ char *args;
+ char **argv;
+ int argc;
+ };
+
+/* Attempts to parse CMD returning a ``struct mi_command''. If CMD is
+ invalid, an error mesage is reported (MI format) and NULL is
+ returned. For a CLI_COMMAND, COMMAND, TOKEN and OP are initialized.
+ For an MI_COMMAND COMMAND, TOKEN, ARGS and OP are
+ initialized. Un-initialized fields are zero. */
+
+extern struct mi_parse *mi_parse (char *cmd);
+
+/* Free a command returned by mi_parse_command. */
+
+extern void mi_parse_free (struct mi_parse *cmd);
+
+#endif
+
+/* Local variables: */
+/* change-log-default-name: "ChangeLog-mi" */
+/* End: */