* Makefile.in (arm-tdep.o, eval.o, target-descriptions.o)
[external/binutils.git] / gdb / xml-support.c
1 /* Helper routines for parsing XML using Expat.
2
3    Copyright (C) 2006, 2007 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 2 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, write to the Free Software
19    Foundation, Inc., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "defs.h"
23 #include "gdbcmd.h"
24
25 /* Debugging flag.  */
26 static int debug_xml;
27
28 /* The contents of this file are only useful if XML support is
29    available.  */
30 #ifdef HAVE_LIBEXPAT
31
32 #include "exceptions.h"
33 #include "xml-support.h"
34
35 #include "gdb_expat.h"
36 #include "gdb_string.h"
37 #include "safe-ctype.h"
38
39 /* The maximum depth of <xi:include> nesting.  No need to be miserly,
40    we just want to avoid running out of stack on loops.  */
41 #define MAX_XINCLUDE_DEPTH 30
42
43 /* Simplified XML parser infrastructure.  */
44
45 /* A parsing level -- used to keep track of the current element
46    nesting.  */
47 struct scope_level
48 {
49   /* Elements we allow at this level.  */
50   const struct gdb_xml_element *elements;
51
52   /* The element which we are within.  */
53   const struct gdb_xml_element *element;
54
55   /* Mask of which elements we've seen at this level (used for
56      optional and repeatable checking).  */
57   unsigned int seen;
58
59   /* Body text accumulation.  */
60   struct obstack *body;
61 };
62 typedef struct scope_level scope_level_s;
63 DEF_VEC_O(scope_level_s);
64
65 /* The parser itself, and our additional state.  */
66 struct gdb_xml_parser
67 {
68   XML_Parser expat_parser;      /* The underlying expat parser.  */
69
70   const char *name;             /* Name of this parser.  */
71   void *user_data;              /* The user's callback data, for handlers.  */
72
73   VEC(scope_level_s) *scopes;   /* Scoping stack.  */
74
75   struct gdb_exception error;   /* A thrown error, if any.  */
76   int last_line;                /* The line of the thrown error, or 0.  */
77
78   const char *dtd_name;         /* The name of the expected / default DTD,
79                                    if specified.  */
80   int is_xinclude;              /* Are we the special <xi:include> parser?  */
81 };
82
83 /* Process some body text.  We accumulate the text for later use; it's
84    wrong to do anything with it immediately, because a single block of
85    text might be broken up into multiple calls to this function.  */
86
87 static void
88 gdb_xml_body_text (void *data, const XML_Char *text, int length)
89 {
90   struct gdb_xml_parser *parser = data;
91   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
92
93   if (parser->error.reason < 0)
94     return;
95
96   if (scope->body == NULL)
97     {
98       scope->body = XZALLOC (struct obstack);
99       obstack_init (scope->body);
100     }
101
102   obstack_grow (scope->body, text, length);
103 }
104
105 /* Issue a debugging message from one of PARSER's handlers.  */
106
107 void
108 gdb_xml_debug (struct gdb_xml_parser *parser, const char *format, ...)
109 {
110   int line = XML_GetCurrentLineNumber (parser->expat_parser);
111   va_list ap;
112   char *message;
113
114   if (!debug_xml)
115     return;
116
117   va_start (ap, format);
118   message = xstrvprintf (format, ap);
119   if (line)
120     fprintf_unfiltered (gdb_stderr, "%s (line %d): %s\n",
121                         parser->name, line, message);
122   else
123     fprintf_unfiltered (gdb_stderr, "%s: %s\n",
124                         parser->name, message);
125   xfree (message);
126 }
127
128 /* Issue an error message from one of PARSER's handlers, and stop
129    parsing.  */
130
131 void
132 gdb_xml_error (struct gdb_xml_parser *parser, const char *format, ...)
133 {
134   int line = XML_GetCurrentLineNumber (parser->expat_parser);
135   va_list ap;
136
137   parser->last_line = line;
138   va_start (ap, format);
139   throw_verror (XML_PARSE_ERROR, format, ap);
140 }
141
142 /* Clean up a vector of parsed attribute values.  */
143
144 static void
145 gdb_xml_values_cleanup (void *data)
146 {
147   VEC(gdb_xml_value_s) **values = data;
148   struct gdb_xml_value *value;
149   int ix;
150
151   for (ix = 0; VEC_iterate (gdb_xml_value_s, *values, ix, value); ix++)
152     xfree (value->value);
153   VEC_free (gdb_xml_value_s, *values);
154 }
155
156 /* Handle the start of an element.  DATA is our local XML parser, NAME
157    is the element, and ATTRS are the names and values of this
158    element's attributes.  */
159
160 static void
161 gdb_xml_start_element (void *data, const XML_Char *name,
162                        const XML_Char **attrs)
163 {
164   struct gdb_xml_parser *parser = data;
165   struct scope_level *scope;
166   struct scope_level new_scope;
167   const struct gdb_xml_element *element;
168   const struct gdb_xml_attribute *attribute;
169   VEC(gdb_xml_value_s) *attributes = NULL;
170   unsigned int seen;
171   struct cleanup *back_to;
172
173   /* Push an error scope.  If we return or throw an exception before
174      filling this in, it will tell us to ignore children of this
175      element.  */
176   VEC_reserve (scope_level_s, parser->scopes, 1);
177   scope = VEC_last (scope_level_s, parser->scopes);
178   memset (&new_scope, 0, sizeof (new_scope));
179   VEC_quick_push (scope_level_s, parser->scopes, &new_scope);
180
181   gdb_xml_debug (parser, _("Entering element <%s>"), name);
182
183   /* Find this element in the list of the current scope's allowed
184      children.  Record that we've seen it.  */
185
186   seen = 1;
187   for (element = scope->elements; element && element->name;
188        element++, seen <<= 1)
189     if (strcmp (element->name, name) == 0)
190       break;
191
192   if (element == NULL || element->name == NULL)
193     {
194       /* If we're working on XInclude, <xi:include> can be the child
195          of absolutely anything.  Copy the previous scope's element
196          list into the new scope even if there was no match.  */
197       if (parser->is_xinclude)
198         {
199           struct scope_level *unknown_scope;
200
201           XML_DefaultCurrent (parser->expat_parser);
202
203           unknown_scope = VEC_last (scope_level_s, parser->scopes);
204           unknown_scope->elements = scope->elements;
205           return;
206         }
207
208       gdb_xml_debug (parser, _("Element <%s> unknown"), name);
209       return;
210     }
211
212   if (!(element->flags & GDB_XML_EF_REPEATABLE) && (seen & scope->seen))
213     gdb_xml_error (parser, _("Element <%s> only expected once"), name);
214
215   scope->seen |= seen;
216
217   back_to = make_cleanup (gdb_xml_values_cleanup, &attributes);
218
219   for (attribute = element->attributes;
220        attribute != NULL && attribute->name != NULL;
221        attribute++)
222     {
223       const char *val = NULL;
224       const XML_Char **p;
225       void *parsed_value;
226       struct gdb_xml_value new_value;
227
228       for (p = attrs; *p != NULL; p += 2)
229         if (!strcmp (attribute->name, p[0]))
230           {
231             val = p[1];
232             break;
233           }
234
235       if (*p != NULL && val == NULL)
236         {
237           gdb_xml_debug (parser, _("Attribute \"%s\" missing a value"),
238                          attribute->name);
239           continue;
240         }
241
242       if (*p == NULL && !(attribute->flags & GDB_XML_AF_OPTIONAL))
243         {
244           gdb_xml_error (parser, _("Required attribute \"%s\" of "
245                                    "<%s> not specified"),
246                          attribute->name, element->name);
247           continue;
248         }
249
250       if (*p == NULL)
251         continue;
252
253       gdb_xml_debug (parser, _("Parsing attribute %s=\"%s\""),
254                      attribute->name, val);
255
256       if (attribute->handler)
257         parsed_value = attribute->handler (parser, attribute, val);
258       else
259         parsed_value = xstrdup (val);
260
261       new_value.name = attribute->name;
262       new_value.value = parsed_value;
263       VEC_safe_push (gdb_xml_value_s, attributes, &new_value);
264     }
265
266   /* Check for unrecognized attributes.  */
267   if (debug_xml)
268     {
269       const XML_Char **p;
270
271       for (p = attrs; *p != NULL; p += 2)
272         {
273           for (attribute = element->attributes;
274                attribute != NULL && attribute->name != NULL;
275                attribute++)
276             if (strcmp (attribute->name, *p) == 0)
277               break;
278
279           if (attribute == NULL || attribute->name == NULL)
280             gdb_xml_debug (parser, _("Ignoring unknown attribute %s"), *p);
281         }
282     }
283
284   /* Call the element handler if there is one.  */
285   if (element->start_handler)
286     element->start_handler (parser, element, parser->user_data, attributes);
287
288   /* Fill in a new scope level.  */
289   scope = VEC_last (scope_level_s, parser->scopes);
290   scope->element = element;
291   scope->elements = element->children;
292
293   do_cleanups (back_to);
294 }
295
296 /* Wrapper for gdb_xml_start_element, to prevent throwing exceptions
297    through expat.  */
298
299 static void
300 gdb_xml_start_element_wrapper (void *data, const XML_Char *name,
301                                const XML_Char **attrs)
302 {
303   struct gdb_xml_parser *parser = data;
304   volatile struct gdb_exception ex;
305
306   if (parser->error.reason < 0)
307     return;
308
309   TRY_CATCH (ex, RETURN_MASK_ALL)
310     {
311       gdb_xml_start_element (data, name, attrs);
312     }
313   if (ex.reason < 0)
314     {
315       parser->error = ex;
316 #ifdef HAVE_XML_STOPPARSER
317       XML_StopParser (parser->expat_parser, XML_FALSE);
318 #endif
319     }
320 }
321
322 /* Handle the end of an element.  DATA is our local XML parser, and
323    NAME is the current element.  */
324
325 static void
326 gdb_xml_end_element (void *data, const XML_Char *name)
327 {
328   struct gdb_xml_parser *parser = data;
329   struct scope_level *scope = VEC_last (scope_level_s, parser->scopes);
330   const struct gdb_xml_element *element;
331   unsigned int seen;
332
333   gdb_xml_debug (parser, _("Leaving element <%s>"), name);
334
335   for (element = scope->elements, seen = 1;
336        element != NULL && element->name != NULL;
337        element++, seen <<= 1)
338     if ((scope->seen & seen) == 0
339         && (element->flags & GDB_XML_EF_OPTIONAL) == 0)
340       gdb_xml_error (parser, _("Required element <%s> is missing"),
341                      element->name);
342
343   /* Call the element processor. */
344   if (scope->element != NULL && scope->element->end_handler)
345     {
346       char *body;
347
348       if (scope->body == NULL)
349         body = "";
350       else
351         {
352           int length;
353
354           length = obstack_object_size (scope->body);
355           obstack_1grow (scope->body, '\0');
356           body = obstack_finish (scope->body);
357
358           /* Strip leading and trailing whitespace.  */
359           while (length > 0 && ISSPACE (body[length-1]))
360             body[--length] = '\0';
361           while (*body && ISSPACE (*body))
362             body++;
363         }
364
365       scope->element->end_handler (parser, scope->element, parser->user_data,
366                                    body);
367     }
368   else if (scope->element == NULL)
369     XML_DefaultCurrent (parser->expat_parser);
370
371   /* Pop the scope level.  */
372   if (scope->body)
373     {
374       obstack_free (scope->body, NULL);
375       xfree (scope->body);
376     }
377   VEC_pop (scope_level_s, parser->scopes);
378 }
379
380 /* Wrapper for gdb_xml_end_element, to prevent throwing exceptions
381    through expat.  */
382
383 static void
384 gdb_xml_end_element_wrapper (void *data, const XML_Char *name)
385 {
386   struct gdb_xml_parser *parser = data;
387   volatile struct gdb_exception ex;
388
389   if (parser->error.reason < 0)
390     return;
391
392   TRY_CATCH (ex, RETURN_MASK_ALL)
393     {
394       gdb_xml_end_element (data, name);
395     }
396   if (ex.reason < 0)
397     {
398       parser->error = ex;
399 #ifdef HAVE_XML_STOPPARSER
400       XML_StopParser (parser->expat_parser, XML_FALSE);
401 #endif
402     }
403 }
404
405 /* Free a parser and all its associated state.  */
406
407 static void
408 gdb_xml_cleanup (void *arg)
409 {
410   struct gdb_xml_parser *parser = arg;
411   struct scope_level *scope;
412   int ix;
413
414   XML_ParserFree (parser->expat_parser);
415
416   /* Clean up the scopes.  */
417   for (ix = 0; VEC_iterate (scope_level_s, parser->scopes, ix, scope); ix++)
418     if (scope->body)
419       {
420         obstack_free (scope->body, NULL);
421         xfree (scope->body);
422       }
423   VEC_free (scope_level_s, parser->scopes);
424
425   xfree (parser);
426 }
427
428 /* Initialize and return a parser.  Register a cleanup to destroy the
429    parser.  */
430
431 struct gdb_xml_parser *
432 gdb_xml_create_parser_and_cleanup (const char *name,
433                                    const struct gdb_xml_element *elements,
434                                    void *user_data)
435 {
436   struct gdb_xml_parser *parser;
437   struct scope_level start_scope;
438
439   /* Initialize the parser.  */
440   parser = XZALLOC (struct gdb_xml_parser);
441   parser->expat_parser = XML_ParserCreateNS (NULL, '!');
442   if (parser->expat_parser == NULL)
443     {
444       xfree (parser);
445       nomem (0);
446     }
447
448   parser->name = name;
449
450   parser->user_data = user_data;
451   XML_SetUserData (parser->expat_parser, parser);
452
453   /* Set the callbacks.  */
454   XML_SetElementHandler (parser->expat_parser, gdb_xml_start_element_wrapper,
455                          gdb_xml_end_element_wrapper);
456   XML_SetCharacterDataHandler (parser->expat_parser, gdb_xml_body_text);
457
458   /* Initialize the outer scope.  */
459   memset (&start_scope, 0, sizeof (start_scope));
460   start_scope.elements = elements;
461   VEC_safe_push (scope_level_s, parser->scopes, &start_scope);
462
463   make_cleanup (gdb_xml_cleanup, parser);
464
465   return parser;
466 }
467
468 /* External entity handler.  The only external entities we support
469    are those compiled into GDB (we do not fetch entities from the
470    target).  */
471
472 static int XMLCALL
473 gdb_xml_fetch_external_entity (XML_Parser expat_parser,
474                                const XML_Char *context,
475                                const XML_Char *base,
476                                const XML_Char *systemId,
477                                const XML_Char *publicId)
478 {
479   struct gdb_xml_parser *parser = XML_GetUserData (expat_parser);
480   XML_Parser entity_parser;
481   const char *text;
482   enum XML_Status status;
483
484   if (systemId == NULL)
485     {
486       text = fetch_xml_builtin (parser->dtd_name);
487       if (text == NULL)
488         internal_error (__FILE__, __LINE__, "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", XML_ErrorString (err));
534 }
535
536 /* Invoke PARSER on BUFFER.  BUFFER is the data to parse, which
537    should be NUL-terminated.
538
539    The return value is 0 for success or -1 for error.  It may throw,
540    but only if something unexpected goes wrong during parsing; parse
541    errors will be caught, warned about, and reported as failure.  */
542
543 int
544 gdb_xml_parse (struct gdb_xml_parser *parser, const char *buffer)
545 {
546   enum XML_Status status;
547   const char *error_string;
548
549   status = XML_Parse (parser->expat_parser, buffer, strlen (buffer), 1);
550
551   if (status == XML_STATUS_OK && parser->error.reason == 0)
552     return 0;
553
554   if (parser->error.reason == RETURN_ERROR
555       && parser->error.error == XML_PARSE_ERROR)
556     {
557       gdb_assert (parser->error.message != NULL);
558       error_string = parser->error.message;
559     }
560   else if (status == XML_STATUS_ERROR)
561     {
562       enum XML_Error err = XML_GetErrorCode (parser->expat_parser);
563       error_string = XML_ErrorString (err);
564     }
565   else
566     {
567       gdb_assert (parser->error.reason < 0);
568       throw_exception (parser->error);
569     }
570
571   if (parser->last_line != 0)
572     warning (_("while parsing %s (at line %d): %s"), parser->name,
573              parser->last_line, error_string);
574   else
575     warning (_("while parsing %s: %s"), parser->name, error_string);
576
577   return -1;
578 }
579
580 /* Parse a field VALSTR that we expect to contain an integer value.
581    The integer is returned in *VALP.  The string is parsed with an
582    equivalent to strtoul.
583
584    Returns 0 for success, -1 for error.  */
585
586 static int
587 xml_parse_unsigned_integer (const char *valstr, ULONGEST *valp)
588 {
589   const char *endptr;
590   ULONGEST result;
591
592   if (*valstr == '\0')
593     return -1;
594
595   result = strtoulst (valstr, &endptr, 0);
596   if (*endptr != '\0')
597     return -1;
598
599   *valp = result;
600   return 0;
601 }
602
603 /* Parse an integer string into a ULONGEST and return it, or call
604    gdb_xml_error if it could not be parsed.  */
605
606 ULONGEST
607 gdb_xml_parse_ulongest (struct gdb_xml_parser *parser, const char *value)
608 {
609   ULONGEST result;
610
611   if (xml_parse_unsigned_integer (value, &result) != 0)
612     gdb_xml_error (parser, _("Can't convert \"%s\" to an integer"), value);
613
614   return result;
615 }
616
617 /* Parse an integer attribute into a ULONGEST.  */
618
619 void *
620 gdb_xml_parse_attr_ulongest (struct gdb_xml_parser *parser,
621                              const struct gdb_xml_attribute *attribute,
622                              const char *value)
623 {
624   ULONGEST result;
625   void *ret;
626
627   if (xml_parse_unsigned_integer (value, &result) != 0)
628     gdb_xml_error (parser, _("Can't convert %s=\"%s\" to an integer"),
629                    attribute->name, value);
630
631   ret = xmalloc (sizeof (result));
632   memcpy (ret, &result, sizeof (result));
633   return ret;
634 }
635
636 /* A handler_data for yes/no boolean values.  */
637
638 const struct gdb_xml_enum gdb_xml_enums_boolean[] = {
639   { "yes", 1 },
640   { "no", 0 },
641   { NULL, 0 }
642 };
643
644 /* Map NAME to VALUE.  A struct gdb_xml_enum * should be saved as the
645    value of handler_data when using gdb_xml_parse_attr_enum to parse a
646    fixed list of possible strings.  The list is terminated by an entry
647    with NAME == NULL.  */
648
649 void *
650 gdb_xml_parse_attr_enum (struct gdb_xml_parser *parser,
651                          const struct gdb_xml_attribute *attribute,
652                          const char *value)
653 {
654   const struct gdb_xml_enum *enums = attribute->handler_data;
655   void *ret;
656
657   for (enums = attribute->handler_data; enums->name != NULL; enums++)
658     if (strcasecmp (enums->name, value) == 0)
659       break;
660
661   if (enums->name == NULL)
662     gdb_xml_error (parser, _("Unknown attribute value %s=\"%s\""),
663                  attribute->name, value);
664
665   ret = xmalloc (sizeof (enums->value));
666   memcpy (ret, &enums->value, sizeof (enums->value));
667   return ret;
668 }
669 \f
670
671 /* XInclude processing.  This is done as a separate step from actually
672    parsing the document, so that we can produce a single combined XML
673    document - e.g. to hand to a front end or to simplify comparing two
674    documents.  We make extensive use of XML_DefaultCurrent, to pass
675    input text directly into the output without reformatting or
676    requoting it.
677
678    We output the DOCTYPE declaration for the first document unchanged,
679    if present, and discard DOCTYPEs from included documents.  Only the
680    one we pass through here is used when we feed the result back to
681    expat.  The XInclude standard explicitly does not discuss
682    validation of the result; we choose to apply the same DTD applied
683    to the outermost document.
684
685    We can not simply include the external DTD subset in the document
686    as an internal subset, because <!IGNORE> and <!INCLUDE> are valid
687    only in external subsets.  But if we do not pass the DTD into the
688    output at all, default values will not be filled in.
689
690    We don't pass through any <?xml> declaration because we generate
691    UTF-8, not whatever the input encoding was.  */
692
693 struct xinclude_parsing_data
694 {
695   /* The obstack to build the output in.  */
696   struct obstack obstack;
697
698   /* A count indicating whether we are in an element whose
699      children should not be copied to the output, and if so,
700      how deep we are nested.  This is used for anything inside
701      an xi:include, and for the DTD.  */
702   int skip_depth;
703
704   /* The number of <xi:include> elements currently being processed,
705      to detect loops.  */
706   int include_depth;
707
708   /* A function to call to obtain additional features, and its
709      baton.  */
710   xml_fetch_another fetcher;
711   void *fetcher_baton;
712 };
713
714 static void
715 xinclude_start_include (struct gdb_xml_parser *parser,
716                         const struct gdb_xml_element *element,
717                         void *user_data, VEC(gdb_xml_value_s) *attributes)
718 {
719   struct xinclude_parsing_data *data = user_data;
720   char *href = VEC_index (gdb_xml_value_s, attributes, 0)->value;
721   struct cleanup *back_to;
722   char *text, *output;
723   int ret;
724
725   gdb_xml_debug (parser, _("Processing XInclude of \"%s\""), href);
726
727   if (data->include_depth > MAX_XINCLUDE_DEPTH)
728     gdb_xml_error (parser, _("Maximum XInclude depth (%d) exceeded"),
729                    MAX_XINCLUDE_DEPTH);
730
731   text = data->fetcher (href, data->fetcher_baton);
732   if (text == NULL)
733     gdb_xml_error (parser, _("Could not load XML document \"%s\""), href);
734   back_to = make_cleanup (xfree, text);
735
736   output = xml_process_xincludes (parser->name, text, data->fetcher,
737                                   data->fetcher_baton,
738                                   data->include_depth + 1);
739   if (output == NULL)
740     gdb_xml_error (parser, _("Parsing \"%s\" failed"), href);
741
742   obstack_grow (&data->obstack, output, strlen (output));
743   xfree (output);
744
745   do_cleanups (back_to);
746
747   data->skip_depth++;
748 }
749
750 static void
751 xinclude_end_include (struct gdb_xml_parser *parser,
752                       const struct gdb_xml_element *element,
753                       void *user_data, const char *body_text)
754 {
755   struct xinclude_parsing_data *data = user_data;
756
757   data->skip_depth--;
758 }
759
760 static void XMLCALL
761 xml_xinclude_default (void *data_, const XML_Char *s, int len)
762 {
763   struct gdb_xml_parser *parser = data_;
764   struct xinclude_parsing_data *data = parser->user_data;
765
766   /* If we are inside of e.g. xi:include or the DTD, don't save this
767      string.  */
768   if (data->skip_depth)
769     return;
770
771   /* Otherwise just add it to the end of the document we're building
772      up.  */
773   obstack_grow (&data->obstack, s, len);
774 }
775
776 static void XMLCALL
777 xml_xinclude_start_doctype (void *data_, const XML_Char *doctypeName,
778                             const XML_Char *sysid, const XML_Char *pubid,
779                             int has_internal_subset)
780 {
781   struct gdb_xml_parser *parser = data_;
782   struct xinclude_parsing_data *data = parser->user_data;
783
784   /* Don't print out the doctype, or the contents of the DTD internal
785      subset, if any.  */
786   data->skip_depth++;
787 }
788
789 static void XMLCALL
790 xml_xinclude_end_doctype (void *data_)
791 {
792   struct gdb_xml_parser *parser = data_;
793   struct xinclude_parsing_data *data = parser->user_data;
794
795   data->skip_depth--;
796 }
797
798 static void XMLCALL
799 xml_xinclude_xml_decl (void *data_, const XML_Char *version,
800                        const XML_Char *encoding, int standalone)
801 {
802   /* Do nothing - this function prevents the default handler from
803      being called, thus suppressing the XML declaration from the
804      output.  */
805 }
806
807 static void
808 xml_xinclude_cleanup (void *data_)
809 {
810   struct xinclude_parsing_data *data = data_;
811
812   obstack_free (&data->obstack, NULL);
813   xfree (data);
814 }
815
816 const struct gdb_xml_attribute xinclude_attributes[] = {
817   { "href", GDB_XML_AF_NONE, NULL, NULL },
818   { NULL, GDB_XML_AF_NONE, NULL, NULL }
819 };
820
821 const struct gdb_xml_element xinclude_elements[] = {
822   { "http://www.w3.org/2001/XInclude!include", xinclude_attributes, NULL,
823     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
824     xinclude_start_include, xinclude_end_include },
825   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
826 };
827
828 /* The main entry point for <xi:include> processing.  */
829
830 char *
831 xml_process_xincludes (const char *name, const char *text,
832                        xml_fetch_another fetcher, void *fetcher_baton,
833                        int depth)
834 {
835   enum XML_Error err;
836   struct gdb_xml_parser *parser;
837   struct xinclude_parsing_data *data;
838   struct cleanup *back_to;
839   char *result = NULL;
840
841   data = XZALLOC (struct xinclude_parsing_data);
842   obstack_init (&data->obstack);
843   back_to = make_cleanup (xml_xinclude_cleanup, data);
844
845   parser = gdb_xml_create_parser_and_cleanup (name, xinclude_elements, data);
846   parser->is_xinclude = 1;
847
848   data->include_depth = depth;
849   data->fetcher = fetcher;
850   data->fetcher_baton = fetcher_baton;
851
852   XML_SetCharacterDataHandler (parser->expat_parser, NULL);
853   XML_SetDefaultHandler (parser->expat_parser, xml_xinclude_default);
854
855   /* Always discard the XML version declarations; the only important
856      thing this provides is encoding, and our result will have been
857      converted to UTF-8.  */
858   XML_SetXmlDeclHandler (parser->expat_parser, xml_xinclude_xml_decl);
859
860   if (depth > 0)
861     /* Discard the doctype for included documents.  */
862     XML_SetDoctypeDeclHandler (parser->expat_parser,
863                                xml_xinclude_start_doctype,
864                                xml_xinclude_end_doctype);
865
866   gdb_xml_use_dtd (parser, "xinclude.dtd");
867
868   if (gdb_xml_parse (parser, text) == 0)
869     {
870       obstack_1grow (&data->obstack, '\0');
871       result = xstrdup (obstack_finish (&data->obstack));
872
873       if (depth == 0)
874         gdb_xml_debug (parser, _("XInclude processing succeeded:\n%s"),
875                        result);
876     }
877   else
878     result = NULL;
879
880   do_cleanups (back_to);
881   return result;
882 }
883 \f
884
885 /* Return an XML document which was compiled into GDB, from
886    the given FILENAME, or NULL if the file was not compiled in.  */
887
888 const char *
889 fetch_xml_builtin (const char *filename)
890 {
891   const char *(*p)[2];
892
893   for (p = xml_builtin; (*p)[0]; p++)
894     if (strcmp ((*p)[0], filename) == 0)
895       return (*p)[1];
896
897   return NULL;
898 }
899
900 #endif /* HAVE_LIBEXPAT */
901
902 static void
903 show_debug_xml (struct ui_file *file, int from_tty,
904                 struct cmd_list_element *c, const char *value)
905 {
906   fprintf_filtered (file, _("XML debugging is %s.\n"), value);
907 }
908
909 void _initialize_xml_support (void);
910
911 void
912 _initialize_xml_support (void)
913 {
914   add_setshow_boolean_cmd ("xml", class_maintenance, &debug_xml,
915                            _("Set XML parser debugging."),
916                            _("Show XML parser debugging."),
917                            _("When set, debugging messages for XML parsers "
918                              "are displayed."),
919                            NULL, show_debug_xml,
920                            &setdebuglist, &showdebuglist);
921 }