From 8b93c6380e299446e645ece29bf77d26f5713529 Mon Sep 17 00:00:00 2001 From: Jason Molenda Date: Thu, 3 Feb 2000 04:14:45 +0000 Subject: import gdb-2000-02-02 snapshot --- gdb/ui-out.c | 1007 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1007 insertions(+) create mode 100644 gdb/ui-out.c (limited to 'gdb/ui-out.c') diff --git a/gdb/ui-out.c b/gdb/ui-out.c new file mode 100644 index 0000000..9e40011 --- /dev/null +++ b/gdb/ui-out.c @@ -0,0 +1,1007 @@ +/* Output generating routines for GDB. + Copyright 1999, 2000 Free Software Foundation, Inc. + Contributed by Cygnus Solutions. + Written by Fernando Nasser for Cygnus. + + 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 "gdb_string.h" +#include "expression.h" /* For language.h */ +#include "language.h" +#include "ui-out.h" + +/* Convenience macro for allocting typesafe memory. */ + +#undef XMALLOC +#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) + +/* table header structures */ + +struct ui_out_hdr + { + int colno; + int width; + int alignment; + char *colhdr; + struct ui_out_hdr *next; + }; + +/* The ui_out structure */ +/* Any change here requires a corresponding one in the initialization + of the default uiout, which is statically initialized */ + +struct ui_out + { + int flags; + /* specific implementation of ui-out */ + struct ui_out_impl *impl; + struct ui_out_data *data; + + /* if on, a table is being generated */ + int table_flag; + + /* if on, the body of a table is being generated */ + int body_flag; + + /* number of table columns (as specified in the table_begin call) */ + int table_columns; + + /* strinf identifying the table (as specified in the table_begin call) */ + char *table_id; + + /* if on, a list is being generated. The value is the level of nesting */ + int list_flag; + + /* we count each field; the first element is for non-list fields */ + int field_count[5]; + + /* points to the first header (if any) */ + struct ui_out_hdr *headerfirst; + + /* points to the last header (if any) */ + struct ui_out_hdr *headerlast; + + /* points to header of next column to format */ + struct ui_out_hdr *headercurr; + + }; + +/* These are the default implementation functions */ + +static void default_table_begin (struct ui_out *uiout, int nbrofcols, + char *tblid); +static void default_table_body (struct ui_out *uiout); +static void default_table_end (struct ui_out *uiout); +static void default_table_header (struct ui_out *uiout, int width, + enum ui_align alig, char *colhdr); +static void default_list_begin (struct ui_out *uiout, int list_flag, + char *lstid); +static void default_list_end (struct ui_out *uiout, int list_flag); +static void default_field_int (struct ui_out *uiout, int fldno, int width, + enum ui_align alig, char *fldname, int value); +static void default_field_skip (struct ui_out *uiout, int fldno, int width, + enum ui_align alig, char *fldname); +static void default_field_string (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname, + const char *string); +static void default_field_fmt (struct ui_out *uiout, int fldno, + int width, enum ui_align align, + char *fldname, char *format, va_list args); +static void default_spaces (struct ui_out *uiout, int numspaces); +static void default_text (struct ui_out *uiout, char *string); +static void default_message (struct ui_out *uiout, int verbosity, char *format, + va_list args); +static void default_wrap_hint (struct ui_out *uiout, char *identstring); +static void default_flush (struct ui_out *uiout); + +/* This is the default ui-out implementation functions vector */ + +struct ui_out_impl default_ui_out_impl = +{ + default_table_begin, + default_table_body, + default_table_end, + default_table_header, + default_list_begin, + default_list_end, + default_field_int, + default_field_skip, + default_field_string, + default_field_fmt, + default_spaces, + default_text, + default_message, + default_wrap_hint, + default_flush +}; + +/* The default ui_out */ + +struct ui_out def_uiout = +{ + 0, /* flags */ + &default_ui_out_impl, /* impl */ +}; + +/* Pointer to current ui_out */ +/* FIXME: This should not be a global, but something passed down from main.c + or top.c */ + +struct ui_out *uiout = &def_uiout; + +/* These are the interfaces to implementation functions */ + +static void uo_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid); +static void uo_table_body (struct ui_out *uiout); +static void uo_table_end (struct ui_out *uiout); +static void uo_table_header (struct ui_out *uiout, int width, + enum ui_align align, char *colhdr); +static void uo_list_begin (struct ui_out *uiout, int list_flag, char *lstid); +static void uo_list_end (struct ui_out *uiout, int list_flag); +static void uo_field_int (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname, int value); +static void uo_field_skip (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname); +static void uo_field_string (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname, const char *string); +static void uo_field_fmt (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname, + char *format, va_list args); +static void uo_spaces (struct ui_out *uiout, int numspaces); +static void uo_text (struct ui_out *uiout, char *string); +static void uo_message (struct ui_out *uiout, int verbosity, + char *format, va_list args); +static void uo_wrap_hint (struct ui_out *uiout, char *identstring); +static void uo_flush (struct ui_out *uiout); + +/* Prototypes for local functions */ + +extern void _initialize_ui_out (void); +static void append_header_to_list (struct ui_out *uiout, int width, int alignment, char *colhdr); +static int get_curr_header (struct ui_out *uiout, int *colno, int *width, + int *alignment, char **colhdr); +static void clear_header_list (struct ui_out *uiout); +static void verify_field_proper_position (struct ui_out *uiout); +static void verify_field_alignment (struct ui_out *uiout, int fldno, int *width, int *alignment); + +static void init_ui_out_state (struct ui_out *uiout); + +/* exported functions (ui_out API) */ + +/* Mark beginning of a table */ + +void +ui_out_table_begin (uiout, nbrofcols, tblid) + struct ui_out *uiout; + int nbrofcols; + char *tblid; +{ + if (uiout->table_flag) + internal_error ("gdb/ui_out.c: tables cannot be nested; table_begin found before \ +previous table_end."); + + uiout->table_flag = 1; + uiout->table_columns = nbrofcols; + if (tblid != NULL) + uiout->table_id = xstrdup (tblid); + else + uiout->table_id = NULL; + clear_header_list (uiout); + + uo_table_begin (uiout, nbrofcols, uiout->table_id); +} + +void +ui_out_table_body (uiout) + struct ui_out *uiout; +{ + if (!uiout->table_flag) + internal_error ("gdb/ui_out.c: table_body outside a table is not valid; it must be \ +after a table_begin and before a table_end."); + if (uiout->body_flag) + internal_error ("gdb/ui_out.c: extra table_body call not allowed; there must be \ +only one table_body after a table_begin and before a table_end."); + if (uiout->headercurr->colno != uiout->table_columns) + internal_error ("gdb/ui_out.c: number of headers differ from number of table \ +columns."); + + uiout->body_flag = 1; + uiout->headercurr = uiout->headerfirst; + + uo_table_body (uiout); +} + +void +ui_out_table_end (uiout) + struct ui_out *uiout; +{ + if (!uiout->table_flag) + internal_error ("gdb/ui_out.c: misplaced table_end or missing table_begin."); + + uiout->body_flag = 0; + uiout->table_flag = 0; + + uo_table_end (uiout); + + if (uiout->table_id) + free (uiout->table_id); + clear_header_list (uiout); +} + +void +ui_out_table_header (uiout, width, alignment, colhdr) + struct ui_out *uiout; + int width; + enum ui_align alignment; + char *colhdr; +{ + if (!uiout->table_flag || uiout->body_flag) + internal_error ("ui_out: table header must be specified after table_begin \ +and before table_body."); + + append_header_to_list (uiout, width, alignment, colhdr); + + uo_table_header (uiout, width, alignment, colhdr); +} + +void +ui_out_list_begin (uiout, lstid) + struct ui_out *uiout; + char *lstid; +{ + if (uiout->table_flag && !uiout->body_flag) + internal_error ("ui_out: table header or table_body expected; lists must be \ +specified after table_body."); + if (uiout->list_flag >= 4) + internal_error ("ui_out: list depth exceeded; only 4 levels of lists can be \ +nested."); + + uiout->list_flag++; + uiout->field_count[uiout->list_flag] = 0; + if (uiout->table_flag && (uiout->list_flag == 1)) + uiout->headercurr = uiout->headerfirst; + + uo_list_begin (uiout, uiout->list_flag, lstid); +} + +void +ui_out_list_end (uiout) + struct ui_out *uiout; +{ + if (!uiout->list_flag) + internal_error ("ui_out: misplaced list_end; there is no list to be closed."); + + uo_list_end (uiout, uiout->list_flag); + + uiout->list_flag--; +} + +void +ui_out_field_int (uiout, fldname, value) + struct ui_out *uiout; + char *fldname; + int value; +{ + int fldno; + int width; + int align; + + verify_field_proper_position (uiout); + + uiout->field_count[uiout->list_flag] += 1; + fldno = uiout->field_count[uiout->list_flag]; + + verify_field_alignment (uiout, fldno, &width, &align); + + uo_field_int (uiout, fldno, width, align, fldname, value); +} + +void +ui_out_field_core_addr (uiout, fldname, address) + struct ui_out *uiout; + char *fldname; + CORE_ADDR address; +{ + char addstr[20]; + + /* FIXME-32x64: need a print_address_numeric with field width */ + /* print_address_numeric (address, 1, local_stream); */ + strcpy (addstr, local_hex_string_custom ((unsigned long) address, "08l")); + + ui_out_field_string (uiout, fldname, addstr); +} + +void +ui_out_field_stream (uiout, fldname, buf) + struct ui_out *uiout; + char *fldname; + struct ui_stream *buf; +{ + long length; + char *buffer = ui_file_xstrdup (buf->stream, &length); + struct cleanup *old_cleanup = make_cleanup (free, buffer); + if (length > 0) + ui_out_field_string (uiout, fldname, buffer); + else + ui_out_field_skip (uiout, fldname); + ui_file_rewind (buf->stream); + do_cleanups (old_cleanup); +} + +/* used to ommit a field */ + +void +ui_out_field_skip (uiout, fldname) + struct ui_out *uiout; + char *fldname; +{ + int fldno; + int width; + int align; + + verify_field_proper_position (uiout); + + uiout->field_count[uiout->list_flag] += 1; + fldno = uiout->field_count[uiout->list_flag]; + + verify_field_alignment (uiout, fldno, &width, &align); + + uo_field_skip (uiout, fldno, width, align, fldname); +} + +void +ui_out_field_string (struct ui_out *uiout, + char *fldname, + const char *string) +{ + int fldno; + int width; + int align; + + verify_field_proper_position (uiout); + + uiout->field_count[uiout->list_flag] += 1; + fldno = uiout->field_count[uiout->list_flag]; + + verify_field_alignment (uiout, fldno, &width, &align); + + uo_field_string (uiout, fldno, width, align, fldname, string); +} + +/* VARARGS */ +void +ui_out_field_fmt (struct ui_out *uiout, char *fldname, char *format,...) +{ + va_list args; + int fldno; + int width; + int align; + + verify_field_proper_position (uiout); + + uiout->field_count[uiout->list_flag] += 1; + fldno = uiout->field_count[uiout->list_flag]; + + /* will not align, but has to call anyway */ + verify_field_alignment (uiout, fldno, &width, &align); + + va_start (args, format); + + uo_field_fmt (uiout, fldno, width, align, fldname, format, args); + + va_end (args); +} + +void +ui_out_spaces (uiout, numspaces) + struct ui_out *uiout; + int numspaces; +{ + uo_spaces (uiout, numspaces); +} + +void +ui_out_text (uiout, string) + struct ui_out *uiout; + char *string; +{ + uo_text (uiout, string); +} + +void +ui_out_message (struct ui_out *uiout, int verbosity, char *format,...) +{ + va_list args; + + va_start (args, format); + + uo_message (uiout, verbosity, format, args); + + va_end (args); +} + +struct ui_stream * +ui_out_stream_new (uiout) + struct ui_out *uiout; +{ + struct ui_stream *tempbuf; + + tempbuf = XMALLOC (struct ui_stream); + tempbuf->uiout = uiout; + tempbuf->stream = mem_fileopen (); + return tempbuf; +} + +void +ui_out_stream_delete (buf) + struct ui_stream *buf; +{ + ui_file_delete (buf->stream); + free (buf); +} + +static void +do_stream_delete (void *buf) +{ + ui_out_stream_delete (buf); +} + +struct cleanup * +make_cleanup_ui_out_stream_delete (struct ui_stream *buf) +{ + return make_cleanup (do_stream_delete, buf); +} + + +void +ui_out_wrap_hint (uiout, identstring) + struct ui_out *uiout; + char *identstring; +{ + uo_wrap_hint (uiout, identstring); +} + +void +ui_out_flush (uiout) + struct ui_out *uiout; +{ + uo_flush (uiout); +} + +/* set the flags specified by the mask given */ +int +ui_out_set_flags (uiout, mask) + struct ui_out *uiout; + int mask; +{ + int oldflags; + + uiout->flags != mask; + + return oldflags; +} + +/* clear the flags specified by the mask given */ +int +ui_out_clear_flags (uiout, mask) + struct ui_out *uiout; + int mask; +{ + int oldflags; + + uiout->flags &= ~mask; + + return oldflags; +} + +/* test the flags against the mask given */ +int +ui_out_test_flags (uiout, mask) + struct ui_out *uiout; + int mask; +{ + return (uiout->flags & mask); +} + +/* obtain the current verbosity level (as stablished by the + 'set verbositylevel' command */ + +int +ui_out_get_verblvl (uiout) + struct ui_out *uiout; +{ + /* FIXME: not implemented yet */ + return 0; +} + +#if 0 +void +ui_out_result_begin (uiout, class) + struct ui_out *uiout; + char *class; +{ +} + +void +ui_out_result_end (uiout) + struct ui_out *uiout; +{ +} + +void +ui_out_info_begin (uiout, class) + struct ui_out *uiout; + char *class; +{ +} + +void +ui_out_info_end (uiout) + struct ui_out *uiout; +{ +} + +void +ui_out_notify_begin (uiout, class) + struct ui_out *uiout; + char *class; +{ +} + +void +ui_out_notify_end (uiout) + struct ui_out *uiout; +{ +} + +void +ui_out_error_begin (uiout, class) + struct ui_out *uiout; + char *class; +{ +} + +void +ui_out_error_end (uiout) + struct ui_out *uiout; +{ +} +#endif + +#if 0 +void +gdb_error (ui_out * uiout, int severity, char *format,...) +{ + va_list args; +} + +void +gdb_query (uiout, qflags, qprompt) + struct ui_out *uiout; + int flags; + char *qprompt; +{ +} +#endif + +/* default gdb-out hook functions */ + +static void +default_table_begin (uiout, nbrofcols, tblid) + struct ui_out *uiout; + int nbrofcols; + char *tblid; +{ +} + +static void +default_table_body (uiout) + struct ui_out *uiout; +{ +} + +static void +default_table_end (uiout) + struct ui_out *uiout; +{ +} + +static void +default_table_header (uiout, width, alignment, colhdr) + struct ui_out *uiout; + int width; + enum ui_align alignment; + char *colhdr; +{ +} + +static void +default_list_begin (uiout, list_flag, lstid) + struct ui_out *uiout; + int list_flag; + char *lstid; +{ +} + +static void +default_list_end (uiout, list_flag) + struct ui_out *uiout; + int list_flag; +{ +} + +static void +default_field_int (uiout, fldno, width, align, fldname, value) + struct ui_out *uiout; + int fldno; + int width; + enum ui_align align; + char *fldname; + int value; +{ +} + +static void +default_field_skip (uiout, fldno, width, align, fldname) + struct ui_out *uiout; + int fldno; + int width; + enum ui_align align; + char *fldname; +{ +} + +static void +default_field_string (struct ui_out *uiout, + int fldno, + int width, + enum ui_align align, + char *fldname, + const char *string) +{ +} + +static void +default_field_fmt (uiout, fldno, width, align, fldname, format, args) + struct ui_out *uiout; + int fldno; + int width; + enum ui_align align; + char *fldname; + char *format; + va_list args; +{ +} + +static void +default_spaces (uiout, numspaces) + struct ui_out *uiout; + int numspaces; +{ +} + +static void +default_text (uiout, string) + struct ui_out *uiout; + char *string; +{ +} + +static void +default_message (uiout, verbosity, format, args) + struct ui_out *uiout; + int verbosity; + char *format; + va_list args; +{ +} + +static void +default_wrap_hint (uiout, identstring) + struct ui_out *uiout; + char *identstring; +{ +} + +static void +default_flush (uiout) + struct ui_out *uiout; +{ +} + +/* Interface to the implementation functions */ + +void +uo_table_begin (struct ui_out *uiout, int nbrofcols, char *tblid) +{ + if (!uiout->impl->table_begin) + return; + uiout->impl->table_begin (uiout, nbrofcols, tblid); +} + +void +uo_table_body (struct ui_out *uiout) +{ + if (!uiout->impl->table_body) + return; + uiout->impl->table_body (uiout); +} + +void +uo_table_end (struct ui_out *uiout) +{ + if (!uiout->impl->table_end) + return; + uiout->impl->table_end (uiout); +} + +void +uo_table_header (struct ui_out *uiout, int width, enum ui_align align, char *colhdr) +{ + if (!uiout->impl->table_header) + return; + uiout->impl->table_header (uiout, width, align, colhdr); +} + +void +uo_list_begin (struct ui_out *uiout, int list_flag, char *lstid) +{ + if (!uiout->impl->list_begin) + return; + uiout->impl->list_begin (uiout, list_flag, lstid); +} + +void +uo_list_end (struct ui_out *uiout, int list_flag) +{ + if (!uiout->impl->list_end) + return; + uiout->impl->list_end (uiout, list_flag); +} + +void +uo_field_int (struct ui_out *uiout, int fldno, int width, enum ui_align align, char *fldname, int value) +{ + if (!uiout->impl->field_int) + return; + uiout->impl->field_int (uiout, fldno, width, align, fldname, value); +} + +void +uo_field_skip (struct ui_out *uiout, int fldno, int width, enum ui_align align, char *fldname) +{ + if (!uiout->impl->field_skip) + return; + uiout->impl->field_skip (uiout, fldno, width, align, fldname); +} + +void +uo_field_string (struct ui_out *uiout, int fldno, int width, + enum ui_align align, char *fldname, const char *string) +{ + if (!uiout->impl->field_string) + return; + uiout->impl->field_string (uiout, fldno, width, align, fldname, string); +} + +void +uo_field_fmt (struct ui_out *uiout, int fldno, int width, enum ui_align align, char *fldname, char *format, va_list args) +{ + if (!uiout->impl->field_fmt) + return; + uiout->impl->field_fmt (uiout, fldno, width, align, fldname, format, args); +} + +void +uo_spaces (struct ui_out *uiout, int numspaces) +{ + if (!uiout->impl->spaces) + return; + uiout->impl->spaces (uiout, numspaces); +} + +void +uo_text (struct ui_out *uiout, char *string) +{ + if (!uiout->impl->text) + return; + uiout->impl->text (uiout, string); +} + +void +uo_message (struct ui_out *uiout, int verbosity, char *format, va_list args) +{ + if (!uiout->impl->message) + return; + uiout->impl->message (uiout, verbosity, format, args); +} + +void +uo_wrap_hint (struct ui_out *uiout, char *identstring) +{ + if (!uiout->impl->wrap_hint) + return; + uiout->impl->wrap_hint (uiout, identstring); +} + +void +uo_flush (struct ui_out *uiout) +{ + if (!uiout->impl->flush) + return; + uiout->impl->flush (uiout); +} + +/* local functions */ + +/* list of column headers manipulation routines */ + +static void +clear_header_list (uiout) + struct ui_out *uiout; +{ + while (uiout->headerfirst != NULL) + { + uiout->headercurr = uiout->headerfirst; + uiout->headerfirst = uiout->headerfirst->next; + if (uiout->headercurr->colhdr != NULL) + free (uiout->headercurr->colhdr); + free (uiout->headercurr); + } + uiout->headerlast = NULL; + uiout->headercurr = NULL; +} + +static void +append_header_to_list (struct ui_out *uiout, + int width, + int alignment, + char *colhdr) +{ + struct ui_out_hdr *temphdr; + + temphdr = XMALLOC (struct ui_out_hdr); + temphdr->width = width; + temphdr->alignment = alignment; + /* we have to copy the column title as the original may be an automatic */ + if (colhdr != NULL) + { + temphdr->colhdr = xmalloc (strlen (colhdr) + 1); + strcpy (temphdr->colhdr, colhdr); + } + temphdr->next = NULL; + if (uiout->headerfirst == NULL) + { + temphdr->colno = 1; + uiout->headerfirst = temphdr; + uiout->headerlast = temphdr; + } + else + { + temphdr->colno = uiout->headerlast->colno + 1; + uiout->headerlast->next = temphdr; + uiout->headerlast = temphdr; + } + uiout->headercurr = uiout->headerlast; +} + +/* returns 0 if there is no more headers */ + +static int +get_curr_header (struct ui_out *uiout, + int *colno, + int *width, + int *alignment, + char **colhdr) +{ + /* There may be no headers at all or we may have used all columns */ + if (uiout->headercurr == NULL) + return 0; + *colno = uiout->headercurr->colno; + *width = uiout->headercurr->width; + *alignment = uiout->headercurr->alignment; + *colhdr = uiout->headercurr->colhdr; + uiout->headercurr = uiout->headercurr->next; + return 1; +} + +/* makes sure the field_* calls were properly placed */ + +static void +verify_field_proper_position (struct ui_out *uiout) +{ + if (uiout->table_flag) + { + if (!uiout->body_flag) + internal_error ("ui_out: table_body missing; table fields must be \ +specified after table_body and inside a list."); + if (!uiout->list_flag) + internal_error ("ui_out: list_begin missing; table fields must be \ +specified after table_body and inside a list."); + } +} + +/* determines what is the alignment policy */ + +static void +verify_field_alignment (struct ui_out *uiout, + int fldno, + int *width, + int *align) +{ + int colno; + char *text; + + if (uiout->table_flag + && get_curr_header (uiout, &colno, width, align, &text)) + { + if (fldno != colno) + internal_error ("gdb/ui-out.c: ui-out internal error in handling headers."); + } + else + { + *width = 0; + *align = ui_noalign; + } +} + +/* access to ui_out format private members */ + +void +ui_out_get_field_separator (uiout) + struct ui_out *uiout; +{ +} + +/* Access to ui-out members data */ + +struct ui_out_data * +ui_out_data (struct ui_out *uiout) +{ + return uiout->data; +} + +/* initalize private members at startup */ + +struct ui_out * +ui_out_new (struct ui_out_impl *impl, + struct ui_out_data *data, + int flags) +{ + struct ui_out *uiout = XMALLOC (struct ui_out); + uiout->data = data; + uiout->impl = impl; + uiout->flags = flags; + uiout->table_flag = 0; + uiout->body_flag = 0; + uiout->list_flag = 0; + uiout->field_count[0] = 0; + uiout->headerfirst = NULL; + uiout->headerlast = NULL; + uiout->headercurr = NULL; + return uiout; +} + +/* standard gdb initialization hook */ + +void +_initialize_ui_out () +{ + /* nothing needs to be done */ +} -- cgit v1.1