aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2001-04-01 09:07:08 +0000
committerEli Zaretskii <eliz@gnu.org>2001-04-01 09:07:08 +0000
commit0ee5478628133b6daedb04d236dfde8e8abfe953 (patch)
tree5478c8d9d8734e36c16e1d48d0200e58a10168b5
parentc534679c58f645dd74018e94d11e776f8c444ced (diff)
downloadgdb-0ee5478628133b6daedb04d236dfde8e8abfe953.zip
gdb-0ee5478628133b6daedb04d236dfde8e8abfe953.tar.gz
gdb-0ee5478628133b6daedb04d236dfde8e8abfe953.tar.bz2
* gdbint.texinfo (User Interface): A new section about ui_out
functions, based on text written by Fernando Nasser.
-rw-r--r--gdb/doc/ChangeLog3
-rw-r--r--gdb/doc/gdbint.texinfo583
2 files changed, 586 insertions, 0 deletions
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index a799d03..8f4611f 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,5 +1,8 @@
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.
2001-03-26 Eli Zaretskii <eliz@is.elta.co.il>
diff --git a/gdb/doc/gdbint.texinfo b/gdb/doc/gdbint.texinfo
index 9be4ffb..7f8697d 100644
--- a/gdb/doc/gdbint.texinfo
+++ b/gdb/doc/gdbint.texinfo
@@ -717,6 +717,7 @@ is the most common and most familiar, there are others.
@section Command Interpreter
@cindex command interpreter
+@cindex CLI
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
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
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 TUI