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