2008-12-02 Pedro Alves * target.h (target_get_osdata): Describe. * osdata.h (make_cleanup_osdata_free): Declare. * osdata.c (osdata_item_clear): Define even if HAVE_LIBEXPAT is not defined. (osdata_free_cleanup): New. (make_cleanup_osdata_free): New. (get_osdata): Fix leak. (info_osdata_command): Use make_cleanup_osdata_free. (info_processes_command): Delete. (_initialize_osdata): Drop undocumented "info processes" alias. * mi/mi-main.c (mi_cmd_list_thread_groups): Fix leak. --- .pc/osdata.diff/gdb/target.h 2008-12-02 15:17:40.000000000 +0000 +++ gdb/target.h 2008-12-02 15:17:59.000000000 +0000 @@ -1286,6 +1286,12 @@ extern int target_resize_to_sections (st extern void remove_target_sections (bfd *abfd); +/* Read OS data object of type TYPE from the target, and return it in + XML format. The result is NUL-terminated and returned as a string, + allocated using xmalloc. If an error occurs or the transfer is + unsupported, NULL is returned. Empty objects are returned as + allocated but empty strings. */ + extern char *target_get_osdata (const char *type); --- .pc/osdata.diff/gdb/osdata.h 2008-12-02 15:17:40.000000000 +0000 +++ gdb/osdata.h 2008-12-02 15:17:59.000000000 +0000 @@ -46,6 +46,7 @@ DEF_VEC_P(osdata_p); struct osdata *osdata_parse (const char *xml); void osdata_free (struct osdata *); +struct cleanup *make_cleanup_osdata_free (struct osdata *data); struct osdata *get_osdata (const char *type); const char *get_osdata_column (struct osdata_item *item, const char *name); --- .pc/osdata.diff/gdb/osdata.c 2008-12-02 15:17:40.000000000 +0000 +++ gdb/osdata.c 2008-12-02 15:25:09.000000000 +0000 @@ -54,26 +54,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 @@ -205,6 +185,26 @@ osdata_parse (const char *xml) } #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) { @@ -226,16 +226,34 @@ osdata_free (struct osdata *osdata) xfree (osdata); } -struct osdata *get_osdata (const char *type) +static void +osdata_free_cleanup (void *arg) +{ + struct osdata *osdata = arg; + osdata_free (osdata); +} + +struct cleanup * +make_cleanup_osdata_free (struct osdata *data) +{ + 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?")); - + else osdata = osdata_parse (xml); + + do_cleanups (old_chain); } if (!osdata) @@ -264,8 +282,8 @@ void info_osdata_command (char *type, int from_tty) { struct osdata * osdata = NULL; - struct cleanup *proc_tbl_chain; struct osdata_item *last; + struct cleanup *old_chain; int ncols; int nprocs; @@ -274,6 +292,7 @@ info_osdata_command (char *type, int fro error (_("Argument required.")); osdata = get_osdata (type); + old_chain = make_cleanup_osdata_free (osdata); nprocs = VEC_length (osdata_item_s, osdata->items); @@ -283,8 +302,7 @@ info_osdata_command (char *type, int fro else ncols = 0; - proc_tbl_chain - = make_cleanup_ui_out_table_begin_end (uiout, ncols, nprocs, + make_cleanup_ui_out_table_begin_end (uiout, ncols, nprocs, "OSDataTable"); if (last && last->columns) @@ -310,14 +328,14 @@ info_osdata_command (char *type, int fro ix_items, item); ix_items++) { - struct cleanup *old_chain, *chain; + struct cleanup *old_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"); + make_cleanup_ui_out_tuple_begin_end (uiout, "item"); for (ix_cols = 0; VEC_iterate (osdata_column_s, item->columns, @@ -325,22 +343,13 @@ info_osdata_command (char *type, int fro 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); + do_cleanups (old_chain); } extern initialize_file_ftype _initialize_osdata; /* -Wmissing-prototypes */ @@ -350,8 +359,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.")); } --- .pc/osdata.diff/gdb/mi/mi-main.c 2008-12-02 15:17:40.000000000 +0000 +++ gdb/mi/mi-main.c 2008-12-02 15:22:06.000000000 +0000 @@ -377,7 +377,7 @@ mi_cmd_list_thread_groups (char *command if (argc > 0) id = argv[0]; - back_to = make_cleanup (&null_cleanup, NULL); + back_to = make_cleanup (null_cleanup, NULL); if (available && id) { @@ -385,10 +385,13 @@ mi_cmd_list_thread_groups (char *command } else if (available) { - struct osdata *data = get_osdata ("processes"); + struct osdata *data; struct osdata_item *item; int ix_items; + data = get_osdata ("processes"); + make_cleanup_osdata_free (data); + make_cleanup_ui_out_list_begin_end (uiout, "groups"); for (ix_items = 0;