X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fosdata.c;h=4ced6260fccd32004cc8fbfe7df36134bd2b694c;hb=ad43e107eb233dcef8e76da6328aa4e4d74afd84;hp=761f34ba53fa71b68e35f9d42193c18ed72b80d4;hpb=07e059b5a9cbdeab8bf2980e07e79f892a2da854;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/osdata.c b/gdb/osdata.c index 761f34ba53..4ced6260fc 100644 --- a/gdb/osdata.c +++ b/gdb/osdata.c @@ -1,6 +1,6 @@ /* Routines for handling XML generic OS data provided by target. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -22,7 +22,6 @@ #include "vec.h" #include "xml-support.h" #include "osdata.h" -#include "gdb_string.h" #include "ui-out.h" #include "gdbcmd.h" @@ -45,8 +44,6 @@ osdata_parse (const char *xml) #else /* HAVE_LIBEXPAT */ -#include "xml-support.h" - /* Internal parsing data passed to all XML callbacks. */ struct osdata_parsing_data { @@ -54,26 +51,6 @@ struct osdata_parsing_data char *property_name; }; -static void -osdata_item_clear (struct osdata_item *item) -{ - if (item->columns != NULL) - { - struct osdata_column *col; - int ix; - for (ix = 0; - VEC_iterate (osdata_column_s, item->columns, - ix, col); - ix++) - { - xfree (col->name); - xfree (col->value); - } - VEC_free (osdata_column_s, item->columns); - item->columns = NULL; - } -} - /* Handle the start of a element. */ static void @@ -81,15 +58,15 @@ osdata_start_osdata (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - struct osdata_parsing_data *data = user_data; + struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data; char *type; struct osdata *osdata; if (data->osdata) gdb_xml_error (parser, _("Seen more than on osdata element")); - type = VEC_index (gdb_xml_value_s, attributes, 0)->value; - osdata = XZALLOC (struct osdata); + type = (char *) xml_find_attribute (attributes, "type")->value; + osdata = XCNEW (struct osdata); osdata->type = xstrdup (type); data->osdata = osdata; } @@ -101,8 +78,9 @@ osdata_start_item (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - struct osdata_parsing_data *data = user_data; + struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data; struct osdata_item item = { NULL }; + VEC_safe_push (osdata_item_s, data->osdata->items, &item); } @@ -113,8 +91,10 @@ osdata_start_column (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - struct osdata_parsing_data *data = user_data; - const char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value; + struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data; + const char *name + = (const char *) xml_find_attribute (attributes, "name")->value; + data->property_name = xstrdup (name); } @@ -125,7 +105,7 @@ osdata_end_column (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, const char *body_text) { - struct osdata_parsing_data *data = user_data; + struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data; struct osdata *osdata = data->osdata; struct osdata_item *item = VEC_last (osdata_item_s, osdata->items); struct osdata_column *col = VEC_safe_push (osdata_column_s, @@ -142,7 +122,8 @@ osdata_end_column (struct gdb_xml_parser *parser, static void clear_parsing_data (void *p) { - struct osdata_parsing_data *data = p; + struct osdata_parsing_data *data = (struct osdata_parsing_data *) p; + osdata_free (data->osdata); data->osdata = NULL; xfree (data->property_name); @@ -185,26 +166,45 @@ const struct gdb_xml_element osdata_elements[] = { struct osdata * osdata_parse (const char *xml) { - struct gdb_xml_parser *parser; - struct cleanup *before_deleting_result, *back_to; + struct cleanup *back_to; struct osdata_parsing_data data = { NULL }; - back_to = make_cleanup (null_cleanup, NULL); - parser = gdb_xml_create_parser_and_cleanup (_("osdata"), - osdata_elements, &data); - gdb_xml_use_dtd (parser, "osdata.dtd"); - - before_deleting_result = make_cleanup (clear_parsing_data, &data); + back_to = make_cleanup (clear_parsing_data, &data); - if (gdb_xml_parse (parser, xml) == 0) - /* Parsed successfully, don't need to delete the result. */ - discard_cleanups (before_deleting_result); + if (gdb_xml_parse_quick (_("osdata"), "osdata.dtd", + osdata_elements, xml, &data) == 0) + { + /* Parsed successfully, don't need to delete the result. */ + discard_cleanups (back_to); + return data.osdata; + } do_cleanups (back_to); - return data.osdata; + return NULL; } #endif +static void +osdata_item_clear (struct osdata_item *item) +{ + if (item->columns != NULL) + { + struct osdata_column *col; + int ix; + + for (ix = 0; + VEC_iterate (osdata_column_s, item->columns, + ix, col); + ix++) + { + xfree (col->name); + xfree (col->value); + } + VEC_free (osdata_column_s, item->columns); + item->columns = NULL; + } +} + void osdata_free (struct osdata *osdata) { @@ -215,6 +215,7 @@ osdata_free (struct osdata *osdata) { struct osdata_item *item; int ix; + for (ix = 0; VEC_iterate (osdata_item_s, osdata->items, ix, item); @@ -226,20 +227,45 @@ osdata_free (struct osdata *osdata) xfree (osdata); } -struct osdata *get_osdata (const char *type) +static void +osdata_free_cleanup (void *arg) +{ + struct osdata *osdata = (struct osdata *) arg; + + osdata_free (osdata); +} + +struct cleanup * +make_cleanup_osdata_free (struct osdata *data) { - struct osdata * osdata = NULL; + return make_cleanup (osdata_free_cleanup, data); +} + +struct osdata * +get_osdata (const char *type) +{ + struct osdata *osdata = NULL; char *xml = target_get_osdata (type); + if (xml) { + struct cleanup *old_chain = make_cleanup (xfree, xml); + if (xml[0] == '\0') - warning (_("Empty data returned by target. Wrong osdata type?")); - - osdata = osdata_parse (xml); + { + if (type) + warning (_("Empty data returned by target. Wrong osdata type?")); + else + warning (_("Empty type list returned by target. No type data?")); + } + else + osdata = osdata_parse (xml); + + do_cleanups (old_chain); } - + if (!osdata) - error (_("Can not fetch data now.\n")); + error (_("Can not fetch data now.")); return osdata; } @@ -263,84 +289,122 @@ get_osdata_column (struct osdata_item *item, const char *name) void info_osdata_command (char *type, int from_tty) { - struct osdata * osdata = NULL; - struct cleanup *proc_tbl_chain; - struct osdata_item *last; - int ncols; - int nprocs; - - if (type == 0) - /* TODO: No type could mean "list availables types". */ - error (_("Argument required.")); + struct ui_out *uiout = current_uiout; + struct osdata *osdata = NULL; + struct osdata_item *last = NULL; + struct cleanup *old_chain; + int ncols = 0; + int nrows; + int col_to_skip = -1; osdata = get_osdata (type); + old_chain = make_cleanup_osdata_free (osdata); - nprocs = VEC_length (osdata_item_s, osdata->items); + nrows = VEC_length (osdata_item_s, osdata->items); - last = VEC_last (osdata_item_s, osdata->items); - if (last && last->columns) - ncols = VEC_length (osdata_column_s, last->columns); - else - ncols = 0; + if (!type && nrows == 0) + error (_("Available types of OS data not reported.")); + + if (!VEC_empty (osdata_item_s, osdata->items)) + { + last = VEC_last (osdata_item_s, osdata->items); + if (last->columns) + ncols = VEC_length (osdata_column_s, last->columns); + + /* As a special case, scan the listing of available data types + for a column named "Title", and only include it with MI + output; this column's normal use is for titles for interface + elements like menus, and it clutters up CLI output. */ + if (!type && !ui_out_is_mi_like_p (uiout)) + { + struct osdata_column *col; + int ix; + + for (ix = 0; + VEC_iterate (osdata_column_s, last->columns, ix, col); + ix++) + { + if (strcmp (col->name, "Title") == 0) + col_to_skip = ix; + } + /* Be sure to reduce the total column count, otherwise + internal errors ensue. */ + if (col_to_skip >= 0) + --ncols; + } + } + + make_cleanup_ui_out_table_begin_end (uiout, ncols, nrows, + "OSDataTable"); - proc_tbl_chain - = make_cleanup_ui_out_table_begin_end (uiout, ncols, nprocs, - "OSDataTable"); + /* With no columns/items, we just output an empty table, but we + still output the table. This matters for MI. */ + if (ncols == 0) + { + do_cleanups (old_chain); + return; + } if (last && last->columns) { struct osdata_column *col; int ix; + for (ix = 0; VEC_iterate (osdata_column_s, last->columns, ix, col); ix++) - ui_out_table_header (uiout, 10, ui_left, - col->name, col->name); + { + char col_name[32]; + + if (ix == col_to_skip) + continue; + + snprintf (col_name, 32, "col%d", ix); + ui_out_table_header (uiout, 10, ui_left, + col_name, col->name); + } } ui_out_table_body (uiout); - if (nprocs != 0) + if (nrows != 0) { struct osdata_item *item; int ix_items; + for (ix_items = 0; VEC_iterate (osdata_item_s, osdata->items, ix_items, item); ix_items++) { - struct cleanup *old_chain, *chain; - struct ui_stream *stb; + struct cleanup *old_chain; int ix_cols; struct osdata_column *col; - stb = ui_out_stream_new (uiout); - old_chain = make_cleanup_ui_out_stream_delete (stb); - chain = make_cleanup_ui_out_tuple_begin_end (uiout, "item"); + old_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "item"); for (ix_cols = 0; VEC_iterate (osdata_column_s, item->columns, ix_cols, col); ix_cols++) - ui_out_field_string (uiout, col->name, col->value); + { + char col_name[32]; + + if (ix_cols == col_to_skip) + continue; - do_cleanups (chain); + snprintf (col_name, 32, "col%d", ix_cols); + ui_out_field_string (uiout, col_name, col->value); + } + do_cleanups (old_chain); ui_out_text (uiout, "\n"); } } - do_cleanups (proc_tbl_chain); - - osdata_free (osdata); -} - -static void -info_processes_command (char *args, int from_tty) -{ - info_osdata_command ("processes", from_tty); + do_cleanups (old_chain); } extern initialize_file_ftype _initialize_osdata; /* -Wmissing-prototypes */ @@ -350,8 +414,4 @@ _initialize_osdata (void) { add_info ("os", info_osdata_command, _("Show OS data ARG.")); - - /* An alias for "info osdata processes". */ - add_info ("processes", info_processes_command, - _("List running processes on the target.")); }