#include <ctype.h>
#include "defs.h"
#include "target.h"
#include "frame.h"
#include "value.h"
#include "mi-cmds.h"
#include "mi-main.h"
#include "ui-out.h"
#include "varobj.h"
#include "wrapper.h"
#include "interps.h"
#include "symtab.h"
#include "block.h"
#include "stack.h"
#include "dictionary.h"
#include "gdb_string.h"
#include "objfiles.h"
#include "gdb_regex.h"
extern void mi_report_var_creation (struct ui_out *uiout, struct varobj *var);
void mi_interp_stack_changed_hook (void);
void mi_interp_frame_changed_hook (int new_frame_number);
void mi_interp_context_hook (int thread_id);
struct re_pattern_buffer mi_symbol_filter;
static char *print_values_bad_input_string =
"Unknown value for PRINT_VALUES: must be: 0 or \"--no-values\", "
"1 or \"--all-values\", 2 or \"--simple-values\", "
"3 or \"--make-varobj\"";
void mi_print_frame_more_info (struct ui_out *uiout,
struct symtab_and_line *sal,
struct frame_info *fi);
static void list_args_or_locals (int locals, enum print_values values,
struct frame_info *fi,
int all_blocks);
static void print_syms_for_block (struct block *block,
struct frame_info *fi,
struct ui_stream *stb,
int locals,
int consts,
enum print_values values,
struct re_pattern_buffer *filter);
static void
print_globals_for_symtab (struct symtab *file_symtab,
struct ui_stream *stb,
enum print_values values,
int consts,
struct re_pattern_buffer *filter);
enum mi_cmd_result
mi_cmd_stack_list_frames (char *command, char **argv, int argc)
{
int frame_low;
int frame_high;
int i;
struct cleanup *cleanup_stack;
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
{
frame_low = -1;
frame_high = -1;
}
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.");
cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "stack");
for (;
fi && (i <= frame_high || frame_high == -1);
i++, fi = get_prev_frame (fi))
{
QUIT;
print_frame_info (fi ,
i ,
LOC_AND_ADDRESS ,
0 );
}
do_cleanups (cleanup_stack);
if (i < frame_high)
error ("mi_cmd_stack_list_frames: Not enough frames in stack.");
return MI_CMD_DONE;
}
static void
mi_print_frame_info_lite (struct ui_out *uiout,
int frame_num,
CORE_ADDR pc,
CORE_ADDR fp)
{
char num_buf[8];
struct cleanup *list_cleanup;
sprintf (num_buf, "%d", frame_num);
ui_out_text (uiout, "Frame ");
ui_out_text(uiout, num_buf);
ui_out_text(uiout, ": ");
list_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, num_buf);
ui_out_field_core_addr (uiout, "pc", pc);
ui_out_field_core_addr (uiout, "fp", fp);
ui_out_text (uiout, "\n");
do_cleanups (list_cleanup);
}
enum mi_cmd_result
mi_cmd_stack_list_frames_lite (char *command, char **argv, int argc)
{
int limit = 0;
int valid;
int count = 0;
#ifndef FAST_COUNT_STACK_DEPTH
int i;
struct frame_info *fi;
#endif
if (!target_has_stack)
error ("mi_cmd_stack_list_frames_lite: No stack.");
if ((argc > 2) || (argc == 1))
error ("mi_cmd_stack_list_frames_lite: Usage: [-limit max_frame_number]");
if (argc == 2)
{
if (strcmp (argv[0], "-limit") != 0)
error ("mi_cmd_stack_list_frames_lite: Invalid option.");
if (! isnumber (argv[1][0]))
error ("mi_cmd_stack_list_frames_lite: Invalid argument to -limit.");
limit = atoi (argv[1]);
}
else
limit = -1;
#ifdef FAST_COUNT_STACK_DEPTH
valid = FAST_COUNT_STACK_DEPTH (1, 0, -1, limit, &count, mi_print_frame_info_lite);
#else
{
struct cleanup *list_cleanup;
for (fi = get_current_frame (); fi ; fi = get_next_frame(fi))
;
fi = get_current_frame ();
if (fi == NULL)
error ("mi_cmd_stack_list_frames_lite: No frames in stack.");
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "frames");
for (i = 0; fi != NULL; (fi = get_prev_frame (fi)), i++)
{
QUIT;
if ((limit == 0) || (i < limit))
{
mi_print_frame_info_lite (uiout, i, get_frame_pc (fi),
get_frame_base(fi));
}
}
count = i;
valid = 1;
do_cleanups (list_cleanup);
}
#endif
ui_out_text (uiout, "Valid: ");
ui_out_field_int (uiout, "valid", valid);
ui_out_text (uiout, "\nCount: ");
ui_out_field_int (uiout, "count", count);
ui_out_text (uiout, "\n");
return MI_CMD_DONE;
}
void
mi_print_frame_more_info (struct ui_out *uiout,
struct symtab_and_line *sal,
struct frame_info *fi)
{
if (sal && sal->symtab && sal->symtab->dirname)
ui_out_field_string (uiout, "dir", sal->symtab->dirname);
}
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
frame_high = -1;
#ifdef FAST_COUNT_STACK_DEPTH
if (! FAST_COUNT_STACK_DEPTH (0, 0, frame_high, frame_high, &i, NULL))
#endif
{
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;
}
enum print_values
mi_decode_print_values (char *arg)
{
enum print_values print_values = 0;
if (strcmp (arg, "0") == 0
|| strcmp (arg, "--no-values") == 0)
print_values = PRINT_NO_VALUES;
else if (strcmp (arg, "1") == 0
|| strcmp (arg, "--all-values") == 0)
print_values = PRINT_ALL_VALUES;
else if (strcmp (arg, "2") == 0)
print_values = PRINT_MAKE_VAROBJ;
else if (strcmp (arg, "--simple-values") == 0)
print_values = PRINT_SIMPLE_VALUES;
else if (strcmp (arg, "3") == 0
|| strcmp (arg, "--make-varobjs") == 0)
print_values = PRINT_MAKE_VAROBJ;
else
print_values = PRINT_BAD_INPUT;
return print_values;
}
enum mi_cmd_result
mi_cmd_stack_list_locals (char *command, char **argv, int argc)
{
struct frame_info *frame;
enum print_values values;
int all_blocks;
if (argc < 1 || argc > 2)
error ("mi_cmd_stack_list_locals: Usage: PRINT_VALUES [ALL_BLOCKS]");
frame = get_selected_frame ();
values = mi_decode_print_values (argv[0]);
if (values == PRINT_BAD_INPUT)
error ("%s", print_values_bad_input_string);
if (argc >= 2)
all_blocks = atoi (argv[1]);
else
all_blocks = 0;
list_args_or_locals (1, values, frame, all_blocks);
return MI_CMD_DONE;
}
enum mi_cmd_result
mi_cmd_stack_list_args (char *command, char **argv, int argc)
{
int frame_low;
int frame_high;
int i;
enum print_values values;
struct frame_info *fi;
struct cleanup *cleanup_stack_args;
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
{
frame_low = -1;
frame_high = -1;
}
values = mi_decode_print_values (argv[0]);
if (values == PRINT_BAD_INPUT)
error ("%s", print_values_bad_input_string);
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.");
cleanup_stack_args = make_cleanup_ui_out_list_begin_end (uiout, "stack-args");
for (;
fi && (i <= frame_high || frame_high == -1);
i++, fi = get_prev_frame (fi))
{
struct cleanup *cleanup_frame;
QUIT;
cleanup_frame = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
ui_out_field_int (uiout, "level", i);
list_args_or_locals (0, values, fi, 0);
do_cleanups (cleanup_frame);
}
do_cleanups (cleanup_stack_args);
if (i < frame_high)
error ("mi_cmd_stack_list_args: Not enough frames in stack.");
return MI_CMD_DONE;
}
static void
list_args_or_locals (int locals, enum print_values values, struct frame_info *fi,
int all_blocks)
{
struct block *block = NULL;
struct cleanup *cleanup_list;
static struct ui_stream *stb = NULL;
stb = ui_out_stream_new (uiout);
cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, locals ? "locals" : "args");
if (all_blocks)
{
CORE_ADDR fstart;
CORE_ADDR endaddr;
int index;
int nblocks;
struct blockvector *bv;
fstart = get_pc_function_start (get_frame_pc (fi));
if (fstart == 0)
{
fstart = get_frame_pc (fi);
}
bv = blockvector_for_pc (fstart, &index);
if (bv == NULL)
{
error ("list_args_or_locals: Couldn't find block vector for pc %s.",
paddr_nz (fstart));
}
nblocks = BLOCKVECTOR_NBLOCKS (bv);
block = BLOCKVECTOR_BLOCK (bv, index);
endaddr = BLOCK_END (block);
while (BLOCK_END (block) <= endaddr)
{
print_syms_for_block (block, fi, stb, locals, 1,
values, NULL);
index++;
if (index == nblocks)
break;
block = BLOCKVECTOR_BLOCK (bv, index);
}
}
else
{
block = get_frame_block (fi, 0);
while (block != 0)
{
print_syms_for_block (block, fi, stb, locals, 1, values, NULL);
if (BLOCK_FUNCTION (block))
break;
else
block = BLOCK_SUPERBLOCK (block);
}
}
do_cleanups (cleanup_list);
ui_out_stream_delete (stb);
}
#define CURRENT_FRAME_COOKIE "*CURRENT FRAME*"
static int
parse_statics_globals_args (char **argv, int argc, char **filename_ptr, char ** shlibname_ptr,
enum print_values *values_ptr, struct re_pattern_buffer **filterp_ptr,
int *consts_ptr)
{
char *filter_arg;
int bad_args;
filter_arg = NULL;
*filename_ptr = NULL;
*shlibname_ptr = NULL;
bad_args = 0;
if (argc > 2 && argc < 5)
{
*filename_ptr = argv[0];
*shlibname_ptr = argv[1];
*values_ptr = mi_decode_print_values (argv[2]);
if (*values_ptr == PRINT_BAD_INPUT)
bad_args = 1;
if (argc == 4)
filter_arg = argv[3];
*consts_ptr = 0;
}
else if (argc == 5 || argc == 7 || argc == 9)
{
int got_values = 0;
while (argc > 0)
{
int step = 2;
if (strcmp (argv[0], "-file") == 0)
*filename_ptr = argv[1];
else if (strcmp (argv[0], "-shlib") == 0)
*shlibname_ptr = argv[1];
else if (strcmp (argv[0], "-filter") == 0)
filter_arg = argv[1];
else if (strcmp (argv[0], "-constants") == 0)
{
if (strcmp (argv[1], "1") == 0)
*consts_ptr = 1;
else if (strcmp (argv[1], "0") == 0)
*consts_ptr = 0;
else
{
bad_args = 1;
break;
}
}
else
{
*values_ptr = mi_decode_print_values (argv[0]);
if (*values_ptr != PRINT_BAD_INPUT)
{
got_values = 1;
step = 1;
}
else
{
bad_args = 1;
break;
}
}
argc -= step;
argv += step;
}
if (*filename_ptr == NULL || *shlibname_ptr == NULL || got_values == 0)
bad_args = 1;
}
else
bad_args = 1;
if (bad_args)
return 0;
if (filter_arg != NULL)
{
const char *msg;
msg = re_compile_pattern (filter_arg, strlen (filter_arg), &mi_symbol_filter);
if (msg)
error ("Error compiling regexp: \"%s\"", msg);
*filterp_ptr = &mi_symbol_filter;
}
else
*filterp_ptr = NULL;
return 1;
}
enum mi_cmd_result
mi_cmd_file_list_statics (char *command, char **argv, int argc)
{
enum print_values values;
char *shlibname, *filename;
struct block *block;
struct partial_symtab *file_ps;
struct symtab *file_symtab;
struct cleanup *cleanup_list;
struct ui_stream *stb;
struct re_pattern_buffer *filterp = NULL;
int consts = 1;
if (!parse_statics_globals_args (argv, argc, &filename, &shlibname, &values,
&filterp, &consts))
error ("mi_cmd_file_list_statics: Usage: -file FILE -shlib SHLIB"
" VALUES"
" [-filter FILTER] [-constants 0/1]");
if (strcmp (filename, CURRENT_FRAME_COOKIE) == 0)
{
CORE_ADDR pc;
struct obj_section *objsec;
pc = get_frame_pc (get_selected_frame ());
objsec = find_pc_section (pc);
if (objsec != NULL && objsec->objfile != NULL)
cleanup_list = make_cleanup_restrict_to_objfile (objsec->objfile);
else
cleanup_list = make_cleanup (null_cleanup, NULL);
file_ps = find_pc_psymtab (pc);
do_cleanups (cleanup_list);
}
else
{
if (*shlibname != '\0')
{
cleanup_list = make_cleanup_restrict_to_shlib (shlibname);
if (cleanup_list == (void *) -1)
{
error ("mi_cmd_file_list_statics: Could not find shlib \"%s\".", shlibname);
}
}
else
cleanup_list = make_cleanup (null_cleanup, NULL);
if (*filename != '\0')
{
file_ps = lookup_partial_symtab (filename);
if (file_ps == NULL)
if (lbasename(filename) != filename)
file_ps = lookup_partial_symtab (lbasename (filename));
}
else
file_ps = NULL;
do_cleanups (cleanup_list);
}
if (file_ps == NULL)
{
if (filename[0] == '\0' || strcmp (filename, CURRENT_FRAME_COOKIE) == 0)
{
cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, "statics");
do_cleanups (cleanup_list);
return MI_CMD_DONE;
}
else
error ("mi_cmd_file_list_statics: "
"Could not get symtab for file \"%s\".", filename);
}
file_symtab = PSYMTAB_TO_SYMTAB (file_ps);
if (file_symtab == NULL)
error ("Could not convert psymtab to symtab for file \"%s\"", filename);
block = BLOCKVECTOR_BLOCK (file_symtab->blockvector, STATIC_BLOCK);
stb = ui_out_stream_new (uiout);
cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, "statics");
print_syms_for_block (block, NULL, stb, -1, consts, values, filterp);
do_cleanups (cleanup_list);
ui_out_stream_delete (stb);
return MI_CMD_DONE;
}
static void
print_globals_for_symtab (struct symtab *file_symtab,
struct ui_stream *stb,
enum print_values values,
int consts,
struct re_pattern_buffer *filter)
{
struct block *block;
struct cleanup *cleanup_list;
block = BLOCKVECTOR_BLOCK (file_symtab->blockvector, GLOBAL_BLOCK);
cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, "globals");
print_syms_for_block (block, NULL, stb, -1, consts, values, filter);
do_cleanups (cleanup_list);
}
enum mi_cmd_result
mi_cmd_file_list_globals (char *command, char **argv, int argc)
{
enum print_values values;
char *shlibname, *filename;
struct partial_symtab *file_ps;
struct symtab *file_symtab;
struct ui_stream *stb;
struct re_pattern_buffer *filterp;
int consts = 1;
if (!parse_statics_globals_args (argv, argc, &filename, &shlibname, &values,
&filterp, &consts))
error ("mi_cmd_file_list_globals: Usage: -file FILE -shlib SHLIB"
" VALUES"
" [-filter FILTER] [-constants 0/1]");
stb = ui_out_stream_new (uiout);
if (*filename != '\0')
{
struct cleanup *cleanup_list;
if (*shlibname != '\0')
{
cleanup_list = make_cleanup_restrict_to_shlib (shlibname);
if (cleanup_list == (void *) -1)
{
error ("mi_cmd_file_list_globals: "
"Could not find shlib \"%s\".",
shlibname);
}
}
else
cleanup_list = make_cleanup (null_cleanup, NULL);
file_ps = lookup_partial_symtab (filename);
if (file_ps == NULL)
error ("mi_cmd_file_list_statics: "
"Could not get symtab for file \"%s\".",
filename);
do_cleanups (cleanup_list);
file_symtab = PSYMTAB_TO_SYMTAB (file_ps);
print_globals_for_symtab (file_symtab, stb, values,
consts, filterp);
}
else
{
if (*shlibname != '\0')
{
struct objfile *ofile, *requested_ofile = NULL;
struct partial_symtab *ps;
ALL_OBJFILES (ofile)
{
if (objfile_matches_name (ofile, shlibname) != objfile_no_match)
{
requested_ofile = ofile;
break;
}
}
if (requested_ofile == NULL)
error ("mi_file_list_globals: "
"Couldn't find shared library \"%s\"\n",
shlibname);
ALL_OBJFILE_PSYMTABS (requested_ofile, ps)
{
struct symtab *file_symtab;
file_symtab = PSYMTAB_TO_SYMTAB (ps);
if (!file_symtab)
continue;
if (file_symtab->primary)
{
struct cleanup *file_cleanup;
file_cleanup =
make_cleanup_ui_out_list_begin_end (uiout, "file");
ui_out_field_string (uiout, "filename",
file_symtab->filename);
print_globals_for_symtab (file_symtab, stb, values,
consts, filterp);
do_cleanups (file_cleanup);
}
}
}
else
{
struct objfile *ofile;
struct partial_symtab *ps;
ALL_OBJFILES (ofile)
{
struct cleanup *ofile_cleanup;
ofile_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "image");
if (ofile->name != NULL)
ui_out_field_string (uiout, "imagename", ofile->name);
else
ui_out_field_string (uiout, "imagename", "<unknown>");
ALL_OBJFILE_PSYMTABS (ofile, ps)
{
struct symtab *file_symtab;
file_symtab = PSYMTAB_TO_SYMTAB (ps);
if (!file_symtab)
continue;
if (file_symtab->primary)
{
struct cleanup *file_cleanup;
file_cleanup =
make_cleanup_ui_out_list_begin_end (uiout, "file");
ui_out_field_string (uiout, "filename",
file_symtab->filename);
print_globals_for_symtab (file_symtab, stb,
values,
consts, filterp);
do_cleanups (file_cleanup);
}
}
do_cleanups (ofile_cleanup);
}
}
}
ui_out_stream_delete (stb);
return MI_CMD_DONE;
}
static void
print_syms_for_block (struct block *block,
struct frame_info *fi,
struct ui_stream *stb,
int locals,
int consts,
enum print_values values,
struct re_pattern_buffer *filter)
{
int print_me;
struct symbol *sym;
struct dict_iterator iter;
struct ui_stream *error_stb;
struct cleanup *old_chain;
if (dict_empty (BLOCK_DICT (block)))
return;
error_stb = ui_out_stream_new (uiout);
old_chain = make_cleanup_ui_out_stream_delete (error_stb);
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
print_me = 0;
switch (SYMBOL_CLASS (sym))
{
default:
case LOC_UNDEF:
case LOC_CONST:
case LOC_TYPEDEF:
case LOC_LABEL:
case LOC_BLOCK:
case LOC_CONST_BYTES:
case LOC_UNRESOLVED:
case LOC_OPTIMIZED_OUT:
print_me = 0;
break;
case LOC_ARG:
case LOC_REF_ARG:
case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL_ARG:
case LOC_BASEREG_ARG:
case LOC_COMPUTED_ARG:
if (locals == 0)
print_me = 1;
break;
case LOC_STATIC:
if (locals == -1 || locals == 1)
print_me = 1;
break;
case LOC_LOCAL:
case LOC_BASEREG:
case LOC_REGISTER:
case LOC_COMPUTED:
if (locals == 1)
print_me = 1;
break;
}
if (print_me
&& !consts && (SYMBOL_TYPE (sym) != NULL)
&& TYPE_CONST (check_typedef (SYMBOL_TYPE (sym)))
&& (!(TYPE_CODE (check_typedef (SYMBOL_TYPE (sym))) == TYPE_CODE_PTR)))
print_me = 0;
if (print_me)
{
struct symbol *sym2;
int len = strlen (DEPRECATED_SYMBOL_NAME (sym));
if (filter && re_search (filter, DEPRECATED_SYMBOL_NAME (sym),
len, 0, len,
(struct re_registers *) 0) >= 0)
continue;
if (values == PRINT_NO_VALUES)
{
struct cleanup *tuple_cleanup;
tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", DEPRECATED_SYMBOL_NAME (sym));
do_cleanups (tuple_cleanup);
continue;
}
if (!locals)
sym2 = lookup_symbol (SYMBOL_NATURAL_NAME (sym),
block, VAR_DOMAIN,
(int *) NULL,
(struct symtab **) NULL);
else
sym2 = sym;
if (values == PRINT_MAKE_VAROBJ)
{
struct varobj *new_var;
struct cleanup *tuple_cleanup;
if (fi)
new_var = varobj_create (varobj_gen_name (),
DEPRECATED_SYMBOL_NAME (sym2),
get_frame_base (fi),
block,
USE_BLOCK_IN_FRAME);
else
new_var = varobj_create (varobj_gen_name (),
DEPRECATED_SYMBOL_NAME (sym2),
0,
block,
NO_FRAME_NEEDED);
if (new_var == NULL)
continue;
tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, "varobj");
ui_out_field_string (uiout, "exp", DEPRECATED_SYMBOL_NAME (sym));
if (new_var != NULL)
{
char *value_str;
struct ui_file *save_stderr;
save_stderr = gdb_stderr;
gdb_stderr = error_stb->stream;
if (gdb_varobj_get_value (new_var, &value_str))
{
ui_out_field_string (uiout, "value", value_str);
}
else
{
ui_out_field_stream (uiout, "value",
error_stb);
}
gdb_stderr = save_stderr;
}
else
ui_out_field_skip (uiout, "value");
mi_report_var_creation (uiout, new_var);
do_cleanups (tuple_cleanup);
}
else
{
struct cleanup *cleanup_tuple = NULL;
struct type *type;
cleanup_tuple =
make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
ui_out_field_string (uiout, "name", SYMBOL_PRINT_NAME (sym));
switch (values)
{
case PRINT_SIMPLE_VALUES:
type = check_typedef (sym2->type);
type_print (sym2->type, "", stb->stream, -1);
ui_out_field_stream (uiout, "type", stb);
if (TYPE_CODE (type) != TYPE_CODE_ARRAY
&& TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION)
{
print_variable_value (sym2, fi, stb->stream);
ui_out_field_stream (uiout, "value", stb);
}
do_cleanups (cleanup_tuple);
break;
case PRINT_ALL_VALUES:
print_variable_value (sym2, fi, stb->stream);
ui_out_field_stream (uiout, "value", stb);
do_cleanups (cleanup_tuple);
break;
default:
internal_error (__FILE__, __LINE__,
"Wrong print_values value for this branch.\n");
}
}
}
}
do_cleanups (old_chain);
}
enum mi_cmd_result
mi_cmd_stack_select_frame (char *command, char **argv, int argc)
{
if (!target_has_stack)
error ("mi_cmd_stack_select_frame: No stack.");
if (argc > 1)
error ("mi_cmd_stack_select_frame: Usage: [FRAME_SPEC]");
if (argc == 0)
select_frame_command (0, 1 );
else
select_frame_command (argv[0], 1 );
return MI_CMD_DONE;
}
void
mi_interp_stack_changed_hook (void)
{
struct ui_out *saved_ui_out = uiout;
struct cleanup *list_cleanup;
uiout = interp_ui_out (mi_interp);
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "MI_HOOK_RESULT");
ui_out_field_string (uiout, "HOOK_TYPE", "stack_changed");
do_cleanups (list_cleanup);
uiout = saved_ui_out;
}
void
mi_interp_frame_changed_hook (int new_frame_number)
{
struct ui_out *saved_ui_out = uiout;
struct cleanup *list_cleanup;
if (new_frame_number == -1)
return;
uiout = interp_ui_out (mi_interp);
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "MI_HOOK_RESULT");
ui_out_field_string (uiout, "HOOK_TYPE", "frame_changed");
ui_out_field_int (uiout, "frame", new_frame_number);
do_cleanups (list_cleanup);
uiout = saved_ui_out;
}
void
mi_interp_context_hook (int thread_id)
{
struct ui_out *saved_ui_out = uiout;
struct cleanup *list_cleanup;
uiout = interp_ui_out (mi_interp);
list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "MI_HOOK_RESULT");
ui_out_field_string (uiout, "HOOK_TYPE", "thread_changed");
ui_out_field_int (uiout, "thread", thread_id);
do_cleanups (list_cleanup);
uiout = saved_ui_out;
}