Browse Source
* Makefile.in (XMLFILES): Add osdata.dtd.
(SFILES): Add osdata.c.
(COMMON_OBS): Add osdata.o.
* linux-nat.c: Include pwd.h, sys/types.h, gdb_dirent.h and xml-support.h.
(linux_nat_xfer_osdata): New function.
(linux_xfer_partial): Handle TARGET_OBJECT_OSDATA.
* osdata.c: New file.
* osdata.h: New file.
* remote.c (PACKET_qXfer_osdata): New packet enum.
(remote_protocol_features): Add "qXfer:osdata:read".
(remote_read_qxfer): Handle TARGET_OBJECT_OSDATA.
(extended_remote_can_run): New.
(init_extended_remote_ops): Set to_can_run to
extended_remote_can_run.
(_initialize_remote): Add packet config command for
"qXfer:osdata:read".
* xml-support.c (obstack_xml_printf): New function.
* xml-support.h (obstack_xml_printf): Declare.
* target.c (target_get_osdata): New function.
* target.h (enum target_object): Add TARGET_OBJECT_OSDATA.
(target_os_data): Declare.
* features/osdata.dtd: New file.
* mi/mi-main.c (mi_list_thread_groups): Handle the --available
option.
cgen-1_1-branch
22 changed files with 1093 additions and 7 deletions
@ -0,0 +1,16 @@ |
|||
<!-- Copyright (C) 2008 Free Software Foundation, Inc. |
|||
|
|||
Copying and distribution of this file, with or without modification, |
|||
are permitted in any medium without royalty provided the copyright |
|||
notice and this notice are preserved. --> |
|||
|
|||
<!-- osdata: Root element with versioning --> |
|||
|
|||
<!ELEMENT osdata (item*)> |
|||
<!ATTLIST osdata version CDATA #FIXED "1.0"> |
|||
<!ATTLIST osdata type CDATA #REQUIRED> |
|||
|
|||
<!ELEMENT item (column*)> |
|||
|
|||
<!ELEMENT column (#PCDATA)> |
|||
<!ATTLIST column name CDATA #REQUIRED> |
|||
@ -0,0 +1,357 @@ |
|||
/* Routines for handling XML generic OS data provided by target.
|
|||
|
|||
Copyright (C) 2008 Free Software Foundation, Inc. |
|||
|
|||
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 3 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, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#include "defs.h" |
|||
#include "target.h" |
|||
#include "vec.h" |
|||
#include "xml-support.h" |
|||
#include "osdata.h" |
|||
#include "gdb_string.h" |
|||
#include "ui-out.h" |
|||
#include "gdbcmd.h" |
|||
|
|||
#if !defined(HAVE_LIBEXPAT) |
|||
|
|||
struct osdata * |
|||
osdata_parse (const char *xml) |
|||
{ |
|||
static int have_warned; |
|||
|
|||
if (!have_warned) |
|||
{ |
|||
have_warned = 1; |
|||
warning (_("Can not parse XML OS data; XML support was disabled " |
|||
"at compile time")); |
|||
} |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
#else /* HAVE_LIBEXPAT */ |
|||
|
|||
#include "xml-support.h" |
|||
|
|||
/* Internal parsing data passed to all XML callbacks. */ |
|||
struct osdata_parsing_data |
|||
{ |
|||
struct osdata *osdata; |
|||
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 <osdata> element. */ |
|||
|
|||
static void |
|||
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; |
|||
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); |
|||
osdata->type = xstrdup (type); |
|||
data->osdata = osdata; |
|||
} |
|||
|
|||
/* Handle the start of a <item> element. */ |
|||
|
|||
static void |
|||
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_item item = { NULL }; |
|||
VEC_safe_push (osdata_item_s, data->osdata->items, &item); |
|||
} |
|||
|
|||
/* Handle the start of a <column> element. */ |
|||
|
|||
static void |
|||
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; |
|||
data->property_name = xstrdup (name); |
|||
} |
|||
|
|||
/* Handle the end of a <column> element. */ |
|||
|
|||
static void |
|||
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 *osdata = data->osdata; |
|||
struct osdata_item *item = VEC_last (osdata_item_s, osdata->items); |
|||
struct osdata_column *col = VEC_safe_push (osdata_column_s, |
|||
item->columns, NULL); |
|||
|
|||
/* Transfer memory ownership. NAME was already strdup'ed. */ |
|||
col->name = data->property_name; |
|||
col->value = xstrdup (body_text); |
|||
data->property_name = NULL; |
|||
} |
|||
|
|||
/* Discard the constructed osdata (if an error occurs). */ |
|||
|
|||
static void |
|||
clear_parsing_data (void *p) |
|||
{ |
|||
struct osdata_parsing_data *data = p; |
|||
osdata_free (data->osdata); |
|||
data->osdata = NULL; |
|||
xfree (data->property_name); |
|||
data->property_name = NULL; |
|||
} |
|||
|
|||
/* The allowed elements and attributes for OS data object.
|
|||
The root element is a <osdata>. */ |
|||
|
|||
const struct gdb_xml_attribute column_attributes[] = { |
|||
{ "name", GDB_XML_AF_NONE, NULL, NULL }, |
|||
{ NULL, GDB_XML_AF_NONE, NULL, NULL } |
|||
}; |
|||
|
|||
const struct gdb_xml_element item_children[] = { |
|||
{ "column", column_attributes, NULL, |
|||
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, |
|||
osdata_start_column, osdata_end_column }, |
|||
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } |
|||
}; |
|||
|
|||
const struct gdb_xml_attribute osdata_attributes[] = { |
|||
{ "type", GDB_XML_AF_NONE, NULL, NULL }, |
|||
{ NULL, GDB_XML_AF_NONE, NULL, NULL } |
|||
}; |
|||
|
|||
const struct gdb_xml_element osdata_children[] = { |
|||
{ "item", NULL, item_children, |
|||
GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, |
|||
osdata_start_item, NULL }, |
|||
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } |
|||
}; |
|||
|
|||
const struct gdb_xml_element osdata_elements[] = { |
|||
{ "osdata", osdata_attributes, osdata_children, |
|||
GDB_XML_EF_NONE, osdata_start_osdata, NULL }, |
|||
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } |
|||
}; |
|||
|
|||
struct osdata * |
|||
osdata_parse (const char *xml) |
|||
{ |
|||
struct gdb_xml_parser *parser; |
|||
struct cleanup *before_deleting_result, *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); |
|||
|
|||
if (gdb_xml_parse (parser, xml) == 0) |
|||
/* Parsed successfully, don't need to delete the result. */ |
|||
discard_cleanups (before_deleting_result); |
|||
|
|||
do_cleanups (back_to); |
|||
return data.osdata; |
|||
} |
|||
#endif |
|||
|
|||
void |
|||
osdata_free (struct osdata *osdata) |
|||
{ |
|||
if (osdata == NULL) |
|||
return; |
|||
|
|||
if (osdata->items != NULL) |
|||
{ |
|||
struct osdata_item *item; |
|||
int ix; |
|||
for (ix = 0; |
|||
VEC_iterate (osdata_item_s, osdata->items, |
|||
ix, item); |
|||
ix++) |
|||
osdata_item_clear (item); |
|||
VEC_free (osdata_item_s, osdata->items); |
|||
} |
|||
|
|||
xfree (osdata); |
|||
} |
|||
|
|||
struct osdata *get_osdata (const char *type) |
|||
{ |
|||
struct osdata * osdata = NULL; |
|||
char *xml = target_get_osdata (type); |
|||
if (xml) |
|||
{ |
|||
if (xml[0] == '\0') |
|||
warning (_("Empty data returned by target. Wrong osdata type?")); |
|||
|
|||
osdata = osdata_parse (xml); |
|||
} |
|||
|
|||
if (!osdata) |
|||
error (_("Can not fetch data now.\n")); |
|||
|
|||
return osdata; |
|||
} |
|||
|
|||
const char * |
|||
get_osdata_column (struct osdata_item *item, const char *name) |
|||
{ |
|||
struct osdata_column *col; |
|||
int ix_cols; |
|||
|
|||
for (ix_cols = 0; |
|||
VEC_iterate (osdata_column_s, item->columns, |
|||
ix_cols, col); |
|||
ix_cols++) |
|||
if (strcmp (col->name, name) == 0) |
|||
return col->value; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
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.")); |
|||
|
|||
osdata = get_osdata (type); |
|||
|
|||
nprocs = 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; |
|||
|
|||
proc_tbl_chain |
|||
= make_cleanup_ui_out_table_begin_end (uiout, ncols, nprocs, |
|||
"OSDataTable"); |
|||
|
|||
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); |
|||
} |
|||
|
|||
ui_out_table_body (uiout); |
|||
|
|||
if (nprocs != 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; |
|||
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"); |
|||
|
|||
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); |
|||
|
|||
do_cleanups (chain); |
|||
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); |
|||
} |
|||
|
|||
extern initialize_file_ftype _initialize_osdata; /* -Wmissing-prototypes */ |
|||
|
|||
void |
|||
_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.")); |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
/* Routines for handling XML generic OS data provided by target.
|
|||
|
|||
Copyright (C) 2008 Free Software Foundation, Inc. |
|||
|
|||
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 3 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, see <http://www.gnu.org/licenses/>. */
|
|||
|
|||
#ifndef OSDATA_H |
|||
#define OSDATA_H |
|||
|
|||
#include "vec.h" |
|||
|
|||
typedef struct osdata_column |
|||
{ |
|||
char *name; |
|||
char *value; |
|||
} osdata_column_s; |
|||
DEF_VEC_O(osdata_column_s); |
|||
|
|||
typedef struct osdata_item |
|||
{ |
|||
VEC(osdata_column_s) *columns; |
|||
} osdata_item_s; |
|||
DEF_VEC_O(osdata_item_s); |
|||
|
|||
struct osdata |
|||
{ |
|||
char *type; |
|||
|
|||
VEC(osdata_item_s) *items; |
|||
}; |
|||
typedef struct osdata *osdata_p; |
|||
DEF_VEC_P(osdata_p); |
|||
|
|||
struct osdata *osdata_parse (const char *xml); |
|||
void osdata_free (struct osdata *); |
|||
struct osdata *get_osdata (const char *type); |
|||
const char *get_osdata_column (struct osdata_item *item, const char *name); |
|||
|
|||
#endif /* OSDATA_H */ |
|||
Loading…
Reference in new issue