* gdbint.texinfo (User Interface): A new section about ui_out
functions, based on text written by Fernando Nasser.
This commit is contained in:
parent
c534679c58
commit
0ee5478628
|
@ -1,5 +1,8 @@
|
||||||
2001-04-01 Eli Zaretskii <eliz@is.elta.co.il>
|
2001-04-01 Eli Zaretskii <eliz@is.elta.co.il>
|
||||||
|
|
||||||
|
* gdbint.texinfo (User Interface): A new section about ui_out
|
||||||
|
functions, based on text written by Fernando Nasser.
|
||||||
|
|
||||||
* stabs.texinfo: Change Permissions to GFDL. Update Copyright.
|
* stabs.texinfo: Change Permissions to GFDL. Update Copyright.
|
||||||
|
|
||||||
2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
|
2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
|
||||||
|
|
|
@ -717,6 +717,7 @@ is the most common and most familiar, there are others.
|
||||||
@section Command Interpreter
|
@section Command Interpreter
|
||||||
|
|
||||||
@cindex command interpreter
|
@cindex command interpreter
|
||||||
|
@cindex CLI
|
||||||
The command interpreter in @value{GDBN} is fairly simple. It is designed to
|
The command interpreter in @value{GDBN} is fairly simple. It is designed to
|
||||||
allow for the set of commands to be augmented dynamically, and also
|
allow for the set of commands to be augmented dynamically, and also
|
||||||
has a recursive subcommand capability, where the first argument to
|
has a recursive subcommand capability, where the first argument to
|
||||||
|
@ -747,6 +748,588 @@ replacement (if one exists). Note that the replacement string passed to
|
||||||
@code{deprecate_cmd} should be the full name of the command, i.e. the
|
@code{deprecate_cmd} should be the full name of the command, i.e. the
|
||||||
entire string the user should type at the command line.
|
entire string the user should type at the command line.
|
||||||
|
|
||||||
|
@section UI-Independent Output---the @code{ui_out} Functions
|
||||||
|
@c This section is based on the documentation written by Fernando
|
||||||
|
@c Nasser <fnasser@redhat.com>.
|
||||||
|
|
||||||
|
@cindex @code{ui_out} functions
|
||||||
|
The @code{ui_out} functions present an abstraction level for the
|
||||||
|
@value{GDBN} output code. They hide the specifics of different user
|
||||||
|
interfaces supported by @value{GDBN}, and thus free the programmer
|
||||||
|
from the need to write several versions of the same code, one each for
|
||||||
|
every UI, to produce output.
|
||||||
|
|
||||||
|
@subsection Overview and Terminology
|
||||||
|
|
||||||
|
In general, execution of each @value{GDBN} command produces some sort
|
||||||
|
of output, and can even generate an input request.
|
||||||
|
|
||||||
|
Output can be generated for the following purposes:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
to display a @emph{result} of an operation;
|
||||||
|
|
||||||
|
@item
|
||||||
|
to convey @emph{info} or produce side-effects of a requested
|
||||||
|
operation;
|
||||||
|
|
||||||
|
@item
|
||||||
|
to provide a @emph{notification} of an asynchronous event (including
|
||||||
|
progress indication of a prolonged asynchronous operation);
|
||||||
|
|
||||||
|
@item
|
||||||
|
to display @emph{error messages} (including warnings);
|
||||||
|
|
||||||
|
@item
|
||||||
|
to show @emph{debug data};
|
||||||
|
|
||||||
|
@item
|
||||||
|
to @emph{query} or prompt a user for input (a special case).
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
This section mainly concentrates on how to build result output,
|
||||||
|
although some of it also applies to other kinds of output.
|
||||||
|
|
||||||
|
Generation of output that displays the results of an operation
|
||||||
|
involves one or more of the following:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
output of the actual data
|
||||||
|
|
||||||
|
@item
|
||||||
|
formatting the output as appropriate for console output, to make it
|
||||||
|
easily readable by humans
|
||||||
|
|
||||||
|
@item
|
||||||
|
machine oriented formatting--a more terse formatting to allow for easy
|
||||||
|
parsing by programs which read @value{GDBN}'s output
|
||||||
|
|
||||||
|
@item
|
||||||
|
annotation, whose purpose is to help a GUI (such as GDBTK or Emacs) to
|
||||||
|
identify interesting parts in the output
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The @code{ui_out} routines take care of the first three aspects.
|
||||||
|
Annotations are provided by separate annotation routines. Note that
|
||||||
|
use of annotations for an interface between a GUI and @value{GDBN} is
|
||||||
|
deprecated.
|
||||||
|
|
||||||
|
Output can be in the form of a single item, which we call a
|
||||||
|
@dfn{field}; a @dfn{list} of fields; or a @dfn{table}, which is a list
|
||||||
|
of fields with a header. In a BNF-like form:
|
||||||
|
|
||||||
|
@example
|
||||||
|
<field> ::= any single item of data kept by gdb ;;
|
||||||
|
|
||||||
|
<list> ::= @{ <field> @} ;;
|
||||||
|
|
||||||
|
<table> ::= <header> @{ <list> @} ;;
|
||||||
|
|
||||||
|
<header> ::= @{ <column> @} ;;
|
||||||
|
|
||||||
|
<column> ::= <width> <alignment> <title> ;;
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@subsection General Conventions
|
||||||
|
|
||||||
|
All @code{ui_out} routines currently are of type @code{void}, except
|
||||||
|
for @code{ui_out_stream_new} which returns a pointer to the newly
|
||||||
|
created object.
|
||||||
|
|
||||||
|
The first parameter is always the @code{ui_out} vector object, a
|
||||||
|
pointer to a @code{struct ui_out}.
|
||||||
|
|
||||||
|
The @var{format} parameter is like in @code{printf} family of
|
||||||
|
functions. When it is present, there is usually also a variable list
|
||||||
|
of arguments used to satisfy the @code{%} specifiers in the supplied
|
||||||
|
format.
|
||||||
|
|
||||||
|
When a character string argument is not used in a @code{ui_out}
|
||||||
|
function call, a @code{NULL} pointer has to be supplied instead.
|
||||||
|
|
||||||
|
|
||||||
|
@subsection Table and List Functions
|
||||||
|
|
||||||
|
@cindex list output functions
|
||||||
|
@cindex table output functions
|
||||||
|
This section introduces @code{ui_out} routines for building lists and
|
||||||
|
tables. The routines to output the actual data items (fields) are
|
||||||
|
presented in the next section.
|
||||||
|
|
||||||
|
To recap: A @dfn{list} is a sequence of @dfn{fields} with information
|
||||||
|
about an object; a @dfn{table} is a list of lists, each on a separate
|
||||||
|
line, prefixed by a @dfn{header} line with the column @dfn{titles}.
|
||||||
|
|
||||||
|
Use the table functions if your output is composed of a list of fields
|
||||||
|
for several objects and the console output should have a header. Use
|
||||||
|
this even when you are listing just one object but you still want the
|
||||||
|
header.
|
||||||
|
|
||||||
|
Use the list functions for the output of each object of a table or if
|
||||||
|
your output consists of a single list of fields.
|
||||||
|
|
||||||
|
You can nest a list into a table, but not the other way around.
|
||||||
|
|
||||||
|
@cindex nesting level in @code{ui_out} functions
|
||||||
|
Lists can also be nested: some of your fields may be lists or
|
||||||
|
@dfn{tuples}--@code{@{@var{name},@var{value}@}} pairs. The maximum
|
||||||
|
nesting level is currently 4.
|
||||||
|
|
||||||
|
The overall structure of the table output code is something like this:
|
||||||
|
|
||||||
|
@example
|
||||||
|
ui_out_table_begin
|
||||||
|
ui_out_table_header
|
||||||
|
...
|
||||||
|
ui_out_table_body
|
||||||
|
ui_out_list_begin
|
||||||
|
ui_out_field_*
|
||||||
|
...
|
||||||
|
ui_out_list_end
|
||||||
|
...
|
||||||
|
ui_out_table_end
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here's the description of table- and list-related @code{ui_out}
|
||||||
|
functions:
|
||||||
|
|
||||||
|
@deftypefun void ui_out_table_begin (struct ui_out *@var{uiout}, int @var{nbrofcols}, char *@var{tblid})
|
||||||
|
The function @code{ui_out_table_begin} marks the beginning of the
|
||||||
|
output of a table. It should always be called before any other
|
||||||
|
@code{ui_out} function for a given table. @var{nbrofcols} is the
|
||||||
|
number of columns in the table, and @var{tblid} is an optional string
|
||||||
|
identifying the table. The string pointed to by @var{tblid} is copied
|
||||||
|
by the implementation of @code{ui_out_table_begin}, so the application
|
||||||
|
can free the string if it was @code{malloc}ed.
|
||||||
|
|
||||||
|
The companion function @code{ui_out_table_end}, described below, marks
|
||||||
|
the end of the table's output.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_table_header (struct ui_out *@var{uiout}, int @var{width}, enum ui_align @var{alignment}, char *@var{colhdr})
|
||||||
|
@code{ui_out_table_header} provides the header information for a
|
||||||
|
single table column. You call this function several times, one each
|
||||||
|
for every column of the table, after @code{ui_out_table_begin}, but
|
||||||
|
before @code{ui_out_table_body}.
|
||||||
|
|
||||||
|
The value of @var{width} gives the column width in characters. The
|
||||||
|
value of @var{alignment} is one of @code{left}, @code{center}, and
|
||||||
|
@code{right}, and it specifies how to align the header: left-justify,
|
||||||
|
center, or right-justify it. @var{colhdr} points to a string that
|
||||||
|
specifies the column header; the implementation copies that string, so
|
||||||
|
column header strings in @code{malloc}ed storage can be freed after
|
||||||
|
the call.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_table_body (struct ui_out *@var{uiout})
|
||||||
|
This function marks the end of header information and the beginning of
|
||||||
|
table body output. It doesn't by itself produce any data output; that
|
||||||
|
is done by the list and field output functions described below.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_table_end (struct ui_out *@var{uiout})
|
||||||
|
This function signals the end of a table's output. It should be
|
||||||
|
called after the table body has been produced by the list and field
|
||||||
|
output functions.
|
||||||
|
|
||||||
|
There should be exactly one call to @code{ui_out_table_end} for each
|
||||||
|
call to @code{ui_out_table_begin}, otherwise the @code{ui_out}
|
||||||
|
functions will signal an internal error.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
The output of the lists that represent the table rows must follow the
|
||||||
|
call to @code{ui_out_table_body} and precede the call to
|
||||||
|
@code{ui_out_table_end}. You produce the lists by calling
|
||||||
|
@code{ui_out_list_begin} and @code{ui_out_list_end}, with suitable
|
||||||
|
calls to functions which actually output fields between them.
|
||||||
|
|
||||||
|
@deftypefun void ui_out_list_begin (struct ui_out *@var{uiout}, char *@var{lstid})
|
||||||
|
This function marks the beginning or a list output. @var{lstid}
|
||||||
|
points to an optional string that identifies the list; it is copied by
|
||||||
|
the implementation, and so strings in @code{malloc}ed storage can be
|
||||||
|
freed after the call.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_list_end (struct ui_out *@var{uiout})
|
||||||
|
This function signals an end of a list output. There should be
|
||||||
|
exactly one call to @code{ui_out_list_end} for each call to
|
||||||
|
@code{ui_out_list_begin}, otherwise an internal @value{GDBN} error
|
||||||
|
will be signaled.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@subsection Item Output Functions
|
||||||
|
|
||||||
|
@cindex item output functions
|
||||||
|
@cindex field output functions
|
||||||
|
@cindex data output
|
||||||
|
The functions described below produce output for the actual data
|
||||||
|
items, or fields, which contain information about the object.
|
||||||
|
|
||||||
|
Choose the appropriate function accordingly to your particular needs.
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_fmt (struct ui_out *@var{uiout}, char *@var{fldname}, char *@var{format}, ...)
|
||||||
|
This is the most general output function. It produces the
|
||||||
|
representation of the data in the variable-length argument list
|
||||||
|
according to formatting specifications in @var{format}, a
|
||||||
|
@code{printf}-like format string. The optional argument @var{fldname}
|
||||||
|
supplies the name of the field. The data items themselves are
|
||||||
|
supplied as additional arguments after @var{format}.
|
||||||
|
|
||||||
|
This generic function should be used only when it is not possible to
|
||||||
|
use one of the specialized versions (see below).
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_int (struct ui_out *@var{uiout}, char *@var{fldname}, int @var{value})
|
||||||
|
This function outputs a value of an @code{int} variable. It uses the
|
||||||
|
@code{"%d"} output conversion specification. @var{fldname} specifies
|
||||||
|
the name of the field.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_core_addr (struct ui_out *@var{uiout}, char *@var{fldname}, CORE_ADDR @var{address})
|
||||||
|
This function outputs an address.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_string (struct ui_out *@var{uiout}, char *@var{fldname}, const char *@var{string})
|
||||||
|
This function outputs a string using the @code{"%s"} conversion
|
||||||
|
specification.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
Sometimes, there's a need to compose your output piece by piece using
|
||||||
|
functions that operate on a stream, such as @code{value_print} or
|
||||||
|
@code{fprintf_symbol_filtered}. These functions accept an argument of
|
||||||
|
the type @code{struct ui_file *}, a pointer to a @code{ui_file} object
|
||||||
|
used to store the data stream used for the output. When you use one
|
||||||
|
of these functions, you need a way to pass their results stored in a
|
||||||
|
@code{ui_file} object to the @code{ui_out} functions. To this end,
|
||||||
|
you first create a @code{ui_stream} object by calling
|
||||||
|
@code{ui_out_stream_new}, pass the @code{stream} member of that
|
||||||
|
@code{ui_stream} object to @code{value_print} and similar functions,
|
||||||
|
and finally call @code{ui_out_field_stream} to output the field you
|
||||||
|
constructed. When the @code{ui_stream} object is no longer needed,
|
||||||
|
you should destroy it and free its memory by calling
|
||||||
|
@code{ui_out_stream_delete}.
|
||||||
|
|
||||||
|
@deftypefun struct ui_stream *ui_out_stream_new (struct ui_out *@var{uiout})
|
||||||
|
This function creates a new @code{ui_stream} object which uses the
|
||||||
|
same output methods as the @code{ui_out} object whose pointer is
|
||||||
|
passed in @var{uiout}. It returns a pointer to the newly created
|
||||||
|
@code{ui_stream} object.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_stream_delete (struct ui_stream *@var{streambuf})
|
||||||
|
This functions destroys a @code{ui_stream} object specified by
|
||||||
|
@var{streambuf}.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_stream (struct ui_out *@var{uiout}, char *@var{fieldname}, struct ui_stream *@var{streambuf})
|
||||||
|
This function consumes all the data accumulated in
|
||||||
|
@code{streambuf->stream} and outputs it like
|
||||||
|
@code{ui_out_field_string} does. After a call to
|
||||||
|
@code{ui_out_field_stream}, the accumulated data no longer exists, but
|
||||||
|
the stream is still valid and may be used for producing more fields.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@strong{Important:} If there is any chance that your code could bail
|
||||||
|
out before completing output generation and reaching the point where
|
||||||
|
@code{ui_out_stream_delete} is called, it is necessary to set up a
|
||||||
|
cleanup, to avoid leaking memory and other resources. Here's a
|
||||||
|
skeleton code to do that:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
struct ui_stream *mybuf = ui_out_stream_new (uiout);
|
||||||
|
struct cleanup *old = make_cleanup (ui_out_stream_delete, mybuf);
|
||||||
|
...
|
||||||
|
do_cleanups (old);
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
If the function already has the old cleanup chain set (for other kinds
|
||||||
|
of cleanups), you just have to add your cleanup to it:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
mybuf = ui_out_stream_new (uiout);
|
||||||
|
make_cleanup (ui_out_stream_delete, mybuf);
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
Note that with cleanups in place, you should not call
|
||||||
|
@code{ui_out_stream_delete} directly, or you would attempt to free the
|
||||||
|
same buffer twice.
|
||||||
|
|
||||||
|
@subsection Utility Output Functions
|
||||||
|
|
||||||
|
@deftypefun void ui_out_field_skip (struct ui_out *@var{uiout}, char *@var{fldname})
|
||||||
|
This function skips a field in a table. Use it if you have to leave
|
||||||
|
an empty field without disrupting the table alignment. The argument
|
||||||
|
@var{fldname} specifies a name for the (missing) filed.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_text (struct ui_out *@var{uiout}, char *@var{string})
|
||||||
|
This function outputs the text in @var{string} in a way that makes it
|
||||||
|
easy to be read by humans. For example, the console implementation of
|
||||||
|
this method filters the text through a built-in pager, to prevent it
|
||||||
|
from scrolling off the visible portion of the screen.
|
||||||
|
|
||||||
|
Use this function for printing relatively long chunks of text around
|
||||||
|
the actual field data: the text it produces is not aligned according
|
||||||
|
to the table's format. Use @code{ui_out_field_string} to output a
|
||||||
|
string field, and use @code{ui_out_message}, described below, to
|
||||||
|
output short messages.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_spaces (struct ui_out *@var{uiout}, int @var{nspaces})
|
||||||
|
This function outputs @var{nspaces} spaces. It is handy to align the
|
||||||
|
text produced by @code{ui_out_text} with the rest of the table or
|
||||||
|
list.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_message (struct ui_out *@var{uiout}, int @var{verbosity}, char *@var{format}, ...)
|
||||||
|
This function produces a formatted message, provided that the current
|
||||||
|
verbosity level is at least as large as given by @var{verbosity}. The
|
||||||
|
current verbosity level is specified by the user with the @samp{set
|
||||||
|
verbositylevel} command.@footnote{As of this writing (April 2001),
|
||||||
|
setting verbosity level is not yet implemented, and is always returned
|
||||||
|
as zero. So calling @code{ui_out_message} with a @var{verbosity}
|
||||||
|
argument more than zero will cause the message to never be printed.}
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_wrap_hint (struct ui_out *@var{uiout}, char *@var{indent})
|
||||||
|
This function gives the console output filter (a paging filter) a hint
|
||||||
|
of where to break lines which are too long. Ignored for all other
|
||||||
|
output consumers. @var{indent}, if non-@code{NULL}, is the string to
|
||||||
|
be printed to indent the wrapped text on the next line; it must remain
|
||||||
|
accessible until the next call to @code{ui_out_wrap_hint}, or until an
|
||||||
|
explicit newline is produced by one of the other functions. If
|
||||||
|
@var{indent} is @code{NULL}, the wrapped text will not be indented.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
@deftypefun void ui_out_flush (struct ui_out *@var{uiout})
|
||||||
|
This function flushes whatever output has been accumulated so far, if
|
||||||
|
the UI buffers output.
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
|
|
||||||
|
@subsection Examples of Use of @code{ui_out} functions
|
||||||
|
|
||||||
|
@cindex using @code{ui_out} functions
|
||||||
|
@cindex @code{ui_out} functions, usage examples
|
||||||
|
This section gives some practical examples of using the @code{ui_out}
|
||||||
|
functions to generalize the old console-oriented code in
|
||||||
|
@value{GDBN}. The examples all come from functions defined on the
|
||||||
|
@file{breakpoints.c} file.
|
||||||
|
|
||||||
|
This example, from the @code{breakpoint_1} function, shows how to
|
||||||
|
produce a table.
|
||||||
|
|
||||||
|
The original code was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
if (!found_a_breakpoint++)
|
||||||
|
@{
|
||||||
|
annotate_breakpoints_headers ();
|
||||||
|
|
||||||
|
annotate_field (0);
|
||||||
|
printf_filtered ("Num ");
|
||||||
|
annotate_field (1);
|
||||||
|
printf_filtered ("Type ");
|
||||||
|
annotate_field (2);
|
||||||
|
printf_filtered ("Disp ");
|
||||||
|
annotate_field (3);
|
||||||
|
printf_filtered ("Enb ");
|
||||||
|
if (addressprint)
|
||||||
|
@{
|
||||||
|
annotate_field (4);
|
||||||
|
printf_filtered ("Address ");
|
||||||
|
@}
|
||||||
|
annotate_field (5);
|
||||||
|
printf_filtered ("What\n");
|
||||||
|
|
||||||
|
annotate_breakpoints_table ();
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here's the new version:
|
||||||
|
|
||||||
|
@example
|
||||||
|
if (!found_a_breakpoint++)
|
||||||
|
@{
|
||||||
|
annotate_breakpoints_headers ();
|
||||||
|
if (addressprint)
|
||||||
|
ui_out_table_begin (ui, 6);
|
||||||
|
else
|
||||||
|
ui_out_table_begin (ui, 5);
|
||||||
|
|
||||||
|
annotate_field (0);
|
||||||
|
ui_out_table_header (ui, 4, left, "Num");
|
||||||
|
annotate_field (1);
|
||||||
|
ui_out_table_header (ui, 15, left, "Type");
|
||||||
|
annotate_field (2);
|
||||||
|
ui_out_table_header (ui, 5, left, "Disp");
|
||||||
|
annotate_field (3);
|
||||||
|
ui_out_table_header (ui, 4, left, "Enb");
|
||||||
|
if (addressprint)
|
||||||
|
@{
|
||||||
|
annotate_field (4);
|
||||||
|
ui_out_table_header (ui, 11, left, "Address");
|
||||||
|
@}
|
||||||
|
annotate_field (5);
|
||||||
|
ui_out_table_header (ui, 40, left, "What");
|
||||||
|
|
||||||
|
ui_out_table_body (ui);
|
||||||
|
annotate_breakpoints_table ();
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This example, from the @code{print_one_breakpoint} function, shows how
|
||||||
|
to produce the actual data for the table whose structure was defined
|
||||||
|
in the above example. The original code was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_record ();
|
||||||
|
annotate_field (0);
|
||||||
|
printf_filtered ("%-3d ", b->number);
|
||||||
|
annotate_field (1);
|
||||||
|
if ((int)b->type > (sizeof(bptypes)/sizeof(bptypes[0]))
|
||||||
|
|| ((int) b->type != bptypes[(int) b->type].type))
|
||||||
|
internal_error ("bptypes table does not describe type #%d.",
|
||||||
|
(int)b->type);
|
||||||
|
printf_filtered ("%-14s ", bptypes[(int)b->type].description);
|
||||||
|
annotate_field (2);
|
||||||
|
printf_filtered ("%-4s ", bpdisps[(int)b->disposition]);
|
||||||
|
annotate_field (3);
|
||||||
|
printf_filtered ("%-3c ", bpenables[(int)b->enable]);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This is the new version:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_record ();
|
||||||
|
ui_out_list_begin (uiout, "bkpt");
|
||||||
|
annotate_field (0);
|
||||||
|
ui_out_field_int (uiout, "number", b->number);
|
||||||
|
annotate_field (1);
|
||||||
|
if (((int) b->type > (sizeof (bptypes) / sizeof (bptypes[0])))
|
||||||
|
|| ((int) b->type != bptypes[(int) b->type].type))
|
||||||
|
internal_error ("bptypes table does not describe type #%d.",
|
||||||
|
(int) b->type);
|
||||||
|
ui_out_field_string (uiout, "type", bptypes[(int)b->type].description);
|
||||||
|
annotate_field (2);
|
||||||
|
ui_out_field_string (uiout, "disp", bpdisps[(int)b->disposition]);
|
||||||
|
annotate_field (3);
|
||||||
|
ui_out_field_fmt (uiout, "enabled", "%c", bpenables[(int)b->enable]);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This example, also from @code{print_one_breakpoint}, shows how to
|
||||||
|
produce a complicated output field using the @code{print_expression}
|
||||||
|
functions which requires a stream to be passed. It also shows how to
|
||||||
|
automate stream destruction with cleanups. The original code was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
print_expression (b->exp, gdb_stdout);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The new version is:
|
||||||
|
|
||||||
|
@example
|
||||||
|
struct ui_stream *stb = ui_out_stream_new (uiout);
|
||||||
|
struct cleanup *old_chain = make_cleanup_ui_out_stream_delete (stb);
|
||||||
|
...
|
||||||
|
annotate_field (5);
|
||||||
|
print_expression (b->exp, stb->stream);
|
||||||
|
ui_out_field_stream (uiout, "what", local_stream);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This example, also from @code{print_one_breakpoint}, shows how to use
|
||||||
|
@code{ui_out_text} and @code{ui_out_field_string}. The original code
|
||||||
|
was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->dll_pathname == NULL)
|
||||||
|
printf_filtered ("<any library> ");
|
||||||
|
else
|
||||||
|
printf_filtered ("library \"%s\" ", b->dll_pathname);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
It became:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->dll_pathname == NULL)
|
||||||
|
@{
|
||||||
|
ui_out_field_string (uiout, "what", "<any library>");
|
||||||
|
ui_out_spaces (uiout, 1);
|
||||||
|
@}
|
||||||
|
else
|
||||||
|
@{
|
||||||
|
ui_out_text (uiout, "library \"");
|
||||||
|
ui_out_field_string (uiout, "what", b->dll_pathname);
|
||||||
|
ui_out_text (uiout, "\" ");
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The following example from @code{print_one_breakpoint} shows how to
|
||||||
|
use @code{ui_out_field_int} and @code{ui_out_spaces}. The original
|
||||||
|
code was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->forked_inferior_pid != 0)
|
||||||
|
printf_filtered ("process %d ", b->forked_inferior_pid);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
It became:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->forked_inferior_pid != 0)
|
||||||
|
@{
|
||||||
|
ui_out_text (uiout, "process ");
|
||||||
|
ui_out_field_int (uiout, "what", b->forked_inferior_pid);
|
||||||
|
ui_out_spaces (uiout, 1);
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Here's an example of using @code{ui_out_field_string}. The original
|
||||||
|
code was:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->exec_pathname != NULL)
|
||||||
|
printf_filtered ("program \"%s\" ", b->exec_pathname);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
It became:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (5);
|
||||||
|
if (b->exec_pathname != NULL)
|
||||||
|
@{
|
||||||
|
ui_out_text (uiout, "program \"");
|
||||||
|
ui_out_field_string (uiout, "what", b->exec_pathname);
|
||||||
|
ui_out_text (uiout, "\" ");
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Finally, here's an example of printing an address. The original code:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (4);
|
||||||
|
printf_filtered ("%s ",
|
||||||
|
local_hex_string_custom ((unsigned long) b->address, "08l"));
|
||||||
|
@end example
|
||||||
|
|
||||||
|
It became:
|
||||||
|
|
||||||
|
@example
|
||||||
|
annotate_field (4);
|
||||||
|
ui_out_field_core_addr (uiout, "Address", b->address);
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
@section Console Printing
|
@section Console Printing
|
||||||
|
|
||||||
@section TUI
|
@section TUI
|
||||||
|
|
Loading…
Reference in New Issue