GDB (xrefs)
/tmp/gdb-8.1/gdb/xml-support.c
Go to the documentation of this file.
1 /* Helper routines for parsing XML using Expat.
2 
3  Copyright (C) 2006-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 "gdbcmd.h"
22 #include "xml-support.h"
23 #include "filestuff.h"
24 #include "safe-ctype.h"
25 #include <vector>
26 #include <string>
27 
28 /* Debugging flag. */
29 static int debug_xml;
30 
31 /* The contents of this file are only useful if XML support is
32  available. */
33 #ifdef HAVE_LIBEXPAT
34 
35 #include "gdb_expat.h"
36 
37 /* The maximum depth of <xi:include> nesting. No need to be miserly,
38  we just want to avoid running out of stack on loops. */
39 #define MAX_XINCLUDE_DEPTH 30
40 
41 /* Simplified XML parser infrastructure. */
42 
43 /* A parsing level -- used to keep track of the current element
44  nesting. */
46 {
47  explicit scope_level (const gdb_xml_element *elements_ = NULL)
48  : elements (elements_),
49  element (NULL),
50  seen (0)
51  {}
52 
53  /* Elements we allow at this level. */
54  const struct gdb_xml_element *elements;
55 
56  /* The element which we are within. */
57  const struct gdb_xml_element *element;
58 
59  /* Mask of which elements we've seen at this level (used for
60  optional and repeatable checking). */
61  unsigned int seen;
62 
63  /* Body text accumulation. */
65 };
66 
67 /* The parser itself, and our additional state. */
69 {
70  gdb_xml_parser (const char *name,
71  const gdb_xml_element *elements,
72  void *user_data);
74 
75  /* Associate DTD_NAME, which must be the name of a compiled-in DTD,
76  with the parser. */
77  void use_dtd (const char *dtd_name);
78 
79  /* Return the name of the expected / default DTD, if specified. */
80  const char *dtd_name ()
81  { return m_dtd_name; }
82 
83  /* Invoke the parser on BUFFER. BUFFER is the data to parse, which
84  should be NUL-terminated.
85 
86  The return value is 0 for success or -1 for error. It may throw,
87  but only if something unexpected goes wrong during parsing; parse
88  errors will be caught, warned about, and reported as failure. */
89  int parse (const char *buffer);
90 
91  /* Issue a debugging message. */
92  void vdebug (const char *format, va_list ap)
93  ATTRIBUTE_PRINTF (2, 0);
94 
95  /* Issue an error message, and stop parsing. */
96  void verror (const char *format, va_list ap)
97  ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 0);
98 
99  void body_text (const XML_Char *text, int length);
100  void start_element (const XML_Char *name, const XML_Char **attrs);
101  void end_element (const XML_Char *name);
102 
103  /* Return the name of this parser. */
104  const char *name ()
105  { return m_name; }
106 
107  /* Return the user's callback data, for handlers. */
108  void *user_data ()
109  { return m_user_data; };
110 
111  /* Are we the special <xi:include> parser? */
112  void set_is_xinclude (bool is_xinclude)
113  { m_is_xinclude = is_xinclude; }
114 
115  /* A thrown error, if any. */
117  {
118  m_error = error;
119 #ifdef HAVE_XML_STOPPARSER
120  XML_StopParser (m_expat_parser, XML_FALSE);
121 #endif
122  }
123 
124  /* Return the underlying expat parser. */
125  XML_Parser expat_parser ()
126  { return m_expat_parser; }
127 
128 private:
129  /* The underlying expat parser. */
130  XML_Parser m_expat_parser;
131 
132  /* Name of this parser. */
133  const char *m_name;
134 
135  /* The user's callback data, for handlers. */
136  void *m_user_data;
137 
138  /* Scoping stack. */
139  std::vector<scope_level> m_scopes;
140 
141 /* A thrown error, if any. */
143 
144  /* The line of the thrown error, or 0. */
146 
147  /* The name of the expected / default DTD, if specified. */
148  const char *m_dtd_name;
149 
150  /* Are we the special <xi:include> parser? */
152 };
153 
154 /* Process some body text. We accumulate the text for later use; it's
155  wrong to do anything with it immediately, because a single block of
156  text might be broken up into multiple calls to this function. */
157 
158 void
159 gdb_xml_parser::body_text (const XML_Char *text, int length)
160 {
161  if (m_error.reason < 0)
162  return;
163 
164  scope_level &scope = m_scopes.back ();
165  scope.body.append (text, length);
166 }
167 
168 static void
169 gdb_xml_body_text (void *data, const XML_Char *text, int length)
170 {
171  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
172 
173  parser->body_text (text, length);
174 }
175 
176 /* Issue a debugging message from one of PARSER's handlers. */
177 
178 void
179 gdb_xml_parser::vdebug (const char *format, va_list ap)
180 {
181  int line = XML_GetCurrentLineNumber (m_expat_parser);
182  char *message;
183 
184  message = xstrvprintf (format, ap);
185  if (line)
186  fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
187  m_name, line, message);
188  else
189  fprintf_unfiltered (gdb_stderr, "%s: %s\n",
190  m_name, message);
191  xfree (message);
192 }
193 
194 void
195 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
196 {
197  if (!debug_xml)
198  return;
199 
200  va_list ap;
201  va_start (ap, format);
202  parser->vdebug (format, ap);
203  va_end (ap);
204 }
205 
206 /* Issue an error message from one of PARSER's handlers, and stop
207  parsing. */
208 
209 void
210 gdb_xml_parser::verror (const char *format, va_list ap)
211 {
212  int line = XML_GetCurrentLineNumber (m_expat_parser);
213 
214  m_last_line = line;
215  throw_verror (XML_PARSE_ERROR, format, ap);
216 }
217 
218 void
219 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
220 {
221  va_list ap;
222  va_start (ap, format);
223  parser->verror (format, ap);
224  va_end (ap);
225 }
226 
227 /* Find the attribute named NAME in the set of parsed attributes
228  ATTRIBUTES. Returns NULL if not found. */
229 
230 struct gdb_xml_value *
231 xml_find_attribute (VEC(gdb_xml_value_s) *attributes, const char *name)
232 {
233  struct gdb_xml_value *value;
234  int ix;
235 
236  for (ix = 0; VEC_iterate (gdb_xml_value_s, attributes, ix, value); ix++)
237  if (strcmp (value->name, name) == 0)
238  return value;
239 
240  return NULL;
241 }
242 
243 /* Clean up a vector of parsed attribute values. */
244 
245 static void
247 {
248  VEC(gdb_xml_value_s) **values = (VEC(gdb_xml_value_s) **) data;
249  struct gdb_xml_value *value;
250  int ix;
251 
252  for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++)
253  xfree (value->value);
254  VEC_free (gdb_xml_value_s, *values);
255 }
256 
257 /* Handle the start of an element. NAME is the element, and ATTRS are
258  the names and values of this element's attributes. */
259 
260 void
262  const XML_Char **attrs)
263 {
264  if (m_error.reason < 0)
265  return;
266 
267  const struct gdb_xml_element *element;
268  const struct gdb_xml_attribute *attribute;
269  VEC(gdb_xml_value_s) *attributes = NULL;
270  unsigned int seen;
271  struct cleanup *back_to;
272 
273  /* Push an error scope. If we return or throw an exception before
274  filling this in, it will tell us to ignore children of this
275  element. Note we don't take a reference to the element yet
276  because further below we'll process the element which may recurse
277  back here and push more elements to the vector. When the
278  recursion unrolls all such elements will have been popped back
279  already, but if one of those pushes reallocates the vector,
280  previous element references will be invalidated. */
281  m_scopes.emplace_back ();
282 
283  /* Get a reference to the current scope. */
284  scope_level &scope = m_scopes[m_scopes.size () - 2];
285 
286  gdb_xml_debug (this, _("Entering element <%s>"), name);
287 
288  /* Find this element in the list of the current scope's allowed
289  children. Record that we've seen it. */
290 
291  seen = 1;
292  for (element = scope.elements; element && element->name;
293  element++, seen <<= 1)
294  if (strcmp (element->name, name) == 0)
295  break;
296 
297  if (element == NULL || element->name == NULL)
298  {
299  /* If we're working on XInclude, <xi:include> can be the child
300  of absolutely anything. Copy the previous scope's element
301  list into the new scope even if there was no match. */
302  if (m_is_xinclude)
303  {
304  XML_DefaultCurrent (m_expat_parser);
305 
306  scope_level &unknown_scope = m_scopes.back ();
307  unknown_scope.elements = scope.elements;
308  return;
309  }
310 
311  gdb_xml_debug (this, _("Element <%s> unknown"), name);
312  return;
313  }
314 
315  if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope.seen))
316  gdb_xml_error (this, _("Element <%s> only expected once"), name);
317 
318  scope.seen |= seen;
319 
320  back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
321 
322  for (attribute = element->attributes;
323  attribute != NULL && attribute->name != NULL;
324  attribute++)
325  {
326  const char *val = NULL;
327  const XML_Char **p;
328  void *parsed_value;
329  struct gdb_xml_value new_value;
330 
331  for (p = attrs; *p != NULL; p += 2)
332  if (!strcmp (attribute->name, p[0]))
333  {
334  val = p[1];
335  break;
336  }
337 
338  if (*p != NULL && val == NULL)
339  {
340  gdb_xml_debug (this, _("Attribute \"%s\" missing a value"),
341  attribute->name);
342  continue;
343  }
344 
345  if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
346  {
347  gdb_xml_error (this, _("Required attribute \"%s\" of "
348  "<%s> not specified"),
349  attribute->name, element->name);
350  continue;
351  }
352 
353  if (*p == NULL)
354  continue;
355 
356  gdb_xml_debug (this, _("Parsing attribute %s=\"%s\""),
357  attribute->name, val);
358 
359  if (attribute->handler)
360  parsed_value = attribute->handler (this, attribute, val);
361  else
362  parsed_value = xstrdup (val);
363 
364  new_value.name = attribute->name;
365  new_value.value = parsed_value;
366  VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
367  }
368 
369  /* Check for unrecognized attributes. */
370  if (debug_xml)
371  {
372  const XML_Char **p;
373 
374  for (p = attrs; *p != NULL; p += 2)
375  {
376  for (attribute = element->attributes;
377  attribute != NULL && attribute->name != NULL;
378  attribute++)
379  if (strcmp (attribute->name, *p) == 0)
380  break;
381 
382  if (attribute == NULL || attribute->name == NULL)
383  gdb_xml_debug (this, _("Ignoring unknown attribute %s"), *p);
384  }
385  }
386 
387  /* Call the element handler if there is one. */
388  if (element->start_handler)
389  element->start_handler (this, element, m_user_data, attributes);
390 
391  /* Fill in a new scope level. Note that we must delay getting a
392  back reference till here because above we might have recursed,
393  which may have reallocated the vector which invalidates
394  iterators/pointers/references. */
395  scope_level &new_scope = m_scopes.back ();
396  new_scope.element = element;
397  new_scope.elements = element->children;
398 
399  do_cleanups (back_to);
400 }
401 
402 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
403  through expat. */
404 
405 static void
406 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
407  const XML_Char **attrs)
408 {
409  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
410 
411  TRY
412  {
413  parser->start_element (name, attrs);
414  }
415  CATCH (ex, RETURN_MASK_ALL)
416  {
417  parser->set_error (ex);
418  }
419  END_CATCH
420 }
421 
422 /* Handle the end of an element. NAME is the current element. */
423 
424 void
426 {
427  if (m_error.reason < 0)
428  return;
429 
430  struct scope_level *scope = &m_scopes.back ();
431  const struct gdb_xml_element *element;
432  unsigned int seen;
433 
434  gdb_xml_debug (this, _("Leaving element <%s>"), name);
435 
436  for (element = scope->elements, seen = 1;
437  element != NULL && element->name != NULL;
438  element++, seen <<= 1)
439  if ((scope->seen & seen) == 0
440  && (element->flags & GDB_XML_EF_OPTIONAL) == 0)
441  gdb_xml_error (this, _("Required element <%s> is missing"),
442  element->name);
443 
444  /* Call the element processor. */
445  if (scope->element != NULL && scope->element->end_handler)
446  {
447  const char *body;
448 
449  if (scope->body.empty ())
450  body = "";
451  else
452  {
453  int length;
454 
455  length = scope->body.size ();
456  body = scope->body.c_str ();
457 
458  /* Strip leading and trailing whitespace. */
459  while (length > 0 && ISSPACE (body[length - 1]))
460  length--;
461  scope->body.erase (length);
462  while (*body && ISSPACE (*body))
463  body++;
464  }
465 
466  scope->element->end_handler (this, scope->element,
467  m_user_data, body);
468  }
469  else if (scope->element == NULL)
470  XML_DefaultCurrent (m_expat_parser);
471 
472  /* Pop the scope level. */
473  m_scopes.pop_back ();
474 }
475 
476 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
477  through expat. */
478 
479 static void
480 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
481 {
482  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data;
483 
484  TRY
485  {
486  parser->end_element (name);
487  }
488  CATCH (ex, RETURN_MASK_ALL)
489  {
490  parser->set_error (ex);
491  }
492  END_CATCH
493 }
494 
495 /* Free a parser and all its associated state. */
496 
498 {
499  XML_ParserFree (m_expat_parser);
500 }
501 
502 /* Initialize a parser. */
503 
505  const gdb_xml_element *elements,
506  void *user_data)
507  : m_name (name),
510  m_last_line (0),
511  m_dtd_name (NULL),
512  m_is_xinclude (false)
513 {
514  m_expat_parser = XML_ParserCreateNS (NULL, '!');
515  if (m_expat_parser == NULL)
516  malloc_failure (0);
517 
518  XML_SetUserData (m_expat_parser, this);
519 
520  /* Set the callbacks. */
521  XML_SetElementHandler (m_expat_parser, gdb_xml_start_element_wrapper,
523  XML_SetCharacterDataHandler (m_expat_parser, gdb_xml_body_text);
524 
525  /* Initialize the outer scope. */
526  m_scopes.emplace_back (elements);
527 }
528 
529 /* External entity handler. The only external entities we support
530  are those compiled into GDB (we do not fetch entities from the
531  target). */
532 
533 static int XMLCALL
535  const XML_Char *context,
536  const XML_Char *base,
537  const XML_Char *systemId,
538  const XML_Char *publicId)
539 {
540  XML_Parser entity_parser;
541  const char *text;
542  enum XML_Status status;
543 
544  if (systemId == NULL)
545  {
546  gdb_xml_parser *parser
547  = (gdb_xml_parser *) XML_GetUserData (expat_parser);
548 
549  text = fetch_xml_builtin (parser->dtd_name ());
550  if (text == NULL)
551  internal_error (__FILE__, __LINE__,
552  _("could not locate built-in DTD %s"),
553  parser->dtd_name ());
554  }
555  else
556  {
557  text = fetch_xml_builtin (systemId);
558  if (text == NULL)
559  return XML_STATUS_ERROR;
560  }
561 
562  entity_parser = XML_ExternalEntityParserCreate (expat_parser,
563  context, NULL);
564 
565  /* Don't use our handlers for the contents of the DTD. Just let expat
566  process it. */
567  XML_SetElementHandler (entity_parser, NULL, NULL);
568  XML_SetDoctypeDeclHandler (entity_parser, NULL, NULL);
569  XML_SetXmlDeclHandler (entity_parser, NULL);
570  XML_SetDefaultHandler (entity_parser, NULL);
571  XML_SetUserData (entity_parser, NULL);
572 
573  status = XML_Parse (entity_parser, text, strlen (text), 1);
574 
575  XML_ParserFree (entity_parser);
576  return status;
577 }
578 
579 void
581 {
582  enum XML_Error err;
583 
585 
586  XML_SetParamEntityParsing (m_expat_parser,
587  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE);
588  XML_SetExternalEntityRefHandler (m_expat_parser,
590 
591  /* Even if no DTD is provided, use the built-in DTD anyway. */
592  err = XML_UseForeignDTD (m_expat_parser, XML_TRUE);
593  if (err != XML_ERROR_NONE)
594  internal_error (__FILE__, __LINE__,
595  _("XML_UseForeignDTD failed: %s"),
596  XML_ErrorString (err));
597 }
598 
599 /* Invoke PARSER on BUFFER. BUFFER is the data to parse, which
600  should be NUL-terminated.
601 
602  The return value is 0 for success or -1 for error. It may throw,
603  but only if something unexpected goes wrong during parsing; parse
604  errors will be caught, warned about, and reported as failure. */
605 
606 int
608 {
609  enum XML_Status status;
610  const char *error_string;
611 
612  gdb_xml_debug (this, _("Starting:\n%s"), buffer);
613 
614  status = XML_Parse (m_expat_parser, buffer, strlen (buffer), 1);
615 
616  if (status == XML_STATUS_OK && m_error.reason == 0)
617  return 0;
618 
621  {
622  gdb_assert (m_error.message != NULL);
623  error_string = m_error.message;
624  }
625  else if (status == XML_STATUS_ERROR)
626  {
627  enum XML_Error err = XML_GetErrorCode (m_expat_parser);
628 
629  error_string = XML_ErrorString (err);
630  }
631  else
632  {
633  gdb_assert (m_error.reason < 0);
635  }
636 
637  if (m_last_line != 0)
638  warning (_("while parsing %s (at line %d): %s"), m_name,
639  m_last_line, error_string);
640  else
641  warning (_("while parsing %s: %s"), m_name, error_string);
642 
643  return -1;
644 }
645 
646 int
647 gdb_xml_parse_quick (const char *name, const char *dtd_name,
648  const struct gdb_xml_element *elements,
649  const char *document, void *user_data)
650 {
651  gdb_xml_parser parser (name, elements, user_data);
652  if (dtd_name != NULL)
653  parser.use_dtd (dtd_name);
654  return parser.parse (document);
655 }
656 
657 /* Parse a field VALSTR that we expect to contain an integer value.
658  The integer is returned in *VALP. The string is parsed with an
659  equivalent to strtoul.
660 
661  Returns 0 for success, -1 for error. */
662 
663 static int
664 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
665 {
666  const char *endptr;
667  ULONGEST result;
668 
669  if (*valstr == '\0')
670  return -1;
671 
672  result = strtoulst (valstr, &endptr, 0);
673  if (*endptr != '\0')
674  return -1;
675 
676  *valp = result;
677  return 0;
678 }
679 
680 /* Parse an integer string into a ULONGEST and return it, or call
681  gdb_xml_error if it could not be parsed. */
682 
683 ULONGEST
684 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
685 {
686  ULONGEST result;
687 
688  if (xml_parse_unsigned_integer (value, &result) != 0)
689  gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
690 
691  return result;
692 }
693 
694 /* Parse an integer attribute into a ULONGEST. */
695 
696 void *
698  const struct gdb_xml_attribute *attribute,
699  const char *value)
700 {
701  ULONGEST result;
702  void *ret;
703 
704  if (xml_parse_unsigned_integer (value, &result) != 0)
705  gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
706  attribute->name, value);
707 
708  ret = XNEW (ULONGEST);
709  memcpy (ret, &result, sizeof (result));
710  return ret;
711 }
712 
713 /* A handler_data for yes/no boolean values. */
714 
716  { "yes", 1 },
717  { "no", 0 },
718  { NULL, 0 }
719 };
720 
721 /* Map NAME to VALUE. A struct gdb_xml_enum * should be saved as the
722  value of handler_data when using gdb_xml_parse_attr_enum to parse a
723  fixed list of possible strings. The list is terminated by an entry
724  with NAME == NULL. */
725 
726 void *
728  const struct gdb_xml_attribute *attribute,
729  const char *value)
730 {
731  const struct gdb_xml_enum *enums
732  = (const struct gdb_xml_enum *) attribute->handler_data;
733  void *ret;
734 
735  for (enums = (const struct gdb_xml_enum *) attribute->handler_data;
736  enums->name != NULL; enums++)
737  if (strcasecmp (enums->name, value) == 0)
738  break;
739 
740  if (enums->name == NULL)
741  gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
742  attribute->name, value);
743 
744  ret = xmalloc (sizeof (enums->value));
745  memcpy (ret, &enums->value, sizeof (enums->value));
746  return ret;
747 }
748 
749 
750 /* XInclude processing. This is done as a separate step from actually
751  parsing the document, so that we can produce a single combined XML
752  document - e.g. to hand to a front end or to simplify comparing two
753  documents. We make extensive use of XML_DefaultCurrent, to pass
754  input text directly into the output without reformatting or
755  requoting it.
756 
757  We output the DOCTYPE declaration for the first document unchanged,
758  if present, and discard DOCTYPEs from included documents. Only the
759  one we pass through here is used when we feed the result back to
760  expat. The XInclude standard explicitly does not discuss
761  validation of the result; we choose to apply the same DTD applied
762  to the outermost document.
763 
764  We can not simply include the external DTD subset in the document
765  as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
766  only in external subsets. But if we do not pass the DTD into the
767  output at all, default values will not be filled in.
768 
769  We don't pass through any <?xml> declaration because we generate
770  UTF-8, not whatever the input encoding was. */
771 
773 {
775  xml_fetch_another fetcher_, void *fetcher_baton_,
776  int include_depth_)
777  : output (output_),
778  skip_depth (0),
779  include_depth (include_depth_),
780  fetcher (fetcher_),
781  fetcher_baton (fetcher_baton_)
782  {}
783 
784  /* Where the output goes. */
786 
787  /* A count indicating whether we are in an element whose
788  children should not be copied to the output, and if so,
789  how deep we are nested. This is used for anything inside
790  an xi:include, and for the DTD. */
792 
793  /* The number of <xi:include> elements currently being processed,
794  to detect loops. */
796 
797  /* A function to call to obtain additional features, and its
798  baton. */
801 };
802 
803 static void
805  const struct gdb_xml_element *element,
806  void *user_data, VEC(gdb_xml_value_s) *attributes)
807 {
808  struct xinclude_parsing_data *data
809  = (struct xinclude_parsing_data *) user_data;
810  char *href = (char *) xml_find_attribute (attributes, "href")->value;
811 
812  gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
813 
814  if (data->include_depth > MAX_XINCLUDE_DEPTH)
815  gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
817 
818  gdb::unique_xmalloc_ptr<char> text = data->fetcher (href,
819  data->fetcher_baton);
820  if (text == NULL)
821  gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
822 
823  if (!xml_process_xincludes (data->output, parser->name (),
824  text.get (), data->fetcher,
825  data->fetcher_baton,
826  data->include_depth + 1))
827  gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
828 
829  data->skip_depth++;
830 }
831 
832 static void
834  const struct gdb_xml_element *element,
835  void *user_data, const char *body_text)
836 {
837  struct xinclude_parsing_data *data
838  = (struct xinclude_parsing_data *) user_data;
839 
840  data->skip_depth--;
841 }
842 
843 static void XMLCALL
844 xml_xinclude_default (void *data_, const XML_Char *s, int len)
845 {
846  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
848 
849  /* If we are inside of e.g. xi:include or the DTD, don't save this
850  string. */
851  if (data->skip_depth)
852  return;
853 
854  /* Otherwise just add it to the end of the document we're building
855  up. */
856  data->output.append (s, len);
857 }
858 
859 static void XMLCALL
860 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
861  const XML_Char *sysid, const XML_Char *pubid,
862  int has_internal_subset)
863 {
864  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
866 
867  /* Don't print out the doctype, or the contents of the DTD internal
868  subset, if any. */
869  data->skip_depth++;
870 }
871 
872 static void XMLCALL
874 {
875  struct gdb_xml_parser *parser = (struct gdb_xml_parser *) data_;
877 
878  data->skip_depth--;
879 }
880 
881 static void XMLCALL
882 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
883  const XML_Char *encoding, int standalone)
884 {
885  /* Do nothing - this function prevents the default handler from
886  being called, thus suppressing the XML declaration from the
887  output. */
888 }
889 
891  { "href", GDB_XML_AF_NONE, NULL, NULL },
892  { NULL, GDB_XML_AF_NONE, NULL, NULL }
893 };
894 
896  { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
899  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
900 };
901 
902 /* The main entry point for <xi:include> processing. */
903 
904 bool
906  const char *name, const char *text,
907  xml_fetch_another fetcher, void *fetcher_baton,
908  int depth)
909 {
910  xinclude_parsing_data data (result, fetcher, fetcher_baton, depth);
911 
912  gdb_xml_parser parser (name, xinclude_elements, &data);
913  parser.set_is_xinclude (true);
914 
915  XML_SetCharacterDataHandler (parser.expat_parser (), NULL);
916  XML_SetDefaultHandler (parser.expat_parser (), xml_xinclude_default);
917 
918  /* Always discard the XML version declarations; the only important
919  thing this provides is encoding, and our result will have been
920  converted to UTF-8. */
921  XML_SetXmlDeclHandler (parser.expat_parser (), xml_xinclude_xml_decl);
922 
923  if (depth > 0)
924  /* Discard the doctype for included documents. */
925  XML_SetDoctypeDeclHandler (parser.expat_parser (),
928 
929  parser.use_dtd ("xinclude.dtd");
930 
931  if (parser.parse (text) == 0)
932  {
933  if (depth == 0)
934  gdb_xml_debug (&parser, _("XInclude processing succeeded."));
935  return true;
936  }
937 
938  return false;
939 }
940 #endif /* HAVE_LIBEXPAT */
941 
942 
943 /* Return an XML document which was compiled into GDB, from
944  the given FILENAME, or NULL if the file was not compiled in. */
945 
946 const char *
947 fetch_xml_builtin (const char *filename)
948 {
949  const char *(*p)[2];
950 
951  for (p = xml_builtin; (*p)[0]; p++)
952  if (strcmp ((*p)[0], filename) == 0)
953  return (*p)[1];
954 
955  return NULL;
956 }
957 
958 /* A to_xfer_partial helper function which reads XML files which were
959  compiled into GDB. The target may call this function from its own
960  to_xfer_partial handler, after converting object and annex to the
961  appropriate filename. */
962 
963 LONGEST
964 xml_builtin_xfer_partial (const char *filename,
965  gdb_byte *readbuf, const gdb_byte *writebuf,
966  ULONGEST offset, LONGEST len)
967 {
968  const char *buf;
969  LONGEST len_avail;
970 
971  gdb_assert (readbuf != NULL && writebuf == NULL);
972  gdb_assert (filename != NULL);
973 
974  buf = fetch_xml_builtin (filename);
975  if (buf == NULL)
976  return -1;
977 
978  len_avail = strlen (buf);
979  if (offset >= len_avail)
980  return 0;
981 
982  if (len > len_avail - offset)
983  len = len_avail - offset;
984  memcpy (readbuf, buf + offset, len);
985  return len;
986 }
987 
988 
989 static void
990 show_debug_xml (struct ui_file *file, int from_tty,
991  struct cmd_list_element *c, const char *value)
992 {
993  fprintf_filtered (file, _("XML debugging is %s.\n"), value);
994 }
995 
997 xml_fetch_content_from_file (const char *filename, void *baton)
998 {
999  const char *dirname = (const char *) baton;
1000  gdb_file_up file;
1001 
1002  if (dirname && *dirname)
1003  {
1004  char *fullname = concat (dirname, "/", filename, (char *) NULL);
1005 
1006  if (fullname == NULL)
1007  malloc_failure (0);
1008  file = gdb_fopen_cloexec (fullname, FOPEN_RT);
1009  xfree (fullname);
1010  }
1011  else
1012  file = gdb_fopen_cloexec (filename, FOPEN_RT);
1013 
1014  if (file == NULL)
1015  return NULL;
1016 
1017  /* Read in the whole file. */
1018 
1019  size_t len;
1020 
1021  if (fseek (file.get (), 0, SEEK_END) == -1)
1022  perror_with_name (_("seek to end of file"));
1023  len = ftell (file.get ());
1024  rewind (file.get ());
1025 
1026  gdb::unique_xmalloc_ptr<char> text ((char *) xmalloc (len + 1));
1027 
1028  if (fread (text.get (), 1, len, file.get ()) != len
1029  || ferror (file.get ()))
1030  {
1031  warning (_("Read error from \"%s\""), filename);
1032  return NULL;
1033  }
1034 
1035  text.get ()[len] = '\0';
1036  return text;
1037 }
1038 
1039 void
1041 {
1043  _("Set XML parser debugging."),
1044  _("Show XML parser debugging."),
1045  _("When set, debugging messages for XML parsers "
1046  "are displayed."),
1047  NULL, show_debug_xml,
1049 }
xml_fetch_another fetcher
Definition: xml-support.c:799
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t err
Definition: gnu-nat.c:1822
const char * string
Definition: signals.c:50
void set_is_xinclude(bool is_xinclude)
Definition: xml-support.c:112
static void XMLCALL xml_xinclude_end_doctype(void *data_)
Definition: xml-support.c:873
static void gdb_xml_body_text(void *data, const XML_Char *text, int length)
Definition: xml-support.c:169
ULONGEST value
Definition: xml-support.h:217
void start_element(const XML_Char *name, const XML_Char **attrs)
Definition: xml-support.c:261
const char *const xml_builtin[][2]
gdb_xml_parser(const char *name, const gdb_xml_element *elements, void *user_data)
Definition: xml-support.c:504
const struct gdb_xml_attribute * attributes
Definition: xml-support.h:168
std::string & output
Definition: xml-support.c:785
static void xinclude_end_include(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, const char *body_text)
Definition: xml-support.c:833
void * value
Definition: xml-support.h:78
std::string body
Definition: xml-support.c:64
void xfree(void *)
char * xstrvprintf(const char *format, va_list ap)
Definition: common-utils.c:119
void warning(const char *fmt,...)
Definition: errors.c:26
XML_Parser expat_parser()
Definition: xml-support.c:125
enum errors error
void internal_error(const char *file, int line, const char *fmt,...)
Definition: errors.c:50
std::vector< scope_level > m_scopes
Definition: xml-support.c:139
static void gdb_xml_start_element_wrapper(void *data, const XML_Char *name, const XML_Char **attrs)
Definition: xml-support.c:406
int parse(const char *buffer)
Definition: xml-support.c:607
const struct gdb_exception exception_none
void set_error(gdb_exception error)
Definition: xml-support.c:116
gdb::unique_xmalloc_ptr< char >(* xml_fetch_another)(const char *href, void *baton)
Definition: xml-support.h:55
#define VEC_safe_push(T, V, O)
Definition: vec.h:276
struct gdb_exception m_error
Definition: xml-support.c:142
#define VEC(T)
Definition: vec.h:414
#define _(String)
Definition: gdb_locale.h:35
#define XML_STATUS_ERROR
Definition: gdb_expat.h:29
#define XML_STATUS_OK
Definition: gdb_expat.h:28
const struct gdb_xml_element xinclude_elements[]
Definition: xml-support.c:895
#define END_CATCH
const char * name
Definition: xml-support.h:77
void * m_user_data
Definition: xml-support.c:136
#define XNEW(T)
Definition: poison.h:109
const char * dtd_name()
Definition: xml-support.c:80
void void void body_text(const XML_Char *text, int length)
Definition: xml-support.c:159
#define TRY
const char * m_name
Definition: xml-support.c:133
const char *const name
Definition: aarch64-tdep.c:76
#define VEC_iterate(T, V, I, P)
Definition: vec.h:181
const struct gdb_xml_element * children
Definition: xml-support.h:169
static void show_debug_xml(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
Definition: xml-support.c:990
#define CATCH(EXCEPTION, MASK)
std::unique_ptr< FILE, gdb_file_deleter > gdb_file_up
Definition: filestuff.h:59
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
struct gdb_xml_value * xml_find_attribute(VEC(gdb_xml_value_s) *attributes, const char *name)
Definition: xml-support.c:231
XML_Parser m_expat_parser
Definition: xml-support.c:130
static void gdb_xml_values_cleanup(void *data)
Definition: xml-support.c:246
__extension__ enum dwarf_attribute name
Definition: dwarf2read.c:1517
void fprintf_filtered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2008
void gdb_xml_debug(struct gdb_xml_parser *parser, const char *format,...)
Definition: xml-support.c:195
static int xml_parse_unsigned_integer(const char *valstr, ULONGEST *valp)
Definition: xml-support.c:664
bool xml_process_xincludes(std::string &result, const char *name, const char *text, xml_fetch_another fetcher, void *fetcher_baton, int depth)
Definition: xml-support.c:905
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2018
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:116
const char version[]
Definition: version.c:2
static void xinclude_start_include(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes)
Definition: xml-support.c:804
#define ATTRIBUTE_PRINTF
Definition: common-defs.h:70
#define XMLCALL
Definition: gdb_expat.h:35
void * gdb_xml_parse_attr_ulongest(struct gdb_xml_parser *parser, const struct gdb_xml_attribute *attribute, const char *value)
Definition: xml-support.c:697
gdb_file_up gdb_fopen_cloexec(const char *filename, const char *opentype)
Definition: filestuff.c:296
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
Definition: gnu-nat.c:1822
static void XMLCALL xml_xinclude_xml_decl(void *data_, const XML_Char *version, const XML_Char *encoding, int standalone)
Definition: xml-support.c:882
unsigned int seen
Definition: xml-support.c:61
gdb_xml_element_end_handler * end_handler
Definition: xml-support.h:173
static void XMLCALL xml_xinclude_default(void *data_, const XML_Char *s, int len)
Definition: xml-support.c:844
const struct gdb_xml_element * element
Definition: xml-support.c:57
ULONGEST strtoulst(const char *num, const char **trailer, int base)
Definition: common-utils.c:266
struct cmd_list_element * setdebuglist
Definition: cli-cmds.c:153
const struct gdb_xml_element * elements
Definition: xml-support.c:54
ULONGEST gdb_xml_parse_ulongest(struct gdb_xml_parser *parser, const char *value)
Definition: xml-support.c:684
void * xmalloc(YYSIZE_T)
void gdb_xml_error(struct gdb_xml_parser *parser, const char *format,...)
Definition: xml-support.c:219
#define gdb_assert(expr)
Definition: gdb_assert.h:32
#define MAX_XINCLUDE_DEPTH
Definition: xml-support.c:39
Definition: value.c:169
const struct gdb_xml_enum gdb_xml_enums_boolean[]
Definition: xml-support.c:715
const char * name()
Definition: xml-support.c:104
void throw_exception(struct gdb_exception exception)
bfd_byte gdb_byte
Definition: common-types.h:38
const char * name
Definition: xml-support.h:167
const char * m_dtd_name
Definition: xml-support.c:148
void use_dtd(const char *dtd_name)
Definition: xml-support.c:580
void vdebug(const char *format, va_list ap) ATTRIBUTE_PRINTF(2
Definition: xml-support.c:179
static void XMLCALL xml_xinclude_start_doctype(void *data_, const XML_Char *doctypeName, const XML_Char *sysid, const XML_Char *pubid, int has_internal_subset)
Definition: xml-support.c:860
void void void void void void void void void perror_with_name(const char *string) ATTRIBUTE_NORETURN
Definition: utils.c:692
static void gdb_xml_end_element_wrapper(void *data, const XML_Char *name)
Definition: xml-support.c:480
#define gdb_stderr
Definition: utils.h:344
void throw_verror(enum errors error, const char *fmt, va_list ap)
gdb::unique_xmalloc_ptr< char > xml_fetch_content_from_file(const char *filename, void *baton)
Definition: xml-support.c:997
scope_level(const gdb_xml_element *elements_=NULL)
Definition: xml-support.c:47
int offset
Definition: agent.c:65
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_const_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
Definition: cli-decode.c:569
Definition: buffer.h:23
#define VEC_free(T, V)
Definition: vec.h:196
LONGEST xml_builtin_xfer_partial(const char *filename, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
Definition: xml-support.c:964
static int XMLCALL gdb_xml_fetch_external_entity(XML_Parser expat_parser, const XML_Char *context, const XML_Char *base, const XML_Char *systemId, const XML_Char *publicId)
Definition: xml-support.c:534
const char * name
Definition: xml-support.h:216
unsigned long long ULONGEST
Definition: common-types.h:53
void * gdb_xml_parse_attr_enum(struct gdb_xml_parser *parser, const struct gdb_xml_attribute *attribute, const char *value)
Definition: xml-support.c:727
const char * message
xinclude_parsing_data(std::string &output_, xml_fetch_another fetcher_, void *fetcher_baton_, int include_depth_)
Definition: xml-support.c:774
void _initialize_xml_support(void)
Definition: xml-support.c:1040
struct cmd_list_element * showdebuglist
Definition: cli-cmds.c:155
void void verror(const char *format, va_list ap) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF(2
Definition: xml-support.c:210
void end_element(const XML_Char *name)
Definition: xml-support.c:425
void error(const char *fmt,...)
Definition: errors.c:38
void malloc_failure(long size) ATTRIBUTE_NORETURN
Definition: utils.c:773
static int debug_xml
Definition: xml-support.c:29
void * user_data()
Definition: xml-support.c:108
const struct gdb_xml_attribute xinclude_attributes[]
Definition: xml-support.c:890
long long LONGEST
Definition: common-types.h:52
const char * fetch_xml_builtin(const char *filename)
Definition: xml-support.c:947
void do_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:174
enum return_reason reason
gdb_xml_element_start_handler * start_handler
Definition: xml-support.h:172