GDB (xrefs)
/tmp/gdb-8.1/gdb/osdata.c
Go to the documentation of this file.
1 /* Routines for handling XML generic OS data provided by target.
2 
3  Copyright (C) 2008-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "defs.h"
21 #include "target.h"
22 #include "vec.h"
23 #include "xml-support.h"
24 #include "osdata.h"
25 #include "ui-out.h"
26 #include "gdbcmd.h"
27 
28 #if !defined(HAVE_LIBEXPAT)
29 
30 std::unique_ptr<osdata>
31 osdata_parse (const char *xml)
32 {
33  static int have_warned;
34 
35  if (!have_warned)
36  {
37  have_warned = 1;
38  warning (_("Can not parse XML OS data; XML support was disabled "
39  "at compile time"));
40  }
41 
42  return NULL;
43 }
44 
45 #else /* HAVE_LIBEXPAT */
46 
47 /* Internal parsing data passed to all XML callbacks. */
49 {
50  std::unique_ptr<struct osdata> osdata;
52 };
53 
54 /* Handle the start of a <osdata> element. */
55 
56 static void
58  const struct gdb_xml_element *element,
59  void *user_data, VEC(gdb_xml_value_s) *attributes)
60 {
61  struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data;
62 
63  if (data->osdata != NULL)
64  gdb_xml_error (parser, _("Seen more than on osdata element"));
65 
66  char *type = (char *) xml_find_attribute (attributes, "type")->value;
67  data->osdata.reset (new struct osdata (std::string (type)));
68 }
69 
70 /* Handle the start of a <item> element. */
71 
72 static void
74  const struct gdb_xml_element *element,
75  void *user_data, VEC(gdb_xml_value_s) *attributes)
76 {
77  struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data;
78  data->osdata->items.emplace_back ();
79 }
80 
81 /* Handle the start of a <column> element. */
82 
83 static void
85  const struct gdb_xml_element *element,
86  void *user_data, VEC(gdb_xml_value_s) *attributes)
87 {
88  struct osdata_parsing_data *data = (struct osdata_parsing_data *) user_data;
89  const char *name
90  = (const char *) xml_find_attribute (attributes, "name")->value;
91 
92  data->property_name.assign (name);
93 }
94 
95 /* Handle the end of a <column> element. */
96 
97 static void
99  const struct gdb_xml_element *element,
100  void *user_data, const char *body_text)
101 {
102  osdata_parsing_data *data = (struct osdata_parsing_data *) user_data;
103  struct osdata *osdata = data->osdata.get ();
104  osdata_item &item = osdata->items.back ();
105 
106  item.columns.emplace_back (std::move (data->property_name),
107  std::string (body_text));
108 }
109 
110 /* The allowed elements and attributes for OS data object.
111  The root element is a <osdata>. */
112 
114  { "name", GDB_XML_AF_NONE, NULL, NULL },
115  { NULL, GDB_XML_AF_NONE, NULL, NULL }
116 };
117 
118 const struct gdb_xml_element item_children[] = {
119  { "column", column_attributes, NULL,
122  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
123 };
124 
126  { "type", GDB_XML_AF_NONE, NULL, NULL },
127  { NULL, GDB_XML_AF_NONE, NULL, NULL }
128 };
129 
131  { "item", NULL, item_children,
133  osdata_start_item, NULL },
134  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
135 };
136 
138  { "osdata", osdata_attributes, osdata_children,
140  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
141 };
142 
143 std::unique_ptr<osdata>
144 osdata_parse (const char *xml)
145 {
146  osdata_parsing_data data;
147 
148  if (gdb_xml_parse_quick (_("osdata"), "osdata.dtd",
149  osdata_elements, xml, &data) == 0)
150  {
151  /* Parsed successfully, don't need to delete the result. */
152  return std::move (data.osdata);
153  }
154 
155  return NULL;
156 }
157 #endif
158 
159 std::unique_ptr<osdata>
160 get_osdata (const char *type)
161 {
162  std::unique_ptr<osdata> osdata;
164 
165  if (xml)
166  {
167  if (xml.get ()[0] == '\0')
168  {
169  if (type)
170  warning (_("Empty data returned by target. Wrong osdata type?"));
171  else
172  warning (_("Empty type list returned by target. No type data?"));
173  }
174  else
175  osdata = osdata_parse (xml.get ());
176  }
177 
178  if (osdata == NULL)
179  error (_("Can not fetch data now."));
180 
181  return osdata;
182 }
183 
184 const std::string *
185 get_osdata_column (const osdata_item &item, const char *name)
186 {
187  for (const osdata_column &col : item.columns)
188  if (col.name == name)
189  return &col.value;
190 
191  return NULL;
192 }
193 
194 void
195 info_osdata (const char *type)
196 {
197  struct ui_out *uiout = current_uiout;
198  struct osdata_item *last = NULL;
199  int ncols = 0;
200  int col_to_skip = -1;
201 
202  if (type == NULL)
203  type = "";
204 
205  std::unique_ptr<osdata> osdata = get_osdata (type);
206 
207  int nrows = osdata->items.size ();
208 
209  if (*type == '\0' && nrows == 0)
210  error (_("Available types of OS data not reported."));
211 
212  if (!osdata->items.empty ())
213  {
214  last = &osdata->items.back ();
215  ncols = last->columns.size ();
216 
217  /* As a special case, scan the listing of available data types
218  for a column named "Title", and only include it with MI
219  output; this column's normal use is for titles for interface
220  elements like menus, and it clutters up CLI output. */
221  if (*type == '\0' && !uiout->is_mi_like_p ())
222  {
223  for (int ix = 0; ix < last->columns.size (); ix++)
224  {
225  if (last->columns[ix].name == "Title")
226  col_to_skip = ix;
227  }
228  /* Be sure to reduce the total column count, otherwise
229  internal errors ensue. */
230  if (col_to_skip >= 0)
231  --ncols;
232  }
233  }
234 
235  ui_out_emit_table table_emitter (uiout, ncols, nrows, "OSDataTable");
236 
237  /* With no columns/items, we just output an empty table, but we
238  still output the table. This matters for MI. */
239  if (ncols == 0)
240  return;
241 
242  if (last != NULL && !last->columns.empty ())
243  {
244  for (int ix = 0; ix < last->columns.size (); ix++)
245  {
246  char col_name[32];
247 
248  if (ix == col_to_skip)
249  continue;
250 
251  snprintf (col_name, 32, "col%d", ix);
252  uiout->table_header (10, ui_left,
253  col_name, last->columns[ix].name.c_str ());
254  }
255  }
256 
257  uiout->table_body ();
258 
259  if (nrows != 0)
260  {
261  for (const osdata_item &item : osdata->items)
262  {
263  {
264  ui_out_emit_tuple tuple_emitter (uiout, "item");
265 
266  for (int ix_cols = 0; ix_cols < item.columns.size (); ix_cols++)
267  {
268  char col_name[32];
269 
270  if (ix_cols == col_to_skip)
271  continue;
272 
273  snprintf (col_name, 32, "col%d", ix_cols);
274  uiout->field_string (col_name,
275  item.columns[ix_cols].value.c_str ());
276  }
277  }
278 
279  uiout->text ("\n");
280  }
281  }
282 }
283 
284 static void
285 info_osdata_command (const char *arg, int from_tty)
286 {
287  info_osdata (arg);
288 }
289 
290 void
292 {
294  _("Show OS data ARG."));
295 }
const char * string
Definition: signals.c:50
std::unique_ptr< struct osdata > osdata
Definition: osdata.c:50
std::string property_name
Definition: osdata.c:51
static void osdata_end_column(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, const char *body_text)
Definition: osdata.c:98
void field_string(const char *fldname, const char *string)
Definition: ui-out.c:544
void * value
Definition: xml-support.h:78
void warning(const char *fmt,...)
Definition: errors.c:26
struct cmd_list_element * add_info(const char *name, cmd_const_cfunc_ftype *fun, const char *doc)
Definition: cli-decode.c:886
void table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr)
Definition: ui-out.c:365
std::unique_ptr< osdata > get_osdata(const char *type)
Definition: osdata.c:160
#define VEC(T)
Definition: vec.h:414
#define _(String)
Definition: gdb_locale.h:35
Definition: ui-out.h:44
void text(const char *string)
Definition: ui-out.c:581
const struct gdb_xml_element osdata_elements[]
Definition: osdata.c:137
const char *const name
Definition: aarch64-tdep.c:76
const struct gdb_xml_attribute column_attributes[]
Definition: osdata.c:113
std::unique_ptr< T, xfree_deleter< T > > unique_xmalloc_ptr
int gdb_xml_parse_quick(const char *name, const char *dtd_name, const struct gdb_xml_element *elements, const char *document, void *user_data)
Definition: xml-support.c:647
std::unique_ptr< osdata > osdata_parse(const char *xml)
Definition: osdata.c:144
struct gdb_xml_value * xml_find_attribute(VEC(gdb_xml_value_s) *attributes, const char *name)
Definition: xml-support.c:231
#define current_uiout
Definition: ui-out.h:39
const std::string * get_osdata_column(const osdata_item &item, const char *name)
Definition: osdata.c:185
Definition: gdbtypes.h:749
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)
Definition: osdata.c:73
std::vector< osdata_column > columns
Definition: osdata.h:37
Definition: osdata.h:40
void gdb_xml_error(struct gdb_xml_parser *parser, const char *format,...)
Definition: xml-support.c:219
Definition: ui-out.h:77
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)
Definition: osdata.c:57
std::vector< osdata_item > items
Definition: osdata.h:47
static void info_osdata_command(const char *arg, int from_tty)
Definition: osdata.c:285
const struct gdb_xml_element osdata_children[]
Definition: osdata.c:130
std::string name
Definition: osdata.h:31
void table_body()
Definition: ui-out.c:379
void _initialize_osdata(void)
Definition: osdata.c:291
gdb::unique_xmalloc_ptr< char > target_get_osdata(const char *type)
Definition: target.c:2651
void info_osdata(const char *type)
Definition: osdata.c:195
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)
Definition: osdata.c:84
std::string value
Definition: osdata.h:32
const struct gdb_xml_element item_children[]
Definition: osdata.c:118
void error(const char *fmt,...)
Definition: errors.c:38
const struct gdb_xml_attribute osdata_attributes[]
Definition: osdata.c:125
bool is_mi_like_p()
Definition: ui-out.c:622